From 279fd1e1553a0469def07a984af4df76fd93b7e8 Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Tue, 1 Dec 2015 02:25:28 +1100 Subject: [PATCH] 20030306 release --- bin/banked/adduser | Bin 0 -> 14678 bytes bin/banked/align | Bin 0 -> 7624 bytes bin/banked/apropos | Bin 0 -> 12184 bytes bin/banked/banner | Bin 0 -> 10322 bytes bin/banked/basename | Bin 0 -> 892 bytes bin/banked/bsh | Bin 0 -> 27158 bytes bin/banked/cal | Bin 0 -> 8525 bytes bin/banked/cat | Bin 0 -> 841 bytes bin/banked/catman | Bin 0 -> 14553 bytes bin/banked/cdiff | Bin 0 -> 16493 bytes bin/banked/cgrep | Bin 0 -> 16892 bytes bin/banked/chgrp | Bin 0 -> 8312 bytes bin/banked/chmod | Bin 0 -> 8025 bytes bin/banked/chown | Bin 0 -> 8380 bytes bin/banked/cksum | Bin 0 -> 8474 bytes bin/banked/cmp | Bin 0 -> 8076 bytes bin/banked/cp | Bin 0 -> 22137 bytes bin/banked/cr | Bin 0 -> 10539 bytes bin/banked/crc | Bin 0 -> 9075 bytes bin/banked/cron | Bin 0 -> 16047 bytes bin/banked/date | Bin 0 -> 6258 bytes bin/banked/dd | Bin 0 -> 13021 bytes bin/banked/df | Bin 0 -> 9295 bytes bin/banked/dhry | Bin 0 -> 8526 bytes bin/banked/diff | Bin 0 -> 26570 bytes bin/banked/dirname | Bin 0 -> 727 bytes bin/banked/diskusag | Bin 0 -> 19904 bytes bin/banked/dtree | Bin 0 -> 15589 bytes bin/banked/du | Bin 0 -> 10731 bytes bin/banked/echo | Bin 0 -> 5727 bytes bin/banked/ed | Bin 0 -> 24122 bytes bin/banked/expr | Bin 0 -> 12074 bytes bin/banked/false | Bin 0 -> 188 bytes bin/banked/fgrep | Bin 0 -> 9928 bytes bin/banked/file | Bin 0 -> 9459 bytes bin/banked/find | Bin 0 -> 22038 bytes bin/banked/fld | Bin 0 -> 12207 bytes bin/banked/fortune | Bin 0 -> 9333 bytes bin/banked/grep | Bin 0 -> 15657 bytes bin/banked/gres | Bin 0 -> 13197 bytes bin/banked/head | Bin 0 -> 9396 bytes bin/banked/id | Bin 0 -> 8553 bytes bin/banked/init | Bin 0 -> 21590 bytes bin/banked/inodes | Bin 0 -> 10517 bytes bin/banked/kill | Bin 0 -> 7696 bytes bin/banked/login | Bin 0 -> 12821 bytes bin/banked/lpd | Bin 0 -> 21763 bytes bin/banked/lpr | Bin 0 -> 7116 bytes bin/banked/ls | Bin 0 -> 13419 bytes bin/banked/man | Bin 0 -> 13576 bytes bin/banked/mkdir | Bin 0 -> 1558 bytes bin/banked/mknod | Bin 0 -> 2288 bytes bin/banked/more | Bin 0 -> 10986 bytes bin/banked/mount | Bin 0 -> 9491 bytes bin/banked/msh | Bin 0 -> 40306 bytes bin/banked/ncheck | Bin 0 -> 16380 bytes bin/banked/nroff | Bin 0 -> 69116 bytes bin/banked/od | Bin 0 -> 8569 bytes bin/banked/passwd | Bin 0 -> 13747 bytes bin/banked/pathchk | Bin 0 -> 1897 bytes bin/banked/pr | Bin 0 -> 15515 bytes bin/banked/printenv | Bin 0 -> 5173 bytes bin/banked/ps | Bin 0 -> 13966 bytes bin/banked/pwd | Bin 0 -> 3001 bytes bin/banked/readall | Bin 0 -> 6636 bytes bin/banked/reboot | Bin 0 -> 4561 bytes bin/banked/renice | Bin 0 -> 8829 bytes bin/banked/rm | Bin 0 -> 10035 bytes bin/banked/rmdir | Bin 0 -> 4372 bytes bin/banked/roff | Bin 0 -> 22541 bytes bin/banked/sash | Bin 0 -> 26404 bytes bin/banked/setclock | Bin 0 -> 1537 bytes bin/banked/sort | Bin 0 -> 14205 bytes bin/banked/split | Bin 0 -> 4477 bytes bin/banked/su | Bin 0 -> 11425 bytes bin/banked/sum | Bin 0 -> 6066 bytes bin/banked/sync | Bin 0 -> 209 bytes bin/banked/tail | Bin 0 -> 10366 bytes bin/banked/tar | Bin 0 -> 22587 bytes bin/banked/tee | Bin 0 -> 683 bytes bin/banked/ter | Bin 0 -> 7877 bytes bin/banked/termcap | Bin 0 -> 12925 bytes bin/banked/test | Bin 0 -> 6867 bytes bin/banked/tget | Bin 0 -> 14039 bytes bin/banked/time | Bin 0 -> 6301 bytes bin/banked/top | Bin 0 -> 20681 bytes bin/banked/touch | Bin 0 -> 2352 bytes bin/banked/tr | Bin 0 -> 12972 bytes bin/banked/true | Bin 0 -> 188 bytes bin/banked/ualign | Bin 0 -> 7628 bytes bin/banked/umount | Bin 0 -> 10684 bytes bin/banked/uname | Bin 0 -> 1096 bytes bin/banked/uniq | Bin 0 -> 10989 bytes bin/banked/uudecode | Bin 0 -> 14434 bytes bin/banked/uuencode | Bin 0 -> 10868 bytes bin/banked/wc | Bin 0 -> 11634 bytes bin/banked/which | Bin 0 -> 6209 bytes bin/banked/whoami | Bin 0 -> 6992 bytes bin/banked/yes | Bin 0 -> 490 bytes bin/boot.bin | Bin 0 -> 1920 bytes bin/catman.bat | 47 + bin/checksum | Bin 0 -> 128 bytes bin/chset.sh | 9 + bin/chset/cog-chs | Bin 0 -> 46244 bytes bin/chset/lpr-chs | Bin 0 -> 113 bytes bin/chset/ned-chs | Bin 0 -> 17264 bytes bin/chset/std-chs | Bin 0 -> 22708 bytes bin/demos.sh | 9 + bin/demos/cog-lab | 1 + bin/demos/lpr-rec | 21 + bin/demos/ned01-1 | Bin 0 -> 40 bytes bin/demos/ned01-2 | 1 + bin/demos/ned01-3 | 1 + bin/demos/ned01-4 | 1 + bin/demos/ned02-1 | Bin 0 -> 40 bytes bin/demos/ned02-2 | Bin 0 -> 156 bytes bin/demos/ned02-3 | 1 + bin/demos/ned02-4 | 1 + bin/demos/ned02-5 | 1 + bin/demos/ned02-6 | Bin 0 -> 100 bytes bin/demos/ned03-1 | Bin 0 -> 237 bytes bin/demos/ned03-2 | 1 + bin/demos/ned04-1 | Bin 0 -> 245 bytes bin/demos/ned04-2 | Bin 0 -> 107 bytes bin/demos/ned04-3 | 1 + bin/demos/ned05-1 | Bin 0 -> 82 bytes bin/demos/ned05-2 | Bin 0 -> 178 bytes bin/demos/ned05-3 | Bin 0 -> 178 bytes bin/demos/ned05-4 | Bin 0 -> 178 bytes bin/demos/ned05-5 | Bin 0 -> 156 bytes bin/demos/ned06-1 | Bin 0 -> 40 bytes bin/demos/ned06-2 | Bin 0 -> 156 bytes bin/demos/ned06-3 | 1 + bin/demos/ned06-4 | 1 + bin/demos/ned06-5 | 1 + bin/demos/ned06-6 | Bin 0 -> 109 bytes bin/fortune.dat | 1017 ++ bin/group.txt | 4 + bin/hytdisk.dat | 1 + bin/inittab.txt | 4 + bin/kernel.bin | Bin 0 -> 81008 bytes bin/large/adduser | Bin 0 -> 13559 bytes bin/large/align | Bin 0 -> 7134 bytes bin/large/apropos | Bin 0 -> 11487 bytes bin/large/banner | Bin 0 -> 9988 bytes bin/large/basename | Bin 0 -> 780 bytes bin/large/bd | Bin 0 -> 7442 bytes bin/large/cal | Bin 0 -> 8031 bytes bin/large/cat | Bin 0 -> 732 bytes bin/large/catman | Bin 0 -> 13456 bytes bin/large/cdiff | Bin 0 -> 15315 bytes bin/large/cgrep | Bin 0 -> 15713 bytes bin/large/chgrp | Bin 0 -> 7776 bytes bin/large/chmod | Bin 0 -> 7579 bytes bin/large/chown | Bin 0 -> 7844 bytes bin/large/cksum | Bin 0 -> 8024 bytes bin/large/cmp | Bin 0 -> 7556 bytes bin/large/cp | Bin 0 -> 19863 bytes bin/large/cr | Bin 0 -> 9863 bytes bin/large/crc | Bin 0 -> 8550 bytes bin/large/cron | Bin 0 -> 15084 bytes bin/large/date | Bin 0 -> 5914 bytes bin/large/dd | Bin 0 -> 12055 bytes bin/large/df | Bin 0 -> 8746 bytes bin/large/dhry | Bin 0 -> 7992 bytes bin/large/diff | Bin 0 -> 24281 bytes bin/large/dirname | Bin 0 -> 638 bytes bin/large/diskusag | Bin 0 -> 16669 bytes bin/large/dtree | Bin 0 -> 14662 bytes bin/large/du | Bin 0 -> 10057 bytes bin/large/echo | Bin 0 -> 5383 bytes bin/large/ed | Bin 0 -> 22341 bytes bin/large/expr | Bin 0 -> 11148 bytes bin/large/false | Bin 0 -> 142 bytes bin/large/fgrep | Bin 0 -> 9243 bytes bin/large/file | Bin 0 -> 8772 bytes bin/large/find | Bin 0 -> 19305 bytes bin/large/fld | Bin 0 -> 11501 bytes bin/large/fortune | Bin 0 -> 8750 bytes bin/large/fsck | Bin 0 -> 18252 bytes bin/large/grep | Bin 0 -> 14659 bytes bin/large/gres | Bin 0 -> 12405 bytes bin/large/head | Bin 0 -> 8875 bytes bin/large/id | Bin 0 -> 7938 bytes bin/large/init | Bin 0 -> 18309 bytes bin/large/inodes | Bin 0 -> 9863 bytes bin/large/kill | Bin 0 -> 7245 bytes bin/large/login | Bin 0 -> 11975 bytes bin/large/lpd | Bin 0 -> 19952 bytes bin/large/lpr | Bin 0 -> 6651 bytes bin/large/ls | Bin 0 -> 12513 bytes bin/large/man | Bin 0 -> 12494 bytes bin/large/mkdir | Bin 0 -> 1437 bytes bin/large/mkfs | Bin 0 -> 15063 bytes bin/large/mknod | Bin 0 -> 2173 bytes bin/large/more | Bin 0 -> 10306 bytes bin/large/mount | Bin 0 -> 8961 bytes bin/large/ncheck | Bin 0 -> 15246 bytes bin/large/od | Bin 0 -> 7965 bytes bin/large/passwd | Bin 0 -> 12788 bytes bin/large/pathchk | Bin 0 -> 1707 bytes bin/large/pr | Bin 0 -> 14712 bytes bin/large/printenv | Bin 0 -> 4834 bytes bin/large/ps | Bin 0 -> 13219 bytes bin/large/pwd | Bin 0 -> 2711 bytes bin/large/readall | Bin 0 -> 6197 bytes bin/large/reboot | Bin 0 -> 4212 bytes bin/large/renice | Bin 0 -> 8217 bytes bin/large/rm | Bin 0 -> 9243 bytes bin/large/rmdir | Bin 0 -> 4075 bytes bin/large/roff | Bin 0 -> 20362 bytes bin/large/sash | Bin 0 -> 24054 bytes bin/large/setclock | Bin 0 -> 1412 bytes bin/large/sort | Bin 0 -> 13153 bytes bin/large/split | Bin 0 -> 4055 bytes bin/large/su | Bin 0 -> 10642 bytes bin/large/sum | Bin 0 -> 5667 bytes bin/large/sync | Bin 0 -> 151 bytes bin/large/tail | Bin 0 -> 9647 bytes bin/large/tar | Bin 0 -> 20135 bytes bin/large/tee | Bin 0 -> 578 bytes bin/large/ter | Bin 0 -> 7297 bytes bin/large/termcap | Bin 0 -> 12175 bytes bin/large/test | Bin 0 -> 6419 bytes bin/large/tget | Bin 0 -> 13324 bytes bin/large/time | Bin 0 -> 5875 bytes bin/large/top | Bin 0 -> 18954 bytes bin/large/touch | Bin 0 -> 2138 bytes bin/large/tr | Bin 0 -> 12249 bytes bin/large/true | Bin 0 -> 142 bytes bin/large/ualign | Bin 0 -> 7138 bytes bin/large/umount | Bin 0 -> 10044 bytes bin/large/uname | Bin 0 -> 959 bytes bin/large/uniq | Bin 0 -> 10380 bytes bin/large/uudecode | Bin 0 -> 13391 bytes bin/large/uuencode | Bin 0 -> 10187 bytes bin/large/wc | Bin 0 -> 10971 bytes bin/large/which | Bin 0 -> 5770 bytes bin/large/whoami | Bin 0 -> 6535 bytes bin/large/yes | Bin 0 -> 419 bytes bin/liberror.txt | 52 + bin/man/man1/basename.1 | 29 + bin/man/man1/cal.1 | 27 + bin/man/man1/cat.1 | 38 + bin/man/man1/chmod.1 | 172 + bin/man/man1/chown.1 | 35 + bin/man/man1/cmp.1 | 42 + bin/man/man1/cp.1 | 29 + bin/man/man1/date.1 | 42 + bin/man/man1/dd.1 | 192 + bin/man/man1/diff.1 | 138 + bin/man/man1/du.1 | 43 + bin/man/man1/echo.1 | 23 + bin/man/man1/ed.1 | 652 + bin/man/man1/expr.1 | 96 + bin/man/man1/file.1 | 18 + bin/man/man1/find.1 | 169 + bin/man/man1/grep.1 | 176 + bin/man/man1/kill.1 | 38 + bin/man/man1/ln.1 | 33 + bin/man/man1/login.1 | 61 + bin/man/man1/ls.1 | 172 + bin/man/man1/man.1 | 99 + bin/man/man1/mkdir.1 | 25 + bin/man/man1/mv.1 | 69 + bin/man/man1/od.1 | 70 + bin/man/man1/passwd.1 | 30 + bin/man/man1/pr.1 | 75 + bin/man/man1/ps.1 | 124 + bin/man/man1/pwd.1 | 10 + bin/man/man1/rm.1 | 63 + bin/man/man1/roff.1 | 318 + bin/man/man1/sh.1 | 261 + bin/man/man1/sort.1 | 176 + bin/man/man1/split.1 | 35 + bin/man/man1/su.1 | 27 + bin/man/man1/sum.1 | 19 + bin/man/man1/tail.1 | 35 + bin/man/man1/tar.1 | 167 + bin/man/man1/tee.1 | 24 + bin/man/man1/test.1 | 115 + bin/man/man1/time.1 | 26 + bin/man/man1/touch.1 | 22 + bin/man/man1/tr.1 | 67 + bin/man/man1/troff.1 | 212 + bin/man/man1/true.1 | 30 + bin/man/man1/uniq.1 | 72 + bin/man/man1/wc.1 | 23 + bin/man/mkwhatis.bat | 32 + bin/man/mkwhatis.sed | 45 + bin/man/mkwhatis.sh | 32 + bin/man/sh.1 | 261 + bin/mkramfs.sh | 13 + bin/mtab.txt | 2 + bin/n.bat | 18 + bin/n.ucp | 470 + bin/newkrnl.sh | 10 + bin/passwd.txt | 2 + bin/term/tab37 | Bin 0 -> 1288 bytes bin/tmac/tmac.an | 267 + bin/uzidisk.dat | Bin 0 -> 4194304 bytes doc/030131SD test readme.txt | 45 + doc/030131SD.P | 45 + doc/030217SD test readme.txt | 116 + doc/030217SD.P | 116 + doc/ASxxxx Cross Assembler Documentation.htm | 9024 +++++++++++ .../home.gif | Bin 0 -> 1536 bytes .../rnbow.gif | Bin 0 -> 3072 bytes .../spcshp.gif | Bin 0 -> 1536 bytes .../welcom.gif | Bin 0 -> 2560 bytes doc/ASxxxx Cross Assemblers.htm | 90 + doc/ASxxxx Cross Assemblers_files/bug.gif | Bin 0 -> 1536 bytes doc/ASxxxx Cross Assemblers_files/home.gif | Bin 0 -> 1536 bytes doc/ASxxxx Cross Assemblers_files/manual.gif | Bin 0 -> 1536 bytes doc/ASxxxx Cross Assemblers_files/netwrk.gif | Bin 0 -> 1024 bytes doc/ASxxxx Cross Assemblers_files/notes.gif | Bin 0 -> 1536 bytes doc/ASxxxx Cross Assemblers_files/questn.gif | Bin 0 -> 1024 bytes doc/ASxxxx Cross Assemblers_files/rnbow.gif | Bin 0 -> 3072 bytes doc/ASxxxx Cross Assemblers_files/welcom.gif | Bin 0 -> 2560 bytes doc/Betriebssystem UNIX - Literatur.htm | 618 + .../kd14.jpg | Bin 0 -> 79006 bytes doc/C-history.htm | 1221 ++ ...- History and Timeline -- UNIX History.htm | 455 + .../b.gif | Bin 0 -> 43 bytes .../background.gif | Bin 0 -> 106 bytes .../code | 69 + .../info1.css | 105 + .../opengroup-logo.gif | Bin 0 -> 3921 bytes .../topcell.gif | Bin 0 -> 374 bytes .../under-logo2.gif | Bin 0 -> 222 bytes .../unix_plate-small.jpg | Bin 0 -> 20958 bytes .../what_is_unix.htm | 530 + doc/UNIX Evolution.htm | 861 ++ doc/UNIX.htm | 1120 ++ doc/cmx-lic.p | 31 + doc/cmx-lic.txt | 112 + doc/index.htm | 15 + doc/lcd0.txt | 34 + doc/overview.txt | 231 + doc/stdlib.txt | 230 + doc/syscalls.p | 1106 ++ doc/syscalls.txt | 1106 ++ doc/uzi-lic.txt | 339 + doc/uzi-summ.txt | 199 + doc/uzi-tech.txt | 548 + doc/z180-mem.p | 588 + doc/z180-mem.txt | 588 + include/!readme! | 10 + include/alloc.h | 3 + include/ar.h | 18 + include/assert.h | 27 + include/ctype.h | 88 + include/curses.h | 229 + include/dirent.h | 48 + include/errno.h | 71 + include/fcntl.h | 36 + include/features.h | 61 + include/float.h | 174 + include/getopt.h | 13 + include/grp.h | 35 + include/include.zip | Bin 0 -> 30570 bytes include/limits.h | 55 + include/malloc.h | 13 + include/math.h | 34 + include/mem.h | 54 + include/memory.h | 3 + include/ncurses.h | 7 + include/paths.h | 32 + include/pwd.h | 37 + include/regexp.h | 27 + include/regmagic.h | 5 + include/search.h | 55 + include/setjmp.h | 172 + include/setjmp.h$ | 38 + include/sgtty.h | 38 + include/signal.h | 99 + include/stdarg.h | 23 + include/stddef.h | 13 + include/stdio.h | 160 + include/stdlib.h | 93 + include/string.h | 99 + include/strings.h | 3 + include/sys/cdefs.h | 24 + include/sys/exec.h | 4 + include/sys/ioctl.h | 38 + include/sys/seek.h | 19 + include/sys/stat.h | 79 + include/sys/utsname.h | 18 + include/sys/wait.h | 48 + include/sys/wait.h% | 37 + include/sys/z8.pmm | 12 + include/sys/z9.pmm | 6 + include/syscalls.h | 132 + include/tcpip.h | 120 + include/termcap.h | 21 + include/termio.h | 3 + include/termios.h | 23 + include/time.h | 61 + include/types.h | 106 + include/unistd.h | 58 + include/utime.h | 9 + include/utmp.h | 45 + include/utsname.h | 18 + include/varargs.h | 13 + include/vendor.h | 11 + include/z8.pmm | 49 + include/z9.pmm | 6 + lib/libcb.lib | 142 + lib/libcl.lib | 142 + lib/libiar.lib | 195 + lib/libsysb.lib | 58 + lib/libsysl.lib | 58 + relnotes/20030306.txt | 234 + silly.bat | 2 + src/as-z80/as-z80.exe | Bin 0 -> 110637 bytes src/as-z80/as-z80.lnk | 17 + src/as-z80/asdata.c | 323 + src/as-z80/asexpr.c | 1218 ++ src/as-z80/aslex.c | 529 + src/as-z80/aslist.c | 953 ++ src/as-z80/asmain.c | 1524 ++ src/as-z80/asout.c | 1440 ++ src/as-z80/assubr.c | 241 + src/as-z80/assym.c | 610 + src/as-z80/asxxxx.h | 850 ++ src/as-z80/n.bat | 34 + src/as-z80/tz80.asm | 1013 ++ src/as-z80/tz80l.asm | 47 + src/as-z80/z80.h | 185 + src/as-z80/z80adr.c | 247 + src/as-z80/z80ext.c | 19 + src/as-z80/z80mch.c | 761 + src/as-z80/z80pst.c | 260 + src/as-z80/z80pst.c$ | 157 + src/bin/4dos.com | Bin 0 -> 153314 bytes src/bin/as-z80.exe | Bin 0 -> 110637 bytes src/bin/bd.exe | Bin 0 -> 57384 bytes src/bin/bin2c.exe | Bin 0 -> 57388 bytes src/bin/crc.com | Bin 0 -> 5413 bytes src/bin/crcd.com | Bin 0 -> 1045 bytes src/bin/fsck.exe | Bin 0 -> 73770 bytes src/bin/ihex2bin.exe | Bin 0 -> 57391 bytes src/bin/link-z80.exe | Bin 0 -> 106545 bytes src/bin/make.exe | Bin 0 -> 188416 bytes src/bin/mkfs.exe | Bin 0 -> 65578 bytes src/bin/mklink-b.bat | 30 + src/bin/mklink-l.bat | 28 + src/bin/mknbat-b.bat | 34 + src/bin/mknbat-l.bat | 34 + src/bin/nroff.exe | Bin 0 -> 143403 bytes src/bin/roff.exe | Bin 0 -> 77866 bytes src/bin/touch.exe | Bin 0 -> 61484 bytes src/bin/ucp.exe | Bin 0 -> 143402 bytes src/chset/CHSET00.WIN | Bin 0 -> 1792 bytes src/chset/CHSET01.WIN | Bin 0 -> 2432 bytes src/chset/CHSET02.WIN | Bin 0 -> 3584 bytes src/chset/CHSET03.WIN | Bin 0 -> 1664 bytes src/chset/CHSET04.WIN | Bin 0 -> 3712 bytes src/chset/CHSET05.WIN | Bin 0 -> 3456 bytes src/chset/CHSET06.WIN | Bin 0 -> 2560 bytes src/chset/CHSET07.WIN | Bin 0 -> 3200 bytes src/chset/CHSET08.WIN | Bin 0 -> 2688 bytes src/chset/CHSET09.WIN | Bin 0 -> 2816 bytes src/chset/CLRSCRN.BIN | 2 + src/chset/CUTPULL.BIN | 1 + src/chset/HEADER0 | Bin 0 -> 34 bytes src/chset/HEADER1 | 2 + src/chset/HEADER2 | Bin 0 -> 34 bytes src/chset/HEADER3 | 2 + src/chset/HEADER4 | 2 + src/chset/HEADER5 | 2 + src/chset/HEADER6 | Bin 0 -> 34 bytes src/chset/HEADER7 | 2 + src/chset/HEADER8 | 2 + src/chset/HEADER9 | Bin 0 -> 34 bytes src/chset/HYLAB.TXT | 15 + src/chset/HYLAB0-0.TXT | 2 + src/chset/HYLAB0-1.TXT | 12 + src/chset/HYLAB1-0.TXT | 2 + src/chset/HYLAB1-1.TXT | 13 + src/chset/HYLAB2.TXT | 19 + src/chset/NED.TXT | 2 + src/chset/PRINTER.BIN | Bin 0 -> 108 bytes src/chset/TRI08.CHR | Bin 0 -> 12344 bytes src/chset/TRI10.CHR | Bin 0 -> 13924 bytes src/chset/TRI16.CHR | Bin 0 -> 18831 bytes src/chset/chset.sh | 9 + src/chset/chset0 | Bin 0 -> 1826 bytes src/chset/chset1 | Bin 0 -> 2466 bytes src/chset/chset2 | Bin 0 -> 3618 bytes src/chset/chset3 | Bin 0 -> 1698 bytes src/chset/chset4 | Bin 0 -> 3746 bytes src/chset/chset5 | Bin 0 -> 3490 bytes src/chset/chset6 | Bin 0 -> 2594 bytes src/chset/chset7 | Bin 0 -> 3234 bytes src/chset/chset8 | Bin 0 -> 2722 bytes src/chset/chset9 | Bin 0 -> 2850 bytes src/chset/clrscrn.dbg | 18 + src/chset/cognitiv.bat | 5 + src/chset/cutpull.dbg | 11 + src/chset/demos/cog-lab | 1 + src/chset/demos/demos.sh | 9 + src/chset/demos/lpr-rec | 21 + src/chset/demos/ned-chs | Bin 0 -> 17228 bytes src/chset/demos/ned01-1 | Bin 0 -> 40 bytes src/chset/demos/ned01-2 | 1 + src/chset/demos/ned01-3 | 1 + src/chset/demos/ned01-4 | 1 + src/chset/demos/ned02-1 | Bin 0 -> 40 bytes src/chset/demos/ned02-2 | Bin 0 -> 156 bytes src/chset/demos/ned02-3 | 1 + src/chset/demos/ned02-4 | 1 + src/chset/demos/ned02-5 | 1 + src/chset/demos/ned02-6 | Bin 0 -> 100 bytes src/chset/demos/ned03-1 | Bin 0 -> 237 bytes src/chset/demos/ned03-2 | 1 + src/chset/demos/ned04-1 | Bin 0 -> 245 bytes src/chset/demos/ned04-2 | Bin 0 -> 107 bytes src/chset/demos/ned04-3 | 1 + src/chset/demos/ned05-1 | Bin 0 -> 82 bytes src/chset/demos/ned05-2 | Bin 0 -> 178 bytes src/chset/demos/ned05-3 | Bin 0 -> 178 bytes src/chset/demos/ned05-4 | Bin 0 -> 178 bytes src/chset/demos/ned05-5 | Bin 0 -> 156 bytes src/chset/demos/ned06-1 | Bin 0 -> 40 bytes src/chset/demos/ned06-2 | Bin 0 -> 156 bytes src/chset/demos/ned06-3 | 1 + src/chset/demos/ned06-4 | 1 + src/chset/demos/ned06-5 | 1 + src/chset/demos/ned06-6 | Bin 0 -> 109 bytes src/chset/headers.bat | 14 + src/chset/headers.dbg | 75 + src/chset/hylab.tmp | Bin 0 -> 45298 bytes src/chset/hylab0.tmp | 14 + src/chset/hylab1.tmp | 15 + src/chset/hylab2.tmp | 19 + src/chset/n.bat | 37 + src/chset/printer.bat | 3 + src/chset/printer.dbg | 21 + src/fsutil/bd.c | 198 + src/fsutil/bd.exe | Bin 0 -> 57384 bytes src/fsutil/bd.lnk | 11 + src/fsutil/bd.w32 | 6 + src/fsutil/boot.c | 243 + src/fsutil/f.bat | 13 + src/fsutil/fsck.c | 1262 ++ src/fsutil/fsck.exe | Bin 0 -> 73770 bytes src/fsutil/fsck.lnk | 12 + src/fsutil/fsck.w32 | 6 + src/fsutil/hdasm.c | 68 + src/fsutil/kernel.bin | Bin 0 -> 88832 bytes src/fsutil/m.bat | 13 + src/fsutil/main.c | 39 + src/fsutil/mkboot.c | 252 + src/fsutil/mkfs.c | 829 + src/fsutil/mkfs.exe | Bin 0 -> 65578 bytes src/fsutil/mkfs.lnk | 12 + src/fsutil/mkfs.ltc | 1 + src/fsutil/mkfs.w32 | 6 + src/fsutil/n.bat | 107 + src/fsutil/readme | 33 + src/fsutil/runfsck.bat | 1 + src/fsutil/runmkfs.bat | 3 + src/fsutil/tcmake.bat | 39 + src/fsutil/ucp.c | 420 + src/fsutil/ucp.exe | Bin 0 -> 143402 bytes src/fsutil/ucp.ltc | 16 + src/fsutil/ucp.w32 | 20 + src/fsutil/ucpsub.c | 649 + src/fsutil/utildos.c | 88 + src/fsutil/utildos.h | 52 + src/fsutil/utils.c | 75 + src/fsutil/utils.h | 14 + src/fsutil/uzidisk.dat | Bin 0 -> 1572352 bytes src/fsutil/xfs.c | 397 + src/fsutil/xfs.h | 71 + src/gboot/checksum.dat | 2 + src/gboot/clears.inc | 50 + src/gboot/copyr.inc | 312 + src/gboot/diag.inc | 132 + src/gboot/gboot.asm | 1175 ++ src/gboot/gboot.asm$ | 793 + src/gboot/gboot.lnk | 6 + src/gboot/io64180.inc | 155 + src/gboot/n.bat | 25 + src/hello/build-b.ban | 17 + src/hello/build-l.ban | 17 + src/hello/hello-b | Bin 0 -> 4833 bytes src/hello/hello-b.lnk | 13 + src/hello/hello-l | Bin 0 -> 4512 bytes src/hello/hello-l.lnk | 11 + src/hello/hello.c | 7 + src/hello/n.bat | 14 + src/init/build-b.ban | 28 + src/init/build-l.ban | 28 + src/init/init.c | 460 + src/init/login.c | 101 + src/init/n.bat | 16 + src/kernel/build.ban | 280 + src/kernel/cmx/apibus.asm | 557 + src/kernel/cmx/asci.asm | 473 + src/kernel/cmx/bstartup.asm | 442 + src/kernel/cmx/cmx_init.c | 658 + src/kernel/cmx/cmxbug.c | 1865 +++ src/kernel/cmx/cmxbug.h | 33 + src/kernel/cmx/cmxintb.asm | 114 + src/kernel/cmx/cmxio3.c | 665 + src/kernel/cmx/cmxtrack.c | 1466 ++ src/kernel/cmx/cmxtrack.h | 92 + src/kernel/cmx/cmxtrack.txt | 82 + src/kernel/cmx/copyr.asm | 310 + src/kernel/cmx/cxconfig.h | 58 + src/kernel/cmx/cxdefine.h | 47 + src/kernel/cmx/cxextern.h | 52 + src/kernel/cmx/cxfuncs.h | 217 + src/kernel/cmx/cxskv5b.asm | 645 + src/kernel/cmx/cxstruct.h | 104 + src/kernel/cmx/cxvendor.h | 241 + src/kernel/cmx/cxver5.c | 2033 +++ src/kernel/cmx/diag.asm | 157 + src/kernel/cmx/escc.asm | 980 ++ src/kernel/cmx/io64180.h | 134 + src/kernel/cmx/io64180.inc | 155 + src/kernel/kernel.lnk | 53 + src/kernel/libc/_exit.asm | 69 + src/kernel/libc/abort.c | 27 + src/kernel/libc/c0k.asm | 240 + src/kernel/libc/exit.c | 14 + src/kernel/libc/itoa.c | 213 + src/kernel/libc/itoa.h | 11 + src/kernel/libc/kprintf.c | 56 + src/kernel/libc/kprintf.h | 9 + src/kernel/libc/ltoa.c | 33 + src/kernel/libc/ltoa.h | 9 + src/kernel/libc/memcpy.c | 53 + src/kernel/libc/memcpy.h | 9 + src/kernel/libc/strcat.c | 29 + src/kernel/libc/strcat.h | 9 + src/kernel/libc/strcpy.c | 29 + src/kernel/libc/strcpy.h | 9 + src/kernel/libc/strlen.c | 43 + src/kernel/libc/strlen.h | 9 + src/kernel/libc/strncmp.c | 34 + src/kernel/libc/strncmp.h | 9 + src/kernel/libc/ultoa.c | 33 + src/kernel/libc/ultoa.h | 9 + src/kernel/libc/vendor.h | 14 + src/kernel/libc/vfprintf.c | 317 + src/kernel/libc/vfprintf.h | 9 + src/kernel/n.bat | 6 + src/kernel/uzi/asmdef.inc | 107 + src/kernel/uzi/config.h | 91 + src/kernel/uzi/data.c | 214 + src/kernel/uzi/devflop.c | 141 + src/kernel/uzi/devhd.c | 241 + src/kernel/uzi/devhd.h | 13 + src/kernel/uzi/devio.c | 577 + src/kernel/uzi/devio.c$ | 499 + src/kernel/uzi/devio.h | 38 + src/kernel/uzi/devio.h$ | 36 + src/kernel/uzi/devmisc.c | 134 + src/kernel/uzi/devmisc.h | 18 + src/kernel/uzi/devmt.c$ | 38 + src/kernel/uzi/devtty.c | 502 + src/kernel/uzi/devtty.h | 68 + src/kernel/uzi/dispatch | 40 + src/kernel/uzi/emu.asm | 1389 ++ src/kernel/uzi/extern.h | 150 + src/kernel/uzi/filesys.c | 1599 ++ src/kernel/uzi/filesys.h | 42 + src/kernel/uzi/flopasm.asm | 714 + src/kernel/uzi/hdasm.asm | 234 + src/kernel/uzi/hdconf.h | 72 + src/kernel/uzi/machasm.asm | 1590 ++ src/kernel/uzi/machdep.c | 313 + src/kernel/uzi/main.c | 803 + src/kernel/uzi/procasm.asm | 770 + src/kernel/uzi/process.c | 701 + src/kernel/uzi/scall1.c | 1452 ++ src/kernel/uzi/scall1.h | 46 + src/kernel/uzi/scall2.c | 639 + src/kernel/uzi/scall2.h | 25 + src/kernel/uzi/scall3.c | 1047 ++ src/kernel/uzi/scall3.h | 26 + src/kernel/uzi/startasm.asm | 71 + src/kernel/uzi/systrace.c | 362 + src/kernel/uzi/unix.h | 1011 ++ src/kernel/uzi/utils.asm | 630 + src/kernel/uzi/vendor.h | 87 + src/kernel/uzi/xip.c | 1394 ++ src/kernel/uzi/xip.h | 30 + src/kernel/uzi/z180.inc | 88 + src/libc/!readme! | 410 + src/libc/N9.PMM | 9 + src/libc/T | 1 + src/libc/abort.c | 16 + src/libc/alloca-l.h | 55 + src/libc/alloca.c | 53 + src/libc/asctime.c | 59 + src/libc/assert.c | 30 + src/libc/atexit.c | 71 + src/libc/atoi.c | 14 + src/libc/atol.c | 14 + src/libc/bsearch.c | 37 + src/libc/build-b.ban | 997 ++ src/libc/build-l.ban | 997 ++ src/libc/c0b.asm | 305 + src/libc/c0l.asm | 305 + src/libc/c0u.asm | 172 + src/libc/c9.pmm | 7 + src/libc/calloc.c | 28 + src/libc/clock.c | 15 + src/libc/closedir.c | 26 + src/libc/convtime.c | 64 + src/libc/crypt.c | 64 + src/libc/cstartup.r01 | Bin 0 -> 1537 bytes src/libc/ctime.c | 11 + src/libc/ctype.c | 67 + src/libc/cvt.h | 21 + src/libc/difftime.c | 22 + src/libc/environ.h | 12 + src/libc/error.c | 57 + src/libc/etime.c | 83 + src/libc/exec.h | 112 + src/libc/execl.c | 65 + src/libc/execle.c | 26 + src/libc/execlp.c | 21 + src/libc/execlpe.c | 26 + src/libc/exect.c | 18 + src/libc/execv.c | 17 + src/libc/execvp.c | 17 + src/libc/execvpe.c | 18 + src/libc/exit.c | 14 + src/libc/fclose.c | 48 + src/libc/fflush.c | 71 + src/libc/fgetc.c | 44 + src/libc/fgetgren.c | 17 + src/libc/fgetpwen.c | 17 + src/libc/fgets.c | 36 + src/libc/fopen.c | 131 + src/libc/fprintf.c | 36 + src/libc/fputc.c | 49 + src/libc/fputs.c | 27 + src/libc/fread.c | 62 + src/libc/free.c | 37 + src/libc/free.c$ | 148 + src/libc/fscanf.c | 25 + src/libc/ftell.c | 20 + src/libc/fwrite.c | 70 + src/libc/getcwd.c | 103 + src/libc/getenv.c | 27 + src/libc/getgrent.c | 87 + src/libc/getgrgid.c | 21 + src/libc/getgrnam.c | 25 + src/libc/getopt.c | 66 + src/libc/getpass.c | 70 + src/libc/getpw.c | 29 + src/libc/getpwent.c | 70 + src/libc/getpwnam.c | 27 + src/libc/getpwuid.c | 21 + src/libc/gets.c | 39 + src/libc/gmtime.c | 141 + src/libc/grp-l.h | 21 + src/libc/initgrup.c | 35 + src/libc/isatty.c | 13 + src/libc/itoa.c | 199 + src/libc/libcb.lib | 142 + src/libc/libcl.lib | 142 + src/libc/liberror.src | 42 + src/libc/localtim.c | 14 + src/libc/longjmpb.asm | 69 + src/libc/longjmpl.asm | 21 + src/libc/lsearch.c | 39 + src/libc/lseek.c$ | 32 + src/libc/lstat.c | 21 + src/libc/ltoa.c | 22 + src/libc/ltostr.c | 24 + src/libc/malloc-l.h | 29 + src/libc/malloc-l.h$ | 53 + src/libc/malloc.c | 64 + src/libc/malloc.c$ | 305 + src/libc/mem-l.h | 16 + src/libc/memccpy.c | 25 + src/libc/memchr.c | 26 + src/libc/memcmp.c | 66 + src/libc/memcpy.c | 43 + src/libc/memmove.c | 76 + src/libc/memset.c | 51 + src/libc/mkdir.c | 12 + src/libc/mktime.c | 18 + src/libc/n.bat | 12 + src/libc/n.xlb | 142 + src/libc/opendir.c | 40 + src/libc/passwd.h | 28 + src/libc/perror.asm | 132 + src/libc/perror.c | 29 + src/libc/popen.c | 52 + src/libc/printf.c | 36 + src/libc/printf.h | 39 + src/libc/putenv.c | 55 + src/libc/putgetch.c | 28 + src/libc/putpwent.c | 23 + src/libc/qsort.c | 141 + src/libc/rand.c | 70 + src/libc/readdir.c | 34 + src/libc/readlink.c | 20 + src/libc/realloc.c | 30 + src/libc/realloc.c$ | 32 + src/libc/regerror.c | 18 + src/libc/regexp.c | 1086 ++ src/libc/regsub.c | 80 + src/libc/rename.c | 16 + src/libc/rewind.c | 54 + src/libc/rewindir.c | 22 + src/libc/rmdir.c | 51 + src/libc/scanf.c | 24 + src/libc/scanf.h | 27 + src/libc/setbuff.c | 36 + src/libc/setenv.c | 88 + src/libc/setgrent.c | 33 + src/libc/setjmp.c$ | 48 + src/libc/setjmp.msx | 126 + src/libc/setjmp.r01 | Bin 0 -> 513 bytes src/libc/setjmpb.asm | 64 + src/libc/setjmpl.asm | 21 + src/libc/setpwent.c | 35 + src/libc/setvbuff.c | 38 + src/libc/sleep.c | 26 + src/libc/sprintf.c | 43 + src/libc/sscanf.c | 31 + src/libc/stdio-l.h | 50 + src/libc/stdio0.c | 69 + src/libc/strcat.c | 19 + src/libc/strchr.c | 26 + src/libc/strcmp.c | 22 + src/libc/strcpy.c | 18 + src/libc/strcspn.c | 29 + src/libc/strdup.c | 23 + src/libc/stricmp.c | 29 + src/libc/string-l.h | 34 + src/libc/strlen.c | 33 + src/libc/strncat.c | 26 + src/libc/strncmp.c | 24 + src/libc/strncpy.c | 28 + src/libc/strnicmp.c | 31 + src/libc/strpbrk.c | 24 + src/libc/strrchr.c | 27 + src/libc/strsep.c | 27 + src/libc/strspn.c | 33 + src/libc/strstr.c | 57 + src/libc/strtod.c | 96 + src/libc/strtok.c | 54 + src/libc/strtol.c | 30 + src/libc/strtoul.c | 74 + src/libc/system.c | 42 + src/libc/termcap.c | 651 + src/libc/termcap.src | 225 + src/libc/time-l.h | 24 + src/libc/tmpnam.c | 48 + src/libc/tparam.c | 286 + src/libc/ttyname.c | 45 + src/libc/tzset.c | 35 + src/libc/ultoa.c | 22 + src/libc/ungetc.c | 30 + src/libc/unix.h$ | 440 + src/libc/utsname.c | 39 + src/libc/vfprintf.c | 285 + src/libc/vfscanf.c | 375 + src/libc/vprintf.c | 25 + src/libc/vscanf.c | 14 + src/libc/vsprintf.c | 36 + src/libc/vsscanf.c | 21 + src/libc/x.bat | 12 + src/libc/xitoa.c | 14 + src/libc/xltoa.c | 20 + src/libiar/BANKCALL.asm | 18 + src/libiar/BANKCALLDIRECT.asm | 43 + src/libiar/BANKCALLDIRECTEXAF.asm | 17 + src/libiar/BANKCALLEXAF.asm | 18 + src/libiar/BANKLEAVE.asm | 18 + src/libiar/BANKLEAVE32.asm | 17 + src/libiar/BANKLEAVEDIRECT.asm | 41 + src/libiar/BFCANDASG.asm | 22 + src/libiar/BFCLSHASG.asm | 22 + src/libiar/BFCMULASG.asm | 22 + src/libiar/BFCORASG.asm | 22 + src/libiar/BFCRETVAL.asm | 31 + src/libiar/BFCSHIFTUP.asm | 18 + src/libiar/BFCXORASG.asm | 22 + src/libiar/BFMASKEDLD.asm | 17 + src/libiar/BFMASKEDST.asm | 19 + src/libiar/BFSADDASG.asm | 24 + src/libiar/BFSANDASG.asm | 24 + src/libiar/BFSCDIVASG.asm | 28 + src/libiar/BFSCEXT.asm | 18 + src/libiar/BFSCLDSHIFTDOWN.asm | 22 + src/libiar/BFSCMODASG.asm | 28 + src/libiar/BFSCRSHASG.asm | 26 + src/libiar/BFSLSHASG.asm | 26 + src/libiar/BFSMULASG.asm | 24 + src/libiar/BFSNEGASG.asm | 24 + src/libiar/BFSORASG.asm | 24 + src/libiar/BFSPOSTDEC.asm | 24 + src/libiar/BFSPOSTINC.asm | 24 + src/libiar/BFSPREDEC.asm | 24 + src/libiar/BFSPREINC.asm | 24 + src/libiar/BFSRETVAL.asm | 40 + src/libiar/BFSSDIVASG.asm | 29 + src/libiar/BFSSEXT.asm | 22 + src/libiar/BFSSHIFTUP.asm | 18 + src/libiar/BFSSLDSHIFTDOWN.asm | 25 + src/libiar/BFSSMODASG.asm | 29 + src/libiar/BFSSRSHASG.asm | 29 + src/libiar/BFSSUBASG.asm | 24 + src/libiar/BFSXORASG.asm | 24 + src/libiar/BFUCDIVASG.asm | 28 + src/libiar/BFUCLDSHIFTDOWN.asm | 20 + src/libiar/BFUCMODASG.asm | 28 + src/libiar/BFUCRSHASG.asm | 22 + src/libiar/BFUSDIVASG.asm | 29 + src/libiar/BFUSLDSHIFTDOWN.asm | 22 + src/libiar/BFUSMODASG.asm | 29 + src/libiar/BFUSRSHASG.asm | 26 + src/libiar/CALLIND.asm | 16 + src/libiar/CDIVMOD.asm | 18 + src/libiar/CFINDSIGN.asm | 18 + src/libiar/CLSH.asm | 16 + src/libiar/CLSHASG.asm | 19 + src/libiar/CMUL.asm | 16 + src/libiar/CMULASG.asm | 19 + src/libiar/CSSWITCH.asm | 19 + src/libiar/CVSWITCH.asm | 20 + src/libiar/ENTAUTO.asm | 18 + src/libiar/ENTAUTODIRECT.asm | 18 + src/libiar/ENTPARM.asm | 18 + src/libiar/ENTPARMDIRECT.asm | 17 + src/libiar/FADDASG.asm | 22 + src/libiar/FADDSUB.asm | 75 + src/libiar/FCMP.asm | 28 + src/libiar/FDEC.asm | 20 + src/libiar/FDECASG.asm | 21 + src/libiar/FDIV.asm | 59 + src/libiar/FDIVASG.asm | 22 + src/libiar/FENDASG2.asm | 17 + src/libiar/FINC.asm | 20 + src/libiar/FINCASG.asm | 21 + src/libiar/FMUL.asm | 64 + src/libiar/FMULASG.asm | 22 + src/libiar/FNEGASG.asm | 19 + src/libiar/FPACK.asm | 32 + src/libiar/FROUND.asm | 30 + src/libiar/FSUBASG.asm | 22 + src/libiar/FTOL.asm | 34 + src/libiar/FUNPACK.asm | 25 + src/libiar/LADDASG.asm | 19 + src/libiar/LAND.asm | 20 + src/libiar/LANDASG.asm | 19 + src/libiar/LDEC.asm | 17 + src/libiar/LDECASG.asm | 22 + src/libiar/LDIVMOD.asm | 28 + src/libiar/LEAVE.asm | 16 + src/libiar/LEAVE32.asm | 17 + src/libiar/LEAVEDIRECT.asm | 16 + src/libiar/LENDASG.asm | 17 + src/libiar/LENDMULDIVASG.asm | 17 + src/libiar/LFINDSIGN.asm | 33 + src/libiar/LIBVERSION.asm | 15 + src/libiar/LINC.asm | 17 + src/libiar/LINCASG.asm | 22 + src/libiar/LLSH.asm | 19 + src/libiar/LLSHASG.asm | 22 + src/libiar/LMUL.asm | 35 + src/libiar/LMULASG.asm | 22 + src/libiar/LNEG.asm | 18 + src/libiar/LNEGASG.asm | 22 + src/libiar/LNOT.asm | 18 + src/libiar/LNOTASG.asm | 22 + src/libiar/LOR.asm | 20 + src/libiar/LORASG.asm | 19 + src/libiar/LSSWITCH.asm | 22 + src/libiar/LSUBASG.asm | 19 + src/libiar/LTOF.asm | 31 + src/libiar/LVSWITCH.asm | 26 + src/libiar/LXOR.asm | 20 + src/libiar/LXORASG.asm | 19 + src/libiar/MEMCMP.asm | 20 + src/libiar/MEMSET.asm | 19 + src/libiar/MONITOR.asm | 40 + src/libiar/MONITORBANKLEAVE.asm | 20 + src/libiar/MONITORBANKLEAVE32.asm | 21 + src/libiar/MONITORBANKLEAVEIX.asm | 20 + src/libiar/MONITORBANKLEAVEPOP.asm | 21 + src/libiar/MONITORLEAVE.asm | 16 + src/libiar/MONITORLEAVE32.asm | 17 + src/libiar/MONITORLEAVEIX.asm | 17 + src/libiar/MONITORLEAVEIXPA.asm | 17 + src/libiar/MONITORLEAVEPA.asm | 16 + src/libiar/MONITORLEAVEPOP.asm | 17 + src/libiar/SCDIV.asm | 23 + src/libiar/SCMOD.asm | 23 + src/libiar/SCRSH.asm | 17 + src/libiar/SCRSHASG.asm | 19 + src/libiar/SDIVMOD.asm | 19 + src/libiar/SFINDSIGN.asm | 19 + src/libiar/SLCMP.asm | 22 + src/libiar/SLDIV.asm | 31 + src/libiar/SLDIVASG.asm | 22 + src/libiar/SLMOD.asm | 32 + src/libiar/SLMODASG.asm | 22 + src/libiar/SLRSH.asm | 17 + src/libiar/SLRSHASG.asm | 22 + src/libiar/SLSH.asm | 17 + src/libiar/SLSHASG.asm | 19 + src/libiar/SLSHASGBCprim.asm | 18 + src/libiar/SLSHASGDEprim.asm | 17 + src/libiar/SMUL.asm | 19 + src/libiar/SMULASG.asm | 19 + src/libiar/SMULASGBCprim.asm | 19 + src/libiar/SMULASGDEprim.asm | 19 + src/libiar/SMULASGIX.asm | 19 + src/libiar/SMULASGIY.asm | 19 + src/libiar/SSCMP.asm | 18 + src/libiar/SSDIV.asm | 24 + src/libiar/SSDIVASG.asm | 19 + src/libiar/SSDIVASGBCprim.asm | 20 + src/libiar/SSDIVASGDEprim.asm | 19 + src/libiar/SSDIVASGIX.asm | 19 + src/libiar/SSDIVASGIY.asm | 19 + src/libiar/SSMOD.asm | 24 + src/libiar/SSMODASG.asm | 19 + src/libiar/SSMODASGBCprim.asm | 20 + src/libiar/SSMODASGDEprim.asm | 19 + src/libiar/SSMODASGIX.asm | 19 + src/libiar/SSMODASGIY.asm | 19 + src/libiar/SSRSH.asm | 17 + src/libiar/SSRSHASG.asm | 19 + src/libiar/SSRSHASGBCprim.asm | 18 + src/libiar/SSRSHASGDEprim.asm | 18 + src/libiar/SSRSHASGIX.asm | 19 + src/libiar/SSRSHASGIY.asm | 19 + src/libiar/SSSWITCH.asm | 20 + src/libiar/SSWITCHEND.asm | 17 + src/libiar/STRCAT.asm | 18 + src/libiar/STRCHR.asm | 17 + src/libiar/STRCMP.asm | 18 + src/libiar/STRCPY.asm | 18 + src/libiar/STRLEN.asm | 18 + src/libiar/SVSWITCH.asm | 21 + src/libiar/UCDIV.asm | 19 + src/libiar/UCMOD.asm | 19 + src/libiar/UCRSH.asm | 17 + src/libiar/UCRSHASG.asm | 19 + src/libiar/ULDIV.asm | 25 + src/libiar/ULDIVASG.asm | 22 + src/libiar/ULMOD.asm | 23 + src/libiar/ULMODASG.asm | 22 + src/libiar/ULRSH.asm | 19 + src/libiar/ULRSHASG.asm | 22 + src/libiar/USDIV.asm | 20 + src/libiar/USDIVASG.asm | 19 + src/libiar/USDIVASGBCprim.asm | 20 + src/libiar/USDIVASGDEprim.asm | 19 + src/libiar/USDIVASGIX.asm | 19 + src/libiar/USDIVASGIY.asm | 19 + src/libiar/USMOD.asm | 19 + src/libiar/USMODASG.asm | 19 + src/libiar/USMODASGBCprim.asm | 20 + src/libiar/USMODASGDEprim.asm | 19 + src/libiar/USMODASGIX.asm | 19 + src/libiar/USMODASGIY.asm | 19 + src/libiar/USRSH.asm | 17 + src/libiar/USRSHASG.asm | 19 + src/libiar/USRSHASGBCprim.asm | 18 + src/libiar/USRSHASGDEprim.asm | 18 + src/libiar/USRSHASGIX.asm | 19 + src/libiar/USRSHASGIY.asm | 19 + src/libiar/VSWITCHEND.asm | 17 + src/libiar/abort.asm | 27 + src/libiar/abs.asm | 25 + src/libiar/acos.asm | 44 + src/libiar/asin.asm | 88 + src/libiar/assert.asm | 50 + src/libiar/atan.asm | 34 + src/libiar/atan2.asm | 79 + src/libiar/atof.asm | 112 + src/libiar/atoi.asm | 42 + src/libiar/atol.asm | 54 + src/libiar/bsearch.asm | 51 + src/libiar/build.ban | 1018 ++ src/libiar/calloc.asm | 47 + src/libiar/ceil.asm | 33 + src/libiar/cos.asm | 31 + src/libiar/cosh.asm | 64 + src/libiar/ctype.asm | 38 + src/libiar/daddexp.asm | 19 + src/libiar/div.asm | 36 + src/libiar/errno.asm | 19 + src/libiar/exit0.asm | 22 + src/libiar/exit1.asm | 22 + src/libiar/exit2.asm | 22 + src/libiar/exp.asm | 118 + src/libiar/exp10.asm | 45 + src/libiar/fabs.asm | 23 + src/libiar/floor.asm | 55 + src/libiar/fmod.asm | 58 + src/libiar/formattedread.asm | 597 + src/libiar/formattedwrite.asm | 612 + src/libiar/free.asm | 70 + src/libiar/frexp.asm | 31 + src/libiar/getchar.asm | 119 + src/libiar/getchar0.asm | 22 + src/libiar/getchar1.asm | 23 + src/libiar/getchar2.asm | 23 + src/libiar/gets.asm | 36 + src/libiar/heap.asm | 34 + src/libiar/isalnum.asm | 27 + src/libiar/isalpha.asm | 27 + src/libiar/iscntrl.asm | 27 + src/libiar/isdigit.asm | 27 + src/libiar/isgraph.asm | 27 + src/libiar/islower.asm | 27 + src/libiar/isprint.asm | 27 + src/libiar/ispunct.asm | 27 + src/libiar/isspace.asm | 27 + src/libiar/isupper.asm | 27 + src/libiar/isxdigit.asm | 27 + src/libiar/labs.asm | 26 + src/libiar/largectype.asm | 58 + src/libiar/ldexp.asm | 57 + src/libiar/ldiv.asm | 46 + src/libiar/libiar.lib | 195 + src/libiar/log.asm | 103 + src/libiar/log10.asm | 48 + src/libiar/longjmp.asm | 23 + src/libiar/longjmp2.asm | 28 + src/libiar/malloc.asm | 85 + src/libiar/mediumread.asm | 369 + src/libiar/mediumwrite.asm | 372 + src/libiar/memchr.asm | 29 + src/libiar/memcmplc.asm | 27 + src/libiar/memcpy.asm | 26 + src/libiar/memmove.asm | 46 + src/libiar/memsetlc.asm | 27 + src/libiar/modf.asm | 45 + src/libiar/n.bat | 4 + src/libiar/pow.asm | 182 + src/libiar/printf.asm | 51 + src/libiar/putchar.asm | 23 + src/libiar/putchar0.asm | 22 + src/libiar/putchar1.asm | 23 + src/libiar/putchar2.asm | 23 + src/libiar/puts.asm | 39 + src/libiar/qsort.asm | 192 + src/libiar/rand.asm | 42 + src/libiar/realloc.asm | 162 + src/libiar/satan.asm | 97 + src/libiar/scanf.asm | 59 + src/libiar/setjmp.asm | 23 + src/libiar/silly.zip | Bin 0 -> 158858 bytes src/libiar/sin.asm | 31 + src/libiar/sinh.asm | 69 + src/libiar/sinus.asm | 140 + src/libiar/smallwrite.asm | 155 + src/libiar/sprintf.asm | 46 + src/libiar/sqrt.asm | 90 + src/libiar/srand.asm | 28 + src/libiar/sscanf.asm | 37 + src/libiar/strcatlc.asm | 27 + src/libiar/strchrlc.asm | 26 + src/libiar/strcmplc.asm | 26 + src/libiar/strcoll.asm | 26 + src/libiar/strcpylc.asm | 27 + src/libiar/strcspn.asm | 32 + src/libiar/strerror.asm | 70 + src/libiar/strlenlc.asm | 26 + src/libiar/strncat.asm | 33 + src/libiar/strncmp.asm | 31 + src/libiar/strncpy.asm | 34 + src/libiar/strpbrk.asm | 30 + src/libiar/strrchr.asm | 28 + src/libiar/strspn.asm | 32 + src/libiar/strstr.asm | 32 + src/libiar/strtod.asm | 235 + src/libiar/strtok.asm | 69 + src/libiar/strtol.asm | 145 + src/libiar/strtoul.asm | 136 + src/libiar/strxfrm.asm | 36 + src/libiar/tan.asm | 114 + src/libiar/tanh.asm | 74 + src/libiar/tolower.asm | 30 + src/libiar/toupper.asm | 30 + src/libiar/vprintf.asm | 46 + src/libiar/vsprintf.asm | 44 + src/libsys/!readme! | 354 + src/libsys/_exit.c | 27 + src/libsys/access.c | 23 + src/libsys/alarm.c | 23 + src/libsys/brk.c | 21 + src/libsys/build-b.ban | 410 + src/libsys/build-l.ban | 410 + src/libsys/chdir.c | 21 + src/libsys/chmod.c | 21 + src/libsys/chown.c | 24 + src/libsys/chroot.c | 21 + src/libsys/close.c | 21 + src/libsys/creat.c | 17 + src/libsys/dup.c | 21 + src/libsys/dup2.c | 21 + src/libsys/execve.c | 24 + src/libsys/falign.c | 21 + src/libsys/fork.c | 21 + src/libsys/fstat.c | 21 + src/libsys/getegid.c | 31 + src/libsys/geteuid.c | 31 + src/libsys/getfsys.c | 21 + src/libsys/getgid.c | 31 + src/libsys/getpid.c | 31 + src/libsys/getppid.c | 31 + src/libsys/getprio.c | 31 + src/libsys/getuid.c | 31 + src/libsys/ioctl.c | 49 + src/libsys/kill.c | 21 + src/libsys/libsysb.lib | 58 + src/libsys/libsysl.lib | 58 + src/libsys/link.c | 21 + src/libsys/lseek.c | 61 + src/libsys/mkfifo.c | 14 + src/libsys/mknod.c | 24 + src/libsys/module.c | 159 + src/libsys/mount.c | 24 + src/libsys/n.bat | 12 + src/libsys/open.c | 49 + src/libsys/pause.c | 23 + src/libsys/pipe.c | 23 + src/libsys/read.c | 26 + src/libsys/reboot.c | 26 + src/libsys/sbrk.c | 23 + src/libsys/seek.c | 61 + src/libsys/setgid.c | 32 + src/libsys/setprio.c | 32 + src/libsys/setuid.c | 32 + src/libsys/signal.c | 24 + src/libsys/stat.c | 23 + src/libsys/stime.c | 23 + src/libsys/symlink.c | 21 + src/libsys/sync.c | 23 + src/libsys/sys0b.asm | 45 + src/libsys/sys0l.asm | 43 + src/libsys/sys1b.asm | 47 + src/libsys/sys1l.asm | 45 + src/libsys/syscalls.h | 82 + src/libsys/systrace.c | 32 + src/libsys/time.c | 35 + src/libsys/times.c | 23 + src/libsys/umask.c | 32 + src/libsys/umount.c | 23 + src/libsys/unlink.c | 23 + src/libsys/utime.c | 23 + src/libsys/waitpid.c | 24 + src/libsys/write.c | 26 + src/link-z80/aslink.h | 908 ++ src/link-z80/link-z80.exe | Bin 0 -> 106545 bytes src/link-z80/link-z80.lnk | 16 + src/link-z80/lkarea.c | 607 + src/link-z80/lkdata.c | 509 + src/link-z80/lkeval.c | 443 + src/link-z80/lkhead.c | 164 + src/link-z80/lklex.c | 537 + src/link-z80/lklibr.c | 626 + src/link-z80/lklist.c | 1007 ++ src/link-z80/lkmain.c | 1563 ++ src/link-z80/lkout.c | 576 + src/link-z80/lkrloc.c | 1527 ++ src/link-z80/lksym.c | 768 + src/link-z80/n.bat | 32 + src/link-z80/x.bat | 9 + src/make-3.80/ABOUT-NLS | 435 + src/make-3.80/AUTHORS | 57 + src/make-3.80/COPYING | 340 + src/make-3.80/ChangeLog | 857 ++ src/make-3.80/INSTALL | 187 + src/make-3.80/Makefile.DOS | 693 + src/make-3.80/Makefile.am | 162 + src/make-3.80/Makefile.ami | 305 + src/make-3.80/Makefile.in | 925 ++ src/make-3.80/NEWS | 859 ++ src/make-3.80/NMakefile | 250 + src/make-3.80/NMakefile$ | 248 + src/make-3.80/README | 164 + src/make-3.80/README.Amiga | 61 + src/make-3.80/README.DOS | 323 + src/make-3.80/README.W32 | 241 + src/make-3.80/README.customs | 95 + src/make-3.80/SCOPTIONS | 13 + src/make-3.80/SMakefile | 338 + src/make-3.80/acinclude.m4 | 164 + src/make-3.80/aclocal.m4 | 3053 ++++ src/make-3.80/alloca.c | 504 + src/make-3.80/amiga.c | 123 + src/make-3.80/amiga.h | 22 + src/make-3.80/ar.c | 329 + src/make-3.80/arscan.c | 861 ++ src/make-3.80/build.sh.in | 80 + src/make-3.80/build_w32.bat | 138 + src/make-3.80/commands.c | 584 + src/make-3.80/commands.h | 42 + src/make-3.80/config.ami | 317 + src/make-3.80/config.h | 399 + src/make-3.80/config.h-vms | 403 + src/make-3.80/config.h.W32 | 399 + src/make-3.80/config.h.in | 391 + src/make-3.80/configh.dos | 94 + src/make-3.80/configure | 12603 ++++++++++++++++ src/make-3.80/configure.bat | 44 + src/make-3.80/configure.in | 390 + src/make-3.80/debug.h | 41 + src/make-3.80/default.c | 585 + src/make-3.80/dep.h | 78 + src/make-3.80/dir.c | 1212 ++ src/make-3.80/dosbuild.bat | 42 + src/make-3.80/expand.c | 566 + src/make-3.80/file.c | 827 + src/make-3.80/filedef.h | 199 + src/make-3.80/function.c | 2076 +++ src/make-3.80/getloadavg.c | 1034 ++ src/make-3.80/getopt.c | 1047 ++ src/make-3.80/getopt.h | 133 + src/make-3.80/getopt1.c | 190 + src/make-3.80/gettext.h | 59 + src/make-3.80/glob/COPYING.LIB | 481 + src/make-3.80/glob/ChangeLog | 136 + src/make-3.80/glob/Makefile.am | 14 + src/make-3.80/glob/Makefile.ami | 69 + src/make-3.80/glob/Makefile.in | 399 + src/make-3.80/glob/SCOPTIONS | 13 + src/make-3.80/glob/SMakefile | 69 + src/make-3.80/glob/configure.bat | 26 + src/make-3.80/glob/fnmatch.c | 488 + src/make-3.80/glob/fnmatch.h | 84 + src/make-3.80/glob/glob.c | 1428 ++ src/make-3.80/glob/glob.h | 205 + src/make-3.80/hash.c | 369 + src/make-3.80/hash.h | 233 + src/make-3.80/implicit.c | 635 + src/make-3.80/job.c | 3110 ++++ src/make-3.80/job.h | 83 + src/make-3.80/link.dbg | 28 + src/make-3.80/loadavg.c | 1034 ++ src/make-3.80/main.c | 2813 ++++ src/make-3.80/make.1 | 291 + src/make-3.80/make.h | 562 + src/make-3.80/make.lnk | 5 + src/make-3.80/makefile.com | 138 + src/make-3.80/makefile.vms | 147 + src/make-3.80/misc.c | 893 ++ src/make-3.80/n.bat | 21 + src/make-3.80/read.c | 3105 ++++ src/make-3.80/readme.vms | 183 + src/make-3.80/remake.c | 1420 ++ src/make-3.80/remote-cstms.c | 310 + src/make-3.80/remote-stub.c | 109 + src/make-3.80/respf.$$$ | 23 + src/make-3.80/rule.c | 717 + src/make-3.80/rule.h | 72 + src/make-3.80/signame.c | 255 + src/make-3.80/subproc.bat | 6 + src/make-3.80/variable.c | 1263 ++ src/make-3.80/variable.h | 183 + src/make-3.80/version.c | 17 + src/make-3.80/vmsdir.h | 61 + src/make-3.80/vmsfunctions.c | 261 + src/make-3.80/vmsify.c | 981 ++ src/make-3.80/vpath.c | 587 + src/make-3.80/w32/compat/dirent.c | 188 + src/make-3.80/w32/include/dirent.h | 37 + src/make-3.80/w32/include/pathstuff.h | 9 + src/make-3.80/w32/include/sub_proc.h | 47 + src/make-3.80/w32/include/w32err.h | 10 + src/make-3.80/w32/pathstuff.c | 238 + src/make-3.80/w32/subproc/NMakefile | 60 + src/make-3.80/w32/subproc/build.bat | 10 + src/make-3.80/w32/subproc/misc.c | 65 + src/make-3.80/w32/subproc/proc.h | 13 + src/make-3.80/w32/subproc/sub_proc.c | 1207 ++ src/make-3.80/w32/subproc/w32err.c | 51 + src/make-3.80/x.bat | 15 + src/man/apropo-b.lnk | 14 + src/man/apropo-l.lnk | 12 + src/man/apropos.c | 224 + src/man/build-b.ban | 45 + src/man/build-l.ban | 45 + src/man/catman-b.lnk | 14 + src/man/catman-l.lnk | 12 + src/man/catman.8 | 119 + src/man/catman.bat | 47 + src/man/catman.c | 277 + src/man/man-b.lnk | 13 + src/man/man-l.lnk | 11 + src/man/man.c | 484 + src/man/mkwhatis.bat | 32 + src/man/mkwhatis.sed | 45 + src/man/mkwhatis.sh | 32 + src/man/n.bat | 23 + src/man/utils.c | 75 + src/man/utils.h | 14 + src/mkutil/4dos.com | Bin 0 -> 153314 bytes src/mkutil/bin2c.c | 131 + src/mkutil/bin2c.exe | Bin 0 -> 57388 bytes src/mkutil/crc.c | 18 + src/mkutil/crc.com | Bin 0 -> 5413 bytes src/mkutil/crcd.com | Bin 0 -> 1045 bytes src/mkutil/ihex2bin.c | 272 + src/mkutil/ihex2bin.exe | Bin 0 -> 57391 bytes src/mkutil/mklink-b.bat | 30 + src/mkutil/mklink-l.bat | 28 + src/mkutil/mknbat-b.bat | 34 + src/mkutil/mknbat-l.bat | 34 + src/mkutil/n.bat | 30 + src/mkutil/setfsize.c | 93 + src/mkutil/setfsize.exe | Bin 0 -> 57390 bytes src/mkutil/touch.c | 161 + src/mkutil/touch.exe | Bin 0 -> 61484 bytes src/sh/bsh/args.c | 135 + src/sh/bsh/blok.c | 116 + src/sh/bsh/brkincr.h | 3 + src/sh/bsh/bsh.lnk | 33 + src/sh/bsh/builtin.c | 3 + src/sh/bsh/cmd.c | 425 + src/sh/bsh/ctype.c | 110 + src/sh/bsh/ctype.h | 90 + src/sh/bsh/data.c | 89 + src/sh/bsh/defs.h | 302 + src/sh/bsh/dup.h | 13 + src/sh/bsh/error.c | 83 + src/sh/bsh/expand.c | 198 + src/sh/bsh/fault.c | 109 + src/sh/bsh/io.c | 138 + src/sh/bsh/junk/REPL8.PMM | 33 + src/sh/bsh/junk/REPL9X.PMM | 11 + src/sh/bsh/junk/REPL9Y.PMM | 105 + src/sh/bsh/junk/X.bat | 1 + src/sh/bsh/junk/makefile | 34 + src/sh/bsh/junk/nick.h | 82 + src/sh/bsh/junk/pre.bat | 3 + src/sh/bsh/junk/preall.bat | 32 + src/sh/bsh/junk/silly.c | 484 + src/sh/bsh/junk/silly.exe | Bin 0 -> 28672 bytes src/sh/bsh/junk/silly.zip | Bin 0 -> 33072 bytes src/sh/bsh/junk/silly1.zip | Bin 0 -> 78035 bytes src/sh/bsh/junk/silly2.zip | Bin 0 -> 187473 bytes src/sh/bsh/junk/silly3.zip | Bin 0 -> 559955 bytes src/sh/bsh/mac.h | 0 src/sh/bsh/macro.c | 234 + src/sh/bsh/main.c | 216 + src/sh/bsh/mode.h | 164 + src/sh/bsh/msg.c | 145 + src/sh/bsh/n.bat | 137 + src/sh/bsh/name.c | 320 + src/sh/bsh/name.h | 25 + src/sh/bsh/print.c | 98 + src/sh/bsh/service.c | 384 + src/sh/bsh/setbrk.c | 30 + src/sh/bsh/stak.c | 83 + src/sh/bsh/stak.h | 78 + src/sh/bsh/string.c | 57 + src/sh/bsh/sym.h | 47 + src/sh/bsh/timeout.h | 11 + src/sh/bsh/word.c | 133 + src/sh/bsh/xec.c | 423 + src/sh/msh/Makefile | 17 + src/sh/msh/msh.lnk | 18 + src/sh/msh/n.bat | 49 + src/sh/msh/sh.1 | 261 + src/sh/msh/sh.h | 400 + src/sh/msh/sh1.c | 970 ++ src/sh/msh/sh2.c | 801 + src/sh/msh/sh3.c | 1161 ++ src/sh/msh/sh4.c | 769 + src/sh/msh/sh5.c | 675 + src/sh/msh/sh6.c | 9 + src/sh/sash/build-b.ban | 59 + src/sh/sash/build-l.ban | 59 + src/sh/sash/cmd_dd.c | 226 + src/sh/sash/cmd_ed.c | 1227 ++ src/sh/sash/cmd_grep.c | 120 + src/sh/sash/cmd_ls.c | 347 + src/sh/sash/cmd_tar.c | 331 + src/sh/sash/cmds.c | 915 ++ src/sh/sash/n.bat | 14 + src/sh/sash/readme | 50 + src/sh/sash/sash-b.lnk | 20 + src/sh/sash/sash-l.lnk | 18 + src/sh/sash/sash.1 | 338 + src/sh/sash/sash.c | 1048 ++ src/sh/sash/sash.h | 97 + src/sh/sash/sashcfg.h | 89 + src/sh/sash/utils.c | 477 + src/simple/adduser.c | 185 + src/simple/align.c | 129 + src/simple/banner.c | 162 + src/simple/basename.c | 55 + src/simple/bogomips.c | 147 + src/simple/build-b.ban | 1042 ++ src/simple/build-l.ban | 1042 ++ src/simple/cal.c | 319 + src/simple/cat.c | 48 + src/simple/cdiff.c | 376 + src/simple/cgrep.c | 387 + src/simple/chgrp.c | 53 + src/simple/chmod.c | 110 + src/simple/chown.c | 53 + src/simple/cksum.c | 159 + src/simple/cmp.c | 100 + src/simple/cp.c | 1336 ++ src/simple/cr$.c | 50 + src/simple/cr.c | 126 + src/simple/crc.c | 177 + src/simple/cron.c | 370 + src/simple/date.c | 13 + src/simple/dd.c | 665 + src/simple/df.c | 170 + src/simple/dhry.c | 559 + src/simple/diff.c | 1268 ++ src/simple/dirname.c | 41 + src/simple/diskusag.c | 496 + src/simple/dosread.c | 1307 ++ src/simple/dtree.c | 652 + src/simple/du.c | 223 + src/simple/echo.c | 105 + src/simple/ed.c | 2196 +++ src/simple/expr.c | 648 + src/simple/false.c | 6 + src/simple/fgrep.c | 358 + src/simple/file.c | 285 + src/simple/find.c | 938 ++ src/simple/fld.c | 410 + src/simple/fortune.c | 101 + src/simple/grep.c | 717 + src/simple/gres.c | 189 + src/simple/head.c | 87 + src/simple/id.c | 55 + src/simple/inodes.c | 262 + src/simple/kill.c | 60 + src/simple/lpd.c | 435 + src/simple/lpr.c | 55 + src/simple/ls.c | 321 + src/simple/m.bat | 37 + src/simple/man.c$ | 1032 ++ src/simple/mkdir.c | 94 + src/simple/mknod.c | 67 + src/simple/more.c | 196 + src/simple/mount.c | 51 + src/simple/n.bat | 196 + src/simple/ncheck.c | 218 + src/simple/ncr$.c | 53 + src/simple/od.c | 347 + src/simple/passwd.c | 142 + src/simple/pathchk.c | 192 + src/simple/pr.c | 508 + src/simple/printenv.c | 38 + src/simple/ps.c | 240 + src/simple/pwd.c | 13 + src/simple/readall.c | 154 + src/simple/reboot.c | 29 + src/simple/renice.c | 102 + src/simple/rm.c | 265 + src/simple/rmdir.c | 63 + src/simple/roff.c | 1569 ++ src/simple/setclock.c | 97 + src/simple/sort.c | 1202 ++ src/simple/split.c | 133 + src/simple/su.c | 87 + src/simple/sum.c | 120 + src/simple/sync.c | 8 + src/simple/tail.c | 362 + src/simple/tar.c | 1200 ++ src/simple/tee.c | 32 + src/simple/ter.c | 178 + src/simple/termcap.c | 167 + src/simple/test.c | 360 + src/simple/tget.c | 111 + src/simple/time.c | 185 + src/simple/top.c | 434 + src/simple/touch.c | 158 + src/simple/tr.c | 376 + src/simple/true.c | 6 + src/simple/ualign.c | 129 + src/simple/umount.c | 73 + src/simple/uname.c | 65 + src/simple/uniq.c | 189 + src/simple/uudecode.c | 580 + src/simple/uuencode.c | 224 + src/simple/wc.c | 161 + src/simple/which.c | 79 + src/simple/whoami.c | 20 + src/simple/yes.c | 21 + src/troff/README | 18 + src/troff/d.h | 2 + src/troff/font/chars.c | 22 + src/troff/font/ftB.c | 136 + src/troff/font/ftBC.c | 137 + src/troff/font/ftC.c | 137 + src/troff/font/ftCE.c | 136 + src/troff/font/ftCI.c | 140 + src/troff/font/ftCK.c | 136 + src/troff/font/ftCS.c | 140 + src/troff/font/ftCW.c | 137 + src/troff/font/ftG.c | 136 + src/troff/font/ftGI.c | 135 + src/troff/font/ftGM.c | 136 + src/troff/font/ftGR.c | 137 + src/troff/font/ftI.c | 136 + src/troff/font/ftL.c | 138 + src/troff/font/ftLI.c | 138 + src/troff/font/ftPA.c | 136 + src/troff/font/ftPB.c | 136 + src/troff/font/ftPI.c | 136 + src/troff/font/ftR.c | 136 + src/troff/font/ftS.c | 135 + src/troff/font/ftSB.c | 138 + src/troff/font/ftSI.c | 138 + src/troff/font/ftSM.c | 138 + src/troff/font/ftUD.c | 136 + src/troff/font/ftXM.c | 138 + src/troff/font/linkrc | 7 + src/troff/font/makefile | 16 + src/troff/font/mkfont.c | 103 + src/troff/font/mkfont1.c | 369 + src/troff/hytab.c | 123 + src/troff/makefile | 18 + src/troff/n.bat | 135 + src/troff/n1.c | 1059 ++ src/troff/n10.c | 302 + src/troff/n2.c | 366 + src/troff/n3.c | 709 + src/troff/n4.c | 526 + src/troff/n5.c | 823 + src/troff/n6.c | 281 + src/troff/n7.c | 755 + src/troff/n8.c | 276 + src/troff/n9.c | 328 + src/troff/ni.c | 265 + src/troff/nii.c | 140 + src/troff/nmake | 32 + src/troff/nroff.exe | Bin 0 -> 143403 bytes src/troff/nroff.lnk | 27 + src/troff/nroff.w32 | 20 + src/troff/ntab.c | 135 + src/troff/s.h | 12 + src/troff/sh.1 | 261 + src/troff/suftab.c | 606 + src/troff/t10.c | 315 + src/troff/t6.c | 606 + src/troff/tab3.c | 892 ++ src/troff/tdef.h | 130 + src/troff/term/code.300 | 211 + src/troff/term/makefile | 14 + src/troff/term/n.bat | 20 + src/troff/term/tab300-12.c | 59 + src/troff/term/tab300.c | 59 + src/troff/term/tab300s-12.c | 59 + src/troff/term/tab300s.c | 59 + src/troff/term/tab37 | Bin 0 -> 1288 bytes src/troff/term/tab37.asm | 927 ++ src/troff/term/tab37.c | 270 + src/troff/term/tab37.lnk | 8 + src/troff/term/tab450-12-8.c | 60 + src/troff/term/tab450-12.c | 60 + src/troff/term/tab450.c | 59 + src/troff/term/tab832.c | 59 + src/troff/term/taba1.c | 59 + src/troff/term/tablp.c | 269 + src/troff/term/tabtn300.c | 269 + src/troff/textscript | 5 + src/troff/tmac/tmac.an | 267 + src/troff/tmac/tmac.an$ | 267 + src/troff/tmake | 32 + src/troff/tw.h | 59 + src/troff/v.h | 2 + 1679 files changed, 246789 insertions(+) create mode 100755 bin/banked/adduser create mode 100755 bin/banked/align create mode 100755 bin/banked/apropos create mode 100755 bin/banked/banner create mode 100755 bin/banked/basename create mode 100755 bin/banked/bsh create mode 100755 bin/banked/cal create mode 100755 bin/banked/cat create mode 100755 bin/banked/catman create mode 100755 bin/banked/cdiff create mode 100755 bin/banked/cgrep create mode 100755 bin/banked/chgrp create mode 100755 bin/banked/chmod create mode 100755 bin/banked/chown create mode 100755 bin/banked/cksum create mode 100755 bin/banked/cmp create mode 100755 bin/banked/cp create mode 100755 bin/banked/cr create mode 100755 bin/banked/crc create mode 100755 bin/banked/cron create mode 100755 bin/banked/date create mode 100755 bin/banked/dd create mode 100755 bin/banked/df create mode 100755 bin/banked/dhry create mode 100755 bin/banked/diff create mode 100755 bin/banked/dirname create mode 100755 bin/banked/diskusag create mode 100755 bin/banked/dtree create mode 100755 bin/banked/du create mode 100755 bin/banked/echo create mode 100755 bin/banked/ed create mode 100755 bin/banked/expr create mode 100755 bin/banked/false create mode 100755 bin/banked/fgrep create mode 100755 bin/banked/file create mode 100755 bin/banked/find create mode 100755 bin/banked/fld create mode 100755 bin/banked/fortune create mode 100755 bin/banked/grep create mode 100755 bin/banked/gres create mode 100755 bin/banked/head create mode 100755 bin/banked/id create mode 100755 bin/banked/init create mode 100755 bin/banked/inodes create mode 100755 bin/banked/kill create mode 100755 bin/banked/login create mode 100755 bin/banked/lpd create mode 100755 bin/banked/lpr create mode 100755 bin/banked/ls create mode 100755 bin/banked/man create mode 100755 bin/banked/mkdir create mode 100755 bin/banked/mknod create mode 100755 bin/banked/more create mode 100755 bin/banked/mount create mode 100755 bin/banked/msh create mode 100755 bin/banked/ncheck create mode 100755 bin/banked/nroff create mode 100755 bin/banked/od create mode 100755 bin/banked/passwd create mode 100755 bin/banked/pathchk create mode 100755 bin/banked/pr create mode 100755 bin/banked/printenv create mode 100755 bin/banked/ps create mode 100755 bin/banked/pwd create mode 100755 bin/banked/readall create mode 100755 bin/banked/reboot create mode 100755 bin/banked/renice create mode 100755 bin/banked/rm create mode 100755 bin/banked/rmdir create mode 100755 bin/banked/roff create mode 100755 bin/banked/sash create mode 100755 bin/banked/setclock create mode 100755 bin/banked/sort create mode 100755 bin/banked/split create mode 100755 bin/banked/su create mode 100755 bin/banked/sum create mode 100755 bin/banked/sync create mode 100755 bin/banked/tail create mode 100755 bin/banked/tar create mode 100755 bin/banked/tee create mode 100755 bin/banked/ter create mode 100755 bin/banked/termcap create mode 100755 bin/banked/test create mode 100755 bin/banked/tget create mode 100755 bin/banked/time create mode 100755 bin/banked/top create mode 100755 bin/banked/touch create mode 100755 bin/banked/tr create mode 100755 bin/banked/true create mode 100755 bin/banked/ualign create mode 100755 bin/banked/umount create mode 100755 bin/banked/uname create mode 100755 bin/banked/uniq create mode 100755 bin/banked/uudecode create mode 100755 bin/banked/uuencode create mode 100755 bin/banked/wc create mode 100755 bin/banked/which create mode 100755 bin/banked/whoami create mode 100755 bin/banked/yes create mode 100755 bin/boot.bin create mode 100755 bin/catman.bat create mode 100755 bin/checksum create mode 100755 bin/chset.sh create mode 100755 bin/chset/cog-chs create mode 100755 bin/chset/lpr-chs create mode 100755 bin/chset/ned-chs create mode 100755 bin/chset/std-chs create mode 100755 bin/demos.sh create mode 100755 bin/demos/cog-lab create mode 100755 bin/demos/lpr-rec create mode 100755 bin/demos/ned01-1 create mode 100755 bin/demos/ned01-2 create mode 100755 bin/demos/ned01-3 create mode 100755 bin/demos/ned01-4 create mode 100755 bin/demos/ned02-1 create mode 100755 bin/demos/ned02-2 create mode 100755 bin/demos/ned02-3 create mode 100755 bin/demos/ned02-4 create mode 100755 bin/demos/ned02-5 create mode 100755 bin/demos/ned02-6 create mode 100755 bin/demos/ned03-1 create mode 100755 bin/demos/ned03-2 create mode 100755 bin/demos/ned04-1 create mode 100755 bin/demos/ned04-2 create mode 100755 bin/demos/ned04-3 create mode 100755 bin/demos/ned05-1 create mode 100755 bin/demos/ned05-2 create mode 100755 bin/demos/ned05-3 create mode 100755 bin/demos/ned05-4 create mode 100755 bin/demos/ned05-5 create mode 100755 bin/demos/ned06-1 create mode 100755 bin/demos/ned06-2 create mode 100755 bin/demos/ned06-3 create mode 100755 bin/demos/ned06-4 create mode 100755 bin/demos/ned06-5 create mode 100755 bin/demos/ned06-6 create mode 100755 bin/fortune.dat create mode 100755 bin/group.txt create mode 100755 bin/hytdisk.dat create mode 100755 bin/inittab.txt create mode 100755 bin/kernel.bin create mode 100755 bin/large/adduser create mode 100755 bin/large/align create mode 100755 bin/large/apropos create mode 100755 bin/large/banner create mode 100755 bin/large/basename create mode 100755 bin/large/bd create mode 100755 bin/large/cal create mode 100755 bin/large/cat create mode 100755 bin/large/catman create mode 100755 bin/large/cdiff create mode 100755 bin/large/cgrep create mode 100755 bin/large/chgrp create mode 100755 bin/large/chmod create mode 100755 bin/large/chown create mode 100755 bin/large/cksum create mode 100755 bin/large/cmp create mode 100755 bin/large/cp create mode 100755 bin/large/cr create mode 100755 bin/large/crc create mode 100755 bin/large/cron create mode 100755 bin/large/date create mode 100755 bin/large/dd create mode 100755 bin/large/df create mode 100755 bin/large/dhry create mode 100755 bin/large/diff create mode 100755 bin/large/dirname create mode 100755 bin/large/diskusag create mode 100755 bin/large/dtree create mode 100755 bin/large/du create mode 100755 bin/large/echo create mode 100755 bin/large/ed create mode 100755 bin/large/expr create mode 100755 bin/large/false create mode 100755 bin/large/fgrep create mode 100755 bin/large/file create mode 100755 bin/large/find create mode 100755 bin/large/fld create mode 100755 bin/large/fortune create mode 100755 bin/large/fsck create mode 100755 bin/large/grep create mode 100755 bin/large/gres create mode 100755 bin/large/head create mode 100755 bin/large/id create mode 100755 bin/large/init create mode 100755 bin/large/inodes create mode 100755 bin/large/kill create mode 100755 bin/large/login create mode 100755 bin/large/lpd create mode 100755 bin/large/lpr create mode 100755 bin/large/ls create mode 100755 bin/large/man create mode 100755 bin/large/mkdir create mode 100755 bin/large/mkfs create mode 100755 bin/large/mknod create mode 100755 bin/large/more create mode 100755 bin/large/mount create mode 100755 bin/large/ncheck create mode 100755 bin/large/od create mode 100755 bin/large/passwd create mode 100755 bin/large/pathchk create mode 100755 bin/large/pr create mode 100755 bin/large/printenv create mode 100755 bin/large/ps create mode 100755 bin/large/pwd create mode 100755 bin/large/readall create mode 100755 bin/large/reboot create mode 100755 bin/large/renice create mode 100755 bin/large/rm create mode 100755 bin/large/rmdir create mode 100755 bin/large/roff create mode 100755 bin/large/sash create mode 100755 bin/large/setclock create mode 100755 bin/large/sort create mode 100755 bin/large/split create mode 100755 bin/large/su create mode 100755 bin/large/sum create mode 100755 bin/large/sync create mode 100755 bin/large/tail create mode 100755 bin/large/tar create mode 100755 bin/large/tee create mode 100755 bin/large/ter create mode 100755 bin/large/termcap create mode 100755 bin/large/test create mode 100755 bin/large/tget create mode 100755 bin/large/time create mode 100755 bin/large/top create mode 100755 bin/large/touch create mode 100755 bin/large/tr create mode 100755 bin/large/true create mode 100755 bin/large/ualign create mode 100755 bin/large/umount create mode 100755 bin/large/uname create mode 100755 bin/large/uniq create mode 100755 bin/large/uudecode create mode 100755 bin/large/uuencode create mode 100755 bin/large/wc create mode 100755 bin/large/which create mode 100755 bin/large/whoami create mode 100755 bin/large/yes create mode 100755 bin/liberror.txt create mode 100755 bin/man/man1/basename.1 create mode 100755 bin/man/man1/cal.1 create mode 100755 bin/man/man1/cat.1 create mode 100755 bin/man/man1/chmod.1 create mode 100755 bin/man/man1/chown.1 create mode 100755 bin/man/man1/cmp.1 create mode 100755 bin/man/man1/cp.1 create mode 100755 bin/man/man1/date.1 create mode 100755 bin/man/man1/dd.1 create mode 100755 bin/man/man1/diff.1 create mode 100755 bin/man/man1/du.1 create mode 100755 bin/man/man1/echo.1 create mode 100755 bin/man/man1/ed.1 create mode 100755 bin/man/man1/expr.1 create mode 100755 bin/man/man1/file.1 create mode 100755 bin/man/man1/find.1 create mode 100755 bin/man/man1/grep.1 create mode 100755 bin/man/man1/kill.1 create mode 100755 bin/man/man1/ln.1 create mode 100755 bin/man/man1/login.1 create mode 100755 bin/man/man1/ls.1 create mode 100755 bin/man/man1/man.1 create mode 100755 bin/man/man1/mkdir.1 create mode 100755 bin/man/man1/mv.1 create mode 100755 bin/man/man1/od.1 create mode 100755 bin/man/man1/passwd.1 create mode 100755 bin/man/man1/pr.1 create mode 100755 bin/man/man1/ps.1 create mode 100755 bin/man/man1/pwd.1 create mode 100755 bin/man/man1/rm.1 create mode 100755 bin/man/man1/roff.1 create mode 100755 bin/man/man1/sh.1 create mode 100755 bin/man/man1/sort.1 create mode 100755 bin/man/man1/split.1 create mode 100755 bin/man/man1/su.1 create mode 100755 bin/man/man1/sum.1 create mode 100755 bin/man/man1/tail.1 create mode 100755 bin/man/man1/tar.1 create mode 100755 bin/man/man1/tee.1 create mode 100755 bin/man/man1/test.1 create mode 100755 bin/man/man1/time.1 create mode 100755 bin/man/man1/touch.1 create mode 100755 bin/man/man1/tr.1 create mode 100755 bin/man/man1/troff.1 create mode 100755 bin/man/man1/true.1 create mode 100755 bin/man/man1/uniq.1 create mode 100755 bin/man/man1/wc.1 create mode 100755 bin/man/mkwhatis.bat create mode 100755 bin/man/mkwhatis.sed create mode 100755 bin/man/mkwhatis.sh create mode 100755 bin/man/sh.1 create mode 100755 bin/mkramfs.sh create mode 100755 bin/mtab.txt create mode 100755 bin/n.bat create mode 100755 bin/n.ucp create mode 100755 bin/newkrnl.sh create mode 100755 bin/passwd.txt create mode 100755 bin/term/tab37 create mode 100755 bin/tmac/tmac.an create mode 100755 bin/uzidisk.dat create mode 100755 doc/030131SD test readme.txt create mode 100755 doc/030131SD.P create mode 100755 doc/030217SD test readme.txt create mode 100755 doc/030217SD.P create mode 100755 doc/ASxxxx Cross Assembler Documentation.htm create mode 100755 doc/ASxxxx Cross Assembler Documentation_files/home.gif create mode 100755 doc/ASxxxx Cross Assembler Documentation_files/rnbow.gif create mode 100755 doc/ASxxxx Cross Assembler Documentation_files/spcshp.gif create mode 100755 doc/ASxxxx Cross Assembler Documentation_files/welcom.gif create mode 100755 doc/ASxxxx Cross Assemblers.htm create mode 100755 doc/ASxxxx Cross Assemblers_files/bug.gif create mode 100755 doc/ASxxxx Cross Assemblers_files/home.gif create mode 100755 doc/ASxxxx Cross Assemblers_files/manual.gif create mode 100755 doc/ASxxxx Cross Assemblers_files/netwrk.gif create mode 100755 doc/ASxxxx Cross Assemblers_files/notes.gif create mode 100755 doc/ASxxxx Cross Assemblers_files/questn.gif create mode 100755 doc/ASxxxx Cross Assemblers_files/rnbow.gif create mode 100755 doc/ASxxxx Cross Assemblers_files/welcom.gif create mode 100755 doc/Betriebssystem UNIX - Literatur.htm create mode 100755 doc/Betriebssystem UNIX - Literatur_files/kd14.jpg create mode 100755 doc/C-history.htm create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History.htm create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History_files/b.gif create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History_files/background.gif create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History_files/code create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History_files/info1.css create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History_files/opengroup-logo.gif create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History_files/topcell.gif create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History_files/under-logo2.gif create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History_files/unix_plate-small.jpg create mode 100755 doc/The UNIX System -- History and Timeline -- UNIX History_files/what_is_unix.htm create mode 100755 doc/UNIX Evolution.htm create mode 100755 doc/UNIX.htm create mode 100755 doc/cmx-lic.p create mode 100755 doc/cmx-lic.txt create mode 100755 doc/index.htm create mode 100755 doc/lcd0.txt create mode 100755 doc/overview.txt create mode 100755 doc/stdlib.txt create mode 100755 doc/syscalls.p create mode 100755 doc/syscalls.txt create mode 100755 doc/uzi-lic.txt create mode 100755 doc/uzi-summ.txt create mode 100755 doc/uzi-tech.txt create mode 100755 doc/z180-mem.p create mode 100755 doc/z180-mem.txt create mode 100755 include/!readme! create mode 100755 include/alloc.h create mode 100755 include/ar.h create mode 100755 include/assert.h create mode 100755 include/ctype.h create mode 100755 include/curses.h create mode 100755 include/dirent.h create mode 100755 include/errno.h create mode 100755 include/fcntl.h create mode 100755 include/features.h create mode 100755 include/float.h create mode 100755 include/getopt.h create mode 100755 include/grp.h create mode 100755 include/include.zip create mode 100755 include/limits.h create mode 100755 include/malloc.h create mode 100755 include/math.h create mode 100755 include/mem.h create mode 100755 include/memory.h create mode 100755 include/ncurses.h create mode 100755 include/paths.h create mode 100755 include/pwd.h create mode 100755 include/regexp.h create mode 100755 include/regmagic.h create mode 100755 include/search.h create mode 100755 include/setjmp.h create mode 100755 include/setjmp.h$ create mode 100755 include/sgtty.h create mode 100755 include/signal.h create mode 100755 include/stdarg.h create mode 100755 include/stddef.h create mode 100755 include/stdio.h create mode 100755 include/stdlib.h create mode 100755 include/string.h create mode 100755 include/strings.h create mode 100755 include/sys/cdefs.h create mode 100755 include/sys/exec.h create mode 100755 include/sys/ioctl.h create mode 100755 include/sys/seek.h create mode 100755 include/sys/stat.h create mode 100755 include/sys/utsname.h create mode 100755 include/sys/wait.h create mode 100755 include/sys/wait.h% create mode 100755 include/sys/z8.pmm create mode 100755 include/sys/z9.pmm create mode 100755 include/syscalls.h create mode 100755 include/tcpip.h create mode 100755 include/termcap.h create mode 100755 include/termio.h create mode 100755 include/termios.h create mode 100755 include/time.h create mode 100755 include/types.h create mode 100755 include/unistd.h create mode 100755 include/utime.h create mode 100755 include/utmp.h create mode 100755 include/utsname.h create mode 100755 include/varargs.h create mode 100755 include/vendor.h create mode 100755 include/z8.pmm create mode 100755 include/z9.pmm create mode 100755 lib/libcb.lib create mode 100755 lib/libcl.lib create mode 100755 lib/libiar.lib create mode 100755 lib/libsysb.lib create mode 100755 lib/libsysl.lib create mode 100644 relnotes/20030306.txt create mode 100755 silly.bat create mode 100755 src/as-z80/as-z80.exe create mode 100755 src/as-z80/as-z80.lnk create mode 100755 src/as-z80/asdata.c create mode 100755 src/as-z80/asexpr.c create mode 100755 src/as-z80/aslex.c create mode 100755 src/as-z80/aslist.c create mode 100755 src/as-z80/asmain.c create mode 100755 src/as-z80/asout.c create mode 100755 src/as-z80/assubr.c create mode 100755 src/as-z80/assym.c create mode 100755 src/as-z80/asxxxx.h create mode 100755 src/as-z80/n.bat create mode 100755 src/as-z80/tz80.asm create mode 100755 src/as-z80/tz80l.asm create mode 100755 src/as-z80/z80.h create mode 100755 src/as-z80/z80adr.c create mode 100755 src/as-z80/z80ext.c create mode 100755 src/as-z80/z80mch.c create mode 100755 src/as-z80/z80pst.c create mode 100755 src/as-z80/z80pst.c$ create mode 100755 src/bin/4dos.com create mode 100755 src/bin/as-z80.exe create mode 100755 src/bin/bd.exe create mode 100755 src/bin/bin2c.exe create mode 100755 src/bin/crc.com create mode 100755 src/bin/crcd.com create mode 100755 src/bin/fsck.exe create mode 100755 src/bin/ihex2bin.exe create mode 100755 src/bin/link-z80.exe create mode 100755 src/bin/make.exe create mode 100755 src/bin/mkfs.exe create mode 100755 src/bin/mklink-b.bat create mode 100755 src/bin/mklink-l.bat create mode 100755 src/bin/mknbat-b.bat create mode 100755 src/bin/mknbat-l.bat create mode 100755 src/bin/nroff.exe create mode 100755 src/bin/roff.exe create mode 100755 src/bin/touch.exe create mode 100755 src/bin/ucp.exe create mode 100755 src/chset/CHSET00.WIN create mode 100755 src/chset/CHSET01.WIN create mode 100755 src/chset/CHSET02.WIN create mode 100755 src/chset/CHSET03.WIN create mode 100755 src/chset/CHSET04.WIN create mode 100755 src/chset/CHSET05.WIN create mode 100755 src/chset/CHSET06.WIN create mode 100755 src/chset/CHSET07.WIN create mode 100755 src/chset/CHSET08.WIN create mode 100755 src/chset/CHSET09.WIN create mode 100755 src/chset/CLRSCRN.BIN create mode 100755 src/chset/CUTPULL.BIN create mode 100755 src/chset/HEADER0 create mode 100755 src/chset/HEADER1 create mode 100755 src/chset/HEADER2 create mode 100755 src/chset/HEADER3 create mode 100755 src/chset/HEADER4 create mode 100755 src/chset/HEADER5 create mode 100755 src/chset/HEADER6 create mode 100755 src/chset/HEADER7 create mode 100755 src/chset/HEADER8 create mode 100755 src/chset/HEADER9 create mode 100755 src/chset/HYLAB.TXT create mode 100755 src/chset/HYLAB0-0.TXT create mode 100755 src/chset/HYLAB0-1.TXT create mode 100755 src/chset/HYLAB1-0.TXT create mode 100755 src/chset/HYLAB1-1.TXT create mode 100755 src/chset/HYLAB2.TXT create mode 100755 src/chset/NED.TXT create mode 100755 src/chset/PRINTER.BIN create mode 100755 src/chset/TRI08.CHR create mode 100755 src/chset/TRI10.CHR create mode 100755 src/chset/TRI16.CHR create mode 100755 src/chset/chset.sh create mode 100755 src/chset/chset0 create mode 100755 src/chset/chset1 create mode 100755 src/chset/chset2 create mode 100755 src/chset/chset3 create mode 100755 src/chset/chset4 create mode 100755 src/chset/chset5 create mode 100755 src/chset/chset6 create mode 100755 src/chset/chset7 create mode 100755 src/chset/chset8 create mode 100755 src/chset/chset9 create mode 100755 src/chset/clrscrn.dbg create mode 100755 src/chset/cognitiv.bat create mode 100755 src/chset/cutpull.dbg create mode 100755 src/chset/demos/cog-lab create mode 100755 src/chset/demos/demos.sh create mode 100755 src/chset/demos/lpr-rec create mode 100755 src/chset/demos/ned-chs create mode 100755 src/chset/demos/ned01-1 create mode 100755 src/chset/demos/ned01-2 create mode 100755 src/chset/demos/ned01-3 create mode 100755 src/chset/demos/ned01-4 create mode 100755 src/chset/demos/ned02-1 create mode 100755 src/chset/demos/ned02-2 create mode 100755 src/chset/demos/ned02-3 create mode 100755 src/chset/demos/ned02-4 create mode 100755 src/chset/demos/ned02-5 create mode 100755 src/chset/demos/ned02-6 create mode 100755 src/chset/demos/ned03-1 create mode 100755 src/chset/demos/ned03-2 create mode 100755 src/chset/demos/ned04-1 create mode 100755 src/chset/demos/ned04-2 create mode 100755 src/chset/demos/ned04-3 create mode 100755 src/chset/demos/ned05-1 create mode 100755 src/chset/demos/ned05-2 create mode 100755 src/chset/demos/ned05-3 create mode 100755 src/chset/demos/ned05-4 create mode 100755 src/chset/demos/ned05-5 create mode 100755 src/chset/demos/ned06-1 create mode 100755 src/chset/demos/ned06-2 create mode 100755 src/chset/demos/ned06-3 create mode 100755 src/chset/demos/ned06-4 create mode 100755 src/chset/demos/ned06-5 create mode 100755 src/chset/demos/ned06-6 create mode 100755 src/chset/headers.bat create mode 100755 src/chset/headers.dbg create mode 100755 src/chset/hylab.tmp create mode 100755 src/chset/hylab0.tmp create mode 100755 src/chset/hylab1.tmp create mode 100755 src/chset/hylab2.tmp create mode 100755 src/chset/n.bat create mode 100755 src/chset/printer.bat create mode 100755 src/chset/printer.dbg create mode 100755 src/fsutil/bd.c create mode 100755 src/fsutil/bd.exe create mode 100755 src/fsutil/bd.lnk create mode 100755 src/fsutil/bd.w32 create mode 100755 src/fsutil/boot.c create mode 100755 src/fsutil/f.bat create mode 100755 src/fsutil/fsck.c create mode 100755 src/fsutil/fsck.exe create mode 100755 src/fsutil/fsck.lnk create mode 100755 src/fsutil/fsck.w32 create mode 100755 src/fsutil/hdasm.c create mode 100755 src/fsutil/kernel.bin create mode 100755 src/fsutil/m.bat create mode 100755 src/fsutil/main.c create mode 100755 src/fsutil/mkboot.c create mode 100755 src/fsutil/mkfs.c create mode 100755 src/fsutil/mkfs.exe create mode 100755 src/fsutil/mkfs.lnk create mode 100755 src/fsutil/mkfs.ltc create mode 100755 src/fsutil/mkfs.w32 create mode 100755 src/fsutil/n.bat create mode 100755 src/fsutil/readme create mode 100755 src/fsutil/runfsck.bat create mode 100755 src/fsutil/runmkfs.bat create mode 100755 src/fsutil/tcmake.bat create mode 100755 src/fsutil/ucp.c create mode 100755 src/fsutil/ucp.exe create mode 100755 src/fsutil/ucp.ltc create mode 100755 src/fsutil/ucp.w32 create mode 100755 src/fsutil/ucpsub.c create mode 100755 src/fsutil/utildos.c create mode 100755 src/fsutil/utildos.h create mode 100755 src/fsutil/utils.c create mode 100755 src/fsutil/utils.h create mode 100755 src/fsutil/uzidisk.dat create mode 100755 src/fsutil/xfs.c create mode 100755 src/fsutil/xfs.h create mode 100755 src/gboot/checksum.dat create mode 100755 src/gboot/clears.inc create mode 100755 src/gboot/copyr.inc create mode 100755 src/gboot/diag.inc create mode 100755 src/gboot/gboot.asm create mode 100755 src/gboot/gboot.asm$ create mode 100755 src/gboot/gboot.lnk create mode 100755 src/gboot/io64180.inc create mode 100755 src/gboot/n.bat create mode 100755 src/hello/build-b.ban create mode 100755 src/hello/build-l.ban create mode 100755 src/hello/hello-b create mode 100755 src/hello/hello-b.lnk create mode 100755 src/hello/hello-l create mode 100755 src/hello/hello-l.lnk create mode 100755 src/hello/hello.c create mode 100755 src/hello/n.bat create mode 100755 src/init/build-b.ban create mode 100755 src/init/build-l.ban create mode 100755 src/init/init.c create mode 100755 src/init/login.c create mode 100755 src/init/n.bat create mode 100755 src/kernel/build.ban create mode 100755 src/kernel/cmx/apibus.asm create mode 100755 src/kernel/cmx/asci.asm create mode 100755 src/kernel/cmx/bstartup.asm create mode 100755 src/kernel/cmx/cmx_init.c create mode 100755 src/kernel/cmx/cmxbug.c create mode 100755 src/kernel/cmx/cmxbug.h create mode 100755 src/kernel/cmx/cmxintb.asm create mode 100755 src/kernel/cmx/cmxio3.c create mode 100755 src/kernel/cmx/cmxtrack.c create mode 100755 src/kernel/cmx/cmxtrack.h create mode 100755 src/kernel/cmx/cmxtrack.txt create mode 100755 src/kernel/cmx/copyr.asm create mode 100755 src/kernel/cmx/cxconfig.h create mode 100755 src/kernel/cmx/cxdefine.h create mode 100755 src/kernel/cmx/cxextern.h create mode 100755 src/kernel/cmx/cxfuncs.h create mode 100755 src/kernel/cmx/cxskv5b.asm create mode 100755 src/kernel/cmx/cxstruct.h create mode 100755 src/kernel/cmx/cxvendor.h create mode 100755 src/kernel/cmx/cxver5.c create mode 100755 src/kernel/cmx/diag.asm create mode 100755 src/kernel/cmx/escc.asm create mode 100755 src/kernel/cmx/io64180.h create mode 100755 src/kernel/cmx/io64180.inc create mode 100755 src/kernel/kernel.lnk create mode 100755 src/kernel/libc/_exit.asm create mode 100755 src/kernel/libc/abort.c create mode 100755 src/kernel/libc/c0k.asm create mode 100755 src/kernel/libc/exit.c create mode 100755 src/kernel/libc/itoa.c create mode 100755 src/kernel/libc/itoa.h create mode 100755 src/kernel/libc/kprintf.c create mode 100755 src/kernel/libc/kprintf.h create mode 100755 src/kernel/libc/ltoa.c create mode 100755 src/kernel/libc/ltoa.h create mode 100755 src/kernel/libc/memcpy.c create mode 100755 src/kernel/libc/memcpy.h create mode 100755 src/kernel/libc/strcat.c create mode 100755 src/kernel/libc/strcat.h create mode 100755 src/kernel/libc/strcpy.c create mode 100755 src/kernel/libc/strcpy.h create mode 100755 src/kernel/libc/strlen.c create mode 100755 src/kernel/libc/strlen.h create mode 100755 src/kernel/libc/strncmp.c create mode 100755 src/kernel/libc/strncmp.h create mode 100755 src/kernel/libc/ultoa.c create mode 100755 src/kernel/libc/ultoa.h create mode 100755 src/kernel/libc/vendor.h create mode 100755 src/kernel/libc/vfprintf.c create mode 100755 src/kernel/libc/vfprintf.h create mode 100755 src/kernel/n.bat create mode 100755 src/kernel/uzi/asmdef.inc create mode 100755 src/kernel/uzi/config.h create mode 100755 src/kernel/uzi/data.c create mode 100755 src/kernel/uzi/devflop.c create mode 100755 src/kernel/uzi/devhd.c create mode 100755 src/kernel/uzi/devhd.h create mode 100755 src/kernel/uzi/devio.c create mode 100755 src/kernel/uzi/devio.c$ create mode 100755 src/kernel/uzi/devio.h create mode 100755 src/kernel/uzi/devio.h$ create mode 100755 src/kernel/uzi/devmisc.c create mode 100755 src/kernel/uzi/devmisc.h create mode 100755 src/kernel/uzi/devmt.c$ create mode 100755 src/kernel/uzi/devtty.c create mode 100755 src/kernel/uzi/devtty.h create mode 100755 src/kernel/uzi/dispatch create mode 100755 src/kernel/uzi/emu.asm create mode 100755 src/kernel/uzi/extern.h create mode 100755 src/kernel/uzi/filesys.c create mode 100755 src/kernel/uzi/filesys.h create mode 100755 src/kernel/uzi/flopasm.asm create mode 100755 src/kernel/uzi/hdasm.asm create mode 100755 src/kernel/uzi/hdconf.h create mode 100755 src/kernel/uzi/machasm.asm create mode 100755 src/kernel/uzi/machdep.c create mode 100755 src/kernel/uzi/main.c create mode 100755 src/kernel/uzi/procasm.asm create mode 100755 src/kernel/uzi/process.c create mode 100755 src/kernel/uzi/scall1.c create mode 100755 src/kernel/uzi/scall1.h create mode 100755 src/kernel/uzi/scall2.c create mode 100755 src/kernel/uzi/scall2.h create mode 100755 src/kernel/uzi/scall3.c create mode 100755 src/kernel/uzi/scall3.h create mode 100755 src/kernel/uzi/startasm.asm create mode 100755 src/kernel/uzi/systrace.c create mode 100755 src/kernel/uzi/unix.h create mode 100755 src/kernel/uzi/utils.asm create mode 100755 src/kernel/uzi/vendor.h create mode 100755 src/kernel/uzi/xip.c create mode 100755 src/kernel/uzi/xip.h create mode 100755 src/kernel/uzi/z180.inc create mode 100755 src/libc/!readme! create mode 100755 src/libc/N9.PMM create mode 100755 src/libc/T create mode 100755 src/libc/abort.c create mode 100755 src/libc/alloca-l.h create mode 100755 src/libc/alloca.c create mode 100755 src/libc/asctime.c create mode 100755 src/libc/assert.c create mode 100755 src/libc/atexit.c create mode 100755 src/libc/atoi.c create mode 100755 src/libc/atol.c create mode 100755 src/libc/bsearch.c create mode 100755 src/libc/build-b.ban create mode 100755 src/libc/build-l.ban create mode 100755 src/libc/c0b.asm create mode 100755 src/libc/c0l.asm create mode 100755 src/libc/c0u.asm create mode 100755 src/libc/c9.pmm create mode 100755 src/libc/calloc.c create mode 100755 src/libc/clock.c create mode 100755 src/libc/closedir.c create mode 100755 src/libc/convtime.c create mode 100755 src/libc/crypt.c create mode 100755 src/libc/cstartup.r01 create mode 100755 src/libc/ctime.c create mode 100755 src/libc/ctype.c create mode 100755 src/libc/cvt.h create mode 100755 src/libc/difftime.c create mode 100755 src/libc/environ.h create mode 100755 src/libc/error.c create mode 100755 src/libc/etime.c create mode 100755 src/libc/exec.h create mode 100755 src/libc/execl.c create mode 100755 src/libc/execle.c create mode 100755 src/libc/execlp.c create mode 100755 src/libc/execlpe.c create mode 100755 src/libc/exect.c create mode 100755 src/libc/execv.c create mode 100755 src/libc/execvp.c create mode 100755 src/libc/execvpe.c create mode 100755 src/libc/exit.c create mode 100755 src/libc/fclose.c create mode 100755 src/libc/fflush.c create mode 100755 src/libc/fgetc.c create mode 100755 src/libc/fgetgren.c create mode 100755 src/libc/fgetpwen.c create mode 100755 src/libc/fgets.c create mode 100755 src/libc/fopen.c create mode 100755 src/libc/fprintf.c create mode 100755 src/libc/fputc.c create mode 100755 src/libc/fputs.c create mode 100755 src/libc/fread.c create mode 100755 src/libc/free.c create mode 100755 src/libc/free.c$ create mode 100755 src/libc/fscanf.c create mode 100755 src/libc/ftell.c create mode 100755 src/libc/fwrite.c create mode 100755 src/libc/getcwd.c create mode 100755 src/libc/getenv.c create mode 100755 src/libc/getgrent.c create mode 100755 src/libc/getgrgid.c create mode 100755 src/libc/getgrnam.c create mode 100755 src/libc/getopt.c create mode 100755 src/libc/getpass.c create mode 100755 src/libc/getpw.c create mode 100755 src/libc/getpwent.c create mode 100755 src/libc/getpwnam.c create mode 100755 src/libc/getpwuid.c create mode 100755 src/libc/gets.c create mode 100755 src/libc/gmtime.c create mode 100755 src/libc/grp-l.h create mode 100755 src/libc/initgrup.c create mode 100755 src/libc/isatty.c create mode 100755 src/libc/itoa.c create mode 100755 src/libc/libcb.lib create mode 100755 src/libc/libcl.lib create mode 100755 src/libc/liberror.src create mode 100755 src/libc/localtim.c create mode 100755 src/libc/longjmpb.asm create mode 100755 src/libc/longjmpl.asm create mode 100755 src/libc/lsearch.c create mode 100755 src/libc/lseek.c$ create mode 100755 src/libc/lstat.c create mode 100755 src/libc/ltoa.c create mode 100755 src/libc/ltostr.c create mode 100755 src/libc/malloc-l.h create mode 100755 src/libc/malloc-l.h$ create mode 100755 src/libc/malloc.c create mode 100755 src/libc/malloc.c$ create mode 100755 src/libc/mem-l.h create mode 100755 src/libc/memccpy.c create mode 100755 src/libc/memchr.c create mode 100755 src/libc/memcmp.c create mode 100755 src/libc/memcpy.c create mode 100755 src/libc/memmove.c create mode 100755 src/libc/memset.c create mode 100755 src/libc/mkdir.c create mode 100755 src/libc/mktime.c create mode 100755 src/libc/n.bat create mode 100755 src/libc/n.xlb create mode 100755 src/libc/opendir.c create mode 100755 src/libc/passwd.h create mode 100755 src/libc/perror.asm create mode 100755 src/libc/perror.c create mode 100755 src/libc/popen.c create mode 100755 src/libc/printf.c create mode 100755 src/libc/printf.h create mode 100755 src/libc/putenv.c create mode 100755 src/libc/putgetch.c create mode 100755 src/libc/putpwent.c create mode 100755 src/libc/qsort.c create mode 100755 src/libc/rand.c create mode 100755 src/libc/readdir.c create mode 100755 src/libc/readlink.c create mode 100755 src/libc/realloc.c create mode 100755 src/libc/realloc.c$ create mode 100755 src/libc/regerror.c create mode 100755 src/libc/regexp.c create mode 100755 src/libc/regsub.c create mode 100755 src/libc/rename.c create mode 100755 src/libc/rewind.c create mode 100755 src/libc/rewindir.c create mode 100755 src/libc/rmdir.c create mode 100755 src/libc/scanf.c create mode 100755 src/libc/scanf.h create mode 100755 src/libc/setbuff.c create mode 100755 src/libc/setenv.c create mode 100755 src/libc/setgrent.c create mode 100755 src/libc/setjmp.c$ create mode 100755 src/libc/setjmp.msx create mode 100755 src/libc/setjmp.r01 create mode 100755 src/libc/setjmpb.asm create mode 100755 src/libc/setjmpl.asm create mode 100755 src/libc/setpwent.c create mode 100755 src/libc/setvbuff.c create mode 100755 src/libc/sleep.c create mode 100755 src/libc/sprintf.c create mode 100755 src/libc/sscanf.c create mode 100755 src/libc/stdio-l.h create mode 100755 src/libc/stdio0.c create mode 100755 src/libc/strcat.c create mode 100755 src/libc/strchr.c create mode 100755 src/libc/strcmp.c create mode 100755 src/libc/strcpy.c create mode 100755 src/libc/strcspn.c create mode 100755 src/libc/strdup.c create mode 100755 src/libc/stricmp.c create mode 100755 src/libc/string-l.h create mode 100755 src/libc/strlen.c create mode 100755 src/libc/strncat.c create mode 100755 src/libc/strncmp.c create mode 100755 src/libc/strncpy.c create mode 100755 src/libc/strnicmp.c create mode 100755 src/libc/strpbrk.c create mode 100755 src/libc/strrchr.c create mode 100755 src/libc/strsep.c create mode 100755 src/libc/strspn.c create mode 100755 src/libc/strstr.c create mode 100755 src/libc/strtod.c create mode 100755 src/libc/strtok.c create mode 100755 src/libc/strtol.c create mode 100755 src/libc/strtoul.c create mode 100755 src/libc/system.c create mode 100755 src/libc/termcap.c create mode 100755 src/libc/termcap.src create mode 100755 src/libc/time-l.h create mode 100755 src/libc/tmpnam.c create mode 100755 src/libc/tparam.c create mode 100755 src/libc/ttyname.c create mode 100755 src/libc/tzset.c create mode 100755 src/libc/ultoa.c create mode 100755 src/libc/ungetc.c create mode 100755 src/libc/unix.h$ create mode 100755 src/libc/utsname.c create mode 100755 src/libc/vfprintf.c create mode 100755 src/libc/vfscanf.c create mode 100755 src/libc/vprintf.c create mode 100755 src/libc/vscanf.c create mode 100755 src/libc/vsprintf.c create mode 100755 src/libc/vsscanf.c create mode 100755 src/libc/x.bat create mode 100755 src/libc/xitoa.c create mode 100755 src/libc/xltoa.c create mode 100755 src/libiar/BANKCALL.asm create mode 100755 src/libiar/BANKCALLDIRECT.asm create mode 100755 src/libiar/BANKCALLDIRECTEXAF.asm create mode 100755 src/libiar/BANKCALLEXAF.asm create mode 100755 src/libiar/BANKLEAVE.asm create mode 100755 src/libiar/BANKLEAVE32.asm create mode 100755 src/libiar/BANKLEAVEDIRECT.asm create mode 100755 src/libiar/BFCANDASG.asm create mode 100755 src/libiar/BFCLSHASG.asm create mode 100755 src/libiar/BFCMULASG.asm create mode 100755 src/libiar/BFCORASG.asm create mode 100755 src/libiar/BFCRETVAL.asm create mode 100755 src/libiar/BFCSHIFTUP.asm create mode 100755 src/libiar/BFCXORASG.asm create mode 100755 src/libiar/BFMASKEDLD.asm create mode 100755 src/libiar/BFMASKEDST.asm create mode 100755 src/libiar/BFSADDASG.asm create mode 100755 src/libiar/BFSANDASG.asm create mode 100755 src/libiar/BFSCDIVASG.asm create mode 100755 src/libiar/BFSCEXT.asm create mode 100755 src/libiar/BFSCLDSHIFTDOWN.asm create mode 100755 src/libiar/BFSCMODASG.asm create mode 100755 src/libiar/BFSCRSHASG.asm create mode 100755 src/libiar/BFSLSHASG.asm create mode 100755 src/libiar/BFSMULASG.asm create mode 100755 src/libiar/BFSNEGASG.asm create mode 100755 src/libiar/BFSORASG.asm create mode 100755 src/libiar/BFSPOSTDEC.asm create mode 100755 src/libiar/BFSPOSTINC.asm create mode 100755 src/libiar/BFSPREDEC.asm create mode 100755 src/libiar/BFSPREINC.asm create mode 100755 src/libiar/BFSRETVAL.asm create mode 100755 src/libiar/BFSSDIVASG.asm create mode 100755 src/libiar/BFSSEXT.asm create mode 100755 src/libiar/BFSSHIFTUP.asm create mode 100755 src/libiar/BFSSLDSHIFTDOWN.asm create mode 100755 src/libiar/BFSSMODASG.asm create mode 100755 src/libiar/BFSSRSHASG.asm create mode 100755 src/libiar/BFSSUBASG.asm create mode 100755 src/libiar/BFSXORASG.asm create mode 100755 src/libiar/BFUCDIVASG.asm create mode 100755 src/libiar/BFUCLDSHIFTDOWN.asm create mode 100755 src/libiar/BFUCMODASG.asm create mode 100755 src/libiar/BFUCRSHASG.asm create mode 100755 src/libiar/BFUSDIVASG.asm create mode 100755 src/libiar/BFUSLDSHIFTDOWN.asm create mode 100755 src/libiar/BFUSMODASG.asm create mode 100755 src/libiar/BFUSRSHASG.asm create mode 100755 src/libiar/CALLIND.asm create mode 100755 src/libiar/CDIVMOD.asm create mode 100755 src/libiar/CFINDSIGN.asm create mode 100755 src/libiar/CLSH.asm create mode 100755 src/libiar/CLSHASG.asm create mode 100755 src/libiar/CMUL.asm create mode 100755 src/libiar/CMULASG.asm create mode 100755 src/libiar/CSSWITCH.asm create mode 100755 src/libiar/CVSWITCH.asm create mode 100755 src/libiar/ENTAUTO.asm create mode 100755 src/libiar/ENTAUTODIRECT.asm create mode 100755 src/libiar/ENTPARM.asm create mode 100755 src/libiar/ENTPARMDIRECT.asm create mode 100755 src/libiar/FADDASG.asm create mode 100755 src/libiar/FADDSUB.asm create mode 100755 src/libiar/FCMP.asm create mode 100755 src/libiar/FDEC.asm create mode 100755 src/libiar/FDECASG.asm create mode 100755 src/libiar/FDIV.asm create mode 100755 src/libiar/FDIVASG.asm create mode 100755 src/libiar/FENDASG2.asm create mode 100755 src/libiar/FINC.asm create mode 100755 src/libiar/FINCASG.asm create mode 100755 src/libiar/FMUL.asm create mode 100755 src/libiar/FMULASG.asm create mode 100755 src/libiar/FNEGASG.asm create mode 100755 src/libiar/FPACK.asm create mode 100755 src/libiar/FROUND.asm create mode 100755 src/libiar/FSUBASG.asm create mode 100755 src/libiar/FTOL.asm create mode 100755 src/libiar/FUNPACK.asm create mode 100755 src/libiar/LADDASG.asm create mode 100755 src/libiar/LAND.asm create mode 100755 src/libiar/LANDASG.asm create mode 100755 src/libiar/LDEC.asm create mode 100755 src/libiar/LDECASG.asm create mode 100755 src/libiar/LDIVMOD.asm create mode 100755 src/libiar/LEAVE.asm create mode 100755 src/libiar/LEAVE32.asm create mode 100755 src/libiar/LEAVEDIRECT.asm create mode 100755 src/libiar/LENDASG.asm create mode 100755 src/libiar/LENDMULDIVASG.asm create mode 100755 src/libiar/LFINDSIGN.asm create mode 100755 src/libiar/LIBVERSION.asm create mode 100755 src/libiar/LINC.asm create mode 100755 src/libiar/LINCASG.asm create mode 100755 src/libiar/LLSH.asm create mode 100755 src/libiar/LLSHASG.asm create mode 100755 src/libiar/LMUL.asm create mode 100755 src/libiar/LMULASG.asm create mode 100755 src/libiar/LNEG.asm create mode 100755 src/libiar/LNEGASG.asm create mode 100755 src/libiar/LNOT.asm create mode 100755 src/libiar/LNOTASG.asm create mode 100755 src/libiar/LOR.asm create mode 100755 src/libiar/LORASG.asm create mode 100755 src/libiar/LSSWITCH.asm create mode 100755 src/libiar/LSUBASG.asm create mode 100755 src/libiar/LTOF.asm create mode 100755 src/libiar/LVSWITCH.asm create mode 100755 src/libiar/LXOR.asm create mode 100755 src/libiar/LXORASG.asm create mode 100755 src/libiar/MEMCMP.asm create mode 100755 src/libiar/MEMSET.asm create mode 100755 src/libiar/MONITOR.asm create mode 100755 src/libiar/MONITORBANKLEAVE.asm create mode 100755 src/libiar/MONITORBANKLEAVE32.asm create mode 100755 src/libiar/MONITORBANKLEAVEIX.asm create mode 100755 src/libiar/MONITORBANKLEAVEPOP.asm create mode 100755 src/libiar/MONITORLEAVE.asm create mode 100755 src/libiar/MONITORLEAVE32.asm create mode 100755 src/libiar/MONITORLEAVEIX.asm create mode 100755 src/libiar/MONITORLEAVEIXPA.asm create mode 100755 src/libiar/MONITORLEAVEPA.asm create mode 100755 src/libiar/MONITORLEAVEPOP.asm create mode 100755 src/libiar/SCDIV.asm create mode 100755 src/libiar/SCMOD.asm create mode 100755 src/libiar/SCRSH.asm create mode 100755 src/libiar/SCRSHASG.asm create mode 100755 src/libiar/SDIVMOD.asm create mode 100755 src/libiar/SFINDSIGN.asm create mode 100755 src/libiar/SLCMP.asm create mode 100755 src/libiar/SLDIV.asm create mode 100755 src/libiar/SLDIVASG.asm create mode 100755 src/libiar/SLMOD.asm create mode 100755 src/libiar/SLMODASG.asm create mode 100755 src/libiar/SLRSH.asm create mode 100755 src/libiar/SLRSHASG.asm create mode 100755 src/libiar/SLSH.asm create mode 100755 src/libiar/SLSHASG.asm create mode 100755 src/libiar/SLSHASGBCprim.asm create mode 100755 src/libiar/SLSHASGDEprim.asm create mode 100755 src/libiar/SMUL.asm create mode 100755 src/libiar/SMULASG.asm create mode 100755 src/libiar/SMULASGBCprim.asm create mode 100755 src/libiar/SMULASGDEprim.asm create mode 100755 src/libiar/SMULASGIX.asm create mode 100755 src/libiar/SMULASGIY.asm create mode 100755 src/libiar/SSCMP.asm create mode 100755 src/libiar/SSDIV.asm create mode 100755 src/libiar/SSDIVASG.asm create mode 100755 src/libiar/SSDIVASGBCprim.asm create mode 100755 src/libiar/SSDIVASGDEprim.asm create mode 100755 src/libiar/SSDIVASGIX.asm create mode 100755 src/libiar/SSDIVASGIY.asm create mode 100755 src/libiar/SSMOD.asm create mode 100755 src/libiar/SSMODASG.asm create mode 100755 src/libiar/SSMODASGBCprim.asm create mode 100755 src/libiar/SSMODASGDEprim.asm create mode 100755 src/libiar/SSMODASGIX.asm create mode 100755 src/libiar/SSMODASGIY.asm create mode 100755 src/libiar/SSRSH.asm create mode 100755 src/libiar/SSRSHASG.asm create mode 100755 src/libiar/SSRSHASGBCprim.asm create mode 100755 src/libiar/SSRSHASGDEprim.asm create mode 100755 src/libiar/SSRSHASGIX.asm create mode 100755 src/libiar/SSRSHASGIY.asm create mode 100755 src/libiar/SSSWITCH.asm create mode 100755 src/libiar/SSWITCHEND.asm create mode 100755 src/libiar/STRCAT.asm create mode 100755 src/libiar/STRCHR.asm create mode 100755 src/libiar/STRCMP.asm create mode 100755 src/libiar/STRCPY.asm create mode 100755 src/libiar/STRLEN.asm create mode 100755 src/libiar/SVSWITCH.asm create mode 100755 src/libiar/UCDIV.asm create mode 100755 src/libiar/UCMOD.asm create mode 100755 src/libiar/UCRSH.asm create mode 100755 src/libiar/UCRSHASG.asm create mode 100755 src/libiar/ULDIV.asm create mode 100755 src/libiar/ULDIVASG.asm create mode 100755 src/libiar/ULMOD.asm create mode 100755 src/libiar/ULMODASG.asm create mode 100755 src/libiar/ULRSH.asm create mode 100755 src/libiar/ULRSHASG.asm create mode 100755 src/libiar/USDIV.asm create mode 100755 src/libiar/USDIVASG.asm create mode 100755 src/libiar/USDIVASGBCprim.asm create mode 100755 src/libiar/USDIVASGDEprim.asm create mode 100755 src/libiar/USDIVASGIX.asm create mode 100755 src/libiar/USDIVASGIY.asm create mode 100755 src/libiar/USMOD.asm create mode 100755 src/libiar/USMODASG.asm create mode 100755 src/libiar/USMODASGBCprim.asm create mode 100755 src/libiar/USMODASGDEprim.asm create mode 100755 src/libiar/USMODASGIX.asm create mode 100755 src/libiar/USMODASGIY.asm create mode 100755 src/libiar/USRSH.asm create mode 100755 src/libiar/USRSHASG.asm create mode 100755 src/libiar/USRSHASGBCprim.asm create mode 100755 src/libiar/USRSHASGDEprim.asm create mode 100755 src/libiar/USRSHASGIX.asm create mode 100755 src/libiar/USRSHASGIY.asm create mode 100755 src/libiar/VSWITCHEND.asm create mode 100755 src/libiar/abort.asm create mode 100755 src/libiar/abs.asm create mode 100755 src/libiar/acos.asm create mode 100755 src/libiar/asin.asm create mode 100755 src/libiar/assert.asm create mode 100755 src/libiar/atan.asm create mode 100755 src/libiar/atan2.asm create mode 100755 src/libiar/atof.asm create mode 100755 src/libiar/atoi.asm create mode 100755 src/libiar/atol.asm create mode 100755 src/libiar/bsearch.asm create mode 100755 src/libiar/build.ban create mode 100755 src/libiar/calloc.asm create mode 100755 src/libiar/ceil.asm create mode 100755 src/libiar/cos.asm create mode 100755 src/libiar/cosh.asm create mode 100755 src/libiar/ctype.asm create mode 100755 src/libiar/daddexp.asm create mode 100755 src/libiar/div.asm create mode 100755 src/libiar/errno.asm create mode 100755 src/libiar/exit0.asm create mode 100755 src/libiar/exit1.asm create mode 100755 src/libiar/exit2.asm create mode 100755 src/libiar/exp.asm create mode 100755 src/libiar/exp10.asm create mode 100755 src/libiar/fabs.asm create mode 100755 src/libiar/floor.asm create mode 100755 src/libiar/fmod.asm create mode 100755 src/libiar/formattedread.asm create mode 100755 src/libiar/formattedwrite.asm create mode 100755 src/libiar/free.asm create mode 100755 src/libiar/frexp.asm create mode 100755 src/libiar/getchar.asm create mode 100755 src/libiar/getchar0.asm create mode 100755 src/libiar/getchar1.asm create mode 100755 src/libiar/getchar2.asm create mode 100755 src/libiar/gets.asm create mode 100755 src/libiar/heap.asm create mode 100755 src/libiar/isalnum.asm create mode 100755 src/libiar/isalpha.asm create mode 100755 src/libiar/iscntrl.asm create mode 100755 src/libiar/isdigit.asm create mode 100755 src/libiar/isgraph.asm create mode 100755 src/libiar/islower.asm create mode 100755 src/libiar/isprint.asm create mode 100755 src/libiar/ispunct.asm create mode 100755 src/libiar/isspace.asm create mode 100755 src/libiar/isupper.asm create mode 100755 src/libiar/isxdigit.asm create mode 100755 src/libiar/labs.asm create mode 100755 src/libiar/largectype.asm create mode 100755 src/libiar/ldexp.asm create mode 100755 src/libiar/ldiv.asm create mode 100755 src/libiar/libiar.lib create mode 100755 src/libiar/log.asm create mode 100755 src/libiar/log10.asm create mode 100755 src/libiar/longjmp.asm create mode 100755 src/libiar/longjmp2.asm create mode 100755 src/libiar/malloc.asm create mode 100755 src/libiar/mediumread.asm create mode 100755 src/libiar/mediumwrite.asm create mode 100755 src/libiar/memchr.asm create mode 100755 src/libiar/memcmplc.asm create mode 100755 src/libiar/memcpy.asm create mode 100755 src/libiar/memmove.asm create mode 100755 src/libiar/memsetlc.asm create mode 100755 src/libiar/modf.asm create mode 100755 src/libiar/n.bat create mode 100755 src/libiar/pow.asm create mode 100755 src/libiar/printf.asm create mode 100755 src/libiar/putchar.asm create mode 100755 src/libiar/putchar0.asm create mode 100755 src/libiar/putchar1.asm create mode 100755 src/libiar/putchar2.asm create mode 100755 src/libiar/puts.asm create mode 100755 src/libiar/qsort.asm create mode 100755 src/libiar/rand.asm create mode 100755 src/libiar/realloc.asm create mode 100755 src/libiar/satan.asm create mode 100755 src/libiar/scanf.asm create mode 100755 src/libiar/setjmp.asm create mode 100755 src/libiar/silly.zip create mode 100755 src/libiar/sin.asm create mode 100755 src/libiar/sinh.asm create mode 100755 src/libiar/sinus.asm create mode 100755 src/libiar/smallwrite.asm create mode 100755 src/libiar/sprintf.asm create mode 100755 src/libiar/sqrt.asm create mode 100755 src/libiar/srand.asm create mode 100755 src/libiar/sscanf.asm create mode 100755 src/libiar/strcatlc.asm create mode 100755 src/libiar/strchrlc.asm create mode 100755 src/libiar/strcmplc.asm create mode 100755 src/libiar/strcoll.asm create mode 100755 src/libiar/strcpylc.asm create mode 100755 src/libiar/strcspn.asm create mode 100755 src/libiar/strerror.asm create mode 100755 src/libiar/strlenlc.asm create mode 100755 src/libiar/strncat.asm create mode 100755 src/libiar/strncmp.asm create mode 100755 src/libiar/strncpy.asm create mode 100755 src/libiar/strpbrk.asm create mode 100755 src/libiar/strrchr.asm create mode 100755 src/libiar/strspn.asm create mode 100755 src/libiar/strstr.asm create mode 100755 src/libiar/strtod.asm create mode 100755 src/libiar/strtok.asm create mode 100755 src/libiar/strtol.asm create mode 100755 src/libiar/strtoul.asm create mode 100755 src/libiar/strxfrm.asm create mode 100755 src/libiar/tan.asm create mode 100755 src/libiar/tanh.asm create mode 100755 src/libiar/tolower.asm create mode 100755 src/libiar/toupper.asm create mode 100755 src/libiar/vprintf.asm create mode 100755 src/libiar/vsprintf.asm create mode 100755 src/libsys/!readme! create mode 100755 src/libsys/_exit.c create mode 100755 src/libsys/access.c create mode 100755 src/libsys/alarm.c create mode 100755 src/libsys/brk.c create mode 100755 src/libsys/build-b.ban create mode 100755 src/libsys/build-l.ban create mode 100755 src/libsys/chdir.c create mode 100755 src/libsys/chmod.c create mode 100755 src/libsys/chown.c create mode 100755 src/libsys/chroot.c create mode 100755 src/libsys/close.c create mode 100755 src/libsys/creat.c create mode 100755 src/libsys/dup.c create mode 100755 src/libsys/dup2.c create mode 100755 src/libsys/execve.c create mode 100755 src/libsys/falign.c create mode 100755 src/libsys/fork.c create mode 100755 src/libsys/fstat.c create mode 100755 src/libsys/getegid.c create mode 100755 src/libsys/geteuid.c create mode 100755 src/libsys/getfsys.c create mode 100755 src/libsys/getgid.c create mode 100755 src/libsys/getpid.c create mode 100755 src/libsys/getppid.c create mode 100755 src/libsys/getprio.c create mode 100755 src/libsys/getuid.c create mode 100755 src/libsys/ioctl.c create mode 100755 src/libsys/kill.c create mode 100755 src/libsys/libsysb.lib create mode 100755 src/libsys/libsysl.lib create mode 100755 src/libsys/link.c create mode 100755 src/libsys/lseek.c create mode 100755 src/libsys/mkfifo.c create mode 100755 src/libsys/mknod.c create mode 100755 src/libsys/module.c create mode 100755 src/libsys/mount.c create mode 100755 src/libsys/n.bat create mode 100755 src/libsys/open.c create mode 100755 src/libsys/pause.c create mode 100755 src/libsys/pipe.c create mode 100755 src/libsys/read.c create mode 100755 src/libsys/reboot.c create mode 100755 src/libsys/sbrk.c create mode 100755 src/libsys/seek.c create mode 100755 src/libsys/setgid.c create mode 100755 src/libsys/setprio.c create mode 100755 src/libsys/setuid.c create mode 100755 src/libsys/signal.c create mode 100755 src/libsys/stat.c create mode 100755 src/libsys/stime.c create mode 100755 src/libsys/symlink.c create mode 100755 src/libsys/sync.c create mode 100755 src/libsys/sys0b.asm create mode 100755 src/libsys/sys0l.asm create mode 100755 src/libsys/sys1b.asm create mode 100755 src/libsys/sys1l.asm create mode 100755 src/libsys/syscalls.h create mode 100755 src/libsys/systrace.c create mode 100755 src/libsys/time.c create mode 100755 src/libsys/times.c create mode 100755 src/libsys/umask.c create mode 100755 src/libsys/umount.c create mode 100755 src/libsys/unlink.c create mode 100755 src/libsys/utime.c create mode 100755 src/libsys/waitpid.c create mode 100755 src/libsys/write.c create mode 100755 src/link-z80/aslink.h create mode 100755 src/link-z80/link-z80.exe create mode 100755 src/link-z80/link-z80.lnk create mode 100755 src/link-z80/lkarea.c create mode 100755 src/link-z80/lkdata.c create mode 100755 src/link-z80/lkeval.c create mode 100755 src/link-z80/lkhead.c create mode 100755 src/link-z80/lklex.c create mode 100755 src/link-z80/lklibr.c create mode 100755 src/link-z80/lklist.c create mode 100755 src/link-z80/lkmain.c create mode 100755 src/link-z80/lkout.c create mode 100755 src/link-z80/lkrloc.c create mode 100755 src/link-z80/lksym.c create mode 100755 src/link-z80/n.bat create mode 100755 src/link-z80/x.bat create mode 100755 src/make-3.80/ABOUT-NLS create mode 100755 src/make-3.80/AUTHORS create mode 100755 src/make-3.80/COPYING create mode 100755 src/make-3.80/ChangeLog create mode 100755 src/make-3.80/INSTALL create mode 100755 src/make-3.80/Makefile.DOS create mode 100755 src/make-3.80/Makefile.am create mode 100755 src/make-3.80/Makefile.ami create mode 100755 src/make-3.80/Makefile.in create mode 100755 src/make-3.80/NEWS create mode 100755 src/make-3.80/NMakefile create mode 100755 src/make-3.80/NMakefile$ create mode 100755 src/make-3.80/README create mode 100755 src/make-3.80/README.Amiga create mode 100755 src/make-3.80/README.DOS create mode 100755 src/make-3.80/README.W32 create mode 100755 src/make-3.80/README.customs create mode 100755 src/make-3.80/SCOPTIONS create mode 100755 src/make-3.80/SMakefile create mode 100755 src/make-3.80/acinclude.m4 create mode 100755 src/make-3.80/aclocal.m4 create mode 100755 src/make-3.80/alloca.c create mode 100755 src/make-3.80/amiga.c create mode 100755 src/make-3.80/amiga.h create mode 100755 src/make-3.80/ar.c create mode 100755 src/make-3.80/arscan.c create mode 100755 src/make-3.80/build.sh.in create mode 100755 src/make-3.80/build_w32.bat create mode 100755 src/make-3.80/commands.c create mode 100755 src/make-3.80/commands.h create mode 100755 src/make-3.80/config.ami create mode 100755 src/make-3.80/config.h create mode 100755 src/make-3.80/config.h-vms create mode 100755 src/make-3.80/config.h.W32 create mode 100755 src/make-3.80/config.h.in create mode 100755 src/make-3.80/configh.dos create mode 100755 src/make-3.80/configure create mode 100755 src/make-3.80/configure.bat create mode 100755 src/make-3.80/configure.in create mode 100755 src/make-3.80/debug.h create mode 100755 src/make-3.80/default.c create mode 100755 src/make-3.80/dep.h create mode 100755 src/make-3.80/dir.c create mode 100755 src/make-3.80/dosbuild.bat create mode 100755 src/make-3.80/expand.c create mode 100755 src/make-3.80/file.c create mode 100755 src/make-3.80/filedef.h create mode 100755 src/make-3.80/function.c create mode 100755 src/make-3.80/getloadavg.c create mode 100755 src/make-3.80/getopt.c create mode 100755 src/make-3.80/getopt.h create mode 100755 src/make-3.80/getopt1.c create mode 100755 src/make-3.80/gettext.h create mode 100755 src/make-3.80/glob/COPYING.LIB create mode 100755 src/make-3.80/glob/ChangeLog create mode 100755 src/make-3.80/glob/Makefile.am create mode 100755 src/make-3.80/glob/Makefile.ami create mode 100755 src/make-3.80/glob/Makefile.in create mode 100755 src/make-3.80/glob/SCOPTIONS create mode 100755 src/make-3.80/glob/SMakefile create mode 100755 src/make-3.80/glob/configure.bat create mode 100755 src/make-3.80/glob/fnmatch.c create mode 100755 src/make-3.80/glob/fnmatch.h create mode 100755 src/make-3.80/glob/glob.c create mode 100755 src/make-3.80/glob/glob.h create mode 100755 src/make-3.80/hash.c create mode 100755 src/make-3.80/hash.h create mode 100755 src/make-3.80/implicit.c create mode 100755 src/make-3.80/job.c create mode 100755 src/make-3.80/job.h create mode 100755 src/make-3.80/link.dbg create mode 100755 src/make-3.80/loadavg.c create mode 100755 src/make-3.80/main.c create mode 100755 src/make-3.80/make.1 create mode 100755 src/make-3.80/make.h create mode 100755 src/make-3.80/make.lnk create mode 100755 src/make-3.80/makefile.com create mode 100755 src/make-3.80/makefile.vms create mode 100755 src/make-3.80/misc.c create mode 100755 src/make-3.80/n.bat create mode 100755 src/make-3.80/read.c create mode 100755 src/make-3.80/readme.vms create mode 100755 src/make-3.80/remake.c create mode 100755 src/make-3.80/remote-cstms.c create mode 100755 src/make-3.80/remote-stub.c create mode 100755 src/make-3.80/respf.$$$ create mode 100755 src/make-3.80/rule.c create mode 100755 src/make-3.80/rule.h create mode 100755 src/make-3.80/signame.c create mode 100755 src/make-3.80/subproc.bat create mode 100755 src/make-3.80/variable.c create mode 100755 src/make-3.80/variable.h create mode 100755 src/make-3.80/version.c create mode 100755 src/make-3.80/vmsdir.h create mode 100755 src/make-3.80/vmsfunctions.c create mode 100755 src/make-3.80/vmsify.c create mode 100755 src/make-3.80/vpath.c create mode 100755 src/make-3.80/w32/compat/dirent.c create mode 100755 src/make-3.80/w32/include/dirent.h create mode 100755 src/make-3.80/w32/include/pathstuff.h create mode 100755 src/make-3.80/w32/include/sub_proc.h create mode 100755 src/make-3.80/w32/include/w32err.h create mode 100755 src/make-3.80/w32/pathstuff.c create mode 100755 src/make-3.80/w32/subproc/NMakefile create mode 100755 src/make-3.80/w32/subproc/build.bat create mode 100755 src/make-3.80/w32/subproc/misc.c create mode 100755 src/make-3.80/w32/subproc/proc.h create mode 100755 src/make-3.80/w32/subproc/sub_proc.c create mode 100755 src/make-3.80/w32/subproc/w32err.c create mode 100755 src/make-3.80/x.bat create mode 100755 src/man/apropo-b.lnk create mode 100755 src/man/apropo-l.lnk create mode 100755 src/man/apropos.c create mode 100755 src/man/build-b.ban create mode 100755 src/man/build-l.ban create mode 100755 src/man/catman-b.lnk create mode 100755 src/man/catman-l.lnk create mode 100755 src/man/catman.8 create mode 100755 src/man/catman.bat create mode 100755 src/man/catman.c create mode 100755 src/man/man-b.lnk create mode 100755 src/man/man-l.lnk create mode 100755 src/man/man.c create mode 100755 src/man/mkwhatis.bat create mode 100755 src/man/mkwhatis.sed create mode 100755 src/man/mkwhatis.sh create mode 100755 src/man/n.bat create mode 100755 src/man/utils.c create mode 100755 src/man/utils.h create mode 100755 src/mkutil/4dos.com create mode 100755 src/mkutil/bin2c.c create mode 100755 src/mkutil/bin2c.exe create mode 100755 src/mkutil/crc.c create mode 100755 src/mkutil/crc.com create mode 100755 src/mkutil/crcd.com create mode 100755 src/mkutil/ihex2bin.c create mode 100755 src/mkutil/ihex2bin.exe create mode 100755 src/mkutil/mklink-b.bat create mode 100755 src/mkutil/mklink-l.bat create mode 100755 src/mkutil/mknbat-b.bat create mode 100755 src/mkutil/mknbat-l.bat create mode 100755 src/mkutil/n.bat create mode 100755 src/mkutil/setfsize.c create mode 100755 src/mkutil/setfsize.exe create mode 100755 src/mkutil/touch.c create mode 100755 src/mkutil/touch.exe create mode 100755 src/sh/bsh/args.c create mode 100755 src/sh/bsh/blok.c create mode 100755 src/sh/bsh/brkincr.h create mode 100755 src/sh/bsh/bsh.lnk create mode 100755 src/sh/bsh/builtin.c create mode 100755 src/sh/bsh/cmd.c create mode 100755 src/sh/bsh/ctype.c create mode 100755 src/sh/bsh/ctype.h create mode 100755 src/sh/bsh/data.c create mode 100755 src/sh/bsh/defs.h create mode 100755 src/sh/bsh/dup.h create mode 100755 src/sh/bsh/error.c create mode 100755 src/sh/bsh/expand.c create mode 100755 src/sh/bsh/fault.c create mode 100755 src/sh/bsh/io.c create mode 100755 src/sh/bsh/junk/REPL8.PMM create mode 100755 src/sh/bsh/junk/REPL9X.PMM create mode 100755 src/sh/bsh/junk/REPL9Y.PMM create mode 100755 src/sh/bsh/junk/X.bat create mode 100755 src/sh/bsh/junk/makefile create mode 100755 src/sh/bsh/junk/nick.h create mode 100755 src/sh/bsh/junk/pre.bat create mode 100755 src/sh/bsh/junk/preall.bat create mode 100755 src/sh/bsh/junk/silly.c create mode 100755 src/sh/bsh/junk/silly.exe create mode 100755 src/sh/bsh/junk/silly.zip create mode 100755 src/sh/bsh/junk/silly1.zip create mode 100755 src/sh/bsh/junk/silly2.zip create mode 100755 src/sh/bsh/junk/silly3.zip create mode 100755 src/sh/bsh/mac.h create mode 100755 src/sh/bsh/macro.c create mode 100755 src/sh/bsh/main.c create mode 100755 src/sh/bsh/mode.h create mode 100755 src/sh/bsh/msg.c create mode 100755 src/sh/bsh/n.bat create mode 100755 src/sh/bsh/name.c create mode 100755 src/sh/bsh/name.h create mode 100755 src/sh/bsh/print.c create mode 100755 src/sh/bsh/service.c create mode 100755 src/sh/bsh/setbrk.c create mode 100755 src/sh/bsh/stak.c create mode 100755 src/sh/bsh/stak.h create mode 100755 src/sh/bsh/string.c create mode 100755 src/sh/bsh/sym.h create mode 100755 src/sh/bsh/timeout.h create mode 100755 src/sh/bsh/word.c create mode 100755 src/sh/bsh/xec.c create mode 100755 src/sh/msh/Makefile create mode 100755 src/sh/msh/msh.lnk create mode 100755 src/sh/msh/n.bat create mode 100755 src/sh/msh/sh.1 create mode 100755 src/sh/msh/sh.h create mode 100755 src/sh/msh/sh1.c create mode 100755 src/sh/msh/sh2.c create mode 100755 src/sh/msh/sh3.c create mode 100755 src/sh/msh/sh4.c create mode 100755 src/sh/msh/sh5.c create mode 100755 src/sh/msh/sh6.c create mode 100755 src/sh/sash/build-b.ban create mode 100755 src/sh/sash/build-l.ban create mode 100755 src/sh/sash/cmd_dd.c create mode 100755 src/sh/sash/cmd_ed.c create mode 100755 src/sh/sash/cmd_grep.c create mode 100755 src/sh/sash/cmd_ls.c create mode 100755 src/sh/sash/cmd_tar.c create mode 100755 src/sh/sash/cmds.c create mode 100755 src/sh/sash/n.bat create mode 100755 src/sh/sash/readme create mode 100755 src/sh/sash/sash-b.lnk create mode 100755 src/sh/sash/sash-l.lnk create mode 100755 src/sh/sash/sash.1 create mode 100755 src/sh/sash/sash.c create mode 100755 src/sh/sash/sash.h create mode 100755 src/sh/sash/sashcfg.h create mode 100755 src/sh/sash/utils.c create mode 100755 src/simple/adduser.c create mode 100755 src/simple/align.c create mode 100755 src/simple/banner.c create mode 100755 src/simple/basename.c create mode 100755 src/simple/bogomips.c create mode 100755 src/simple/build-b.ban create mode 100755 src/simple/build-l.ban create mode 100755 src/simple/cal.c create mode 100755 src/simple/cat.c create mode 100755 src/simple/cdiff.c create mode 100755 src/simple/cgrep.c create mode 100755 src/simple/chgrp.c create mode 100755 src/simple/chmod.c create mode 100755 src/simple/chown.c create mode 100755 src/simple/cksum.c create mode 100755 src/simple/cmp.c create mode 100755 src/simple/cp.c create mode 100755 src/simple/cr$.c create mode 100755 src/simple/cr.c create mode 100755 src/simple/crc.c create mode 100755 src/simple/cron.c create mode 100755 src/simple/date.c create mode 100755 src/simple/dd.c create mode 100755 src/simple/df.c create mode 100755 src/simple/dhry.c create mode 100755 src/simple/diff.c create mode 100755 src/simple/dirname.c create mode 100755 src/simple/diskusag.c create mode 100755 src/simple/dosread.c create mode 100755 src/simple/dtree.c create mode 100755 src/simple/du.c create mode 100755 src/simple/echo.c create mode 100755 src/simple/ed.c create mode 100755 src/simple/expr.c create mode 100755 src/simple/false.c create mode 100755 src/simple/fgrep.c create mode 100755 src/simple/file.c create mode 100755 src/simple/find.c create mode 100755 src/simple/fld.c create mode 100755 src/simple/fortune.c create mode 100755 src/simple/grep.c create mode 100755 src/simple/gres.c create mode 100755 src/simple/head.c create mode 100755 src/simple/id.c create mode 100755 src/simple/inodes.c create mode 100755 src/simple/kill.c create mode 100755 src/simple/lpd.c create mode 100755 src/simple/lpr.c create mode 100755 src/simple/ls.c create mode 100755 src/simple/m.bat create mode 100755 src/simple/man.c$ create mode 100755 src/simple/mkdir.c create mode 100755 src/simple/mknod.c create mode 100755 src/simple/more.c create mode 100755 src/simple/mount.c create mode 100755 src/simple/n.bat create mode 100755 src/simple/ncheck.c create mode 100755 src/simple/ncr$.c create mode 100755 src/simple/od.c create mode 100755 src/simple/passwd.c create mode 100755 src/simple/pathchk.c create mode 100755 src/simple/pr.c create mode 100755 src/simple/printenv.c create mode 100755 src/simple/ps.c create mode 100755 src/simple/pwd.c create mode 100755 src/simple/readall.c create mode 100755 src/simple/reboot.c create mode 100755 src/simple/renice.c create mode 100755 src/simple/rm.c create mode 100755 src/simple/rmdir.c create mode 100755 src/simple/roff.c create mode 100755 src/simple/setclock.c create mode 100755 src/simple/sort.c create mode 100755 src/simple/split.c create mode 100755 src/simple/su.c create mode 100755 src/simple/sum.c create mode 100755 src/simple/sync.c create mode 100755 src/simple/tail.c create mode 100755 src/simple/tar.c create mode 100755 src/simple/tee.c create mode 100755 src/simple/ter.c create mode 100755 src/simple/termcap.c create mode 100755 src/simple/test.c create mode 100755 src/simple/tget.c create mode 100755 src/simple/time.c create mode 100755 src/simple/top.c create mode 100755 src/simple/touch.c create mode 100755 src/simple/tr.c create mode 100755 src/simple/true.c create mode 100755 src/simple/ualign.c create mode 100755 src/simple/umount.c create mode 100755 src/simple/uname.c create mode 100755 src/simple/uniq.c create mode 100755 src/simple/uudecode.c create mode 100755 src/simple/uuencode.c create mode 100755 src/simple/wc.c create mode 100755 src/simple/which.c create mode 100755 src/simple/whoami.c create mode 100755 src/simple/yes.c create mode 100755 src/troff/README create mode 100755 src/troff/d.h create mode 100755 src/troff/font/chars.c create mode 100755 src/troff/font/ftB.c create mode 100755 src/troff/font/ftBC.c create mode 100755 src/troff/font/ftC.c create mode 100755 src/troff/font/ftCE.c create mode 100755 src/troff/font/ftCI.c create mode 100755 src/troff/font/ftCK.c create mode 100755 src/troff/font/ftCS.c create mode 100755 src/troff/font/ftCW.c create mode 100755 src/troff/font/ftG.c create mode 100755 src/troff/font/ftGI.c create mode 100755 src/troff/font/ftGM.c create mode 100755 src/troff/font/ftGR.c create mode 100755 src/troff/font/ftI.c create mode 100755 src/troff/font/ftL.c create mode 100755 src/troff/font/ftLI.c create mode 100755 src/troff/font/ftPA.c create mode 100755 src/troff/font/ftPB.c create mode 100755 src/troff/font/ftPI.c create mode 100755 src/troff/font/ftR.c create mode 100755 src/troff/font/ftS.c create mode 100755 src/troff/font/ftSB.c create mode 100755 src/troff/font/ftSI.c create mode 100755 src/troff/font/ftSM.c create mode 100755 src/troff/font/ftUD.c create mode 100755 src/troff/font/ftXM.c create mode 100755 src/troff/font/linkrc create mode 100755 src/troff/font/makefile create mode 100755 src/troff/font/mkfont.c create mode 100755 src/troff/font/mkfont1.c create mode 100755 src/troff/hytab.c create mode 100755 src/troff/makefile create mode 100755 src/troff/n.bat create mode 100755 src/troff/n1.c create mode 100755 src/troff/n10.c create mode 100755 src/troff/n2.c create mode 100755 src/troff/n3.c create mode 100755 src/troff/n4.c create mode 100755 src/troff/n5.c create mode 100755 src/troff/n6.c create mode 100755 src/troff/n7.c create mode 100755 src/troff/n8.c create mode 100755 src/troff/n9.c create mode 100755 src/troff/ni.c create mode 100755 src/troff/nii.c create mode 100755 src/troff/nmake create mode 100755 src/troff/nroff.exe create mode 100755 src/troff/nroff.lnk create mode 100755 src/troff/nroff.w32 create mode 100755 src/troff/ntab.c create mode 100755 src/troff/s.h create mode 100755 src/troff/sh.1 create mode 100755 src/troff/suftab.c create mode 100755 src/troff/t10.c create mode 100755 src/troff/t6.c create mode 100755 src/troff/tab3.c create mode 100755 src/troff/tdef.h create mode 100755 src/troff/term/code.300 create mode 100755 src/troff/term/makefile create mode 100755 src/troff/term/n.bat create mode 100755 src/troff/term/tab300-12.c create mode 100755 src/troff/term/tab300.c create mode 100755 src/troff/term/tab300s-12.c create mode 100755 src/troff/term/tab300s.c create mode 100755 src/troff/term/tab37 create mode 100755 src/troff/term/tab37.asm create mode 100755 src/troff/term/tab37.c create mode 100755 src/troff/term/tab37.lnk create mode 100755 src/troff/term/tab450-12-8.c create mode 100755 src/troff/term/tab450-12.c create mode 100755 src/troff/term/tab450.c create mode 100755 src/troff/term/tab832.c create mode 100755 src/troff/term/taba1.c create mode 100755 src/troff/term/tablp.c create mode 100755 src/troff/term/tabtn300.c create mode 100755 src/troff/textscript create mode 100755 src/troff/tmac/tmac.an create mode 100755 src/troff/tmac/tmac.an$ create mode 100755 src/troff/tmake create mode 100755 src/troff/tw.h create mode 100755 src/troff/v.h diff --git a/bin/banked/adduser b/bin/banked/adduser new file mode 100755 index 0000000000000000000000000000000000000000..759c5d148ab12fa7182dffa5580df6e681b2f9db GIT binary patch literal 14678 zcmc&*4|G)3nSV3+Loz@}K=GxBzLzOD5Di(uF|e8n;s92Hg2q2+a7Z#qG|Ys_j6*8U zA^4||n)aNYt=m1jwOv$DQ9!}qzqZC4+(I_B^lW-|yZx#uomh;6L=8gz%b8sIU60{yZ3(g`@Z}AyWjop^XP87Qn^@BE>V`rHHS95FMkzR_Ct|+wlWNhxXKs2r`2IPs8mVqi~rE_5Mxq*|pxlyMt&^dVG=#kja z)>GT+ww&6wVsKAx*uJz;X4cN#@OLsC34Dg z8@(&DmEYy4Uv!ss7j|FXJ^My&NOHMwpv&*+|h zYyHxqN%DxcTTnQ}O0vei=Fv+p_GAx`*Sp#T(=Iw>-K1?!L~! zqXQ>~VtTf+IJ!6DjJ_N>?u<6Sw8j|?zPMuWc;C^X=)uSaXY}>R-OlK15%eF3tSBxn z9yH{K@yB_*jmLNL_zq+I#8B^}&p0=H=UM07c;eCZlkKIM1I~Gc;B4SHORF~}l#jP} zUHSwVF@+BCSLRYEm#T6ooYV7-$5~s0#}_VSZZ8Vd*V&W(gaJ3S|3}dHKh%{gf48Pw z`SFUuqeGCB4H|Wy)m3}p_0&B&le)+7OW>EBN!Oiqm9R*K4A+*CmcNCbnN-%R<+RW< z*=0RyCO_9~p=T$pDD5oXqyBs__FzM&bs5_q$1+Z&Ovk#0-XlZg&)gVqq{^)L{e|~Z z|)D*JXkVpNq$m5KQMVKP^9Mp&bGWG~5DeAUlxVjH z19d^~Ce6E1b_jf0O~8LuNUQfgQmc8Zt81H^wNOCw*3@WT&0iY&Ah;yOu;y!kAedKQAna%U z9k&JQ8vG_7uBw~)b#u5OG;fKf+zC>RV%+cDRI67(rC~2VsD=pD(t`7v7AqlWk52XbBwam{gH4Pyab%P%Y z+~f^41pGpkrVO<8bDAH3`W&8cW244=fzcIE?fN-258#!xY`i+|_6GgHwL~bEJ2h`( zu-04C!c2jOtF=%)bQ=kT8^LkF?`v$R4r!5wP`yKm)I&7}bRgn~=oyq%q^(+BBDlD! zSs&Hs z5p88%eJz$J){2ph4Sr}DL(1)j>6t^0RsV&Y1i2cM9COk9fJ0z6-cu-zHUubnbwH}d zo8nky2%tI;WX`{(t#4US!CX7;Vv#UbVOKC$*gw>>w5EpDD9wk5;cX5jszj7q*e11V zC_*UObS7=1xBB65lQ2<0N~lOsTEj(vZuYW6852`5Y~;Y;g}j#Vzcu1t`QGeMR(nN! zNXbMnFSuJSZP1t&UNQ&&rltv36Etd+Th^|vSc5pB1)6Hv!cq?AP?XY*N~u!1MJc^U z;lE^(f61gKTIPS|wi*9?Pf_yCPCVy+&-mwQo1$6zGj_^M@Cw zDn`jOhK$FRXQLej4h8eq-^cTfSryhDRw+X~frSZ9wvL07wdKjPFK% zJ>IpT6^mJv+)t4>MNZ){NRcnFnxZ0xzw!i%F1)v?kd+A!n zdy}&GfjiOC8?CJe?m=tyay>_ZKuf3T4_jud2eIPMDRMeB*MKJf=j1!h6CULus`#8d zr*or;rDge+cKLn3D81d%jwZb0$G`K7($aC`rQ^pJ|DrTsf7ZfK*PdHx(dSwQEjryb zaw|_2E84UkYk&+h^K7a;Psvu|H-EFO<$x<+e`oyU@#Yd=U(_}uzD}re9*Z7YWt=hn zkCthJ`lP2U61NC+)i{CHz{D@HKn@mIK$UTzW^45Z5T)=*3Vr(6AuWg8Cu_+4sWQK) zEv8@jzd|)Yq0fLS7bqyq4XPTT%Fm#6!@<6$&{;_8X7Ue^@3WXb-%3UHqdrOn=V`I!**Zs|ai#J*Ar+2iXF_^c9jkWBC}rEl>pbu3#S<#GjSi zml*H2QnJeWhvySAJ4`~V&htm`duBWhD+yr-iHp%_IG={uVbUm+i(w+0#uL$hsVs)S z{gZ*=?|p0o(J%X_eXx`w{rq-%14X~;SMJWv?76b_(GR>7`GnkmQ6$E^@1~7$P{-0@ zdWiqCz}i1Z{*&bUG-hgAS7HwpmXyI^o85@E&0M`FB$tD|oNa zfB9WAZ0eZ?q!BqOe2zlHFdbFzv>>%aMHtYB92|@|hUP-K(HMU4*Hm$iJi}D=HC3L) z=nq9ifBptw{A6N`X8chP0{jwztm+(94x=Tu51Vb9jE?2oUa3QXoT^XRk=B?#Z-=>< z0&8%WE3v3^H8ggf65kbe(`<+!)PQBh^xIgo#XA6dj(o#RXfp3y1Nw9Y#R4)}6FWev zB^YJ@i|I=(%njP&wv<;cVXrhfs2Cv6XKZIePq*BQp+SAUWh%B;-Hre_NnsWiNuR~; z$r_Uf@72q{F3m2Q)utzt$2;Y|I-1n;mBlu@k}In<7s{Lbyp5WGpQp>o2<`NBmvc@Pf@7CPM(Zh9Qu2)VasQZ z@ys@!nev&D(eNOuB}Zg>!EgFT7HKB=vd$N2_g2__G6}m^6lP&V>sd|@5)?^N)J`24 z+7^okaagnX7MjxvhEib@fjAquy5`(DziS7D?G(z8I9w%EWv9vvtX^m?4Tv=w3#)Yc z9+Gp^W6aB(JJXAf_HR4(=sJ{H(n4?qG8}b#;%g~9Orep-4jpT;jC-8EdJ3PV&^huC zlWzp_KTDo-kelR#izwj5C2}{ZEQByc>3OWR^a^&@C_OcbdJcVmECM?~^BK{6b}S;3 zH3?hxj}#rH-D5XkgPPS=o{32D1Bwn)$B1i|h50iIP@S)&9`stdbM`FCJlyP8L&&ZT?uzQP3u~PaL z*ytaQG(6~Z#$d?C9IjsFGQn8GgPoh5O?}4CYL(=7kZ*GANU#1)t3wP9N~7%sQISa< zFC4(DhC8#n9_GI?RGE0yr$&Q51M$TQ?uiQzeI|-{4B9Tt2 zz6-vN^v<8U6ZURbOCbBAsXJvI`ond#p!uQED#kgjK2 zWhW&w%)T~Ekr6ybDKeJwJO_15c3mg5$D+!O_D@5d5Syql$Ah5rdIY2B|B|(ujNE%W z2#P=`<+i`W)g<4X6rMt%sl`=2i&`_4Vs9{Vd*zJE%*y$dODhGoGx?Hj^+ws$WRu*( zDEEzIsBBxzo$I^r2`P#H_J6Vr=f3g zN>IQdnsyThMS0=c6*g6o@~xIBr94NO7>%If)H`f259#3Ic*enP6>lUk4+>{eD2uwY zqOKBnr}QPm81hoa@F?p~;^0^-7?w=DKXA8n0SY@PG}#7|h=03l2fRaCWKq|Sw0hh* zPQ-C8LuP>m(ajIMXp}Xo(Hkbvw*;FatHdFok5&ua%0@G;YEU~ z^Ux_h2}6bxm)oAGlM~oD&SV;@6h36Sy`;`FVEc@me+>^Z72al~y-|mVcpV6U@Cvy! z0VaJEl8UwTCj(phr`0`nMp?7<%uOrU;(3=9QGq>E#sKL=QkJkv2Q5nQi6^OkCL@p> zLAW!$-;6cWt^Oio&4$+D6jqM=w0V@8#^jM0cFt$>Vh=R|hOGiU3{+e}n-eW>YB~F< zBjK{EzoCjGwi170E}s#lBmODLmbiL(YM-hRj{W=%uIUu*?^gm8{iOeNUAgwk8|ggp ze1@|wWY~kip-&yxF9{+hqNpIlwv>?58FhBZ4fLM-=C5owlL#&jq-0cPloFh{alsxZ zLKqfNy3UXR-;&5z^p?$&0O^jIVGHMUccPCT?;7N~Yx;9Nb>?qcler$3l z5~L*zl;Kjv&M6QHrvnw1h&t2S4<9x9;R1705-}1gGqJ;IgMCIM^mrPXyiqc`(&`*? zk223Uk=*lCH2MFL8jj*uABpRlC7 zgIpb&7)dgTS=Qk^gT@g)FNoApl$JcLViyvr09y@9DdkYBgVxY+(RI%jauhqWv~bRP zVWikW?CS9gR*ekcE4Z#LW}EwTiqs}PG8h@QnLU+>-RRa0HiuF$_i5ni1+W?K@nxHy`asyWPtTj?5k;QxTVcSY(a zR1NwY*7c6#O?2()j4vC&FV+j#&fEcbVrTr;Snmalb{)Ha$=s(CPS>UU&|G=^aJVM% zBUj77FuA{)OYWhkjikgj2}eM#U&PJ;S ztCDLkn%l0fG+tfp>W%VM24r=C+2Ryk)eW$cb`|l7)lgL0u1+>yuWeTqTlP2(N=s}@ zu-kq`l|$z%Qu2SEE@{yy?>J*!^Qy3!aqcT3{aLC!hxvaSVrwb7x}E%I$oDn2D3*a0 zaF{Ab(tz{N1Dx9~_W_<^!)3Cfw?C3Lbp&~F^ucX%syO@+S1e`Fhv^kc;qu&6S~68Q ziwwXro{CIy1X*I*#V9;Rp@clvMHAO(2;zLggAH@$!~38^&BLDOz>#v%7)u~Q(R|un zaD!_$Rg94bbMwhpz^9%m^3_0T400N7433d6LE$_KO_SLd4g=$pP2Za=mgg`KIW6$b1= z0gKbKgF)O5MV)@ZGBK6;!&DZCI%5KSMl`J&o|&$$M~4#*O)a<4zUkC4Lqk$%J)?H5 zeUSVk8k?a#oCJ#t;zJVs3k44{j%CZyw%$Ne40N`0n+ z=DdHRw%ktpST^Sq1McT3@&dUJBISNvBljyfDZa`iU#7@ja=(b?OZe?`kbA$P&q9ql z{04yWR`lN_ zky7$Nv=!X%fF56_j=iot^6w(wa}<7&LNCEfqr0f%Ic+LMUr%USHux-6+f0yGDDd$dW_kQ)8)#cUes#oE+pmtw1 zRWGc5W8-@p|7By(#)8`SHomY?VuEJbq`OYklKXiZxnEGaKJ>~VSouM2xDVOz(Ce{? z5BNCoYb8?buPZK=na3^)JvZU1=35tlTF5s{0#vb!JkQB$_v-a{Lunmv*BFFZ6R?;pSPZP^MGU@#=e~Ragx0>(ctbTuuylnK(S$4w zsD%>?kV8}WEegF&o8O_Pcd2S0RqpTQmD*5p!cPAVdC>b7RlW_@%S8AySSR=4pOX8{ z9dP4A$MS>&?4yqT*dpDBf5rpqs`4D#C;C*1zC|5xQ^z~h@h*av`|xuD;;Qm|1A=G4 zOE7Cj`84j^z5fQjXgK^Lcar}w`QAhTzZN3FN#-zl-eg}%S7WK-4f1rP`b0rCEn*oy z;SscX7d1VH8y5sl=}zk96HA7|!n8cQ$o~fUI*=Lj1BXFguM1I?o3PQ>)uM}|kelLJvR3QiQ5%=LFY;1wCPs6j>v$3lesjzr{Q0ga=oz$f!!G0mDU zlm7tuUXvSVuYQH~fF$?3(Ik$-ItL}8y{Fh6xFuH&v+Io?=tEF4b9DhA7c>q;V&lSF zVkvb`jk;#y%`5A%rgw9B1bc0a4+K-FW2%-}Zc}ah*BlvNf;umuy{%4osCh8`9S)s* za+P&Q!KyfY>Q{5H7PrPrpq}43P(tKlFiL6ITgwV;cH}l(=`srJ8C@UNo98RuT(F&N zJK*{&*i)XXnEYqScMdx|Cr-ugYYdkBd^g>b^SDuS-JD5HSt%UO4(zcNl7^YQ%G6v= zduKcB%6eSx+$?ymnnIORML6o&i_L-)KygIX4ymP5#Bw1$KQIa?U`rggn+?m{jeeem zvVnZT`Bpo^lEFD!P~^Nij9m`(xtnAUB0b}P$0W8S9HkB%x;`jHIa)=wkf5jXxiURY z2FPNX=(?o(w(RC=I%{FP+9#*f&czK=?OfJjwddKOXi;>K_9N^-)S;%zl?Wk#1F`Mf zM2a^~`5r8Ef|4b&BR+T;w+E)3`~jwT_APRsYe9hx!F=Rd+!}E5SForZ&@%HwY0Wr4 z$zFMQg5@d@Ln5!V1ji9BVX)qFqlaBr= z7?mA&!p_>9`rFGI`I)1+E)>$`5E9tGeLHHaA7mo^FGb)s3SK7t$NIm8+nVxh>0~`W z#`SA5F@=36`9TRr)I#ochZfV?<;DpCU3&J4D=lU!x zS_SXiYkDodYmm+chqyH&$ceHD$juo4%>y_92HdG|07p3sF^C~0BC}TLbUM3l=$_3# zV?0$}Lq)%U+@s6MJ=U%-Z!hw+qlje&JDEF*I-?AbM$t{&z{Hmw`*4#CS`0T2wKne0 zjhS^aUfe@QWEB(R-(K0yotIiWWg$-x6)_k^Kwkjqp@cCLa)Ugan`synOhPC>bzN;? zB_-S6xBJr!rh2u@&Gn5(C(2lrQjDq9SfmkOzp@>n9HK)>&_a6x5-|WB7h#{*WUUXH zOWz-HM&OZ#%+#w`A!2PTpfv?bCNzJY)I7_d)hr4)^NhX5tvKDbiIMRYlql;9C8xD# zc%322v~D3gobS%RyoGFdm!>KQRZa%R3$Ll>&u&|CW!oEvT+?lQa_6%n+UR9_6-`VV zP*Xrk z4C8l?B+~%$VoO{ZWx5t25|5iG1cnR`7fK^Y?Qntx1g;fO$z)aa34Nt5p`-md$NHPZ z#T$nKYy*5>oK6rKnjIcN;VRSL&2QXhiYs4k8CPtg*nIpvFztHY?>my(3;{0kM^+hb zU64ofrLiax#?qr^!PS(!Sdp4{9#ca5W|&EjA;-dT*PJSE2raA4=W~9>3cksbC20pT z8V*=aS#Rf8;`>8ZfsxfxD812TgfM2uVp= zE7CE}lAJIpMEA^bF&5GN_i~1uZ+;_b_?f_c0TyjM3WPb4SIRlS_-iZ1;pF@oJB^GG zF}`R9*R>Vp+AG_NX17uINK{*A%Yy51eGc_C{nqwE-V;3o1`ADz0t}0=!o#cE3pua~ zEwgnA((J6lC=5F49_g*1+`U!HvpKfmO{V5$lOa#zi;Q*PXnh9Rj#aZW}%7IGCxRLE7i z*4N2fZiT!!?~z3doyG=i9^;MAL1g*g z_*!W5Fg1-BJ69GC)an!&KIGw2im?}`8_T&)I?gE9YA0qM^{9pBIo*p0VcU<2`h`f9*0qQofwLIn{#9gBa;M|7 zJ&=i=4xcRb=ffCA_|`RF+`1wdt!puCR8&|}*B4TwB0=S%1y=-k+rl}XOA^?>$`(t` zVTufpinyR=oMJ`4Ntl4g!fe;MFYl$tyIvi5IM+zRBq4i J)&XeiKL7;iRc-(P literal 0 HcmV?d00001 diff --git a/bin/banked/align b/bin/banked/align new file mode 100755 index 0000000000000000000000000000000000000000..5899fda55ab2141f21fc39639558944ac1caa048 GIT binary patch literal 7624 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 KefMd+f&VX@ax1a` literal 0 HcmV?d00001 diff --git a/bin/banked/basename b/bin/banked/basename new file mode 100755 index 0000000000000000000000000000000000000000..6224a15fb4464cf424e60f02bf13ef7837dae1aa GIT binary patch literal 892 zcmZ9K!E4h{9LIl2+OoDMhl~uFCd)R$JZ!=oWU%5|$w62Ug@TCH3eE6fJ#+;H?R?DIW&-e07Sj{24_suWw`+48ruk}ubrwYJX z00Lx>?34XBo#D+rQXl3B>CL|&`oUHP+M8sc&*d`E*d%y@y-xjjXjv_>Z1tL5^iT&t ztM4s6e^eW47W@3Of9gZQ$QuLeWYAARwNl(EZD{w4l~TF*u%rdA+m)*8K6rd51?_8O zM6n=aUde#|E6cpaZWgN}+#TP#9?D6q`nXHc8KFJKvW%{BFwCxAM#o2+VmXFxoC^zB z_R*ymMY)IN5xQfxG;p&1$9%Xp-i>5L*)U+t{8rD3pq zSu8iUcv`{5Luo0H0@Uy~ZAOm)Ix)24Nyo6U;A5V)-(C@mFkMf?ct!%IeB&2B)+O+y z0-2Bi)EWIe)9+2{5`^57VMM*;t$XrOV>$EYsFp}jn6j>!ixWvW35XgR{S#Nev#H}g zm)NaS=%&49S6={+5pU->F?%A6U_kzjOyK$9$V}myuPL}j)!(8+!j$=oQ`{*!`-UI literal 0 HcmV?d00001 diff --git a/bin/banked/bsh b/bin/banked/bsh new file mode 100755 index 0000000000000000000000000000000000000000..45057b4afd1066caca307de804232352b3ec614d GIT binary patch literal 27158 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 AbpQYW literal 0 HcmV?d00001 diff --git a/bin/banked/cal b/bin/banked/cal new file mode 100755 index 0000000000000000000000000000000000000000..21e89608bed7e1a502ef0ad6fee9a4b7d8c5b5e2 GIT binary patch literal 8525 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 L^t&~Wp%ok2Dnm02LSp|Ytn~&pnlJY(GvCcg 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ⅇ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 literal 0 HcmV?d00001 diff --git a/bin/banked/chown b/bin/banked/chown new file mode 100755 index 0000000000000000000000000000000000000000..8bdfbb6a45473e6d06082dd25eb1f89d33332b6c GIT binary patch literal 8380 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 M8P2jm_A3JY4^nWj#{d8T literal 0 HcmV?d00001 diff --git a/bin/banked/cp b/bin/banked/cp new file mode 100755 index 0000000000000000000000000000000000000000..d1c4f60b7d99c7080e375bc2892c7ac0a68ad12d GIT binary patch literal 22137 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 aicK##&qA&9JhPKYgLmS&J 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 K9Ay38LH`HRVv|__ literal 0 HcmV?d00001 diff --git a/bin/banked/crc b/bin/banked/crc new file mode 100755 index 0000000000000000000000000000000000000000..fb8618c90aa3fd843ef5a63f05407e8e6a47026b GIT binary patch literal 9075 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 V67c`cgaSdDFwvz8&f_mu{|5*`PZa7c?$ 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 literal 0 HcmV?d00001 diff --git a/bin/banked/dd b/bin/banked/dd new file mode 100755 index 0000000000000000000000000000000000000000..41ecb5266b2ec3a7fdf48e557dc8c96484948adb GIT binary patch literal 13021 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 literal 0 HcmV?d00001 diff --git a/bin/banked/df b/bin/banked/df new file mode 100755 index 0000000000000000000000000000000000000000..8f0931722c144ddd0f9f5cc61db8d517811fb023 GIT binary patch literal 9295 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 M^>wLA7A^7r0-*>zTL1t6 literal 0 HcmV?d00001 diff --git a/bin/banked/dhry b/bin/banked/dhry new file mode 100755 index 0000000000000000000000000000000000000000..a4c58b2ce994ad2a653651541604793bb4992ce0 GIT binary patch literal 8526 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 literal 0 HcmV?d00001 diff --git a/bin/banked/diff b/bin/banked/diff new file mode 100755 index 0000000000000000000000000000000000000000..11ee6f511cdd3054b53faa277e969911e8d2b291 GIT binary patch literal 26570 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 MsMkC=G`szO12HQlt^fc4 literal 0 HcmV?d00001 diff --git a/bin/banked/dirname b/bin/banked/dirname new file mode 100755 index 0000000000000000000000000000000000000000..5162c71c9bfd96e5e7dda47c5130c1053a0805c1 GIT binary patch literal 727 zcmZ8fL2DC16n?wg7MmW#DzXaVPS#4O(Do1l+e2tl$<17Zh?hXYtQK^IG?6N%IG5i0 z6TGM=^-z28mWCWE^ble3Any=l4uF}bdGCGS``$Zxr^62&;0gc- zUgs^|+Ute)>%1MVH+Vn&g0r7%c{tATA=@tIp_Aiyg8g1Q3LWRD-}Ny-27t~Wxc%n& zPG~uV{~Db6sM-~K=$s4(DQIqOJg%);k2dSx#`Mq-bT} z1LN>*0lg`7r)|4ryH8Z)kjQq|B-t`xHO7h{;A?>ZY>u!oZtYu_Rq5Q4I%VxFmPc3` zD?lo_j@}5}u~c$VT}g?|H+}V_tV#K#xj;2@NdqEG%XTBCL7+Y0=O6&{Dl-Xxcple4 zwfDbg%E4=@xtE`<3reHuDAyDzDb6gYk5j|SGoZYouSw3d`Hki(c@{Z(DRk$8uFq~k zK#D&kilZo+$VjGgI;UhTpAIr9%*K|1Sz-QGgPb^~sxH3btFQT&{mi^Z3zQ6>-h@j3 n|Lww|q@s8>1y0wOyL9jFpOu;PHfKWg+MNZd&u4RIby4_V1dLx% literal 0 HcmV?d00001 diff --git a/bin/banked/diskusag b/bin/banked/diskusag new file mode 100755 index 0000000000000000000000000000000000000000..3aff0dd54d35fb03875eccdde41b07c1b01644ee GIT binary patch literal 19904 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 ARsaA1 literal 0 HcmV?d00001 diff --git a/bin/banked/dtree b/bin/banked/dtree new file mode 100755 index 0000000000000000000000000000000000000000..b01616b8de5ef6fb48dd40716d0a755695e2d30a GIT binary patch literal 15589 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 SRBE^*!h5A!8H=owF8V*TU#j~6 literal 0 HcmV?d00001 diff --git a/bin/banked/du b/bin/banked/du new file mode 100755 index 0000000000000000000000000000000000000000..a5ea66eedbf7624e44e43373ba926fac1e6b17bf GIT binary patch literal 10731 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 literal 0 HcmV?d00001 diff --git a/bin/banked/echo b/bin/banked/echo new file mode 100755 index 0000000000000000000000000000000000000000..bd6e5a8c237d76d931876622967a4147fdaea193 GIT binary patch literal 5727 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 op literal 0 HcmV?d00001 diff --git a/bin/banked/ed b/bin/banked/ed new file mode 100755 index 0000000000000000000000000000000000000000..93cbad33431c21ce18f7e174c8205ab0f9b9c9d1 GIT binary patch literal 24122 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 literal 0 HcmV?d00001 diff --git a/bin/banked/expr b/bin/banked/expr new file mode 100755 index 0000000000000000000000000000000000000000..5e877dd645f74ef0563f003051b41bdce6f3b65d GIT binary patch literal 12074 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 ZUX4=@Q}%WFZosDG*{Jyc|HXqq;{m$IP-XxC literal 0 HcmV?d00001 diff --git a/bin/banked/fgrep b/bin/banked/fgrep new file mode 100755 index 0000000000000000000000000000000000000000..da927fe1991ed062c175b8329c5342d1a2d2a7bd GIT binary patch literal 9928 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%0DOX_q$*Cn_vhQl-8Jx{yn+;)=|!E@1{&MP$kG zfy}4fGxeJz;csp1mz1sorEt|2U^>CHnz^rOfj(+W-OK4bm){)EbETcBj(&=!WKw#2 z&(-vv%N}?Xi)hjbAUjs;WWocYKr}| zJGJL6Etd&IKKl{*)676>k&*%XM}$SC9Kqad7TCD_LfRvS;|fR2mXI#O z?whWoE(bnMt>8r{NJXR&fJCGK7LE?;eCv3w;xNXc9E-R}hN_QqOXmu@4%_Yr=SDd@ zNuiX~CEl`&RN#qL8HEYzh>zE1xMJ zsZ)S7CfO2=$w>;NsI!1Vvna^J)Om$M6Z$+6%_kuddO6ia;R1@z(i{|?gtDCdRW*fk zDeBOc%L(_La>6}J5QSwkQ>Cye7x`vV+qeXb7{^#tzp-|iSUZz^PF~`5D(al;*u++* z4_ldfb?!9q40EU(x3ovX<0+@6a`$TvMdxY-8TA!eRqWhD6ud%#iP#mE{{fc&Yt;2R ztAb2>!lPN6kpn2}X!j)S8WRh`qnz1{rn@AK{n4}i$Vb@N!>NVu@2st~(@B=iwa5Vb z5Op0U?;GgEp3=yB9J$R2MtO|7UM25QyuO0ZNhf*x75!$VoI2m6P?Wp_3Kkuqu0DJn zpss_oJeyBC$HZD%mM0%8%YTE+w}CCy=2S+8kcKc_Ttt18c8Ij7JZzLw;bRni)m=cr z0~9z&okuD3imFri07VaK`4m2t(zF?%vsC?ibIEZEoiI_WXsI#ix{)t>(A(E^m#4U7 zNzKk(k2f{9w6=A0cGuMgwgtB(x3Au|V%x84KCbx?pOf25wmq`#RL%05RW(~{HrBkj zeO1j5Ya}F`EUR>EXDxXT*~oiXiTNLvQ_%7^_{BS5!A3P(85rK{{(*^r{0GQ)P-ceI$?OR%$AJA+f!%uqkA3`T8~~$tDslZ*r94jI zBNXj(->SDTJ=qz0Y!f2paC=|4)b*9Q#+XXsw<-D#Mc<|9dvIFb)Bh?~EUuhw+4X@Kn_D@H$By)`L=5$w9^yd? zo~FQCh=V_dNRY*!Cf{3ZD~~=1s=jIfRpft@e9_Fl1>dAV6kR<2a(Q8u(E&HSD!)QUPpL)U4?|?pY_mo@3cf~x*E7kCH?^9E z^TY1>sOol*AMQTiG`*P=Lbojy=Xg7lqWM~OrA@W@6`!5~bJ3WBZK~es?ytEp$({|QZXbWBQL_wThqA?Lv4PEaV{CrpOz0{kaEVzzzZf=vCj9R^O4sUT8Px^HYyKFLUf%7nsM+ zg)Sd^fei;OiU6stLJyo2%|jp(VOR(O6o?l%Dwz5;hd;q_ly7UMR>4Njyv&q0zaw`N zJyOdp3OB+<3OC!l*->LsV$23t^V1Y8NQ^8wyQziKRrV}pzhE4Vs@qIf{ZsDVWT#bq zkWUA#X(y*!FXS1$l+3H#i!(BN1c1goVT5@yS_F7wb#Fr=FBH?vF6A4p$%j`C-^w3D z6rNC@+=23^kh~LZ&C=}P#+K8XdRS2TY*$4w2NB~*e=(Ysf$#0m(kfVFqnvtYRAq$ zc9oP&1NbxVj%h}2$`vi`9OsHSU{T#m24>d8ys$!ak*;;vJ(* zwXj5s10wL&Wy}rTI%(6YQIPx42N+M&{<9>v)L5X{7ixTA&g0418$M< zTNC?i_l+pKW%x9j1VT`j7&v-aX8Ks?h$Hek#xCF-QESS#!dzv696MV+nsnc?&+w!?UQU5wg~A!tT_sNzoF;A=N-U^R z|FOS_=AkCxtCQ>7mB>1obpABgGaMlq=v=w{Ey|{g3vAAPc#?6sEDr}GDO9(DlDBpll!W;jn4;P43Xqei zT^(U;Acm^5<>A8OT zLGfcA7GSORon| z>8FIP`nk1*;nJ<QAI0L5U;{Q@opK zLF1~M!CPHfMuJy+7rcL(7$?QRjs3r#5EdxN46I$kYam{i1xWpZ22jTYwexQ`jC)Vf fSsHLJko?AN?4)v015&7Hr9Vk2lq78uQxr0k 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 literal 0 HcmV?d00001 diff --git a/bin/banked/fortune b/bin/banked/fortune new file mode 100755 index 0000000000000000000000000000000000000000..3e86ab3c2ff4b426ddf59c69240be7339772c6db GIT binary patch literal 9333 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
7=uldj_MT;nC?;JNw#bJt*ICBVdxDOjs62$s z)O%PV;%qFS>Ov(QieI%$WZo=)G>BxM;;`OrcPS2+Wp-jQEEW9%q2y`p>2;|t%4yv~ zc0k6Gv*Ab1h0mOJ&V$uS^TRVnnFnEwAlu79Oxk;@B_z8XS}rOY*?sNrcqX-AMxEI4 z43ZYTbT-vQC?gS8VXLl*mN2?6h{a4nRD%3fLKlEhXBwgvCsOlnVM-{A1%3tPA#w>*^P6J<0Pfo@ zaa0gDIGyJ+LT93u*IQA@deSM9;VjTQcUh>5I0%V`)s}5ybMBAob-%DY**9l^1~I+f z9Um<~wLihteu1d=(LLC*O}1=gm`v56G8hPl=DsGwy0;mEm2rjJ0Tt365gB*_&opH6 zcY0~c<7k76PS49zD0mp*#fCS?!|{(RM?GNu88ZA;O2VI1hol2uu!dohD-#%~2u4NH z&T82Okr{IgM9O~qw1l|%jt;yv2ua_d;7#>53f-W{O;`ZiosgnF#{!PU-qHwSGLj-@ z#iT2xw57XJd*RMhZvpsxr>X0J$9z-g!RWyF>V#gA5KPb z^%7**k9Q`IIdJLY?K8a2Xy3@Fx&QQ~3#RuHO;}12lYp#3H7rj4grkdduT-c=QA8QY zin|k=qqI+{SM+P?pwRX!(6(r#NhO!R#%_9aYK4}KUa31Bw)Zm%jZz8dQ@sj6ymjrfc*Mb-9;%NU}P1n zb0iXgsPCg5lgNmj2cOsSEVcuk7WQ x8oY65ct(98fi|_}|D%4%Q;^6qE(1GdK0A}*jEaR1r+%BEX(L}`ekroo{{_={JR|@B literal 0 HcmV?d00001 diff --git a/bin/banked/grep b/bin/banked/grep new file mode 100755 index 0000000000000000000000000000000000000000..80eae153bdae7922442a0507c0cf05296b10df3d GIT binary patch literal 15657 zcmc&*eSDMEy?>In(1cPNarofdo;19KmSPl$E!SlVE^Gott5zMf5=v4kZ4%PNw2HZu z0;?U@-F-H7yPI>vDT67X)A+XQhPk*&Z#VIN*xkqN>|W-l>~3AXt4e{sB=`F}=R8l6 zQnx?$$E}t;&+nY`JHNN{dpqgd&zO}(pHY-c6{Sn*s_6adzOR1!Mf&z^elF~_|R ze8+JYKJk(Ic9&e<@w{{93;?yW4?Ly~JAjBVxe5mzi{>^u>IY8_zyEd)UVt2fH5Uf| zXt5+5fzUCG9v?Wn_N@FaGJgpO*Zz@a?k${TI3hPY;WS2d}yJ zfotx<8wm8+`eyfC@|mCaeX8%$p_Q%=E$aUQbN{EiB9-lu$G4B4qRqhKVE>)FQs(Z# z_s{CwfzNsii&|J?F^d)Ve`ObmW%%UMrEmYWNvDtXf3!=^JA35OkVpA;vq$;ndXMsr z)u0h%nIJm%dAn+!dp+wLpTqhl@SDbOW)53^-npdD)>p^sv}yN*>JQ2%v!U{lL6!Oha8TxDk;x+b*an&!@H)^}WkEeFGu+bfCV z+B?^-wJHmhMopQgDWBDp4a$Z_#aiLi6l*2@Q-y!lYRa9Oa+9XqjDKr2Wz`*Z04a;C zN}ZTg#pRZUuz z7LK$8qgp7~+Nt@prcjJt0$Q6d+O*ZbMQd#d@|i(C)8FI=%9AC3p~#k&pfA#?HEs1pd`)2A zvJv3zu~5|CuK9vuK(RCexY^&_5)2X&@K1bO<^k#tZqeTr%Mt+eMHb7(U@!;(823k7 znl$ICs`hAStACMpzppjsS1c=9F$%i;k*X$NyWe725d$C=4od)L_y}QZc&l%-KiblS z8Cw9@($Wm6VwAA+QMm=iBLo83kyv|si!Z3P`bnpl+m3jO)D|QPb;Io2-kaiY_q>39PtBtD5zK}FeVhBJ>ZXo zAWy9=6!BXsv+z*RuY;j{z(e6E*7{muP{NAZx!wq^V%e}{Ndx8(3xPnp0P` zFW3yVc^A$hw00`Bp&*nI_QNP~ zq;jn6b8X=$6il*E?hG31wrEX+NJj@oTYV8s5!1z3ZAgoDhW(l^fMwdk6$^o2TQC&I z$pJVYTfV0AHfrw-MtvR19oVCdG$oH@J80G-A!v;RA%RK>31j~9Ef%HD4}tk35e(AF zhe#k-aloY|K+1qbLs4I=m5}*^p;+_QsMh9(RdpJ~w#QrGeQ1KdNkm!Y3oe9(hW$Zh ze(S|p0pe)2mLP3G`#am=6cyKI#ih796xZF#jBZ=^?Cv?;bGxtXzPj7qy`a0Y+tt0a z+udE$eM9$+-QMoi-M4hF>sF@tDX?+it=${DAMAd*`>Wko5=A?BVh%m4P76fFmSWv}?}>Rz)_o&zUV`VV!bGe=lF&Egpr zOtU~{5vw&bZvk?Ur1P455E6#t_T_sA?4`W}9>tz%M^ZIBJj|A*wF0&*qrPD?DS%%a z1w6I9tG}+R^Qg11Ws_Q9_jV7kpqT{<2JAH#AsD`BUB&gip0eG|>u#=ix(A6*bt!1I zdG`YOzkC76nb(W~NBPq|m0_{b@l*CMUW}Iott>F3vUZwsoYfXGZ;=21JbL1hS{D3}1wO(kEvWRe@Ca+X!0Jc)w{@A6*^00Bo;CNcd34Q@HEnC# z*1o##k##HA{dvu)H3e(mSabQ>`nA4VU+uMP>(`{d3{1KEB-k4x&S~H<_4QglNZVA3 zZHCq??}bc1X*lt6&d3p#9MN*{)Q(J3?7!`?B+e914K_~=E}R-XZEA37E;uog-dR1} z^CUQOl`_12x7zCYU%XWpfHT1&fi2GI^r2Pfkee@)Gnw@y{xKFF7t%_k%d{H1S*c09 zRSU@56i*R5e1RoLwL*_cH63|H=h=YImZ)ZM3cEm4Pn>jF`!VyLWsM)Q z`j4()?H{tpM>uHj-9iT~c8*2Qv&N5E{aL^^3K$t4OPpiL^Ue|$JjVj(g&q7YTx60D zy{MBVELEBii%qa-T7YoG7U$BGPs~FvI!kjmRZmPwUhM?)N_^x%mj6|R#R8$aI*%sx zHQ0i>v|@QLeAfjQ7#*-bda=_$33XG9&z?}(D(B^`qY22 z_vZkJ+%iez6Q3m3zhm=va`r;#<|@2MZGQ*;U+3XZ#n#*ZI|o8mRo4Z3a*#c-n3+Wj z>{cE%D@{IVl!BemX!YeH5wQoj$1AZP%*f0{U2byaPqo`!Fc1px7BPo>WQqM9V?}{I zlMxnu-iWB@S@Z%pr;p0UISOkZWs$K5U(n{V;CU9fFd#75eoqNO0Xe?YCM(Y2D61a> ze*TLY zWqii6^A!6psFwg@&Vzt0N-zXTpfbBN9W>bI0wx#BiTr4z+aokPSGXVbRW#G3SP6$A7?4L0d$L3!OBOk8^1QNO zAqx~8+wKSpUUV0!=QkusnTNuWK?mdxbsb#D>Oc%6(i=4gMX_}^=Q%ToXK|gO81*tS z8(Jpx!YzqIPQ*}#J6oK0xL=(-b*{)p-{pyBW17`xfK|M4qNcJV<{m9#?lC2iZq&*Q zjkrgr5fG`Wa3>;ENK|ALN0KKx?-cS#q#N+8vvi)-U%;-f-OhO-6HTP6-n?JVbs(ck zh-D6}b4KiiLK3tLZv8xqOj^xqN11m_NP|+;Nj84Tm#~?zaa$SLm}Fksx_pxnh`*(h zh&sdq?LP_I)md!9C`A%4VuMNPlIMHUs%vvrCHM)NG~uS43EokmH)%|csjTTDt>1Gi zIOC3Iu>T*sP{t}grAgVMv?@U*qO>bfC8m_z6{-JCeX9Oo{kQA4)IU<6tlwGxQN7J- z2qiWDF58T}x01ZKnR#!e#+$msc1iXnWSfl=HZ2RkB^PeV!eunq568M3x#XRi zdnXSFDUBK)P>%l$_mI>a%xymaxNVmdv1xl0aLbv8(F$Y>>lOP2Mbehq0OJ z@vQiyX~p%~X_uLv?J=CUJXb{QWacUl9(7*osS+riR!@aQzCtI_Qz;>Zo?^93pNX8? zqMAL^#Sx3!Y*{`kMCu|A0R%#MOhGoEYXptM7_3A!E2Ynaq;QNp7v@nhk)D?=Cl{fd zY&5g_0!V(zU7Sk_rO1W(T%l-`uCjQfT!s?Ap;b@!kc*maGaK|71*q=oq$X(%_Qc$R zi{|FAm*>-{e*lW1e0tKA|D~+*^>b>PwX@<-k8}jQxc?SS62-mF*k$*CF`3RT+Ja}C zXrgKmGyh{dXIiGgHW{m*GmrrLB2!JT1vF6nJf2N^vG@Zn^L00$Ml`}iNBN;1LD)#9 z;wij7)uTru7C+D87w|U1;^%}k2TV%Y(1zudV{am&h97$I#K8>`!pWp^*iz|M*s>9_ z^m7$Y_6)80UQhpfUFCRM^*zEq%Hm`A7-#VbCcNE^Lu(Gf04VH{hrU)kawfcvz}9k} z)jwW~9oOAV{yybIkDwrrd>nNVL5c%0KK9`8XaUnXAPd}f1qPv}vp;#;8R2~G{3 zRz1;E@iolX8Y{j@%dTMwej-tNP(Xw-uM$rK_G4el76L}kr{Yms^(ht{VS#f4_P289 zNSVBJFKABP_eFaNk{QujI-{(1B+i(RIyGaPVv)b81txE|tuL!bBF?!?;uj%D25ZoU zx{aumdH-*6Hy<9>RVt-zQ_6I^DPP_Tq?hDEt_MWphB#{M&DSltJH!P}7vpB0dEWox;lf z%7KRRhQ$q~4QfMS!^lS4;T~|~p&TXklLn~JQU0|adU_O3kMgH);^~|G>2W+gPETTg z2<}qhhNOnR+YB^R{E`wu-3W`GGxBH`nt%k?xkW9PyDWc@GwU8l?mN*fXC0+etg2!| zbTN4GR6^AA)1G>EqlzY&hza_MNp0SUbE#|O3S+W7Du|1U?RO6Y#TULv0{EZCtg0x_ zLHSC0daY3~AxM;vJYKSzgFX0#_eJSPalyWzX8?ExOqq<~tC#z*8;U0Gg+LwL4moq1 zGfN-`Fx{1M@{Bhh^+gR9XEySK=UfPvGf?q8{62}_C-D0%?7XzcIBbJBIJg!zYVvWz zt&{f?ok!W|WHBp?&TxPk94vCd(qp0z$Q_Grd13Vzxq%{!k=(10Y$i^`^1S(>@896O z+GCY9^rdJ<f zW@AhwU5^An2SC7($*42)b|yr1U2~{^I5%;o5PhM9`2#J)5(OV9&D1H-cgs#PfAXY5 zUE>*hsZwJyD;B{xf`^rPXV^x_)V|U}$``uVIjH#U!!onyQ~n&o6k92U2L32~sq+TI z0yq@)u8@lbm++XXkyQa`ac3OvjD3z`sdohK6L{4hW2@t*Di)A?GOJ5q1mz2QMP9g3 zbaezsAw?`HhIdBs+!e#9u1$fAiNqwP{6@osWS_?sW4q)T)Wz&Dnh0IWY=VWcWP#IRPnr;hM2gGJjO2R@88Kam#0puoi1igEoJ%TP==||SlLuCq zpY9wEll}yba#t^?NfCM?;>{<~6{F)T&a(+7F|_8l5A)iYE;P!2`*2o0?qUbdU1K4u zF9Hd=QOwRxFj$5a2!pmDhcV?aDKa65ZBfn?90kkZ>2^oNUaVMf<)c_kco0+7MF8r! zu!dW#$F#dyEFj|;DU_<@S1=C80CJYx6|j9mPQNXiXcx*3guSukIM$+H7pGGpSmV?5 zV8E9=A3gXY;*21cuN-WMe~`R9TDY(fNv2 zOagP7)puBJh6I{kpcuUWo^G{xn?;rzk8`&JAAJc+oH?Vw+y3FqUz$DIvoE22jBa!R zddNgk9sHJkX0G3n85z7R0uGl3{49BVhl5%%)2K)HNlKH+^ua1|_qoNB$9gD++w z-{NUKz^>aRlk{~a@ko=At%$xE<&dV;MjtAWpG^xO;@)OJv4bYjF5>e;m!r>weNtqW&L*M~IRB(_eVKCyp zD8+=}U=_UdqwXcYnt&W-oyX<(A{CaTEVwUtJlUCB(n(G?|0E!mjiI>8?yFxf@wQ*O zitb(L5$AwBHC>Zh)l!@SD@uxG6I4*8S)zet8C@%O2%wl6KI&Qxd!G}FIL7we9={QT2vg9oETM`pEdnfj`utYISTC`tWl^phvEiKRpzmePHj zI(rIy(gik-@@_NFzmRvQt(r=gHkYvEYz;w7dIN68spM7`9Akm;)ZAS-0Q)JkILhMB zljZS=$j%DZQx373ZJ&VK#sEO%<&i!J8qo^g;K*}FR^HnxnEQ;=@}M3fRFtw z{uEnQNSZFvcXd_cN{h_GQ}YHqgP$Cq36~SIb_p;#V7O912&938xISfxLoE42x{=(^ z0#C8n4_Ne|YG;Z4Ecui+lOe`kcPC+AUC1f`l)yYIa9OWz~|q zH#cqB+R_>dx5qkG1=qCR-ukPy1+7=M?%($Ew&(EswYE!IZ)$yf+uUvQwpDMtc3Z4% z-ZslNfeD%=lTNJ;GWYjUzCNv_mfk0ZVC6re7x#-MeAu^wiMJ^I!7X)Vu(`5QxT^gu z`qY$MRpc_zx5Ih4z5%P<&%93^fK-N7vKX<)cR7UJf5>-tKZC~u^e7cT+gp_Z`&CNK z082c>k_Vhu*;|Po${GYcrtu6V$mFlp%f(g88;~NoU*1YU7JQinUP1129Yli6>t*JBh0aRD9iWQ$16b`#%$qb|_Y8riq(Ta&@vHvY4Kz!w`)0|6W#OdUo6{&1MjAT7?=!Jka9f zBpKX3@*R<2vKT^8GUL2aK;VWc!-hGhJJME{6)DtPE>zemLV23)Eu&(a-=ASKeglnf ztAyF|jQW}Yqom_n$XELeL+w;4>1wB*52?M>1VsxC^W(|wfETqh1t(kxpn%6@I4T_V zJmuGcQOZ~#N2=cO!LcEA$>|>Gb}~*Om-nx^`1PuYGHbY%rMgDx9XwJ3N4M0FzE~ODCRk3mlzw>hbcFpUX^LNDAS+k$~3QltSpZ>OmeYNdDBjCwK1Zx+<>gU9qh9 zCENi}xaP+J?|>53{1t?xDB|hX2wSIKnP~rLCFs&o&jtnSFJs1nypryhF=RNh%0;dM ze7w(xiVrau*6kk4WG9HuAMdFZI+vli%3H`Kf{=oa+n7k1sr(wCz6|N&G*?K@*p;1d+Y-rCp2YiW=SN0$YgL-n(H0^rwVYs%P z&8PE#MLI!S3W1w2Q0WZ<>5-4>C7~`_&XHO=i72jK2pq;$BmP2Z-OcA*(}bW!FY{2> zd2&0VQOPUV4$-cbve&K_&076+R!%ooFSf_yTsYKmk=?u{Q>$=1p5;KaWND3h0-isG zu^fr-JW&_V)0$qXizt8_!dr93h5eG(7pDMc`8@MpAamdXqCXCUz04AYEf2Z8=AioW zYHW@=axd?YJ%SDy^<>#&{PjB%2+5>M%)#91@9Eum3!0FgLNpb=BJT*V$RQrhPjo=d zaikNlO7z(8%Naz=VuR2=_iMaag`7NaAFM_2W>B^ieIMzSL|~FJI&0;Et;a;lJKWdd z6rC-RC!P5$nf7SBWs}}3%qBv#;XunK`tlHYI?;#8cD~X%){P{CTCBO%X)ZfuRD~9- zroOP~yp(hb_GDj(7?kY2_hE-VMA=yOL>etiF`Pe0hmyhox-`rYbd>VIBml)j~Fz(dEZ>JEv_>1D?HUAKg`{M+($hi zSi{cv&ReO;x)V?G>jN_&9N{C>+d)aNQ&N&3|G<)k&J`eMXoIs?62s~Xg)(7Ej!4cJ zC=o4a3;?|YoY7I|GQ|VsK!4(AQh-k3oj0{k&ZW2|iYBfaF+OE3b;>@MBl^n@ZVb3A zNc~|KzoMCut1H4F|MuW-X8Wc1 zphOa}E5Qp39?*w&@S{bsR<=2LycZ{sl5Qa5ju>9&Oc|P+W7OO%wrDyU zO+Ud4cQ^bB3B6%DPH;EmF{%4mBWy%wsfO`jH_=TL7;>DXn9n!lj+VPemn=g53L5%; zo6KwTyUAEXN03@U9nm6kzNI@=#gBRl@J|c?r0Ie=u0K)6)bU{B`+X~QY7J0 wlygit;(TurNC$;N`vTB*$Q6;hzc` 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 Gi*dNoC4n88+vF)|pb`BahdU(>v&s?! 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

;$mzdPE-2qjFaek)nM37!F{IX^?q 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 jkj*dL63rB8tpF`A*G|7EYG3z^nfQdfzG{ literal 0 HcmV?d00001 diff --git a/bin/banked/pathchk b/bin/banked/pathchk new file mode 100755 index 0000000000000000000000000000000000000000..db110c891762d0556fde5e5380146381ef0c2cfb GIT binary patch literal 1897 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 literal 0 HcmV?d00001 diff --git a/bin/banked/ps b/bin/banked/ps new file mode 100755 index 0000000000000000000000000000000000000000..f22985d603ec5ad9cba5e71166bd51c50040f8e2 GIT binary patch literal 13966 zcmc&*4_H*!m49#eJAepc_0iP$o>Q7p{6nLeh-+yy2xXLs4`(57^Z*kBN0W`F12_htq( z{o3!_Z+B$oy?5`q=bU@*`G21mp0g=ma4E`cMQK%9$BuWL?D)o|;FhuD-NAduj}I=G zIBqCq1xkOYb=WxmXo1obYJF#b0%Rx(>X5| zgbP(9ZpI}*74cLa3O-Dp1ac<@YqF^*F?hdSwgXVKCkAUev*(Tq*u>z&8xxgI``ib+ z?;o_ccej=l506~BM1z-><8y(o;^QzhS7yNc3Pv(JL9sn#3Rdg9bP78DuB#KKw@K5?2T*8&}`XvQ{TiK>YKzjgl~8b z-8JT1+Lzgv(f5(Q*}<}vq-PwWr;}C==*i9WbmGc>EuOEN4$(77#d+Pir?nrA1a=?j zmJ7aoxmfY|grD`T>bost`~rv-WcFqC&HB{O1j4m>SMAz+yewy0d09q}E~|ZPS#|TW zO^22hkC?l5p?84S5?e6bzx-IwjkZ6uc)ZbK4dNG(_%6@=Qnw zstZ$nh?*wJJHe!&m4>Y-J8Nc^gIm^>DGzQa zRCImwhC=(+tvl>nwyxP~-@2h>oz9no^wyF*qZLj9qj8nz9o6tuW-=yZJ#qr(|7;7$7L(r%a;wL!`HCC@x)dzrJ~0 zY2k*_VjWML%GMPM@`CvY?FdydF=kruE+z=Jf6AvZ&%5?1Im`Dw%0DGa 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 literal 0 HcmV?d00001 diff --git a/bin/banked/pwd b/bin/banked/pwd new file mode 100755 index 0000000000000000000000000000000000000000..81e7f2e8ea6ca9e38c873042b3dbdb5aabc832f6 GIT binary patch literal 3001 zcmaJ@Z){Ul6u++>3tcBL81g_2eSL_fi?9UJP$dhjqeJJ022*0tWgkp&NXCFI17*#w z35NK=pfScs2qB<;(Li+0kQkHNG-S-0EIL0Bk8#mQvdm5zWn){{=Q;Pj*S^BSl5Ovu zd;b2;@0|OFKXb9`UdCz}7n`#t>=eb=d$!Q8Rly|sOl-j^EK@MG25ceACF>NC=PBR^t3i%qNr5wEhehI zSyFFpvJ$paeGn^m>Z!)yrwEi4&ZjwH^Q|f-yq^*dp6BX1v?!M%aV(GyQ1|oZgJDGZ z*F{SNBH0#o>7 zq}vkor7lO<{1-Vw>Ayrlk)c`z3#Z3ucw3uh>MIE%(;Q8vo}jQ}b|**I7Cp;Yau(kD zDzHv8lIFyd(1!wEd5n)fueMAeZklSdlwuTgI7}6ntfcVQJt*w#xZ0=pm5%7`ybp3u?j0wv}B>Ilc7Bhtj32+BUYoSJ) z6Q%VowbqskuOhH|rU-=0!R_wsKr=$Z)|T#z0)JX8Gtq3(f3Zz;L(YG3$+ifrBn*F; zNDsUiiicv&;!wF$*P0>m*KLM>joZ7f`8)_NvK+zy+Ns*wM9H7JhO1C?uEqv zr(w1wEjI3Ir%?J7L1l=99zQB5NUsUrrzg(#*#<}#c})ts*?|!L)RDcVR3!B<{H=^5 z!J^c+-mb6Q9T7l{$p#gxaiEbsnC3X82pui}N9;uc8>loY_5~Gzeq}^Qm0~Ma;7Smf zsZUZv#519`uZC41%U+WlCj9%a?36e825b)b3^6^V*szp4qqQ!!t7vkmd)Cqr=2j=g zw+Lb9$(`@)MaxlA{Q6L~mJA3q!DL(Sd_fwj_sq0mPk nt!vacMVRNDQ#z)p&e4*!-T$FUqwBz_7NQm9RduVkipl*CGdO(+ literal 0 HcmV?d00001 diff --git a/bin/banked/readall b/bin/banked/readall new file mode 100755 index 0000000000000000000000000000000000000000..7aee90db7f69d743464477ff42d16e021d29cc8e GIT binary patch literal 6636 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 literal 0 HcmV?d00001 diff --git a/bin/banked/renice b/bin/banked/renice new file mode 100755 index 0000000000000000000000000000000000000000..9f5c8c8e088d329318a45416fc4054acc08973fa GIT binary patch literal 8829 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 Q!Rbh$bhOKtaF6tV0hgjvdjJ3c literal 0 HcmV?d00001 diff --git a/bin/banked/rm b/bin/banked/rm new file mode 100755 index 0000000000000000000000000000000000000000..78dfb46a5435d38d9782d9d47ee11b5525e79a20 GIT binary patch literal 10035 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 literal 0 HcmV?d00001 diff --git a/bin/banked/rmdir b/bin/banked/rmdir new file mode 100755 index 0000000000000000000000000000000000000000..ef9b71fb71e9f746915831af93df4a0819ce71c7 GIT binary patch literal 4372 zcmc&%du&^06~EWc%TC(HU1@K4Z1?W6;ng$`nz~J4VQo_GzekI*@y3r=OEw0T~0&iCEx z#H9m?fB01Q-h0mXIFH}?eJ5i-w+I^?g0MjlB0}VR?8DfH-yctZ>3nP?z302J$%nre zQw}%O3(3bL)5_aT^+Npd2+YIe_(&#QS2xCA$0kQ7AO(sbK;5m>qx~IPTCPL&&0DJ! zKDAAquA85}HJY03o9S=wndxuLTu$$v92uJ(e50dY_+fj!@K$TRaG^0XHk(Sm6`7ti zUS6(x?o8Fw_=P9bI}#5h)<6E|#K#gF(z~nwX_Ib`PSD<7)ia&^AQJ!j!1T>o(;Bp^ z%?2SG_)4I=Bw02<24}{%ZXNqilO{)!!2x65ES@Q%W9~UcvQ%t`#L`AcEaOkdUv?vG zn{!qs9Eoyf&r>@pb-4U=~ETpDM}x(aXC(8@}l&q!HP|@Y;IBdaC4C`Xxnsf zgejNtgN&PC%U>ix`dswU>7Qd%1WUM|D8H{oPJDI8R`iM2LoRV zbc6#klgI)M(HssM=EusjT+Sa&xnan6vthZ<;1e3yD7eocJ?8%ZJCZe#dO<1kUDMzq@_)T2CI;RDXx2Z;?Naumyjis(Mua z3#z6E2+VjAAxxHGN0kRk&*oCca?QUgc*J|JU}#u2q&l7;o-9n0^O3yVc#8yX2C8yv3Z-jC zLTVxqu!FxeH9DbuT1cUx6U}IS21m{e1^|98-+FM^X@^>!tj}-Wx0@2WRY#GLt7T7{f$klFaOn$d=LUN;J=NhREtNW%7bDZR&fPE@-O@O>5_Q- zesb9&{S17@hQFb?%4ZClq;KadcxIFbg}NhO#*L5C>Ea38)DY}qtIe-t#<>=0JG1D& zOj@4{m$|S|$!2qvUK5#6>==OJJWx?qY9h}(iPkVstC)7G%G_SJ8T$A%2&@JFI*f7| z_}Acr;S>|_Zz!#aYQ%RZttt)pt-dP`c3!S4vXOvd2)`X zmx#NFv^JlMV&Ytouxj$U^!{^Ejs&Ee9oG1zX8!e9djD%tMmO;r%|S?NbLLXS|n0Bwso@NkkN4AWLOE;So;3f?*J%yTA0aNoGttXPCP&P+&O z_IHmrD;Hy&C2VfNagi$La|b9s><%G%I6`%h5@kdC62+^fVX{*VBHxtf3}K*?LNu8( zw=9>^N3AN0wbI}7=aGUaSL!ulCv6d1k&+CysD5abnI0}iBB!g!g*H|Mp>~OQW;y=O zzW6Kq#4}NDIm0pmjDIpPi5Fv7+_`lBwFS-3pwpN<3MFrzS{m+F7h%;SR>w!;kIfEFE zjWBY|5)$~1%4g|~0;lXm483m;gSQMkYmkqrJRG8>pBH_7|1aB-sIBoti(w?vFyrF> zE6y6UXDt>XyXlR~-{sz75DN1$8N{}R?gi*9fM8*64|Nz>)XUH4EBiz+H66JiLWhj1x9_~db8+rO~wPJ(uK`{(Rr8# z8W)IhBc5(0D~wjKa{+>jW*>@RkjlWj0G>r2nE3MpSp8UbZu(`Z-`YrqRcKQs&UHwO zXy$e542g~SC$qZ1RQ}>VN{gwyvZ7=+9Ai9!H+D0|c}!$B><$7w<%xm*sU2&1W_V3h z7bAPxA&ki(D##C@K?E2;(rLO&#_r4zz6csi+X+)yEkDa&Rc%Jrzann}x4j(PrGip| zrFhj6R<-wpu(WN}q}^;1{xxy$BwS}lZ%PI8IO8ys+3h4pqZc5&$p13n{_uT$$+VZp z_3Tf-;H+fS;Il(pDKD;92e^cC$|awSnrBGw7=NEQ_*Ph{)Mbz0EoJoKtd1zTH4!tP d1@(M&l5<=qe90|+> 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 TX||rSIO3Jue$Z#yx6@1<1A++2IrIO%Z|!~d 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 literal 0 HcmV?d00001 diff --git a/bin/banked/setclock b/bin/banked/setclock new file mode 100755 index 0000000000000000000000000000000000000000..eff169f004a3c5607c39e5d9a22d896c8664e88e GIT binary patch literal 1537 zcmb7^U1%d!6vyu*Y1XEzY*xW6DxKL8X_>*|tf>b7w-kD`mwz<(@g` zchC9X|GlMeO@y%$@)#isQR+%dX??k^zFAia>V&FP&;PA(I}={AB`J08n@KO(kdy!~ zZ8??Xg;c3otSyhf9=WQ%sxGMSu6+8*OtsJ`!9G;C3k_8eO4VWoYQPZ!!cOg(Tq3Ko z0>=N`x#t7o_`0xP-znCbncKO@^6lJI<2!Y{S|}~0W+NdFn+nNu3yHa_?EJhZ7JJ8& zN?m4y!O>W3bOnDlGCmt*gR^pIRF1|%Y&emO&B`|Nc4CR0pZzez#uMyfC>e{UQqe@5 zl@pZ5>OdRWnp1k(bx8LhtwG!bVRN?Uatp>^ukf?`A~r8Dm^iE$LBEx7ziNZiKKdc6 zr1|V;X&5uHW*9R&ZW=i?h+7~$P`Jh~Lc9lIZR14+ciQc50ZToQHSRPKrhO3Tfuwl} zr@e$4!_qFud*uwvfqxgoJ??R`l~&x38Wi3rypZjAMy$B~Msea~$Q_WI2zdnjcR*}% zFHnf9UtyrGuaC_9PiPC|HbNcXZ-Ll0pl;g{u8((|LN!~EZW|IjXwAa${Tdx&850Z4~W(3KTex?D7yA=F;4C}<*S5=~SCzX?RM zogo-`o<`nB|iK?=pu1Coi(%BmN45Q_}A&2_ElGZxRS}Elj(I6`S5)C zx$;vV-?;SA+7w*tz+zXI(gNau&amgTbCgq~a#AR-bL!RApDty7oI+V4U;%01+{*fu zWqy4IQawm&R0Rl_Kr&!B(YHc# z+%k^I_=4}9L9K94-b*ur&+aLnrgCF#K&FriqXuj;g~ X?XsS4D4eEk7d9rTM=IRVzwrM66$r!XKZ4k- zk&FaN$8`v;CvH0FI8E&&CBaFsu=|r4c_V62MS`btpvfK2hAfUFFO4$61tIPBJNMl8 z_N@@fOsCU6kJ$I_J@?#m&prS5`uwX-?eN2zcCV(jYweL^KREe=zq=IM7&+D(d+h45 zNM7`qXaDC*wSmU=A})5nI+i(4XcsdqTGY}xr6 zebIv}zp&@&*xK0s*i(l(JGMl6htFTV(O2m$^F9;%f#LLeUEzWDNZ+7{3Xi6VWgkZ8 zAE^(;jAa;q^~0g7gMBv!`-VKzv}K{|N6MT0mCZwuXRjaG6I&TE+(Z75Ke%V;wb+K< zgT0YU4?cLF=!r;rY&g;A9a?s4=tGw)r2@Gwx$p-clq<(t zN^|;W^xyO8cltlke{XDM;qP7ge==*%_aF4RPM=s;s(r1z)Y1Q?cW$UDhp#)%-#GnO z^`+Y1>?ze=mH@*b5R?sp8u_B818sw}EHH9t;9^I3`1zr$H%uOan^i8+;u6(aqBU#a z;|`j4nAr2jfFivEzj|K5-2nX#Y)A1;kM7KUSoDw16#ZlPi{mdbQ#^Fjx1>L(f4W@T zh7w^+KPX+us6)#;)t9(zgzGeqsA*#2BmmKj^?;&uSa_RQG+ z)48*5NZ8ESQ>!zz)2>;Yd)G!>M|;~V%7=z8U4oQ8i0Ax`!v*!v7VJ4xuP+Q*=Fq&Ix znp(Kkqq((B_4USqn&2UBY1S5NkJSW&^#p;z=0|-)AZTdT=dPweO^cyz2-NI00!>Zz zP1=^Gx|V=?Z*JLL7t~hOHP<)o4m25cLEzdSFtp10pwSwvYc%%P1q1fx79$X>Z{4%k zI1o5c-*jk+vAH>5?AnVjqov-c*}uPjR}HYEFJKbX6le~#D0q!YSZ-iB1^erE(w}Tv z(sHmx+Z=p4Sl20R{+)q6+Z*be(G>{prnhZqU0iR}x3i_M%;Dq|`tC}|5Mn%C_)qf`)5UJ$z(=Pt+QkPT9OE!~w%g13p zIrNwx$=~Tl>hn44QSB?`qZpj>!vL$~lRm*i{U#YU%KmR(2LkQ0w-0P=&(wDAhITe} zlsA@dDK9I3sQiKQ8RZ_gCMwfKS%$0F;VstmM$hEbh8>=%sSWEq(^DHtJ@=$E0Hs3q zfF~=ZN1x%*w5a2;&K!qUs(DUU!qY~=OWOzDYL6$}^=a-s3u9~MpKz6VYxj!QxM)eh zOp4l!&^bq2q0?I=isD9^C`yQsTl8f6=7{RJs7e6SrKf=@DuPZ?o7UUtZP4%cq+@2M zC`%)|X@{y<6#;+<#zk$SGE?)s(CG?Y%ksHR-1@J%FBD&5>@yqHg!l6dUhjlBF=^)i zd{SPLk0(Ff0C{g8KtTMb zavtl%XKx)oNoZnQe?;9y^gZlxK#+=#rnE6h3-+U5F)w&o)LsGA@A}pV`MyvIJ4@J2 z(Q+#kU+kMKf;UAiUj1(qAipm*rt+&dbk;}HxiW3V&C@y*uz9LZ> z7i9@iJu0fk2Bvj9bFNS^ni=75^E{v}8#vwWnXfH#xV3?wx9dNFrVi|#s`W*4oMbw_ zN!W*n^L?EVl+Q8;@_Z-q@=xUFpD=k4^7i;#`1Yb%|3Fk;7G+oPi9naO;ZQYDwng_C}o%Z<`SWzeU8r^Wm=Ry-L_Wh zb&9+b9H#z&?BwvUXdMwPxBmpz&Ev5$KRhOt>@|Rxg#y@_LGwiLx1x3k*7!G~_Cr`o z5*hR=PFZ5MZ7n0rw(SAHhBt!5{6{-W9ndX%Uu-KH)wW@QrrUsUZGdncm#&873Mo*J zZ<_p+_Fwun>E>*`+Iq<~+Is0T*-L8(v_G*P z%VI0X)`>-&?VR#F9#QQURoON`wlUe~EO0bNBWql>K8c8JjH}dl>W#Pk>j99rh_?CV zFVI4yoD!_7N;Jhqa75JJb`_J#N-^OE+1~_Z8WnA0On?ok?~^G_3YjF+)g+2W$#RY9 z?=X<;g=^BMo2ch?yYO8M8$R*M!#mf7U;2UwP8PLOAo6Zen~fi0!n2e9cHN@`q4swl zN4Lcl%h4VoIgi|Ry~P@~37BZbrI(NHk=Xj6P0CL{C%qt4Swf(9`^LfK#M?Jkz%39l za;uoU*oL9H9k2Dm`r$7+i2dtz4S|5(*y@T^L!#9!TCzpsWYI7swsmfIY~wr<4aMh_ z<(V`njn+$fDi#H~_ZFGFN|U)JGp+7Zvl7JkAv%E0pkX`$U4Dc=KHm8ad~LQz;~G9R3st zCEiVd!onyw0M^!<_h=_uBX+5N_J*-Fz7ww4n*0+K`OUJmC1Xu}fn&Cc5v4D$Sz6ke zY>Bi#bFOCTBb}Zl3cXShaDy!aHeimjaU4iBrI;S3DLF_P#Y(b%5bbee58pBNt@hDG z{#@)KF)4*{2(j;DmfKmFWk&q^6=vSTp&2tkEQhTShT=FPql7dENFyxNj0rfG-iZ^_ z&^BNi%4qyxozd+Qm7}6;j8c`KsEK5=-+#Kz+r~jZMf=w`L1gk5k$la>=NM&7v8@k~ zX1-4rQqRswPy!@BVp|RB_%?;utPZ0{peQHmU(|mePw#Lb=q7SF=q~ZHKeBS9A8y8A zhA=hk-&AD830Wn1GuS4Qh-#=uQVmkqLHRrtTnw4ps1fjiTITOoFCgqdsUr4OU_4_#hlX_@6qY`YnlbisM z5UY5k-*1hjc_$d(|19gV$zF3Dt(#fR_~dYx-w*wk=^@ zVFQbruP)yw%vZM!bWndpHQxZ*^5Hj)B${ifJrg7NMfh8fGn}cSN<9j5yEau&H zGRIvfb4)au1fOs+2A73GYqGaa1&nalvi6Pa2NUIfDy(vdjn0ri+#gzl4p8 zhC~t;CL#$-?u)$$)CZ**utj<$cD-oRA@)iJn2O+h4b6}xz#@^kNm1fW(RNEk9xV)o zQjl>EN*M6)w={Db^ciNS->|s~S(XI6E@1Ve=nL3voOy*4GZog!LZPH^Fb&)EN9Y!ESHe3I>2#t!KF>HYh&UKg=>Q<{-!89bN zF!Juk2^<{CU`Wq0<3Y9CQ&|uvHeu$9q`l{<$+kbTT^1)O9CR^S_6X=Jv0^@^P0hL~ z8DCTNY~qL;c~8y~%B1bdJ;Lzu8IC1RtU|IVhf!bIPHqvtJ9N%1RW#gL&8fj;N(#7) zhAk&n5OY-+DH%#$00j%mdQi9?6-{Fl%3A5yK1%xZi)`89?qxcO%rv%v*H^I$rDEg~ zrSXm}v5o7GQ#Ok6GOWdXd5ce&+~A4HUnbf4(GEK)(0ZUl4H4ndN5^tmw5Tp;uG6B* ztjeJlOqm;nU3#_DmK4w^C{a~3s3k#Cgo^`j1pf3T%ipQkqmI;4TK-~GBp091k)Cmm z7>#XRe;jyalEJZ+EMHOa)rC5v)9f3fun{qbD~bTcMI=V(A6Y;;z6)G6bt3%l+u41_ z)-0xar!h?>4V-X4z0;CKismim6_%jfs_L@LFc}W%<6D`HdQt_?s#qRNBa!y) zvdd-(@U7iMqb%y^p}UY!JAN`E0iia`&z@)~@-wG?jZ0oZ!bQ>@Xn*F1hA;nx zF3P~w25<^bV*EmveNXhYfb*i!EC!I-LoooYrCF!mFlMV-zyxSm8%z^Pp~e~3t$2cX zCe=&vN0MfRI#Of~e`|$Ni@lIVlS zC{>anbjd=Vo%^L4aD!A>rIHk~_3Td0P0FRXi~Bsad!xxN;F*C-6mufEs+Q9PUK5S1 zcObMhe(LX6kgp+b7Q6YEQUW+>YC7HX_BVH#ujApcn^Y`770|47k0!D~B{9II_;@N{ zsZgp3d^Ip$`sKdO8Q;o=l2AJJ=cIZ`uKp?YV$x8@${UZ6iffioId!N0U0kLK`A}mZ z0#kJs)|kNG+D#g(=a`xq{`qdTJSfmx?OHrZ7jK;uVa01OhtpD-#N8>^PJL-|IF@C> zo0T~I&M_pP`g#30CLbN+N;)>DI31;*jH85rN|7-6^h&ac!(a~%ye+eBCBP|`TXkph zu^@@EwBcmODHV<+jXAGgVv%>bXsVAF=$?8O3;Q_>m{D$D$z6WfUf zIqp74GRAbnn31eN1#5HE@nXt}P|Czi*mTOJQ8EBU=DI+U{ggsKEG5E78GHxT`X)BL z*37T`FU*`4{(Y@IlrZg(6~amTVKbw)I{{Z&PiY7;bQvF;;U*N`9-%fIgoZoyUs%}9 zV);Gtj8SSenOrV*zL`?6v`+%n_*ZrG$Dr3zKuz@6q9|hT)KgJ3;(%D$bjR$Jf*%ED z>NFu8 z`=sIknTm4UgN>v((qD#zQ$=J9u?0KUr^s%GO8~Rvlo2upbo(3uZL~_E1l7V(0k2>Tj{`Mvk zA6}IRP9SHVds7x_$*FE{=JEL-9$P+i?2R+Ndw`p{if^=H3X92Jn$VojRFPSBWR{8y zdgi3GV-%Jf^-Qw2(kUyMmsH)DEkP{ZFjd2uGEzFrFPev6`2sBU`9*(P2$BC9(Zxav zV_uRLt_kuN3f8~qlCf9#r65ZsNHSq0bs3$ubcdA!u{ELa9AO(zBB!dO=1DKzWigBE z@74sZ80DrY!zC0-xS^EqRtL#ZaR~21RP^@zpr_!ZlAU5Lr{E+uT3+i)Mk(7s6l&Cl z>irFg0Xx=1uN%oQUCNx^LcrufQ4uw==|fhj_1{WXP!+z@j1<=qYwgFe+oB9WhTp^ z?glKe$dGEA1cZt*!6dIe!V-S* z;vRbKK1eOAfJNDZx#)Mi)3!-CPx1IT}YXT)sU3D_emf$ZRyalybq6w{@WpAqay>nHE(M@cajo7 zT%}jVnud4|x+|%`K$%^~$y{2j+zPVmT*ZNB42x>9+6yr#571xbmzDnpPx+ z$}@M$szPnOGyG>pA(HEqTx1|I(-=f4ITPq-f6yMNB-lj_V*CC@F^Q9 zC77^G3DY8aqj<=(9BTHS8~Qa_lube8NBWiHpgWu7pVXbrwD6ZvJSU@$dk@#Na{P1T zb>E+Xw^QMNpB9*s-0_3zcBYg$#6{SC-w>_-5`M_;WQ%9?a5$a8zmZ5ohQs z4ULcn04^3+7(bJu86;x}`wQLB9o%JXi|a1ZqOR#wRY~E2D2q3UhZ6cfa&s}{l6HY* zhm2ADQPH0r^3B9s4J!g$7Iix(7>`bM^zk6@fn+*b>K5Op>(Is&UWsG^D3Idmkde`( zW|B}9u+xqIKW@wt#ctei z&DN0CqG0ZXUB9Tc=?~d}R!Sh}oj@4p#%i*y11B{Z+T3nx2hns(R2_%N^)TM*fvQ$E zFcj!h_zX3mTY{_xmCthvnFwwfdET;fXGJJo^kn#Q7?qMGd0C^9P9j*oIo34yGu<~8 Y(Zh8E$wb<9ZI8X47ic$uoOcEKZw5-JiI2TP!Ce%c7&LG@R25)yNrZ|t(cJ#Lx^3I z3f?e|ldgYke{9P(sme4d3YwIPE~2E;J``e6jaZIGCH|Rq{-BvzBW6@fF(G{T?c96c zGp5P3zouPey?f6&_uO;O$M0NbuItILjgTFLgh^N*9lJdC%h}X%eRL|d-x!^*Fh#|k zjc$@~g%`!4!)_9Dh2b&G&rYRNb#*iI({qpnkr1eRko?L>pPUlvkbeKc;{A-qKoPG6 z0v6~nL(uHjC5lE9*TT01Q(`@wc$aBQ&sJCG>*|oa(qi4?#Rt>L%+S(E_u$e59=hVt`;^`O*zNxe@Z7$_e{-XhWGXj?d`s>w{385Q+g); zmc!m~1bl_ySM5D|0s@5)G`V$nj{KJlcob;Of^P%->*|gA6*!lLzy<`@(@VOU%=j<* z+~nPEH~Dp&oBRs3G7nZ)GZ$v2lYl z4Oq#i210^S_3siPWn^;%FR6c*bwt=ClZO%hw;a)viaa`I713$KMu)c8{FVt@$HClC z=?!e?pE9^WBOAu249ce_{9i}n&2Uz6557QFNWLFRa<;0rVXHi&yX*d3TPc2ONFBKuL8Zd(tuk0gXxvMO(YT76 z5&Pb)T(0?+P*zzI9llmCm_L^NbDJp{n;lJ+e)LjX9racHCe#`HA?JkqiTzZ zn@Lv_!m|k9D5}Mx1m`RksM`LLt~0_ly+=LBrihcMddx{~`D?5*KpHS?isKrplX4tNuO#+k>izzGK?ZphuCLV#+t7?ZG*O2IS0S(lt;^uS z1F3pUjHJ5mSOxDIO7hTXR86X-aUNw^LN~C4W(?JKZEJ#YR8PeEJ>Xvk-y>*!2p)Qp zV2IUv{+C9fdLEptg0ZXdxZnD)%8D~rCk7z4;`ZlA65|o)Rg_NC zt5t@lMV%ozhjg{NR5GQoLYggK#3`>222Fh1oM_6|rn!lu7cf`wJ7EP_wZgLh>vPD& zw|#f+{M*1+ilti&z7qVfIEy>B_(K(~v_|(8 zM?aWwY)3Wx2wWo-wdGFy5!KE8x|uY)o=}Hfr;fjyS{ff!nJUb*dGQOq8D3Ek#u$Lf zdYCi_gSN?>)6r48^TL74(!7vhdo!V;Sf-i9P7eVCFddFPISW}BHw7^wJfYOM&^`9M z7ztD&7Hd3tVdUy31$iB=Z`2Ex zN^{h0d~d?>QwnC2YmR5~jK|Eu^wEdFmBogjDE2dX%!OAR?Y!i$Me>P+?^)j&L`QzN zoMqKmGkB9#@T`rY0jUNR_*u@=$Ap^m$5?`;)A2zE$v^33G-F{k)N@*rl9&OiFO%q2 z=KN&O>8W#4|GfIk;Td+ebwxvk&7Q*Z3)_(*!X@3~?6=?J zIyhjgDwX6SZl>LbKAgx!tRg~QD2`TGqYz({h2y#cj27)ciL;|(@G^}VKJwMJ)}OT@ zoB4vW2QQaX_p#toU|>hn!eHT7&#{m3%D|K3L&7$lbp&VZnbuHSgpT56U_XwQ9Bxr9 zVd)E#M#nxhC)G|as>XoV$o+@jk_Pg4XbH4h!Bd0`R4?Jp@Lv32oKX1wsO7%^z?@jl z1nb+VARV#JQG}W~u_(WkxhGkGA1K5tu*SYq#-0V$-Eh^g={MD};*FV%_3eJ@ul&j;^IIe>v+E zuwkmivmjexvPkICm{r1e`BajZgzR^OUEs2ofvbp!W<;8g^jM|$NXY(To=^i5(myGL z`>c4IBBC9q9)>ilmD17ZRS2!A?^2eSTyICh+s6Hhk9h~}eRa@b1#i(?^fj4?jB*N% zHm7_wqMc#C1+oz)3mi7C3j3B3d<7IdI6CsG<2kFv)9BcSyO2hBL*mM#g*?|_` z5=bDrJ>7HMuIswHu0;iZK~Ql}YkN-2ffmx((sSb3Q$DXqTIq$uDzd!Ex{=WCU(}(QhM|TJ@U5IAUJly(=Cw}qF*?84(Ye#(X#n#@U zkyelE?sCx`Xzuqsxw>3*2Ab&-^`7k*h?kX}?mgK+?NZc6`2P>A>OmqTY_vj0$=y`nw~|ov$>X_<16?)LFNFS&sNH zSNo!?w5zb|rmmR_^`X-W^^N75XGzrUUGA=eh5E(Q{SE%D{%!v4r~A(j#XLEp%y>28 zHC~CF^%~n>uJjt)URpYEw)gaq@n&SL*LWkc+H1TX0sL5Gso(D(IIWHX{65A%!T84+ z-)7>^5A}TSDev0vKI>hLD=wWk?=5lkdv7lU>HTL1&YvENbyx1~?;TJ#-Lwy^zS>L;v`i&snJO_xzv=~ zb8?8njt%iTs?LtDDf}i?Pr`+2a#rFJqZ$WQC*o@;oK2xg@w!5)$cZm^DmVs8cuu^o zz3_%1IW{N0=H499?!4i_j^(}1mX78XOZx}To`pQ;;K%al&f3TP96A}>vFQFS-;OVj z*TvWDY~8!Mw`1V+`Js~#m-l<|*LAzs>+D>zFC~Dq<80rD<2ap$H&ovN4nZ`QjzC+| z&enZoAG2uyd;i5jy&c`zE#|nP_J6J~7yrJcT>NWgxp;ah_zw2kpn!pk9?f3(Rq7g@ zL0x0`OW-d#gXUfI&0=+ttY1}1dch8QYEo&Bp1YHt$|>#E9DJ?ZLC;QFTGHV^to>vl zwyw70^w93v^}A+o**Uv%$82nKr`T3s-zXjoe>+?s3G20+=Ig>G#LD&Cw@2!?ZJIBt z>bGs%=@M1T#Di6LuUd$kg<@Idin|wzV7c{4lsqJ6Z>SB=-u|eV-L!q1buaKsCcoJt#4~N?zsH3r zV6gdn=5h1i6E>k+KwN*{qW=A%#V(4{;5K2ies2C*4_B@QdggCg>Sw|i$)A0KpBk`4 z{u~qh7!L{lfB(7{H=j$kQ)HAPV-&PgMV7}Vx>q-stg=mSfe}(D+v|melnc+o``{0E zAJbps>m-Rf;1!*R+^5l2ZD&CRB;okCfDYO+&fR>t~YwPsg%LyuC^ zIcn^+Ab(*!Etdl4W>BEFg=)@GbuY-;wE|>OQ-T_kAZ~;E#ufl`nAVu>#um3t;IZsp zJPxF$C@clfQAKb10Jkq~t}kP*8usLBtb_FuRk-dxenwkL;RJ<}UUum2VxE2f{Xnf) zV!<<6ccZNsOjR>7Fj&d$=jj~}U^+E@LXGGD0yWke*p+HNq3ZMh%f`Oj-1E|oHZSvN zc4m=08X2P$9rG1=CJPECs3Pf9()pAcW5x*`%>VTJ6o|EGGu;b#y|#NKwTuSuQ)u=~ zHJ?&-3`6EKKe~4L82Lk&;(JIwwCQ{IQo8!SQli zi~GqGf`Xq?Ma=zl3ZQUm6ezW?{~_iL zG`T?Gz2+1xTl>CAaB(w*T@=cTo$T@aO$I}mqmtKI>EJZr)dB#UN0TQ16bH5@s3A#) zi=uhHIcg^`(nXE10qHgrSN#==1zyECe}f}iw`+FoWX2RPxN%+Pz<|&`RvR*5Qp(ap zt7X+5?NOhL<|cIb@1*ue<+K$BGE~z>QdBe3l@KyFs^D`-34lf(XhJXi~|Bsqq4ZhbeSHX$&hJy!gK?PpJ&+6|2lW#bH@$$-X4=n)Lf+M zOPJ+)gjM~jRd1)@MXI>uq$cJS90cerey#F9iOj{{7BmW7ir7JlHHE3uQ*OD}Xr`E65+74MaP z4<{vVL{9+RWY z2m7zB>dBx@f)01Y7xm*W)`PJf&VC%bBYtnJ=PE)wzaN}Gyg%XfUC$TYm(LfMZxUae zdKSEMK{N z>xoTH^O(aD2ecXHt!U$vg(XsCZ_|V=Cxe2L zS+@D`XoFNeG+vO3{&BLTxufig$2$8fkvPOSXd}I}>^Sl*7GTln0n^%|KITFCz!9px zjE&5JBjW}RA7DM?sFqKmsgTlS3QfU9#yHRP^iU>q1`I{y6B%%&$sZ?CjlM&HOFJnr z@>L34e%4a}Efm7-Xv6+z9%e#4c4&gM1_f27K!JonfKTL?%z~zJRN$(?X`Jxg?8#}9 zAe8rMn2O#8L@2E*9fr|b`t$spw*7ZuHpcyzq{Pt%wv>JA0T83Mg@z1LWC)I#A{X#* zjv~Dj`Gg|p@$fN4h$6qC$ZtX2*EwjNsjBj5qRh$}*pYS*z^@>|cxdsM2?Wbf=77r(-v}cKPeaDd{_?aqtNfL z(26Df-ETJIe}69%0ELKwuU8ZBX9^9-d0$ZIzfA&uL!sYd=Z`6b_QXU4fJLd3SOol$ zLUFm!=M?(WRRqwyMCVslF(1q{E|9RZG^hM}u!^s_y6*aICMHk)E$*ZucpPm`)G(|n zo$IUG?{c>R0%i4NkI#lx$~(%1a6-ufKnf)r@f%egc&RZU^QV}lB zodHq1uJaF^x?N1#-bWQ|I`U^~L7w}44tFOweNr5Uo#KXL-l>$M=M+cn!HMoPjBm<_5hL#NBdpV+e~s~zIv@mp6SeI5NRcfUaz-nLDx+FGY?t( zbeqY|Wc!@wanf}=k{6lb z$Fj0&*Ks!jBlO48C&ur4x{ZO?rvue4a#LQ)>*XFESJrZ6qZ#~ZL&>3Va6`O@xr4P4 zvYpO1A5>#xYH7vWkEXAl0IEaYECw&925HN2`$WTuIMGR+CXE~MN1krm?%f8~VP@Li z6KoN~ptBgOP%<0i9n((9i5WD&TnC{7vTN^8Py?Bv7eN-m9)wx-x;zzI zz2&0}nL+Pxzml?fSm@1ZE&z{H-5;f4eX=TlL?ZwHH(jM3V z*Bm&nqJ!Tu;NWJ@PWl-u4=%ZxJ&r;9M`4uogRuz5J%gT-kI#-pRB?teoHPH3dk2Tc z7U)i7_~nix$9?~(3M}7^X~Yi;EH!M8Aj%_wNhY<&(vW>$=iHi;5$O;3#)~i?dJHzA z&X%HVj!bfu0fB&2s?Em=T71E=tc<&Bhfk#M^fh+FBazy5Fl}j;at>z}PTnw9yN;_# z_7ME1e1xUUmSS@7xJn_XQ-wnfx57(<_K}*Q=1xVvkTOb zTw_DRE~>~=x_M?jEZD4XtOH1mWa`t@H%)a_to1FRngmrR!9*3}Qk^!XFsjUR31=Yb z4J4tvl5r~3Y42gHlRd>>pp-?`I13Ug`oe6MeNY2}xWe^(&|(bRSRF(pU%3C_5$qIy z3`o@zyGD}S<0+Jes(+i$#lOzQd*RMx(+w+_25cQw@d<7rfj52`tufXv&B>W&%F)iX zbLyX^ossM1r8@*(?-~?&rlt>6X}c`CO%;ck%@Cf!mO`U17tM*FJx6$cm4vLM{>aC{ z7N^nYu#hiLfV5l4V^@$FSyL%GzRILbWtCaWNYZWJqjXdjWUET^m2#k)#;MjMxHlI? zP(Mkl17(tw0&Yo}%=lE{jD#Phss;RxYMOE5h9??{68&Ly>oq>t6A$S(P{36{fjq%| zV&jw@V*Wrxw0UWR7Rf>Os|R783#Z8w)^_G*fVo@@2hk%Gxoo{gVP#kA)^rc7QGDfw z1gl*c)wrlS@4H-xcW>USAgtC3GSF=8p`E~+6pCj1+-fPL>-;u`y@1(+l5v!kZE^D_ zXd|e)(98#&+@|3@uOp+cPt=p~yS_hfDc4_nOXZQ_M6pjHXq0@$O z9t3EKU7K#fRq)`AwN}$5aT3KeWF$mt6}7zdmkdDm12(B+TNdE(<&$CmTnC4;J{Maw zR2!^7nS<=t9>h5=#Lu$7((<9EF=|XGffEciHBMDEJT+aW#!-~+92m!- z=JaeLLPkDCr|M2J#<-I0SWiYSMV&g{r!WFpi$wUQN}@1qG7QMBd8uMDHH@f*k>v0$ zTF@LjM~$`oQ)pBbLI;`u$0+hThf|p+!m(xHdxk!-l(vq+(*gkyCkZHY6piiC zGrtU30=o76y`geD9cA8(-wbQNK#>S$8Ah2^h8V9<^i^nM_#lOzr>2*v@ny82jDr+?o@>%K61tuPI!m-CtRb&a;}L6X zZJ%1Yrn_(-zJ1X>-eUiqvmV;8anqxm)g^y`feY+So>`^LJB$2PCsxMZVR36f=%?%W%qzzcXQ{G#X#Z%`;``J4O@IBvtm z^Jtpe^@q3k{mPUNQseV9(W#2l4}celU$Qo!;6bW*{xI0ZNf;kb?(zzDe^u@tIE357 zd}|7Tx98T`Onw(=9HQu9-%L*()8kNK0QA^Kll-cUTR7U66w-_ll31XmgNBOUx2(w#0e5$r8?z*!G1<@d{P_U9l|sIm?{8$hpOKN>C5ZVNTj-VPi(aZ?#p7LB1rjhXuMc<|9k16^dzso(*B1e3=ydZ7X zehHgaK9ymI+86K};S-NDkisV@^fuls-368)AwEGBZ?mn)Zk+ip_ARQ2reH$)0clCh zV&zx(W#ZO@)bRYyW9&GUIcYad%o%Eus#S52!f#P1ijFByx>HR$vS`M==!ue0!=7(`O!q=S`Ll9s$6fzxH1Ep zuS$z!6nb4H0i3@jzCm463?DwaNUWzI-2D{G^d?i|6vW^dx3nfxbc)&isyvz5MIQI| zqfMEQm6m>JRxH%S6(RdTRaklMu=8YpMUAAH6_efGcW?3Q=OgNA^mh3n=#A#&1wC0KhadS2stsA^u zHD8=)or<4ob$o9y*lMy1!-@u5L6#7AiTy>1R_eNJ=v8>NigX08P4HQu=b0zCAA!#` z&E{1@!VPqgyLOEJk0%N_qm@TwR!hlo3L^z&?xP*%z0u(sZ0*{m=i6L+aHsUPG!MqB zzP!+?K*_~glM;j5I}~;J=7XI0BZI9bF;wkPz5`jUcUu|`l&DGy2rTc#$#5>UF>bh* z)X2rG^_>EqK}O=h(@MU7^4L literal 0 HcmV?d00001 diff --git a/bin/banked/sum b/bin/banked/sum new file mode 100755 index 0000000000000000000000000000000000000000..02323df27ebd39ed79e7db9f1dfc9ad8f4839b13 GIT binary patch literal 6066 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 literal 0 HcmV?d00001 diff --git a/bin/banked/tail b/bin/banked/tail new file mode 100755 index 0000000000000000000000000000000000000000..f1f83701dfbf25be8a0bdf70c7003f57234d2d17 GIT binary patch literal 10366 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 literal 0 HcmV?d00001 diff --git a/bin/banked/tar b/bin/banked/tar new file mode 100755 index 0000000000000000000000000000000000000000..a1400b089f36e587f20e59fd27855c237a54a959 GIT binary patch literal 22587 zcmeHvdw5h;mhU;0@Tdv|3K0)J&q*~>BpM=MHPDzr#6)={7$CHbMgk-uJd%)9On9We z5FV01OMkZH_RO8np7sIStpsfhO4~hRO&lQ|r|}x6TiI$xidJJGp#>3=)cvi!_c?Vc z32ocod~^S~;R|(Y@3r?@d+oK>UTf`ja%`VN`N0nrWwfGfQMP>8aI*2_z7yevA2u8f z-}P}rN78>a7`M+!SK6+r>ooS>ovsG2sr#gzg_xlzY#PgTGQX4M4P})>+gr}FlKAD} zwJdi~_<^zav)m#0V0nWV;3LHH;#qEQ_yJZjh!qYAuN})W28ZW4MLPg_`{3}}rm@$Y z=dgpr56l^?G&!$Xd~{xibKB7^^D{fUPMlyJCnn?P82biKN4vt)rX4%q5~`kcU(uTI zyztua0~@y2E$KMgb?lS#?PHWpjh=@ZJsY3!q{Vl7CXCJV&pMV?fEuF>)Wm@1&ZDx5&Rz+vW<}RZSmHQqlbU*-1cvm z>R3k?&2~k24%_D3CgEB_=ZU6jP}sE}lpQ^G%j@5Jec0>q$IdtHElpScxhP%v$Lw_F zXPI5c&WGAQ-`d&Hb&Ti(_d46AZ4D~hc=M)-4{e;d1bv6!YW22`ZN0wrhCB50QOI{V zBqT+12ccA(?4MQ}%1W?Fua`K6>nY;HR{8|3q8&kF<3^lUv6{Wb$M#BZuGW z9Xi!{=e&Yc<-MWWxe0{m4*lXW(3I|Oy{dK89dB{Gv(nBvwJ$r%Qr4%Gr&Js}Uo)|E z^TeVJ6SJ!)f(JtANVG_>AXZE8iH~5_w$_baZPr|fHY*tn2De?RTW~+~4`G#q(^V`l z@YZ>j5n)-qtgwfbbPEVp7GdjqnZJisc6XgokHrdUOS{GC*Xx4sZu@JSN` w+*^! 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 literal 0 HcmV?d00001 diff --git a/bin/banked/tee b/bin/banked/tee new file mode 100755 index 0000000000000000000000000000000000000000..30adf20ae7006b20014648e95e664a2f0148c5e8 GIT binary patch literal 683 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 VK*_qznxq`@Em`W^Ci6o#{WsL&P7eS8 literal 0 HcmV?d00001 diff --git a/bin/banked/termcap b/bin/banked/termcap new file mode 100755 index 0000000000000000000000000000000000000000..0478a13ee263690e63412bc9f487c48659da046c GIT binary patch literal 12925 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 C=3!<4 literal 0 HcmV?d00001 diff --git a/bin/banked/tget b/bin/banked/tget new file mode 100755 index 0000000000000000000000000000000000000000..b4a2b2ea303dc1d345c48ea4cf2bbc993681c2a7 GIT binary patch literal 14039 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 literal 0 HcmV?d00001 diff --git a/bin/banked/time b/bin/banked/time new file mode 100755 index 0000000000000000000000000000000000000000..bf7076170dfa9c732ef97698df2c7dd3b6cc49d4 GIT binary patch literal 6301 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 literal 0 HcmV?d00001 diff --git a/bin/banked/top b/bin/banked/top new file mode 100755 index 0000000000000000000000000000000000000000..019b26610ea402a4ae062d189d9b84e819c43cd3 GIT binary patch literal 20681 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 literal 0 HcmV?d00001 diff --git a/bin/banked/true b/bin/banked/true new file mode 100755 index 0000000000000000000000000000000000000000..59b499dc1c8ca456efc535a58c91af1d8d49c962 GIT binary patch literal 188 zcmX@PjEP|n0|SEy14AQ2qjRHQqu<1fZ-bp1559GFZG5QY-l!PvV8?J)tMRpBERb3YI|j-S@T9M??x-% z#;sd4gcyMmaZGo^n1OttD9}U**N#E4*8#{oEDutDRgs(FDNtw;Na*87pr9fPgXPhy Yamr!JzAoPl*pxgQ761Rgco1kj0J>vPWdHyG literal 0 HcmV?d00001 diff --git a/bin/banked/ualign b/bin/banked/ualign new file mode 100755 index 0000000000000000000000000000000000000000..457ca93ecc46957664536edf75706b49874a14c8 GIT binary patch literal 7628 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 literal 0 HcmV?d00001 diff --git a/bin/banked/uname b/bin/banked/uname new file mode 100755 index 0000000000000000000000000000000000000000..4880392368e6a9ee0e65e80668821c146e093d9a GIT binary patch literal 1096 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 literal 0 HcmV?d00001 diff --git a/bin/banked/uudecode b/bin/banked/uudecode new file mode 100755 index 0000000000000000000000000000000000000000..0a6ac89e5d465881cc5897b3284df34930017f38 GIT binary patch literal 14434 zcmc&)dvIITnZJ@BiR?Tqpy8TV@3jahHc&Shkz|ZYli&a$4iI9XF~*K9IR+y;vRsAN zZOqFG5W3TuGTWV&ZD%@R+F=`7sOfImod!3w#C6-04W)DrT`kBwj7&^O;-|E~?|k=O zT{%u+Xa87bV%>Wl-}&CJqu2JimF=q(b2zgW z+z?cTuk9Pv8$&^5@Y+5xDUyc|jHg$xe(jy(2kU)xzWdWZ)!aUxXRxC$dGLrx30+ad z>JL&E?d~$t+G?zP=L5$?ldr)yx_WZ-1CPh>g}V-nzw_F`)bR(#cDL^u+r44@+4S1v zf!B_whWGW2Cdc{V{x98m-)Yd%9CJ6r~%>Zx;;<@FkjxZ^TzhG!=@5OuA7-ibQxpy0cu= z6{m0T@HiIA@#1vn{_?Yr%eBSn#_Nlf{hqV89=IXtdE`LfrVXRxhYy35m*WFY9=ZQ% z-<|h8++R9!ggTTu>fjUEPzdVAYKtzB)QHQJ_*o}P|KyB2GSwufR`TSqk1 z8taPQds&Hci#?=Wr7iC%QBK{})72Yo4dw0HVh@?SYI|aB9g(0Cb?jf)61h00b#;d# z67V&VHmxhHg*!S!I5&4peV4X9)ZP)%Iy)jX6KmPt8B*jB|6Sg-yvMQLB8C7(TJ8yH z*qR3*?pO>QB3&jDUA?jH-k3ySjl^iJJl4bn{NYi;bM9CU+iN!0Y4II6nvRV{TOvK3 zEwPR+JQLb^gk2YD?YgJCGZYJb#=`Zz-JKn+Em+sOqb2&;fC-1~p>S6;q=h1FI1_)B zj!0`K1n!`HZA+Wh9Swy$c1hN1%i9PvvCSkO^Tc!QDw2CWXz1+?0q3?*8zWM?yft{q z{Cl^AcG6nHIMjN#7VC{hu&XN^*8D410HZncfX(9&c2E9R|Cdj*UXJG&e`~Z08fXTQ4NU2qa86a4mOsyQx()wIFrM2fkv7K zc+fA>s7M>LbX`{juzIDfb!kyLyN6WNRQj7SKy#7Mt{6yZm5LLNcHP6fbHvs~L(*{NCnKrOzPY%H`3Cc-Y}`nJsmyww8UC> ztT`P!ErKNc<*hL5o|bl~mqm%T?b65{_|ryzddP*)gY-an=!n1`FD2gGQKEQCN*68G zl$UaYK6iTXlOS5#2Y(Trf8-0ADS_xVG|uA?am z&qn6bSNN^Y7vAABGHw1PG-tl8*Uq-ze8x+fM|UX|E&YRUNC4)dNZywE`L?vq*%Hg! za*Osr-YF4b6u#;f@xtl?QB%aURf%4=h!wcQ6tE0=DZCXC#5G3uPxgBd3fFPzrpKwj#EyDSEG$r zBk&q`>`1ER_R+>m{t`>1s#`t(^jHjLH_$G_H{d^qAEbmep97Y*Oz-HgNG4qFhrRD5 z0QVc)!7kOPY$Oi((ioe4499{UbdFG+#i`3rzsca{*kM2Owo)PnKZAq0J2NR}x?|0J@Yudj8y)R6e(- z;*!TJ{f}4dcs!`BY~Mqs()omh=Q0rt6ww2qf~9(`GThU*>Q;I+$$P?+B24%#LT{!e zu5fkJTZ!CAm|Op8v+-&{yxQ%np{>TNh4NYbr~S2umelJlO2v*nczphb%48ztQe67= z%IZ6Afz;DYBq2!W>dFuaUS|tgtS@)S$%`!9v?o>7FL%xq*fW)XOZZ5FMUeldhwTHd zBM(Felmf(W>+v#Je1lxHWu8TDwScCtHL)8Y>?-csBW?DsJym#25#&wllOAwzA^aMV zp3-lJ;??5;XUvA_KzxGke|gcb>a9+6OLFKo5xEuVjZOXDi}zq3YcN1=TF(Ql=3Y9* z8sari<+NPxw6y#k*7A#i<3BhKO?nG+r?UUiY0XQ{HNpEu{z^7_-Ho6vz3m-(ev;f9W~5z8Jbo;lJ$8gFeal1eZ#eIj1(%2 zjK^PUJ!)EssBvp>wgu{c@!Wd!9c{6XZy^+Ks&yWf%bre3)LuxB} zGa{A^Xd;pk;jEF-w6pm!pzt?XOe@s42?#&)M18R$c20@z>3g5|_c+KjeEVvl=T|sU zSzx0gj2SU7t1S?9Q@h}e9Q#E5jHsI}5Ibi?_iQP=iR)@45Hlh?%e-7w0G5lI46!de z_^Zu>#hW33qq8D#yi){DkUy!}dRnGlsD~T~Id#^%&_>Sk8F}myy|W^gfr_ajGAqIv zFoXsq7uoQIF)Idu*I>hq#H7eY$_i0`T-2TLkk1soCq-;x=mE@s<0icT?r8TTr^>Ei zux6{i0F#f*GwHPjc;!}D8J&aJ1#DCLlMbqqN%od!((;r(;GFW7+Ej|jNfDlaNEM(R)qfwEt!pKBIe-7+QClnj@TE{4Z>~W%ae9fDQ4dcJ?*IV4tzvkFr zX~6RI#y1nhF!%_TnMd;Pp}e);Gi+YzZziq) zmf4Qa_`MPz{LPlicM>3*6g>sT>4h%#!v|y*GR`z^TF*ROrRqO+$j2ca7(7QwmrPK- zl(tl)D7>Ge|EF_{*A}Q6;LKT@lR2k1rV`Gyd1-DyW)rSLg{R9~aR~I<&r1JAnJrH_ z4om8u#~fyGCuQ5x{m#j@(;JfsSh=QyN+e_q?hFae?*NcgIU(QR9P@f?g5chN*KaM~uV}Ex9jRbhC8vU- z-Yx11kO;a86nmXRR?Nb0=Ha;5#!>CAOeN}et!(bE+_A@p{5ZXF#~%GYGOp@k&Y061 zoBN9uOoN^N<@iqV$U*%TC(xvKi4B#x{RM!Q_CM)d#~Dl}t1p68yUD64(36dCS}&SP zL<6PBFH!|-<~mu`TE`0K33E(pr_jrqqf4zuwBE&tzGk!%y{zo*5CHz5i#(EoBP>$BBkn3wdjd z^mF)8EY65%R`)2+rf*(VCXCFh)puIQs!QnoO8eck@V@?KB)wlZGvANsCH*-o^SW%w z9v)my31}uO0vSaFvS4J12$#ZdmWWuX50<-<=>(G~N3N<9-E##fc4qGVg;u2($wu)G^GFi7bY`N;SGL++v^r*^yBw28#TkvP2A& z`WFggkr-Ia`TASipk$(ck*Hg2<{VQZHvQnp)!5dwNHi=4up0?J(3T1QTib*&HKKJ1 zV|t{ZJ*c5{vc~I6L>+{LtB|7MmrZeq$RZJ5Oy%oBm>vNvrwSQFh~5bio8;UQuhpkN z@AHCK)smydII$agdO|_aqC^#4Eph>j4XgB@?jo-7h#?-E!E*7`Y@DboAX9M?&k`I2 z?Gl=mY&#%BRZa33dJjXFG+JS#xM$ncf`gjt8nr31Rej(WL(rwh`LEL?0ioc z6Jp&qGJrOJftDg`>5fzBZ-}QQ8P9+W(*!c2Aq(3WWtBMsX-fZi zxO^0kGOpwmO|MO<>6{`v!XtRie{vGGirblWy8JCv%bI36fA?MajO>wHGD56 zr)r#VnVZa4a&d%!!h~xVxKxD=e4n%{>Dv(FrQ*NPWZIceA8;Y1pc)fjR5X)uj?oSn zC)>IhDl+_+L7JkM>#6itFG7s~mY zNrLd!Bp~wEH`yV#wS%P7J0oJV5B{)LL)l5t7&2gT+v0jvla&}LfEAFtgC*i8vb-i| z{yjbpeW@IMP*K>8`+08a6f^JWq(2$?AxkmKUNx?ekF&xLD6-2M;t?j_qY4**P;Vpl=l#5ajZ>NiOO$qK;Tu zy~P@ao99Pbj7pmpg%?N-qWazK^brB)6tfQp#Shun39wVJ_8{ip2}V|&S5 zWbY?qhd}a4x!lAIYot3ci(FU()vvd}7G+q==E9mBms(9%B2*cbbQP4eQ_6s7bs8`- zYXT<}=~X)h8GwR$}` zg^W~P<{XDXn&VKji)@Zmw)eAfc>DS-;=SLoA5BkGYkMNe9g1pFibOkh-QEcUAOqyK zI(!frIm1<72J;Udsr)Hglkl&XK^hf5?Prf-d7wr5-hSKLE>XO1v;b&10X=+xvZmTT z88>8zBGD76cEZj9nm8`B%d_R`=N zoP#_i59O6~lP8UpUX4C@Ujg`BIIDde2=OuuQeGACQ`4$575B(dhtiJ#+M zQEDZ*bG&1eaIh-p2$=(G`IME8afYES(w8Ze7Qin}h3yS_erzf%ZB{0j4x5EREJOl@ zl4LrYTfkN<)3!o?jg0e-jgmfcpvK5FGz3W<`J5Dme&TFWvX>&5++&O^JTwxPUWVc$ z5=hD%rRS6Lw3=JY{)^3UTTg9e$ilx2bg`c|{Ru%(56@YqUCB;LJ5w%~P>I9HeAM&g z5XBoHNWkQ*(J{|zEUPuiEAT=V zDOB>14%3g)z!j_HA;#Gy&jmOfb%|YG$t2xbrjQO`4P9;ifb?VEtfSodCaN*&T%7Ab z9*Maucu-wKoe>=Ga!jIbMU6(OmvnD32ZLP9f|Kmj#_V!*f=%c2ED%VqePF>qZ~p2* zx-~V`hsnA`3VVEfXqTT8HdEcdLN+lK?`XF2SUE1^G98%eXg&a^L=KPsI}Lk(X2(I-A*iy=IHX_$)hw(G-R5vLJr{*SCeoQvlh$}i>47-Oo7OhsAMx; zPi4^a=xDZrunfBhuovb9ShJxqH@BbDOgT%`6`I*1qgvIizQspcM$K=gZgS$fxMKpbEZ#fB5Dgn7TnGRD(kk)3Nqdv>b!pXR?TH-3%jVJT|trQYq zucK}OCKujqVq%cT5d($(H9#l5ZK&TwMl=+%dO$IKQO6uGVV8#qfcJqi(8UMifwG_P z-%VO!32vV3>4;t~7yd9V)rb00?^0%W1WM^hpBTasy>#y2*1j9bWzxkInuaCZDzmPa z^;Ds zj49YQO>K|B2N?bk!{hk=1mB}r`cc-kz8@6uEde*=H}>m~IS0(Ho{_24mYF!sJfrmK}D#Mn16~5-tAw+%ZxGYPIUo4Q}<=DqEv3%-r9y=yms~U?rM(R9=R(r z72OOYcu0%*n7SPNbQ3?- zbMb_%15ZeQ(`E9B2pko0l;bBY^2_|b`GjgYYTPcrA5;I3GMuYg>ceOdV^E1wTyF0j@m*U4%Yt2ndEl48prZV{b?%*zSNqO)# z^NE&7qDA0sT7p-m95Nmi10QKOQRzn*Ya4=>ns5u3xK#HNg&gCk=>7;@my%$WIj4UH zqVLB@3q^fe)Q!<^U670*tl8WxM0hbyj%nzFO^hiU)MCuhGSk>qq6CHs$m_ikMbVbQt>ofw;kQfaV8c;KM^*JA*Fq6DbS2 z_s!w*r@njyjA?Y8{Fmte26kB29#xU{swxVYa;ZrMMOZ=^t;x@|*1Go|+#VB=k45+> zGt;y#)1t`P1eC#*J(6g|X>gV^3Hd`sHhCk{gxb>dF6KrxXBmNGu*6Rh)oF{7xr2Vf z!;hD07xE)Q9A84vF`(znXjRX-quqdYOvFF6mfvw`422eLg(oI`5KYHK!>7ZshZLni z`F-@c=vSh@i4q7(7OVK)=eX!T!JBZgObOl%w7__S+N*Cx#9ty=D3K;9NR9S;Mcqjn&xvn7R647Xu9Z&l{6_K{8zyztl+%Yu`kzw%GiEkW6iT<|y4CQZ6r=PKt&Jq&)9^T_$7nTLCL;QBTcU z>_QJaKKJ$8yI+^d^C{PFvM9*Afx@*^89Kf4(yh$8bbI&foUU=#5a|KmfpR;Ga!T3P zqUJ7T_~w-xwJ%qj-Lc$Ci+88H7L!ToARU;ypsKFo3oWyMMhDIXBk#Lp1;M=`J{P!P z4^;)YJfMP$Zw8^iVBWf2lsNMB;Lrp3Z4Q+el0#Hk$l4FqI)Ow983r!M1}4!Fn7hUW z_riB=vMDgiy~Ny27&ajDl5BSNaU~q?)Q-s7%k8MWe!!KE*~pcs6r%nE+3-^=0_$=U zx0&qSe08Ph19!+a@Q#ZVHE1fN{GB@xOfcie%ZLpgS3pwrI zv_5y~EZK@H<;=C@S; literal 0 HcmV?d00001 diff --git a/bin/banked/uuencode b/bin/banked/uuencode new file mode 100755 index 0000000000000000000000000000000000000000..845405c7e253cb4eb47489d3ac1c5d2ab9cb1fe5 GIT binary patch literal 10868 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 literal 0 HcmV?d00001 diff --git a/bin/banked/wc b/bin/banked/wc new file mode 100755 index 0000000000000000000000000000000000000000..6263980d0b5c2d33907bd3587e6fa6a54781e3e8 GIT binary patch literal 11634 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 literal 0 HcmV?d00001 diff --git a/bin/banked/which b/bin/banked/which new file mode 100755 index 0000000000000000000000000000000000000000..03274a666aa5b53e76e1c147c1aff3c4233423ba GIT binary patch literal 6209 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 literal 0 HcmV?d00001 diff --git a/bin/banked/yes b/bin/banked/yes new file mode 100755 index 0000000000000000000000000000000000000000..e6ddba7f1a47d53d61216e7fb110f10a774166c9 GIT binary patch literal 490 zcmY+Bu}cDR6vyA)X`oI;flb{{E6f&&5-vnE!=_vc+uSmOFbNCG2p=@n)IU*6vtJp+k5Z(-uryt@7KH);avcj1VF$%maufw*0=Il(-TM7 z@fDC=#-h*)V~<_Oqfiec4XD$u8M>l0I}MdIVgRIcwfXYlg)S?+{@NW8GXAu`rwn@C zhW2^hFYgumpE3Y!9jEufT0Nr`eMWv$i@hIWVH0;L?3bhNWAzzq1(9-Y%6hbh%4R|1q~{-xhGE#Uea~<+ z9h+3(vF)-_4Y>a{eT@3&;NjL_5m(Rf=`k?Dzl1U(r6r#8DnDbGa+GSLct3N1(opT^ a-CX|)jrmTHSysDNpR@g`%rokXw|@iLx#Nuh literal 0 HcmV?d00001 diff --git a/bin/boot.bin b/bin/boot.bin new file mode 100755 index 0000000000000000000000000000000000000000..7145102c86721f2c0e13a3ee5b69a0857a3a1b04 GIT binary patch literal 1920 zcmcIlZD>_v@VZtZi;y>8pp|3SV7aeZ9X9CFy4pJ@24dyGug|HMg|9slaMpzX`rdkO1$0 zEIJ`XFvF!qjZ$ zL;lq&P6JKb#2;T4=_!#Gi$XG~4iJ~*ra#+78w;Kz;MPA=M|0{mNv1iW9nDh8 zodx(Spw$-YP{P}HhjvEV0}66g>mL)@hMp1bhX1c5k!T*8lb>u=y$dQ7riFEZR`8W zyS{GX?Fixf z{4nI(Pw1;6P!I~J=>2)3pXkSl8!$FBv*0nJA0ccIY}gi{`#I_W$TzMT2cxv51~A=j z=RU!{8EZbQuff_ftZv5Ia;)|`wFY<-&5teJhgonL7LYi^nx`cMFTWEE*cMPnVqX4= z5A>E}`8^EiJ|~dxdfxH?lBG9bxz`C?f7w&6+FJzpJR7j-d2G{AuxS7rKiK3CRT-G) zk$5yth=$wv3oHmN1O1Y0V}Y^fN+0MtUI|{xbuV^LL%C)%pqm~Snouiy+dU3j2ztVg zP$U-b2*dUr_0iJ~*v>TynjZN`$k3D>_Ug9ui#FJ-{41MYWZMq3iX@Kw0#pFcPuZ)a2GGu&M!>M^UZ=y#fYa7J3GAOSTpB(FLa}Ke%9KO=iRo3jT!aE3t3_1DZztM8G0qE+gdTAXT;5UrMq ziC1QR-yg3t!5* zWU?7nf L*IiTj|Fr%FvnZV8 literal 0 HcmV?d00001 diff --git a/bin/catman.bat b/bin/catman.bat new file mode 100755 index 00000000..9dc3f772 --- /dev/null +++ b/bin/catman.bat @@ -0,0 +1,47 @@ +nroff -man man/man1/basename.1 >man/cat1/basename.0 +nroff -man man/man1/cal.1 >man/cat1/cal.0 +nroff -man man/man1/cat.1 >man/cat1/cat.0 +nroff -man man/man1/chmod.1 >man/cat1/chmod.0 +nroff -man man/man1/chown.1 >man/cat1/chown.0 +nroff -man man/man1/cmp.1 >man/cat1/cmp.0 +nroff -man man/man1/cp.1 >man/cat1/cp.0 +nroff -man man/man1/date.1 >man/cat1/date.0 +nroff -man man/man1/dd.1 >man/cat1/dd.0 +nroff -man man/man1/diff.1 >man/cat1/diff.0 +nroff -man man/man1/du.1 >man/cat1/du.0 +nroff -man man/man1/echo.1 >man/cat1/echo.0 +nroff -man man/man1/ed.1 >man/cat1/ed.0 +nroff -man man/man1/expr.1 >man/cat1/expr.0 +nroff -man man/man1/file.1 >man/cat1/file.0 +nroff -man man/man1/find.1 >man/cat1/find.0 +nroff -man man/man1/grep.1 >man/cat1/grep.0 +nroff -man man/man1/kill.1 >man/cat1/kill.0 +nroff -man man/man1/ln.1 >man/cat1/ln.0 +nroff -man man/man1/login.1 >man/cat1/login.0 +nroff -man man/man1/ls.1 >man/cat1/ls.0 +nroff -man man/man1/man.1 >man/cat1/man.0 +nroff -man man/man1/mkdir.1 >man/cat1/mkdir.0 +nroff -man man/man1/mv.1 >man/cat1/mv.0 +nroff -man man/man1/od.1 >man/cat1/od.0 +nroff -man man/man1/passwd.1 >man/cat1/passwd.0 +nroff -man man/man1/pr.1 >man/cat1/pr.0 +nroff -man man/man1/ps.1 >man/cat1/ps.0 +nroff -man man/man1/pwd.1 >man/cat1/pwd.0 +nroff -man man/man1/rm.1 >man/cat1/rm.0 +nroff -man man/man1/roff.1 >man/cat1/roff.0 +nroff -man man/man1/sh.1 >man/cat1/sh.0 +nroff -man man/man1/sort.1 >man/cat1/sort.0 +nroff -man man/man1/split.1 >man/cat1/split.0 +nroff -man man/man1/su.1 >man/cat1/su.0 +nroff -man man/man1/sum.1 >man/cat1/sum.0 +nroff -man man/man1/tail.1 >man/cat1/tail.0 +nroff -man man/man1/tar.1 >man/cat1/tar.0 +nroff -man man/man1/tee.1 >man/cat1/tee.0 +nroff -man man/man1/test.1 >man/cat1/test.0 +nroff -man man/man1/time.1 >man/cat1/time.0 +nroff -man man/man1/touch.1 >man/cat1/touch.0 +nroff -man man/man1/tr.1 >man/cat1/tr.0 +nroff -man man/man1/troff.1 >man/cat1/troff.0 +nroff -man man/man1/true.1 >man/cat1/true.0 +nroff -man man/man1/uniq.1 >man/cat1/uniq.0 +nroff -man man/man1/wc.1 >man/cat1/wc.0 diff --git a/bin/checksum b/bin/checksum new file mode 100755 index 0000000000000000000000000000000000000000..aadd8dde09f85c4d45df55e23a567c57bbc5e919 GIT binary patch literal 128 zcmXqVGjlO820}9(%C?Y GN&o<#_!77rKPeSh%#^l_M*L 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 IvviOU0Qm_fjQ{`u literal 0 HcmV?d00001 diff --git a/bin/chset/ned-chs b/bin/chset/ned-chs new file mode 100755 index 0000000000000000000000000000000000000000..c41ae52f09fd91f695c43b737753b057a8c15ccf GIT binary patch literal 17264 zcmeHO3y@q@nLhWP`|6pV>4`Adkj~tm0FvkmJ$cb7$LR@z3ZjfFuUc2>PDlie&><9Q zrJcT#7^e`E_$W3~h=Fo+`Oi83ee~?}Gqc~9nLW@m`-05u56sTYJ}2}3m8(}@pT6;$ zl{c*HZflu+LC^Wuue)yb^@Xdiz3vm~71tDQD6F_~woyRWQwHyjJ~{_OkXCIVE?=XURSC5;-To zU;eQCQMn+0O1@Dp%Nyk{%U_jmm+zAQRlZODq5LEHC-MvOFXflzgYq9_na6o2pTpnA z&*53Vj9<=4uqil<0wi+Ylp zQqNS+Rc#5iYC&Cj!m*x67c;>(%7f}x<@M^<)M51r^=ImSwWiL}-ln}v8_-s2 zH)xx*?b`j?kNya4&(y=4YrpQO5o?AdUBZ~Ick9{n-G2A{tYjq9#WaE~8LXpZSyrh- z?$(i8j9E%I-?nX=qz?>uxCSIWUD{Th=cXmyex@Vczcnf8`7PV}hqqkAySd#Dd_CO{ z(*86`NYkiE8cPoshtrg&y>wdT1w!RoLGn2i4s9KNW~eCX={#uDC=`bX za9X-*HKo}_X;cOWi8rtHJK$dG+ zB&#Th@mP-x4V5Gv7@!^sH48#XHz*MO(3WlXwk=?dW(3d=jSUY2o5-FS-bw|G1_8*_ zH;{rB=sjo=#6hFc#7R5@#p#R{jS`Iy14bV%wFn!c;g!$=5O9V(Qel#2A3Yhs0mML)W!?7- zut+UTbgFh69jpUkOP=P#5~{(Z*_c)Y;^txi!&DHY0e?~r*apg(?7)z*=je#VEiI5#as7ybsrau!*B}t7oI}O80+p=De zuii??q+2M-+2%m8L8z17ki@USj0(1xtlw*eSw&H8B%(2$-Z`ndw7T@dtjzm2Y)}*h3pAaEqG3>JIjy8?>DSZsw4aWrf0sTj3NxROJ#<3$Sh0oK z1q+%^$fd*j?AV-`8S9Rn9y>F3R&0K3SU=GflZW+p#NHWeoRH_r{qjZfrSiw+tL5wD zl5EMh%3s0xc!zwC{BQCD@)L4ZeqJ7v_sahzACl{`&O3OLr};d-fWM2M&p*g7=U4G- z_!|CMzJY(4-_F0q@8$RN$N1Cyr~K#K;lJVk&1+m!5=v6(R^Fj3Qr@k+Pq{?-h;pS; zP(G=wRm#d2!t?Pv%0oCGe|E>}pA4nM^H{QPl$Ba-$&C zR3$tm<4K@OdTDfb?Z7Cu)=bd_b&Xo$*}NSV;si=&uN2D3s&LqO25DaY|y})be>IWQ9C=2uX)zjny>BiCQ29*f1Jrx%$$s-F8{<8Lf?u zV#^yHr609mpwtDb2xzI@Wp^nahy)Hoq>^9>EmIKv5*b)l5mskAL}}M9F`WQp zz(rt@8Ib;H8lVc@6|%UPGw384rxxOvabw*|M|O2plW6w3Ip&%Ug;Kmc3N1ka=nkqt z%cxLJ9Dq>*QA^E+DpF(v=nN+iK;<}^0y3c;Ci>O74d|bOL(oxD5Y8eeFM=E^s0Zr1 zc0oTlyTBepAoipma77C=G|3+dVr=XH_zEmoFv%x`NKp&X3;BpXL%gfIc9mBP5b1{) z5ef+kLxF;7G>D9o$)tk$B$*|h>SzT6`KH}u^rWWxzTT64Kj-hHQ{z=1VJBjp>ApYV z*QgGd%UGfbmTQ99K4TTY;n)f~Bq1F*C0y<|=(vC(p|I2S%?MTth$pC>I59ur`yo%j zQ1KnnOmqp?kLVz$i6%jZdvz$lq8^3Jl(^(@v=<1uQly$8RK)C5w!YmVR#(W|8GL z2hkX8pkfV)q!wb*u9Hk+W6pzHb7MS9pg0x*VH!pFbB(%7GKPfQEIyN?6**jQIG@==TR{AIP}?JIkG4JD_GFvg_U#j1G5OnVKWclrZLYik&n}k9m&ljFGg}M4 zY?J(T_+;OgACsSfNA?1IvR}*pE&FnupUQi9AO8Tq5>F~_KgSk z>Y(}sb(8u{^Hrd_37tKFno+O68xwY%{2 z;0M|c?Ky26Pi&4i+L%69KOX$sZ3kwg@72%KFVrv53;JjEuj${>f2<$Ubm*Un7Kb5g6I379vgpJ=64QVRkw2En3Q zg&XC-k*dONkL(0^by(XDYr;Bg{nC2Y+R=1@`NW~|=XZ)OM7N?OgbhYO{n%2QP$*zO zd47;f(GW*zI7GDr*2&4*Fekx$P#Q`uI06!K9$D3!6!J9WcotIq(prZbYk>s>q0fK> zwSZYL+cf{a*4-L-uOyr+!S<}chvgE1CXYnd$E`RyX{}_bKCBituEq*lSsScYKN~5j zMxOKIqP=R{)iT;O3cvwY&|XKo(cPL|eRV$Xi31Pq#%F;rs0j)Z#TJ~ZxD~U|4Nn3Wv8!t1Sv+MXV?7A%7f!`h1*vuLixNP^SK0nQr9o+Y++QW2tFurNN(Q0PfT*=jtGSLr(}qOOuyBW479VDu@f#Qm4~yE%*Sor z;tT-JbSrKr^YCDjPAWjkxkl(Jp&RBKfvXhjZf7(F6b3bj?X?s-BU6p+jq*VP2zRF> ztf`TN6ts#o;V*=KlivgYj5a9>g4OcQU~g&{J64z2wP@d>tBNbyy9kTe&<+;vVF8zb zO`)?L3eE>Wl2QaADr`NFM|d!yw4p>1UYLi2Ym6G(UO=2I)|5gU*kfNqpnmF7%f7ZQ zt7pn(S`w}v%W?eUxLdD>eMS=1-gF(haGBHu$ zHmf0WIC5${W|Bh8a7cl^{6=FmHBiHAEz4(7&(X9j5r+v)N%Mpd>C_1kq=i}0WYi-C z3(QcL;W3j;hCK_MXaMNBF&a`oEGb#6Pw{f)mVNQ5if^bLDviuoC`V!^?@K_H;;O!T zbj8>T7jbk&HOI&^Ucvfi&DBe+pDlathK^-h`Uh^_lsx?ulWy`9Xk7P4@jJ_Z2ETJC z9mDS&f9!gHOYpnI-*Sn6-zEMw{I2rZGnl4|XZp2&Upgme(xkC03vv`C8ws!WnRxVx zdvE|GoI$8*o| z9sAesxKsbUl|1$E9&<-MXQlkjnc;l>uuNuE zvhuP3+*Wzj8Zq~N5rEtXD`qZEIvN0(k=yc;HIiMSWfp41od8^!%xi210P#GR)@KM1 z&sSN#SW4!r@eu|`B1-mu~)y`%h2&u(fpf@!zjKGTF{0V(wDAH-}b|I^Uo;{-hS(c8h~H?Jt#JO_tWcFKJdWpzj*H?KsvJL=1=e4x%7$k zy{|m<^4g~-0aTEjsLDs9QjptGRT^Tg-SA^^BZvnX$>d3=w_q@+<$Nm-$3gs1KoyMu z!HH>vKk>$K<~ziNbceW*wVv0rY$5IrDK1&OICE|!_8ZAtXk{WSlCKF%jBTAP1u({b zChtbuUb&4gjj>1ZmYA_VTKY$Y z+rzd;k-wzH^d&lDAJT6|%GlRM`Uui-Q96qBPpBRW`K2*~f2rX%$Uf_>vWz>#R;gq8 zNs_1667epU!hW1(zUO;L@mP#%Nwg;7dJV5L6U&p>mp#dm?BFt8)8!Ujx}~$|N`xn4 z4KIv&+wxPG#ViS%dBV!sB`2SE@-_=DRPse9XPcIR1%Y>(?Dbj8X9pY;PR^^;*4{a> z372)qI$~AOlBn?~`CXjaHXXXFQbUUq;K$mQbKjxsE%3h`$B{dA+jMhYskfMN+NZmU zsZwvwGhN-5J6REzE4ey`WEN9Yo8baq$MkZw-o8>-vAr000liR+D>>ZOac|wldRe7T zm)x0fA{mM)XtG!LbXWI)(8YvIZda){7zSj>3iW!D$36X#MApo9WqY%wtef@gbcxxa zImybMxf)$WP-GPcQ&w|(9q^=!#@fs`P-Ust?E-`y6xd!+I|euGi7bIwJ2ct&;>3!k zIG9}OX6o1?U6Q^b0*@&(#yJki-pnJ5TTAH9Svcrf=nRyUd-E2PbNpYL12Zzcq^cg*c{CcBxr zgom}b-gZI)vuA-T`Xr{xCt9LCnt92YL!~4OgPcy_IhP3wpwDhlXA1*?V5I? zdG-$4*!DcHB)X(-kGj@T67{b3 zl#UDAQHljyW>8MS=g#4!$*aCIIRDJfVzHJgjjefZNv*W@i{|cZQBT}SNh(U(sT3v^ z7p2B|SV>e*trxbgN@f~K#oX^TRRy4u1j^suZ2j%c7Mx~!JBK%L@Rv{gX6p^VLOE?_ z4|x%J$cwD@_be6PfzmsaMT;^E7sTZMuPZK_;QcndOF13ia$c`=s*mAg0$u;E9`ty* z5#$}QARmawWG5`g$*eGdnFjhV1v(}o@6>cf^=hUXhakLmXRRg8F2PW@1S z)GzfOc(@>VfzHtxyb(*0U zXn?d~S~;sSWr|29k_}Sgwg8{9Ad(Kk2!EF8VN4*W-gD(34kE9Wp{^iu7g~1E5A}s; zT4l&zh7p#bS(^GX^AMYL6P1I0!4L4`MP)v|bg-JEiMk1zDAFu6N5Ky!_&Jzj1y+Jp zgb23?`u8Cp3>K0J9a@1dr`IFtFN!BJ_cyvI>D%ToLef7#QvW!TlC%`3TgZ`wl%H72 zNc+usU`NxKJ;{itW{f*Q6lw}pHl6aLiJTl-Ku#<~4B15ND4(kNp#H{IPc;7Ku}7N` zS$ecV(kd7f7AkaUPp8YM4Z608FX10&^UX*02p562r~39XuGQ)cpFKGv+rEnd8cAZag{3^1m}FNX=_4y^B)GN3W{FVS$r1eF>YDfTr=@R67J zLQH(^<}=Jhm|&Hd7PgK=kYF>$V*r|*91=$)*owF_h{P314aV<@WIo2D`w#~&Bl!8>_qhoNJ>Zd$1#%>~5hrr6WFELNn-a(uCEz3W?qK3D7@RdnCE{2n zJnY#~LRL3MJeXs2qdO)N8{H)Az#wcg4N72q zCg9K!jIS?DT*?xL7jX zXUxY?y`!TT9#Gy$el!oNzY+QfcRD_2oe41^GhlQI!iE3A0#zu34VuJ}w@;6($e^9tCCb=vlc)W-=wtaAq2U*Sv+$99y=ZG`*@oBom*&wnj5c!_4rG~G^p?M$ zUR7=bCuxAmX?e(E{hbPvt$DJ=r2)y3L2Bv$gLMb);NQMGdXt~8#XFf`dIctmh&anfltg?yn~&z#lLm?J^1SsJN>Sq4eUL4BRTKx zpbQvHC03c2vl$Uu3WQM`-s8GnA<|HKR5(PMcMz)x{CKpRyb=!x7~FmNL_S z3C<*hc$79k-CsvXpj1CdDq*kh0ZYbiehOray_Mv{hn$4S*c?J+>|J#5Gqy(HGrZ41 zMY2WKYE=Xo%Q%J|zwFY0t~MQc#8Y(OAF%p*2Xp>`J$ov- zipZ`Cvg?Cv9WpytxtVHy<#Rzch-`Dcj|f68VMh+5kO~^35iOgS@ed0Cd+`cbMlWOA z9|9J1`Qqg;CZ9b`b$D49QyqCu)a$HI)ba7`_WRIYV|k+I9<#SU48^<5COF<{T7=J% zk|pXjF6uhwjOz4cWU{{j);|aRfIQ2$vh7pfN}Th#NC#az|4SpstdDOsCE z-w2s3ZfCI%<*dYB_zjlt#B=|_*og1N;zc+PPt_9mKPBrmU%{VvK$VyGdc zJ2p#;97$82a72~76A{D`LrE-D$Q|bTUYoeFb}7i?QO?3Tvvah2#2dL_7u5~Pe*5X(r^2~Kt>>MS3?kq7mDY(Kt#_o5C^ m9TULem~add8je9i!(SWTvU!s#jMNdS;LlZWc#VI~(*FYQiBl^8 literal 0 HcmV?d00001 diff --git a/bin/chset/std-chs b/bin/chset/std-chs new file mode 100755 index 0000000000000000000000000000000000000000..2a21ef7a11cb9c2d1aea08dce554719dbd90d793 GIT binary patch literal 22708 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 literal 0 HcmV?d00001 diff --git a/bin/demos.sh b/bin/demos.sh new file mode 100755 index 00000000..d93466b7 --- /dev/null +++ b/bin/demos.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# fixme: must be <= 256 bytes + +cd /usr/root +cp -v ned01-1 /dev/lcd0 +cp -v ned01-2 /dev/lcd1 +cp -v lpr-rec /dev/printer +cp -v cog-lab /dev/cognitive + diff --git a/bin/demos/cog-lab b/bin/demos/cog-lab new file mode 100755 index 00000000..81517866 --- /dev/null +++ b/bin/demos/cog-lab @@ -0,0 +1 @@ +!R E HYFMT2 0 100 150 1 Õ 0,39 17-02-03 10:38 \ No newline at end of file diff --git a/bin/demos/lpr-rec b/bin/demos/lpr-rec new file mode 100755 index 00000000..d38b58e2 --- /dev/null +++ b/bin/demos/lpr-rec @@ -0,0 +1,21 @@ + POSTKANTOOR + NW MARKTPASSAGE 19 + 2801 HW GOUDA + TEL 0182-522100 + 29MEI03 18:28 + +BRIEF 031 000002 + AANGETEKEND 12,50 +DISKETTES 10 PACK 9,95 + +TOTAAL EXCL BTW 20,86 +BTW 0,0% 0,00 +BTW 19,0% 1,59 + +TOTAAL 2 ART | 22,45 +KONTANT | 22,45 + + 0000001 + + DANK U EN TOT ZIENS + CR \ No newline at end of file diff --git a/bin/demos/ned01-1 b/bin/demos/ned01-1 new file mode 100755 index 0000000000000000000000000000000000000000..61b723e6358b60075d79eda205bf1aecf255b54e GIT binary patch literal 40 tcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}s(_8cIhP0sxFy BBqaa< literal 0 HcmV?d00001 diff --git a/bin/demos/ned02-3 b/bin/demos/ned02-3 new file mode 100755 index 00000000..3aeaec77 --- /dev/null +++ b/bin/demos/ned02-3 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1S<R(D0S=R& E1X1 \ No newline at end of file diff --git a/bin/demos/ned02-4 b/bin/demos/ned02-4 new file mode 100755 index 00000000..f9202a9a --- /dev/null +++ b/bin/demos/ned02-4 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1S(RPD0S)RNE1X1 \ No newline at end of file diff --git a/bin/demos/ned02-5 b/bin/demos/ned02-5 new file mode 100755 index 00000000..7f16771a --- /dev/null +++ b/bin/demos/ned02-5 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1SRx-D0S Rv+E1X1 \ No newline at end of file diff --git a/bin/demos/ned02-6 b/bin/demos/ned02-6 new file mode 100755 index 0000000000000000000000000000000000000000..95e15ad9d2559001cf13e4eef3fcf975bf5cd266 GIT binary patch literal 100 zcmW-WyAD7w6oyIIJb>gk9GgwgDi-2|MqScY!pn(ARkrVfQ(;gT89PH1>YxmlM6gf$ r9hb(icY_eyY!YL(^5eYllUO0`h)H`{{#faiuI;eYcWxG6LKr8%4e=F- literal 0 HcmV?d00001 diff --git a/bin/demos/ned03-1 b/bin/demos/ned03-1 new file mode 100755 index 0000000000000000000000000000000000000000..adb744a304acf355bb265ef15b1ec87083572dec GIT binary patch literal 237 zcmYL?!3u&v6h#dTT!jlM@NVV<4Brrg5D`fZ5|)ai;79ZUeNEWjMeX{$#!+&07U$jb z&=L|t%29GiLP*Gva0n>N?hM=!Yy=tf_G`FOZwuAQ9SZ8RKy_RVi{78)dX}5Nq)7&| z+#0EKUoP`B%&(?x>vnfA?WJx%_t0M)N7eDIWJOb}OCp(Us-l#}cx8Ofm>~9G6hs2L PclUg@ivmHA94-F=(+@S9 literal 0 HcmV?d00001 diff --git a/bin/demos/ned03-2 b/bin/demos/ned03-2 new file mode 100755 index 00000000..12914e58 --- /dev/null +++ b/bin/demos/ned03-2 @@ -0,0 +1 @@ +X0D0G1P1E0/00S OVERNIGHT PREPAID EXPRESS0S,PACK 5 x 17,501Sl, 87,50E1X1 \ No newline at end of file diff --git a/bin/demos/ned04-1 b/bin/demos/ned04-1 new file mode 100755 index 0000000000000000000000000000000000000000..43d3a6e6ec37ee7ebdf41413537d9519f737cab3 GIT binary patch literal 245 zcmYL>u?oU46h$l4O{9~G&mrA9C`|+x5wV&_4b@nZ2=(Wr?j3aV^GwoWhsT9`?mJLX z;1qHOB?F|8QYe5k*nkeg+DFs|X@mM`!k1g=cL3@TIfMQTK<&rwqnUSb(!=Q=(he?r zxbo2Iz6@oa%8Pf0)?M$sduZLyE!aggDup~{iW4C|?$T8Ceni!Bl#eSEaICB61 literal 0 HcmV?d00001 diff --git a/bin/demos/ned04-2 b/bin/demos/ned04-2 new file mode 100755 index 0000000000000000000000000000000000000000..e2ea2b621a57d2af316358d814239c30419d75d9 GIT binary patch literal 107 zcmb1+FpzdJkajne4ltB{}*gXURD16dp#&Y{5}{=Tk3 z3L*X>jy}>rg*hBjhDN431_odS3XY*69{xd|!JdBZ3IUFhzOH^DdU|@&u7=VPh5)y= B7j*yt literal 0 HcmV?d00001 diff --git a/bin/demos/ned04-3 b/bin/demos/ned04-3 new file mode 100755 index 00000000..df8f32bd --- /dev/null +++ b/bin/demos/ned04-3 @@ -0,0 +1 @@ +X0D0G1P1E0/00S,DEACTIVATING RF SECURITY...E1X1 \ No newline at end of file diff --git a/bin/demos/ned05-1 b/bin/demos/ned05-1 new file mode 100755 index 0000000000000000000000000000000000000000..4028b840d4ba8d0f6fb4708b91293a951607d094 GIT binary patch literal 82 zcmb1+FpzdJkajne4ltB{}*gXURD0|j+>LOdM(ycHt- cLlr@M8HHe1R}fFZ(cRJ0Pf^;{P&&d80JIYkYXATM literal 0 HcmV?d00001 diff --git a/bin/demos/ned05-2 b/bin/demos/ned05-2 new file mode 100755 index 0000000000000000000000000000000000000000..3c4ca4a662a49ea9bfbf2b8973040caaa37e11cc GIT binary patch literal 178 zcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}u&)7U7T%s?Y_S REy^h!RHiNMYA79H2mscPD0%<@ literal 0 HcmV?d00001 diff --git a/bin/demos/ned05-3 b/bin/demos/ned05-3 new file mode 100755 index 0000000000000000000000000000000000000000..43a377c4b87f9d22a1322dddfcd5995f5cbb30d4 GIT binary patch literal 178 zcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}u&)*5H>83XlVv RttlWKHTYA79H2msWBC_(@L literal 0 HcmV?d00001 diff --git a/bin/demos/ned05-4 b/bin/demos/ned05-4 new file mode 100755 index 0000000000000000000000000000000000000000..791fe8c1c24078bdee2725160ec8977a8166081f GIT binary patch literal 178 zcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}u&)wgGC_;0K#+ P3)HU0EA4719bpIn(sw8d literal 0 HcmV?d00001 diff --git a/bin/demos/ned05-5 b/bin/demos/ned05-5 new file mode 100755 index 0000000000000000000000000000000000000000..ed0a33866fab3cb51c1bb06c4221e2eda77ba24f GIT binary patch literal 156 zcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}s(_8cIhP0sxFy BBqaa< literal 0 HcmV?d00001 diff --git a/bin/demos/ned06-1 b/bin/demos/ned06-1 new file mode 100755 index 0000000000000000000000000000000000000000..61b723e6358b60075d79eda205bf1aecf255b54e GIT binary patch literal 40 tcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}s(_8cIhP0sxFy BBqaa< literal 0 HcmV?d00001 diff --git a/bin/demos/ned06-3 b/bin/demos/ned06-3 new file mode 100755 index 00000000..3aeaec77 --- /dev/null +++ b/bin/demos/ned06-3 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1S<R(D0S=R& E1X1 \ No newline at end of file diff --git a/bin/demos/ned06-4 b/bin/demos/ned06-4 new file mode 100755 index 00000000..f9202a9a --- /dev/null +++ b/bin/demos/ned06-4 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1S(RPD0S)RNE1X1 \ No newline at end of file diff --git a/bin/demos/ned06-5 b/bin/demos/ned06-5 new file mode 100755 index 00000000..7f16771a --- /dev/null +++ b/bin/demos/ned06-5 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1SRx-D0S Rv+E1X1 \ No newline at end of file diff --git a/bin/demos/ned06-6 b/bin/demos/ned06-6 new file mode 100755 index 0000000000000000000000000000000000000000..2caa83db537d094b3cd1d2091ec87202355232fb GIT binary patch literal 109 zcmW;Bu?oUK5Jgc11^?kS&(1=~PAfKR9Ad(nU3MlAe=hi`iFWsLFb6yXIzbU=K(npD z4m;HE{U>(Zqb@gWb-H-wL%V*wa+u6nQf!ru-$>uS!cYQOD^q11wn3QLzV3rjC CyBKBw literal 0 HcmV?d00001 diff --git a/bin/fortune.dat b/bin/fortune.dat new file mode 100755 index 00000000..deb02985 --- /dev/null +++ b/bin/fortune.dat @@ -0,0 +1,1017 @@ +Mulder: Do you believe in the existence of extra terrestrials? +Scully: Logically, I'd have to say no. Given the distances + needed to travel from the far reaches of space the + energy requirement would exceed a space craft's + capabilities... +Mulder: Conventional wisdom, though when convention, and + science offer us no answer might we not finally turn + to the fantastic as a plausibility? +Scully: What I find fantastic is the notion that there are + answers beyond the realm of science. The answers are + there, you just have to know where to look. +Mulder: (sarcastically) That's why they put the 'I' in FBI! + + "The X-Files: Pilot" +%% +Scully: Mulder, did you see their eyes? If I were that stoned... +Mulder: Oooh! If you were that stoned, what? + + "The X-Files: Deep Throat" +%% +Mulder: They're here, aren't they? +Deep Throat: Mr Mulder, they've been here for a long, long time. + + "The X-Files: Deep Throat" +%% +Scully: Oh God Mulder, it smells like.. I think it's bile. +Mulder: How can I get it off my fingers quickly without + betraying my cool exterior? + + "The X-Files: Squeeze" +%% +Mulder: And maybe because I run into so many people who are + hostile just because they can't open their minds to the + possibilities that, sometimes, the need to mess with + their heads outweighs the millstone of humiliation. + + "The X-Files: Squeeze" +%% +Scully: It just doesn't seem, substantial enough to warrant an + investigation. +Mulder: OK, Scully, so we disagree. It's not the first time, + and it won't be the last. +Scully: Well, at least if we had a legitimate source, we could.. +Mulder: This is the essence of science, you ask an impertinent + question and you're on your way to a pertinent answer. +Scully: So, what makes this case any more credible than... + (Scully picks up a copy of National Comet, a tabloid, + off Mulder's desk and reads)....the hundred year old + mother with the lizard baby? +Mulder: Because the lizard baby wasn't born anywhere near Lake + Okobogee. +Scully: Oka-what? +Mulder: Bogee. (Mulder gets up and in her face) Okobogee. +Scully: Is that supposed to mean something to me? +Mulder: If you know anything about trout fishing, or UFO + hotspots. + + "The X-Files: Conduit" +%% +Scully: I just think it's a good idea not to antagonize local + law enforcement. +Mulder: Who, me? I'm Mr. Congeniality. +Scully: You never know, we might need his help one of these days. +Mulder: I'll send him a bunt cake. + + "The X-Files: Conduit" +%% +Ellen: Dana, you went through the FBI academy, what better + training could there be for motherhood? Seriously, + you're great with kids, what're you talking about. +Scully: When am I supposed to find the time? +Ellen: Well first you have to get a life. +Scully: Ooooh. +Ellen: And, of course, it helps if you can find a man. +Scully: Know of any? +Ellen: Yeah, they're disappearing faster than the Brazilian + rain forest. What about that guy you work with? +Scully: Mulder? +Ellen: Yeah, I thought you said he was cute. +Scully: He's a jerk. He's not a jerk, he's umm, he's obsessed + with his work. + + "The X-Files: The Jersey Devil" +%% +Scully: I have a date. +Mulder: Can you cancel? +Scully: Unlike you, Mulder, I would like to have a life. +Mulder: I have a life! + + "The X-Files: The Jersey Devil" +%% +Mulder: Hey, Scully, do you believe in the after-life? +Scully: I'd settle for a life in this one. + + "The X-Files: Shadows" +%% +Mulder: I don't trust them. I WANT to trust YOU (Scully). + + "The X-Files: Ice" +%% +Mulder: (smiling) The ENIGMATIC Dr. Scully! + + "The X-Files: Fallen Angel" +%% +Scully: Well, let it never be said that you wouldn't walk + through fire for a woman Mulder. +Mulder: And never let it be said that I wouldn't do it for you + again Scully. + + "The X-Files: Fire" +%% +Scully: You set us up. This was a trap for Mulder because he + helped put you away. Well, I came here to tell you + that if he dies because of what you've done, four days + from now nobody will stop me from being the one that'll + throw the switch and gas you out of this life for good, + you son-of-a-bitch. + + "The X-Files: Beyond the Sea" +%% +Mulder: I know what I saw, Scully. and I saw you about to do + the wild thing with some stranger! + + "The X-Files: Genderbender" +%% +Mulder: I think it's remotely plausible that someone might + think you're hot. + + "The X-Files: E.B.E" +%% +Scully: What do you think? +Mulder: I think I'm going to suggest that we sleep with the + lights on. + + "The X-Files: Darkness Falls" +%% +Mulder: You can get the next mutant. + + "The X-Files: Tooms" +%% +Mulder: No, you'd be in trouble just sitting in this car. And + I'd hate to see you carry an official reprimand in your + career file because of me. +Scully: Fox.. +Mulder: I.. I even made my parents call me Mulder... Mulder. +Scully: Mulder, I wouldn't put myself on the line for anybody + but you. +Mulder: If there's an iced tea in that bag, it could be love. + + "The X-Files: Tooms" +%% +Mulder: How was the wedding? +Scully: You mean the part where the groom passed out or the dog + bit the drummer? +Mulder: Did you catch the bouquet? +Scully: Maybe. + + "The X-Files: Roland" +%% +Scully: I'm warning you, if this is monkey pee, you're on your + own. + + "The X-Files: The Erlenmeyer Flask" +%% +Mulder: Well, I may not have the X-Files, Scully, but I still have my work, and I still have you... + + "The X-Files: Little Green Men" +%% +(Mulder's opening monologue) +Mulder: We wanted to listen... I wanted to believe, but the + tools had been taken away. The X-Files had been shut + down. They closed our eyes. Our voices have been + silenced. Our ears now deaf to the realms of extreme + possibilities. + + "The X-Files: Little Green Men" +%% +Scully: What makes you think they care about us anymore, anyway? +Mulder: So why have you bothered to come here covertly? +Scully: Because I realized that it was the only way that you + would see me. + + "The X-Files: Little Green Men" +%% +(Mulder talking into tape recorder) +Mulder: Deep Throat said 'Trust No One'. It's hard, Scully. + Suspecting everyone, everything. It wears you down. + You even begin to doubt what you know is the truth. + Before, I could only trust myself. Now, I can only + trust you. And they've taken you away from me. + + "The X-Files: Little Green Men" +%% +Scully: This seat taken? +Mulder: No, but i should warn you i'm experiencing violent + impulses. +Scully: Well I'm armed so I'll take my chances. + + "The X-Files: The Host" +%% +Mulder: Don't you get it, Scully? They don't want us working + together, and right now that's the only reason I can + think of to stay. + + "The X-Files: The Host" +%% +Mulder: how big can this thing get? +Scully: Mulder, I.. (smiles) sorry, for a second there it felt + like old times. + + "The X-Files: The Host" +%% +Scully: And Mulder, when you see Skinner to hand in your field + report, I know that it's your decision, but I hope that + you know that I'd consider it MORE than a professional + loss if you decided to leave. + + "The X-Files: The Host" +%% +Frohike: So, Mulder, where's your little partner? +Mulder: She wouldn't come. She's afraid of her love for you. + + "The X-Files: Blood" +%% +Scully: Must be nice not having someone questioning your every + move ... poking holes in all your theorys ... +Mulder: [joking] Oh yeah, it's great, I'm surprised I put up + with you for so long! + + "The X-Files: Sleepless" +%% +Kristin: (looking at Scully's gold cross on a chain around + Mulder's neck) Are you trying to ward me off? +Mulder: It's from someone I lost. (Scully) +Kristin: (sincerely) Well, I hope you find her. + + "The X-Files: 3" +%% +(Scully is found alive but in a coma, and Mulder must fight to + save her life) + +Mulder: (by Scully's bedside in hospital where she is lying + unconscious) I don't know if me being here will help + bring you back, but I'm here. + + "The X-Files: One Breath" +%% +Mulder: I brought you something.. "Superstars of the Superbowls" +Scully: I knew there was a reason to live. +Mulder: Well, I know you want to get some rest; I just came by + to see how you?re doin? and to say hi. (Turns to go) +Scully: Mulder - (he turns back) I had the strength of your + beliefs. + + "The X-Files: One Breath" +%% +Mulder: I have a college, friend, who's with O'Neil (who's + infected) right now. Let me go to her. +Ericson: I can't let you leave (points gun at Mulder's head) +Mulder: Then you're gonna have to shoot me because I'm walking + out of here. + + "The X-Files: Firewalker" +%% +Mulder: (asks Scully on a date.. well!) Vikins vs. Redskins. + Two tickets on the 40-yard line at the Metrodome. + You and me. + + "The X-Files: Irresistible" +%% +Mulder: (to Scully in hallway) I just don't want you to think + you have to hide anything from me. + + "The X-Files: Irresistible" +%% +Scully: (to counsellor) I trust him (Mulder) as much as anyone. + I trust him with my life. + + "The X-Files: Irresistible" +%% +(on phone) Mulder: Look, I know this is a pretty horrific case, + but.. +Scully: I'm OK with it, Mulder. Anyway, you could use my help. +Mulder: Always. + + "The X-Files: Irresistible" +%% +Mulder: (to Boggs on Scully's disappearance).. Elvis in three + states every day.. and yet no one saw a pretty woman + being forced off the road in a rental car? + + "The X-Files: Irresistible" +%% +Mulder: (on human psychopaths) The idea of such a human monster + is as frightening as any X-File. + + "The X-Files: Irresistible" +%% +Scully: Mulder...toads just fell from the sky! +Mulder: I guess their parachutes didn't open. + + "The X-Files: Die Hand Die Verletzt" +%% +Scully: Why didn't you tell me it was your sister? +Mulder: I knew you'd never let me go through with it. (After + Samantha's clone is killed because of a hostage trade + off between she and Scully) + + "The X-Files: End Game" +%% +Mulder: If i was a betting man i'd say that it was ah ... +Scully: An invisible elephant? +Mulder: I saw David Copperfield make the statue of liberty + disappear once. + + "The X-Files: Fearful Symmetry" +%% +Mulder: We were just exhuming,....your potato. + + "The X-Files: Humbug" +%% +Midget: You'd be surprised how many woman find my size + intriguingly alluring. +Mulder: You'd be surprised how many men do as well. + + "The X-Files: Humbug" +%% +Mulder: See, this is a helium balloon here, and the one thing I + DID learn in kindergarten is, when you let them go they + float up up and away, but you see this is moving AWAY + from him ... horizontally. +Scully: Did you learn about WIND in kindergarten? + + "The X-Files: The Calusari" +%% +Mulder: Hey Scully, can you spare a prophylactic? + + "The X-Files: Soft Light" +%% +Scully: I just came up with a pretty sick theory Mulder. +Mulder: Oooh, I'm listening! + + "The X-Files: Our Town" +%% +Mulder: Are you familiar with the 10 commandments Scully? +Scully: You want me to recite them? +Mulder: Just number four, the one about obeying the Sabbath - + the part where God made heaven and earth but didn't + bother to tell anybody about his side projects. + + "The X-Files: Anasazi" +%% +Mulder: You've been making reports on me since the beginning, + Scully, taking your LITTLE NOTES! + + "The X-Files: Anasazi" +%% +Mulder: Lots of files. +Scully: Lots and lots of files! + + "The X-Files: Paper Clip" +%% +Cancerman: Nothing vanishes without a trace... Burn it! + + "The X-Files: Anasazi" +%% +Shaman: You must be careful now to end the ceremony properly. + If you leave, you must not do any work, change clothes + or bathe for four days. +Mulder: That's really gonna cut into my social life. + + "The X-Files: The Blessing Way" +%% +Mulder: I think with a crowbar and a small nuclear device we + might be able to get through one of these things. + + "The X-Files: Paper Clip" +%% +Mulder: I was a dead man and now I'm back. + + "The X-Files: Paper Clip" +%% +Cancerman: What is this? +Skinner: This is where you pucker up and kiss my ass. + + "The X-Files: Paper Clip" +%% +Scully: I've heard the truth. Now what I want are the answers. + + "The X-Files: Paper Clip" +%% +Sheriff: (patronisingly) They can detect every flash of + lightning on this planet. Did you know that? See, each + one emits radio waves at the same exact frequency... +Mulder: ... of human resonance. Eight cycles per second. You + can pick it up on any transistor radio. See that + Sheriff? I did my homework. + + "The X-Files: D.P.O" +%% +Scully: The tread looks like a standard military boot. + Men's... size 8 & a half. +Mulder: 8 & a half! That's pretty impressive, Scully! +Scully: Well, it says it right here on the bottom. +Mulder: oh. + + "The X-Files: D.P.O" +%% +Mulder: Get this Scully, the lab analysis from the first bit + of fibre we found just came back... it's lace. +Scully: Chantilly lace? +Mulder: You know what I like! + + "The X-Files: Clyde Bruckman's Final Repose" +%% +Mulder: If my Miss Manners served me right, that protrusion + from his left cornea is a salad fork. + + "The X-Files: Clyde Bruckman's Final Repose" +%% +Scully: Well, reincarnation has always been a popular theory + on death row, for obvious reasons! + + "The X-Files: The List" +%% +Mulder: Imagine if you could come back and take out five people + who'd caused you to suffer. Who would they be? +Scully: I only get five? +Mulder: I remembered your birthday this year Scully, didn't I? + + "The X-Files: The List" +%% +Mulder: OK, it's not yet the finely detailed insanity that + you've come to expect from me, but... +Scully: From a dry skin sample, you're concluding, what? - that + he's some kind of fat-sucking vampire? + + "The X-Files: 2SHY" +%% +Scully: (after Mulder's explained something weird) That's spooky! +Mulder: That's my name, isn't it? + + "The X-Files: Oubliette" +%% +(Mulder's watching a video tape) +Scully: It's not your usual brand of entertainment... What is + it? +Mulder: According to the magazine ad I answered, it's an alien + autopsy. Guaranteed authentic." +Scully: You spent money for this??? +Mulder: 29.95 plus shipping! + + "The X-Files: Nisei" +%% +Scully: Well done, Agent Pendrel. Keep up the good work! +Pendrel: Thanks, keep it up yourself! (then, to himself) Keep + it up yourself?? What a doof! + + "The X-Files: 731" +%% +Mulder: (to Scully) How come you never run my bath? + + "The X-Files: Revelations" +%% +Mulder: Either we're dealing with a psychotic religious fanatic + who's hell bent on exposing these kinds of frauds, or a + less pragmatic psycho who harbours a murderous + resentment towards the church, or maybe it's just a... + uh... very disgruntled altar boy. + + "The X-Files: Revelations" +%% +(over phone) Scully: ... the very idea of intelligent alien + life is not only astronomically improbable, but at its + most basic level, downright anti-Darwinian. +Mulder: Scully, what are you wearing? + + "The X-Files: War of the Coprophages" +%% +(over phone) Scully: Did he give you any idea of how to catch + them? +Mulder: No, but she did tell me everything else there is to + know about insects. +Scully: SHE? + + "The X-Files: War of the Coprophages" +%% +Scully: Her name is Bambi?? +Mulder: Yeah. Both her parents were naturalists. Her theory + is that UFOs are really nocturnal insect swarms passing + through electrical airfields." +Scully: Her name is Bambi?? + + "The X-Files: War of the Coprophages" +%% +Mulder & Scully: Sure. Fine. Whatever. + + "The X-Files: Syzygy" +%% +Mulder: If you detect a hint of skepticism or incredulity in + Agent Scully's voice, it's because of the overwhelming + evidence gathered by the FBI debunking virtually all + claims of ritual abuse by satanic cults. +Det. Angela White: Is that true? +Mulder: Don't ask me! + + "The X-Files: Syzygy" +%% +Mulder: If you detect a hint of impatience in Agent Scully's + voice, that's because the FBI's study also found that + in most cases like the McMartin Pre-school trial, + witnesses were often prompted in their statements by + rumours of stories that were being circulated, and that + there was in fact nothing to support them. +Det. White: How do you explain the burning coffin at the funeral? +Mulder: Don't ask me! + + "The X-Files: Syzygy" +%% +Scully: What's going on here Mulder? +Mulder: Something cosmic. + + "The X-Files: Syzygy" +%% +Mulder: Go ahead. +Scully: No, you go ahead. +Mulder: No, no. Be my guest. I know how much you like snapping + on the latex. + (Scully snaps on rubber gloves) +Mulder: This may not be any time to mention it, but somebody + is wearing my favourite perfume. + + "The X-Files: Syzygy" +%% +Scully: I'm driving! Why do you always have to drive?! Because + you're the guy? Because you're the big, macho man? +Mulder: No! I was just never sure your little feet could reach + the pedals. + + "The X-Files: Syzygy" +%% +Scully: I'm just constantly amazed by you. I.. you're working + down here in the basement sifting through files and + transmissions that any other agent would just throw + away in the garbage. +Mulder: Well, that's why I'm in the basement, Scully. +Scully: You're in the basement because they know they could + drop you in the middle of a desert and tell you the + truth is out there and you'd ask them for a shovel. +Mulder: That's what you think of me? +Scully: Well, maybe not a shovel. Maybe a back hoe. +Mulder: Well, that's good, because there's some garbage in + San-Francisco I want you to help me dig through. + + "The X-Files: Piper Maru" +%% +Scully: It's a north American P-51 Mustang. +Navy Investigator: Yeah, it sure is. +Mulder: I just got very turned on. (!!!) + + "The X-Files: Piper Maru" +%% +Skinner: If you can't keep you head, it's OK to step away. +Scully: That's exactly what they want. + + "The X-Files: Aprocrypha" +%% +Scully: Is anybody NOT looking for Krycek? + + "The X-Files: Aprocrypha" +%% +(Scully sees deep sea diving suit in Mulder's office) +Mulder: It looked great on me in the store! + + "The X-Files: Aprocrypha" +%% +Scully: One down, 1999 silos to go. + + "The X-Files: Aprocrypha" +%% +Mulder: You can't bury the truth! + + "The X-Files: Aprocrypha" +%% +Mulder: (to Scully) I think you drooled on me. + + "The X-Files: Pusher" +%% +Mulder: Modell psyched the guy out. He put the whammy on him. +Scully: Please explain to me the scientific nature of the + 'whammy'. + + "The X-Files: Pusher" +%% +(over phone to M & S) Modell: Are you two just going to sit +there all night? ... You and your pretty partner seem awfully +close. Do you work well together? + + "The X-Files: Pusher" +%% +Mulder: (giving his gun to Scully before going into the +hospital after Modell) Take it... wouldn't want to end up +pointing it at anybody except Modell. + + "The X-Files: Pusher" +%% +Mulder: Scully, I love you. (add libbed by DD when Mulder sees + Modell behind him in the mirror - that's a nice little + error to have slipped by editing!) HEH HEH HEH! + + "The X-Files: Pusher" +%% +Scully: Label that. +Cop: As what? +Scully: Partial rat body part. + + "The X-Files: Teso Dos Bichos" +%% +Hell Money: +Mulder: How many dishes do you have to break before your boss + tosses you in an oven? +Scully: So now we're chasing ghosts? +Mulder: Who ya gonna call? +Scully: Are you saying that the ancestral spirits pushed + Johnny Low into the oven and turned on the gas? +Mulder: Well, it would teach him to respect his elders, + wouldn't it? + + "The X-Files: Hell Money" +%% +Scully: Do you know how much the human body is worth, Mulder? +Mulder: Depends on the body! + + "The X-Files: Hell Money" +%% +Scully: (voiceover) I was surprised to find Mulder asleep in + my room! + + "The X-Files: Jose Chung's from Outer Space" +%% +Scully: All of her clothes were on inside out and backwards. +Chung: Oh, have I had my share of mornings like that! + + "The X-Files: Jose Chung's from Outer Space" +%% +Mulder: So what if they had sex? +Scully: So we know that it wasn't an alien that probed her. + + "The X-Files: Jose Chung's from Outer Space" +%% +Detective Manners: Well, thanks a lot! You really bleeped up + this case! +Scully: Well of course, he didn't actually SAY 'bleep,' he said. + "The X-Files: Jose Chung's from Outer Space" +%% +Jose: I'm familiar with Detective Manners's 'colorful' + phraseology. +Mulder: You still going to hold the boy?" +Detective Manners: You bet your blankity-blank bleep I am! +Mulder: The victim seems to confirm his alibi. +Detective Manners: The hell she did! Those kid's stories + couldn't be more bleepin' different. + + "The X-Files: Jose Chung's from Outer Space" +%% +Jose: ...for although we may not be alone in the universe, in + our own separate ways, on THIS planet, we are all ... + alone. + + "The X-Files: Jose Chung's from Outer Space" +%% +Mulder: At least they were having safe sex. +Scully: Business must be booming. +Mulder: I think you mean 'banging'. + + "The X-Files: Avatar" +%% +Scully: We eat fish and fish eat us. +Mulder: Are fish also known for eating half and saving half for + later? + + "The X-Files: Quagmire" +%% +Scully: What was that?? +Mulder: I don't know - but it ain't no duck. + + "The X-Files: Quagmire" +%% +Scully: You're so consumed by your personal vengeance + against life whether it be its inherent cruelties or + mysteries that everything takes on a... a warped + significance to fit your megalomaniacal cosmology. +Mulder: Scully, are you coming on to me? + + "The X-Files: Quagmire" +%% +Mulder: You know, I always wanted a peg-leg. It was a boyhood + thing I never grew out of. + + "The X-Files: Quagmire" +%% +Mulder: Television does not make a previously sane man go out + and kill five people thinking they're all the same guy. + Not even 'must-see TV' could do that to you! + + "The X-Files: Wetwired" +%% +Scully: (with gun pointed at Mulder): It's not the truth Mom. + He's lied to me from the beginning. He never trusted me. +Mulder: Scully, you are the ONLY one I trust. + + "The X-Files: Wetwired" +%% +Mulder: Yeah, but why stab her boyfriend through the ear? The + magic was gone??! + + "The X-Files: Unruhe" +%% +Scully's voiceover at end: Addendum to case report. After his + death, a diary was found along Gerald Schnauz's + belongings written in the second person and apparently + intended as an open letter to his father. It includes + the names of his victims, the women he desired to save. + My name is contained in the last entry. I have no + further explanation for the existence of the + photographs, nor am I confident one is forthcoming. My + captivity forced me to understand and even empathize + with Gerry Schnauz. My survival depended on it. I see + now the value of such insight, for truly to pursue + monsters we must understand them, we must venture into + their minds. Only in doing so do we risk letting them + venture into ours. + + "The X-Files: Unruhe" +%% +Mulder: (putting ball under Scully's nose) Smell that. (she + does and wrinkles her nose) That's perfume. Eau De + Ball. You know, this brings back a lot of memories of + my sister... all day pickup games out in the + Vineyard... ride your bikes down to the beach... + eat baloney sandwiches... The only place you had to be + on time was home for dinner. Never had to lock your + door... no modems, no faxes, no cell phones -- +Scully: Mulder, if you had to do without a cell-phone for two + minutes you'd lapse into catatonic schizophrenia. +Mulder: You know, Scully, you don't know me as well as you + think you do. My work demands that I live in a big + city, but if I had to settle down, build a home, it'd + be a place like this. + + "The X-Files: Home" +%% +Scully: Imagine all a woman's hopes and dreams for her child, + and then nature turns so cruel. What must a mother go + through? +Mulder: Apparently not much in this case, if she'd just throw + it out with the trash. +Scully: I...I guess I was just projecting on myself. +Mulder: Why? Is there a history of genetic abnormalities in + your family? +Scully: No. +Mulder: Well, just find yourself a man with a spotless genetic + makeup and a really high tolerance for being second + guessed and start pumping out the little Uberscullies. +Scully: What about your family? +Mulder: "Hmm? (Scully nods) Well, (he smiles) aside for the + need for corrective lenses and the tendency to be + abducted by extraterrestrials involved in an + International governmental conspiracy, the Mulder + family passes genetic muster. + + "The X-Files: Home" +%% +Mulder: Scully... I never saw you as a mother before. + + "The X-Files: Home" +%% +Scully: (as Mulder is pointing the TV bunny-ears at her + forehead) You still planning on making a home here? +Mulder: Nah. Not if I can't get the Knicks game. +Scully: Well, as long as the brutal infanticide doesn't weigh + into your decision...G'night Mulder. +Mulder: G'night MOM... + + "The X-Files: Home" +%% +Scully: You said it once yourself. Once you said that a dream + is an answer to a question we haven't learned how to + ask yet. You do good work Mulder. + + "The X-Files: Paper Hearts" +%% +Scully: Why don't you go on home and get some sleep? +Mulder: (laughs at what she said...she smiles...he puts his + arms around her waist...she pats his head....she + leaves...he puts heart in his desk drawer....) + + "The X-Files: Paper Hearts" +%% +Scully: What do you want Krycek? +Krycek: Same thing you do...to find the man who tried to kill + me... (looks at Mulder) the same man who's responsible + for your father's death... (looks at Scully) your + sister's. +Scully: You want this man brought to justice? +Krycek: You can't bring these men to justice! Protect...the + laws of this country protect these men under the name + of national security! They know no law! + + "The X-Files: Tunguska" +%% +Mulder: "I'll leave the window rolled down. If I'm not back in + a week, I'll call Agent Scully to come and bring you a + bowl of water. +Krycek: Mulder! Mulder you're not gonna leave me here! (yells + from behind the glass) +Mulder: What did you say to me? +Krycek: What?! +Mulder: You called me a bad name! + + "The X-Files: Tunguska" +%% +Scully: (reading from her prepared statement) I left behind a + career in medicine to become an FBI agent four years + ago, because I believed in this country. Because I + wanted to uphold its laws, to punish the guilty and to + protect the innocent. I still believe in this country, + but I believe there are powerful men in the government + who do not. Men who have no respect for the law and who + flout it with disparity. I have come to the conclusion + that it is no longer possible for me to carry out my + duties as an FBI agent.... +Senator: Are you tendering your resignation Agent Scully? Is + that what you're trying to say? +Scully: No sir. What I AM saying is that there is a culture of + lawlessness that has prevented me from doing my job. + That the real target of this commitee's investigation + should be the men who are beyond prosecution and + punishment. The men whose secret policies are behind + the crimes that you are investigating. +Senator: Either you tell us what you know about Agent Mulder's + whereabouts or you will be held in contempt of congress + ......Agent Scully? + + "The X-Files: Tunguska" +%% +Mulder: Why is it so hard to believe? When the accepted + discovery of life off this planet is on the front page + of every newspaper around the world? When even the + most conservative scientists and science journals are + calling for the exploration of Mars and Jupiter, with + every reason to believe that life and the persistence + of it is thriving outside our own terrestrial sphere. + If you cannot get past this, then I suggest that this + whole committee be held in contempt for ignoring + evidence that cannot be refuted. + + "The X-Files: Terma" +%% +Mulder: The truth will save you Scully... I think it will save + both of us. + + "The X-Files: Terma" +%% +Scully: The truth is that the type and placement of the tumor + make it difficult, to the extreme. +Mulder: I refuse to believe that, I.. +Scully: For all the times I have said that to you, I am as + certain of this as you have ever been. I have cancer. + It is a mass on the wall between my sinus and cerebrum. + If it pushes into my brain, statistically there is + about zero chance of survival. +Mulder: I don't accept that. There must be some people who have + received treatment for this, we can... +Scully: Yes there are. + + "The X-Files: Terma" +%% +Mulder: You mean there's no procedure outlined for an invisible assassin? + + "The X-Files: Unrequited" +%% +Scully: Mulder, you have never remembered my birthday in the + four years I've known you. +Mulder: That's the way I like to celebrate 'em, every four + years. It's like dog years that way... +Scully: Dog years? Thank you.... +Mulder: You're welcome. Oh, I got somthin' for ya... +Scully: Oh you've got to be kidding me! +Mulder: It's just something that reminded me of you. +Scully: What? An alien implant? +Mulder: Two actually. I made 'em into earrings. + + "The X-Files: Tempus Fugit" +%% +Mulder: You thinking about Pendrell? +Scully: I realized I didn't even know his first name. - + Actually, I was thinking about, uh... this gift that + you gave me for my birthday. You never got to tell me + why you gave it to me or what it means. But I think I + know. I think that you appreciate that there are + extraordinary men and women; extraordinary moments when + history leaps forward on the backs of these + individuals. What can be imagined, can be achieved. + You must dare to dream, but it is no substitute for + perseverance and hard work. And teamwork, because no + one gets there alone. And while we commemorate the + greatness of these events and the individuals who + achieve them, we cannot forget the sacrifices of those + who make these achievements and dreams possible. +Mulder: I just thought it was a pretty cool keychain. + + "The X-Files: Max" +%% +Scully: Not everything is about you Mulder. + + "The X-Files: Never Again" +%% +Mulder: So you're refusing an assignment based on the + adventures of Moose and Squirrel... + + "The X-Files: The X-Files: Never Again" +%% +Mulder: Eeenee meeeneee chili beanie, the spirits are about to + speak.. + + "The X-Files: The X-Files: Never Again" +%% +Mulder: How did this happen? +Scully: Birds and the bees and the monkey babies Mulder. +Mulder: Birds do it, bees do it, even educated MDs do it... +Mulder: (to woman who had tailed baby) When you were admitted + you said that the baby's father was from another + planet. What did you mean by that exactly? +Amanda: You know, that he's not from this planet.... His name + is Luke Skywalker; he's what's known as a Jedi knight. +Scully: Did he have a light saber? + + "The X-Files: Small Potatoes" +%% +Mulder: Scully, should we be picking out china patterns, or what? + + "The X-Files: Small Potatoes" +%% +Mulder: Hey, Scully, if you could be somebody else for a day, + who would it be? +Scully: Hopefully myself. +Mulder: That's so boring! + + "The X-Files: Small Potatoes" +%% +MulderEddie: You're a damn good-looking man. + + "The X-Files: Small Potatoes" +%% +Scully: I'm seeing a whole new side of you, Mulder. +MulderEddie: Is that a good thing? +Scully: I like it. + + "The X-Files: Small Potatoes" +%% +Scully: I don't imagine you need to be told this, Mulder, but + you're not a loser. +Mulder: Yeah, but I'm no Eddie Van Blundht, either ...am I? + + "The X-Files: Small Potatoes" +%% +(Scully's closing monologue as she types her report): +Although cleared of any wrong doing in the deaths of Amy and +David Cassandra, Agent Mulder still has no recollection of the +events that led to their deaths. His seizures have subsided, +with no evidence of permanent cerebral damage, but I'm +concerned that this experience will have a lasting effect. +Agent Mulder undertook this treatment hoping to lay claim to +his past. That by retrieving memories lost to him, he might +finally understand the path he's on. But if that knowledge +remains elusive, and if it's only by knowing where he's been, +that he can hope to understand where he's going, then I fear +Agent Mulder may lose his course. And the truths he is seeking +from his childhood will continue to evade him, driving him more +dangerously forward in impossible pursuit. + + "The X-Files: Demons" +%% +Section Chief Blevins: Agent Scully, please have a seat. Agent + Scully, we've had a brief discussion, but will you + restate the matter we're here to put to rest? +Scully: Yes sir. Four years ago, Section Chief Blevins assigned + me to a project you all know as the x-files. As I am a + medical doctor with a background in hard science, my + job was to provide an analytical perspective on the + work of Special Agent Fox Mulder, whose investigations + into the paranormal were fuelled by a personal belief + that his sister had been abducted by aliens when he was + twelve. I come here today, four years later, to report + on the illegitimacy of Agent Mulder's work. That it is + my scientific opinion, that he became over the course + of these years a victim, a victim of his own false + hopes and of his belief in the biggest of lies. + + "The X-Files: Gethsemane" +%% +Scully: He said that the men behind this hoax, behind these + lies, gave me this disease to make you believe. + + "The X-Files: Gethsemane" +%% +Scully: Earlier this morning, I got a call from the police, + asking me to come to Agent Mulder's apartment. A + detective asked me ... he needed me to identify a + body... +Blevins: Agent Scully ... +Scully: Agent Mulder died late last night from an apparent + self-inflicted gunshot wound to the head. + + "The X-Files: Gethsemane" +%% diff --git a/bin/group.txt b/bin/group.txt new file mode 100755 index 00000000..a0038f77 --- /dev/null +++ b/bin/group.txt @@ -0,0 +1,4 @@ +root::0:root +bin::1:bin +tty::6:tty +users::100:users diff --git a/bin/hytdisk.dat b/bin/hytdisk.dat new file mode 100755 index 00000000..80199b5a --- /dev/null +++ b/bin/hytdisk.dat @@ -0,0 +1 @@ +ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååFORMATTEDååååååå \ No newline at end of file diff --git a/bin/inittab.txt b/bin/inittab.txt new file mode 100755 index 00000000..b2991151 --- /dev/null +++ b/bin/inittab.txt @@ -0,0 +1,4 @@ +# Hytech initialisation table to format the RAM filesystem + +/boot/mkramfs.sh + diff --git a/bin/kernel.bin b/bin/kernel.bin new file mode 100755 index 0000000000000000000000000000000000000000..9ae4e383ae577480389ac556e46ff0f313e90618 GIT binary patch literal 81008 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�{SZ2cSz-ZQPQ*+9DiOQwNgkJ+6idc+ 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 BlI{Qi literal 0 HcmV?d00001 diff --git a/bin/large/adduser b/bin/large/adduser new file mode 100755 index 0000000000000000000000000000000000000000..b64b9fcfad2608277d9648f3b65ec9300abcb0e0 GIT binary patch literal 13559 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 B^B({J literal 0 HcmV?d00001 diff --git a/bin/large/align b/bin/large/align new file mode 100755 index 0000000000000000000000000000000000000000..860f33f1859387878cc76955194df8f7f9365019 GIT binary patch literal 7134 zcmcgQZE#c9l~0mwB-t1n2s{VKzK5DrSOv6;quLqPn^H!!8?f7KYtjud0g7A)N0zaK zOagBZlwb%S8Olc*JHSH1R{%R;k^bHR-g$N5>Q@%7#1S4*oZCIEd+Oic=zgSodSZ$Dzir}wF)WJ~b>eyIzQ{&b zZRcQnyl%;lD>fvSC#n*wHt*cNvbSxZ^NYdu5{K9EYT|v#>~Pp(9g#2Fdx!{}?NClmW36Y7nas7L^S;YSB;A} zl5)|e?Re2I#w3z@x1RPv@TaX!R6$vKVpZPHpllL0P@eH4Y~oO!24z}e75LM^Hz`q- z2i}atavPsVKsKL|sA|faImlo$6080(Luj(i{At_rUfVC*A}f~l58S$iI6JF_1c85zHN_}{l%jFvARGpFQ$tDPQK=>1EZa}ybn=S}GJR1imRQw267KJsAqQ~i(~KZlWu~4g}Q5TN71u!ZA)S_^*R6MkF8Ki3`LdJ~a<}??!ZVzX{F{x%=8G-TqoCY?Xs0yQ6g5Hl zS5P*nw(jDnpu1gh;*C3!;Q1se&LYj{n8R;Cr~`tZq!7{p(NCOD$nzTF@_D4<3=*7s zp5&?{nuG#OijO@^wr3pKP;i~#VzG57ObvX=*dr0tt$UN)Z z!?$+HS;m^ux2KLozvIF#H2 z?|s>hJR}nG$nU+q3#B>&!O;~cZBl6WW7rlc@Y+b&p}_vpuxzH`5jH$F8itY)@Q!lW z!qcFP!0FM&l8uC!cCp2I2$Ug+4m)S1(EYW5M}2J$gGWO-CX?d&l*PWMon_o&(3|p( z16`}{C3NWgT4R(gkWHvdB}3pHK7#}#mTZ}Hy!3nRak>#RNgLhh&$|W&2DC^@Vh57mlYhMdHPtN6MJCR@-jHh&)cLznW3%LA4a(Oh5|$9oomH<^9=_Fy7wthd z@vCz?Kq)d8$1lX0)f7cLHO%Wj4Ua>%gK|VZkjKn53#4zHd#_%Wtl%*}4IWE_ZW7J) zx!wk~xjymy%|`Y9L2d{AIFb89n&!xVpCtWUu~gr)Zui!A7CWbc($^TZtj!v0X9-0Rx(dN4cv=JmIt}47*qns$DJV!I(WV;+-G!OFTU_*SZZo#U1?Ua`jXM(_~3@I`%FZXWPyJ_#9y*u_^*}rM;^LzP8C`!`d*vEn=Ib~~2&gRSs4S>BXL0cywwH1k5RNYW z340jp88we_?o3EcznC{M?@XAkgg%7eHK_Rr0>6RsOHkI-LzgtA37G$ud<0&c{SeBo zsZSp@s0L5#GvN840j;&At9d_Z{3VDsQRdgWoEF3%7F+c>5tI)hdJUo?+h z4C33xIVrn-%;u&QPocTfO^eC%w*G`B!QTqL572o#ksBC7TEY7PS;z}NQ5{F2mmeg|ql)SQICsm;yg6}jn%vnOT+gqRw6PlEp{_@V*cI6P>9QH(r%i28V0 zocq_0;8sf}j;7B16o$^T;5&!S1@K+O<}&`S;O`yqy^9Q{3+N6hw7Z|8^ZkA_*KE`* zZmyyk{|b$GMMhoD-C992xq|n(p(uund&u<|w~mRglUL(OhyqdO#iLqy0&hi*lASW+ zp*#fDn(`0uH-qne?lLJ|(!K}XnF=P@9&HVj*uk4=*p(fE=$^EAu^rI0MKh(eVv}fU zDs3O1Rq*UyXTol@jj{ZtM|O^niND3bPMHXVC~G8d$1^bbJJh2rQ7%Nz{nn0IAW?!T z5yrH_Toct(l*zDqYKhwt%Q^`D5%7&Vn0v>6+nSw!i=xhQy1;)AeD^W35)PMVzD^&@ zDAYOI^<DbeJ1|2TZfXb}ZX?C|A z6s^OJg@cGuT7%cJsfHNG1I!)*@MKcF#-}}~+a!hYI$#^q0ZJ(i9k9~#0_s4v38l`G zNUpFqeRF;RHATb|Yq# zQ^*4{lsHzeMs%(|a)jS)69s81sPa27BSqEdwkXn+#4{b}m#Bs&<+8+9AL65ViDy1; zU{z{t=OJ!uCOQ-8qISi!O>e2M6#*C=NQ6 zKlZFx`akZBxi=fJe#JL9EJ8+-`8OI+tC<5xCgLTbgP^caj|^j5Fu4q z8SO$Cj+3(=8O>)9A9oFW#=)uO7)+=xlMeHK4|3vGUO$C7rfWJ2*t;Haz{=6CSc)YO z)nOcpjQR%{_gDlZkz4t^XhRR6Ng2o(JO~QRBm#@rm9q64S4%p5a^^!tm%6bYxsk%- ztynuxV-IHODbESgQFJqX5*9XTP zD_;b!IluxO+pT=P4U;mg5h?Ppmyk(>(j>9QjMW%D_~|sIqZ)}%(YnPcvXIBlV5PSn z@R z4K}4OC#BZ@13w&}9;K;<>5moS(~LzIDym+c8*xHsC3`^d{95;jP%{L9VS3exjylsZ z9E(}}!G(t=<59wR$w5iXAeyjjvpT1sCGvtuCz=fz!D+_gxg;hR%s)I>G#iV}4;Go2 znQtTij_E4NIEk!%@ESM7pK&SZ@n_t^Z2sKBvl90tbe~oTV|b)cGM;z3c_QyIEIb|t!hKe}jZHAn z>Bw--iut{b3eq9|F2SM^#d>~jx!U|DXB|CwEI>z7#3L_HZ;o&0GbBzvvuKBbLu|$8 zYlx;hbNNx2D^a4`M%iWwz2@<}g@ijhV#qTMOIXExm;8w3u23On@V(qQ89?U03KXhc zQ?dRjX-!pSg`lSuMYdA>Oiov+Alp` zYZq!aR0aZ-{tBsf^UGD0{taw$-5US5gZhC2KbK(FZ`@eDQFuxc?1JE4E4T%Bo#1{> zSXfoLmVRt`L9i|;{8Y!oW+Xun?lkIuZwo>Wj*aim+xp)zlOP$B*nZH!|E@Kdg}Ev7 u=qlJ}GQM2;jKPC8M;ibAVC>W9m$1(~!N&oXvM+6dkJb$`QYicX?fx(IRsFsI literal 0 HcmV?d00001 diff --git a/bin/large/apropos b/bin/large/apropos new file mode 100755 index 0000000000000000000000000000000000000000..fd370b0228cbc6a7b4412f0ae9c2bb51ff66d9f9 GIT binary patch literal 11487 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

lX3JhO^41+hQxbxsm`A zsG9>OWW6gn1KY4F8T5VR4mb#_r}bS z{h6^`cc7uzjdaCoZQ4!B0X{RZ5J??9Vot`7*qUydr|J2+%>NLv99?%m4@bcS|4yMK z+Rlj3S@No!G7e-) z=-Lz$t(!B#e-;!Gj1u1h#UPpgCN9{_w2Nk^23KI4X;^2gu8GTYTkX@3w>8 z*;($e`eZEy`ZAhI$n$O4Sa5r%V>9IV4 zlvA`J+Qrl6)jR`%Ql?GPTc2{5yTSHfmZMD7ktU?XmT6S6j^hE+m!P;Jt-s0B)E*?& z8Lxz{j1p40ZYd#Y4k_U@8`O^VO?n5Zm9jjX%9KbZ00SBM;TRKRsz}Y%DZ)P$ETm!> zKk_1EL|k}V3OhnEooa5?_~QPa>=VL+m0EJ7h9aa(*>DMUjI)|t`C{P+nf0jtE_0Jf zw8|K-*W0tW=VJP*3o<1FdIkl;H}aA2jmA75#R^3XiMS6+`q*LIt)wpx4qX3nj3zJ0p7hEk2~_F{3K{vLg!fpU z1&ChqytRD{l}u&x;l(dbFiS5cSYgLsN5zR=%ei!hnk;S%eCy*F)D^5lS(62O0uV`T zIw4h?Xv(f}c(d0l-~Up9EP19El0f7$G3cKQG-qP(9#(hiWLl-IWP?xh`fL;5)1O%W zq!jI#%v2>PPcpChT5wFhZyMiX2S>;itIlDjw@&I*+FtxVH4mpl$ywVm#tT7Z&vKsf9r-J}LQ3odynJeR;==I%W5boGvh>9@kiiqutbo zMq_=xGR7M9{>YpSLb#Y!y*F9tqI*p(h_Tm9SCTJ6Lw=^*E}@cnpl^ftPd89e4Fu^? zu3814bRZx`pLPyDQgjw`Me~pd4qJ|bP&n^Pj?0vq|AUSNdKGs4opZYt)K=p^{8+K< zZ{@ixLHtQ}UdGuj-u@eL)ot?;PU^ zH#cd!{%gd9F05tAaMSS_JIASjRo^RvIdnWfYn`1K#YDClsQ4LCeU@}fvRt;?e}N)e z#$j3WP(gbM#iEGVB0E!$pfg2%MzK{6Ul>K4CcVHOiqpHSR~IgH`>LGiLQwfA;=|@e zS$Lzjhz6rQ41qzr@oJ(zYZ2`YxE@j^=mS4^Q4`3&5MZ)0n3bY4q&yc#D;2oMtc9#1 z2YL5k&w5kK267dd$WS=2+G@{94U}mb!Ab^JABD3bN64L;?3ZcT_iQr9%Hiz!d@6e# z%cwBAlYp-XrVltnT4J~RYX65}W_o|kteA)XCONwb4vbpSBY}{qpnOm<% z&jOz1^w619>_Ls{6!9E0U%ewixgg6G8LV&ED|L;6sgf9l|Mgw-LRLt=Blx1H31oKX+=Z;HGIhokRy|8qvqy9mbl6`GYXLakN9wwH{-1m zmUM>FkCo5kJbB_9sJKvV^zn^hY$wg9b`kkhB2N0$Hvm^6hZf40$GAa8C;cFz$Qcnn zt6wA{XGHugA|_d<aglsztPhV3)-~N#w~mI|+}1@#Q(MSr@*Azey1VL2-Iywy+p2}v)`bGC z+T7A&Ic$+T8=H)|t%g6auHNuBwKc9W0*#oEXBOeXtu;1<)&?3IjJhCU)Dox*)zcjB z*4kR@8tQ4I@vQ|bj9^`8?HxvIsD%!cmg1HL3$#T>VBNa*^;-FD+SR7F$XMDG+|UweSQ|3TyNZmj zR90MR+*IFy?X5&=Xl=c5OJm@>^)0P|&<2`WTDLCXZ)#}_)Rnr8Yu2qZWAAPOlYUmi8>rEnjV;V|J>W}o2y&XPDUK=MRV0x2&jEFD$E8+jK=3JqG2$G)B$@1Kyd}Qs3wd>KjAJpk!yzcg}?8 z^p*8Z(*wS#imYj?Y3rn_<5tPNv~^-tI#A4X@oL&WX;EcYMKbWtaQ_|4yJVfv>r-py zu6SVXvU}$)UOjiwaPMG!MMDM8Rr>1YwrrVqE!BA`R#d%q-?E{bDoca!xAmw0V_76@Ww+h?521-)$F6_eyZC|v33N0aHpv?8jAgl zYIak!-B&YF1%H$EQBwyscJ@6Go`ld2ig$wSq4-{1^&X1tm8vUOdP)>6>7d%q^qOYR zB!#^pP0yU=8ENxz#r-*#sO!R2%)If26TU>owkA=cCS?;gLt1y3~)Hv2pH6;}FmA#!z&v|s1nljXw70*moR#7_Rico-F$nV@hNwl?`7_OEOfOg#tsMnhZs=KHe~yjgWnj zY$%cq&QQMEQ0yM5BX9)O9-sYLa?K&j8z{#(%0Ek%c~tuHr`H?`PYJ%4Oq}+_Ly6NW zURL#R`q0K>ypu<=*bL_=KKkRo(tB}?8Z)vx6Pc^5ON0$kQ!zD8sEAU%KTz69DSxmr>0aMG-rVVr9IMrwB_;x=Ld#rPx$s9HUrKS5i^&{5i+iBqDKQd2D-CB`U~IeNvTlqjK;&zdKO@VCSeo~kx%YwTXO%W}m(rysBOQU}jSUOT9EC&hPBNa@ z--B%R4$=dAaGLqIEKV*P63yuNdMw-?O6?7oQe6whTIJ*hf|O{XRI7CnC0@x`)>6|bmUR#BldYEug}wvIch+4%!Nmi@ZZ0M)cmv^9xY z8Cob=UbnIbt?$*XN7}$9nZ?X=vghXgsy}!ck`^V}D3uIf7QBc1Q|$J~GpZ8--^PKj zi!r~m$PxEV+Ohch^wKAWk)?QryVqjO9bR7cz_s9T#eloYw8@Kr%`$=S9PAPp+d(^~ zX(vb>pM%Sq-drxTGj4AN12e~;I}a}DrZ=eZO=@_H>fe?t<~R@1Q>=W*t8Y;h+Bc~7 z&2;l7r`HrYe3Bxsx8bxNI(p_Y-tirj>a?(Z5C4G;fxoCOF}eUH-k{W*lzNL&ZzDHF z4u7FNuB@Jx7xhQ2n_fMYb#0vsEOz`8E2-`<#a>6w4r4ZuZ4XoQbv_|Ky*Yi?CaQUj zqA4T()5hGK>Kz)w?x%(ps&Bpb0B1!xI)QJDKNTd~DB41GuTd;jFC-Mf2}~hLi-`UB zN}&A0RmiF3BaWl4^Hjgwqab`&g1mzAD#}iZ?ZO1}08B!9=ix!V*Uk>&xR$!dHQ>ds z%DJZW$&<7;?*ONQgK|(3PKrA(^*E#MzT;8OYWlMCB`Bq{cq$VgCtGo%)V0hA7CRCB z!HLR;ZGEC4go!yov4hSJ%-nc`MBoiWO}JX{ zPO(LU^vZp}*3GQW_$&Q*#T==mcqV{5IYW<>f-Rf_ycO!{JK4aSqK;rE^C}dsxX)d2 zetJ18Ucw(4Sn*O1)>sx-A4RCiO>Z2>6;FT) zwen)dVHYNZ&&$|7dRy@}a(gx>=usHN2u07y>YIbWBa$@3Bl>V7PBT6-RemGiM-K)@ z;>+&{h5FCSG2B-F@;kbaXE@hLzTsCpFZ!>s`}L;kIgX>=pFV~g$;lO?+1V$P*y=hf zWV7Wbxl`q5lKAdSSU-@%G7BF|?fPTM`5xdC2<<37$S_{L5b`O&`%RxuQ)S?=bO4R? zJz$l3{Av6Y`rVuuA51P7nuM)j5qSHMTwlo`Q*M1%Gu&4?x>y_FU`Sj?L? z3V$3A|6?-;`KHr}#hHXD6uSr+CO?TD56;Ale0MX?$Z+?+uft>=$L^F#GPMOK=gC($ zf0X6Tg~Xx9oxb_$H9HrCFQ&x6fLcL`-wk}etlHZ5T6hAy0!3JDsReU?ku&$Kxw<)% zP5T|htQxKoG`WE01Dd!wj zja!4xCs?f_eDqIVeg{Rp^?Gmd9pX!zUdy{%#rew7X#pR-nE?-f`(_5b7+qeUCh&?~ z$A+SCK<`6cNB&)hZ&$tpjlLxB4)p%HnGgMS7IN~xOy#GW%nimz?0>%>OBJ$Z{$iRt zNGfwPBcFZwch8MC{Hb!HY&rbfN`DbM-?_a1sUbu4=I+G)<)j=!ezRn2<4)oaWPCEp z1te#tqCW7xyUDmE{eLBHs6-mN@rGl)mIJnJTNW3MY)d$;g-(OEvfZ{UB`RPo76!u3 zf1(tg-L*n7r@^(u8N3GVY;hp|ID)YVN^=_7IhJiKnrLxlNxNvQGfuH?T8PHy z^~SL&(+1?(!dh$sLS33L!yrl!0cEsoK@reCwyO~l{%jSTI~}ZIy#_Yo&(YXm@MC1< z1)?TE&P^M&LOY59c2*g}It89-UU7Z2))+(yjm@r*l%dR<;`(S!p%QWIRuCvEV3@QK z#DKVJrK?k7<5mEI;lY9vF(<>7w68Z&T6(cSM zl|tdPXdJXN)B?;ng*oAY`A@L~um$B4<7jN!Tad;|yCO>W%@)bllBvYl@+Fup6X-;6 zIKVO(K@1`>!;*l~f-O1_2HW)j=K!;IUZiqGS1T^?1K1iHjs-3n6tJzi0%BCIEsqgr zBxD4L+m|u>h&D%A$Dp*uW;TZk+_btt!_Mxkg0;B_2!+gG7f2%5xF4Bg`~MMCE>Op# z7ME%hOIm3=L{pv|3nsx}@W*Hz;`kYx631Kw*M6RlGzBGtW7B~;Sky4ENfYB!C}|~p z6+1H6f-X#qi{q)-pTQO+?Lq_yc8KkCLu`uu|39FdrVwm96`0E1HnhQ2IxQM4f;0yT zhFKIQ0Nd7u2~>=cI&{2NiAHOsQufjSXZ-1(AXpSQKn{rnnN?f>wjdB&|5&9QEeoa? zBSh8!Y(Y$H+epgMvJ%B~QdljxuCAvIun?%J8&Mz`qf?Ep*u*0+Uo4Q=pcS?-1>^#O zx+!-5szB)+sizx zM)VpxPB7}9g4WU5;=x$h3otrTX(#d1IFGdeBIYx?J-t_5J3HALG-bUBgi=eQu{l;X zty;S5?(3{Om)6zYz0z9MxN>>jGHcG9IevA;D!=k8Re7hXRF$h$<*n*Ro1fU+vpKW* z+AZ~4+P8eP<9yj{nqUpw;$bJ zv}3`JrX3wSez(JV>BlcU{Zijc#V>#F<-dQq^W{%o4z~QHWmC()v`lENZjHAdX#Gjc zr>*5X|7Pdro#~wucYS}?>RktS{eD-d?Y6cpZAy(K&2P6-(^L*dcAH#P*<)n?YDu5OHCJjR-cE?SehDkiMQg z`#0##dXOGG2&Jr2A%_a9c$mW;a#+?q^kgg9JSY1$kJcO>GsBmeZ@&5V-zsoc1GoSX zLU_c~E%nX8uzJLHhxh-o-b})xrOm`N%9 zN$e%F0O%FaEtWmY#d?Z09xa8Fpvqz)*0chV!wyXaV&x~xGXQg?>5ibj?|aqiuFbU#`le zwYdLy-1d%L!G+Y&aDnT;h45k?jTQ}W!WNzEoI;Kpn~L)2E=e&q*jGj%Qw68f%^djf x!JqlkOv+5o$*RPrYo3{~AY297t;X}_9phP})eIUdO=J8#X|;X-#jB?k_y>MZh&BKK literal 0 HcmV?d00001 diff --git a/bin/large/bd b/bin/large/bd new file mode 100755 index 0000000000000000000000000000000000000000..8419050e03c498fd79345688603165ccad8256a1 GIT binary patch literal 7442 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 MDiMi0lw6dE`Vm2Jv;}I} zEh+t;TTPG7zVT!t!U0~9b!>i6r(3I!j<7v{ccbfhS=mjN$fREySVNVGjL;M)wR%By463x4jV4dQz=Dt{^P@2q zQe6YDsyy)VHMT10w}W;`z{LJThJf10-C^zwyscAdT*n&puu;T4-o%VnETtRx9Y^y< z)?}hd)(4Nphe|5C+zk5Q>7hZEh3F-yBFsQJwsGpoYi9X-hLF3;uqpk4l3{%KKf$+4H^(cmy*-fv>1 z+`&7LG$moubT$d^68BERbw=dIgoQAEoOT%Y88Kxy(H)b@vYN4#5I=n1ve4d-xLm2I z@dSktUT@?%%s?&gA;aN4J2&WONEbk*N}x5HZ-q!h7gEAxtt`vZ6%I1GK9liQsv2$) zXe8YdDyU>evf_xPPcr=Ar0I*7$%|K2c;6_m^q2*2&EkskAInP@uaFnKv9i+h+Rx=R z<%?ID1$n+K&y`>F%JNI{i?7MDOP1#g)22-mW-qQ3T;)rIxrzI z?x6i)vxM=*HREaG_!?^S3HX=31i`*UunYFpg8gOT(t-8^HxAr6FmON&qy$WXVS((x z1A*MY*nkokAD9pjgolMO_>9w@p)Ub{@i;y4xJ-?~UtWXu@1P)L4fbLTJgEIUBnomu z|4-`pziD*_AupjH~sZV3o%G2u9O}$#8V@Ot?P=z{H}CtI_Zlw+_$C5G0Sqv< zXp=S{Z+EY6(OUP?C+bXnruG$Mr+$v&9y;5#hGVtRMFN0o=fHhI$tyeR-cHAIe?8c( zmhSIXFMF@L7oA$8W5sW3)?q&tA7&b3 zCt_~`%^^;~u{O>6Yl8*#Ny9#ApgxM)m}|AjDRAu-Ce`x>l@{w9WOy7mzWdIyXYE8?R+{`i|*x-2g(7j?fHf`55+EfoL& literal 0 HcmV?d00001 diff --git a/bin/large/catman b/bin/large/catman new file mode 100755 index 0000000000000000000000000000000000000000..3d0f27b329213ffda1eeffa6c3cf242e63f5d12b GIT binary patch literal 13456 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 R99sAP_p`2PLsJrh{{wW4zd8T_ literal 0 HcmV?d00001 diff --git a/bin/large/cdiff b/bin/large/cdiff new file mode 100755 index 0000000000000000000000000000000000000000..41819458aec7571d233e179c3b3b2e2e57a67f4c GIT binary patch literal 15315 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 literal 0 HcmV?d00001 diff --git a/bin/large/cgrep b/bin/large/cgrep new file mode 100755 index 0000000000000000000000000000000000000000..1855f65c481907733288674b3bab583c3f059444 GIT binary patch literal 15713 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 literal 0 HcmV?d00001 diff --git a/bin/large/chown b/bin/large/chown new file mode 100755 index 0000000000000000000000000000000000000000..65000688cae8780c101a57e3eebfa9df04bd50ae GIT binary patch literal 7844 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 literal 0 HcmV?d00001 diff --git a/bin/large/cksum b/bin/large/cksum new file mode 100755 index 0000000000000000000000000000000000000000..bcadae56a0cae9b786692a928ce954f6f6bd9fd2 GIT binary patch literal 8024 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 literal 0 HcmV?d00001 diff --git a/bin/large/cmp b/bin/large/cmp new file mode 100755 index 0000000000000000000000000000000000000000..c04ceed26139a618d4010e467c769503633279cc GIT binary patch literal 7556 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 M>ttk5_WwKlA6Hu*j{pDw literal 0 HcmV?d00001 diff --git a/bin/large/cp b/bin/large/cp new file mode 100755 index 0000000000000000000000000000000000000000..88562832dc91e15862ab744d00787d65d293331f GIT binary patch literal 19863 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 literal 0 HcmV?d00001 diff --git a/bin/large/cron b/bin/large/cron new file mode 100755 index 0000000000000000000000000000000000000000..ac0c95d2fc48269f255ba4520da73c0a98805120 GIT binary patch literal 15084 zcmc&)dw5jknLlT8oe)AIf+xkxnT*&WQ4%Yr35%)4n7FkBYT0OOn}XsXEgce=?BInd z0d-w_QC5nzwO~`tD^obz4Z@4a8X1Dkd2qv@J8AE)PA6+ zqnje+(lo04AmzEiUGMIzJk$4q(;0Mom$di4dte~aQKeh|v1-8jw57jqubI{Q=nty2 zU*Fu`(|@2NGH~zll?#_2Us>C~B|5XG9iuU<4_$z#)ta@AD_-c1~Z>Ye0wQbRU1XLolDkT3nV=whnRh<>l|J5-;AA8N>)gP#aB zq*Hw?`aSYxkT)y3xR7cxqu+GOb_^8lnbF0qg%=Env6<2DeIrwAbzbmK?ceNi-q+qT ztG2KI&>j*R1Y)cfdw9ke&jeRlJ&y(2o@k zbS?KdTi494(tcH2rFY%^>VU#>|8f1m-&&xj-CDI;tufI0%OzFX6AP=f$HhWGEfA-J z#^tA7hNJMS)HO7bx`y$M;TxYwSD*Gw?JDTX7f8LSg3SEov@WZn+swX;)@4>$Mmqn_ zUQX+?YRlS7witixkIY*HDz7MAa&PIvyGmy-FRkrA(AQYfRKjQfLP%S!!PPi!Py622 zR;~W`gEqvMzjWzKxi6(3NI_XXqii6!npxr@W{H1gmUvLHMAzLOW9E&Z82K`BaO>de zIo~0F7By#9={QmF)d8xBQ(cU_!{i&1Bd9S>O)>HhQ}Ym`)0)!~i@S2PO5LG3sTnqlX0?{E9X@8qrFYg(-8 zmOi&TqQAROFiD0r^!Tjmo+fvrD_x^H2i2rGxwAmil0BJU*pvN*Jvm?4lbh_(G@ObW z98{lH$ozQp(OK1L3=9K0r{!qem8n(EsxIi=XRX?X!(CK-Q`?F?=2+LMeUai1!x8I` zTl)KfhN7F=!ejoWpf_wyee64Px+4Nt6E$a_c;C_ z9yPyB{vNEI*kbJSqi?|==~!D&*P^>zI`7>|fnyYS3qMCGK*jHbi{1;9?``t-fDFf| z<}H_&4P`T{+V#$UYB)yqZx!}gb!+=q>^a!`0Jn)j&S1>#8JGH+V>*nz$%a1bg0<9q zl>Fq>d-h{^j%kwbD0!(wHp>^an*PpyXStS~J*zr;>w97Ar}q`V7Y@2ZW??~|X8mSU z1h4JDxM=k*X$`moc&u@I@8m<&9iA}6ZTIKiWT8=096%QY7q2^D>-%q}iGYfN$DoW*SW!FuK8qpHW~ykFO-(XXG7_ z;$Jpi4Swy>#L%Oo8K@6gEqotD8o^9>O<^X%EdMj!H>ThnY>cUe#J6T60_{WUDcW zDS@>M;&H2GQ@`XPs4$Pih=f=ClsTZf#hUbU<}YbMgT3jVeDJ6;;|#==>je7=vmWd{ z4dvY%4^S|jLK)`O$)OSOuCuRanR_Yl

iO*;=7&$<>^}lMYNhsRfM5$w|_Gu;-93 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 ZYM&`Sj!`~xK(+X!kMiMu2K@i^^WX0Pivj=u literal 0 HcmV?d00001 diff --git a/bin/large/date b/bin/large/date new file mode 100755 index 0000000000000000000000000000000000000000..693ebd8a2b4e207f07460e023c17f834f6dd72bf GIT binary patch literal 5914 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 E1Bxj;LjV8( literal 0 HcmV?d00001 diff --git a/bin/large/df b/bin/large/df new file mode 100755 index 0000000000000000000000000000000000000000..75e9279129dfe8b8ef43d75218e57f9e3634bfc0 GIT binary patch literal 8746 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 AMF0Q* literal 0 HcmV?d00001 diff --git a/bin/large/dhry b/bin/large/dhry new file mode 100755 index 0000000000000000000000000000000000000000..f95bd0e7d43af106fb07845ff5180c441d85c3eb GIT binary patch literal 7992 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 literal 0 HcmV?d00001 diff --git a/bin/large/diff b/bin/large/diff new file mode 100755 index 0000000000000000000000000000000000000000..fb4c31ed95a26393f465dc1dd75ebfa9186f207e GIT binary patch literal 24281 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 literal 0 HcmV?d00001 diff --git a/bin/large/dtree b/bin/large/dtree new file mode 100755 index 0000000000000000000000000000000000000000..34fa47e8360b6c6ccacdda82619ec34f89dcf5b3 GIT binary patch literal 14662 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 literal 0 HcmV?d00001 diff --git a/bin/large/echo b/bin/large/echo new file mode 100755 index 0000000000000000000000000000000000000000..f8b41300736a6e61cd22c8fbce010e0f31faae81 GIT binary patch literal 5383 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 MUMS9(M<)sY1uOp@jsO4v literal 0 HcmV?d00001 diff --git a/bin/large/ed b/bin/large/ed new file mode 100755 index 0000000000000000000000000000000000000000..e35fe2c6145626883797116369684f47884088f3 GIT binary patch literal 22341 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 sH~w;G{`2m?>3@GSjMQke@$TRBzcz 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 literal 0 HcmV?d00001 diff --git a/bin/large/false b/bin/large/false new file mode 100755 index 0000000000000000000000000000000000000000..980ab4b102761f4ccfb69f9a1f6a0eb96abcc5ae GIT binary patch literal 142 zcmX@PjFF*_fq_AUfuWJ1v8u79v1Q`Lx4~772j4o^G(J?SYdovj`1-JJWMH^!`SPVABg4tFGL2eIjkQ}e_!)tMaZGo^n1TGW8jTS4*`UV5qK!aB oR~5M#o}Nu={P+>bS7c(aJbE=wIZWBt<+}l!QbVKS|NlVK0dR3a{r~^~ literal 0 HcmV?d00001 diff --git a/bin/large/fgrep b/bin/large/fgrep new file mode 100755 index 0000000000000000000000000000000000000000..424fa5a7fe11bc75c246197ca678bfd837d6f0b6 GIT binary patch literal 9243 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 b@Jr*b&!TANBEBy~9FB{b!lWY4+xC8SXH+xAP} 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 literal 0 HcmV?d00001 diff --git a/bin/large/fld b/bin/large/fld new file mode 100755 index 0000000000000000000000000000000000000000..973d79abd03b0ceea10bb1cf6ce1fabd353f7fde GIT binary patch literal 11501 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 literal 0 HcmV?d00001 diff --git a/bin/large/fortune b/bin/large/fortune new file mode 100755 index 0000000000000000000000000000000000000000..6f08431eab5e59d195bb89847c3e3f437e0fb0f8 GIT binary patch literal 8750 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 OhsF&wk}&)K+x&momYe?o literal 0 HcmV?d00001 diff --git a/bin/large/grep b/bin/large/grep new file mode 100755 index 0000000000000000000000000000000000000000..3b4aa59c6d3924c56228dee3228dea8ef147b9f4 GIT binary patch literal 14659 zcmc&*e|Xc?x&J0@p$VllqU`IO`b{Ge8VlKkSWvSGShoRXW7=(3sf0EubtOsD)U>F% z6h-&wCXZgkUyOMRA~K{vN+^}NVTT*^W)q(W_H4UnyIh}i&z`Q^s#2golKXkjIo~wF zZugJ7=edRQJ>U17^PczDdEfWE=gX-*24(3YMY&p0+LiYCJS$3YfnPiHqiU)eHTt9TbF#j{yT#!1{((-Xxp;+o99mqo%-;?$tqi=?UBJln$c!6 z_3mnCm)ZF?7N44{qFP`zD@v^tQLliLHn1)29KbUD&u? z8?pff;c(^;*ydhaW2+uGGxT9LDu8SQi!KlR$z+P!e1Q|_J(;}l=wCL~xBg|*JwtB{ zE;)bV)Ga@~>8C|M%|CS^nfQJC!1*E3cx3*A8|Qx$Z=lI->6_Vi)t$fSyQc5z!6nX* zOzK~OIdM&U$kBZ2PbbgPGGJ>Uv0!sA+dS~$1)UWzRc&Hn6RRm?ErkjHX5x0}%&oVc z`bUG#pGf?2vmAG!^M!z0*-`ISUS8!^Ub+X=fgl6q4jo04B`o?ClzH$7f@SC2+ z7GAQ?>$CKgaAH?iFs-DOZJ%0kRx4~{+ox0{)O>obYGpg8-s3#sctid1P;zag0YkMl)$s#EhNi%Syeu(ED!+TNm@7Nj3lft5LUuOTr*e7z+7oXP}mu_*N9d$Wznu-RVh}P zp2nI|ESQFF5^uFT-Fp8_yH#&awa?O94a!WV_o?4JG5o|eTjp;W#GkUK@}GM5$;K`BZFzi)d&?_Z&TZ*^s`sfwTh2Yv z`ynu8uM=hO4BMxG!`?qX#XD&khgfEC`Jx_3^6zy=k7o6BviPu;g{NwGief$AZHo36 zP7XFs4$hw(JY{llaW*(QoZ3_|)%`)!* zq(8li#6QY{V?tWdREf68YE%|Q-^+{GqQ6ukRuf*%8S(OaB_akn96r1bXoNYtGvK!K4R4$U&oq1Vxf-{|MCQDxyZtoSj{J_`aWHR#6mv7`S;Ki3N-4SIYg*GfwtATWs7>?e=alMNYeUBjx(@eN5fk+Jt3xvO*xjv z1lBUf!sGBstR=<5>B@ov?MC4RZIuPu)v{>=-ZADIkDh-=n||T zs{$W{RX`+tRZQ!QYcmb|y9e*Ty(e+o4&G@{)N;Mkt_>~+0UX6l);z{S_Zszz&SD__zjNNC-YP$)as)SnJ-jzkYDFv&i}-g;kBQ%5jrAMbMr! zXq!Zfk6Gd@u=d48Ah7;St})cx`!ty@tz)0&o+4WB8YiQZysr={%!~BV_o%k!pHEss zCry3c`hjQ@ktLF}-pNQK5&j>faaLdQpU(}`QTHDEt~Dvy;ek1^=S9|HWZ^uknMX8- z!2@+sAQI}T_^b&2Rv-69MbJ-H4@b=`g*A_`(C8zFXd(RZhsaGV=-=l+mi*G%3+$@mjx^0F!*TNnPN>A&1dlfyG8Ck=Fexof)h=)pkPDy zYkIOlu1zL;a6u3{`7mARDK2yYi>4mXZlGwga#@ZWN__bl$?RvuKq!-t3a=t|E0I9S z<4mz};VE^Z)ESib`5tFADOR1P1}9)LBVn$Q0_GZ3qNy6KBqM#-$P@x1DHPs-+&Ez& zwRgr(S3N75(bO8Wb@DH<>dT3re@|FlG*zxi;n#*qXO5D=T1o_W+-8YQ9s_)j_wM_ChA{gTGi`jPuq%-O3qNg8+U1_S zVuDLdh;q}vqOVf)RgMVJ>x@oj2A@*gx4#DOFp#KgH!F(bQEHVsrBU%KA*ERfD=o_R zx0Y}H&ek+G#}ZoO~o!mVvvE$}10$JMZ98hy_T!^ zbA@FFe=ZYtVA1%SOTL--n_UQ5x60Lmr5sDG%Yq5sMlv2okASR+9CS1_S2KwX)2lsa znMo^%SDs&!!Mg2l9@G{IM+2>sLrU156H35z(iiPFot`GK_JR@eBcs^y^VoqDi>Jv- z1jL zCQ&Zb$#FX*B;Q@AmgpmqOPW-pd#Vt2#A4wz&lcfa*daKk*q$fNc+>VFz#TY@NqO>! zB0LLE^mrVJrf#x-P5?=G7FJ_q)p?11TSeSKqQ{2`t>FwNPeBygDd!nny04qIe6hvI zRV9y?(qWKVXe1WFh`j6(f&twh&^Z<~L3Py9RrfuvI(;)3W^5|!?3R0spE+MUN@q?% z@Y?5ia<=wW>=RmYAo1P3!qp*LE0SUAFiilGxrRG?Ojw2D$H|G*Edi0OTy`Gb7-MXu zo!w&T;dI$vyzcGRJu!=1Vv);u8)lJl%nw;uN zn{Rz7ve3UiwQ?Exzvv;H9u7v>f-%BBuKrk{uum=9(T)6bhQ#==cn#>Dx$HI2(ZT6J zYiUP!*-IF%tt#6|v&vYMZxQ6j6bhgjRkV`U_m1-9HB(3^dxa*HF#j;~T})d0WH)Dj z$&0;_=dDEu)S^JquiRsc_8Sk{ugl;q6d8${XILJyywBA`gxKdxgu)HWkOVq#d?1Qs zhWcM}wV@$hQ&OB3r3CsfUDN|q)8)(Uc+t4sq`BR=hEYwpD2WrxLD(OB{{_)TS%v3H zByeF!2u1I1yrQ==V#~;0Xeq}}Ut+<_Z3j=czQAgDR1*$+itGuVPV1W`@}P zT<~2x)g^)pP&3TJ7c&W;vn-c8946$9TsY^;HMSfXOpFis-E%5Vt>j;D0OqN*rJHIq z?b}q8PJ|=XjlB1^ZP-A%v^5$h&9KOTqRxlM64lT5Zrsi?8lX^(6B3F4>)Qpbf*i8` z)?CUa^a0&|UAQ)!HOSRk9owmB2_-M?4}=#W`Yq+0AkK^QQ`OJQ#@N0L z564IYSfUi0KUua1zq|3*f>YACu-B`vyQjR5RQL^BL!Xqk>HXzi5 zlaqc5l_9>*b+ZYozs&Zy6Bx;QpDW?EEo7DfKq(x6JIpzruytzaTZ+v>!((!MTa5#v5P4yUCTdxzg5IimBS>dr06= z-vipSWe)NdMzs{WEp_xz!t*T7{q`d3)Sl?D0X}zFiC8YYnAm#o%qcK_);dK=CceF2 z_e3L9qs?;cc;gk@Xd#Q6>`v|!i64~PW;_U|sC<)`f?_~?ID%flKSsMh9YLB0tMr?h zZyI(vGDK>@TFfjw%^{9X4o@g@@5`Tgx$xzAFW>z#M>Jd_NL23>ubOy8mX4D3Xr6lW zWMHd0Lx7!fvZ6i-+v#_%V$pFp@3w=Yf>ipdy97CyQN78n;W+~`T9gqAaPU{Ev_VEH ztdDrst~IC%iSf+N%!cIUywX=;DJ-66zrh+ez|o7`jhjm{VcJVI>y~^LE?|8HQTyDo zg{brJw2DV4J8Js;XmW0cm|428hjt?&rB&ZO_lmGmvHc9t^x*RI$M|`R>d>Xn; zRcOOrsmW*61wz>~C;Bq%LC?YxO$hl0!H~!qAf35cz1CvIG;qGz7P1y9rX;-?&=5n_ zxd7^DFo&C;+weram_X_u&X*eF^>UjniC~{S12#;^>9=7mtwLc|SQLwoVJ?a_5i)VX z5Fe)R7qJ;pl1_aY-0*-(-T<+cHmPbtX*eY`eP?^79DZ8V;Q0`tK_OWfrCG0?tAEy= zH>GjFDONqt)>l=HdpkmgjX>oQ zM^N{Kuu7xaAy#rJSyIU)AH1#yheVh&^hwINW%2Nq>y;rZxOSo#3(_D*6})>}w^m59 zvK!U+Syh^3nYvlYu>Ie355W)QJf;5G4sxVdv1ot40>Ajj{=e0`wf#p>B1D}r4|PH! zW?4IKOr}d$BC{H}LWF@Tocj;N+k(n$aW3u@ZLFsV?Bsa1WlO)Mjmqdzl3sx*osa2VI7>;Lp$Nr`zffT`|}{Yw=!_P zop`#2ePIsdnd{#eTwO6K25#;kE)O?q(;C*|$|}gMgwKu+ZxY*%%!#~`hMR{}zd<~V z&|VfzJPIzR{ye+Nw-y6Ch-nt&gI*WzCA$|rw?bgn zGRneZ)~gXG*!FSqPCHW(7AY%89kVOuWMe#Anh4NNWe7}b^jljx$%6fD&=+)8;Oc?wz`f`l>~1f) zECUj~Pf#l*Fv>0{5hHFo`MhtftF2q#&=?3dx3pgO`WJRB-gRL2 z^j&$op6%Gx@iKnDv-@&~eb?h11sx?FH+5X!v2u4w$Ay0vn4n6s;och|q1`yuy{`1$ zD7#?RF?w-z8Sp@z95;fLn&3vz;jec%gwN?<;a!t*h2zo$1AUL$KdUdmsybNZt~Vf+ z!6mGP*yF40!|FfctGo7~`35zm0%&=&lC)m0EK0KI9u|MYe!cY}qK87gpvN$lrtFk_ zuKHQgnN2LZHctKFs=E@g*C{O`4flSq8)`>oyi-wcLko3vw94h0qy!iXDzk6FaQ33} zO*{{vw2nb|JMcHO(vq4RgmfmQWs4zTLZv&5t!A9)X} zdYe@OdW==~B>r?zr<%Er)-hK%svq&L(_h_97Jq=nJ2jZ^Q7?6on98EZSiFbD z-)8aS@J+6x>-mT|Zd~_dWq(hqV zLwO>_b}i0qS0qG6wL;I#_|6k<)P)A#cfClrr(aW|5(?rhFDG$l$QW z5y`5=8jsSJKB+Syrp?$4-m>$}6HQj4xyH<@rwJdBhKClJ7?MG)OLYn(5R4>#j^6C~ z&C*2Pm$Psn5YuV$NslmW|%FC`?==#Bga$UHKdAc6y z9h_0tMR%atH4xk($hzwCs`tiL1(yW)9Tr$4KdheqrxW7$+^tbQc?)# zjRbVJMafSrIwX7q6}otZ0*7GEj7zb(43py-NSxcjRXd?Gc_!mCg{%cyNDOBloax}8 z4cX-_@_X_OoKxXi)?RiS)v;$#sO8p<_e82)Zs^|})NKyNOcf_lPSJ``)}m?%&WP3f z<=Ba%RJACFao3Ej0_8BQfRG8xb&aNxr^xfBD3I}bRK9&aPBs!wbI$ERKtQ2tRAjSs z>`79wgG79u%Q>s`UwC@SeqN``y3(GAC%oK@DkVNJ!Phx-uonkOD8)VtjEFZ`r6UYf z+{_uK-A29$*LpMgaLyQ6A1XWuwuFI>w;+(3yjMSpagl-oOOII$t z=$s;iijQTX#!KWuL}8Dg7VD@&OH$UZ7PUyU%%UEtA7X0{a4}HTLKeQ}eo8yF2PViA zl}Q?|{t9lo7kyb`-E{h$w{oR_9QPWJ&UpueOJe}^Vgl@2%S_`#~6&Q*rOMlO(@m5^KnGqCU2y! z%c2{FK~x8g5k!0#9E!=_tWKQ$;SET;+#ONFhMd^<5UfG4m7#1N$|lm8hyWsE>4X6j zM~9Gi4)wL#MLCEoKidCAvf7bI!&<$z#^F3op|z3?Yw5EL@=cTktr!js{%zVaSS;OSX9 zU0O~h-O}57@O^buTPkA6+_{F@<5>lx4Ags^YAiw{Vij_gJnl%8>QTV}7QvT7#Rl^x zwB)t&G>Aa#Z}krAd!4jslozKR7$epcLW5Zd2-XvMf`HfrwPFPWwnRC1&$u8!mFLX0 z19arzg4KmMNuF}ndMzaS`@@vR4)wmbnO`qVlR_3E;vYl*uUT_3zOl~9fO3jV+4<60 ztD1v9s*3vzW@1s2hUFU{wME6#k~bWsWQjQ=$!8G#pEo9C5G~~ zxWD7B%6W6k~SbL;Act_9^4tqm>_hXu`q0!r{ zn96H4e5(~|@Q1a4zp+j8XtjYBdhux+JmK2)-a4(Z!Outf`ABcA7cj4Uq##fqubRIUX=bq#(`s7y0JH>y5`YmNLf9Bw z?^)*!H`HQ89RPI=^^huh2|MqVOQ1hQAdnquX>M-t__ana=@es|(a{|A)M6Ra;xJyq zo^=4%%JH=Ue>fCqyhZc2)_Q|sZAGPavv%)YOEAPsGsB(`*L!ozI&W(*zQW{Pj>vG|JIKIa%+iz^-cZ(P${Y?Umrrb3Woe_Q86xn8Hoz3g?ACee8rzhr zfFH^TdSR5al;EY#fQ4|`gbd$Gm_(v;ki&7fHe1)wz&gaj%@B#hY$>rBdO zF9hZdh0sYmA0mNV#Riv_04W0!4un08Wk=(r6e{hrpB&|-4L_JY_XeT zj+isHFjf(}J?4(x6}vmOJhmdXDz-X?uQNaOlZOxA@N-|x6WbKq7dspKb8K4I^4R>Y zny#n24t4#Z%W&kzBg>DhJF?|S$B_??e0;Ma-JF<)7mQMazO)d&D1Gk5MVjf)gwM0|Q)W AvH$=8 literal 0 HcmV?d00001 diff --git a/bin/large/gres b/bin/large/gres new file mode 100755 index 0000000000000000000000000000000000000000..2cdd99b9f16f8c14dc481266c8e323615f976775 GIT binary patch literal 12405 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 literal 0 HcmV?d00001 diff --git a/bin/large/head b/bin/large/head new file mode 100755 index 0000000000000000000000000000000000000000..76aeebc14f41f38ec271dbd2023c61848a6e99cf GIT binary patch literal 8875 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 ZIexRc?9*JbV41oc(_B2yDEz-({{vC|D-i$y literal 0 HcmV?d00001 diff --git a/bin/large/id b/bin/large/id new file mode 100755 index 0000000000000000000000000000000000000000..c326d9eed5286f047830056608b37b6338bd0894 GIT binary patch literal 7938 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 literal 0 HcmV?d00001 diff --git a/bin/large/inodes b/bin/large/inodes new file mode 100755 index 0000000000000000000000000000000000000000..f5e7ffed603d006c9526d6d9f19525191a30adb1 GIT binary patch literal 9863 zcma(%3tUuXzGsF<%z!-9^q7x(h7lb>aWWdwRWftOwh~+GqP++o3}VQ0Xz;--NIvt0 znwF+0h=cgR=a|}KiA#mtsoa*j)%|amwV~^>RBWp$kD2@bf8RMU7`9h`<2mO$-}isN zj}1pu!um0SFjx?Zh2lI%Lv_QYt8Gu^IcnP;$#*nI+8nO8*RYuC(gu5E9) zUf)DWk%d;5c1_*cHLcffC}bl8NgA+fAUO!~gIu%L5NGXIA9$eQ*ETiRx(=_A_uZ&@ zEh|BIGc7@QV{U@*`fQ{b$yA|COt*BRde~%W>>2`%-T3q1&pQMjyk&@OjA#sJEX<1s zDZBu7-xJ>?1+9SHf$=WUpRRKY;J`hzjkPfj@tt;eN_uSr6FO3Mqi|x@>WOJ9CeAIG zi0E3gV{&4Md)NG8k2gYH1et2E_$3q_PivcJ9NG5V{SMb}HW!{V4Ado8xOMX#Zdb_O z_I9005G|@cyJs3Bdv;4hBMR}{9y}LBcMD3y?~yO@0m$?ROMqSv`Tk%HFzYQ#A>RX5 zFK!$Ri5@U}Y5U?W@}W=hP~F&KS8TDWu*y}mrE#_4UQVD}_p%Q;?a{?mg)PF1t6P4Y z@0wa1APAB$Lr4*dgzfK@Tq-$Va-!s5No9%an-Xzy#A3k}|B5&z$|Yh)9tZ_;UfmYQ@y0=;U|`3o9* zi+8Tx-V!#uUiW&1+ts|G6_2AS|9=68D1Z^riwH=V-=qr>G)a2PvWzi8Aug_FYg!p) zzo-@7zK|&x+)F_hvet#Hbyw*E5mgtMyEP~d)HHh4pFUd~t*_*|0=oyCUPA_Cdcfk< zqiV=zw{J5(~KvismQb}9lj&83oPBr+Yt;2DO}@bq8xUZWYXT=UMH>NkbA8| z+#C_8a{X2)LS_e8I=P9?MH8K!o-$4qRjGl*4ls8<94gq4qB&R1Uj-+-vR1;$?lj2n z0Bfgs2F+XM7Oj0Yn!NfHh9UC1fXZI&x64R3?d6yhe`2TAVD>}LD>7h=Rzs4XYuA3? z^>Fe?zu5`lM^707bzX1Xs~fn7=qcdyTXHb8=dW^lUXipRk%5-YCOrjhNAWG+mlOaf zQ90V?xm7BGZ^1*Z@AmnKH2_hIa}>;WSm&|n?XcBr^P%rh{W)N63=pX)I4v+XVMjOyT~j@gi7G)DMa_U!+ul6WfT#- z(d9XKwE^=+6Y9$CTD>3R3Jc&JUfERf(gn6|ym-Lo1$z)UH3lOSIPrrr4&zal{LFq9 z0iTg&{}ajHYkTHN7nz(EEWtHS0|p(s!^EZqYj8}m>)v92A!cE&ZP}&?n?`M#wduJ{ z4A9MRPNF!SKT7-&OdXi=JN?8l{VnUnFurV*4-4Wtuy?f>=YqW(U1P;5DUkdyeluAz zN@sL}gx4@!o6;i`gux!w3JlJ(G)yH5Bu3cM6JBLtU{{0F&oD~oRG|%#7xytGR5m4X zXbi9$#zn6{Rg>Gw>P3H}80sq7%uhzHaBvDa*7yJZDi6+BH(>##LQS_l9_3)cn=CRi z%F(L|Q;^<-G1(uI0=TjV^}g$2kNG6ioLeQRI74%0H6uin&N!d9m~}O+6zj=1DTQlP zc*D1f<8YB1G`Q z_&Zt{(q|i026R|04p!EAI;XfIuDyF=R(5mn%pM43WLY(t591ge@6kj0o|whL`n9rN z=I<8qhAL5xohaDLr67({mYKcgZ2r~QC+p_jV#w=)+-{$m1nXB;NTBt}^@FRTterFJ z6M8x^>@Wr(zZN&*oF^#hL^GbDEm5nS62fxW|{l?ElK;N(DX4nm5R)L!?_R>g)m<>7IknO=2xI|uw0i9D;{$O^{A)=dpS5Oqyb<*j?$5Si(V5%ED$|(&?jP zCd4jSw0OzV^o*?Ry!?W(yApPocU;;zY)9CRy`?p!mH4ym4A>F3V_RuN>4;Ke>A2Eo zc8(}jm2ya^N=giMF}uKYSOum^p)O`Se}!g!mL5#!RCv)@kckf{A$=^^VlvZWVt9}! z2Wv&YTt)jbfJMxG3Ia$h2Xh6bn6{aaPwX)))rkEV!)`i)w+_0M6+q~za2|_1u-Don-MR!C51r`Cbs| zh4{OKAbCv$`$ceG0_SCLzKyZTbYVE#F*YIG=hR5HHYg#C){fLnlV~G4%3GC?c>yeM zVZ~%XX<+8O0Oq&ILtc0qyDdmO4`!$Qs6EsxQyv@9`XQ$rvMW}cqNvDSM;y_=C?KDi zk+~c)&x6H@1sYwjk{~V(7&7S*?eUBld3O-pYstmY)mfav5~vC+NAYqTEGO`C27hPq zcNi?#gfa%?fHZt-D+U;B@zGte)tB8>RO8=xIixYZl6hE*J4K=3GE-17xtH&N{99nX zO(BfejJol3N2P%-9_948*2eMbMhlq1;v-aQ97|Do&BjtQjed0pcPoX0+!_|0GTe`f z4Kc((<}I+?#zLHM#F!??>7DgJu1RYkUkz42$nl5lfF2lnCuXulj$<{sbiGnu@MG>` z>v$ znp97c!8(wgz$yyzF}2{tWd>it@JckG>3Rx0TB8;#?hlOE#)z1cJ+Lm6I+{K*z*-?2 z9`uTr_%hbgOiz6^uIbS@714^usW>N%hpJG=T)E6-nF&zKgb9XaRwe|bfIVOoa`oyx z7I_Q-%K#K1=@2gr5SAajF;lDqi&iFWxn&&d=rczcMMl?!hK_}nxl1k}`PP_h@hV?H z*6dwyqYtz2$?u;dQK#kPtYZ~3;i-G^MWvNt(XXlGx(tRXEr%gi!)# zK7`M%KNrj9`G-SfbL2?Ob+G3f+Q)fV8#r89QtT6}4mOmtQyVXZ;5dc4aGY{|yHAF@ zYd_*-gRgJ*VKvk{)WR_g&F*n5fn{u`xAz?%%&-}hzhNS4tCc|*iU(5?4o*5T7hye3 z{WHxWHKdMarV|?I@r>0Hbmh~1Y(7L`A1S3NOm9Y`-Q>#X?qd~Crco;@&@coUk>}Gi zo0Ho(i~!u>euu-ejy)BQW9Z3H?kJrJu0M=q2;P;<(b{Jy_mkC(1478s+%+G zXJa6@bo|PQe%PZdt|@6r1m+epeQ7WsOyZrE4<{9OSXahula&h0eGKD%;WF#WdM%3^ zB5fBxA+6y%A6qZF(tMzgt7x*v(XY09Bkwj=?n>e?&=>8l2lD_@k}u!mb*eord8)bSs*{ zLJ*?>romL7mn}047|u!4%n0d5kKakztemseLs={itK@9J>k7HV>WwO7AJQSL6B`Q* zf-jPXD3o;A(o>W{8}rnj(VROyg+BODa^aOM&7JNHm7|roC|9A#3=b77S@V#JH5HXQ zdelFb7yf;ug&3XVKoVF5?Dac=I5?Z^9|vRrU?7 zm({zJf=#+%s3UU)bqeiuZ?54VTKg!86pKxx7RO-JC3(fabFw(c7Rf@BIuSD`glA-?mNU z?VP-hX%-Q4Cs2=JlT!I>^}p=qLWTOimANtyy`z7lk11jw>2^^Tq^~G_9ZJ?!tkQYW zvs@a-@Lsp4unvc~F4AYW_z^c*R2u~@_J1xYkOy(&oHOfcLw?@EwA86mdS=#=)I7NY2moHqFl{CKu-}#!V0A|AI$Zh`Ff?moWImcgEcz_7a&(@*j%?W~XK{stJUYnwy)I zD1sCZoIV~1Wky}9e(u6b$FM!|>%aNg^WFY0-v01E z9(6BRx71NEBWR(hHt6I3v!U(Ft=DUAKe{pf4eimGi#MMA^J5oQ?p~I2-;>%0rVfnm z{`$Wg-|IZkx?*;(<`+39s7KKsM9i-&7H~Qe6KY@jLs^BR`z> z#b;ywVJZzgHDtc!<(Ka@$0a@Sig4V`^-7SX&0naaF(b>WTl| z->_xO>U%PlJpbD#%BPi#|DO@HA^-M6g7<|_R)4dv=F)p#Zo5@BG}C1N_e5**&e$^v tS3`dsB?$Yfns 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 literal 0 HcmV?d00001 diff --git a/bin/large/login b/bin/large/login new file mode 100755 index 0000000000000000000000000000000000000000..c34c50d2d1b9f6916048f6c41d97ca3f04ae8eb2 GIT binary patch literal 11975 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 V<4+ElEB?~P_~U*i=KuBYzX61J literal 0 HcmV?d00001 diff --git a/bin/large/lpd b/bin/large/lpd new file mode 100755 index 0000000000000000000000000000000000000000..ff949657cd132ec117eaeb1b5373ef09f3007c0b GIT binary patch literal 19952 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 OXZWFhI`RM4pZ@_xo$j>& literal 0 HcmV?d00001 diff --git a/bin/large/lpr b/bin/large/lpr new file mode 100755 index 0000000000000000000000000000000000000000..7309adcc701b560378201544d271b0611032b5b6 GIT binary patch literal 6651 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 Z6_0g}M)fI3S6 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 literal 0 HcmV?d00001 diff --git a/bin/large/mkdir b/bin/large/mkdir new file mode 100755 index 0000000000000000000000000000000000000000..f78e869fb25423f6252d25aea3dcf9e5671dbb9c GIT binary patch literal 1437 zcma)6UuauZ7(X|EYLj)&h_Y;;-rK8~8I}Yswb`IZSF(rEOxRW((n!|k#xZkm+TNHI z+SnVDD?>!2Y;V4az6kR{DvAhQteC+SC+6`J@{mG_8T7%V*^+zxPEOj6J(-7_^ZogK ze}3P0PWda2eBmVI8A3Fo-Oz99H*ei*T)3fcG|qgYSBF2vo3($J@2@7W-(Nku^L1mQx>4RX zPHUzKQ5!_;f{lb{E*e*g7$98Zf<$oi6!F5;WOZIlQ*};U_svkp8vR7YNEPGw&Oy!r z>rUU9$1S1b3?wNzGsqvN0%8uO{qx?xs1OmQ_ry`cabz#K);PDOL(B%#cH{5D%6GoQ zEH>{HIO4S0Se|HUmRFgAPcRu*PL2_njY>wf^U;laRGB!U< zOJ{*XW3L|AUKZB$0lV?6##GS(BK%>wD3>k@8ENv^TgzKw=G*JOA~8xghfZ)Q2EH0O=t_n-FQa=+Ycx8Z3^Q#lB^f zcqu>_dY2MqBd+zm zp42e{y}6qe`o>I6wn78LpXq{S;bVliv9n))2h=Xin~+8ge}4Z1^%6r=^6Z_dcHF}s^oYo!3P2XH|cqt;%DQstf>6#LL#mvs7GQ}RTh?b H;wJwAtJbs} literal 0 HcmV?d00001 diff --git a/bin/large/mkfs b/bin/large/mkfs new file mode 100755 index 0000000000000000000000000000000000000000..a8386a805581987a9b92733c0869c974301d8524 GIT binary patch literal 15063 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 literal 0 HcmV?d00001 diff --git a/bin/large/mknod b/bin/large/mknod new file mode 100755 index 0000000000000000000000000000000000000000..9d292acd0322a8dbe16558e1bede031678dab060 GIT binary patch literal 2173 zcmc&!TWBLy7(Sg`I@2z@&Fb!^_^>lOvP45K?AF?@60k0*$~IjTv$~h;_L9VIo1~Y- zQAvhQn@S_T3N8q~h$4vfVTrydbW6n`Bio1i_KQVRC^3aR^p++wo|BVFyBDARVVHCN z+d2RDfB(sRS%(rVLQf*3AY~*qm72P=(C^;-RXCsPkReA z^8ESCa&{}eIURg&bGo50%MD%*q8#{Gh_S27TM#x6 z=EuNm$zN}N8@%=S2R`d%{L6yR3|=jN9l{m})aS>V!EMc7;;0@wR`k~V*h2HEt%|QT zfBiKpTHsE-xp--fOD-yXy}8253a;)vmP~HkIpHLgZ^^ULO;P?xx+2Ocsb7@mrCz7g zS;(kuiYg|v;9kA+iLE6W^5=dnmLh7%{L|Y`@7EG+CZ^qZ_ zuE5kbOzzaN^SCAmSVWOv9Ze?g-a9)h96{ak?~EkMe;`RXiZ?%-@#Z%qQD?Upcn4w{ zM0Htf?;3@$1_9mm{7+rC@PXSP?NALdb{!a7aJRaxCiR3ubsj4c?(1CNMWUA#e89W} z9U5c~j0*@Ko7ETre z5m_7L8=!L+LFe8r`w4BxVb)?b4R1Fsm1hO35kczzGYPRGME3<2amKy`(XySbrkRFt z5d!=ER+NBrsXq?sa_=(8+mPPv2YCn5d%cJ8yqYW|?mAA}o+1?-Hk_NWbylmgH`=YX zuF3`>(!Vy04+{Yr5H3NWEJBQw?sUUA_90bc4RLaMU_yKU2cBJkwB}&!_rarM6vNtCR6B50 zXh2z^-Z+fjg6Qfn6kvev>MhmI1VUAYG16Nb^r zvxc(T6-qGhY2ek>;D-f>?Lu@9CW+8} zVOYoF8RrnbG|xtIH({`3Bq)VM-5q@7gLJY$?; z{~lyBq%95`O_il1yf`6_gQo;;Of@nWq`7U1(NDAED9Fqv9|764iGp@3jin=CI5Gd} z)Dl8H1H*h|C^|64ha$uN1{4|%M}{x(Lj&P(B+7>dM*aM-|J{)xKaUzvY-%9rzra^~ z_-iepO3V#DJP`8p*9PN5@feP{9hu}qBjL#8jRsU_h>eJ`Irum656UYwsp@+w!aPQ( R!^Mi2A0xz$hyDMRe*w@%lobE~ literal 0 HcmV?d00001 diff --git a/bin/large/more b/bin/large/more new file mode 100755 index 0000000000000000000000000000000000000000..d0714cb70b86e27d56b6c646422616f05053548d GIT binary patch literal 10306 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 literal 0 HcmV?d00001 diff --git a/bin/large/mount b/bin/large/mount new file mode 100755 index 0000000000000000000000000000000000000000..09ff19042c510a7e6e3cc543692e543165fb8786 GIT binary patch literal 8961 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 T|E@I1|Dgu6l6RG?n9%+|ca0Ao literal 0 HcmV?d00001 diff --git a/bin/large/passwd b/bin/large/passwd new file mode 100755 index 0000000000000000000000000000000000000000..fcdcae5c8bad9bac24c9f3ec15cb63a002680727 GIT binary patch literal 12788 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 literal 0 HcmV?d00001 diff --git a/bin/large/pathchk b/bin/large/pathchk new file mode 100755 index 0000000000000000000000000000000000000000..3465b3f50e726bf5b1c0490c724645bbe7036f54 GIT binary patch literal 1707 zcmaJ>Z%i9y7=N#S7<7q-MaLzZ@w!gajKGl9o1j_dhGnR9QxwHTOvieFE7wx4D;U?% zrR(`=Sxn3{i!ty4KNwS^OZ6)wHG$-S0_Fb?Lb4hWS<)C|V9@%WR|tsn%ia4t&+mDk z-}CPs>|@9`d4xPcNQi`P%e|lUex6vZyDj&xp8Y~zI&w!=ZiZF{Y9d&}QlfuwDV{_M zW(w(${e#QO;gIs}jT9U@*!6`vqRfQT zg|{NAj=2@dDbQ#@y-~v%U^nK}15bt&YiKwdMPM3%8HhRv`eOKXkn{)|e%2viDAU7c zL{NvA-g=VxGy>58!AKb?_itRg%N_k6Cw`0pKTgp2C&AE;lne_;( zXP%Px%mr;W#AygKbP?joLSFu7Yj}BUjToZTMCe+YbtGlpM^Z|EIGt9dig;4p$=a&F z%JPnUDVwudilUncF&{!fDxNeS&7sq2ZOJyW+JM8q0cjKM8F;e@<|9^MJ)wEgy~~GG zpv{N{{tTpSu^r+DgiR`{ZpB`Mk<+m{HonV+Zj1H6ZXi$Cc`cw8K9dV?hc|OBk7%2v zHZosBu?11YGF%>gdZ+_zI<=^Jc8ER?Tdo=-jb1cnHNloqL0R^9?d{Pl^iD0}`gX$W zkRGCa1K!Qu94QxyS%>hDrl*369kec8KXLgg7psmPg(ItS%{;5FHoewt+}Q_O?_*!d zH223D`d~KdP_L)5;s|MHr8}ZBIZQiiKD5;hO_Mb5&nc)}NlLuL>y%nVXPb+YJRZ*N z5t})|k(a|WFn$R;yPSTUsH?olG|k>t!}rg+3Dt} z>~l6rE}w~zZ8-PHP>+C^h`+SM1g2YF>Tq^;*aI3vawx_tx9>@4Vaap7T=EWtY(0()!^Qcbn+(w);9H N|J6We*GC@&$=|q+PyGM@ literal 0 HcmV?d00001 diff --git a/bin/large/pr b/bin/large/pr new file mode 100755 index 0000000000000000000000000000000000000000..0f49bc909451e4626257258c16d3aea2067e3672 GIT binary patch literal 14712 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 literal 0 HcmV?d00001 diff --git a/bin/large/printenv b/bin/large/printenv new file mode 100755 index 0000000000000000000000000000000000000000..86a9f224cf20d9c1a017f85faaf4027eb0202ac5 GIT binary patch literal 4834 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 literal 0 HcmV?d00001 diff --git a/bin/large/ps b/bin/large/ps new file mode 100755 index 0000000000000000000000000000000000000000..46ae498f83f07e56135b308d312167f92f84bac5 GIT binary patch literal 13219 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 literal 0 HcmV?d00001 diff --git a/bin/large/pwd b/bin/large/pwd new file mode 100755 index 0000000000000000000000000000000000000000..fb5f98a6dccbb1034cf727b1172ae2e6cdd25258 GIT binary patch literal 2711 zcmaJ@U1$_n6uz?)!)}tQX_Gp&3Nt$`j2qCDhOGfBMdSLACT+27DYhY0TpKHC)D6+b zEE)5&>JUUkEEM`w>`O(dX`+u|$wQ1&$iqHVdY}uP(6DZFAI$G&r{~@~vp*sR!rpuC zx!?Kw&bc#lOCUF^2&p4PC;E`_ze0Jiy%*UBinXk@| zT>K(6m7Os)o!Ej+5UTm>&&{pF&f>mqDIU_?)>11F^JhJ)2*eW38_q6KubVq`==MUy zXH6%ScZg*k8_wb%J<;^M4c#7yh|rsdD6aDmvF}W1RnU}|MQF06C(!PJkjPKaKMoi$ zjDc}&i-2Kucpxm|-rT42wdoz<*h@A9^F+8|WR8v*=6rnif>w!6C!#}v8wQ6(Kn>00 znZ|t`deGknmy0@2l2evkG6w68&ET@(XX4f8|2u}1L||7C+i3H=6itU!46 z4LG|3XI9NeqtLWQeP4Hf8Ti5|^yVPCF)%JWPC!Qv!W*VE0=-KRT^<;J_|4EAn8?fZ z(7gna<&YZr7TPNyv>;$lI7rFKGR<;&S+u$wR^QjB7;STn6?<8&T+ z>`d!5>ZZIia2>7YA!O6t7EB&X&ZALk=#Wzdp@O_Luy=(4uHHXv_6=eEYdMtTT-`-U zq%~oT%N)FFbae{i;QqniPL${8JwZ1(>HK3xnrEiA-ysN#U<*dzzh+>D{MQXMg^-lu z(@EMjZ7s`Ww>~O?w^cwb>8Vy`-)P!`|?vfD8!k>L*7x`Y*MK%*=zcu4KWW)h_7&_#&HHy zw=e?1X9Qx;CS^t0N}R?ndiW@w-M{trxaN`Oq`!)8h1JMOr-3^bA^h~LdWQF_s#;y0 zs@krG#GZ!J)v42J4;o{zf`=BFVszvoY-9dTUCAnS$Z^UJUyvxs0t?R>-P0+=?CPX3 zYI@FAayIW@>{2>6RFx*U5=)Yp84XN2^n>;sgfRapt-#l`6R&XD4*mK;$*NS_P46{9&&G`da!Xl)e_*UO2%AaQ2}2$G0vQ9V|%Y9d3N(aJ0Hom{+6_O-VK~M<)$zG)x^*x5V~KOjxKi#~Pgm zfw1H1z|&?BkDOJ$@-rxFAu3f}4?YoHTNh zm9|(j{@A$c#foCa*tFoZb+p)X#F^IsyG#IdXPwezhIty^O&FLa5e{LHq4c{+uoWp zjVytF8PUONHXGT}7ECHq*#q(72N-S1lElZK9_ewxn<}!0?Ag7W>?Z#M3O`6y literal 0 HcmV?d00001 diff --git a/bin/large/readall b/bin/large/readall new file mode 100755 index 0000000000000000000000000000000000000000..fc8cdded00e6f0ff116b68af6212c849feef11fb GIT binary patch literal 6197 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 FzX0gaSWN%` literal 0 HcmV?d00001 diff --git a/bin/large/renice b/bin/large/renice new file mode 100755 index 0000000000000000000000000000000000000000..8f44245bcd478deed01553b2b35099711bdf4b50 GIT binary patch literal 8217 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 PW1J7o>(W^Ie;NJ{c+1@e literal 0 HcmV?d00001 diff --git a/bin/large/rm b/bin/large/rm new file mode 100755 index 0000000000000000000000000000000000000000..d2a25d72ca9d31324a252d1017ad2af3b90a20a7 GIT binary patch literal 9243 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 literal 0 HcmV?d00001 diff --git a/bin/large/rmdir b/bin/large/rmdir new file mode 100755 index 0000000000000000000000000000000000000000..a236543d4d891b43cd067d1112ee8e3a4ffce8f6 GIT binary patch literal 4075 zcmc&%ZERat8NSzc9ABp&aoeRg5XQZ`uzE910!_VS8lfMVv(eQVWA(n;Y~5Cemd!5L(9g9lKH6}J0}0zqUmvMUq4$n zhj;R5jCVm6E!FoyYNZNNtN7FLSEz!W3+~#KD^+Re^H?KDmA&wKd1G2~oP^iyjhbj9 z-?mZ2vm*> z4Y@sce588ooUzuPJNR`wHzI63F#gE2aCSVlzcrhmn!>p5z&1Ijo{2uIs6){w6g3`g zQ`B?OR*%P%pVVq%+QS1G@LRxVby+yAZXln$Bc{1yO9k+*Sirl=LAwP4R&8|vdX^xv ze0o$mz}K15-=BpZ9U_I(qwcSPYJ;&d_kG~k!B>Eg1%g%tO8w^`q(iWv>UGj4+V#*) zikB0wj6ie+qO0N?pf17KvU@$KD=@a|E|Ymqv|9D$f(;T^y%sTsaCw|6=Lp%n+sR5S&L1+>b+O34+VuzX85^ zfmm8iC1@#en!;w#;57JGz_$wRHy|*tZ99XW+d}onWY8uCz^kL?1x~DReRo)^JVV^z zf`$dj3Jr_NDpZX)lR8B&u;4sAKs(jcu_rH~2aI)M6O99n2}Z;H#Wf-D+c|nUP8Ii* zi61h**Tf*?fS{0>NXuW~GTO0t9$WEpBgFJddg{oS+X)Ri(X}A{!}Kdr7|;J7xBWXh zYhtgwOG0dU8@$$G=7PQf*N=y_zJc5`kkCFEgdPh-tXUMeeoDmj^2>VBVZ4nK_P59! zParCwb$3A`xor>)Z`$9&R!t6KbgV>bC+sM`8A@QA}h`L$6lWRKkxYjzzkKlfz|HnA%{5_5bTST{U+ij=TGmDLt zWpbfVOud>|T6Ur#maxuJ>!I61%3<&q0>qM zR1>@RF9}p@BOz&nVsNbaW9+O4hv+>w@wfGs?Fh-wnj#wA?+}h4i&a3Tj>*&SzO1^xx_EmE>UoLy;-%NDMQG62$qQ;Nvf5;QjjFXy_J&@K*9 zRY*Si2^cfHWK1l@_qR-UDPhd*3U=|%A+eJzp*$!_6=cw$NPL6%x8f2aBLpTMW6lw` z^KF>)EGg?hU!swZijfuxr+ZMJ>M%5{kaS*6hR-Ei&hft;CR(-*5=@XD^5L}vCK3zV zH_qqLA`AyPm6pQ&E%Wtu#4LgeUl~|hR#;Ra~1 z5WB77hluvHY%e*Aj4MjUMzv&INPq%eD-d2?t1(`R*OMZF-X)7Xezg4LuO$b$6qEBZ z_zOfS{cetNWlfAYnMX+d>OAAzkC~$=-biTaVe*$qkGMu|L_B=#jDp_@z6zu@0%#X+ z>7&Wm+;_19`Occ$b)M;mlxFZ+-zE2#QI&O=Hbx<2wbA3<&T`x^P-}}(W`!;rgv*L& zC}YS{etO5L^0(V|Pngs|x4jiZ8Ys1XyvxwJ-3ft;m&pe0`$!u`j1?768x`v*q^Kd< zVVo`9e}Vz-7~6G1>89Js<_Y2%#H6tUy$L3}goV$^Fm0W~nFkOckxp_{dK!F>Ht1ecavtl;w1VL_d#EGfNzrP)Is zN1Mz9F4pDE=A;LUC@a>cZj8>2V)N%$8LvUt5`>q{cNs!JTnGLo@GVn!B=`1XR%3Q~ z$*(}(BvnMGYIVlp-iUOD8eS%ECPFH7XeewmCx3RENsBpo>E@(SY7F8cpvDIPyRYO$ zv{Y~rsFUazP=Bm(1C0mGg!*zMK?g)JBqZb4`i|v0`i{)0x<|sd3=_Ttsu8Rs=48F} zH0>(ttfW6FZ3VBR61)N@J1_x1utXL0BQ7fLELpV2ScGrtTNmLz2U;U==5_2clsTM4 zj!G{t*%!L5mz@wB-&fNGhQIzhG0avh?b?xiejF0%Z`MLj1DcO1E2>VE0P zqutUo+rx(>>>PO^(%F5owzk&E9qI1w?B?#5I44)j)z)%#_;>v1^W6-hJydK=zQ<^m+cdhM#b~zMG%}Cb`u}bJ0=6nyYXATM literal 0 HcmV?d00001 diff --git a/bin/large/roff b/bin/large/roff new file mode 100755 index 0000000000000000000000000000000000000000..4ea168ecda9bd65283e2ccac596a6143bb934578 GIT binary patch literal 20362 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 literal 0 HcmV?d00001 diff --git a/bin/large/setclock b/bin/large/setclock new file mode 100755 index 0000000000000000000000000000000000000000..6523833a8d2e1334d1cb7c6eb81fe25b3a6a9aa4 GIT binary patch literal 1412 zcma)6U27Xh6rI(FW65cX(v~Rwz`NN#SV@RgaH!;#Jh*0EXsxtqkSR@+D3MlnV|_%s zj%-&J+9HYmg8qc|r4Xle{ZtCVC?Lc_{h&Y}Zb1(lFs=f!V=K0$-OlU?r=c-)pXTn& zIrrXk&rJ0P1{LfGy^fHAlvHW4wD|pc^NUoe-25nAYMhZv>U)LFwQ@1U2h~9(eNL+G zRJ8fA&trF*pEhTk*A|N3PBqG{D(pdHyYxFK5coI#wZ>?E)4#X5QPFm?Px7(( zC;5rikIk`0xw@f#tmwvl$mozUAYlQ~n$x{LKV4q(|L(hh>HLfnsc$IsXP^&pe;AI* zak7z9GJNj442)Pi^E5@xDWEd3pD#69AF_{s?^am9gw?Bq*sl1kohbRi4KTeTAuef z=ftCZ7|D1o{D}J%GkP?OC;iv44AiJ9$393v_7Ye*LMm zmR8sS*F_V^Aou&+N#wtNwa!_HPdPUU)JkEUv7zQN-BTYFYuTXz*C!^%g4|YOP1EZg z1B>Da^5WOg3&`W~XjZE;X?4c%(&L#NZ!A5ykzJmm=>=Y#uAQ&F^Ubf97gr|WZU<6b zQz07&c9X-kY@8-M8c~Um@+Qw_W9gU6*`Ft{S`e~9(0+Ph^~OBEIt7vrX@fKiAqxbp zxaN9uxj|K=W6&yf?p>s*kBcq*(W3PiF6g1toiL)4`)#=Yrs~rj{De@#I`?*uh{k8< zOG_(5uQK={GPC1YO(=A&>P38rXj-Y0hiP)W?d>~ruf!P!e!=jJ>)gO|vNue-49FGq#;LnN1!VxwSmZQV+Ogzep$#gs{JJFZPId(dH aFUls8Y$}?L&q&ftGQrA8!pE9~PV^6?7=-Wu literal 0 HcmV?d00001 diff --git a/bin/large/sort b/bin/large/sort new file mode 100755 index 0000000000000000000000000000000000000000..2729344bf0642848906790d6a53165778a380bda GIT binary patch literal 13153 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 Zlz@|d7+{{fQZ94Ryh%m^W&gLg{|y94PdESo literal 0 HcmV?d00001 diff --git a/bin/large/split b/bin/large/split new file mode 100755 index 0000000000000000000000000000000000000000..36268fdb479d8cfcb80a2db617ab0044f7aedf2a GIT binary patch literal 4055 zcmc&%eQXow8Gp}q9G^)cW)vr4_Aw8lA`StT(#CHf`vYt`{AwPhRSjG zb>aO?>R9J^JbPwW*TAlhQ@fh`cQs_<4-%(cLfwntFNT2b@PR`REQUU-heJd1U$Wp; zp(zjkB?#p7kh)bknTOyK^yMBD7*z*me9Xtf@|M+#ak;LE2EL!b!VOrIzNuQmM= z&*;dg(XHtdH_EnTHC}7_@OQ1`2EXNd<1bC|=f=a04Kta^Nvz>+T=AK1_epn;yEmSd z&xVdVKV~9Tqxt;tNPjt(L>$O(;#HnG7-~23*^uVv^#xh=U`_-QkRb zk0@J5QXFp(B#sCJ!j>=TaNLV3;wbFNi)PrP#v0G+7Ol(;`gK#>=pcmU)rMYCRo~>w zBUE&5Sh^Q2-+j4a_vIU7E*>9F{1P7Gi<^7vS3Bevw!94MX1o1Q(%c4!mfKYR0Oj^zYUM@Ga6j8w7))v3?5Ku>GzL zGa=nsCQveB1RUFl?#_Y#F*H2_FI6p?WB)w&KXm~0v83l!EXN+N=ky;d?f6#RMys=j zdz+&b{1hWa%uv_pq3x`PwlDXPi3nEKL8y2lDT&x}9%C1g7)h(U@F>%8w17w18is%k z{Co_c2khZYhI+a+JRx!BR8nheosz^ho-CW8J*tg5<4a0bUDAkRcEy-Z6>_W z=|9eN2p^)_WW@&&96ggzj@HXR&@!k&TZ!~$M4sb9PI-=m9B+;&|F}3A$J`w{fT?m~ zLsAUWBf5P-Pa|4NaX3m}zoZi&Py+s^a4PKJUxyE^BGM)!E}g3)f#dJmfRaohek%{d zy7CQ|SUy(DxusB?&NDk_8tWfdTFc`UwXsPM1?E*m0d4+e6O5U~pEyD^Ul{HtmOp&6 zvmBy%E6T;*zo4bq1VJ-sLarUU8&uBV!921;>)E92!aYnN%1b52o;*ExSGa&Jr1N4i z>|JJi$My6c~^V~eh@7Wj! zNe@k}KR>&ObD8LOkwPQiLJy`FLY>E)&J-T4dInRNOfBW9&ST>zo!wLVZy7AG=sDGx z(G}!nt%D$L!;6{|>nJh_1aXQWb+ z#2SWh+>_EeecD(uw3*UQRt+Z$k+8{1q*#QPr%MYE@lzHw-gCr_uqQ{4|D|QP{ED&Z z7HtMmA9Dj=G)O!4nto8j$pz?Mq)j}wTbX|pZc(?~3V z3#!9}_elzb>^@nu9-3_6ACZtyRlroIF`2&1gmN~Fh9`zO z-5Anrc1lO57a+8#U%Iq-nBG?9@0VC!>7ln1C#RPFPszuhruQYKd5BSHnHlAaA;X4n z3uFt76}cQt6&@cJ@E6g+XQ0MllJ%)kPm60kj>xQt2djCObkK_g%@u2UgUR$?nR>fV zbO!f{wm8kQc6}<)$97-6^@82 zWb$5w{oRU~NO=Jr2b^%ma?oXbtUOD_)$4`jrPJ%QWm;n~hI(yT)>w3(y6}Hp{|0bv BEF%B_ literal 0 HcmV?d00001 diff --git a/bin/large/su b/bin/large/su new file mode 100755 index 0000000000000000000000000000000000000000..8d6af8a889819a3b1e71a448aaac2aa920594931 GIT binary patch literal 10642 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 literal 0 HcmV?d00001 diff --git a/bin/large/sum b/bin/large/sum new file mode 100755 index 0000000000000000000000000000000000000000..d5ec7996b8e914ab6361299b186c9cb8320e5a93 GIT binary patch literal 5667 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 W*(4=Bh_|gp{Aab;rQ*zSwEqYFe~mE! literal 0 HcmV?d00001 diff --git a/bin/large/sync b/bin/large/sync new file mode 100755 index 0000000000000000000000000000000000000000..56f31226cb2ae8b56a99cb0677a91a78de59f5ef GIT binary patch literal 151 zcmX@PjFDkF0|SEy14AQ2V{>C~WADU^Z-bi~559G7ZG5QI-gs8C@%3Td#=Af7KD>DF z@b&$iQ&d^5x63L5(NR$~0^;AaF1#xdOuV+QiiYBWOFXNwyTi#96C uGCVyS-T3jOA`^q<(W`OFVamQP-woK5IvW-L{|6ciH07!yH$>4#pauYQEJ$_$ literal 0 HcmV?d00001 diff --git a/bin/large/tail b/bin/large/tail new file mode 100755 index 0000000000000000000000000000000000000000..f1dbc88547eaf6d8ba8e86b9037caceb7deaa96e GIT binary patch literal 9647 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 literal 0 HcmV?d00001 diff --git a/bin/large/tar b/bin/large/tar new file mode 100755 index 0000000000000000000000000000000000000000..2ec66624c4555bf31107bf0c826fe3ecf47bbe4d GIT binary patch literal 20135 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 literal 0 HcmV?d00001 diff --git a/bin/large/tee b/bin/large/tee new file mode 100755 index 0000000000000000000000000000000000000000..f9bd487a9f6fa2f7b88c6fd74a44ad34e898ccdc GIT binary patch literal 578 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 A+5i9m literal 0 HcmV?d00001 diff --git a/bin/large/test b/bin/large/test new file mode 100755 index 0000000000000000000000000000000000000000..ef86d97328625f864d61f1bc87462b248a3c6dc8 GIT binary patch literal 6419 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 B^496-hXSc}&=yD+RLCf7 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 literal 0 HcmV?d00001 diff --git a/bin/large/time b/bin/large/time new file mode 100755 index 0000000000000000000000000000000000000000..a5d189a996e490796a6618f863c61ebc66d140ac GIT binary patch literal 5875 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 L_}JwBzt?{OGDLz( literal 0 HcmV?d00001 diff --git a/bin/large/top b/bin/large/top new file mode 100755 index 0000000000000000000000000000000000000000..f74697483474e403aa19c0f70b319b4931f3a816 GIT binary patch literal 18954 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 augJe1gQ8`$AB%{;HzHX|aYj3B<$nN9Rs-<> literal 0 HcmV?d00001 diff --git a/bin/large/true b/bin/large/true new file mode 100755 index 0000000000000000000000000000000000000000..3b4a7950131c4af41d4d2fac9e75a97515356bc9 GIT binary patch literal 142 zcmX@PjFF*_fq_AUfuWJ1v8u79v1Q`Lx4~772j4o^G(J?SYdovj`1-JJWMH^!`SK-@I(b&6QLCx3c8dl-BTz7o>24S^kbhRA5yCzj)Oc955vb^@ nA~(a+vq_B~KLYuRObnJsuf{2dDf_y7H(*n0XjJ_FA80xNa3Mkc literal 0 HcmV?d00001 diff --git a/bin/large/ualign b/bin/large/ualign new file mode 100755 index 0000000000000000000000000000000000000000..29b39ef52dc1a07295d63b6adcbfde36bbf06e66 GIT binary patch literal 7138 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 literal 0 HcmV?d00001 diff --git a/bin/large/umount b/bin/large/umount new file mode 100755 index 0000000000000000000000000000000000000000..15737765ca6043d37610c765f4e659a9b56c44c1 GIT binary patch literal 10044 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 Zy{7*9ESixuzBwxYTB261G;5qm`5)6~xM2VQ literal 0 HcmV?d00001 diff --git a/bin/large/uudecode b/bin/large/uudecode new file mode 100755 index 0000000000000000000000000000000000000000..002ee80acd30900a7192b7cab80d3a50fc4c32cd GIT binary patch literal 13391 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 GpZ@{3lOwQ@PE$%C6gi1wW+zzH{!C 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 literal 0 HcmV?d00001 diff --git a/bin/large/wc b/bin/large/wc new file mode 100755 index 0000000000000000000000000000000000000000..c8fac38d9ce1a872e7d67ed5a595550bd8c03f95 GIT binary patch literal 10971 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 literal 0 HcmV?d00001 diff --git a/bin/large/which b/bin/large/which new file mode 100755 index 0000000000000000000000000000000000000000..9a66fb67cd19e264034939df4603587c0a6e957f GIT binary patch literal 5770 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 Bw=)0$ literal 0 HcmV?d00001 diff --git a/bin/large/yes b/bin/large/yes new file mode 100755 index 0000000000000000000000000000000000000000..cf6dd884078b8faa37711643283f866f325b89a3 GIT binary patch literal 419 zcmYjNJxIeq82v73#nwTE3K<-d)*Q)dGDk$`B5{i^6BAo@@ z>>}Mu$ zQ_tTg_#t6iRuiqfzNSgwl6$sJfPc}cG7{V+W<7#gAJCN0kg@Dx$>({RE`)F!%?KLN zm~i3|=FZ8OnKI@o8UevdSdw?q^w98yy&5GorpV;s&k8f1Dr3f1no6y^LHQ=d@-miU zu4QXm;PP`e6%)J!p+h;m_V7yJAW*BV$Nx1(i&2GJD7f>&?mqQZ(J2-sEXZQ#CJiyK mFmWV)pR??svXi5q^iuMfX}&MI6=`g3Wu8LZ-NYddD*OVqM$eT1 literal 0 HcmV?d00001 diff --git a/bin/liberror.txt b/bin/liberror.txt new file mode 100755 index 00000000..aeba55c4 --- /dev/null +++ b/bin/liberror.txt @@ -0,0 +1,52 @@ +# Start /usr/lib/liberror.txt + +1 Operation not permitted (EPERM) +2 No such file or directory (ENOENT) +3 No such process (ESRCH) +4 Interrupted system call (EINTR) +5 I/O error (EIO) +6 No such device or address (ENXIO) +7 Arg list too long (E2BIG) +8 Exec format error (ENOEXEC) +9 Bad file number (EBADF) +10 No child processes (ECHILD) +11 Try again (EAGAIN) +12 Out of memory (ENOMEM) +13 Permission denied (EACCES) +14 Bad address (EFAULT) +15 Block device required (ENOTBLK) +16 Device or resource busy (EBUSY) +17 File exists (EEXIST) +18 Cross-device link (EXDEV) +19 No such device (ENODEV) +20 Not a directory (ENOTDIR) +21 Is a directory (EISDIR) +22 Invalid argument (EINVAL) +23 File table overflow (ENFILE) +24 Too many open files (EMFILE) +25 Not a typewriter (ENOTTY) +26 Text file busy (ETXTBSY) +27 File too large (EFBIG) +28 No space left on device (ENOSPC) +29 Illegal seek (ESPIPE) +30 Read-only file system (EROFS) +31 Too many links (EMLINK) +32 Broken pipe (EPIPE) +33 Math argument out of domain of func (EDOM) +34 Math result not representable (ERANGE) +35 Resource deadlock would occur (EDEADLK) +36 File name too long (ENAMETOOLONG) +37 No record locks available (ENOLCK) +38 Function not implemented (EINVFNC) +39 Directory not empty (ENOTEMPTY) +40 Too many symbolic links encountered (ELOOP) +41 It's a shell script (ESHELL) +42 File is already aligned (EISALIGN) +43 File is not aligned (ENOALIGN) +44 File is too short, or hole (ETOOSHORT) +45 Not a regular or aligned file (ENOREGALIGN) +46 Not a locking filesystem (ENOLCKFS) +47 Filesystem is corrupt (ECORRUPTFS) + +# End /usr/lib/liberror.txt + diff --git a/bin/man/man1/basename.1 b/bin/man/man1/basename.1 new file mode 100755 index 00000000..661f3c95 --- /dev/null +++ b/bin/man/man1/basename.1 @@ -0,0 +1,29 @@ +.TH BASENAME 1 +.SH NAME +basename \- strip filename affixes +.SH SYNOPSIS +.B basename +string [ suffix ] +.SH DESCRIPTION +.I Basename +deletes any prefix ending in `/' and the +.I suffix, +if present in +.I string, +from +.I string, +and prints the result on the standard output. +It is normally used inside substitution marks \`\ \` +in shell procedures. +.PP +This shell procedure invoked with the argument +.I /usr/src/cmd/cat.c +compiles the named file and moves the output to +.I cat +in the current directory: +.IP "" 15n +cc $1 +.br +mv a.out \`basename $1 .c\` +.SH "SEE ALSO" +sh(1) diff --git a/bin/man/man1/cal.1 b/bin/man/man1/cal.1 new file mode 100755 index 00000000..d34b849d --- /dev/null +++ b/bin/man/man1/cal.1 @@ -0,0 +1,27 @@ +.TH CAL 1 +.SH NAME +cal \- print calendar +.SH SYNOPSIS +.B cal +[ month ] year +.SH DESCRIPTION +.I Cal +prints a calendar for the specified year. +If a month is also specified, a calendar +just for that month is printed. +.I Year +can be between 1 +and 9999. +The +.I month +is a number between 1 and 12. +The calendar +produced is that for England and her colonies. +.PP +Try September 1752. +.SH BUGS +The year is always considered to start in January even though this +is historically naive. +.br +Beware that `cal 78' refers to the early Christian era, +not the 20th century. diff --git a/bin/man/man1/cat.1 b/bin/man/man1/cat.1 new file mode 100755 index 00000000..ebeac0d8 --- /dev/null +++ b/bin/man/man1/cat.1 @@ -0,0 +1,38 @@ +.TH CAT 1 +.SH NAME +cat \- catenate and print +.SH SYNOPSIS +.B cat +[ +.B \-u +] file ... +.SH DESCRIPTION +.I Cat +reads each +.I file +in sequence and writes it on the standard output. +Thus +.IP +cat file +.LP +prints the file and +.IP +cat file1 file2 >file3 +.LP +concatenates the first two files and places the result +on the third. +.PP +If no +.I file +is given, or if the argument `\-' is encountered, +.I cat +reads from the standard input. +Output is buffered in 512-byte blocks unless the +standard output is a terminal or the +.B \-u +option is present. +.SH SEE ALSO +pr(1), cp(1) +.SH BUGS +Beware of `cat a b >a' and `cat a b >b', which +destroy input files before reading them. diff --git a/bin/man/man1/chmod.1 b/bin/man/man1/chmod.1 new file mode 100755 index 00000000..dc61d366 --- /dev/null +++ b/bin/man/man1/chmod.1 @@ -0,0 +1,172 @@ +.TH CHMOD 1 +.SH NAME +chmod \- change mode +.SH SYNOPSIS +.B chmod +mode file ... +.SH DESCRIPTION +The mode of +each named file +is changed +according to +.I mode, +which may be absolute or symbolic. +An absolute +.I mode +is an octal +number constructed +from the OR of the +following modes: +.TP 10 +4000 +set user ID on execution +.br +.br +.ns +.TP 10 +2000 +set group ID on execution +.br +.br +.ns +.TP 10 +1000 +sticky bit, see +.IR chmod (2) +.br +.br +.ns +.TP 10 +0400 +read by owner +.br +.br +.ns +.TP 10 +0200 +write by owner +.br +.br +.ns +.TP 10 +0100 +execute (search in directory) by owner +.br +.br +.ns +.TP 10 +0070 +read, write, execute (search) by group +.br +.br +.ns +.TP 10 +0007 +read, write, execute (search) by others +.PP +A symbolic +.I mode +has the form: +.IP +.RI [ who ] +.I op permission +.RI [ "op permission" "] ..." +.PP +The +.I who +part is a combination +of the letters +.B u +(for user's permissions), +.B g +(group) +and +.B o +(other). +The letter +.B a +stands for +.B ugo. +If +.I who +is omitted, +the default is +.I a +but the setting of +the file creation mask +(see umask(2)) +is taken into account. +.PP +.I Op +can be +.B + +to add +.I permission +to the file's mode, +.B \- +to take away +.I permission +and +.B = +to assign +.I permission +absolutely +(all other bits will +be reset). +.PP +.I Permission +is any combination of the letters +.B r +(read), +.B w +(write), +.B x +(execute), +.B s +(set owner or group id) +and +.B t +(save text \- sticky). +Letters +.BR u, +.B g +or +.B o +indicate that +.I permission +is to be taken +from the current +mode. +Omitting +.I permission +is only useful +with +.B = +to take away +all permissions. +.PP +The first example denies write permission to others, +the second makes a file executable: +.IP +chmod o\-w file +.br +chmod +x file +.PP +Multiple symbolic modes separated by commas may be given. +Operations are performed +in the order specified. +The letter +.B s +is only useful +with +.B u +or +.B g. +.PP +Only the owner of a file (or the super-user) may change its mode. +.SH "SEE ALSO" +ls(1), +chmod(2), +chown (1), +stat(2), +umask(2) diff --git a/bin/man/man1/chown.1 b/bin/man/man1/chown.1 new file mode 100755 index 00000000..7be9fe58 --- /dev/null +++ b/bin/man/man1/chown.1 @@ -0,0 +1,35 @@ +.TH CHOWN 1 +.SH NAME +chown, chgrp \- change owner or group +.SH SYNOPSIS +.B chown +owner file ... +.PP +.B chgrp +group file ... +.SH DESCRIPTION +.I Chown +changes the owner of the +.I files +to +.IR owner . +The owner may be either a decimal UID or +a login name found in the password file. +.PP +.I Chgrp +changes the group-ID of the +.I files +to +.IR group . +The group may be either a decimal GID or +a group name found in the group-ID file. +.PP +Only the super-user can change owner or group, +in order to simplify as yet unimplemented accounting procedures. +.SH FILES +/etc/passwd +.br +/etc/group +.SH "SEE ALSO" +chown(2), +passwd(5), group(5) diff --git a/bin/man/man1/cmp.1 b/bin/man/man1/cmp.1 new file mode 100755 index 00000000..415bbc8b --- /dev/null +++ b/bin/man/man1/cmp.1 @@ -0,0 +1,42 @@ +.TH CMP 1 +.SH NAME +cmp \- compare two files +.SH SYNOPSIS +.B cmp +[ +.B \-l +] [ +.B \-s +] +file1 file2 +.SH DESCRIPTION +The two files are +compared. +(If +.I file1 +is `\-', +the standard input is used.) +Under default options, +.I cmp +makes no comment if the files are the same; +if they differ, it announces the byte and line number +at which the difference occurred. +If one file is an initial subsequence +of the other, that fact is noted. +.PP +Options: +.TP 6 +.B \-l +Print the byte number (decimal) and the +differing bytes (octal) for each difference. +.TP 6 +.B \-s +Print nothing for differing files; +return codes only. +.dt +.SH "SEE ALSO" +diff(1), comm(1) +.SH DIAGNOSTICS +Exit code 0 is returned for identical +files, 1 for different files, and 2 for an +inaccessible or missing argument. diff --git a/bin/man/man1/cp.1 b/bin/man/man1/cp.1 new file mode 100755 index 00000000..605e4866 --- /dev/null +++ b/bin/man/man1/cp.1 @@ -0,0 +1,29 @@ +.TH CP 1 +.SH NAME +cp \- copy +.SH SYNOPSIS +.B cp +file1 file2 +.PP +.B cp +file ... directory +.SH DESCRIPTION +.I File1 +is copied onto +.IR file2 . +The mode and owner of +.I file2 +are preserved if it already +existed; the mode of the source file +is used otherwise. +.PP +In the second form, one or more +.I files +are copied into the +.I directory +with their original file-names. +.PP +.I Cp +refuses to copy a file onto itself. +.SH "SEE ALSO" +cat(1), pr(1), mv(1) diff --git a/bin/man/man1/date.1 b/bin/man/man1/date.1 new file mode 100755 index 00000000..e9ea7fcb --- /dev/null +++ b/bin/man/man1/date.1 @@ -0,0 +1,42 @@ +.TH DATE 1 +.SH NAME +date \- print and set the date +.SH SYNOPSIS +.B date +.RB "[ yymmddhhmm [ " . "ss ] ]" +.SH DESCRIPTION +If no argument is given, the current date and time are printed. +If an argument is given, the current date is set. +.I yy +is the last two digits of the year; +the first +.I mm +is the month number; +.I dd +is the day number in the month; +.I hh +is the hour number (24 hour system); +the second +.I mm +is the minute number; +.BI . ss +is optional and is the seconds. +For example: +.IP +date 10080045 +.PP +sets the date to Oct 8, 12:45 AM. +The year, month and day may be omitted, the current +values being the defaults. +The system operates in GMT. +.I Date +takes care of the conversion to and from +local standard and daylight time. +.SH FILES +/usr/adm/wtmp to record time-setting +.SH SEE ALSO +utmp(5) +.SH DIAGNOSTICS +`No permission' if +you aren't the super-user and you try to change the date; +`bad conversion' if the date set is syntactically incorrect. diff --git a/bin/man/man1/dd.1 b/bin/man/man1/dd.1 new file mode 100755 index 00000000..56aaab3c --- /dev/null +++ b/bin/man/man1/dd.1 @@ -0,0 +1,192 @@ +.TH DD 1 +.SH NAME +dd \- convert and copy a file +.SH SYNOPSIS +.B dd +[option=value] ... +.SH DESCRIPTION +.I Dd +copies the specified input file +to the specified output with +possible conversions. +The standard input and output are used by default. +The input and output block size may be +specified to take advantage of raw physical I/O. +.PP +.br +.ns +.TP 15 +.I option +.I values +.br +.ns +.TP +if= +input file name; standard input is default +.br +.ns +.TP +of= +output file name; standard output is default +.br +.ns +.TP +.RI ibs= n +input block size +.I n +bytes (default 512) +.br +.ns +.TP +.RI obs= n +output block size (default 512) +.br +.ns +.TP +.RI bs= n +set both input and output block size, +superseding +.I ibs +and +.I obs; +also, if no conversion is specified, +it is particularly efficient since no copy need be done +.br +.ns +.TP +.RI cbs= n +conversion buffer size +.br +.ns +.TP +.RI skip= n +skip +.IR n "" +input records before starting copy +.br +.ns +.TP +.RI files= n +copy +.I n +files from (tape) input +.br +.ns +.TP +.RI seek= n +seek +.I n +records from beginning of output file before copying +.br +.ns +.TP +count=\fIn\fR +copy only +.IR n "" +input records +.br +.ns +.TP +conv=ascii +.ds h \h'\w'conv='u' +convert EBCDIC to ASCII +.br +.ns +.IP \*hebcdic +convert ASCII to EBCDIC +.br +.ns +.IP \*hibm +slightly different map of ASCII to EBCDIC +.br +.ns +.IP \*hlcase +map alphabetics to lower case +.br +.ns +.IP \*hucase +map alphabetics to upper case +.br +.ns +.IP \*hswab +swap every pair of bytes +.br +.ns +.IP \*hnoerror +do not stop processing on an error +.br +.ns +.IP \*hsync +pad every input record to +.I ibs +.br +.ns +.IP "\*h... , ..." +several comma-separated conversions +.PP +.fi +Where sizes are specified, +a number of bytes is expected. +A number may end with +.B "k, b" +or +.B w +to specify multiplication by +1024, 512, or 2 respectively; +a pair of numbers may be separated by +.B x +to indicate a product. +.PP +.I Cbs +is used only if +.I ascii +or +.I ebcdic +conversion is specified. +In the former case +.I cbs +characters are placed into the conversion buffer, converted to +ASCII, and trailing blanks trimmed and new-line added +before sending the line to the output. +In the latter case ASCII characters are read into the +conversion buffer, converted to EBCDIC, and blanks added +to make up an +output record of size +.IR cbs . +.PP +After completion, +.I dd +reports the number of whole and partial input and output +blocks. +.PP +For example, to read an EBCDIC tape blocked ten 80-byte +EBCDIC card images per record into the ASCII file +.IR x : +.IP "" +dd if=/dev/rmt0 of=x ibs=800 cbs=80 conv=ascii,lcase +.PP +Note the use of raw magtape. +.I Dd +is especially suited to I/O on the raw +physical devices because it allows reading +and writing in arbitrary record sizes. +.PP +To skip over a file before copying from magnetic tape do +.IP"" +(dd of=/dev/null; dd of=x) '. +.PP +The +.B \-b +option causes +trailing blanks (spaces and tabs) to be ignored +and other strings of blanks to compare equal. +.PP +The +.B \-e +option produces a script of +.I "a, c" +and +.I d +commands for the editor +.I ed, +which will recreate +.I file2 +from +.IR file1 . +The +.B \-f +option produces a similar script, +not useful with +.I ed, +in the opposite order. +In connection with +.BR \-e , +the following shell program may help maintain +multiple versions of a file. +Only an ancestral file ($1) and a chain of +version-to-version +.I ed +scripts ($2,$3,...) made by +.I diff +need be on hand. +A `latest version' appears on +the standard output. +.IP "" 5 +(shift; cat $*; echo \'1,$p\') \(bv ed \- $1 +.PP +Except in rare circumstances, +.I diff +finds a smallest sufficient set of file +differences. +.PP +Option +.B \-h +does a fast, half-hearted job. +It works only when changed stretches are short +and well separated, +but does work on files of unlimited length. +Options +.B \-e +and +.B \-f +are unavailable with +.BR \-h . +.SH FILES +/tmp/d????? +.br +/usr/lib/diffh for +.B \-h +.SH "SEE ALSO" +cmp(1), comm(1), ed(1) +.SH DIAGNOSTICS +Exit status is 0 for no differences, 1 for some, 2 for trouble. +.SH BUGS +Editing scripts produced under the +.BR \-e " or" +.BR \-f " option are naive about" +creating lines consisting of a single `\fB.\fR'. diff --git a/bin/man/man1/du.1 b/bin/man/man1/du.1 new file mode 100755 index 00000000..59ed53e0 --- /dev/null +++ b/bin/man/man1/du.1 @@ -0,0 +1,43 @@ +.TH DU 1 +.SH NAME +du \- summarize disk usage +.SH SYNOPSIS +.B du +[ +.B \-s +] [ +.B \-a +] [ name ... ] +.SH DESCRIPTION +.I Du +gives the number of blocks contained in all files +and (recursively) directories within each specified directory or +file +.IR name . +If +.I name +is missing, +`\fB.\fR' +is used. +.PP +The optional argument +.B \-s +causes only the grand total to +be given. +The optional argument +.B \-a +causes an entry to be generated +for each file. +Absence of either causes an entry to be generated for +each directory only. +.PP +A file which has two links to it is only counted once. +.SH BUGS +Non-directories +given as arguments (not under +.B \-a +option) are not listed. +.br +If there are too many distinct linked files, +.I du +counts the excess files multiply. diff --git a/bin/man/man1/echo.1 b/bin/man/man1/echo.1 new file mode 100755 index 00000000..16b2ead2 --- /dev/null +++ b/bin/man/man1/echo.1 @@ -0,0 +1,23 @@ +.TH ECHO 1 +.SH NAME +echo \- echo arguments +.SH SYNOPSIS +.B echo +[ +.B \-n +] +[ arg ] ... +.SH DESCRIPTION +.I Echo +writes its arguments separated by blanks and terminated by +a newline on the standard output. +If the flag +.B \-n +is used, +no newline is added to the output. +.PP +.I Echo +is useful for producing diagnostics in +shell programs and for writing constant data on pipes. +To send diagnostics to the standard error file, do +`echo ... 1>&2'. diff --git a/bin/man/man1/ed.1 b/bin/man/man1/ed.1 new file mode 100755 index 00000000..1fbedc45 --- /dev/null +++ b/bin/man/man1/ed.1 @@ -0,0 +1,652 @@ +.TH ED 1 +.if t .ds q \(aa +.if n .ds q ' +.SH NAME +ed \- text editor +.SH SYNOPSIS +.B ed +[ +.B \- +] [ +.B \-x +] [ name ] +.SH DESCRIPTION +.I Ed +is the standard text editor. +.PP +If a +.I name +argument is given, +.I ed +simulates an +.I e +command (see below)\| on the named file; that is to say, +the file is read into +.I ed's +buffer so that it can be edited. +If +.B \-x +is present, an +.I x +command is simulated first to handle an encrypted file. +The optional +.B \- +suppresses the printing +of character counts by +.I e, +.I r, +and +.I w +commands. +.PP +.I Ed +operates on a copy of any file it is editing; changes made +in the copy have no effect on the file until a +.IR w "" +(write)\| +command is given. +The copy of the text being edited resides +in a temporary file called the +.IR buffer . +.PP +Commands to +.I ed +have a simple and regular structure: zero or +more +.I addresses +followed by a single character +.I command, +possibly +followed by parameters to the command. +These addresses specify one or more lines in the buffer. +Missing addresses are supplied by default. +.PP +In general, only one command may appear on a line. +Certain commands allow the +addition of text to the buffer. +While +.I ed +is accepting text, it is said +to be in +.I "input mode." +In this mode, no commands are recognized; +all input is merely collected. +Input mode is left by typing a period `\fB.\fR' alone at the +beginning of a line. +.PP +.I Ed +supports a limited form of +.I "regular expression" +notation. +A regular expression specifies +a set of strings of characters. +A member of this set of strings is said to be +.I matched +by the regular expression. +In the following specification for regular expressions +the word `character' means any character but newline. +.IP 1. +Any character except a special character +matches itself. +Special characters are +the regular expression delimiter plus +.RB \e\|[\| . +and sometimes ^\|*\|$. +.IP 2. +A +.B . +matches any character. +.IP 3. +A \e followed by any character except a digit or (\|) matches that character. +.IP 4. +A nonempty string +.I s +bracketed +.RI [ \|s\| ] +(or +.RI [^ s\| ]) +matches any character in (or not in) +.I s. +In +.I s, +\e has no special meaning, and ] may only appear as +the first letter. +A substring +.I a\-b, +with +.I a +and +.I b +in ascending ASCII order, stands for the inclusive +range of ASCII characters. +.IP 5. +A regular expression of form 1-4 followed by * matches a sequence of +0 or more matches of the regular expression. +.IP 6. +A regular expression, +.I x, +of form 1-8, bracketed +.RI \e( \|x\| \e) +matches what +.I x +matches. +.IP 7. +A \e followed by a digit +.I n +matches a copy of the string that the +bracketed regular expression beginning with the +.IR n th +\e( matched. +.IP 8. +A regular expression of form 1-8, +.I x, +followed by a regular expression of form 1-7, +.I y +matches a match for +.I x +followed by a match for +.I y, +with the +.I x +match being as long as possible while still permitting a +.I y +match. +.IP 9. +A regular expression of form 1-8 preceded by ^ +(or followed by $), is constrained to matches that +begin at the left (or end at the right) end of a line. +.IP 10. +A regular expression of form 1-9 picks out the +longest among the leftmost matches in a line. +.IP 11. +An empty regular expression stands for a copy of the +last regular expression encountered. +.PP +Regular expressions are used in addresses to specify +lines and in one command +(see +.I s +below)\| +to specify a portion of a line which is to be replaced. +If it is desired to use one of +the regular expression metacharacters as an ordinary +character, that character may be preceded by `\e'. +This also applies to the character bounding the regular +expression (often `/')\| and to `\e' itself. +.PP +To understand addressing in +.I ed +it is necessary to know that at any time there is a +.I "current line." +Generally speaking, the current line is +the last line affected by a command; however, +the exact effect on the current line +is discussed under the description of +the command. +Addresses are constructed as follows. +.TP +1. +The character `\fB.\fR' addresses the current line. +.TP +2. +The character `$' addresses the last line of the buffer. +.TP +3. +A decimal number +.I n +addresses the +.IR n -th +line of the buffer. +.TP +4. +`\(fm\fIx\fR' addresses the line marked with the name +.IR x , +which must be a lower-case letter. +Lines are marked with the +.I k +command described below. +.TP +5. +A regular expression enclosed in slashes `/' addresses +the line found by searching forward from the current line +and stopping at the first line containing a +string that matches the regular expression. +If necessary the search wraps around to the beginning of the +buffer. +.TP +6. +A regular expression enclosed in queries `?' addresses +the line found by searching backward from the current line +and stopping at the first line containing +a string that matches the regular expression. +If necessary +the search wraps around to the end of the buffer. +.TP +7. +An address followed by a plus sign `+' +or a minus sign `\-' followed by a decimal number specifies that address plus +(resp. minus)\| the indicated number of lines. +The plus sign may be omitted. +.TP +8. +If an address begins with `+' or `\-' +the addition or subtraction is taken with respect to the current line; +e.g. `\-5' is understood to mean `\fB.\fR\-5'. +.TP +9. +If an address ends with `+' or `\-', +then 1 is added (resp. subtracted). +As a consequence of this rule and rule 8, +the address `\-' refers to the line before the current line. +Moreover, +trailing +`+' and `\-' characters +have cumulative effect, so `\-\-' refers to the current +line less 2. +.TP +10. +To maintain compatibility with earlier versions of the editor, +the character `^' in addresses is +equivalent to `\-'. +.PP +Commands may require zero, one, or two addresses. +Commands which require no addresses regard the presence +of an address as an error. +Commands which accept one or two addresses +assume default addresses when insufficient are given. +If more addresses are given than such a command requires, +the last one or two (depending on what is accepted)\| are used. +.PP +Addresses are separated from each other typically by a comma +`\fB,\fR'. +They may also be separated by a semicolon +`\fB;\fR'. +In this case the current line `\fB.\fR' is set to +the previous address before the next address is interpreted. +This feature can be used to determine the starting +line for forward and backward searches (`/', `?')\|. +The second address of any two-address sequence +must correspond to a line following the line corresponding to the first address. +.PP +In the following list of +.I ed +commands, the default addresses +are shown in parentheses. +The parentheses are not part of +the address, but are used to show that the given addresses are +the default. +.PP +As mentioned, it is generally illegal for more than one +command to appear on a line. +However, most commands may be suffixed by `p' +or by `l', in which case +the current line is either +printed or listed respectively +in the way discussed below. +.TP 5 +.RB (\| .\| )\|a +.br +.ns +.TP 5 + +.br +.ns +.TP 5 +.B . +.br +The append command reads the given text +and appends it after the addressed line. +`\fB.\fR' is left +on the last line input, if there +were any, otherwise at the addressed line. +Address `0' is legal for this command; text is placed +at the beginning of the buffer. +.TP 5 +.RB (\| .\| ,\ .\| )\|c +.br +.ns +.TP 5 + +.br +.ns +.TP 5 +.B . +.br +The change +command deletes the addressed lines, then accepts input +text which replaces these lines. +`\fB.\fR' is left at the last line input; if there were none, +it is left at the line preceding the deleted lines. +.TP 5 +.RB (\| .\| ,\ .\| )\|d +The delete command deletes the addressed lines from the buffer. +The line originally after the last line deleted becomes the current line; +if the lines deleted were originally at the end, +the new last line becomes the current line. +.TP 5 +e filename +The edit +command causes the entire contents of the buffer to be deleted, +and then the named file to be read in. +`\fB.\fR' is set to the last line of the buffer. +The number of characters read is typed. +`filename' is remembered for possible use as a default file name +in a subsequent +.I r +or +.I w +command. +If `filename' is missing, the remembered name is used. +.TP 5 +E filename +This command is the same as +.I e, +except that no diagnostic results when no +.I w +has been given since the last buffer alteration. +.TP 5 +f filename +The filename command prints the currently remembered file name. +If `filename' is given, +the currently remembered file name is changed to `filename'. +.TP 5 +(1,$)\|g/regular expression/command list +In the global +command, the first step is to mark every line which matches +the given regular expression. +Then for every such line, the +given command list is executed with `\fB.\fR' initially set to that line. +A single command or the first of multiple commands +appears on the same line with the global command. +All lines of a multi-line list except the last line must be ended with `\e'. +.I A, +.I i, +and +.I c +commands and associated input are permitted; +the `\fB.\fR' terminating input mode may be omitted if it would be on the +last line of the command list. +The commands +.I g +and +.I v +are not permitted in the command list. +.TP 5 +.RB (\| .\| )\|i +.ns +.TP 5 + +.br +.ns +.TP 5 +.B . +.br +This command inserts the given text before the addressed line. +`\fB.\fR' is left at the last line input, or, if there were none, +at the line before the addressed line. +This command differs from the +.I a +command only in the placement of the +text. +.TP 5 +.RB (\| .\| ,\ . +1)\|j +This command joins the addressed lines into a single line; +intermediate newlines simply disappear. +`\fB.\fR' is left at the resulting line. +.TP 5 +( \fB. \fR)\|k\fIx\fR +The mark command marks the addressed line with +name +.I x, +which must be a lower-case letter. +The address form `\(fm\fIx\fR' then addresses this line. +.ne 2.5 +.TP 5 +.RB (\| .\| ,\ .\| )\|l +The list command +prints the addressed lines in an unambiguous way: +non-graphic characters are +printed in two-digit octal, +and long lines are folded. +The +.I l +command may be placed on the same line after any non-i/o +command. +.TP 5 +.RB (\| .\| ,\ .\| )\|m\fIa +The move command repositions the addressed lines after the line +addressed by +.IR a . +The last of the moved lines becomes the current line. +.TP 5 +.RB (\| .\| ,\ .\| )\|p +The print command prints the addressed lines. +`\fB.\fR' +is left at the last line printed. +The +.I p +command +may +be placed on the same line after any non-i/o command. +.TP +.RB (\| .\| ,\ .\| )\|P +This command is a synonym for +.I p. +.TP 5 +q +The quit command causes +.I ed +to exit. +No automatic write +of a file is done. +.TP 5 +Q +This command is the same as +.I q, +except that no diagnostic results when no +.I w +has been given since the last buffer alteration. +.TP 5 +($)\|r filename +The read command +reads in the given file after the addressed line. +If no file name is given, +the remembered file name, if any, is used +(see +.I e +and +.I f +commands)\|. +The file name is remembered if there was no +remembered file name already. +Address `0' is legal for +.I r +and causes the +file to be read at the beginning of the buffer. +If the read is successful, the number of characters +read is typed. +`\fB.\fR' is left at the last line read in from the file. +.TP 5 +(\| \fB.\fR\|, \fB.\fR\|)\|s/regular expression/replacement/ or, +.br +.ns +.TP 5 +(\| \fB.\fR\|, \fB.\fR\|)\|s/regular expression/replacement/g +The substitute command searches each addressed +line for an occurrence of the specified regular expression. +On each line in which a match is found, +all matched strings are replaced by the replacement specified, +if the global replacement indicator `g' appears after the command. +If the global indicator does not appear, only the first occurrence +of the matched string is replaced. +It is an error for the substitution to fail on all addressed lines. +Any character other than space or new-line +may be used instead of `/' to delimit the regular expression +and the replacement. +`\fB.\fR' is left at the last line substituted. +.IP +An ampersand `&' appearing in the replacement +is replaced by the string matching the regular expression. +The special meaning of `&' in this context may be +suppressed by preceding it by `\e'. +The characters +.I `\|\en' +where +.I n +is a digit, +are replaced by the text matched by the +.IR n -th +regular subexpression +enclosed between `\e(' and `\e)'. +When +nested, parenthesized subexpressions +are present, +.I n +is determined by counting occurrences of `\e(' starting from the left. +.IP +Lines may be split by substituting new-line characters into them. +The new-line in the +replacement string +must be escaped by preceding it by `\e'. +.TP 5 +.RB (\| .\| ,\ .\| )\|t\|\fIa +This command acts just like the +.I m +command, except that a copy of the addressed lines is placed +after address +.I a +(which may be 0). +`\fB.\fR' is left on the last line of the copy. +.TP 5 +.RB (\| .\| ,\ .\| )\|u +The undo command restores the preceding contents +of the current line, which must be the last line +in which a substitution was made. +.TP 5 +(1, $)\|v/regular expression/command list +This command is the same as the global command +.I g +except that the command list is executed +.I g +with `\fB.\fR' initially set to every line +.I except +those +matching the regular expression. +.TP 5 +(1, $)\|w filename +.br +The write command writes the addressed lines onto +the given file. +If the file does not exist, +it is created mode 666 (readable and writable by everyone)\|. +The file name is remembered if there was no +remembered file name already. +If no file name is given, +the remembered file name, if any, is used +(see +.I e +and +.I f +commands)\|. +`\fB.\fR' is unchanged. +If the command is successful, the number of characters written is +printed. +.TP +(1,$)W filename +This command is the same as +.I w, +except that the addressed lines are appended to the file. +.TP 5 +x +A key string is demanded from the standard input. +Later +.I r, e +and +.I w +commands will encrypt and decrypt the text +with this key by the algorithm of +.IR crypt (1). +An explicitly empty key turns off encryption. +.TP 5 +($)\|= +The line number of the addressed line is typed. +`\fB.\fR' is unchanged by this command. +.TP 5 +! +The remainder of the line after the `!' is sent +to +.IR sh (1) +to be interpreted as a command. +.RB ` . ' +is unchanged. +.TP 5 +.RB (\| . +1)\| +An address alone on a line causes the addressed line to be printed. +A blank line alone is equivalent to `.+1p'; it is useful +for stepping through text. +.PP +If an interrupt signal (ASCII DEL)\| is sent, +.I ed +prints a `?' and returns to its command level. +.PP +Some size limitations: +512 characters per line, +256 characters per global command list, +64 characters per file name, +and 128K characters in the temporary file. +The limit on the number of lines depends on the amount of core: +each line takes 1 word. +.PP +When reading a file, +.I ed +discards ASCII NUL characters +and all characters after the last newline. +It refuses to read files containing non-ASCII characters. +.SH FILES +/tmp/e* +.br +ed.hup: work is saved here if terminal hangs up +.SH "SEE ALSO" +B. W. Kernighan, +.I +A Tutorial Introduction to the ED Text Editor +.br +B. W. Kernighan, +.I Advanced editing on UNIX +.br +sed(1), crypt(1) +.SH DIAGNOSTICS +`?name' for inaccessible file; +`?' for +errors in commands; +`?TMP' for temporary file overflow. +.PP +To protect against throwing away valuable work, +a +.I q +or +.I e +command is considered to be in error, unless a +.I w +has occurred since the last buffer change. +A second +.I q +or +.I e +will be obeyed regardless. +.SH BUGS +The +.I l +command mishandles DEL. +.br +A +.I ! +command cannot be subject to a +.I g +command. +.br +Because 0 is an illegal address for a +.I w +command, it is not possible to +create an empty file with +.I ed. diff --git a/bin/man/man1/expr.1 b/bin/man/man1/expr.1 new file mode 100755 index 00000000..dd63e6ac --- /dev/null +++ b/bin/man/man1/expr.1 @@ -0,0 +1,96 @@ +.TH EXPR 1 +.SH NAME +expr \- evaluate arguments as an expression +.SH SYNOPSIS +.B expr +arg +.B .\|.\|. +.SH DESCRIPTION +The arguments are taken as an expression. +After evaluation, the result is written on the standard output. +Each token of the expression is a separate argument. +.PP +The operators and keywords are listed below. +The list is in order of increasing precedence, +with equal precedence operators grouped. +.TP +.I expr | expr +yields the first +.I expr +if it is neither null nor `0', otherwise +yields the second +.I expr. +.TP +.I expr & expr +yields the first +.I expr +if neither +.I expr +is null or `0', otherwise yields `0'. +.TP +.I expr relop expr +where +.I relop is one of +< <= = != >= >, +yields `1' if the indicated comparison is true, `0' if false. +The comparison is numeric if both +.I expr +are integers, otherwise lexicographic. +.TP +.IR expr " + " expr +.br +.IR expr " - " expr +.br +addition or subtraction of the arguments. +.TP +.IR expr " * " expr +.br +.IR expr " / " expr +.br +.IR expr " % " expr +.br +multiplication, division, or remainder of the arguments. +.TP +.IR expr " : " expr +The matching operator compares the string first argument +with the regular expression second argument; +regular expression syntax is the same as that of +.IR ed (1). +The +\fB\\(\|.\|.\|.\|\\)\fP +pattern symbols can be used to select a portion of the +first argument. +Otherwise, +the matching operator yields the number of characters matched +(`0' on failure). +.TP +.RI ( " expr " ) +parentheses for grouping. +.PP +Examples: +.PP +To add 1 to the Shell variable +.IR a : +.IP +a=\`expr $a + 1\` +.PP +To find the filename part (least significant part) +of the pathname stored in variable +.I a, +which may or may not contain `/': +.IP +expr $a : \'.*/\e(\^.*\e)\' \'\^|\' $a +.LP +Note the quoted Shell metacharacters. +.SH "SEE ALSO" +ed(1), sh(1), test(1) +.SH DIAGNOSTICS +.I Expr +returns the following exit codes: +.PP + 0 if the expression is neither null nor `0', +.br + 1 if the expression +is null or `0', +.br + 2 for invalid expressions. diff --git a/bin/man/man1/file.1 b/bin/man/man1/file.1 new file mode 100755 index 00000000..7c7786c4 --- /dev/null +++ b/bin/man/man1/file.1 @@ -0,0 +1,18 @@ +.TH FILE 1 +.SH NAME +file \- determine file type +.SH SYNOPSIS +.B file +file ... +.SH DESCRIPTION +.I File +performs a series of tests on each argument +in an attempt to classify it. +If an argument appears to be ascii, +.I file +examines the first 512 bytes +and tries to guess its language. +.SH BUGS +It often makes mistakes. +In particular it often suggests that +command files are C programs. diff --git a/bin/man/man1/find.1 b/bin/man/man1/find.1 new file mode 100755 index 00000000..bad926d8 --- /dev/null +++ b/bin/man/man1/find.1 @@ -0,0 +1,169 @@ +.TH FIND 1 +.SH NAME +find \- find files +.SH SYNOPSIS +.B find +pathname-list expression +.SH DESCRIPTION +.I Find +recursively descends +the directory hierarchy for +each pathname in the +.I pathname-list +(i.e., one or more pathnames) +seeking files that match a boolean +.I expression +written in the primaries given below. +In the descriptions, the argument +.I n +is used as a decimal integer +where +.I +n +means more than +.I n, +.I \-n +means less than +.I n +and +.I n +means exactly +.IR n . +.TP 10n +.BR \-name " filename" +True if the +.I filename +argument matches the current file name. +Normal +Shell +argument syntax may be used if escaped (watch out for +`[', `?' and `*'). +.TP +.BR \-perm " onum" +True if the file permission flags +exactly +match the +octal number +.I onum +(see +.IR chmod (1)). +If +.I onum +is prefixed by a minus sign, +more flag bits (017777, see +.IR stat (2)) +become significant and +the flags are compared: +.IR (flags&onum)==onum . +.TP +.BR \-type " c" +True if the type of the file +is +.I c, +where +.I c +is +.B "b, c, d" +or +.B f +for +block special file, character special file, +directory or plain file. +.TP +.BR \-links " n" +True if the file has +.I n +links. +.TP +.BR \-user " uname" +True if the file belongs to the user +.I uname +(login name or numeric user ID). +.TP +.BR \-group " gname" +True if the file belongs to group +.I gname +(group name or numeric group ID). +.TP +.BR \-size " n" +True if the file is +.I n +blocks long (512 bytes per block). +.TP +.BR \-inum " n" +True if the file has inode number +.I n. +.TP +.BR \-atime " n" +True if the file has been accessed in +.I n +days. +.TP +.BR \-mtime " n" +True if the file has been modified in +.I n +days. +.TP +.BR \-exec " command" +True if the executed command returns +a zero value as exit status. +The end of the command must be punctuated by an escaped +semicolon. +A command argument `{}' is replaced by the +current pathname. +.TP +.BR \-ok " command" +Like +.B \-exec +except that the generated command is written on +the standard output, then the standard input is read +and the command executed only upon response +.BR y . +.TP +.B \-print +Always true; +causes the current pathname to be printed. +.TP +.BR \-newer " file" +True if +the current file has been modified more recently than the argument +.I file. +.PP +The primaries may be combined using the following operators +(in order of decreasing precedence): +.TP 4 +1) +A parenthesized group of primaries and operators +(parentheses are special to the Shell and must be escaped). +.TP 4 +2) +The negation of a primary +(`!' is the unary +.I not +operator). +.TP 4 +3) +Concatenation of primaries +(the +.I and +operation +is implied by the juxtaposition of two primaries). +.TP 4 +4) +Alternation of primaries +.RB "(`" \-o "' is the" +.I or +operator). +.SH EXAMPLE +To remove all files named +`a.out' or `*.o' that have not been accessed for a week: +.IP "" .2i +find / \\( \-name a.out \-o \-name '*.o' \\) +\-atime +7 \-exec rm {} \\; +.SH FILES +/etc/passwd +.br +/etc/group +.SH "SEE ALSO" +sh(1), test(1), filsys(5) +.SH BUGS +The syntax is painful. diff --git a/bin/man/man1/grep.1 b/bin/man/man1/grep.1 new file mode 100755 index 00000000..18780de0 --- /dev/null +++ b/bin/man/man1/grep.1 @@ -0,0 +1,176 @@ +.TH GREP 1 +.SH NAME +grep, egrep, fgrep \- search a file for a pattern +.SH SYNOPSIS +.B grep +[ option ] ... +expression [ file ] ... +.LP +.B egrep +[ option ] ... +[ expression ] +[ file ] ... +.PP +.B fgrep +[ option ] ... +[ strings ] +[ file ] +.SH DESCRIPTION +Commands of the +.I grep +family search the input +.I files +(standard input default) +for lines matching +a pattern. +Normally, each line found +is copied to the standard output; +unless the +.B \-h +flag is used, +the file name is shown if there is more than one input file. +.PP +.I Grep +patterns are limited regular expressions in the style of +.IR ed (1); +it uses a compact nondeterministic algorithm. +.I Egrep +patterns are full regular expressions; +it uses a fast deterministic algorithm that +sometimes needs exponential space. +.I Fgrep +patterns are fixed strings; it is fast and compact. +.PP +The following options are recognized. +.TP +.B \-v +All lines but those matching +are printed. +.TP +.B \-c +Only a count of matching lines is printed. +.TP +.B \-l +The names of files with matching lines are listed (once) +separated by newlines. +.TP +.B \-n +Each line is preceded by +its line number in the file. +.TP +.B \-b +Each line is preceded by the block number +on which it was found. +This is sometimes useful in locating +disk block numbers by context. +.TP +.B \-s +No output is produced, only status. +.TP +.B \-h +Do not print filename headers with output lines. +.TP +.B \-y +Lower case letters in the pattern will also match +upper case letters in the input +.RI ( grep +only). +.TP +.BI \-e " expression" +Same as a simple +.I expression +argument, +but useful when the +.I expression +begins with a \-. +.TP +.BI \-f " file" +The regular expression +.RI ( egrep ) +or string list +.RI ( fgrep ) +is taken from the +.I file. +.TP +.B \-x +(Exact) only lines matched in their entirety are printed +.RI ( fgrep +only). +.PP +Care should be taken when +using the characters +$ * [ ^ | ? \' " ( ) and \e in the +.I expression +as they are +also meaningful to the Shell. +It is safest to enclose the +entire +.I expression +argument in single quotes \' \'. +.PP +.I Fgrep +searches for lines that contain one of the (newline-separated) +.I strings. +.PP +.I Egrep +accepts extended regular expressions. +In the following description `character' excludes +newline: +.IP +A \e followed by a single character +matches that character. +.IP +The character ^ +($) matches the beginning (end) of a line. +.IP +A +.B . +matches any character. +.IP +A single character not otherwise endowed with special +meaning matches that character. +.IP +A string enclosed in brackets [\|] +matches any single character from the string. +Ranges of ASCII character codes may be abbreviated +as in `a\-z0\-9'. +A ] +may occur only as the first character of the string. +A literal \- must be placed where it can't be +mistaken as a range indicator. +.IP +A regular expression followed by * (+, ?) matches a sequence +of 0 or more (1 or more, 0 or 1) +matches of the regular expression. +.IP +Two regular expressions concatenated +match a match of the first followed by a match of +the second. +.IP +Two regular expressions separated by | or newline +match either a match for the first or a match for the +second. +.IP +A regular expression enclosed in parentheses +matches a match for the regular expression. +.LP +The order of precedence of operators +at the same parenthesis level +is [\|] then +*+? then concatenation then | and newline. +.SH "SEE ALSO" +ed(1), +sed(1), +sh(1) +.SH DIAGNOSTICS +Exit status is 0 if any matches are found, +1 if none, 2 for syntax errors or inaccessible files. +.SH BUGS +Ideally there should be only one +.I grep, +but we don't know a single algorithm that spans a wide enough +range of space-time tradeoffs. +.PP +Lines +are limited to 256 characters; +longer lines are truncated. diff --git a/bin/man/man1/kill.1 b/bin/man/man1/kill.1 new file mode 100755 index 00000000..9eef9b14 --- /dev/null +++ b/bin/man/man1/kill.1 @@ -0,0 +1,38 @@ +.TH KILL 1 +.SH NAME +kill \- terminate a process with extreme prejudice +.SH SYNOPSIS +.B kill +[ +.BR \- signo +] +processid ... +.SH DESCRIPTION +.I Kill +sends signal 15 (terminate) to the specified processes. +If a signal number preceded by `\-' is given +as first argument, that signal is sent instead of +terminate +(see +.IR signal (2)). +This will kill processes that do not catch the signal; +in particular `kill \-9 ...' is a sure kill. +.PP +By convention, if process number 0 is specified, all members +in the process group (i.e. processes resulting from +the current login) are signaled. +.PP +The killed processes must belong +to the current user unless +he is the super-user. +To shut the system down and bring it up single user +the super-user may +use `kill \-1 1'; see +.IR init (8). +.PP +The process number of an asynchronous process +started with `&' is reported by the shell. +Process numbers can also be found by using +.IR ps (1). +.SH "SEE ALSO" +ps(1), kill(2), signal(2) diff --git a/bin/man/man1/ln.1 b/bin/man/man1/ln.1 new file mode 100755 index 00000000..4cf4c1a5 --- /dev/null +++ b/bin/man/man1/ln.1 @@ -0,0 +1,33 @@ +.TH LN 1 +.SH NAME +ln \- make a link +.SH SYNOPSIS +.B ln +name1 [ name2 ] +.SH DESCRIPTION +A link is a directory entry referring +to a file; the same file (together with +its size, all its protection +information, etc.) +may have several links to it. +There is no way to distinguish a link to a file +from its original directory entry; +any changes in the +file are effective +independently of the name by which the file is known. +.PP +.I Ln +creates a link to an existing file +.IR name1 . +If +.I name2 +is given, the link has that name; +otherwise it is placed in the current directory +and its name is the last component +of +.IR name1 . +.PP +It is forbidden to link to a directory +or to link across file systems. +.SH "SEE ALSO" +rm(1) diff --git a/bin/man/man1/login.1 b/bin/man/man1/login.1 new file mode 100755 index 00000000..a1d8dd9b --- /dev/null +++ b/bin/man/man1/login.1 @@ -0,0 +1,61 @@ +.TH LOGIN 1 +.SH NAME +login \- sign on +.SH SYNOPSIS +.B login +[ username ] +.SH DESCRIPTION +The +.I login +command +is used when a user initially +signs on, or it may be used at any time to change +from one user to another. +The latter case is the one summarized above and +described here. +See `How to Get Started' for how to dial up initially. +.PP +If +.I login +is invoked without an argument, +it asks for a user name, and, if +appropriate, a password. +Echoing is turned off (if possible) during the typing of the password, +so it will not appear on the written record of the +session. +.PP +After a successful login, +accounting files are updated and +the user is informed of the +existence of +.I .mail +and message-of-the-day files. +.I Login +initializes the user and group IDs and the working directory, +then executes a command interpreter (usually +.IR sh (1)) +according to specifications found in a password file. +Argument 0 of the command interpreter is `\-sh. +.PP +Login is recognized by +.IR sh (1) +and executed directly (without forking). +.SH FILES +.ta \w'/usr/adm/wtmp\ \ 'u +/etc/utmp accounting +.br +/usr/adm/wtmp accounting +.br +/usr/mail/* mail +.br +/etc/motd message-of-the-day +.br +/etc/passwd password file +.SH "SEE ALSO" +init(8), newgrp(1), getty(8), mail(1), passwd(1), passwd(5) +.SH DIAGNOSTICS +`Login incorrect,' +if the name or the password is bad. +.br +`No Shell', `cannot open password file', `no directory': +consult a programming counselor. diff --git a/bin/man/man1/ls.1 b/bin/man/man1/ls.1 new file mode 100755 index 00000000..8dfe64e3 --- /dev/null +++ b/bin/man/man1/ls.1 @@ -0,0 +1,172 @@ +.TH LS 1 +.SH NAME +ls \- list contents of directory +.SH SYNOPSIS +.B ls +[ +.B \-ltasdrucifg +] name ... +.SH DESCRIPTION +For each directory argument, +.I ls +lists the contents of the directory; +for each file argument, +.I ls +repeats its name and any other information requested. +The output is sorted alphabetically by default. +When no argument is given, the current directory is listed. +When several arguments are given, +the arguments are first sorted appropriately, +but file arguments appear +before directories and their contents. +There are several options: +.TP +.B \-l +List in long format, giving mode, number of links, owner, +size in bytes, and time of last modification +for each file. +(See below.) +If the file is a special file the size field will instead contain +the major and minor device numbers. +.TP +.B \-t +Sort by time modified (latest first) instead of +by name, as is normal. +.TP +.B \-a +List all entries; usually +.RB ` . ' +and +.RB ` .. ' +are suppressed. +.TP +.B \-s +Give size in blocks, +including indirect blocks, for each entry. +.TP +.B \-d +If argument is a directory, list only its name, not +its contents (mostly used with +.B \-l +to get status +on directory). +.TP +.B \-r +Reverse the order of sort to get reverse alphabetic +or oldest first as appropriate. +.TP +.B \-u +Use time of last access instead of last +modification for sorting +.RB ( \-t ) +or printing +.RB ( \-l ). +.TP +.B \-c +Use time of last modification to inode (mode, etc.) +instead of last modification to file for sorting +.RB ( \-t ) +or printing +.RB ( \-l ). +.TP +.B \-i +Print i-number in first column +of the report for each file listed. +.TP +.B \-f +Force each argument to be interpreted as a directory +and list the name found in each slot. +This option turns off +.B "\-l, \-t, \-s," +and +.B \-r, +and +turns on +.B \-a; +the order is the order in which entries +appear in the directory. +.TP +.B \-g +Give group ID instead of owner ID in long listing. +.PP +The mode printed under the +.B \-l +option contains 11 characters +which are interpreted +as follows: +the first character is +.TP 3 +.B d +if the entry is a directory; +.br +.ns +.TP 3 +.B b +if the entry is a block-type special file; +.br +.ns +.TP 3 +.B c +if the entry is a character-type special file; +.br +.ns +.TP 3 +.B \- +if the entry is a plain file. +.PP +The next 9 characters are interpreted +as three sets of three bits each. +The first set refers to owner permissions; +the next to permissions to others in the same user-group; +and the last to all others. +Within each set the three characters indicate +permission respectively to read, to write, or to +execute the file as a program. +For a directory, `execute' permission is interpreted +to mean permission to search the directory +for a specified file. +The permissions are indicated as follows: +.TP 3 +.B r +if the file is readable; +.br +.ns +.TP 3 +.B w +if the file is writable; +.br +.ns +.TP 3 +.B x +if the file is executable; +.br +.ns +.TP 3 +.B \- +if the indicated permission is not granted. +.PP +The group-execute permission character is given +as +.B s +if the file has set-group-ID mode; +likewise the user-execute permission character is given +as +.B s +if the file has set-user-ID mode. +.PP +The last character of the mode (normally `x' or `\-') is +.B t +if the 1000 bit of the mode is on. +See +.IR chmod (1) +for the meaning of this mode. +.PP +When the sizes of the files in a directory +are listed, a total count of blocks, +including indirect blocks is printed. +.SH FILES +/etc/passwd to get user ID's for +`ls \-l'. +.br +/etc/group to get group ID's for +`ls \-g'. diff --git a/bin/man/man1/man.1 b/bin/man/man1/man.1 new file mode 100755 index 00000000..cadea037 --- /dev/null +++ b/bin/man/man1/man.1 @@ -0,0 +1,99 @@ +.TH MAN 1 +.SH NAME +man \- print sections of this manual +.SH SYNOPSIS +.B man +[ option ... ] [ chapter ] title ... +.SH DESCRIPTION +.I Man +locates and prints the section of this manual named +.I title +in the specified +.IR chapter . +(In this context, the word `page' is often used as a synonym for `section'.)\ +The +.I title +is entered in lower case. +The +.I chapter +number does not need a letter suffix. +If no +.I chapter +is specified, the whole manual is searched for +.I title +and all occurrences of it are printed. +.PP +.I Options +and their meanings are: +.TP +.B \-t +Phototypeset the section using +.IR troff (1). +.TP +.B \-n +Print the section on the standard output using +.IR nroff (1). +.TP +.B \-k +Display the output on a Tektronix 4014 terminal using +.IR troff (1) +and +.IR tc (1). +.TP +.B \-e +Appended or prefixed to any of the above +causes the manual section to be preprocessed by +.I neqn +or +.IR eqn (1); +.B \-e +alone means +.BR \-te . +.TP +.B \-w +Print the path names of the manual sections, +but do not print the sections themselves. +.TP +(default) +Copy an already formatted manual section to the terminal, +or, if none is available, act as +.BR \-n . +It may be necessary to use a filter to adapt the output to +the +particular terminal's characteristics. +.PP +Further +.I options, +e.g. to specify the kind of terminal you have, +are passed on to +.IR troff (1) +or +.IR nroff . +.I Options +and +.I chapter +may be changed before each +.IR title . +.PP +For example: +.IP +man man +.PP +would reproduce this section, +as well as any other sections named +.I man +that may exist in other chapters of the manual, e.g. +.IR man (7). +.SH FILES +/usr/man/man?/\(** +.br +/usr/man/cat?/\(** +.SH "SEE ALSO" +nroff(1), +eqn(1), +tc(1), +man(7) +.SH BUGS +The manual is supposed to be reproducible either on +a phototypesetter or on a terminal. +However, on a terminal some information is necessarily lost. diff --git a/bin/man/man1/mkdir.1 b/bin/man/man1/mkdir.1 new file mode 100755 index 00000000..73b86843 --- /dev/null +++ b/bin/man/man1/mkdir.1 @@ -0,0 +1,25 @@ +.TH MKDIR 1 +.SH NAME +mkdir \- make a directory +.SH SYNOPSIS +.B mkdir +dirname ... +.SH DESCRIPTION +.I Mkdir +creates specified directories +in mode 777. +Standard entries, +.RB ` . ', +for the directory itself, +and +.BR ` .. ' +for its parent, are made automatically. +.PP +.I Mkdir +requires write permission in the parent directory. +.SH "SEE ALSO" +rm(1) +.SH DIAGNOSTICS +.I Mkdir +returns exit code 0 if all directories were successfully made. +Otherwise it prints a diagnostic and returns nonzero. diff --git a/bin/man/man1/mv.1 b/bin/man/man1/mv.1 new file mode 100755 index 00000000..318df89d --- /dev/null +++ b/bin/man/man1/mv.1 @@ -0,0 +1,69 @@ +.TH MV 1 +.SH NAME +mv \- move or rename files and directories +.SH SYNOPSIS +.B mv +file1 file2 +.PP +.B mv +file ... directory +.SH DESCRIPTION +.I Mv +moves (changes the name of) +.I file1 +to +.IR file2 . +.PP +If +.I file2 +already exists, +it is removed before +.I file1 +is moved. +If +.I file2 +has a mode which forbids writing, +.I mv +prints the mode (see +.IR chmod (2)) +and +reads the standard input to obtain a line; +if the line begins with +.B y, +the move takes place; +if not, +.I mv +exits. +.PP +In the second form, +one or more +.I files +are moved to the +.I directory +with their original +file-names. +.PP +.I Mv +refuses to move a file onto itself. +.SH "SEE ALSO" +cp(1), chmod(2) +.SH BUGS +If +.I file1 +and +.I file2 +lie on different file systems, +.I mv +must copy the file and delete the original. +In this case the owner name becomes +that of the copying process and any +linking relationship with other files +is lost. +.PP +.I Mv +should take +.B \-f +flag, like +.I rm, +to suppress the question +if the target exists and is not writable. diff --git a/bin/man/man1/od.1 b/bin/man/man1/od.1 new file mode 100755 index 00000000..31338c7d --- /dev/null +++ b/bin/man/man1/od.1 @@ -0,0 +1,70 @@ +.TH OD 1 +.SH NAME +od \- octal dump +.SH SYNOPSIS +.B od +[ +.B \-bcdox +] [ file ] [ [ +.B + +]offset[ +.BR ". " "][" +\fBb\fR ] ] +.SH DESCRIPTION +.I Od +dumps +.I file +in +one or more formats +as +selected by the first argument. +If the first argument is missing, +.B \-o +is default. +The meanings of the format argument characters +are: +.TP 3 +.B b +Interpret bytes in octal. +.TP 3 +.B c +Interpret bytes in ASCII. +Certain non-graphic characters appear as C escapes: +null=\e0, +backspace=\eb, +formfeed=\ef, +newline=\en, +return=\er, +tab=\et; +others appear as 3-digit octal numbers. +.TP 3 +.B d +Interpret words in decimal. +.TP 3 +.B o +Interpret words in octal. +.TP 3 +.B x +Interpret words in hex. +.PP +The +.I file +argument specifies which file is to be dumped. +If no file argument is specified, +the standard input is used. +.PP +The offset argument specifies the offset +in the file where dumping is to commence. +This argument is normally interpreted +as octal bytes. +If `\fB.\fR' is appended, the offset is interpreted in +decimal. +If `\fBb\fR' is appended, the offset is interpreted in +blocks of 512 bytes. +If the file argument is omitted, +the offset argument must be preceded +.RB ` + '. +.PP +Dumping continues until end-of-file. +.SH "SEE ALSO" +adb(1) diff --git a/bin/man/man1/passwd.1 b/bin/man/man1/passwd.1 new file mode 100755 index 00000000..af5a1c61 --- /dev/null +++ b/bin/man/man1/passwd.1 @@ -0,0 +1,30 @@ +.TH PASSWD 1 +.SH NAME +passwd \- change login password +.SH SYNOPSIS +.B passwd +[ name ] +.SH DESCRIPTION +This command changes (or installs) a password +associated with the user +.IR name +(your own name by default). +.PP +The program prompts for the old password and then for the new one. +The caller must supply both. +The new password must be typed twice, to forestall mistakes. +.PP +New passwords must be at least four characters long if they use +a sufficiently rich alphabet and at least six characters long +if monocase. +These rules are relaxed if you are insistent enough. +.PP +Only the owner of the name or the super-user may change a password; +the owner must prove he knows the old password. +.SH FILES +/etc/passwd +.SH "SEE ALSO" +login(1), passwd(5), crypt(3) +.br +Robert Morris and Ken Thompson, +.I Password Security: A Case History diff --git a/bin/man/man1/pr.1 b/bin/man/man1/pr.1 new file mode 100755 index 00000000..a4fe1a37 --- /dev/null +++ b/bin/man/man1/pr.1 @@ -0,0 +1,75 @@ +.TH PR 1 +.SH NAME +pr \- print file +.SH SYNOPSIS +.B pr +[ option ] ... +[ file ] ... +.SH DESCRIPTION +.I Pr +produces a printed listing of one or more +.I files. +The output is separated into pages headed by a date, +the name of the file or a specified header, and the page number. +If there are no file arguments, +.I pr +prints its standard input. +.PP +Options apply to all following files but may be reset +between files: +.TP +.BI \- n +Produce +.IR n -column +output. +.TP +.BI + n +Begin printing with page +.I n. +.TP +.B \-h +Take the next argument as a page header. +.TP +.BI \-w n +For purposes of multi-column output, +take the width of the page to be +.I n +characters instead of the default 72. +.TP +.BI \-l n +Take the length of the page to be +.I n +lines instead of the default 66. +.TP +.B \-t +Do not print the 5-line header or the +5-line trailer normally supplied for each page. +.TP +.BI \-s c +Separate columns by the single character +.I c +instead of by the appropriate amount of white space. +A missing +.I c +is taken to be a tab. +.TP +.B \-m +Print all +.I files +simultaneously, +each in one column, +.PP +Inter-terminal messages via +.IR write (1) +are +forbidden during a +.IR pr . +.SH FILES +/dev/tty? +to suspend messages. +.SH "SEE ALSO" +cat(1) +.SH DIAGNOSTICS +There are no diagnostics when +.I pr +is printing on a terminal. diff --git a/bin/man/man1/ps.1 b/bin/man/man1/ps.1 new file mode 100755 index 00000000..88aa2d91 --- /dev/null +++ b/bin/man/man1/ps.1 @@ -0,0 +1,124 @@ +.TH PS 1 PDP11 +.SH NAME +ps \- process status +.SH SYNOPSIS +.B ps +[ +.B aklx +] +[ namelist ] +.SH DESCRIPTION +.I Ps +prints certain indicia about active +processes. +The +.B a +option asks for information about all processes with terminals (ordinarily +only one's own processes are displayed); +.B x +asks even about processes with no terminal; +.B l +asks for a long listing. +The short listing contains the process ID, tty letter, +the cumulative execution time of the process and an +approximation to the command line. +.PP +The long listing is columnar and contains +.TP +F +Flags associated with the process. +01: in core; +02: system process; +04: locked in core (e.g. for physical I/O); +10: being swapped; +20: being traced by another process. +.TP +S +The state of the process. +0: nonexistent; +S: sleeping; +W: waiting; +R: running; +I: intermediate; +Z: terminated; +T: stopped. +.TP +UID +The user ID of the process owner. +.TP +PID +The process ID of the process; as in certain cults it is possible to kill a process +if you know its true name. +.TP +PPID +The process ID of the parent process. +.TP +CPU +Processor utilization for scheduling. +.TP +PRI +The priority of the +process; high numbers mean low priority. +.TP +NICE +Used in priority computation. +.TP +ADDR +The core address of the process if resident, +otherwise the disk address. +.TP +SZ +The size in blocks of the core image of the process. +.TP +WCHAN +The event for which the process is waiting or sleeping; +if blank, the process is running. +.TP +TTY +The controlling tty for the process. +.TP +TIME +The cumulative execution time for the process. +.TP TIME +The command and its arguments. +.DT +.PP +A process that has exited and has a parent, but has not +yet been waited for by the parent is marked . +.I Ps +makes an educated guess as to the file name +and arguments given when the process was created +by examining core memory or the swap area. +The method is inherently somewhat unreliable and in any event +a process is entitled to destroy this information, +so the names cannot be counted on too much. +.PP +If the +.B k +option is specified, +the file +.I /usr/sys/core +is used in place of +.IR /dev/mem . +This is used for +postmortem system debugging. +If a second argument is given, +it is taken to be the file containing the system's namelist. +.SH FILES +.ta \w'/usr/sys/core 'u +/unix system namelist +.br +/dev/mem core memory +.br +/usr/sys/core alternate core file +.br +/dev searched to find swap device and tty names +.SH "SEE ALSO" +kill(1) +.SH BUGS +Things can change while +.I ps +is running; the picture it gives is only a close +approximation to reality. +.br +Some data printed for defunct processes is irrelevant diff --git a/bin/man/man1/pwd.1 b/bin/man/man1/pwd.1 new file mode 100755 index 00000000..4962aacd --- /dev/null +++ b/bin/man/man1/pwd.1 @@ -0,0 +1,10 @@ +.TH PWD 1 +.SH NAME +pwd \- working directory name +.SH SYNOPSIS +.B pwd +.SH DESCRIPTION +.I Pwd +prints the pathname of the working (current) directory. +.SH "SEE ALSO" +cd(1) diff --git a/bin/man/man1/rm.1 b/bin/man/man1/rm.1 new file mode 100755 index 00000000..1c3c46c6 --- /dev/null +++ b/bin/man/man1/rm.1 @@ -0,0 +1,63 @@ +.TH RM 1 +.SH NAME +rm, rmdir \- remove (unlink) files +.SH SYNOPSIS +.B rm +[ +.B \-fri +] file ... +.PP +.B rmdir +dir ... +.PP +.SH DESCRIPTION +.I Rm +removes the entries for one or more +files +from a directory. +If an entry was the last link to the file, the file +is destroyed. +Removal of a file requires write permission in its directory, +but neither read nor write permission on the file itself. +.PP +If a file has no write permission +and the standard input is a terminal, +its permissions are printed and a line is read from +the standard input. +If that line begins with `y' the file is deleted, +otherwise the file remains. +No questions are asked +when the +.B \-f +(force) option is given. +.PP +If a designated file is a directory, +an error comment is printed unless the optional +argument +.B \-r +has been used. +In that case, +.I rm +recursively deletes the +entire contents of the specified directory, +and the directory itself. +.PP +If the +.B \-i +(interactive) option is in effect, +.I rm +asks whether to delete each file, +and, under +.BR \-r , +whether to examine each directory. +.PP +.I Rmdir +removes entries for the named directories, +which must be empty. +.SH "SEE ALSO" +unlink(2) +.SH DIAGNOSTICS +Generally self-explanatory. +It is forbidden to remove the file `..' merely to avoid the +antisocial consequences of inadvertently doing something like +`rm \-r .*'. diff --git a/bin/man/man1/roff.1 b/bin/man/man1/roff.1 new file mode 100755 index 00000000..a2eda763 --- /dev/null +++ b/bin/man/man1/roff.1 @@ -0,0 +1,318 @@ +.TH ROFF 1 +.SH NAME +roff \- format text +.SH SYNOPSIS +.B roff +[ \fB+\fIn\fR ] [ \fB\-\fIn\fR ] [ +.B \-s +] [ +.B \-h +] file ... +.PP +.B nroff \-mr +[ option ] ... file ... +.br +.B troff \-mr +[ option ] ... file ... +.SH DESCRIPTION +.I Roff +formats text according to control lines embedded +in the text in the given files. +Encountering a nonexistent file terminates printing. +Incoming inter-terminal messages are turned off during printing. +The optional flag arguments mean: +.br +.ns +.TP 5 +.BI + n +Start printing at the first page with number +.IR n . +.br +.ns +.TP 5 +.BI \- n +Stop printing at the first page numbered higher +than +.IR n . +.br +.ns +.TP 5 +.B \-s +Stop before each page (including the first) +to allow paper manipulation; +resume on receipt of an interrupt signal. +.br +.ns +.TP 5 +.B \-h +Insert tabs in the output stream to replace +spaces whenever appropriate. +.PP +.DT +Input consists of intermixed +.I "text lines," +which contain information to be formatted, and +.I "request lines," +which contain instructions about how to format +it. +Request lines begin with a distinguished +.I "control character," +normally a period. +.PP +Output lines may be +.I filled +as nearly as possible with words without regard to +input lineation. +Line +.I breaks +may be caused at specified places by +certain commands, or by the appearance of an +empty input line or an input line beginning with a space. +.PP +The capabilities of +.I roff +are specified in the attached Request Summary. +Numerical values are denoted there by n or +n, +titles by t, and single characters by c. +Numbers denoted +n may be signed + or \-, +in which case they signify relative changes to +a quantity, otherwise they signify +an absolute resetting. +Missing n fields are ordinarily taken to be 1, +missing t fields to be empty, and c fields to shut off +the appropriate special interpretation. +.PP +Running titles usually appear at top and bottom of every +page. +They are set by requests like +.PP +.in +10 +.if t \&.he \(fmpart1\(fmpart2\(fmpart3\(fm +.if n \&.he 'part1'part2'part3' +.in -10 +.PP +Part1 is left justified, part2 is centered, +and part3 is right justified on the page. +Any % sign in a title is replaced by the current +page number. +Any nonblank may serve as a quote. +.PP +ASCII tab characters are replaced in the input by a +.I "replacement character," +normally a space, +according to the +column settings given by a .ta command. +(See .tr for how to convert this character on output.) +.PP +Automatic hyphenation of filled output is done +under control of .hy. +When a word contains a designated +.I "hyphenation character," +that character disappears from the output and +hyphens can be introduced into +the word at the marked places only. +.PP +The +.B \-mr +option of +.I nroff +or +.IR troff (1) +simulates +.I roff +to the greatest extent possible. +.SH FILES +/usr/lib/suftab suffix hyphenation tables +.br +/tmp/rtm? temporary +.br +.SH BUGS +.I Roff +is the simplest of the text formatting +programs, and is utterly frozen. +.bp +.tc | +.tr | +.in 0 +.ce +REQUEST SUMMARY +.PP +.ul +.ta \w'.tr cdef.. 'u +\w'Break 'u +\w'Initial 'u +.di x + \ka +.br +.di +.in \nau +.ti 0 +Request Break Initial Meaning +.na +.ti 0 +.li +.ad yes yes Begin adjusting right margins. +.ti 0 +.li +.ar no arabic Arabic page numbers. +.ti 0 +.li +.br yes \- Causes a line break \*- the filling of +the current line is stopped. +.ti 0 +.li +.bl|n yes \- Insert of n blank lines, on new page if necessary. +.ti 0 +.li +.bp|+n yes n=1 Begin new page and number it n; no n means `+1'. +.ti 0 +.li +.cc|c no c=. Control character becomes `c'. +.ti 0 +.li +.ce|n yes \- Center the next n input lines, +without filling. +.ti 0 +.li +.de|xx no \- Define parameterless macro +to be invoked by request `.xx' +(definition ends on line beginning `\fB..\fR'). +.ti 0 +.li +.ds yes no Double space; same as `.ls 2'. +.ti 0 +.li +.ef|t no t=\*a\*a\*a\*a Even foot title becomes t. +.ti 0 +.li +.eh|t no t=\*a\*a\*a\*a Even head title becomes t. +.ti 0 +.li +.fi yes yes Begin filling output lines. +.ti 0 +.li +.fo no t=\*a\*a\*a\*a All foot titles are t. +.ti 0 +.li +.hc|c no none Hyphenation character becomes `c'. +.ti 0 +.li +.he|t no t=\*a\*a\*a\*a All head titles are t. +.ti 0 +.li +.hx no \- Title lines are suppressed. +.ti 0 +.li +.hy|n no n=1 Hyphenation is done, if n=1; +and is not done, if n=0. +.ti 0 +.li +.ig no \- Ignore input lines through +a line beginning with `\fB..\fR'. +.ti 0 +.li +.in|+n yes \- Indent n spaces from left margin. +.ti 0 +.li +.ix +n no \- Same as `.in' but without break. +.ti 0 +.li +.li|n no \- Literal, treat next n lines as text. +.ti 0 +.li +.ll|+n no n=65 Line length including indent is n characters. +.ti 0 +.li +.ls|+n yes n=1 Line spacing set to n lines per output line. +.ti 0 +.li +.m1|n no n=2 Put n blank lines between the top +of page and head title. +.ti 0 +.li +.m2|n no n=2 n blank lines put between head title +and beginning of text on page. +.ti 0 +.li +.m3|n no n=1 n blank lines put between end of +text and foot title. +.ti 0 +.li +.m4|n no n=3 n blank lines put between the foot title +and the bottom of page. +.ti 0 +.li +.na yes no Stop adjusting the right margin. +.ti 0 +.li +.ne|n no \- Begin new page, if n output lines +cannot fit on present page. +.ti 0 +.li +.nn|+n no \- The next n output lines are not numbered. +.ti 0 +.li +.n1 no no Add 5 to page offset; +number lines in margin from 1 on each page. +.ti 0 +.li +.n2|n no no Add 5 to page offset; +number lines from n; +stop if n=0. +.ti 0 +.li +.ni|+n no n=0 Line numbers are indented n. +.ti 0 +.li +.nf yes no Stop filling output lines. +.ti 0 +.li +.nx|file \- Switch input to `file'. +.ti 0 +.li +.of|t no t=\*a\*a\*a\*a Odd foot title becomes t. +.ti 0 +.li +.oh|t no t=\*a\*a\*a\*a Odd head title becomes t. +.ti 0 +.li +.pa|+n yes n=1 Same as `.bp'. +.ti 0 +.li +.pl|+n no n=66 Total paper length taken to be n lines. +.ti 0 +.li +.po|+n no n=0 Page offset. +All lines are preceded by n spaces. +.ti 0 +.li +.ro no arabic Roman page numbers. +.ti 0 +.li +.sk|n no \- Produce n blank pages starting next page. +.ti 0 +.li +.sp|n yes \- Insert block of n blank lines, +except at top of page. +.ti 0 +.li +.ss yes yes Single space output lines, +equivalent to `.ls 1'. +.ti 0 +.li +.ta|n|n.. \- Pseudotab settings. +Initial tab settings are columns 9 17 25 ... +.ti 0 +.li +.tc|c no space Tab replacement character becomes `c'. +.ti 0 +.li +.ti|+n yes \- Temporarily indent next output +line n spaces. +.ti0 +.li +.tr|cdef.. no \- Translate c into d, e into f, etc. +.ti0 +.li +.ul|n no \- Underline the letters and numbers +in the next n input lines. +.br +.tr || diff --git a/bin/man/man1/sh.1 b/bin/man/man1/sh.1 new file mode 100755 index 00000000..1cb61240 --- /dev/null +++ b/bin/man/man1/sh.1 @@ -0,0 +1,261 @@ +.TH SH 1 +.SH NAME +sh, ., break, case, cd, continue, eval, exec, exit, export, for, if, read, readonly, set, shift, trap, umask, wait, while \- shell +.SH SYNOPSIS +\fBsh\fR [\fB\-eiknqstvxu\fR] [\fB\-c \fIstr\fR] \fB[\fIfile\fR]\fR +.br +.de FL +.TP +\\fB\\$1\\fR +\\$2 +.. +.de EX +.TP 20 +\\fB\\$1\\fR +# \\$2 +.. +.SH OPTIONS +.FL "\-c" "Execute the commands in \fIstr\fR" +.FL "\-e" "Quit on error" +.FL "\-i" "Interactive mode; ignore QUIT, TERMINATE, INTERRUPT" +.FL "\-k" "Look for name=value everywhere on command line" +.FL "\-n" "Do not execute commands" +.FL "\-q" "Change qflag from sig_ign to sig_del" +.FL "\-s" "Read commands from standard input" +.FL "\-t" "Exit after reading and executing one command" +.FL "\-v" "Echo input lines as they are read" +.FL "\-x" "Trace" +.FL "\-u" "Unset variables" +.SH EXAMPLES +.EX "sh script" "Run a shell script" +.SH DESCRIPTION +.PP +.I Sh +is the shell, which forms the user's main interface with the system. +On startup, the shell reads /etc/profile and $HOME/.profile, if they exist, +and executes any commands they contain. The Minix shell has most of the +features of the V7 (Bourne) shell, including redirection of input and output, +pipes, magic characters, background processes, and shell scripts. A brief +summary follows, but whole books have been written on shell programming alone. +.LP +Some of the more common notations are: +.PP +.in +2.45i +.ta 2i 2.2i +.ti -2.2i +date # Regular command +.ti -2.2i +sort file2 # Redirect \fIstdin\fR and \fIstdout\fR +.ti -2.2i +cc file.c 2>error # Redirect \fIstderr\fR +.ti -2.2i +a.out >f 2>&1 # Combine standard output and standard error +.ti -2.2i +sort >file2 # Append output to \fIfile2\fR +.ti -2.2i +sort file2 & # Background job +.ti -2.2i +(ls \-l; a.out) & # Run two background commands sequentially +.ti -2.2i +sort with no command name, modify shell I/O +.ti -2i +exit [n] exit a shell program, with exit value n +.ti -2i +export [var] export var to shell's children; list exported variables +.ti -2i +pwd print the name of the current working directory +.ti -2i +read var read a line from stdin and assign to var +.ti -2i +readonly [var] make var readonly; list readonly variables +.ti -2i +set -f set shell flag (+f unsets flag) +.ti -2i +set str set positional parameter to str +.ti -2i +set show the current shell variables +.ti -2i +shift reassign positional parameters (except ${0}) one left +.ti -2i +times print accumulated user and system times for processes +.ti -2i +trap arg sigs trap signals sigs and run arg on receipt +.ti -2i +trap list trapped signals +.ti -2i +umask [n] set the user file creation mask; show the current umask +.ti -2i +wait [n] wait for process pid n; wait for all processes +.in -2.25i +.LP +The shell also contains a programming language, which has the following +operators and flow control statements: +.PP +.in +3.50i +.ta 2i 3.25i +.ti -3.25i +# Comment The rest of the line is ignored +.ti -3.25i += Assignment Set a shell variable +.ti -3.25i +&& Logical AND Execute second command only if first succeeds +.ti -3.25i +|| Logical OR Execute second command only if first fails +.ti -3.25i +(...) Group Execute enclosed commands before continuing +.in -3.50i +.PP +.in +2.25i +.ta 2i +.ti -2i +for For loop (for ... in ... do ... done) +.ti -2i +case Case statement ((case ... ) ... ;; ... esac) +.ti -2i +esac Case statement end +.ti -2i +while While loop (while ... do ... done) +.ti -2i +do Do/For/While loop start (do ... until ...) +.ti -2i +done For/While loop end +.ti -2i +if Conditional statement (if ... else ... elif ... fi) +.ti -2i +in For loop selection +.ti -2i +then Conditional statement start +.ti -2i +else Conditional statement alternative +.ti -2i +elif Conditional statement end +.ti -2i +until Do loop end +.ti -2i +fi Conditional statement end +.in -2.25i +.SH "SEE ALSO" +.BR echo (1), +.BR expr (1), +.BR pwd (1), +.BR true (1). diff --git a/bin/man/man1/sort.1 b/bin/man/man1/sort.1 new file mode 100755 index 00000000..ccc7c475 --- /dev/null +++ b/bin/man/man1/sort.1 @@ -0,0 +1,176 @@ +.TH SORT 1 +.SH NAME +sort \- sort or merge files +.SH SYNOPSIS +.B sort +[ +.if t \fB\-mubdf\&inrt\fIx\fR +.if n -mubdfinrt_________x +] +[ \fB+\fIpos1 \fR [ \fB\-\fIpos2 \fR] +] ... +[ +.B \-o +name ] [ +.B \-T +directory ] [ name ] ... +.SH DESCRIPTION +.I Sort +sorts +lines of all the named files together +and writes the result on +the standard output. +The name `\-' means +the standard input. +If no input files are named, the standard input is sorted. +.PP +The default sort key is an entire line. +Default ordering is +lexicographic by bytes in machine +collating sequence. +The ordering is affected globally by the following options, +one or more of which may appear. +.TP 5 +.B b +Ignore leading blanks (spaces and tabs) in field comparisons. +.TP 5 +.B d +`Dictionary' order: only letters, digits and blanks +are significant in comparisons. +.TP 5 +.B f +Fold upper case +letters onto lower case. +.TP 5 +.B i +Ignore characters outside the ASCII range 040-0176 +in nonnumeric comparisons. +.TP 5 +.B n +An initial numeric string, +consisting of optional blanks, optional minus sign, +and zero or more digits with optional decimal point, +is sorted by arithmetic value. +Option +.B n +implies option +.B b. +.TP 5 +.B r +Reverse the sense of comparisons. +.TP 5 +.BI t x +`Tab character' separating fields is +.IR x . +.PP +The notation +.BI + "pos1 " "\-\fIpos2" +restricts a sort key to a field beginning at +.I pos1 +and ending just before +.IR pos2 . +.I Pos1 +and +.I pos2 +each have the form +.IB m . n\fR, +optionally followed by one or more of the flags +.B bdf\&inr, +where +.I m +tells a number of fields to skip from the beginning of the line and +.I n +tells a number of characters to skip further. +If any flags are present they override all the global +ordering options for this key. +If the +.B b +option is in effect +.I n +is counted from the first nonblank in the field; +.B b +is attached independently to +.IR pos2 . +A missing +\&\fB.\fIn\fR +means .0; +a missing +.BI \- pos2 +means the end of the line. +Under the +.BI \-t x +option, fields are strings separated by +.IR x ; +otherwise fields are +nonempty nonblank strings separated by blanks. +.PP +When there are multiple sort keys, later keys +are compared only after all earlier keys +compare equal. +Lines that otherwise compare equal are ordered +with all bytes significant. +.PP +These option arguments are also understood: +.TP 5 +.B c +Check that the input file is sorted according to the ordering rules; +give no output unless the file is out of sort. +.TP 5 +.B m +Merge only, the input files are already sorted. +.TP 5 +.B o +The next argument is the name of an output file +to use instead of the standard output. +This file may be the same as one of the inputs. +.TP 5 +.B T +The next argument is the name of a directory in which temporary files +should be made. +.TP 5 +.B u +Suppress all but one in each +set of equal lines. +Ignored bytes +and bytes outside keys +do not participate in +this comparison. +.PP +.B Examples. +Print in alphabetical order all the unique spellings +in a list of words. +Capitalized words differ from uncapitalized. +.PP +.ti +8 +sort \-u +0f +0 list +.PP +Print the password file +.RI ( passwd (5)) +sorted by user id number (the 3rd colon-separated field). +.PP +.ti +8 +sort \-t: +2n /etc/passwd +.PP +Print the first instance of each month in an already sorted file +of (month day) entries. +The options +.B \-um +with just one input file make the choice of a +unique representative from a set of equal lines predictable. +.PP +.ti +8 +sort \-um +0 \-1 dates +.SH FILES +/usr/tmp/stm*, /tmp/*: first and second tries for +temporary files +.SH "SEE ALSO" +uniq(1), +comm(1), +rev(1), +join(1) +.SH DIAGNOSTICS +Comments and exits with nonzero status for various trouble +conditions and for disorder discovered under option +.BR \-c . +.SH BUGS +Very long lines are silently truncated. diff --git a/bin/man/man1/split.1 b/bin/man/man1/split.1 new file mode 100755 index 00000000..0e5c682f --- /dev/null +++ b/bin/man/man1/split.1 @@ -0,0 +1,35 @@ +.TH SPLIT 1 +.SH NAME +split \- split a file into pieces +.SH SYNOPSIS +.B split +[ +.B \-\fIn +] +[ file [ name ] ] +.SH DESCRIPTION +.I Split +reads +.I file +and writes +it in +.IR n -line +pieces +(default 1000), as many as necessary, +onto +a set of output files. The name of the first output +file is +.I name +with +.B aa +appended, and so on +lexicographically. +If no output name is given, +.B x +is default. +.PP +If no input file is given, or +if +.B \- +is given in its stead, +then the standard input file is used. diff --git a/bin/man/man1/su.1 b/bin/man/man1/su.1 new file mode 100755 index 00000000..14646aa8 --- /dev/null +++ b/bin/man/man1/su.1 @@ -0,0 +1,27 @@ +.TH SU 1 +.SH NAME +su \- substitute user id temporarily +.SH SYNOPSIS +.B su +[ userid ] +.SH DESCRIPTION +.I Su +demands the password of the specified +.I userid, +and if it is given, +changes to that +.I userid +and invokes the Shell +.IR sh (1) +without changing the current directory or the +user environment (see +.IR environ (5)). +The new user ID stays in force until the Shell exits. +.PP +If no +.I userid +is specified, `root' is assumed. +To remind the super-user of his responsibilities, +the Shell substitutes `#' for its usual prompt. +.SH "SEE ALSO" +sh(1) diff --git a/bin/man/man1/sum.1 b/bin/man/man1/sum.1 new file mode 100755 index 00000000..58182c30 --- /dev/null +++ b/bin/man/man1/sum.1 @@ -0,0 +1,19 @@ +.TH SUM 1 +.SH NAME +sum \- sum and count blocks in a file +.SH SYNOPSIS +.B sum +file +.SH DESCRIPTION +.I Sum +calculates and prints a 16-bit checksum for the named file, +and also prints the number of blocks in the file. +It is typically used to look for bad spots, or +to validate a file communicated over +some transmission line. +.SH "SEE ALSO" +wc(1) +.SH DIAGNOSTICS +`Read error' +is indistinuishable from end of file on +most devices; check the block count. diff --git a/bin/man/man1/tail.1 b/bin/man/man1/tail.1 new file mode 100755 index 00000000..82edce46 --- /dev/null +++ b/bin/man/man1/tail.1 @@ -0,0 +1,35 @@ +.TH TAIL 1 +.SH NAME +tail \- deliver the last part of a file +.SH SYNOPSIS +.B tail +.if t [ \(+-number[\fBlbc\fR] ] +.if n +_number[lbc___] +[ file ] +.SH DESCRIPTION +.I Tail +copies the named file to the standard output beginning +at a designated place. +If no file is named, the standard input is used. +.PP +Copying begins at distance +.I +number +from the beginning, or +.I \-number +from the end of the input. +.I Number +is counted in units of lines, blocks or characters, +according to the appended option +.B l, +.B b +or +.B c. +When no units are specified, counting is by lines. +.SH "SEE ALSO" +dd(1) +.SH BUGS +Tails relative to the end of the file +are treasured up in a buffer, and thus +are limited in length. +Various kinds of anomalous behavior may happen +with character special files. diff --git a/bin/man/man1/tar.1 b/bin/man/man1/tar.1 new file mode 100755 index 00000000..cae6821e --- /dev/null +++ b/bin/man/man1/tar.1 @@ -0,0 +1,167 @@ +.TH TAR 1 +.SH NAME +tar \- tape archiver +.SH SYNOPSIS +.B tar +[ key ] [ name ... ] +.SH DESCRIPTION +.I Tar +saves and restores files +on magtape. +Its actions are controlled by the +.I key +argument. +The +.I key +is a string of characters containing +at most one function letter and possibly +one or more function modifiers. +Other arguments to the command are file or directory +names specifying which files are to be dumped or restored. +In all cases, appearance of a directory name refers to +the files and (recursively) subdirectories of that directory. +.PP +The function portion of +the key is specified by one of the following letters: +.TP 8 +.B r +The named files +are written +on the end of the tape. +The +.B c +function implies this. +.TP 8 +.B x +The named files are extracted from the tape. +If the named file matches a directory whose contents +had been written onto the tape, this directory is (recursively) extracted. +The owner, modification time, and mode are restored (if possible). +If no file argument is given, the entire content of the +tape is extracted. +Note that if multiple entries specifying the same file +are on the tape, the last one overwrites +all earlier. +.TP 8 +.B t +The names of the specified files are listed each time they occur +on the tape. +If no file argument is given, +all of the names on the tape are listed. +.TP 8 +.B u +The named files are added to the tape if either they +are not already there or have +been modified since last put on the tape. +.TP 8 +.B c +Create a new tape; writing begins on the beginning +of the tape instead of after the last file. +This command implies +.B r. +.PP +The following characters may be used in addition to the letter +which selects the function desired. +.TP 10 +.B 0,...,7 +This +modifier selects the drive on which the tape is mounted. +The default is +.BR 1 . +.TP 10 +.B v +Normally +.I tar +does its work silently. +The +.B v +(verbose) +option causes it to type the name of each file it treats +preceded by the function letter. +With the +.B t +function, +.B v +gives more information about the +tape entries than just the name. +.TP 10 +.B w +causes +.I tar +to print the action to be taken followed by file name, then +wait for user confirmation. If a word beginning with `y' +is given, the action is performed. Any other input means +don't do it. +.TP 10 +.B f +causes +.I tar +to use the next argument as the name of the archive instead +of /dev/mt?. +If the name of the file is `\-', tar writes to +standard output or reads from standard input, whichever is +appropriate. Thus, +.I tar +can be used as the head or tail of a filter chain +.I Tar +can also be used to move hierarchies with the command +.ce 1 +cd fromdir; tar cf - . | (cd todir; tar xf -) +.TP 10 +.B b +causes +.I tar +to use the next argument as the blocking factor for tape +records. The default is 1, the maximum is 20. This option +should only be used with raw magnetic tape archives (See +.B f +above). +The block size is determined automatically when reading +tapes (key letters `x' and `t'). +.TP 10 +.B l +tells +.I tar +to complain if it cannot resolve all of the links +to the files dumped. If this is not specified, no +error messages are printed. +.TP 10 +.B m +tells +.I tar +to not restore the modification times. +The mod time +will be the time of extraction. +.PP +.SH FILES +/dev/mt? +.br +/tmp/tar* +.SH DIAGNOSTICS +Complaints about bad key characters and tape read/write errors. +.br +Complaints if enough memory is not available to hold +the link tables. +.SH BUGS +There is no way to ask for the +.IR n -th +occurrence of a file. +.br +Tape errors are handled ungracefully. +.br +The +.B u +option can be slow. +.br +The +.B b +option should not be used with archives that are +going to be updated. The current magtape driver cannot +backspace raw magtape. +If the archive is on a disk file the +.B b +option should not be used at all, as updating +an archive stored in this manner can destroy it. +.br +The current limit on file name length is +100 characters. diff --git a/bin/man/man1/tee.1 b/bin/man/man1/tee.1 new file mode 100755 index 00000000..609a4cb7 --- /dev/null +++ b/bin/man/man1/tee.1 @@ -0,0 +1,24 @@ +.TH TEE 1 +.SH NAME +tee \- pipe fitting +.SH SYNOPSIS +.B tee +[ +.B \-i +] [ +.B \-a +] +[ file ] ... +.SH DESCRIPTION +.I Tee +transcribes the standard input to the standard +output and makes copies in the +.I files. +Option +.B \-i +ignores interrupts; +option +.B \-a +causes the output to be appended to the +.I files +rather than overwriting them. diff --git a/bin/man/man1/test.1 b/bin/man/man1/test.1 new file mode 100755 index 00000000..c7440419 --- /dev/null +++ b/bin/man/man1/test.1 @@ -0,0 +1,115 @@ +.TH TEST 1 +.SH NAME +test \- condition command +.SH SYNOPSIS +.B test +expr +.SH DESCRIPTION +.I test +evaluates the expression +.IR expr , +and if its value is true then returns zero exit status; otherwise, a +non zero exit status is returned. +.I test +returns a non zero exit if there are no arguments. +.PP +The following primitives are used to construct +.IR expr . +.TP 9n +.BR \-r " file" +true if the file exists and is readable. +.TP +.BR \-w " file" +true if the file exists and is writable. +.TP +.BR \-f " file" +true if the file exists and is not a directory. +.TP +.BR \-d " file" +true if the file exists and is a directory. +.TP +.BR \-s " file" +true if the file exists and has a size greater than zero. +.TP +.BR \-t " [ fildes ]" +true if the open file whose file descriptor number is +.I fildes +(1 by default) +is associated with a terminal device. +.TP +.BR \-z " s1" +true if the length of string +.I s1 +is zero. +.TP +.BR \-n " s1" +true if the length of the string +.I s1 +is nonzero. +.TP +.RB s1 " = " s2 +true +if the strings +.I s1 +and +.I s2 +are equal. +.TP +.RB s1 " != " s2 +true +if the strings +.I s1 +and +.I s2 +are not equal. +.TP +s1 +true if +.I s1 +is not the null string. +.TP +.RB n1 " \-eq " n2 +true if the integers +.I n1 +and +.I n2 +are algebraically equal. +Any of the comparisons +.BR \-ne , +.BR \-gt , +.BR \-ge , +.BR \-lt , +or +.BR \-le +may be used in place of +.BR \-eq . +.PP +These primaries may be combined with the +following operators: +.TP +.B ! +unary negation operator +.TP +.B \-a +binary +.I and +operator +.TP +.B \-o +binary +.I or +operator +.TP +.BR "( " "expr" " )" +parentheses for grouping. +.PP +.B \-a +has higher precedence than +.B \-o. +Notice that all the operators and flags are separate +arguments to +.IR test . +Notice also that parentheses are meaningful +to the Shell and must be escaped. +.SH "SEE ALSO" +sh(1), find(1) diff --git a/bin/man/man1/time.1 b/bin/man/man1/time.1 new file mode 100755 index 00000000..45135e94 --- /dev/null +++ b/bin/man/man1/time.1 @@ -0,0 +1,26 @@ +.TH TIME 1 +.SH NAME +time \- time a command +.SH SYNOPSIS +.B time +command +.SH DESCRIPTION +The +given command is executed; after it is complete, +.I time +prints the elapsed time during the command, the time +spent in the system, and the time spent in execution +of the command. +Times are reported in seconds. +.PP +The execution time can depend on what kind of memory +the program happens to land in; +the user time in MOS is often half what it is in core. +.PP +The times are printed on the diagnostic output stream. +.SH BUGS +Elapsed time is accurate to the second, +while the CPU times are measured +to the 60th second. +Thus the sum of the CPU times can be up to a second larger +than the elapsed time. diff --git a/bin/man/man1/touch.1 b/bin/man/man1/touch.1 new file mode 100755 index 00000000..6ec9db25 --- /dev/null +++ b/bin/man/man1/touch.1 @@ -0,0 +1,22 @@ +.TH TOUCH 1 +.SH NAME +touch \- update date last modified of a file +.SH SYNOPSIS +.B touch +[ +.B \-c +] +file ... +.SH DESCRIPTION +.I Touch +attempts to set the modified date of each +.I file. +This is done by reading a character from the file +and writing it back. +.PP +If a +.I file +does not exist, +an attempt will be made to create it unless the +.B \-c +option is specified. diff --git a/bin/man/man1/tr.1 b/bin/man/man1/tr.1 new file mode 100755 index 00000000..58507829 --- /dev/null +++ b/bin/man/man1/tr.1 @@ -0,0 +1,67 @@ +.TH TR 1 +.SH NAME +tr \- translate characters +.SH SYNOPSIS +.B tr +[ +.B \-cds +] [ string1 [ string2 ] ] +.SH DESCRIPTION +.I Tr +copies the standard input to the standard output with +substitution or deletion of selected characters. +Input characters found in +.I string1 +are mapped into the corresponding characters of +.IR string2 . +When +.I string2 +is short it is padded to the length of +.I string1 +by duplicating its last character. +Any combination of the options +.B \-cds +may be used: +.B \-c +complements the set of characters in +.I string1 +with respect to the universe of characters +whose ASCII codes are 01 through 0377 octal; +.B \-d +deletes all input characters in +.I string1; +.B \-s +squeezes all strings of repeated output characters that are +in +.I string2 +to single characters. +.PP +In either string the notation +.IB a \- b +means a range of characters from +.I a +to +.I b +in increasing ASCII order. +The character +`\e' followed by 1, 2 or 3 octal digits stands for the +character whose ASCII code is given by those digits. +A `\e' followed by any other character stands +for that character. +.PP +The following example creates a list of all +the words in `file1' one per line in `file2', +where a word is taken to be a maximal string of alphabetics. +The second string is quoted +to protect `\e' from the Shell. +012 is the ASCII code for newline. +.IP +tr \-cs A\-Za\-z \'\e012\' file2 +.SH "SEE ALSO" +ed(1), ascii(7) +.SH BUGS +Won't handle ASCII NUL in +.I string1 +or +.I string2; +always deletes NUL from input. diff --git a/bin/man/man1/troff.1 b/bin/man/man1/troff.1 new file mode 100755 index 00000000..ab83e329 --- /dev/null +++ b/bin/man/man1/troff.1 @@ -0,0 +1,212 @@ +.TH TROFF 1 +.SH NAME +troff, nroff \- text formatting and typesetting +.SH SYNOPSIS +.B troff +[ option ] ... +[ file ] ... +.PP +.B nroff +[ option ] ... +[ file ] ... +.SH DESCRIPTION +.I Troff +formats text in the named +.I files +for +printing on a Graphic Systems C/A/T phototypesetter; +.I nroff +for typewriter-like devices. +Their capabilities are described in the +.I Nroff/Troff user's manual. +.PP +If no +.I file +argument is present, the standard input is read. +An argument consisting of a single minus +.RB ( \- ) +is taken to be +a file name corresponding to the standard input. +The options, which may appear in any order so long as they appear +before the files, are: +.TP "\w'\f3\-m\f1name 'u" +.BI \-o list +Print only pages whose page numbers appear in +the comma-separated +.I list +of numbers and ranges. +A range +.IB N \- M +means pages +.I N +through +.IR M ; +an initial +.I \-N +means +from the beginning to page +.IR N ; +and a final +.IR N \- +means +from +.I N +to the end. +.TP +.BI \-n N +Number first generated page +.IR N . +.TP +.BI \-s N +Stop every +.I N +pages. +.I Nroff +will halt prior to every +.I N +pages (default +.IR N =1) +to allow paper loading or +changing, and will resume upon receipt of a newline. +.I Troff +will stop the phototypesetter every +.I N +pages, +produce a trailer to allow changing cassettes, +and resume when the typesetter's start button is pressed. +.TP +.BI \-m name +Prepend the macro file +.BI /usr/lib/tmac/tmac. name +to the input +.IR files . +.TP +.BI \-r aN +Set register +.I a +(one-character) to +.IR N . +.TP +.B \-i +Read standard input after the input files are exhausted. +.TP +.B \-q +Invoke the simultaneous input-output mode of the +.B rd +request. +.HP +.bd I 3 +.I Nroff only +.br +.bd I +.TP +.BI \-T name +Prepare output for specified terminal. +Known +.I names +are +.B 37 +for the (default) +Teletype Corporation Model 37 terminal, +.B tn300 +for the GE TermiNet\ 300 (or any terminal without half-line +capability), +.B 300S +for the \s-1DASI\s+1-300S, +.B 300 +for the \s-1DASI\s+1-300, +and +.B 450 +for the \s-1DASI\s+1-450 +(Diablo Hyterm). +.TP +.B \-e +Produce equally-spaced words in adjusted +lines, using full terminal resolution. +.TP +.B \-h +Use output tabs during horizontal spacing +to speed output and reduce output character count. +Tab settings are assumed to be every +8 nominal character widths. +.HP +.bd I 3 +.I Troff only +.br +.bd I +.TP +.B \-t +Direct output to the standard output instead +of the phototypesetter. +.TP +.B \-f +Refrain from feeding out paper and stopping +phototypesetter at the end of the run. +.TP +.B \-w +Wait until phototypesetter is available, if +currently busy. +.TP +.B \-b +Report whether the phototypesetter +is busy or available. +No text processing is done. +.TP +.B \-a +Send a printable ASCII approximation +of the results to the standard output. +.TP +.BR \-p N +Print all characters in point size +.I N +while retaining all prescribed spacings and motions, +to reduce phototypesetter elasped time. +.TP +.B \-g +Prepare output for a GCOS +phototypesetter and direct it to the standard output +(see +.IR gcat (1)). +.PP +If the file +.I /usr/adm/tracct +is writable, +.I troff +keeps phototypesetter accounting records there. +The integrity of that file may be secured by making +.I troff +a `set user-id' program. +.SH FILES +.ta \w'/usr/lib/tmac/tmac.* 'u +/usr/lib/suftab suffix hyphenation tables +.br +/tmp/ta* temporary file +.br +/usr/lib/tmac/tmac.* standard macro files +.br +/usr/lib/term/* terminal driving tables for +.I nroff +.br +/usr/lib/font/* font width tables for +.I troff +.br +/dev/cat phototypesetter +.br +/usr/adm/tracct accounting statistics for /dev/cat +.SH "SEE ALSO" +J. F. Ossanna, +.I Nroff/Troff user's manual +.br +B. W. Kernighan, +.I +A TROFF Tutorial +.br +eqn(1), tbl(1) +.br +col(1), tk(1) +.RI ( nroff +only) +.br +tc(1), gcat(1) +.RI ( troff +only) diff --git a/bin/man/man1/true.1 b/bin/man/man1/true.1 new file mode 100755 index 00000000..cf415714 --- /dev/null +++ b/bin/man/man1/true.1 @@ -0,0 +1,30 @@ +.TH TRUE 1 +.SH NAME +true, false \- provide truth values +.SH SYNOPSIS +.B true +.PP +.B false +.SH DESCRIPTION +.I True +does nothing, successfully. +.I False +does nothing, unsuccessfully. +They are typically used in input to +.IR sh (1) +such as: +.PP + while true +.br + do +.br + command +.br + done +.SH "SEE ALSO" +sh(1) +.SH DIAGNOSTICS +.I True +has exit status zero, +.I false +nonzero. diff --git a/bin/man/man1/uniq.1 b/bin/man/man1/uniq.1 new file mode 100755 index 00000000..ad5439a8 --- /dev/null +++ b/bin/man/man1/uniq.1 @@ -0,0 +1,72 @@ +.TH UNIQ 1 +.SH NAME +uniq \- report repeated lines in a file +.SH SYNOPSIS +.B uniq +[ +.B \-udc +[ +.BR + n +] [ +.BR \- n +] +] [ input [ output ] ] +.SH DESCRIPTION +.I Uniq +reads the input +file comparing adjacent lines. +In the normal case, the second and succeeding copies +of repeated lines are +removed; the remainder is written on the output file. +Note that repeated lines must be adjacent +in order to be found; +see +.IR sort (1). +If the +.B \-u +flag is used, +just the lines that are not repeated +in the original file are output. +The +.B \-d +option specifies that +one copy of just the repeated lines is to +be written. +The normal mode output is the union of the +.B \-u +and +.B \-d +mode outputs. +.PP +The +.B \-c +option supersedes +.B \-u +and +.B \-d +and generates +an output report in default style +but with each line preceded by a count of the +number of times it occurred. +.PP +The +.I n +arguments specify skipping an initial portion of each line +in the comparison: +.TP 8 +.BI \- n +The first +.IR n +fields +together with any blanks before each are ignored. +A field is defined as a string of non-space, non-tab characters +separated by tabs and spaces from its neighbors. +.TP 8 +.BI + n +The first +.IR n +characters are ignored. +Fields are skipped before characters. +.PP +.SH "SEE ALSO" +sort(1), comm(1) diff --git a/bin/man/man1/wc.1 b/bin/man/man1/wc.1 new file mode 100755 index 00000000..7363fcf9 --- /dev/null +++ b/bin/man/man1/wc.1 @@ -0,0 +1,23 @@ +.TH WC 1 +.SH NAME +wc \- word count +.SH SYNOPSIS +.B wc +[ +.B \-lwc +] +[ name ... ] +.SH DESCRIPTION +.I Wc +counts lines, words and characters in the named files, +or in the standard input if no name appears. +A word is a maximal string of characters +delimited by spaces, tabs or newlines. +.PP +If the optional argument is present, +just the specified counts (lines, words or characters) +are selected by the letters +.BR l , +.BR w , +or +.BR c . diff --git a/bin/man/mkwhatis.bat b/bin/man/mkwhatis.bat new file mode 100755 index 00000000..5f4c41d2 --- /dev/null +++ b/bin/man/mkwhatis.bat @@ -0,0 +1,32 @@ +#!/bin/sh - +# +# Copyright (c) 1980 Regents of the University of California. +# All rights reserved. The Berkeley software License Agreement +# specifies the terms and conditions for redistribution. +# +# @(#)makewhatis.sh 5.3 (Berkeley) 3/29/86 +# +trap "rm -f /tmp/whatis$$; exit 1" 1 2 13 15 +MANDIR=${1-/usr/man} +TMPFILE=/tmp/whatis$$ +rm -f $TMPFILE +cp /dev/null $TMPFILE +if test ! -d $MANDIR ; then exit 0 ; fi +cd $MANDIR +top=`pwd` +for i in cat* +do + if [ -d $i ] ; then + cd $i + for file in `find . -type f -name '*.0' -print` + do + sed -n -f /usr/man/makewhatis.sed $file + done >> $TMPFILE + cd $top + fi +done +rm -f $top/whatis +sort -u $TMPFILE > $top/whatis +chmod 664 whatis >/dev/null 2>&1 +rm -f $TMPFILE +exit 0 diff --git a/bin/man/mkwhatis.sed b/bin/man/mkwhatis.sed new file mode 100755 index 00000000..13df2f49 --- /dev/null +++ b/bin/man/mkwhatis.sed @@ -0,0 +1,45 @@ +#!/bin/sh - +# +# Copyright (c) 1988 Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that the above copyright notice and this paragraph are +# duplicated in all such forms and that any documentation, +# advertising materials, and other materials related to such +# distribution and use acknowledge that the software was developed +# by the University of California, Berkeley. The name of the +# University may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +# +# @(#)makewhatis.sed 5.3 (Berkeley) 7/9/88 +# +/(\([a-zA-Z0-9]*\).*UNIX Programmer's Manual/ { + s;.*(\([a-zA-Z0-9]*\).*UNIX.*;\1; + h + d +} +/^NAME/!d + +:name + s;.*;; + N + s;\n;; + # some twits underline the command name + s;_;;g + /^[^ ]/b print + H + b name + +:print + x + s;\n;;g + /-/!d + s;\([a-z][A-z]\)-[ ][ ]*;\1; + s;\([a-zA-Z0-9,]\)[ ][ ]*;\1 ;g + s;[^a-zA-Z0-9]*\([a-zA-Z0-9]*\)[^a-zA-Z0-9]*\(.*\) - \(.*\);\2 (\1) - \3; + p + d diff --git a/bin/man/mkwhatis.sh b/bin/man/mkwhatis.sh new file mode 100755 index 00000000..5f4c41d2 --- /dev/null +++ b/bin/man/mkwhatis.sh @@ -0,0 +1,32 @@ +#!/bin/sh - +# +# Copyright (c) 1980 Regents of the University of California. +# All rights reserved. The Berkeley software License Agreement +# specifies the terms and conditions for redistribution. +# +# @(#)makewhatis.sh 5.3 (Berkeley) 3/29/86 +# +trap "rm -f /tmp/whatis$$; exit 1" 1 2 13 15 +MANDIR=${1-/usr/man} +TMPFILE=/tmp/whatis$$ +rm -f $TMPFILE +cp /dev/null $TMPFILE +if test ! -d $MANDIR ; then exit 0 ; fi +cd $MANDIR +top=`pwd` +for i in cat* +do + if [ -d $i ] ; then + cd $i + for file in `find . -type f -name '*.0' -print` + do + sed -n -f /usr/man/makewhatis.sed $file + done >> $TMPFILE + cd $top + fi +done +rm -f $top/whatis +sort -u $TMPFILE > $top/whatis +chmod 664 whatis >/dev/null 2>&1 +rm -f $TMPFILE +exit 0 diff --git a/bin/man/sh.1 b/bin/man/sh.1 new file mode 100755 index 00000000..1cb61240 --- /dev/null +++ b/bin/man/sh.1 @@ -0,0 +1,261 @@ +.TH SH 1 +.SH NAME +sh, ., break, case, cd, continue, eval, exec, exit, export, for, if, read, readonly, set, shift, trap, umask, wait, while \- shell +.SH SYNOPSIS +\fBsh\fR [\fB\-eiknqstvxu\fR] [\fB\-c \fIstr\fR] \fB[\fIfile\fR]\fR +.br +.de FL +.TP +\\fB\\$1\\fR +\\$2 +.. +.de EX +.TP 20 +\\fB\\$1\\fR +# \\$2 +.. +.SH OPTIONS +.FL "\-c" "Execute the commands in \fIstr\fR" +.FL "\-e" "Quit on error" +.FL "\-i" "Interactive mode; ignore QUIT, TERMINATE, INTERRUPT" +.FL "\-k" "Look for name=value everywhere on command line" +.FL "\-n" "Do not execute commands" +.FL "\-q" "Change qflag from sig_ign to sig_del" +.FL "\-s" "Read commands from standard input" +.FL "\-t" "Exit after reading and executing one command" +.FL "\-v" "Echo input lines as they are read" +.FL "\-x" "Trace" +.FL "\-u" "Unset variables" +.SH EXAMPLES +.EX "sh script" "Run a shell script" +.SH DESCRIPTION +.PP +.I Sh +is the shell, which forms the user's main interface with the system. +On startup, the shell reads /etc/profile and $HOME/.profile, if they exist, +and executes any commands they contain. The Minix shell has most of the +features of the V7 (Bourne) shell, including redirection of input and output, +pipes, magic characters, background processes, and shell scripts. A brief +summary follows, but whole books have been written on shell programming alone. +.LP +Some of the more common notations are: +.PP +.in +2.45i +.ta 2i 2.2i +.ti -2.2i +date # Regular command +.ti -2.2i +sort file2 # Redirect \fIstdin\fR and \fIstdout\fR +.ti -2.2i +cc file.c 2>error # Redirect \fIstderr\fR +.ti -2.2i +a.out >f 2>&1 # Combine standard output and standard error +.ti -2.2i +sort >file2 # Append output to \fIfile2\fR +.ti -2.2i +sort file2 & # Background job +.ti -2.2i +(ls \-l; a.out) & # Run two background commands sequentially +.ti -2.2i +sort with no command name, modify shell I/O +.ti -2i +exit [n] exit a shell program, with exit value n +.ti -2i +export [var] export var to shell's children; list exported variables +.ti -2i +pwd print the name of the current working directory +.ti -2i +read var read a line from stdin and assign to var +.ti -2i +readonly [var] make var readonly; list readonly variables +.ti -2i +set -f set shell flag (+f unsets flag) +.ti -2i +set str set positional parameter to str +.ti -2i +set show the current shell variables +.ti -2i +shift reassign positional parameters (except ${0}) one left +.ti -2i +times print accumulated user and system times for processes +.ti -2i +trap arg sigs trap signals sigs and run arg on receipt +.ti -2i +trap list trapped signals +.ti -2i +umask [n] set the user file creation mask; show the current umask +.ti -2i +wait [n] wait for process pid n; wait for all processes +.in -2.25i +.LP +The shell also contains a programming language, which has the following +operators and flow control statements: +.PP +.in +3.50i +.ta 2i 3.25i +.ti -3.25i +# Comment The rest of the line is ignored +.ti -3.25i += Assignment Set a shell variable +.ti -3.25i +&& Logical AND Execute second command only if first succeeds +.ti -3.25i +|| Logical OR Execute second command only if first fails +.ti -3.25i +(...) Group Execute enclosed commands before continuing +.in -3.50i +.PP +.in +2.25i +.ta 2i +.ti -2i +for For loop (for ... in ... do ... done) +.ti -2i +case Case statement ((case ... ) ... ;; ... esac) +.ti -2i +esac Case statement end +.ti -2i +while While loop (while ... do ... done) +.ti -2i +do Do/For/While loop start (do ... until ...) +.ti -2i +done For/While loop end +.ti -2i +if Conditional statement (if ... else ... elif ... fi) +.ti -2i +in For loop selection +.ti -2i +then Conditional statement start +.ti -2i +else Conditional statement alternative +.ti -2i +elif Conditional statement end +.ti -2i +until Do loop end +.ti -2i +fi Conditional statement end +.in -2.25i +.SH "SEE ALSO" +.BR echo (1), +.BR expr (1), +.BR pwd (1), +.BR true (1). diff --git a/bin/mkramfs.sh b/bin/mkramfs.sh new file mode 100755 index 00000000..6d037695 --- /dev/null +++ b/bin/mkramfs.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# fixme: must be <= 256 bytes + +cd /boot/skel +mkfs -l -q -v -y /dev/hd0 1536 30 +mount /dev/hd0 /mnt +cp -r -v * /mnt +align -s -v /mnt/bin/* +cp -v /boot/kernel.bin /mnt/boot +align -v /mnt/boot/kernel.bin +umount /dev/hd0 +reboot + diff --git a/bin/mtab.txt b/bin/mtab.txt new file mode 100755 index 00000000..de99268e --- /dev/null +++ b/bin/mtab.txt @@ -0,0 +1,2 @@ +/dev/hd0 / rw +/dev/hd1 /usr rw diff --git a/bin/n.bat b/bin/n.bat new file mode 100755 index 00000000..e9d5d73b --- /dev/null +++ b/bin/n.bat @@ -0,0 +1,18 @@ +del uzidisk.dat +touch uzidisk.dat +@if errorlevel 1 goto failure +rem mkfs -b -f -q -v -y uzidisk.dat 8192 163 +mkfs -l -f -q -v -y uzidisk.dat 8192 163 +@if errorlevel 1 goto failure +ucp < n.ucp +@if errorlevel 1 goto failure +fsck -y uzidisk.dat +@if errorlevel 1 goto failure +copy uzidisk.dat e:\ + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/bin/n.ucp b/bin/n.ucp new file mode 100755 index 00000000..f9ef3b43 --- /dev/null +++ b/bin/n.ucp @@ -0,0 +1,470 @@ +root b: +cd / +mkdir bin +mkdir boot +mkdir dev +mkdir etc +mkdir home +mkdir lib +mkdir man +mkdir mnt +mkdir root +mkdir tmp +mkdir var +cd /bin +bget large\adduser adduser +chmod 755 adduser +bget large\align align +chmod 755 align +bget large\apropos apropos +chmod 755 apropos +bget large\banner banner +chmod 755 banner +bget large\basename basename +chmod 755 basename +bget large\bd bd +chmod 755 bd +bget large\cal cal +chmod 755 cal +bget large\cat cat +chmod 755 cat +bget large\catman catman +chmod 755 catman +bget large\cdiff cdiff +chmod 755 cdiff +bget large\cgrep cgrep +chmod 755 cgrep +bget large\chgrp chgrp +chmod 755 chgrp +bget large\chmod chmod +chmod 755 chmod +bget large\chown chown +chmod 755 chown +bget large\cksum cksum +chmod 755 cksum +bget large\cmp cmp +chmod 755 cmp +bget large\cp cp +chmod 755 cp +bget large\cr cr +chmod 755 cr +bget large\crc crc +chmod 755 crc +bget large\cron cron +chmod 755 cron +bget large\date date +chmod 755 date +bget large\dd dd +chmod 755 dd +bget large\df df +chmod 755 df +bget large\dhry dhry +chmod 755 dhry +bget large\diff diff +chmod 755 diff +bget large\dirname dirname +chmod 755 dirname +bget large\diskusag diskusag +chmod 755 diskusag +bget large\dtree dtree +chmod 755 dtree +bget large\du du +chmod 755 du +bget large\echo echo +chmod 755 echo +bget large\ed ed +chmod 755 ed +bget large\expr expr +chmod 755 expr +bget large\false false +chmod 755 false +bget large\fgrep fgrep +chmod 755 fgrep +bget large\file file +chmod 755 file +bget large\find find +chmod 755 find +bget large\fld fld +chmod 755 fld +bget large\fortune fortune +chmod 755 fortune +bget large\fsck fsck +chmod 755 fsck +bget large\grep grep +chmod 755 grep +bget large\gres gres +chmod 755 gres +bget large\head head +chmod 755 head +bget large\id id +chmod 755 id +bget large\init init +chmod 755 init +bget large\inodes inodes +chmod 755 inodes +bget large\kill kill +chmod 755 kill +sln cp ln +bget large\login login +chmod 755 login +bget large\lpd lpd +chmod 755 lpd +bget large\lpr lpr +chmod 755 lpr +bget large\ls ls +chmod 755 ls +get man\mkwhatis.sh makewhatis +chmod 755 makewhatis +bget large\man man +chmod 755 man +bget large\mkdir mkdir +chmod 755 mkdir +bget large\mkfs mkfs +chmod 755 mkfs +bget large\mknod mknod +chmod 755 mknod +bget large\more more +chmod 755 more +bget large\mount mount +chmod 755 mount +sln cp mv +bget large\ncheck ncheck +chmod 755 ncheck +bget large\od od +chmod 755 od +bget large\passwd passwd +chmod 755 passwd +bget large\pathchk pathchk +chmod 755 pathchk +bget large\pr pr +chmod 755 pr +bget large\printenv printenv +chmod 755 printenv +bget large\ps ps +chmod 755 ps +bget large\pwd pwd +chmod 755 pwd +bget large\readall readall +chmod 755 readall +bget large\reboot reboot +chmod 755 reboot +bget large\renice renice +chmod 755 renice +bget large\rm rm +chmod 755 rm +bget large\rmdir rmdir +chmod 755 rmdir +bget large\roff roff +chmod 755 roff +bget large\sash sash +chmod 755 sash +bget large\setclock setclock +chmod 755 setclock +sln sash sh +bget large\sort sort +chmod 755 sort +bget large\split split +chmod 755 split +bget large\su su +chmod 755 su +bget large\sum sum +chmod 755 sum +bget large\sync sync +chmod 755 sync +bget large\tail tail +chmod 755 tail +bget large\tar tar +chmod 755 tar +bget large\tee tee +chmod 755 tee +bget large\ter ter +chmod 755 ter +bget large\termcap termcap +chmod 755 termcap +bget large\test test +chmod 755 test +bget large\tget tget +chmod 755 tget +bget large\time time +chmod 755 time +bget large\top top +chmod 755 top +bget large\touch touch +chmod 755 touch +bget large\tr tr +chmod 755 tr +bget large\true true +chmod 755 true +bget large\ualign ualign +chmod 755 ualign +bget large\umount umount +chmod 755 umount +bget large\uniq uniq +chmod 755 uniq +bget large\uudecode uudecode +chmod 755 uudecode +bget large\uuencode uuencode +chmod 755 uuencode +bget large\wc wc +chmod 755 wc +bget large\which which +chmod 755 which +bget large\whoami whoami +chmod 755 whoami +bget large\yes yes +chmod 755 yes +cd /boot +get mkramfs.sh +chmod 755 mkramfs.sh +bget kernel.bin +bget boot.bin +bget checksum +mkdir skel +cd /boot/skel +mkdir bin +mkdir boot +mkdir dev +mkdir etc +mkdir home +mkdir lib +mkdir mnt +mkdir root +mkdir tmp +mkdir usr +mkdir var +cd /boot/skel/bin +bget banked\align align +chmod 755 align +bget banked\cat cat +chmod 755 cat +bget banked\cp cp +chmod 755 cp +bget banked\init init +chmod 755 init +sln cp ln +bget banked\login login +chmod 755 login +bget banked\ls ls +chmod 755 ls +bget banked\mkdir mkdir +chmod 755 mkdir +bget banked\more more +chmod 755 more +bget banked\mount mount +chmod 755 mount +bget banked\msh msh +chmod 755 msh +sln cp mv +bget banked\nroff nroff +chmod 755 nroff +bget banked\rm rm +chmod 755 rm +bget banked\rmdir rmdir +chmod 755 rmdir +sln msh sh +bget banked\ualign ualign +chmod 755 ualign +bget banked\umount umount +chmod 755 umount +cd /boot/skel/boot +get newkrnl.sh +chmod 755 newkrnl.sh +cd /boot/skel/dev +mknod hd0 60666 0 0 +mknod hd1 60666 0 1 +mknod null 20644 1 0 +mknod zero 20644 2 0 +mknod kmem 20644 3 0 +mknod tty 20644 4 0 +mknod tty0 20644 4 1 +mknod tty1 20644 4 2 +mknod tty2 20644 4 3 +mknod tty3 20644 4 4 +mknod scale 20644 4 5 +mknod lcd0 20644 4 6 +mknod lcd1 20644 4 7 +mknod lpr0 20644 4 9 +sln tty0 cognitive +sln tty1 barcode +sln tty1 console +sln tty2 atmodem +sln tty3 apilan +sln lpr0 printer +cd /boot/skel/etc +get group.txt group +get mtab.txt mtab +get passwd.txt passwd +cd /boot/skel/lib +get liberror.txt +cd /dev +mknod hd0 60666 0 0 +mknod hd1 60666 0 1 +mknod null 20644 1 0 +mknod zero 20644 2 0 +mknod kmem 20644 3 0 +mknod tty 20644 4 0 +mknod tty0 20644 4 1 +mknod tty1 20644 4 2 +mknod tty2 20644 4 3 +mknod tty3 20644 4 4 +mknod scale 20644 4 5 +mknod lcd0 20644 4 6 +mknod lcd1 20644 4 7 +mknod lpr0 20644 4 9 +sln tty0 cognitive +sln tty1 barcode +sln tty1 console +sln tty2 atmodem +sln tty3 apilan +sln lpr0 printer +cd /etc +get group.txt group +get inittab.txt inittab +get passwd.txt passwd +cd /lib +get liberror.txt +get fortune.dat +mkdir term +mkdir tmac +cd /lib/term +bget term\tab37 tab37 +cd /lib/tmac +get tmac\tmac.an tmac.an +cd /man +mkdir man1 +mkdir cat1 +get man\mkwhatis.sed makewhatis.sed +cd /man/man1 +get man\man1\basename.1 basename.1 +get man\man1\cal.1 cal.1 +get man\man1\cat.1 cat.1 +get man\man1\chmod.1 chmod.1 +get man\man1\chown.1 chown.1 +get man\man1\cmp.1 cmp.1 +get man\man1\cp.1 cp.1 +get man\man1\date.1 date.1 +get man\man1\dd.1 dd.1 +get man\man1\diff.1 diff.1 +get man\man1\du.1 du.1 +get man\man1\echo.1 echo.1 +get man\man1\ed.1 ed.1 +get man\man1\expr.1 expr.1 +get man\man1\file.1 file.1 +get man\man1\find.1 find.1 +get man\man1\grep.1 grep.1 +get man\man1\kill.1 kill.1 +get man\man1\ln.1 ln.1 +get man\man1\login.1 login.1 +get man\man1\ls.1 ls.1 +get man\man1\man.1 man.1 +get man\man1\mkdir.1 mkdir.1 +get man\man1\mv.1 mv.1 +get man\man1\od.1 od.1 +get man\man1\passwd.1 passwd.1 +get man\man1\pr.1 pr.1 +get man\man1\ps.1 ps.1 +get man\man1\pwd.1 pwd.1 +get man\man1\rm.1 rm.1 +get man\man1\roff.1 roff.1 +get man\man1\sh.1 sh.1 +get man\man1\sort.1 sort.1 +get man\man1\split.1 split.1 +get man\man1\su.1 su.1 +get man\man1\sum.1 sum.1 +get man\man1\tail.1 tail.1 +get man\man1\tar.1 tar.1 +get man\man1\tee.1 tee.1 +get man\man1\test.1 test.1 +get man\man1\time.1 time.1 +get man\man1\touch.1 touch.1 +get man\man1\tr.1 tr.1 +get man\man1\troff.1 troff.1 +get man\man1\true.1 true.1 +get man\man1\uniq.1 uniq.1 +get man\man1\wc.1 wc.1 +cd /man/cat1 +get man\cat1\basename.0 basename.0 +get man\cat1\cal.0 cal.0 +get man\cat1\cat.0 cat.0 +get man\cat1\chmod.0 chmod.0 +get man\cat1\chown.0 chown.0 +get man\cat1\cmp.0 cmp.0 +get man\cat1\cp.0 cp.0 +get man\cat1\date.0 date.0 +get man\cat1\dd.0 dd.0 +get man\cat1\diff.0 diff.0 +get man\cat1\du.0 du.0 +get man\cat1\echo.0 echo.0 +get man\cat1\ed.0 ed.0 +get man\cat1\expr.0 expr.0 +get man\cat1\file.0 file.0 +get man\cat1\find.0 find.0 +get man\cat1\grep.0 grep.0 +get man\cat1\kill.0 kill.0 +get man\cat1\ln.0 ln.0 +get man\cat1\login.0 login.0 +get man\cat1\ls.0 ls.0 +get man\cat1\man.0 man.0 +get man\cat1\mkdir.0 mkdir.0 +get man\cat1\mv.0 mv.0 +get man\cat1\od.0 od.0 +get man\cat1\passwd.0 passwd.0 +get man\cat1\pr.0 pr.0 +get man\cat1\ps.0 ps.0 +get man\cat1\pwd.0 pwd.0 +get man\cat1\rm.0 rm.0 +get man\cat1\roff.0 roff.0 +get man\cat1\sh.0 sh.0 +get man\cat1\sort.0 sort.0 +get man\cat1\split.0 split.0 +get man\cat1\su.0 su.0 +get man\cat1\sum.0 sum.0 +get man\cat1\tail.0 tail.0 +get man\cat1\tar.0 tar.0 +get man\cat1\tee.0 tee.0 +get man\cat1\test.0 test.0 +get man\cat1\time.0 time.0 +get man\cat1\touch.0 touch.0 +get man\cat1\tr.0 tr.0 +get man\cat1\troff.0 troff.0 +get man\cat1\true.0 true.0 +get man\cat1\uniq.0 uniq.0 +get man\cat1\wc.0 wc.0 +cd /root +get chset.sh +chmod 755 chset.sh +get demos.sh +chmod 755 demos.sh +bget demos\ned01-1 ned01-1 +bget demos\ned01-2 ned01-2 +bget demos\ned01-3 ned01-3 +bget demos\ned01-4 ned01-4 +bget demos\ned02-1 ned02-1 +bget demos\ned02-2 ned02-2 +bget demos\ned02-3 ned02-3 +bget demos\ned02-4 ned02-4 +bget demos\ned02-5 ned02-5 +bget demos\ned02-6 ned02-6 +bget demos\ned03-1 ned03-1 +bget demos\ned03-2 ned03-2 +bget demos\ned04-1 ned04-1 +bget demos\ned04-2 ned04-2 +bget demos\ned04-3 ned04-3 +bget demos\ned05-1 ned05-1 +bget demos\ned05-2 ned05-2 +bget demos\ned05-3 ned05-3 +bget demos\ned05-4 ned05-4 +bget demos\ned05-5 ned05-5 +bget demos\ned06-1 ned06-1 +bget demos\ned06-2 ned06-2 +bget demos\ned06-3 ned06-3 +bget demos\ned06-4 ned06-4 +bget demos\ned06-5 ned06-5 +bget demos\ned06-6 ned06-6 +bget chset\ned-chs ned-chs +bget chset\std-chs std-chs +bget chset\lpr-chs lpr-chs +bget demos\lpr-rec lpr-rec +bget chset\cog-chs cog-chs +bget demos\cog-lab cog-lab +exit diff --git a/bin/newkrnl.sh b/bin/newkrnl.sh new file mode 100755 index 00000000..af07773c --- /dev/null +++ b/bin/newkrnl.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# fixme: must be <= 256 bytes + +cd /boot +cp -v /usr/boot/kernel.bin kernel.tmp +align -v kernel.tmp +mv -v kernel.tmp kernel.bin +cp -v /usr/boot/boot.bin /dev/hd0 +reboot + diff --git a/bin/passwd.txt b/bin/passwd.txt new file mode 100755 index 00000000..44938c47 --- /dev/null +++ b/bin/passwd.txt @@ -0,0 +1,2 @@ +root::0:0::/root: +bin:!:1:1::/bin: diff --git a/bin/term/tab37 b/bin/term/tab37 new file mode 100755 index 0000000000000000000000000000000000000000..9df5607f8d619d6ec097c60dc2ea3c286ae4b2e5 GIT binary patch literal 1288 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�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

NJ*{W*a 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

}|pj9anlF>{qs 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≶NQ^dUZ}*3FgB(|Qd!6U$ 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 z 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

NRSQ zdab%q?NzT+uUBtS`_xTpzxuzmea`UxIwerZ38Wo;lDRZsLSLXY(4DG=T5Dh}Kw~PG zrP!4axfV`!V{Jh)ru&u4hV`2c0r6TxZDA~%>3vwN$5q!@E0A^@;j)=j3VlKm9S3@v zBI_-%#Ka$B5DzGDfC+r0LRv69#+6{QKjC-cBBMmd{fdf_Q&?Y^B}Z8p%oo}0IkklV z%h6p78^v7MDDXRJ7J3)&DI^x}F%#DvHJ9`rGneF!nf1jN47z6*HX7kVo(1SOll)f9 zrI=#Q=C>n|(Eu-&OU2$oLMVkx`BEO;Um;QGeGa2izLebQ&@vj*7W1XvUUYf&B-HW< ziM@#K92mub37ne1qsfu{NN*qERIcKZQXe|ok-(#c`eFjKi(xY`vG$%dG3=E}y*x|G z_PEOtsl~{`7_3QV5|Ki0p>(u(tnj4ytWn0UjWT=DIA$C(k5ZCiq1PfZDLoHNF4;KW z#U;fhy}fqH)QkouG0K%v=o6>BJds+wa7iSf-{e>(nGB;@V0;@1jL!DgE4VNm)iZ0z zwEXpW=1StF*>mMW{~2>@bGecF-oxDwEF9_GaC7+4L{16ZK~{am@{`ZD@`BA=Y3~e4bbV zQvstNgM1$fO*ht(Cfrzg1e^g6H^VXs?ta{OJtmZ};D`CXQUHo+p}Y?8QiigY%O>6E zNyct)NvW~DLIS5_)ig~NSzK|>kcbkFf&*|B23KKl#r=q5dECT3;S!q@OE2wld)+8Q3@GvrMt?09?vF*=ODTa7X$eF6)+xka7X}P+qvh zMj!a^gA(>ZvQ+hbtb}`_Y$|>$U(f^mM7MkfcDfi7?=Zq)q^aCg3lncn4=T6`s+fnC zpcUc9v1mhPz3 zUz^K{^e4KO9!;V4#3NQsnN+ZDE+$)KQwhIPkz+-(k`oDj+hi)_$ek>CEBwc`o=W*A zmc7y$k)~HVNNNTBTtm4m&8cKriG!?7qD%NEXg#R8|4BED94HrlgL@O*sTnrQCiL5c zzMBeeq5P!D@;93kB}JT7?un(IsvCBq8+Hi{iz%kHFq9uDkDfZ`j0sgVu8C}dR{oX! z6ZNs;pEvgm-YHG6BUso~kLTP#0Xbkv&_Hrnco3)LAjwLg#!RxnU&R6)-gjFS zhr(d2InLt4GU1`mu2@9HA`0@X#4Y5;O2}L&fekDNVro&6%Gkk4Oj1W$Ho*8OiiwU2 zqXA=79?naE3YDbjN}(V?0ki886{=tts=y1y%fqdulr?dJ0R?opMSS*ii}F}Hl{JpS zQ*et@;q=DI^V~?71yyau{gDO=G;>`P#($<0)&NZ>}msXyDE``WYsaUQ3_#L zCb9{bmO_}M8e~EF!hl0YP`;(MRYdP&DHy5RxaL`kIIfrDx|#$DONlLY9x~Yk6<3Zh z=@ONK2KHCqBZwm$8ibYtKZ$hVJ+zKzO^1j!FEH} zF%U|a@<9jL_>=7PPpAv%33Y+tSr}_sV86qQ;T>KRV{YujWdCQ)#qx=ZezxOF_B+C< z@fNsx-BUyUcf?x%R5d(j%sq?YSG56y(+l@(tj24e02Z=tZl?GmPyV z?Pmm?s*N&?*=rk{ZhI(C$DT^i!;z zA?006V2&2-v^$e+k%5<*=P|@x(Y35L)G*9;x$t+~El2bYWN2CeBUz3e@>`+$6d<-h@b5|* z8ii5;%?>?43N5gZMBfuG7xQR`N$QphET4RZ{?5=}=FThSm#O!&9r!6U*`YW@PU+++ zwumA4Npg}z3`0=)X>!8lUt%%|CcZ@-pi|a6bOgaAK{^=rgBD1=J5Xfd+jE3rI5g6tmfYzLWq6#T@(^iUs&62r5l+l zd4(p=p!}4vbV+}*{M3;n`DC6uZ?l~DTFyo|W-@;Rh06I&meUVsXmlwhu&LM?6&RU% zE3#6emU+?giyXinx&oT9gt5E71}w<(q06C6W%dIKW0rL>h2bW7c$6*WVQikhdpF`o zSenvHC1&3JbqK!5OoHQ`wn6wTBp5tABJr?-I-@YHjEv>i%2KByU!+ejru?s9OS@6| zfaj0Feduzb2>KM($mRK4Vak_>X~KN>cFqU;8Tg?^0^&zmYQg;ho}SgirSwa%k%#h6 zpt(>uCzw2(77X@KE5Z`sNWTR8dZ>J};S#8SRQv3rt`$0rf>8hAIG}fkZGB_n000gXQw66TD+CS9zdY?!|CP zf7fC0fYw72m^ApqG*R%g0O|%@GS#3xVqxYp6X=JMM&Kys4Mw@(OCDluZ@J|5yp9u5AzFMIpkw>SG0l@MR%X55jk& zpcGz9;v_ifArG^(1&3>eQ|NxmJ+LPEr=kPz{I4XW#;@B91Jsa{tG>9j~i?}nK}Oj8(RK~=f4=v z#m&u4(O4`VT^w83ym&z@;GE^0Cw^Ky#d#{u)QmVAoq^Z9++x5v*Lk|LT0B*pC!Q%b zi|2?d@r{#zz&WAs#5Yd*#rKQb#gB@2;Iznw z)GVDRoiDA%xuG4>yQCheU%DA5#e7Wql=S)IzHsuQ#ALTzEuSi%F303^@qLqv<+V6T z^lfsN{2uu_d9%D#{;>QBd6)bp`8)D{d51(_IQfVeh0pC zf`2zUaUOT{!a}NWVN{N|^i+X9WMJT=YCVV7U^yLoJ|p~_8`#xpedq)U>@S^^aq?Iy zRWJ%VQpq@{+R#&m4*2-zPCyGErbvMlPPBy2Ao3{#IQZO&jt`#T3_}T-()UgXSMCrB z4tz1kFbDv0^j!^nU1fN<0AI?a)Z{DZdI4YGuzd)?M@YJ^Qyf^b;t0t~OEEA6MT8y4 zQxrsE-N27Ne3DAxXNbg)ks>AvtUw`y^O73Y2|+*+ckkY9q{*{=dvW`AK`CtCPCtq< z3}ZV$2*PkC!G_H)_Zb{(_xA1hXa-P$~gnx{JC~W7S_Sg=lK@z3_!Hs?QWc&6* zpn#l-h3$5R1z_1R!>txm_-+c%E{*SnQ1MgT@QkfwJo#{nXv5&+9>9VyQ@AbPFj7!T z9TkGZAtH*2Tnxh`@!;zx6v1hlf|wdss1EU^8&o*pj+CArrfh)@dX&VG8a9TBo(|CP zaN3G07=&djAflXrrFC;GGZR$tWo$BrC$JBpT?@&Lk z-l={<9acZ7-lcvD>stS!{;T>Kb(i{C^=|cZ>c7pL3Nt#US-X1bP%fW~_A>9h{8R1$3S0Y*}g;YF`%dF&ILI!P&9+ zUI7|(ar<_{NwWfV7=^KTv~$bP8*REmhZ-5tN%34kr$Qgh+kS8h9K^Q{Gm`>D2Y%j* zfKU5C5<#ElGco_ejfT_zyJhD5g;$?GFcUL#{=(}xkAeQ@ZenNr%=ruSk052zUHSJo zx%l&*N&nG)jen5OoWH>TAvCodEB|pP_qG1#K6Cy8W>$UnjsNN3-zogYe}(A(Le^ct ze?^YFCrjSa=$Z2uX3k%reJV5OFQC~Z(ROCeUzl(b1GZh+M>O#6hFkrJ8^ON-`B4%A zohN~#6b<}`9)qM(z~9yag_-jg(4_cT3=?|iN-zDIZYAwR_s>OV=KO_MpS?imF<=V! zw?2PCZCSpMzOt2wE{rwB5=~9_;3U51#d}=SU5|M0aXsR_Se^<#q)ZiS#oZ0q7jb`8 zc|dstUzqZ`8eQkQ*0|o~8k{z-S5y1y338Z-{qaA7=EQXWcm4ZaA9Mes=N?zUC((CM z)i?ZKIe%fn%=rr#R{s*`FTCrGsmlN1DF>G1+p4)2e^s9t;Kw}J05&O*r^!IYOoq_t zR53VEYTV?FaX%{;CIsv=HpXMlJ}~a5z0_kNY^oloA0CnXW00h&;P2?R$zy|eZzWJ< zBAtH2jqq{-o3kr{R}2&wHyLR(hd-^G+>b5dA)N7CumVbXzwknMEKmyn(%Og~G_VW( z@o*t(p&?KaN*c#*@Ga(4ev$qQKWZ?1zXgZ}0HqXTm*CqTsml;Ra$)Eu#!QO9PBj~Fpza6AZg%Fq%=tH9E5|FWgZA&(|aXjcKRmp0x57k_yzl( z!3qd`A88JJ@}E{X1~fYMiYXVJSFK^s4twddn_2y)r+s>jcqM!3%B}3`&QS5ovD+Ki z^Isg6uD^Z#^5laX6!ye1Hv6g_;qSY?wd(Ec&Cl*VbmTqdXMgY8{)+MZxxR-I>0|$X zPVSXK_Tm%Y{Cz4g^!8^ixL=6o9{c1iyZ0~IdHAuVO{wp_@O*#ooWB3qKk)7chWmei z^M5>f^YdSS>Ac%_nzKIo1^124Md8hRYo83g{hlZbHErz(&u0Vk-nuRw_WQQZDmJ~) zllp1-P+wrri#Hx_7=2~l(?*V+(^uXc{sH^djedO6tH3{ifJHIOB^zf~xm-u3M55q! zb%?o~=*21Jx#O=SzAjB)5G>i}Wmm9pa!gJ#15n%ou5wZILaaDCL!pyZ0K*~ZxRR#m zWoee_GgqZ>o%;syNxglHh6Kk%M{mDZ`3ArJ(3Bc2>TNoN`4mG z$|2=M_lTb@zJulR+ZK=V0L3HC$dY0`?^trVz)L2m`B{=TZNWr7Jdn#t&zXU}pw>Ab zN^P4t6%X8g!5j;<2!%2KLk4vNmU#$=hg8gO3}?m5?z>qWSvtGi7dp1Vc%eMl)fvCN zE7TohM_$?7wP$yzYyO+#>>cF)4*3_dfBM~?zCCw_`p&-u$Bg}MZ+g$op|1W5&K1rM z52W`DhPnnXh~50nFW!{yY=nP#Z0N=R9?30T8XDQ#kuW!l?AVg}En6zbO5A<-GtWGB z1RYbQF9cVDyrO;W+J_!HlBakwrp;@^nd9j`_w5%a!A_L!#QAaJ{BJrhe|zJ`%0U-v z*9L=jwj4&8jlTTt&)t3ZnGL#OL+DTxGS5Et(0ID`6|XnlH2IAY|1*2U5D4m16Lk_S z{l~$i+|t0%&ZEzLqtq9;$()>4D&@lu-oE#xkA)S!7ka<=v!Wr(-7&bcLDJ`}j_D=UT z?rYs=%DwLE-F@zUx8Z*0>$(Q;U0#bXYnn{g?CtzL@Ng{c@cgmgmW5ya-j|%F^GD8O&ObQ) z%1O#p7_W{yN4anU=H(Oo72J*Z*wp)#%`OUWbXT!q3-a z>^=Z2R5VKiloMPUiy|iy3U-HK$I5o-6(C$*&`H|5LYdgfh&BnOLK3V3W^(ZmC%OOm zF&$_V*q4$@MZqK*0&Z}mK}one=^7Lga)NHA0AREqFsHjBZmsX(LwzSb+^6{({33H= zF*&41q0T0*G<+dFP;lY_3t$(XMn>5n+l(RYC-vNw@Af*!}+1m4R2j5k?;Kwt_9 z{()dq#bjJ$1eyA4!+@ONJH%yAhvqxZOo$s9v0+Y6hkGm_mpw=EfoE<;M#`Ry+xp0D z#l{y7OebQ=t;AU_rPRh!+8&^agbG61Wb{`P0B>%arI8WY2|h;n7sNqIVAZen)mT?V zN%W15j`k&>Kw2~x)y_N(hlleCs*@f{@!(98>@=fs-k_fVPYMENOsD5roE8Yp$4&Ei z*|v4~MZn2U!4_=Wz^Ts6Fjxz>;Xxk)(DXJTkKt3=iPUsZuH-T?cZ(kxQ0vG{-R7AY zAW$ibRW7THyu5;I#5UUTpVCD{4yBp9?X=c87tdLC&07)C0=}2eZ;7`wv^3ms7h(7= zlvn&}WzEXpu99=lXbrBF#tLJ_9eua1xOK%HD-SVEL`{V-E5&L+C?rUQ;X>7GeR$N@ z0Nr&v~tnY;MP!EWn&Ajiaq*@c+|yr%b`1UDILNn z1_sLry7(8`LiRd#piRHaY!S^67a6|un-{Lc^e_=!5KAnGH7!7W&Y1sW67Y&w$}c+G z-G@9lE7Z%^@O>`vivL{2r)}-z$(Tf)6bMq#fYXQoT8x=(@_CSevD2EEs&c&1z!t< z8}+vs?)hD7YrNC;<<{HOM0wmhkay zc}NR`g2DC>MYvCL*JMlUDQvPOH0B6<4GN;ewDQB!slmfcGSl26m`g0zaB|nm4>|D= z1_v4gV4M~hr_Neo#dhJig)4qzeT!PRV5mAf6^mAum!cLQKp+9XPGjeZ+^tPTV9Uu& zo>-zo=gA1)Gr5a0+8&`?uwq{Akt!gZTT8^3V6Db*Mp@uj@Q^|$aF#C4XE6hXdOCbx zD3(|=sf<)KS(d2c(S!Yf2?ex+KH&#+K5>Y>UBWgoS~+ig!cVHEv(uJ1u^Miq*?e5( za=}EySR&x4Z4>QeHWs^+)MQ2#EMmeFDEqmmy0mvBSwIYwqLeh@A@h1X;Q~j6f{l4B zg+t7U4Z`O_En|Ij0{%ed<%nOgvHg{I7JlB6fit^OU-c*Q*p*9PR^;Z@p0H_af>QGL za~xp=hfs49R)!4jQT8g92TQv=g0X__j(MzJ2(c0*$c+>&ag1yA{S45eb02}j4n=P<3Xrt{fS+Mtxuw~@K!fhA1sEGM? zc(DNw`i3wMm#l(71)@A$go?o=3zi!;nMq-sY|UMG4csu6D3pTbCPx(>iKRz!6)a7X zn>p{_u%rie~0bLhj~D;Qa?jsva(L%v zlc$TAR(d^chD%5nji$H)YN1q^*b0TxOVC#{S4dCLJ2#)EC!_*qy&B$4k(xgeXilT*-juA{|W9b_0eL7EH@!McYl}3ye&C-jakrN}STj z*2~>`s~*tmEmN=@!Gtow2zw;k-E6QovMYWK;V;Wg6k%bT7qFj?Lj$)&d*yIz9zJG72lKB@1j;2v(p3%a=%+%)Y6DSfY54jtOCCki zO~(*lJcg)(WI%G30MiJQ)I_p;t`ME~&t=azBt;Md0)xaYi#$^s)E~ZGZi0TG01U49 zNibv$*JziB8>v`%I%WOY5_3vJCH91*(13tm{|<}|{G}qGFkm!6m5o|4>FoBjQZ`u* z(+ZZzm(kE)Dq~B}QCO(&gJhYoAXHcdSm7~?2QAA4AYZX~&2yEYDG@%)1q*X1lz}Xh zTVO&k$1H<<26*BYW)23kESwQ9JqaZWlu?dw7z3%_zZ5dH)E~8j3c;NY!7|acN>oHA zQ(#H3mPtKcKBkU^Sy7M0KbHXukOhF znev|@^S712v`_o$DQ87%e!QGv9^20kXX!^r3|{wkE$P}zgUr&-Qo7WMCjJQ)2=#|T zA@p_I_o5FPHBEFT?`M0FuxuikYMWD*pVC(Kw=M2W?#D@>##*9PBjz{+|2JYeogbT|4 z_SNkzEns)$mCG;Im$hFpj_!{~ftgrHn0`PYm+1WH+;M~nK0l#GIRh4IZ1J?HG2(Uc z@%hK~mbP|?r*A^F#Hm=#oK^ott1oRw4cXA?(73E7@HNQ`2Fb+itO4_{Xu0$v)Wllc zD=&owX~6!6RVy!Dqk4GTooTtpHJkr$f)TuK;+N{Vyrpeb%d(5nXxdh;S=p|7(9BfN z6bO3D+V<7U*S71cFC9;%FJFDhCHmrp(dhh3=O^aJ=A#p-P}EnT54m*Znl*YHy}(%P z`72khcw76MTUYAKS|(zzU9+<7Z3J9KEq78TSG28aUs>U7mEHvXa_ zt{s%AUKH(vGS!n@`_HnPMp*i^>@!%|EBqS|%hEkE@)>3iN`<^Qrn!NR*UP~(JtAf4{C;^#Y2Ka$^fp3}#O@3od2 ze2)#k(doGm`gGC`r*D@a3w58c!=G}h>!6>~mz;HJs*i6I9ob)Vzf%RiJNUfQDzB_q zuC7?^V7VR6Dry4qsJ>C*d}w#u@jtZjeq)E7E~g9m2OC@@4@H~LU0F-G0xsqV)VA1e z#sxib_-Y1SwJ1-u?>3j!&c5NY^8cyJ%KsTVthgZu$UAJiO>Q6Z@t(B8T{VyBrrp5{ zL9aINMtaC)2f3)f&$}&syU%U4%ctF>2QE$WSn!iPPSBOLg?2dUvGTdXW65Qmhv=%c zd5;J5T&}ygtGK>G_>w31J&%teAJ4;{x+vP2@}j2>^s2Q{50$4{o9E^2F?gBRgBPrB z*IR7&o!&a|UtN72ckAkI@z!l&a$ViOdF%dDM7`b1<9&7ad7mKvfZD&HAaLj_&J>j$Jqv*5hu~x0anIwMyIcnXoi2PQn#7CXKRi*sv z{Qqdd>)xr>83;RWu;6urD(FZa&xcjw$E$r-#YRi?2luL$J`~iz0jkH}+hMm~1>C3A z`yoe%T(iWFcI{AVR{9keb2w`+^HaV)-&_23MG@ud@LO`cid>=2`%b@a8110;Jv^OU zbBzV}ZSq4eAlJ=)YOikX6L$D(w)=CxRo>tEtLBk@RRz@Evgi*i2=IQQ_R@gWFTOnx z1Yf?IUfX@Y?S4GK>!fJhgF+%c-_SBRti2wWeZBbI8|gq^B;|jT*IUr}QCBImARs+Nrq_FMI!4 zbAyh{dzbBgRYN%?mutUfje9@TupNcfumTN%jAf+78)K~*DbBJ|^#Yb%))3zi?K3kc z$FlK;4bhAzmThQ=?dUV(EYr44zpksQp(^i)Wu=D9Nt^XSE!$SzCB_?K!5&{`)Umo-#3c0bs>?xco>WgCmEYxA;YdcHoJ>B{F= zX8ERULp>YPco}cAG!g8hhXFW|T3m0eo+aeVSqdc!Tn;EmvUJ;YGV%)6Fl*6VsKyR0hD^vJD1zPZrEGV@}__IS3cCNqmNY|Y#n zLyB$_DJZ{Y$|b&`HI~7S%sCl%R$9Ix71z1}1wAkFj^uYh1d-T|_zue5VmnUkZpv1* z>tqW|)WPW@LyQO%`p&dhq zBAcUw`hY$V9n?bX{@7(Kc7KeSgPlU!Xxd@Kg2oZ!8RKc=mwRvF`Pc$jpVxOpphiug zd+jzo+uYgTx}kMl)tah?uBt>Mw4f=TE3%rV+*^y;swG`jE9PXXdp7Hvu>_gv+>~vr ziuFOhJ0h7kK;PC=UBvn{c0lVqEgFnR?$bI?C-;Xs%bX86HLe(Xo^5DFjf?TDcvq~a z$i^l)`G>xHIR^&Pm#EoJ2pM&{h?`3oziQVw69!ud_uT3JwWIFu0>?2itSr zeb9U9Q{85KomiEris#R!4v>LhtP6nZs$6SqM{GxRRaU$vRyD>+>xNXm zb%9-s#i&D+!z%H-_mA_-v6{QY?s(6UZ1vin9GG3(nE5gLq1HK%{K5srx_4*JBpvagWt_*d;=s9Fbn`ZX$-!%)F=_#p)l-aT+T$Bpmzc?P z`>y$Ed|g#bRa4Ks(RgEzT+BAFh;PhMp+D49+(E6Tr+7^?(;3^8U0$6Br+r$!bq5jc zDME<}0pPWfjVMliEc2=Shax-l4`)ON`2Zp+Z3`_p zBcjb^I4jhuZf&BbaYnYf8M=^a;;rQjL|IK}SsrRgEf0yR*6?QCq@NMnrlX5l%qFF5 z*nBnv9T2-UD|Vut&AOH|6W!mrEIOp=i`bs{ywJHU(-3dXG%TGLA?RG)DBt=6tuqEq zstOvxD$=zsv9USpI;l%;ZrsqkA-aflHjERo8a+vuc;)>DFYpR|NSILIJedl zX^v?T@VabStmg<6BNA!2hDEb;=GZ#1rYCw$5n@=d5yJ@T4(hG-wSvNWXw{Bb@S0*Q z)2zkN5#JDDnOU)$ih2FRks;_4`rZD8dOp^pEkyQa>Lk*O0c~NhCzg*agy6E(71Sg`3( zSM`Er8@jU_*8jLVTl)qmU+z$sv~YR0Zr-(NmU*w9ZEJ|-Sv(uRD3&<`qXx$HY}M5} zCJUlzQe&AQgvo$$0URHnZGif=PEr@D&WRD00!*#jG@pWa>;VT2cXBsxF*KV}&-kOz{UxRTwE6in?6&SY~FcXPos$#*RRBZ52d`KTkVH(1+Yg@LRT^#y2 zLr-RQiR&A3#Se8Cvo-5CnB7I=KZ--o7g#p9dD9{E)|rJH(M>ltqJ!Ru$=3?qI25}D zz1ks6ubMEKVwp9(MNF&mnQDTIP=m3ibDZ3Wz$6(pHe^oARy9(~Ys|Q^a^r?nWD(0Q zZ^)dVjZ^frLuBoytQbd=ml`5SSX~W0q?o2mExM}Z=uel$F)`W!1&K9uM>BN;MHDI9 z(9#v06I>_6B9ShkIRZ~GR+|lWZ$7)2SwX{J<}UP-4FkQ!*g&Az*wEFmtl3}zeO*Jm zF+R7epywHYYa%#CTQi1=iKEtRdUBIL{160f;oM$^_$^FhImw z`pg~qVyvh2niNJtp`}~f(bF2s7dJ$Aur7H;b5m=R<;1yT#of4~In}iF;G<>}`Ql@~ zCU#j}(^V^$rp>KF5+ zcvUc4U4z;2K#?XI%dJTSb(EMx@ga&^s7)%kdCvU|ZX2s(xa}D89Ei=1rl{E@P;} z@gx<@u3!y%vgI3c`PL?y5_So5Fzhu(&`|M|lv#x5gyUM<8MCqt*^{fQV%t(IHej+? zt{BT)PVV*pWmOdJwLz)Af&? zV#;`Kuw_V#8%L^)s1a<67)LNYtLX4_=`0PN4w`Lh$Slk@Q2p|!sL5l*c;!!(A6&yfM zd;S0(_uBA0!5?wg#9HH+@xxjJW+K2B8Zzk5=U^g=@qo}y!gB~Th(D+|%!`EUyOF@d!b<1+wH^P0 zbQ1AV<)w9f@cl+v5Jy9aj2;Gpf~K`<#R7^;7`#g|1zxWQ$80s zd=&Ov=5SKE#j6}O2>Y~k4wYQ@CZwnQK48=Nxb5zCUYW!I5N4`P#KBuL3zp&lkayRI$Q>^$!+^zOrj&=Pq(>%R){B7I~dUxC5LkiaO zS zJN%f7_|)9LwOtqf4OV6+c|&f}r`o_mH|bZc?;qTjeAjbV^KRpCE$~^l)h_RIs~YII zj@a<$-Ms$fYLAugDIP1IxQFUD=w9I=y{uK=?D1efq07}{xyntzhul3oJie5`Jl@ZE zsGTXkdp&i)*QyVCc)wBoTMy}DP&(D?Nnw|(d#>#^d+XBZU#geG9c6WOSJ>{g-n!!G zD|N!HR@nCuTE}NKfjeyX`?mWVua&Rrr#1sby)95dHi*!kvm%FPr$`Od>z*Pc{wjq@m_^_Ja1Jkd3V#gKHBkC z)zXL0aJSa?T|4}kh3EUNO8rcYd=jnCvl>O`Zml!w=luK5^Aq1bUyC1dfIKhYuD9-D zKlG$rE42ElKd6!0E&RHF@{``w1Tuc!UflzB_%_@9D!orYyLyO+YXi^v)hKpI`l|y} z@3r2u0=%E|wFF4-YJ9D>o3-8Ru&z&dLjmfaYW$xMsE4GosN5S+6Vj+89|&0E!UKUi z?8puHejM;YK9cv*fHmG61s?eJgs_fJbl#|O{Z-d!>b!DUcDzkfLn4lLd51=HC1=%3gT@>-iYdT<^EtJ2c-;0r>aW>-t}uysn>>&N=gBc5nOxH(|1o>5}3N zSyw}5RW=h^2Y?sZaQ zRlKXJdO>#1noJ!=`ivL>W1xFW6wkA@9~t_oW<1VVI}>VZjkDP1^NK&N9w-bRVwre0 zSe0=M=&|d`gCt{1`dOhdgLfr+7SK##50Za%A+ znU59EPOl!Ts(LWSIu}I;gsUQ_N4wj*TVvg+s_wqd({jdamTg)-#Pp%Z+0gS^m)O=8 z&(&wE78`5uRss*2!R)f?TI|nA?Z|vp(^#e{TUTp*7ul|9 z$~BK?+=K_um3`a0q^70~zXPD>t%e>hX3j-ajd6xX}`gcxz8FhDF#|56cyMSPbh4?J?BUr?9Y=mA=#^Rj;qkcDD7HncEP% z@fNJ#Ujy;wTf3^(whj4pwoYtnTb5hE;<>kA(eF+1>|5~2`>9+Ji^=Z-E9T&iPAP3P zUge173>Gt3^bH0((&@+Jj}JVEr2|w#hW2dEM;6yOYogofw0yxqdinn z19&S%*pLx_6|?y)#>@I(?5eqQ^+e}<-2$&~TaW#9yHMUH zl$X%Z8X~vm4q@)S!Q50FI$Ye0#Tk_G2kO1*K6Sr(K)p}>p?bf1Q2mkmfcl_%Nd2+; z6ZNO+&(w$1ht;2}ht>a3f1y62KB_*Z{!%@n7SyBaSL(0TC)6j^|5SgY{+IgS z>Qm~|>ND!IYEgYoeO`S*{jK^t_4n$FYDs-b{e$|lI-04If9Rbe^86&PSSpJ(;u6hdg%++p+Bse~TBxTfFEFyu@QWkYFp@THLyOn;98s zeP8NEUEf;RYHr&d9B92Ub)$A87Po|>-R2Iozn+klmy>J5&XDy%PPnUnR5Xtkkgyaz>_ zsl2AjEW|3&^8VJUIF|Cd4eBziC~8}AYJgU|T(}9Zs;l#knx-CawrVcD5WXvx2?Vou zHDEER;ru?VCdb!oxEH-@_uG2v4`I|t+jr3_NQ_=IW_{J*RE)K=U=>ChBKkf<+mvmt z>PMHc-s&*;LgJv-6VG@fnZX@eOoyiuX$LsJoViL7+E_4_?X-#&?Ae{^MgMTqCd5#w ztP%u~H`XWzL-1r9nmDu78-Cl=?aS6S+GUxoV{HIvkaJfAAP8I^u(=iJs=LD1i{C71P_(ayx0lVY^oX890xs3!AaluekW z#qu!-_&{eJ)<8ZI!wb{{EOQ&W#7=aHUBSjr<(top84ZkGQ=eUP>)2S3IWv1oV^;by ze{HuHul}frV->qjjK_oFlX|>Z0O$2fO0*726xra=aD`h6HeCM{AJ+-SuiM$C0g(WamL_D{DIs zC~cuhAkh9=w@C^urB!T)q~s+#h6V_~C=Xib@7J<+9zem??|bg7WZ4Nx;Pd}G(cZZ; zckbNBx#ygFUY8j;A*P2Etrh^q;f#tT@(xfkNN@+;YCM_~m3Tr83If*R*U= zp*B`-yV)yrDH@fiVJh`5TBwD-iudipa~17syNt@r1NN&b0n4ixoRgxc*Qp)aDL~;F z88EyA!*9fj6S96?I@9Y<=)D^Z8_V?eM~(Ut)2;);m@%e{^E7;$L&?h^;%7j`8Ikek zc{*-V;rO=JRz+y?dWj^fM3NUSUbT?Sg|)?G#eub#x6dy=(}W;GOhRNU>Tdu&ohRxv zr=E4nXit7kcxmo<;dKrAXmeF(Y-xyw2+-*Y#B|{kHUHt3PB22{+kh5PxBW$42z3-< zdYuUIBNm5ldn`W{S)#cKdR~GM>5+`})`ZbGjX58i);ArVh%xOe=2DsCN;2-hfQS`r z2-u2aQK*0ag0Eeo>m2Fow%19Q3_y2#Ma@I#SGTm0VaGb~!`8@JaEiGUa!|W2$5d## z^=dzmj77M%^o z!$>i0)xH=wI3P6QhAyB`zAym&OfIlwPDq-di2-TQUJ({x%ZzngY|Nb~yuk;RqY>Tu zw+)3PK!`-Q>0`n`RU(!Xa>?v!CH-)0QYIW(9~-D$Cm83g+o!i1+y5zVY(Mdex%scb4^X@#<8 zjVN{$+R^75F{7Ywy{qnIAR_g$YK#fT(w3MJ0i`h%BQns^5*z9t6Xk>7{enA}Oh=PI zM5ol-1>N!?%~lwfi$tXKNZN4Ah9W>jnbtm_hU{4V|IO^k_zp*pt3PFR`cUCub+WFW`TZYn(JqPtp+{oL?vSz5c7kr&}VKN zYo69R#-?FDq~4L``x9)6k71iU6uYpo;n>vYYwT=mn@6Z7X2g?7jN?dk!6hNw`R7rg zwRIW2mY~}@w8FIc9rQ$id|4{buxGb!hsoJt<1$8!($7VAsE@fNk@dpjMC@mRN9yPm zJqqh}dsSj_C^a={T&LFKhvw$H_|t1b;0ZjE@^ew@U{B%B{0@$|GeVPMqf~f9_rTsq z<9O03YR|)VXsz0!+pZZ)U$pB3eg(GohL^S$USIIa9Qw^CQJ>lZ+-^O#U`u6^33c*} zAm`VsSr>5f8NK~RZTW@9pkn@9!eg~?#%Q)ebCxz6M9>44I2P2`_G@bkld=&Ti|u1z zk$Rc;QihBMLyv2;eY<83>yJV&d8PsA#>Dub1iI%WjD$dMqR>2ZGQi10KMb2CPIRm$ zZ_ddMz!X#mmP&13o{;4Ul@arHnm9C*yVk468g5hAIOxTLoWXt!9Ru&g#T@B2xyyJ| zHLi!&+9E=cxqS^;SSgv_NPN(;77`uXs*I<_Gbfw*EvQdBJt^;&MRd4V@|wSB#QmA* z3eO~aMi{iMTj$BoCbJ2aeVXO2n#%a2U1Kk@lD3zGFT`}jkupt0BRnty;V6EA^5&R& zKt<0Wl+nh4jfr_Jx6>Mlt00h)2b8ZDBn6bfz1Ho~t=(>}zM1~f|Hp14>n`#eQDfY1 zr298&EcLFABUW}=VeB*J0tXf9-&_6TOgY+~LwlYUe^?$PPPK(XuI>)NFGK;OM(o+2p z9I$OJ3*NKX>~0H{ua>+P0q;Adb_=~%B_+%G50}$z<@Ann`lWLESULS!Ih`%15o`4? z$zSAy*6N)|Jw4X&H5R)le!?1l!D1DvZZ7A?tn}S_=})ZTEzA)J{jJr5yj%Kjt2D(N zg5fPU_bqJUS5>G zX%lh3UV7FRNHT{T8BB#Jr0^DM=0$OFwfQY zPdl9VK`w47I1pda;jj-o1lZNPT)Q3Om#BY#=5Qfj@A?Oai1(b*_xN+C>nyLYN^(|+ zc<%IuD@1&!PP(e15~)r4NCo8H_|E1E7xMK|x_p0UMc@Ty^SVYVM5J}DgBA2Wr|VC6 z-swGBuJ5Ue8a%IZ{YQlp&+A-gDyn0!Gk4clid!fjs-*k%uEmvJq#oCmm5^_vo==+h zy|?hR&UJTXeG2_-e6Z5_Q;WkA{$^!;jPn0fN&T;}KU;}7IT-&JD!nr1G5DXA;x%Na z@2?Wt(O>UUp1QmrDW|*2>6fd}ZimbNuT^|}q&LguL)GSc$#SYylRbZxcOOryy^}n3 zc>lE86Jr(b&_m_)*=o-;t8j&WSsg-u0{k~YS(C zO{o51T^Qy3(#v&(H++&<&)1_jSziZ#iQ3u^meY^dhcQlpK$fTB@ZS3H?aUDl-(Meo z$mXzy|B2ssg{SJxaroD!Yus&u@3>t5&C7*duk-t1*RRd{VVf%qt}kq@aZ&x@u+wFZSI}j) zXM-#Jq}AbeXI9OKIE&uU9RT|7YLx;<@#aSpJLYK zWweeJ!Gwpa%ITJJ`bQ{E^JoZFn1_nc1Bd|1Dyl6?E~m@O=||iqd=9uJwAT~5)h)~bZmbWvg+anQf9W>q!r!_% zTzVdHJ8wt)PTMiJNpGG&IkYQe^>8{7lsqQPc7~{>W4hFGQL;8r<~sFalSzQI)CW_Uc|q@_PCkMLf|6#Kh3s!7?y4}XeewR z81ljQVziXdnpAyloUCH%!9DR?MerBf56Z<%i(A^`kW@H1h}xoY+PH3)u<^64O_10= zSEnt3(q{&KC|wgb$FNCGkM^~+whY4XJ^{nL^YTsB-bf@~m_0M-k3@QRz=dQY-V1+- zkx%N{@W@uC^&gZ)m>@$_1*UDq@MtDVc2c7r-L~27h9W303=2EpOtJ#33^|i1feGd=@j<_PyJNq2v4Yy8$PLC<4LK(wW>@5I@$1dMvr z(ReY=-$m8jO=A;`+NAYp(`af1v@ki?3k?%LsmW^l0jBO_AK*>^yY-fC_%tYS?S6T5 zS8;UDsH!=^L~Z1+kCKzg;r&br?qvlS`JftfG0ZChE2%w!o?k&E<}HUS3h^7y2Y z&?7Bc2mgLbdl*}ii3RV$xCtNag2++B2(=n6S*zC_>+{&!L01H$QEdsYANAdjap2=c zjx+Q>+J&7nbqnH3@+TmT+j_`~O)0I}u(_t^lOAgCl-8&(c8~v@X@3V>Pu`FQ`oOWo zf#nkzJ6j^Pd~P^j5)ZIjb{&}Bbzo+4TE$LYJ~V+JFvaY-cn?#b!^nV}$Afui74?=~ zhYn8f+5=hg+=pq*)X~F$(mvGxmHjfr+8YNZPr>P9R2Y=jdlDJXwF$7iUF+2B8!XY5 zYm8+)i6w?*T`9LiYbod(Z`5uO5cNwN+8r1ldtxLBZhw(dr5ynxgsr%mz(5rYsEt1cQQhY{k zXV1oubv+Y5*8OapA?bQLer)C2s={=BDsEJ;0*g>}OuI_|U<4Ji^yRS?&&Bb(k{wHW zn0ELINXXzXpoNBuEWIje%-##Xn%?B3K<+C=(R~Qzgr~9a?2o{Ir5GQydHOu@>?awn zGqw%uxCe{!CBD0#5Ze{S8j!%bc+gS?jmTvDdXnO|X}0GS3s z?IvhwF%g<%q~NAr41GUwhx+i*ZH z`lt=W;pJkRm@vIuq;;P4aAr`mT`c<;hPM>WKF(Bq<7PlR_jr*WD3prP0+t{=TDA$p zXi-`k0Zc(Gl7h~pNFzxP3CK;GRqk<8P>0d`=D7BVI(kICoA%prb|T)M^aKFUHno7Z zaO{JWu%;s(NP61wC;^R!2ijbSU*Nzi0>ZJ0(QoP9dopCnJ1uCdv%(o< z6lR1w(V#{G+d>R-U#bqIMm-w=W)D3EOyh(-c>TV{!lj zw+4V(Fi==o6pNr-#TD``iyL@9MH4Atri+F^8&VV*^ID#lcLX39o0HoZm3j}@))VxJ_bjHZ$4YrW<@$DmQHg6C z;G^AAo34k@uiqc&=*^ErT(5kCN$1(2qzFG5A=@T>3ruF$&ecQyzfF5X? zJW8MsX=pz8BR$lR&yK$`!~U%SUa|Qo>{H;Y)Axr(RqyHpEtU0X9-_2K6$JBbqX+3C zH>=>w_~K!^=+PzPb@8)xAlH0OE(OgNK2n$5orB`vw$Ai4AJliJdeETrrEoF**{En& zj1uaeg3XWzK03O0T^`6{R2SRk7{M+QudA>qFC0w4#Yc$i%hza2ck2q)*C4!ngi{`n z&pj#B;hB&|-{77;L$kW?@GunO)1qz*lR=3t{w;a?9M(3$fQuH_VRH8AmsPM-2f;Ls zPbcQwedZSEdn`RoG8eK9AU5}k37r>@w$6)PI;e@bws;geAi@u=*=engqfeHHrKIXgj>uUb7)&U*Ko!;;-Wl6D6`gP~I0wbG_1Rwy z#<3O2&O)djkKeE759doGNAoiypix^Pd|xxMuzYV{_BSnq@pv!xyD++9ne^IteoF8A zpfXu8qX5orXeiu-R^!Ep_jQYzI&l0J;ELf%wjPkxuv`v`c~K^!r~*Et1H+DCJ?HCSl<4!QxWITR=}|+ zjt~M9)BFcjm}B(V>Su9%YIQFQlMxvFmoad3^Rd+!=J`i-S6>&`R*k}B10(QW^h8g` zwJoZ?mdd`zpr%{oRq2)~^|3?`dWJvv4^r)??Y6?N~8lkjggUg`)LD&G#0<5C2> zvE6#!Tt@F+i>903e)m!rLEAf^Vm%+%235V6AnZMAN@IUe0%hhu5x6%+jI}HijYhR7 zcKoAn-%~8)p^qiZeQbG?2R?EyAF4~XU*t|_vU!(2SkHTV>D@U(^4kb;c|zW0yY(a% zCs8eu&}egFo0R6l#<~alDZTaZ?ij3V)A@D!_P&wWfmxR6?p-^9NY*5H>dHMgHMVI( z9~;K~!_i2-q)&9rVepLJEt2ddA*k?#BIo{1n1PlqqTMafE*5p$2E!^8$7C4!UOrw5 z1auGIGSGfR!-gb|X5c4{mPJHeA@)&%p)mnA39d-A66Bj!uz8HcOKW6Ej3y9z_CAscw{9+XEp+cD^-&a+VE#UF=pBKdsTf;lq`6}U4<@{&O^7VH@cQrd3 z3fymn4v0za87uklNW!eu%ky5Fm-lzM&2t~_yFO%dQ#+m4ao;4#owj+=A4#~)Rz<1p z5b3U%RCkZf9H$3tBHgcl%od>cJx`eR2`}4xR8D%+=Arsremmv8Qk&gN<-`=}q?m+_ zC3IIv_fh;GeCLqeV^ID9djqAxe=*B>{+o1H43b@ko9+uM9M!)(KO1uNIm~gs-cb!- ziIC&d4k2crwO0>0oKx_Pa>CxM9eKyNgT~M0`W*K;lAI4Ys2{HSZMuz zr4#-0)~74^^SaT>`Yq>Y8>^30I;YQ{4_m%gS)V-58ms@RlJ~#nu}aAHXC>*WN-uma zg6iUCnS}3Pq;;G*S-4))G>R&hSJ3Rn9dT&)Z<+>~8t-6DB zR?J&{Uo~`k%5V>{Dh>2T7r|1a4mFGsLz?*vq5EAaJtJ`9ot*QPi=&-D;ruwlu0pIu5pM*uY z6(NLwT1V@wTBxsw&II^Es^@sax30drgn738aXoZjthRQzoF1qT6MhLmSB3crhrdxy zzh57oI)5%~J!|G&Z`GUQcD|fOoo4>SPV>7tCx734k2CxN-m7|$=iTnVafW9AKkk2V zQop47XUggS;m=*JDyYRQ=Un)Ql)1u^i|TQO8z?;&cD3^R)^I1k9}cVB$H(hh?J~cg zc7=b*&bi$OUEwX~k$%y|zZd>1Ufv!47k)qNe%=LL466#iQm*HxE&+L$>(^zUAz9$~ z#eJ44L8=|dAs8mZj&y| zy2D3j&wE@}j}zmMpp+hy-k^G%0v@XS1NsaLItS=J=t`0DvyO^Cg=@Wawzl>mkMI!i zSk<>Y)km$MFULH!J1w*Ij>kQ$FWUOx@1 z^cZ_0e)|(3zT>b`iW^DD>aeZ+)HrO9w3UMuk@#AkFY4nfGvo2Kur6d;Uf;B7WO}=h zN#xh&)$EC07Qk+B`}W+^aPhfz!*Fc81Z}}rp$^IC!3Sh4+95+}X1e2w@yLv}eq27R zujoD)ku$dZI^zs%ldOl-!cnaOqG@uZ4zA1C*TF^Vri^Wy{Fo~0`Dp8Ys(H)!4TMV>|^0W^}NsYq3T6UhKN=%9#aoa(^W6J zF~x~5Ly<^}}1`ot`>)w5+n<5cR8CRB0x`!vGnf6Lt zg!I}Y!q6vuU2@DiW*LaDNamo<6JaWv&3!n%{7XhNjL!6R>4Qujq2|H#)0XZ_}iIo6c7VQ9>IOK^qWM zbmaM<7${`yp2HrGK9MFh&eyOt<+Hn6-&mMDDUdUov{5%^6_%YIw72vpjM6I>LG_R? zmhJj=5kQ`PJYVV{@x|zlaZC?XV~61WVZ`+GN?1s$Mm^I$V~}TvF?|U8R|#sJbl-~X zi@ImEF;E)HYS3hEJBZ0{y`aPCDxjGK1B$Al7}*ZeYr5@KC^1ca%9R8O81{kX-LcEl zSH{c&hx=Cbir`{*5a=wZ4c6Oz>3E?oXDd|ci(7Zbme9ND>ewnIbP4#E<;f`}Ax=xc zf*cNp3Po|ZJ|ID*vI~w{qe*g2&@5E^*ed>heHP9oKR)!G1MmR6%SaqDRH}+zeo2Cp z)-AjCz*CE|&^jS_;ldVi2eWclNEl$YeP^eDNp`LrvBC zKpp{$t}IPM{dL9IS#uDomd94O^RXUJx@b&ZHU&8*MER30d5@6s^tX(3!xBDQYAM*@ zRJj-+3a2;uGzA)7ELM<2452&S(}`se2^u=s`NGak%-+0L{(F zz)~Ap51y6D3C=jnxZg*wN0Qs+TXv1^x_xGGP`hC1o`CNk-Ni$+LKF*vJgUIy2ODV>u@wzKYK!iR zLjjbrM_TfZtfUS>cVDM9$_mtB=7b;pdo!Y|(^R4E6k_5{H|Rzhx*k9HWj-yCHSA9afpPx?R@na1|=zJ@{q`FqWqELjVTEpMazSkO^~p zV~SwuiT(T1)}zK+BV`<2kc)v->XwrnpmI|HCvDYu32pPWLL{98rq3q<2aIRzqI;f_nf47rVg*{V8FAh5(Z>cYZqKXm zEqE0)fC1m?=@Sn#>1wua#PxGKN2=`mX0A~|Z4Z&q)L$2fn zKq`aqAV65n!>>mYvMe=}Otuy3N_t~_B&O99FwcQHm4o*X%SyoBiNsKH(7iU%QmA8k zW0&USa6ea+Rt223yLz(H)Uu%@qZUkOBJq~F1u|EV>Rd-2NvO~r$0A}>X=|Y_J74nN zo8gzV9?(r*25uUSVL{jX7cL)t$(li|mH3E5$lFuCHk|L2tBVb}Vi)>K>xs&AjW}4| z&O4ye;I!oGFevQp1#cX2Oy%u>E8cXJyl4^jiZHw8EPQk>6I;ddO+prXSxWHTz&x1c4)3xQU6Q=550rw0k@lqd2vI#sZ0Pt zB8X_I+m?67g(jaDu1v_riH5;b0=^c6kfKt4g9H@}5S_LZHzZFqZyBA#A^{WYOicvf z`D_@`(10Uh7z{uX^AHJ|CyG4s+mbaIsXq?yrVSEe;d1{b)3%0|KORAfnNQLR&DajN zTtEXHJK*t+qc`NQp&^_`nFWtm>rKjtpxd9%r`(Z32`*1Ag~KiZb&qa8o2P-FMxa$% z?ifwo_FBgFjTUm3FqUD^8po&gZ4Znm*#vt29~0y&x{yj{>?c~V3_@ zq?jhzD%pJ@jF}v0JMv03}m^08bxyJ7!p9mQCsQ&4sMCw4iUosu<6R z8rt=-!n7WO1lgVOfUh2{(`_eUQZH*Fv{;)bn_^IEwZVu6j!58@_U8MusUx`?bk9Ax zB={4k!>;#?zg&7}jTge68Yw|@P00I5Ykxed0=njx;~eGTOMJ{iOMHx$xZZeUc{O5C zF{^5?2V0+o_!@IXH~}aDJ_c~1GH2Apu)6JKyi;IfZs3z1nv-YKXJz+5Z7WcoJG)v{ z(yt>d=+m6O%t}80!IHcywTs=tc9r(9U2GTpZuv7v1Sey=U5yF zTYx1`x^imFatu60ihQgN8}5O&*3`IF9+Tw*pT7f5&t=msTVX}=l3Rrbz^4sapzsV7 z3F5GxC>Zdyim*()WlWE+%cfuhI042xeL87+Ta}ft6nk#|66|!>Pz;jJ?qLAN+$B_7 zn>KKD7bQ@4Az_&f_}%}le>$4jyQx3Lue#>1$oDGTMMX#n!Y|+^UB0tWM>CHij2Q5O z0`^$;8ub>Yf2P+sc_|*zZ@STl2`CpeY!*Q>>Ve}vlQ5H=O+^E-ThlAy zmE>ZrV7O-%aNHLrBB4UTr7ELuLb@9+!3*ogOY~gxTAWLDG+Y73)mj%6I;0As6}wws zuM-LZw*pI%`?2pT95vY-uygI1hXGmYTIx~xledKWr7ue~yLRu?M-sd)=^SXR;x{=UjBj6nwjg;1GoYaiE9E3na+A z&TeanHBP~jPjW_Es3F1%! z{hd1DHv@pxdJDya@DeM6axm^D7J3_B zPGA5j2kja^He8(F$q_BYWWZN!C|M?mL@i4WpC6I}fhab@r^H}DXj02LQW^}6Ou=z1 zx&$^nb34Hctn`582ZGUQ1N&yQ$VNg)JF~>GU)Z$ibze4SWT0jJ*2CipDynFo%t#+X|D08pDu-fW-gZk>9ZviR#&Do+MB=HxZ6oU(WL1kIx3MOq;m9jy z`8vhoyaq?Pb}X_ut0>)Q3F3X1bHLKM)e7Crn8g{hSRD2HEzWPkx5ROe#d#O<6`$wj zoslnEf_UE-nX&|Bd{_Q=Gq1dfdRUb|(r69JNac@MgGrQAK4Ue@f6>g#r_1>_%IPAT z)38)H0$XiP8ENx2Tc>QT42O5vI-j)KgSCHJ&VSVwOtC6&-aRZz*>6+CZ@e!;FF-=LhdHz5ruXYFC6euX)rc-|DPbwrR4Dc3sckvf!3jsV*2 ziG0*Sgk%6`Wpq|M4a$LFKXvs!wkHV1@a;+bf!o4@JLT z5k`Ft%70Yw_adc=CgdBHn#v_;?-FHYrP=OXmCeXED}Pf-Jy1XQZl5@mGf^A8D_q@{*FSu0`rlc2(C_(RaqH1N{D>^8LT5Ui4E|p#&eM z@)c6>>1z6(KlC!s`y!4Sdw;)e&6yq8)V{{-d9)BRC91zEsZtfb!LWHeWp-pU4gMX8B^h z376k3=YL&K<4~`}oKS>S)km)2X?5feolOF(Y3lg66Gw#AHZ7fWHr;2b2`qWaxfuOj z6#94PGQ77`S?Z$i`=eW2^nHKibLIRau22^3jJ{G%9RkLw%Gc2%0DfxZCA~sKu+)T> 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 zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N j0t5&UAV7cs0RjXF5FkK+009C72oNAZfB=CHiNJpV3{g$% literal 0 HcmV?d00001 diff --git a/doc/030131SD test readme.txt b/doc/030131SD test readme.txt new file mode 100755 index 00000000..9a9d5595 --- /dev/null +++ b/doc/030131SD test readme.txt @@ -0,0 +1,45 @@ +HYTECH-INTERNATIONAL BV +CMX/UZI TESTRELEASE FOR SOFTWARE DEPARTMENT 030131SD + +MANIFEST + +-rw-r--r-- 1 nick users 6986817 Jan 31 23:06 uzi.zip + +INTRODUCTION + +Full release of the Hytech CMX/UZI kernel and associated utilities. + +Note: This doesn't contain Joost's userlevel work at the moment. However we +do have a small "helloworld" program which compiles to /usr/bin/hello, Nick +uses this to test. + +CHANGES IN THIS RELEASE + +Contains a major filesystem upgrade - the superblock now begins at block 4, +rather than block 1. This is partway towards implementing a RAMdrive in the +terminal's internal memory. Utilities which construct and maintain the +filesystem are also completely new versions, with much better error checking +and help messages. These utilities are now available at the terminal level +(also partway towards implementing the RAMdrive). + +In the kernel itself, symbolic linking is now implemented. The kernel also has +much better error checking and messages. In the C library, a bug is fixed in +the creat() function (the bug caused it to pass garbage for the filename, so +that an EINVAL message was always returned). This means shell redirections now +work again. + +When building the filesystem, you should now use /uzi/bin/n.bat rather than the +former loadall.bat - the contents have been revised so that the filesystem is +now built from scratch every time, rather than relying on a pre-initialised +image in /uzi/utils. The filesystem is now checked after copying the necessary +files into the uzidisk.dat image. + +Note: HD1_START has been set to 0x239. For Joost's system this may need to be +changed to 0x259. If possible, please advise the starting position for a brand +new flash card! + +Note: When prompted with "boot: " at startup, you must type 2. The RAMdrive +is device 0 (but this won't boot until it's been formatted using mkfs and other +steps performed). Similarly in the UCP program you need to type "root c:" +which translates to device 2. + diff --git a/doc/030131SD.P b/doc/030131SD.P new file mode 100755 index 00000000..6cc1b571 --- /dev/null +++ b/doc/030131SD.P @@ -0,0 +1,45 @@ +HYTECH-INTERNATIONAL BV +CMX/UZI TESTRELEASE FOR SOFTWARE DEPARTMENT 030131SD + +MANIFEST + +-rw-r--r-- 1 nick users 6986817 Jan 31 23:06 uzi.zip + +INTRODUCTION + +Full release of the Hytech CMX/UZI kernel and associated utilities. + +Note: This doesn't contain Joost's userlevel work at the moment. However we +do have a small "helloworld" program which compiles to /usr/bin/hello, Nick +uses this to test. + +CHANGES IN THIS RELEASE + +Contains a major filesystem upgrade - the superblock now begins at block 4, +rather than block 1. This is partway towards implementing a RAMdrive in the +terminal's internal memory. Utilities which construct and maintain the +filesystem are also completely new versions, with much better error checking +and help messages. These utilities are now available at the terminal level +(also partway towards implementing the RAMdrive). + +In the kernel itself, symbolic linking is now implemented. The kernel also has +much better error checking and messages. In the C library, a bug is fixed in +the creat() function (the bug caused it to pass garbage for the filename, so +that an EINVAL message was always returned). This means shell redirections now +work again. + +When building the filesystem, you should now use /uzi/bin/n.bat rather than the +former loadall.bat - the contents have been revised so that the filesystem is +now built from scratch every time, rather than relying on a pre-initialised +image in /uzi/utils. The filesystem is now checked after copying the necessary +files into the uzidisk.dat image. + +Note: HD1_START has been set to 0x239. For Joost's system this may need to be +changed to 0x259. If possible, please advise the starting position for a brand +new flash card! + +Note: When prompted with "boot: " at startup, you must type 2. The RAMdrive +is device 0 (but this won't boot until it's been formatted using mkfs and other +steps performed). Similarly in the UCP program you need to type "root c:" +which translates to device 2. + diff --git a/doc/030217SD test readme.txt b/doc/030217SD test readme.txt new file mode 100755 index 00000000..70c3c920 --- /dev/null +++ b/doc/030217SD test readme.txt @@ -0,0 +1,116 @@ +HYTECH-INTERNATIONAL BV +CMX/UZI TESTRELEASE FOR SOFTWARE DEPARTMENT 030217SD + +MANIFEST + +-rw-r--r-- 1 nick users 7808012 Feb 17 20:05 uzi.zip + +INTRODUCTION + +Full release of the Hytech CMX/UZI kernel and associated utilities. The +release is at "www.hytechscales.com/release/nld/test/030217SD". + +Note: This doesn't contain Joost's userlevel work at the moment. + +CHANGES IN THIS RELEASE + +Contains an upgrade to the "teletype driver" so that now you have access to all +the serial ports, the scale, the internal printer, and both the LCDs. I put +some testroutines in the directory /usr/root to give you a starting point. + +The rough list of changes: + - now got a ramdrive as drive a: + - compactflash has changed to drive b:, not c: + - now got a generic bootloader + - now got a virtual memory table + - can now run shell scripts + - disk format has changed again + - can now install a new kernel + - can now access more devices + - console is now serial 1 @ 9600 + - rtc is working, and prompts for initial set + - revised malloc implementation + - now got sample files for devices + - now got ter program to test devices + - can now run "passwd" for userfile maintenance + - can now run "adduser" for userfile maintenance + - now got a default group of "100" for users + - ls program now displays in columns by default + +Your installation procedure should be something like this, hopefully avoiding +the problems of last time: + + - rename /uzi to something else (as usual) + - unpack uzi.zip to /uzi + - reinstall the files making up your gui + application + - cd /uzi/boot and run n.bat + (this will copy BOOT.BIN into \NLDDL on your Win98 + machine, so that it can be loaded using POS) + - cd /uzi/kernel and run n.bat + (this will copy KERNEL.BIN and CHECKSUM into \NLDDL + so that they can be loaded using POS) + - insert the flash card into your drive (I assume E:) + - cd /uzi/bin and run n.bat + (this will copy UZIDISK.DAT onto your flash card, + which must already have the HYTDISK.DAT file. Note, + the size has changed to 4 Megabytes from 1.5 Meg, so + there's a strong likelihood you'll need to reformat + your flash card from scratch. Be sure to try this!) + - stop the flash card and insert it into the terminal. + - run HyperTerminal using a serial lead plugged into + SERIAL 1 on the Hytech 1000/1500. (The barcode + scanner port). HyperTerminal must be set to use + 9600 bps, because it's the barcode scanner port. + - clear the terminal's RAM using the CLR MEM switch. + - allow the terminal to load using POS. + - the terminal gets CHECKSUM, KERNEL.BIN, BOOT.BIN + and then reboots. + - follow the prompts on your HyperTerminal screen. + In particular, type the current date and time when + prompted. After the RTC has been set, using this + method, try not to use the CLR MEM switch anymore. + - the terminal will take several minutes to prepare + the RAMdrive for use. This happens every time the + terminal is loaded using POS. The download using + POS results in a very inefficient memory layout, + hence this automatic procedure which rearranges the + memory layout and makes it all accessible to you. + - after this, you will install your software by using + the flash card. Note that communications are not + working yet, so the flash card is the only way of + copying data into the terminal's memory. + - for example, you could use the "ucp" program to put + your program into "/bin/myprogram" on the card, then + insert the flash card into the terminal, reboot by + using the on/off switch. The flash card is mounted + on /usr, so your program is "/usr/bin/myprogram". + You can execute it directly from there, or else, you + can copy it eg. "cp /usr/bin/myprogram /bin". This + means the program can be loaded very fast, because + the /bin directory is part of the RAMdrive, not the + flash card. Similarly you can run my special script + "/boot/newkrnl.sh" and this will copy a new kernel + onto the system. Previously I would have given you + "kernel.bin" and you would have copied it to + "/boot/kernel" on your flash card. Although I think + it's better if we always build it from source..?? + +Good luck! When you've got it working, try the following script: + + root@sn1234:/root$ cd /usr/root + root@sn1234:/usr/root$ chset.sh + +This will copy character sets into all system devices. +Then try the following script: + + root@sn1234:/usr/root$ demos.sh + +This will copy demo data onto all system devices. +You can also do things like: + + root@sn1234:/root$ echo Hello world! > /dev/lcd0 + +which is useful for a quick test. In your programs +you use open(), read(), write(), ioctl() and close() +just like you are now doing for "/dev/lcd0". + diff --git a/doc/030217SD.P b/doc/030217SD.P new file mode 100755 index 00000000..38a3ce54 --- /dev/null +++ b/doc/030217SD.P @@ -0,0 +1,116 @@ +HYTECH-INTERNATIONAL BV +CMX/UZI TESTRELEASE FOR SOFTWARE DEPARTMENT 030217SD + +MANIFEST + +-rw-r--r-- 1 nick users 7808012 Feb 17 20:05 uzi.zip + +INTRODUCTION + +Full release of the Hytech CMX/UZI kernel and associated utilities. The +release is at "www.hytechscales.com/release/nld/test/030217SD". + +Note: This doesn't contain Joost's userlevel work at the moment. + +CHANGES IN THIS RELEASE + +Contains an upgrade to the "teletype driver" so that now you have access to all +the serial ports, the scale, the internal printer, and both the LCDs. I put +some testroutines in the directory /usr/root to give you a starting point. + +The rough list of changes: + - now got a ramdrive as drive a: + - compactflash has changed to drive b:, not c: + - now got a generic bootloader + - now got a virtual memory table + - can now run shell scripts + - disk format has changed again + - can now install a new kernel + - can now access more devices + - console is now serial 1 @ 9600 + - rtc is working, and prompts for initial set + - revised malloc implementation + - now got sample files for devices + - now got ter program to test devices + - can now run "passwd" for userfile maintenance + - can now run "adduser" for userfile maintenance + - now got a default group of "100" for users + - ls program now displays in columns by default + +Your installation procedure should be something like this, hopefully avoiding +the problems of last time: + + - rename /uzi to something else (as usual) + - unpack uzi.zip to /uzi + - reinstall the files making up your gui + application + - cd /uzi/boot and run n.bat + (this will copy BOOT.BIN into \NLDDL on your Win98 + machine, so that it can be loaded using POS) + - cd /uzi/kernel and run n.bat + (this will copy KERNEL.BIN and CHECKSUM into \NLDDL + so that they can be loaded using POS) + - insert the flash card into your drive (I assume E:) + - cd /uzi/bin and run n.bat + (this will copy UZIDISK.DAT onto your flash card, + which must already have the HYTDISK.DAT file. Note, + the size has changed to 4 Megabytes from 1.5 Meg, so + there's a strong likelihood you'll need to reformat + your flash card from scratch. Be sure to try this!) + - stop the flash card and insert it into the terminal. + - run HyperTerminal using a serial lead plugged into + SERIAL 1 on the Hytech 1000/1500. (The barcode + scanner port). HyperTerminal must be set to use + 9600 bps, because it's the barcode scanner port. + - clear the terminal's RAM using the CLR MEM switch. + - allow the terminal to load using POS. + - the terminal gets CHECKSUM, KERNEL.BIN, BOOT.BIN + and then reboots. + - follow the prompts on your HyperTerminal screen. + In particular, type the current date and time when + prompted. After the RTC has been set, using this + method, try not to use the CLR MEM switch anymore. + - the terminal will take several minutes to prepare + the RAMdrive for use. This happens every time the + terminal is loaded using POS. The download using + POS results in a very inefficient memory layout, + hence this automatic procedure which rearranges the + memory layout and makes it all accessible to you. + - after this, you will install your software by using + the flash card. Note that communications are not + working yet, so the flash card is the only way of + copying data into the terminal's memory. + - for example, you could use the "ucp" program to put + your program into "/bin/myprogram" on the card, then + insert the flash card into the terminal, reboot by + using the on/off switch. The flash card is mounted + on /usr, so your program is "/usr/bin/myprogram". + You can execute it directly from there, or else, you + can copy it eg. "cp /usr/bin/myprogram /bin". This + means the program can be loaded very fast, because + the /bin directory is part of the RAMdrive, not the + flash card. Similarly you can run my special script + "/boot/newkrnl.sh" and this will copy a new kernel + onto the system. Previously I would have given you + "kernel.bin" and you would have copied it to + "/boot/kernel" on your flash card. Although I think + it's better if we always build it from source..?? + +Good luck! When you've got it working, try the following script: + + root@sn1234:/root$ cd /usr/root + root@sn1234:/usr/root$ chset.sh + +This will copy character sets into all system devices. +Then try the following script: + + root@sn1234:/usr/root$ demos.sh + +This will copy demo data onto all system devices. +You can also do things like: + + root@sn1234:/root$ echo Hello world! > /dev/lcd0 + +which is useful for a quick test. In your programs +you use open(), read(), write(), ioctl() and close() +just like you are now doing for "/dev/lcd0". + diff --git a/doc/ASxxxx Cross Assembler Documentation.htm b/doc/ASxxxx Cross Assembler Documentation.htm new file mode 100755 index 00000000..54b390ee --- /dev/null +++ b/doc/ASxxxx Cross Assembler Documentation.htm @@ -0,0 +1,9024 @@ + + +ASxxxx Cross Assembler Documentation + + + +

ASxxxx Cross Assembler Documentation

+                                ASxxxx Assemblers
+
+
+                                       and
+
+
+                            ASLINK Relocating Linker
+
+
+
+
+                                 Version   3.11
+                                  January 2002
+
+
+                                                                  Page 2
+        
+
+
+         
+                                  P R E F A C E
+
+
+
+
+
+           The  ASxxxx  assemblers  were  written following the style of
+        several cross assemblers found in the Digital Equipment Corpora-
+        tion  Users  Society  (DECUS)  distribution of the C programming
+        language.  The DECUS code was provided with no documentation  as
+        to  the  input  syntax  or the output format.  Study of the code
+        revealed that the unknown author of the code  had  attempted  to
+        formulate  an assembler with attributes similiar to those of the
+        PDP-11 MACRO assembler (without macro's).  The  incomplete  code
+        from  the  DECUS C distribution has been largely rewritten, only
+        the program structure, and C source  file  organization  remains
+        relatively  unchanged.   However, I wish to thank the author for
+        his contribution to this set of assemblers.  
+
+           The  ASLINK  program was written as a companion to the ASxxxx
+        assemblers, its design and implementation was not  derived  from
+        any other work.  
+
+           The  ASxxxx  assemblers  and the ASLINK relocating linker are
+        placed in the Public Domain.   Publication  or  distribution  of
+        these programs for non-commercial use is hereby granted with the
+        stipulation that the  copyright  notice  be  included  with  all
+        copies.  
+
+           I  would  greatly  appreciate  receiving  the  details of any
+        changes, additions, or errors pertaining to these  programs  and
+        will  attempt  to  incorporate  any  fixes  or  generally useful
+        changes in a future update to these programs.  
+
+
+
+                Alan R.  Baldwin 
+                Kent State University 
+                Physics Department 
+                Kent, Ohio 44242 
+                U.S.A.  
+
+
+                http://shop-pdp.kent.edu/ashtml/asxxxx.htm 
+
+                baldwin@shop-pdp.kent.edu 
+                tel:  (330) 672 2531 
+                fax:  (330) 672 2959 
+
+
+                                                                  Page 3
+        
+
+
+         
+
+
+
+
+                             C O N T R I B U T O R S
+
+
+
+
+           Thanks  to  Marko  Makela  for his contribution of the AS6500
+        cross assembler.  
+
+                Marko Makela
+                Sillitie 10 A
+                01480 Vantaa
+                Finland
+                Internet: Marko.Makela@Helsinki.Fi
+                EARN/BitNet: msmakela@finuh
+
+
+
+
+
+           Thanks  to  John  Hartman  for his contribution of the AS8051
+        cross assembler and updates to the ASxxxx and ASLINK internals. 
+
+                John L. Hartman
+                jhartman@compuserve.com
+                http://ourworld.compuserve.com/homepages/jhartman/
+
+
+
+
+
+           Thanks  to  G.   Osborn  for his contributions to LKS19.C and
+        LKIHX.C.  
+
+                G. Osborn
+                gary@s-4.com
+
+
+
+
+
+           Thanks  to  Ken  Hornstein  for  his  contribution  of object
+        libraries contained in LKLIBR.C.  
+
+                Ken Hornstein
+                kenh@cmf.nrl.navy.mil
+
+
+                                                                  Page 4
+        
+
+
+
+
+
+
+
+           Thanks to Bill McKinnon for his contributions to the AS8XCXXX
+        cross assembler for the DS8XCXXX series of microprocessors.  
+
+                Bill McKinnon
+                w_mckinnon@conknet.com
+
+
+
+
+
+           Thanks  to  Roger Ivie for his contribution of the ASGB cross
+        assembler for the GameBoy.  
+
+                Roger Ivie
+                ivie@cc.usu.edu
+
+
+                                                                  Page 5
+        
+
+
+        ASxxxx Cross Assemblers, Version 3.11, January 2002 
+
+        Submitted by Alan R.  Baldwin, 
+        Kent State University, Kent, Ohio 
+
+        Operating System:  MS-DOS, Windows, Linux 
+        or other supporting K&R C.  
+
+        Source Langauge:  C 
+
+        Abstract:  
+
+           The  ASxxxx  assemblers are a series of microprocessor assem-
+        blers written in the C programming  language.   This  collection
+        contains cross assemblers for the 6800(6802/6808), 6801(hd6303),
+        6804,  6805,  68HC08,  6809,  68HC11,  68HC12,   68HC16,   8051,
+        8085(8080),  z80(hd64180),  GameBoy(Z80),  H8/3xx,  DS8xCxxx and
+        6500  series  microprocessors.   Each  assembler  has  a  device
+        specific  section  which includes:  (1) device description, byte
+        order, and file extension information, (2) a table of  assembler
+        general  directives, special directives, assembler mnemonics and
+        associated operation codes, (3) machine specific code  for  pro-
+        cessing  the  device  mnemonics,  addressing  modes, and special
+        directives.  
+
+           The assemblers have a common device independent section which
+        handles the details of file input/output, symbol  table  genera-
+        tion,  program/data  areas,  expression  analysis, and assembler
+        directive processing.  
+
+           The  assemblers  provide  the following features:  (1) alpha-
+        betized, formatted symbol table listings, (2) relocatable object
+        modules, (3) global symbols for linking object modules, (4) con-
+        ditional assembly directives, (5) reusable  local  symbols,  and
+        (6) include-file processing.  
+
+           The  companion program ASLINK is a relocating linker perform-
+        ing the following functions:  (1) bind multiple  object  modules
+        into  a  single  memory  image,  (2) resolve inter-module symbol
+        references,  (3)  resolve  undefined  symbols   from   specified
+        librarys of object modules, (4) process absolute, relative, con-
+        catenated, and overlay attributes in data and program  sections,
+        (5)  perform  byte and word program-counter relative (pc or pcr)
+        addressing calculations, (6) define absolute  symbol  values  at
+        link  time, (7) define absolute area base address values at link
+        time, (8) produce Intel Hex or Motorola S  record  output  file,
+        (9)  produce  a  map of the linked memory image, and (10) update
+        the ASxxxx assembler listing files with the absolute linked  ad-
+        dresses and data.  
+
+           The  assemblers  and  linker  have  been  tested using Linux,
+        DJGPP,  Cygwin-1.3.x,  Sun   Solaris   (GCC),   Symantec   C/C++
+        V6.1/V7.2,  and VC6 with MS-DOS/Windows 3.x/9x/NT/2000/XP.  Com-
+        plete source code  and  documentation  for  the  assemblers  and
+        linker  is  included  with the distribution.  Additionally, test
+        code for each assembler and several  microprocessor  monitors  (
+        ASSIST05  for  the  6805,  MONDEB and ASSIST09 for the 6809, and
+
+
+                                                                  Page 6
+        
+
+
+        BUFFALO 2.5 for the 6811) are included as  working  examples  of
+        use of these assemblers.  
+
+
+        CHAPTER 1  THE ASSEMBLER                                     1-1 
+          1.1     THE ASXXXX ASSEMBLERS                              1-1 
+          1.1.1     Assembly Pass 1                                  1-2 
+          1.1.2     Assembly Pass 2                                  1-2 
+          1.1.3     Assembly Pass 3                                  1-2 
+          1.2     SOURCE PROGRAM FORMAT                              1-3 
+          1.2.1     Statement Format                                 1-3 
+          1.2.1.1     Label Field                                    1-3 
+          1.2.1.2     Operator Field                                 1-5 
+          1.2.1.3     Operand Field                                  1-5 
+          1.2.1.4     Comment Field                                  1-6 
+          1.3     SYMBOLS AND EXPRESSIONS                            1-6 
+          1.3.1     Character Set                                    1-6 
+          1.3.2     User-Defined Symbols                            1-10 
+          1.3.3     Local Symbols                                   1-10 
+          1.3.4     Current Location Counter                        1-12 
+          1.3.5     Numbers                                         1-13 
+          1.3.6     Terms                                           1-14 
+          1.3.7     Expressions                                     1-14 
+          1.4     GENERAL ASSEMBLER DIRECTIVES                      1-16 
+          1.4.1     .module Directive                               1-16 
+          1.4.2     .title Directive                                1-16 
+          1.4.3     .sbttl Directive                                1-17 
+          1.4.4     .page Directive                                 1-17 
+          1.4.5     .error Directive                                1-17 
+          1.4.6     .byte and .db Directives                        1-18 
+          1.4.7     .word and .dw Directives                        1-18 
+          1.4.8     .3byte Directive                                1-19 
+          1.4.9     .4byte or .quad Directive                       1-19 
+          1.4.10    .blkb, .blkw, .ds, .blk3, and .blk4
+                    Directives                                      1-20 
+          1.4.11    .ascii Directive                                1-20 
+          1.4.12    .ascis Directive                                1-20 
+          1.4.13    .asciz Directive                                1-21 
+          1.4.14    .assume Directive                               1-21 
+          1.4.15    .radix Directive                                1-22 
+          1.4.16    .even Directive                                 1-22 
+          1.4.17    .odd Directive                                  1-22 
+          1.4.18    .area Directive                                 1-23 
+          1.4.19    .org Directive                                  1-24 
+          1.4.20    .globl Directive                                1-25 
+          1.4.21    .if, .else, and .endif Directives               1-25 
+          1.4.22    .include Directive                              1-26 
+          1.4.23    .setdp Directive                                1-27 
+          1.4.24    .16bit, .24bit, and .32bit Directives           1-29 
+          1.5     INVOKING ASXXXX                                   1-30 
+          1.6     ERRORS                                            1-31 
+          1.7     LISTING FILE                                      1-32 
+          1.8     SYMBOL TABLE FILE                                 1-34 
+          1.9     OBJECT FILE                                       1-35 
+
+        CHAPTER 2  THE LINKER                                        2-1 
+          2.1     ASLINK RELOCATING LINKER                           2-1 
+          2.2     INVOKING ASLINK                                    2-2 
+          2.3     LIBRARY PATH(S) AND FILE(S)                        2-3 
+          2.4     ASLINK PROCESSING                                  2-4 
+
+
+                                                                 Page ii
+        
+
+
+          2.5     LINKER INPUT FORMAT                                2-6 
+          2.5.1     Object Module Format                             2-7 
+          2.5.2     Header Line                                      2-7 
+          2.5.3     Module Line                                      2-7 
+          2.5.4     Symbol Line                                      2-7 
+          2.5.5     Area Line                                        2-8 
+          2.5.6     T Line                                           2-8 
+          2.5.7     R Line                                           2-8 
+          2.5.8     P Line                                           2-9 
+          2.5.9     24-Bit and 32-Bit Addressing                     2-9 
+          2.6     LINKER ERROR MESSAGES                             2-10 
+          2.7     INTEL IHX OUTPUT FORMAT (16-BIT)                  2-12 
+          2.8     INTEL I86 OUTPUT FORMAT (24 OR 32-BIT)            2-13 
+          2.9     MOTORLA S1-S9 OUTPUT FORMAT (16-BIT)              2-14 
+          2.10    MOTORLA S2-S8 OUTPUT FORMAT (24-BIT)              2-15 
+          2.11    MOTORLA S3-S7 OUTPUT FORMAT (32-BIT)              2-16 
+
+        CHAPTER 3  BUILDING ASXXXX AND ASLINK                        3-1 
+          3.1     BUILDING AN ASSEMBLER                              3-1 
+          3.2     BUILDING ASLINK                                    3-2 
+
+        APPENDIX A  AS6800 ASSEMBLER                                 A-1 
+          A.1     6800 REGISTER SET                                  A-1 
+          A.2     6800 INSTRUCTION SET                               A-1 
+          A.2.1     Inherent Instructions                            A-2 
+          A.2.2     Branch Instructions                              A-2 
+          A.2.3     Single Operand Instructions                      A-3 
+          A.2.4     Double Operand Instructions                      A-4 
+          A.2.5     Jump and Jump to Subroutine Instructions         A-4 
+          A.2.6     Long Register Instructions                       A-5 
+
+        APPENDIX B  AS6801 ASSEMBLER                                 B-1 
+          B.1     .hd6303 DIRECTIVE                                  B-1 
+          B.2     6801 REGISTER SET                                  B-1 
+          B.3     6801 INSTRUCTION SET                               B-1 
+          B.3.1     Inherent Instructions                            B-2 
+          B.3.2     Branch Instructions                              B-2 
+          B.3.3     Single Operand Instructions                      B-3 
+          B.3.4     Double Operand Instructions                      B-4 
+          B.3.5     Jump and Jump to Subroutine Instructions         B-5 
+          B.3.6     Long Register Instructions                       B-5 
+          B.3.7     6303 Specific Instructions                       B-5 
+
+        APPENDIX C  AS6804 ASSEMBLER                                 C-1 
+          C.1     6804 REGISTER SET                                  C-1 
+          C.2     6804 INSTRUCTION SET                               C-1 
+          C.2.1     Inherent Instructions                            C-2 
+          C.2.2     Branch Instructions                              C-2 
+          C.2.3     Single Operand Instructions                      C-2 
+          C.2.4     Jump and Jump to Subroutine Instructions         C-2 
+          C.2.5     Bit Test Instructions                            C-2 
+          C.2.6     Load Immediate data Instruction                  C-3 
+
+
+                                                                Page iii
+        
+
+
+          C.2.7     6804 Derived Instructions                        C-3 
+
+        APPENDIX D  AS6805 ASSEMBLER                                 D-1 
+          D.1     6805 REGISTER SET                                  D-1 
+          D.2     6805 INSTRUCTION SET                               D-1 
+          D.2.1     Control Instructions                             D-2 
+          D.2.2     Bit Manipulation Instructions                    D-2 
+          D.2.3     Branch Instructions                              D-2 
+          D.2.4     Read-Modify-Write Instructions                   D-3 
+          D.2.5     Register\Memory Instructions                     D-3 
+          D.2.6     Jump and Jump to Subroutine Instructions         D-4 
+
+        APPENDIX E  AS6808 ASSEMBLER                                 E-1 
+          E.1     68HC08 REGISTER SET                                E-1 
+          E.2     68HC08 INSTRUCTION SET                             E-1 
+          E.2.1     Control Instructions                             E-2 
+          E.2.2     Bit Manipulation Instructions                    E-2 
+          E.2.3     Branch Instructions                              E-3 
+          E.2.4     Complex Branch Instructions                      E-3 
+          E.2.5     Read-Modify-Write Instructions                   E-4 
+          E.2.6     Register\Memory Instructions                     E-5 
+          E.2.7     Double Operand Move Instruction                  E-5 
+          E.2.8     16-Bit <H:X> Index Register Instructions         E-5 
+          E.2.9     Jump and Jump to Subroutine Instructions         E-5 
+
+        APPENDIX F  AS6809 ASSEMBLER                                 F-1 
+          F.1     6809 REGISTER SET                                  F-1 
+          F.2     6809 INSTRUCTION SET                               F-1 
+          F.2.1     Inherent Instructions                            F-3 
+          F.2.2     Short Branch Instructions                        F-3 
+          F.2.3     Long Branch Instructions                         F-3 
+          F.2.4     Single Operand Instructions                      F-4 
+          F.2.5     Double Operand Instructions                      F-5 
+          F.2.6     D-register Instructions                          F-5 
+          F.2.7     Index/Stack Register Instructions                F-5 
+          F.2.8     Jump and Jump to Subroutine Instructions         F-6 
+          F.2.9     Register - Register Instructions                 F-6 
+          F.2.10    Condition Code Register Instructions             F-6 
+          F.2.11    6800 Compatibility Instructions                  F-6 
+
+        APPENDIX G  AS6811 ASSEMBLER                                 G-1 
+          G.1     68HC11 REGISTER SET                                G-1 
+          G.2     68HC11 INSTRUCTION SET                             G-1 
+          G.2.1     Inherent Instructions                            G-2 
+          G.2.2     Branch Instructions                              G-2 
+          G.2.3     Single Operand Instructions                      G-3 
+          G.2.4     Double Operand Instructions                      G-4 
+          G.2.5     Bit Manupulation Instructions                    G-4 
+          G.2.6     Jump and Jump to Subroutine Instructions         G-5 
+          G.2.7     Long Register Instructions                       G-5 
+
+
+
+                                                                 Page iv
+        
+
+
+        APPENDIX H  AS6812 ASSEMBLER                                 H-1 
+          H.1     68HC12 REGISTER SET                                H-1 
+          H.2     68HC12 INSTRUCTION SET                             H-1 
+          H.2.1     Inherent Instructions                            H-3 
+          H.2.2     Short Branch Instructions                        H-3 
+          H.2.3     Long Branch Instructions                         H-3 
+          H.2.4     Branch on Decrement, Test, or Increment          H-4 
+          H.2.5     Bit Clear and Set Instructions                   H-4 
+          H.2.6     Branch on Bit Clear or Set                       H-4 
+          H.2.7     Single Operand Instructions                      H-5 
+          H.2.8     Double Operand Instructions                      H-6 
+          H.2.9     Move Instructions                                H-6 
+          H.2.10    D-register Instructions                          H-6 
+          H.2.11    Index/Stack Register Instructions                H-7 
+          H.2.12    Jump and Jump/Call to Subroutine
+                    Instructions                                     H-7 
+          H.2.13    Other Special Instructions                       H-7 
+          H.2.14    Register - Register Instructions                 H-7 
+          H.2.15    Condition Code Register Instructions             H-7 
+          H.2.16    M68HC11 Compatibility Mode Instructions          H-8 
+
+        APPENDIX I  AS6816 ASSEMBLER                                 I-1 
+          I.1     68HC16 REGISTER SET                                I-1 
+          I.2     68HC16 INSTRUCTION SET                             I-1 
+          I.2.1     Inherent Instructions                            I-2 
+          I.2.2     Push/Pull Multiple Register Instructions         I-3 
+          I.2.3     Short Branch Instructions                        I-3 
+          I.2.4     Long Branch Instructions                         I-3 
+          I.2.5     Bit Manipulation Instructions                    I-3 
+          I.2.6     Single Operand Instructions                      I-4 
+          I.2.7     Double Operand Instructions                      I-5 
+          I.2.8     Index/Stack Register Instructions                I-5 
+          I.2.9     Jump and Jump to Subroutine Instructions         I-6 
+          I.2.10    Condition Code Register Instructions             I-6 
+          I.2.11    Multiply and Accumulate Instructions             I-6 
+
+        APPENDIX J  ASH8 ASSEMBLER                                   J-1 
+          J.1     H8/3XX REGISTER SET                                J-1 
+          J.2     H8/3XX INSTRUCTION SET                             J-1 
+          J.2.1     Inherent Instructions                            J-2 
+          J.2.2     Branch Instructions                              J-2 
+          J.2.3     Single Operand Instructions                      J-3 
+          J.2.4     Double Operand Instructions                      J-4 
+          J.2.5     Mov Instructions                                 J-5 
+          J.2.6     Bit Manipulation Instructions                    J-6 
+          J.2.7     Extended Bit Manipulation Instructions           J-7 
+          J.2.8     Condition Code Instructions                      J-7 
+          J.2.9     Other Instructions                               J-8 
+          J.2.10    Jump and Jump to Subroutine Instructions         J-8 
+
+        APPENDIX K  AS8051 ASSEMBLER                                 K-1 
+          K.1     ACKNOWLEDGMENT                                     K-1 
+
+
+                                                                  Page v
+        
+
+
+          K.2     8051 REGISTER SET                                  K-1 
+          K.3     8051 INSTRUCTION SET                               K-2 
+          K.3.1     Inherent Instructions                            K-2 
+          K.3.2     Move Instructions                                K-3 
+          K.3.3     Single Operand Instructions                      K-3 
+          K.3.4     Two Operand Instructions                         K-4 
+          K.3.5     Call and Return Instructions                     K-4 
+          K.3.6     Jump Instructions                                K-4 
+          K.3.7     Predefined Symbols:  SFR Map                     K-5 
+          K.3.8     Predefined Symbols:  SFR Bit Addresses           K-6 
+          K.3.9     Predefined Symbols:  Control Bits                K-7 
+
+        APPENDIX L  AS8085 ASSEMBLER                                 L-1 
+          L.1     8085 REGISTER SET                                  L-1 
+          L.2     8085 INSTRUCTION SET                               L-1 
+          L.2.1     Inherent Instructions                            L-2 
+          L.2.2     Register/Memory/Immediate Instructions           L-2 
+          L.2.3     Call and Return Instructions                     L-2 
+          L.2.4     Jump Instructions                                L-2 
+          L.2.5     Input/Output/Reset Instructions                  L-3 
+          L.2.6     Move Instructions                                L-3 
+          L.2.7     Other Instructions                               L-3 
+
+        APPENDIX M  AS8XCXXX ASSEMBLER                               M-1 
+          M.1     ACKNOWLEDGMENTS                                    M-1 
+          M.2     DS8XCXXX ASSEMBLER DIRECTIVES                      M-1 
+          M.2.1     DS80C390 Addressing Mode Directive               M-2 
+          M.3     DS8XCXXX REGISTER SET                              M-3 
+          M.4     DS8XCXXX INSTRUCTION SET                           M-3 
+          M.4.1     Inherent Instructions                            M-4 
+          M.4.2     Move Instructions                                M-4 
+          M.4.3     Single Operand Instructions                      M-4 
+          M.4.4     Two Operand Instructions                         M-5 
+          M.4.5     Call and Return Instructions                     M-5 
+          M.4.6     Jump Instructions                                M-5 
+          M.5     DS8XCXXX SPECIAL FUNCTION REGISTERS                M-6 
+          M.5.1     SFR Map                                          M-6 
+          M.5.2     Bit Addressable Registers:  Generic              M-7 
+          M.5.3     Bit Addressable Registers:  Specific             M-8 
+          M.5.4     Optional Symbols:  Control Bits                  M-9 
+          M.6     DS80C310 SPECIAL FUNCTION REGISTERS               M-10 
+          M.6.1     SFR Map                                         M-10 
+          M.6.2     Bit Addressable Registers:  Generic             M-11 
+          M.6.3     Bit Addressable Registers:  Specific            M-12 
+          M.6.4     Optional Symbols:  Control Bits                 M-13 
+          M.7     DS80C320/DS80C323 SPECIAL FUNCTION REGISTERS      M-14 
+          M.7.1     SFR Map                                         M-14 
+          M.7.2     Bit Addressable Registers:  Generic             M-15 
+          M.7.3     Bit Addressable Registers:  Specific            M-16 
+          M.7.4     Optional Symbols:  Control Bits                 M-17 
+          M.8     DS80C390 SPECIAL FUNCTION REGISTERS               M-18 
+          M.8.1     SFR Map                                         M-18 
+
+
+                                                                 Page vi
+        
+
+
+          M.8.2     Bit Addressable Registers:  Generic             M-19 
+          M.8.3     Bit Addressable Registers:  Specific            M-20 
+          M.8.4     Optional Symbols:  Control Bits                 M-21 
+          M.9     DS83C520/DS87C520 SPECIAL FUNCTION REGISTERS      M-23 
+          M.9.1     SFR Map                                         M-23 
+          M.9.2     Bit Addressable Registers:  Generic             M-24 
+          M.9.3     Bit Addressable Registers:  Specific            M-25 
+          M.9.4     Optional Symbols:  Control Bits                 M-26 
+          M.10    DS83C530/DS87C530 SPECIAL FUNCTION REGISTERS      M-27 
+          M.10.1    SFR Map                                         M-27 
+          M.10.2    Bit Addressable Registers:  Generic             M-28 
+          M.10.3    Bit Addressable Registers:  Specific            M-29 
+          M.10.4    Optional Symbols:  Control Bits                 M-30 
+          M.11    DS83C550/DS87C550 SPECIAL FUNCTION REGISTERS      M-31 
+          M.11.1    SFR Map                                         M-31 
+          M.11.2    Bit Addressable Registers:  Generic             M-33 
+          M.11.3    Bit Addressable Registers:  Specific            M-34 
+          M.11.4    Optional Symbols:  Control Bits                 M-36 
+
+        APPENDIX N  ASZ80 ASSEMBLER                                  N-1 
+          N.1     .hd64 DIRECTIVE                                    N-1 
+          N.2     Z80 REGISTER SET AND CONDITIONS                    N-1 
+          N.3     Z80 INSTRUCTION SET                                N-2 
+          N.3.1     Inherent Instructions                            N-3 
+          N.3.2     Implicit Operand Instructions                    N-3 
+          N.3.3     Load Instruction                                 N-4 
+          N.3.4     Call/Return Instructions                         N-4 
+          N.3.5     Jump and Jump to Subroutine Instructions         N-4 
+          N.3.6     Bit Manipulation Instructions                    N-5 
+          N.3.7     Interrupt Mode and Reset Instructions            N-5 
+          N.3.8     Input and Output Instructions                    N-5 
+          N.3.9     Register Pair Instructions                       N-5 
+          N.3.10    HD64180 Specific Instructions                    N-6 
+
+        APPENDIX O  ASGB ASSEMBLER                                   O-1 
+          O.1     ACKNOWLEDGEMENT                                    O-1 
+          O.2     INTRODUCTION                                       O-1 
+          O.3     GAMEBOY REGISTER SET AND CONDITIONS                O-1 
+          O.4     GAMEBOY INSTRUCTION SET                            O-2 
+          O.4.1     .tile Directive                                  O-2 
+          O.4.2     Potentially Controversial Mnemonic Selection     O-4 
+          O.4.2.1     Auto-Indexing Loads                            O-4 
+          O.4.2.2     Input and Output Operations                    O-4 
+          O.4.2.3     The 'stop' Instruction                         O-5 
+          O.4.3     Inherent Instructions                            O-5 
+          O.4.4     Implicit Operand Instructions                    O-5 
+          O.4.5     Load Instructions                                O-6 
+          O.4.6     Call/Return Instructions                         O-6 
+          O.4.7     Jump Instructions                                O-6 
+          O.4.8     Bit Manipulation Instructions                    O-6 
+          O.4.9     Input and Output Instructions                    O-7 
+          O.4.10    Register Pair Instructions                       O-7 
+
+
+                                                                Page vii
+        
+
+
+        APPENDIX P  AS6500 ASSEMBLER                                 P-1 
+          P.1     ACKNOWLEDGMENT                                     P-1 
+          P.2     6500 REGISTER SET                                  P-2 
+          P.3     6500 INSTRUCTION SET                               P-2 
+          P.3.1     Processor Specific Directives                    P-3 
+          P.3.2     65xx Core Inherent Instructions                  P-3 
+          P.3.3     65xx Core Branch Instructions                    P-3 
+          P.3.4     65xx Core Single Operand Instructions            P-3 
+          P.3.5     65xx Core Double Operand Instructions            P-4 
+          P.3.6     65xx Core Jump and Jump to Subroutine
+                    Instructions                                     P-4 
+          P.3.7     65xx Core Miscellaneous X and Y Register
+                    Instructions                                     P-4 
+          P.3.8     65F11 and 65F12 Specific Instructions            P-5 
+          P.3.9     65C00/21 and 65C29 Specific Instructions         P-5 
+          P.3.10    65C02, 65C102, and 65C112 Specific
+                    Instructions                                     P-6 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                    CHAPTER 1
+
+                                  THE ASSEMBLER
+
+
+
+
+
+        1.1  THE ASXXXX ASSEMBLERS 
+
+
+           The  ASxxxx  assemblers are a series of microprocessor assem-
+        blers written in the C programming language.  Each assembler has
+        a device specific section which includes:  
+
+             1.  device  description, byte order, and file extension in-
+                 formation 
+
+             2.  a  table  of  the assembler general directives, special
+                 device directives, assembler mnemonics  and  associated
+                 operation codes 
+
+             3.  machine specific code for processing the device mnemon-
+                 ics, addressing modes, and special directives 
+
+        The device specific information is detailed in the appendices.  
+
+           The assemblers have a common device independent section which
+        handles the details of file input/output, symbol  table  genera-
+        tion,  program/data  areas,  expression  analysis, and assembler
+        directive processing.  
+
+        The assemblers provide the following features:  
+
+             1.  Command string control of assembly functions 
+
+             2.  Alphabetized, formatted symbol table listing 
+
+             3.  Relocatable object modules 
+
+             4.  Global symbols for linking object modules 
+
+             5.  Conditional assembly directives 
+
+
+
+        THE ASSEMBLER                                           PAGE 1-2
+        THE ASXXXX ASSEMBLERS
+
+
+             6.  Program sectioning directives 
+
+
+           ASxxxx assembles one or more source files into a single relo-
+        catable ascii object file.  The output of the ASxxxx  assemblers
+        consists of an ascii relocatable object file(*.rel), an assembly
+        listing file(*.lst), and a symbol file(*.sym).  
+
+
+        1.1.1  Assembly Pass 1 
+
+
+           During  pass  1, ASxxxx opens all source files and performs a
+        rudimenatry assembly of each source statement.  During this pro-
+        cess  all symbol tables are built, program sections defined, and
+        number of bytes for each assembled source line is estimated.  
+
+           At the end of pass 1 all undefined symbols may be made global
+        (external) using the ASxxxx switch -g, otherwise undefined  sym-
+        bols will be flagged as errors during succeeding passes.  
+
+
+        1.1.2  Assembly Pass 2 
+
+
+           During  pass  2  the ASxxxx assembler resolves forward refer-
+        ences and determines the number  of  bytes  for  each  assembled
+        line.   The  number  of bytes used by a particular assembler in-
+        struction may depend upon the addressing mode, whether  the  in-
+        struction allows multiple forms based upon the relative distance
+        to the addressed location, or other factors.   Pass  2  resolves
+        these cases and determines the address of all symbols.  
+
+
+        1.1.3  Assembly Pass 3 
+
+
+           Pass 3 by the assembler generates the listing file, the relo-
+        catable output file, and the symbol tables.  Also during pass  3
+        the errors will be reported.  
+
+           The  relocatable object file is an ascii file containing sym-
+        bol references and definitions, program  area  definitions,  and
+        the  relocatable assembled code, the linker ASLINK will use this
+        information to generate an absolute load file (Motorola or Intel
+        formats).  
+
+
+
+
+        THE ASSEMBLER                                           PAGE 1-3
+        SOURCE PROGRAM FORMAT
+
+
+        1.2  SOURCE PROGRAM FORMAT 
+
+
+
+        1.2.1  Statement Format 
+
+
+           A source program is composed of assembly-language statements.
+        Each statement must be completed on one line.  A line  may  con-
+        tain a maximum of 128 characters, longer lines are truncated and
+        lost.  
+
+           An  ASxxxx  assembler  statement  may  have  as  many as four
+        fields.  These fields are identified by their order  within  the
+        statement  and/or  by separating characters between fields.  The
+        general format of the ASxxxx statement is:  
+
+              [label:]  Operator        Operand         [;Comment(s)] 
+
+           The  label and comment fields are optional.  The operator and
+        operand fields are interdependent.  The operator field may be an
+        assembler  directive or an assembly mnemonic.  The operand field
+        may be optional or required as defined in  the  context  of  the
+        operator.  
+
+           ASxxxx  interprets  and  processes source statements one at a
+        time.  Each statement causes a particular operation to  be  per-
+        formed.  
+
+
+        1.2.1.1  Label Field  - 
+
+           A  label is a user-defined symbol which is assigned the value
+        of the current location counter and entered into  the  user  de-
+        fined  symbol  table.   The  current location counter is used by
+        ASxxxx to assign memory addresses to the source  program  state-
+        ments as they are encountered during the assembly process.  Thus
+        a label is a means  of  symbolically  referring  to  a  specific
+        statement.  
+
+           When  a program section is absolute, the value of the current
+        location counter is absolute;  its value references an  absolute
+        memory  address.   Similarly, when a program section is relocat-
+        able, the value of the current location counter is  relocatable.
+        A  relocation  bias  calculated at link time is added to the ap-
+        parent value of the current location counter  to  establish  its
+        effective  absolute  address  at  execution time.  (The user can
+        also force the linker to relocate sections defined as  absolute.
+        This may be required under special circumstances.) 
+
+           If  present,  a  label  must  be  the first field in a source
+        statement and must be terminated by a colon (:).   For  example,
+
+
+        THE ASSEMBLER                                           PAGE 1-4
+        SOURCE PROGRAM FORMAT
+
+
+        if  the  value  of  the  current  location  counter  is absolute
+        01F0(H), the statement:  
+
+              abcd:     nop 
+
+        assigns  the  value  01F0(H) to the label abcd.  If the location
+        counter value were relocatable, the final value of abcd would be
+        01F0(H)+K, where K represents the relocation bias of the program
+        section, as calculated by the linker at link time.  
+
+           More  than  one label may appear within a single label field.
+        Each label so specified is assigned the same address value.  For
+        example,  if  the  value  of  the  current  location  counter is
+        1FF0(H), the multiple labels in the following statement are each
+        assigned the value 1FF0(H):  
+
+              abcd:     aq:     $abc:   nop 
+
+           Multiple labels may also appear on successive lines.  For ex-
+        ample, the statements 
+
+              abcd:  
+              aq:  
+              $abc:     nop 
+
+        likewise  cause  the  same value to be assigned to all three la-
+        bels.  
+
+           A  double  colon  (::)  defines the label as a global symbol.
+        For example, the statement 
+
+              abcd::    nop 
+
+        establishes the label abcd as a global symbol.  The distinguish-
+        ing attribute of a global symbol is that it  can  be  referenced
+        from  within an object module other than the module in which the
+        symbol is defined.  References to this label  in  other  modules
+        are  resolved when the modules are linked as a composite execut-
+        able image.  
+
+        The legal characters for defining labels are:  
+
+                A through Z 
+                a through z 
+                0 through 9 
+                . (Period) 
+                $ (Dollar sign) 
+                _ (underscore) 
+
+           A  label  may  be  any  length,  however  only  the  first 79
+        characters are significant and, therefore must be  unique  among
+        all   labels  in  the  source  program  (not  necessarily  among
+
+
+        THE ASSEMBLER                                           PAGE 1-5
+        SOURCE PROGRAM FORMAT
+
+
+        separately compiled modules).  An error code(s) (m or p) will be
+        generated  in the assembly listing if the first 79 characters in
+        two or more labels are the same.  The m code is  caused  by  the
+        redeclaration  of  the symbol or its reference by another state-
+        ment.  The p code is generated because the symbols  location  is
+        changing on each pass through the source file.  
+
+           The  label  must  not  start with the characters 0-9, as this
+        designates a local symbol with special attributes described in a
+        later section.  
+
+           The  label  must  not  start  with  the  sequence $$, as this
+        represents the temporary radix 16 for constants.  
+
+
+        1.2.1.2  Operator Field  - 
+
+           The  operator field specifies the action to be performed.  It
+        may consist of an instruction mnemonic (op code) or an assembler
+        directive.  
+
+           When  the  operator is an instruction mnemonic, a machine in-
+        struction is generated and the assembler evaluates the addresses
+        of  the operands which follow.  When the operator is a directive
+        ASxxxx performs certain control actions or processing operations
+        during assembly of the source program.  
+
+           Leading  and  trailing  spaces  or tabs in the operator field
+        have no significance;  such characters serve  only  to  separate
+        the operator field from the preceeding and following fields.  
+
+           An operator is terminated by a space, tab or end of line.  
+
+
+        1.2.1.3  Operand Field  - 
+
+           When  the  operator is an instruction mnemonic (op code), the
+        operand  field  contains  program  variables  that  are  to   be
+        evaluated/manipulated by the operator.  
+
+           Operands  may  be  expressions  or  symbols, depending on the
+        operator.  Multiple expressions used in the operand  fields  may
+        be  separated  by a comma.  An operand should be preceeded by an
+        operator field;  if it is not, the statement will give an  error
+        (q  or  o).   All  operands  following instruction mnemonics are
+        treated as expressions.  
+
+           The operand field is terminated by a semicolon when the field
+        is followed  by  a  comment.   For  example,  in  the  following
+        statement:  
+
+              label:    lda     abcd,x          ;Comment field 
+
+
+        THE ASSEMBLER                                           PAGE 1-6
+        SOURCE PROGRAM FORMAT
+
+
+
+        the  tab  between lda and abcd terminates the operator field and
+        defines the beginning of the operand field;  a  comma  separates
+        the operands abcd and x;  and a semicolon terminates the operand
+        field and defines the beginning of the comment field.   When  no
+        comment  field  follows,  the operand field is terminated by the
+        end of the source line.  
+
+
+        1.2.1.4  Comment Field  - 
+
+           The comment field begins with a semicolon and extends through
+        the end of the line.  This field is optional and may contain any
+        7-bit ascii character except null.  
+
+           Comments  do not affect assembly processing or program execu-
+        tion.  
+
+
+        1.3  SYMBOLS AND EXPRESSIONS 
+
+
+           This  section  describes the generic components of the ASxxxx
+        assemblers:  the character set, the conventions observed in con-
+        structing  symbols,  and  the use of numbers, operators, and ex-
+        pressions.  
+
+
+        1.3.1  Character Set 
+
+
+           The following characters are legal in ASxxxx source programs: 
+
+             1.  The  letters  A  through Z.  Both upper- and lower-case
+                 letters are acceptable.  The  assemblers,  by  default,
+                 are  not  case  sensitive,  i.e.  ABCD and abcd are the
+                 same symbols.  (The assemblers can be made case  sensi-
+                 tive by using the -z command line option.) 
+
+             2.  The digits 0 through 9 
+
+             3.  The  characters . (period), $ (dollar sign), and _ (un-
+                 derscore).  
+
+             4.  The special characters listed in Tables 1 through 6.  
+
+
+           Tables  1  through  6  describe  the various ASxxxx label and
+        field terminators, assignment operators, operand separators, as-
+        sembly, unary, binary, and radix operators.  
+
+
+        THE ASSEMBLER                                           PAGE 1-7
+        SYMBOLS AND EXPRESSIONS
+
+
+        Table 1         Label Terminators and Assignment Operators 
+        ---------------------------------------------------------------- 
+
+                :   Colon               Label terminator.  
+
+                ::  Double colon        Label  Terminator;   defines the
+                                        label as a global label.  
+
+                =   Equal sign          Direct assignment operator.  
+
+                ==  Double equal        Direct assignment operator;  
+                    sign                defines  the  symbol as a global
+                                        symbol.  
+
+        ---------------------------------------------------------------- 
+
+
+
+
+
+        Table 2         Field Terminators and Operand Separators 
+        ---------------------------------------------------------------- 
+
+                    Tab                 Item or field terminator.  
+
+                    Space               Item or field terminator.  
+
+                ,   Comma               Operand field separator.  
+
+                ;   Semicolon           Comment field indicator.  
+
+        ---------------------------------------------------------------- 
+
+
+
+
+
+        Table 3         Assembler Operators 
+        ---------------------------------------------------------------- 
+
+                #   Number sign         Immediate expression indicator. 
+
+                .   Period              Current location counter.  
+
+                (   Left parenthesis    Expression delimiter.  
+
+                )   Right parenthesis   Expression delimeter.  
+
+        ---------------------------------------------------------------- 
+
+
+        THE ASSEMBLER                                           PAGE 1-8
+        SYMBOLS AND EXPRESSIONS
+
+
+
+
+
+
+
+        Table 4         Unary Operators 
+        ---------------------------------------------------------------- 
+
+                <   Left bracket        <FEDC   Produces  the lower byte
+                                                value of the expression.
+                                                (DC) 
+
+                >   Right bracket       >FEDC   Produces  the upper byte
+                                                value of the expression.
+                                                (FE) 
+
+                +   Plus sign           +A      Positive value of A 
+
+                -   Minus sign          -A      Produces   the  negative
+                                                (2's complement) of A.  
+
+                ~   Tilde               ~A      Produces the 1's comple-
+                                                ment of A.  
+
+                '   Single quote        'D      Produces  the  value  of
+                                                the character D.  
+
+                "   Double quote        "AB     Produces the double byte
+                                                value for AB.  
+
+                \   Backslash           '\n     Unix style characters 
+                                                \b, \f, \n, \r, \t 
+                                     or '\001   or octal byte values.  
+
+        ---------------------------------------------------------------- 
+
+
+
+
+
+
+
+        THE ASSEMBLER                                           PAGE 1-9
+        SYMBOLS AND EXPRESSIONS
+
+
+        Table 5         Binary Operators 
+        ---------------------------------------------------------------- 
+
+                <<  Double          0800 << 4   Produces the 4 bit 
+                    Left bracket                left-shifted   value  of
+                                                0800.  (8000) 
+
+                >>  Double          0800 >> 4   Produces the 4 bit 
+                    Right bracket               right-shifted  value  of
+                                                0800.  (0080) 
+
+                +   Plus sign       A + B       Arithmetic      Addition
+                                                operator.  
+
+                -   Minus sign      A - B       Arithmetic   Subtraction
+                                                operator.  
+
+                *   Asterisk        A * B       Arithmetic   Multiplica-
+                                                tion operator.  
+
+                /   Slash           A / B       Arithmetic      Division
+                                                operator.  
+
+                &   Ampersand       A & B       Logical AND operator.  
+
+                |   Bar             A | B       Logical OR operator.  
+
+                %   Percent sign    A % B       Modulus operator.  
+
+                ^   Up arrow or     A ^ B       EXCLUSIVE OR operator.  
+                    circumflex 
+
+        ---------------------------------------------------------------- 
+
+
+
+
+
+        Table 6         Temporary Radix Operators 
+        ---------------------------------------------------------------- 
+
+                $%,   0b, 0B            Binary radix operator.  
+
+                $&,   0o, 0O, 0q, 0Q    Octal radix operator.  
+
+                $#,   0d, 0D            Decimal radix operator.  
+
+                $$,   0h, 0H, 0x, 0X    Hexidecimal radix operator.  
+
+
+                Potential  ambiguities arising from the use of 0b and 0d
+                as temporary radix  operators  may  be  circumvented  by
+
+
+        THE ASSEMBLER                                          PAGE 1-10
+        SYMBOLS AND EXPRESSIONS
+
+
+                preceding  all non-prefixed hexidecimal numbers with 00.
+                Leading 0's are required in any  case  where  the  first
+                hexidecimal  digit is abcdef as the assembler will treat
+                the letter sequence as a label.  
+
+        ---------------------------------------------------------------- 
+
+
+
+
+
+
+
+        1.3.2  User-Defined Symbols 
+
+
+           User-defined  symbols are those symbols that are equated to a
+        specific value through a direct assignment statement  or  appear
+        as  labels.  These symbols are added to the User Symbol Table as
+        they are encountered during assembly.  
+
+        The following rules govern the creation of user-defined symbols: 
+
+             1.  Symbols  can  be  composed  of alphanumeric characters,
+                 dollar signs ($),  periods  (.),  and  underscores  (_)
+                 only.  
+
+             2.  The  first  character  of a symbol must not be a number
+                 (except in the case of local symbols).  
+
+             3.  The  first 79 characters of a symbol must be unique.  A
+                 symbol  can  be  written  with  more  than   79   legal
+                 characters,  but the 80th and subsequent characters are
+                 ignored.  
+
+             4.  Spaces and Tabs must not be embedded within a symbol.  
+
+
+
+        1.3.3  Local Symbols 
+
+
+           Local  symbols are specially formatted symbols used as labels
+        within a block of coding that has been delimited as a local sym-
+        bol  block.   Local  symbols  are  of  the form n$, where n is a
+        decimal integer from 0 to 255,  inclusive.   Examples  of  local
+        symbols are:  
+
+              1$ 
+              27$ 
+              138$ 
+              244$ 
+
+
+        THE ASSEMBLER                                          PAGE 1-11
+        SYMBOLS AND EXPRESSIONS
+
+
+           The  range  of  a local symbol block consists of those state-
+        ments between two normally constructed  symbolic  labels.   Note
+        that a statement of the form:  
+
+              ALPHA = EXPRESSION 
+
+        is a direct assignment statement but does not create a label and
+        thus does not delimit the range of a local symbol block.  
+
+           Note that the range of a local symbol block may extend across
+        program areas.  
+
+           Local symbols provide a convenient means of generating labels
+        for branch instructions and other such references  within  local
+        symbol  blocks.   Using local symbols reduces the possibility of
+        symbols with multiple definitions appearing within a  user  pro-
+        gram.   In  addition,  the  use  of local symbols differentiates
+        entry-point labels from local labels, since local labels  cannot
+        be referenced from outside their respective local symbol blocks.
+        Thus, local symbols of the same name can appear in  other  local
+        symbol blocks without conflict.  Local symbols require less sym-
+        bol table space than normal symbols.  Their use is recommended. 
+
+           The  use of the same local symbol within a local symbol block
+        will generate one or both of the m or p errors.  
+
+        Example of local symbols:  
+
+                a:      ldx     #atable ;get table address
+                        lda     #0d48   ;table length
+                1$:     clr     ,x+     ;clear
+                        deca
+                        bne     1$
+                        
+                b:      ldx     #btable ;get table address
+                        lda     #0d48   ;table length
+                1$:     clr     ,x+     ;clear
+                        deca
+                        bne     1$
+
+
+
+
+        THE ASSEMBLER                                          PAGE 1-12
+        SYMBOLS AND EXPRESSIONS
+
+
+        1.3.4  Current Location Counter 
+
+
+           The  period  (.) is the symbol for the current location coun-
+        ter.  When used in the operand  field  of  an  instruction,  the
+        period   represents  the  address  of  the  first  byte  of  the
+        instruction:  
+
+                AS:     ldx     #.      ;The period (.) refers to
+                                        ;the address of the ldx
+                                        ;instruction.
+
+           When  used  in  the  operand field of an ASxxxx directive, it
+        represents the address of the current byte or word:  
+
+                QK = 0
+        
+                .word   0xFFFE,.+4,QK   ;The operand .+4 in the .word
+                                        ;directive represents a value
+                                        ;stored in the second of the
+                                        ;three words during assembly.
+
+           If  we  assume  the  current  value of the program counter is
+        0H0200, then during assembly, ASxxxx  reserves  three  words  of
+        storage  starting  at  location 0H0200.  The first value, a hex-
+        idecimal constant FFFE, will be stored at location 0H0200.   The
+        second  value  represented  by  .+4  will  be stored at location
+        0H0202, its value will be 0H0206 ( = 0H0202  +  4).   The  third
+        value  defined  by  the  symbol  QK  will  be placed at location
+        0H0204.  
+
+           At the beginning of each assembly pass, ASxxxx resets the lo-
+        cation counter.  Normally, consecutive memory locations are  as-
+        signed  to  each  byte  of  object code generated.  However, the
+        value of the location counter can be changed  through  a  direct
+        assignment statement of the following form:  
+
+              . = . + expression 
+
+
+           The  new  location  counter can only be specified relative to
+        the current location counter.  Neglecting to specify the current
+        program  counter  along with the expression on the right side of
+        the assignment operator will generate the (.) error.   (Absolute
+        program areas may use the .org directive to specify the absolute
+        location of the current program counter.) 
+
+        The following coding illustrates the use of the current location
+        counter:  
+
+                .area   CODE1   (ABS)   ;program area CODE1
+                                        ;is ABSOLUTE
+
+
+        THE ASSEMBLER                                          PAGE 1-13
+        SYMBOLS AND EXPRESSIONS
+
+
+        
+                .org    0H100           ;set location to
+                                        ;0H100 absolute
+        
+        num1:   ldx     #.+0H10         ;The label num1 has
+                                        ;the value 0H100.
+                                        ;X is loaded with
+                                        ;0H100 + 0H10
+        
+                .org    0H130           ;location counter
+                                        ;set to 0H130
+        
+        num2:   ldy     #.              ;The label num2 has
+                                        ;the value 0H130.
+                                        ;Y is loaded with
+                                        ;value 0H130.
+        
+        
+                .area   CODE2   (REL)   ;program area CODE2
+                                        ;is RELOCATABLE
+        
+                . = . + 0H20            ;Set location counter
+                                        ;to relocatable 0H20 of
+                                        ;the program section.
+        
+        num3:   .word   0               ;The label num3 has
+                                        ;the value
+                                        ;of relocatable 0H20.
+        
+                . = . + 0H40            ;will reserve 0H40
+                                        ;bytes of storage as will
+                .blkb   0H40            ;or
+                .blkw   0H20
+
+           The  .blkb  and .blkw directives are the preferred methods of
+        allocating space.  
+
+
+        1.3.5  Numbers 
+
+
+           ASxxxx  assumes that all numbers in the source program are to
+        be interpreted in decimal radix unless otherwise specified.  The
+        .radix  directive  may  be used to specify the default as octal,
+        decimal, or hexidecimal.  Individual numbers can  be  designated
+        as  binary, octal, decimal, or hexidecimal through the temporary
+        radix prefixes shown in table 6.  
+
+           Negative  numbers  must be preceeded by a minus sign;  ASxxxx
+        translates such numbers into two's  complement  form.   Positive
+        numbers may (but need not) be preceeded by a plus sign.  
+
+
+
+        THE ASSEMBLER                                          PAGE 1-14
+        SYMBOLS AND EXPRESSIONS
+
+
+           Numbers are always considered to be absolute values, therefor
+        they are never relocatable.  
+
+
+        1.3.6  Terms 
+
+
+           A  term is a component of an expression and may be one of the
+        following:  
+
+
+             1.  A number.  
+
+             2.  A symbol:  
+                 1.  A  period (.) specified in an expression causes the
+                     current location counter to be used.  
+                 2.  A User-defined symbol.  
+                 3.  An undefined symbol is assigned a value of zero and
+                     inserted in the User-Defined symbol table as an un-
+                     defined symbol.  
+
+             3.  A single quote followed by a single ascii character, or
+                 a double quote followed by two ascii characters.  
+
+             4.  An  expression enclosed in parenthesis.  Any expression
+                 so enclosed is evaluated and reduced to a  single  term
+                 before  the remainder of the expression in which it ap-
+                 pears is evaluated.  Parenthesis, for example,  may  be
+                 used  to  alter the left-to-right evaluation of expres-
+                 sions, (as in A*B+C versus A*(B+C)), or to apply a  un-
+                 ary operator to an entire expression (as in -(A+B)).  
+
+             5.  A unary operator followed by a symbol or number.  
+
+
+
+        1.3.7  Expressions 
+
+
+           Expressions  are  combinations  of  terms  joined together by
+        binary operators.  Expressions reduce to a value.   The  evalua-
+        tion  of  an expression includes the determination of its attri-
+        butes.  A resultant expression value may be one of  three  types
+        (as  described  later  in this section):  relocatable, absolute,
+        and external.  
+
+
+
+        THE ASSEMBLER                                          PAGE 1-15
+        SYMBOLS AND EXPRESSIONS
+
+
+        Expressions are evaluate with an operand hierarchy as follows:  
+
+                *       /       %       multiplication,
+                                        division, and
+                                        modulus first.
+        
+                +       -               addition and
+                                        subtraction second.
+        
+                <<      >>              left shift and
+                                        right shift third.
+        
+                ^                       exclusive or fourth.
+        
+                &                       logical and fifth.
+        
+                |                       logical or last
+        
+                except that unary operators take precedence over binary
+                operators.
+
+
+           A  missing  or  illegal  operator  terminates  the expression
+        analysis, causing error codes (o) and/or  (q)  to  be  generated
+        depending upon the context of the expression itself.  
+
+           At assembly time the value of an external (global) expression
+        is equal to the value of the absolute part of  that  expression.
+        For  example,  the expression external+4, where 'external' is an
+        external symbol, has the value of 4.  This expression,  however,
+        when  evaluated  at link time takes on the resolved value of the
+        symbol 'external', plus 4.  
+
+           Expressions,  when  evaluated  by  ASxxxx,  are  one of three
+        types:  relocatable, absolute, or external.  The following  dis-
+        tinctions are important:  
+
+             1.  An  expression is relocatable if its value is fixed re-
+                 lative to the base address of the program area in which
+                 it appears;  it will have an offset value added at link
+                 time.  Terms that contain labels defined in relocatable
+                 program  areas  will  have  a relocatable value;  simi-
+                 larly, a period (.)  in  a  relocatable  program  area,
+                 representing  the value of the current program location
+                 counter, will also have a relocatable value.  
+
+             2.  An  expression  is  absolute if its value is fixed.  An
+                 expression whose terms are numbers and ascii characters
+                 will  reduce  to  an absolute value.  A relocatable ex-
+                 pression or term minus a relocatable term,  where  both
+                 elements  being  evaluated  belong  to the same program
+                 area, is an absolute expression.  This is because every
+
+
+        THE ASSEMBLER                                          PAGE 1-16
+        SYMBOLS AND EXPRESSIONS
+
+
+                 term  in  a  program area has the same relocation bias.
+                 When one term is subtracted from the other the  reloca-
+                 tion bias is zero.  
+
+             3.  An  expression is external (or global) if it contains a
+                 single global reference (plus or minus an absolute  ex-
+                 pression  value) that is not defined within the current
+                 program.  Thus, an external  expression  is  only  par-
+                 tially  defined following assembly and must be resolved
+                 at link time.  
+
+
+
+        1.4  GENERAL ASSEMBLER DIRECTIVES 
+
+
+           An  ASxxxx  directive  is placed in the operator field of the
+        source line.  Only one directive is  allowed  per  source  line.
+        Each  directive  may  have  a blank operand field or one or more
+        operands.  Legal operands differ with each directive.  
+
+
+        1.4.1  .module Directive 
+
+        Format:  
+
+                .module string 
+
+           The .module directive causes the string to be included in the
+        assemblers output file as an identifier for this particular  ob-
+        ject  module.   The  string  may  be  from 1 to 79 characters in
+        length.  Only one identifier is allowed  per  assembled  module.
+        The  main use of this directive is to allow the linker to report
+        a modules' use of undefined symbols.  At link time all undefined
+        symbols  are  reported  and  the  modules  referencing  them are
+        listed.  
+
+
+        1.4.2  .title Directive 
+
+        Format:  
+
+                .title  string 
+
+           The .title directive provides a character string to be placed
+        on the second line of each page during listing.  
+
+
+
+
+        THE ASSEMBLER                                          PAGE 1-17
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        1.4.3  .sbttl Directive 
+
+        Format:  
+
+                .sbttl  string 
+
+           The .sbttl directive provides a character string to be placed
+        on the third line of each page during listing.  
+
+
+        1.4.4  .page Directive 
+
+        Format:  
+
+                .page 
+
+           The .page directive causes a page ejection with a new heading
+        to be printed.  The new page occurs after the next line  of  the
+        source  program is processed, this allows an immediately follow-
+        ing .sbttl directive to appear  on  the  new  page.   The  .page
+        source  line will not appear in the file listing.  Paging may be
+        disabled by invoking the -p directive.  
+
+
+        1.4.5  .error Directive 
+
+        Format:  
+
+                .error exp 
+
+        where:  exp     represents   an  absolute  expression.   If  the
+                        evaluation of the expression results  in  a  non
+                        zero value then an 'e' error is reported and the
+                        text line is listed in the generated error.  
+
+
+           The  .error  directive  is  useful to report configuration or
+        value errors during the assembly process.  (The .error directive
+        is  identical in function to the .assume directive, just perhaps
+        more descriptive.) 
+
+
+
+
+        THE ASSEMBLER                                          PAGE 1-18
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        1.4.6  .byte and .db Directives 
+
+        Format:  
+
+                .byte   exp             ;Stores the binary value
+                .db     exp             ;of the expression in the
+                                        ;next byte.
+        
+                .byte   exp1,exp2,expn  ;Stores the binary values
+                .db     exp1,exp2,expn  ;of the list of expressions
+                                        ;in successive bytes.
+        
+        where:  exp,    represent expressions that will be
+                exp1,   truncated to 8-bits of data.
+                .       Each expression will be calculated,
+                .       the high-order byte will be truncated.
+                .       Multiple expressions must be
+                expn    separated by commas.
+
+           The  .byte  or .db directives are used to generate successive
+        bytes of binary data in the object module.  
+
+
+        1.4.7  .word and .dw Directives 
+
+        Format:  
+
+                .word   exp             ;Stores the binary value
+                .dw     exp             ;of the expression in
+                                        ;the next word.
+        
+                .word   exp1,exp2,expn  ;Stores the binary values
+                .dw     exp1,exp2,expn  ;of the list of expressions
+                                        ;in successive words.
+        
+        where:  exp,    represent expressions that will occupy two
+                exp1,   bytes of data. Each expression will be
+                .       calculated as a 16-bit word expression.
+                .       Multiple expressions must be
+                expn    separated by commas.
+
+           The  .word  or .dw directives are used to generate successive
+        words of binary data in the object module.  
+
+
+
+
+        THE ASSEMBLER                                          PAGE 1-19
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        1.4.8  .3byte Directive 
+
+        Format:  
+
+                .3byte  exp             ;Stores the binary value
+                                        ;of the expression in
+                                        ;the next triple (3 bytes).
+        
+                .3byte  exp1,exp2,expn  ;Stores the binary values
+                                        ;of the list of expressions
+                                        ;in successive triples
+                                        ;(3 bytes).
+        
+        where:  exp,    represent expressions that will occupy three
+                exp1,   bytes of data. Each expression will be
+                .       calculated as a 24-bit word expression.
+                .       Multiple expressions must be
+                expn    separated by commas.
+
+           The  .3byte  directive is used to generate successive triples
+        of binary data in the object module.  (This  directive  is  only
+        available in assemblers supporting 24-bit addressing.) 
+
+
+        1.4.9  .4byte or .quad Directive 
+
+        Format:  
+
+                .4byte  exp             ;Stores the binary value
+                .quad   exp             ;of the expression in
+                                        ;the next quad (4 bytes).
+        
+                .4byte  exp1,exp2,expn  ;Stores the binary values
+                .quad   exp1,exp2,expn  ;of the list of expressions
+                                        ;in successive quads
+                                        ;(4 bytes).
+        
+        where:  exp,    represent expressions that will occupy three
+                exp1,   bytes of data. Each expression will be
+                .       calculated as a 32-bit word expression.
+                .       Multiple expressions must be
+                expn    separated by commas.
+
+           The  .4byte or .quad directive is used to generate successive
+        quads of binary data in the object module.  (This  directive  is
+        only available in assemblers supporting 32-bit addressing.) 
+
+
+
+
+        THE ASSEMBLER                                          PAGE 1-20
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        1.4.10  .blkb, .blkw, .ds, .blk3, and .blk4 Directives 
+
+        Format:  
+
+                .blkb   N       ;reserve N bytes of space
+                .blkw   N       ;reserve N words of space
+                .ds     N       ;reserve N bytes of space
+                .blk3   N       ;reserve N triples of space
+                .blk4   N       ;reserve N quads of space
+
+           The  .blkb  and .ds directives reserve byte blocks in the ob-
+        ject module;  the .blkw directive  reserves  word  blocks;   the
+        .blk3  reserves  3 byte blocks(available in assembles supporting
+        24-bit addressing);  the .blk4 reserves 4 byte blocks (available
+        in assemblers supporting 32-bit addressing).  
+
+
+        1.4.11  .ascii Directive 
+
+        Format:  
+
+                .ascii  /string/ 
+
+        where:  string  is a string of printable ascii characters.  
+
+                /  /    represent   the  delimiting  characters.   These
+                        delimiters   may   be   any   paired    printing
+                        characters,  as  long  as the characters are not
+                        contained within  the  string  itself.   If  the
+                        delimiting  characters  do not match, the .ascii
+                        directive will give the (q) error.  
+
+        The  .ascii  directive  places  one binary byte of data for each
+        character in the string into the object module.  
+
+
+        1.4.12  .ascis Directive 
+
+        Format:  
+
+                .ascis  /string/ 
+
+        where:  string  is a string of printable ascii characters.  
+
+                /  /    represent   the  delimiting  characters.   These
+                        delimiters   may   be   any   paired    printing
+                        characters,  as  long  as the characters are not
+                        contained within  the  string  itself.   If  the
+                        delimiting  characters  do not match, the .ascis
+                        directive will give the (q) error.  
+
+        The  .ascis  directive  places  one binary byte of data for each
+
+
+        THE ASSEMBLER                                          PAGE 1-21
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        character in the  string  into  the  object  module.   The  last
+        character in the string will have the high order bit set.  
+
+
+        1.4.13  .asciz Directive 
+
+        Format:  
+
+                .asciz  /string/ 
+
+        where:  string  is a string of printable ascii characters.  
+
+                /  /    represent   the  delimiting  characters.   These
+                        delimiters   may   be   any   paired    printing
+                        characters,  as  long  as the characters are not
+                        contained within  the  string  itself.   If  the
+                        delimiting  characters  do not match, the .asciz
+                        directive will give the (q) error.  
+
+        The  .asciz  directive  places  one binary byte of data for each
+        character in the string into the object module.   Following  all
+        the  character  data  a  zero  byte is inserted to terminate the
+        character string.  
+
+
+        1.4.14  .assume Directive 
+
+        Format:  
+
+                .assume exp 
+
+        where:  exp     represents   an  absolute  expression.   If  the
+                        evaluation of the expression results  in  a  non
+                        zero value then an 'e' error is reported and the
+                        text line is listed in the generated error.  
+
+
+           The  .assume  directive  is useful to check assumptions about
+        assembler values.  (The .assume directive is identical in  func-
+        tion to the .error directive, just perhaps more descriptive.) 
+
+
+
+
+        THE ASSEMBLER                                          PAGE 1-22
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        1.4.15  .radix Directive 
+
+        Format:  
+
+                .radix  character 
+
+        where:  character  represents  a single character specifying the
+                default radix to be used for  succeeding  numbers.   The
+                character may be any one of the following:  
+
+                        B,b     Binary
+        
+                        O,o     Octal
+                        Q,q
+        
+                        D,d     Decimal
+                        'blank'
+        
+                        H,h     Hexidecimal
+                        X,x
+
+
+        1.4.16  .even Directive 
+
+        Format:  
+
+                .even 
+
+           The .even directive ensures that the current location counter
+        contains an even boundary value by adding 1 if the current loca-
+        tion is odd.  
+
+
+        1.4.17  .odd Directive 
+
+        Format:  
+
+                .odd 
+
+           The  .odd directive ensures that the current location counter
+        contains an odd boundary value by adding one if the current  lo-
+        cation is even.  
+
+
+
+
+        THE ASSEMBLER                                          PAGE 1-23
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        1.4.18  .area Directive 
+
+        Format:  
+
+                .area   name    [(options)] 
+
+        where:  name    represents the symbolic name of the program sec-
+                        tion.   This  name  may  be  the  same  as   any
+                        user-defined  symbol  as  the area names are in-
+                        dependent of all symbols and labels.  
+
+                options specify the type of program or data area:  
+                        ABS     absolute (automatically invokes OVR) 
+                        REL     relocatable 
+                        OVR     overlay 
+                        CON     concatenate 
+                        PAG     paged area 
+
+
+           The .area directive provides a means of defining and separat-
+        ing multiple programming and data sections.   The  name  is  the
+        area  label used by the assembler and the linker to collect code
+        from various separately assembled modules into one section.  The
+        name may be from 1 to 79 characters in length.  
+
+           The options are specified within parenthesis and separated by
+        commas as shown in the following example:  
+
+                .area  TEST  (REL,CON)  ;This section is relocatable
+                                        ;and concatenated with other
+                                        ;sections of this program area.
+        
+                .area  DATA  (REL,OVR)  ;This section is relocatable
+                                        ;and overlays other sections
+                                        ;of this program area.
+        
+                .area  SYS   (ABS,OVR)  ;(CON not allowed with ABS)
+                                        ;This section is defined as
+                                        ;absolute. Absolute sections
+                                        ;are always overlayed with
+                                        ;other sections of this program
+                                        ;area.
+        
+                .area  PAGE  (PAG)      ;This is a paged section. The
+                                        ;section must be on a 256 byte
+                                        ;boundary and its length is
+                                        ;checked by the linker to be
+                                        ;no larger than 256 bytes.
+                                        ;This is useful for direct page
+                                        ;areas.
+
+
+
+        THE ASSEMBLER                                          PAGE 1-24
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+           The  default  area type is REL|CON;  i.e.  a relocatable sec-
+        tion which is concatenated with other sections of code with  the
+        same area name.  The ABS option indicates an absolute area.  The
+        OVR and CON options indicate if program  sections  of  the  same
+        name  will overlay each other (start at the same location) or be
+        concatenated with each other (appended to each other).  
+
+           Multiple  invocations  of  the  .area directive with the same
+        name must specify the same options or leave  the  options  field
+        blank,  this  defaults  to  the previously specified options for
+        this program area.  
+
+        The   ASxxxx   assemblers   automatically  provide  two  program
+        sections:  
+
+                '.  .ABS.'      This dumby section contains all absolute
+                                symbols and their values.  
+
+                '_CODE'         This  is  the default program/data area.
+                                This program area is of type (REL,CON). 
+
+        The  ASxxxx  assemblers  also automatically generate two symbols
+        for each program area:  
+
+                's_<area>'      This is the starting address of the pro-
+                                gram area.  
+
+                'l_<area>'      This is the length of the program area. 
+
+        The .area names and options are never case sensitive.  
+
+
+        1.4.19  .org Directive 
+
+        Format:  
+
+                .org    exp 
+
+        where:  exp     is  an absolute expression that becomes the cur-
+                        rent location counter.  
+
+        The  .org directive is valid only in an absolute program section
+        and will give a (q) error if used in a relocatable program area.
+        The  .org  directive specifies that the current location counter
+        is to become the specified absolute value.  
+
+
+
+
+        THE ASSEMBLER                                          PAGE 1-25
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        1.4.20  .globl Directive 
+
+        Format:  
+
+                .globl  sym1,sym2,...,symn 
+
+        where:  sym1,           represent legal symbolic names. When
+                sym2,...        When multiple symbols are specified,
+                symn            they are separated by commas.
+
+           A  .globl directive may also have a label field and/or a com-
+        ment field.  
+
+           The  .globl directive is provided to define (and thus provide
+        linkage to) symbols not  otherwise  defined  as  global  symbols
+        within  a  module.   In  defining  global  symbols the directive
+        .globl J is similar to:  
+
+              J == expression or J::  
+
+           Because  object  modules  are linked by global symbols, these
+        symbols are vital to a program.  All internal symbols  appearing
+        within  a  given program must be defined at the end of pass 1 or
+        they will be considered undefined.  The assembly directive  (-g)
+        can  be  be  invoked to make all undefined symbols global at the
+        end of pass 1.  
+
+
+        1.4.21  .if, .else, and .endif Directives 
+
+        Format:  
+
+                .if     expr
+                .                       ;}
+                .                       ;} range of true condition
+                .                       ;}
+                .else
+                .                       ;}
+                .                       ;} range of false condition
+                .                       ;}
+                .endif
+
+           The  conditional  assembly directives allow you to include or
+        exclude blocks of source code during the assembly process, based
+        on the evaluation of the condition test.  
+
+           The  range of true condition will be processed if the expres-
+        sion 'expr' is not zero (i.e.  true) and the range of false con-
+        dition  will  be processed if the expression 'expr' is zero (i.e
+        false).  The range of true condition is optional as is the .else
+        directive  and  the range of false condition.  The following are
+        all valid .if/.else/.endif constructions:  
+
+
+        THE ASSEMBLER                                          PAGE 1-26
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+
+                .if     A-4             ;evaluate A-4
+                .byte   1,2             ;insert bytes if A-4 is
+                .endif                  ;not zero
+        
+                .if     K+3             ;evaluate K+3
+                .else
+                .byte   3,4             ;insert bytes if K+3
+                .endif                  ;is zero
+        
+                .if     J&3             ;evaluate J masked by 3
+                .byte   12              ;insert this byte if J&3
+                .else                   ;is not zero
+                .byte   13              ;insert this byte if J&3
+                .endif                  ;is zero
+
+
+        The .if/.else/.endif directives may be nested upto 10 levels.  
+
+           The  .page  directive  is  processed within a false condition
+        range to allow extended textual information to  be  incorporated
+        in  the  source  program  with  out  the need to use the comment
+        delimiter (;):  
+
+                .if     0
+        
+                .page
+                This text will be bypassed during assembly
+                but appear in the listing file.
+                .
+                .
+                .
+        
+                .endif
+
+
+        1.4.22  .include Directive 
+
+        Format:  
+
+                .include        string 
+
+        where:  string  represents  a  delimited string that is the file
+                        specification of an ASxxxx source file.  
+
+           The .include directive is used to insert a source file within
+        the source file currently being assembled.  When this  directive
+        is encountered, an implicit .page directive is issued.  When the
+        end of the specified source file is reached, an  implicit  .page
+        directive is issued and input continues from the previous source
+        file.  The maximum nesting level of source files specified by  a
+        .include directive is five.  
+
+
+        THE ASSEMBLER                                          PAGE 1-27
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+           The  total  number  of separately specified .include files is
+        unlimited as each .include file is opened and then closed during
+        each pass made by the assembler.  
+
+           The  default  directory  path,  if none is specified, for any
+        .include file is the directory path of the  current  file.   For
+        example:   if  the  current  source file, D:\proj\file1.asm, in-
+        cludes  a  file  specified   as   "include1"   then   the   file
+        D:\proj\include1.asm is opened.  
+
+
+        1.4.23  .setdp Directive 
+
+        Format:  
+
+                .setdp [base [,area]] 
+
+        The  set  direct  page  directive has a common format in all the
+        AS68xx assemblers.  The .setdp directive is used to  inform  the
+        assembler  of  the current direct page region and the offset ad-
+        dress within the selected area.  The normal  invocation  methods
+        are:  
+
+                .area   DIRECT  (PAG)
+                .setdp
+        
+                or
+        
+                .setdp  0,DIRECT
+
+        for  all  the  68xx microprocessors (the 6804 has only the paged
+        ram area).  The commands specify that the direct page is in area
+        DIRECT and its offset address is 0 (the only valid value for all
+        but the 6809 microprocessor).  Be sure to place the DIRECT  area
+        at address 0 during linking.  When the base address and area are
+        not specified, then zero and the current area are the  defaults.
+        If  a  .setdp directive is not issued the assembler defaults the
+        direct page to the area "_CODE" at offset 0.  
+
+           The  assembler  verifies  that  any  local variable used in a
+        direct variable reference is located in this area.  Local  vari-
+        able  and  constant value direct access addresses are checked to
+        be within the address range from 0 to 255.  
+
+           External direct references are assumed by the assembler to be
+        in the correct area and have valid  offsets.   The  linker  will
+        check all direct page relocations to verify that they are within
+        the correct area.  
+
+           The  6809  microprocessor  allows the selection of the direct
+        page to be on any 256 byte boundary by loading  the  appropriate
+
+
+        THE ASSEMBLER                                          PAGE 1-28
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        value  into the dp register.  Typically one would like to select
+        the page boundary at link time, one method follows:  
+
+                .area   DIRECT  (PAG)   ; define the direct page
+                .setdp
+                .
+                .
+                .
+                .area   PROGRAM
+                .
+                ldd     #DIRECT         ; load the direct page register
+                tfr     a,dp            ; for access to the direct page
+
+        At  link  time specify the base and global equates to locate the
+        direct page:  
+
+                -b DIRECT = 0x1000
+                -g DIRECT = 0x1000
+
+        Both  the  area address and offset value must be specified (area
+        and variable names are independent).   The  linker  will  verify
+        that  the  relocated  direct page accesses are within the direct
+        page.  
+        The  preceeding  sequence  could  be repeated for multiple paged
+        areas, however an alternate method is to define a non-paged area
+        and use the .setdp directive to specify the offset value:  
+
+                .area   DIRECT          ; define non-paged area
+                .
+                .
+                .
+                .area   PROGRAM
+                .
+                .setdp  0,DIRECT        ; direct page area
+                ldd     #DIRECT         ; load the direct page register
+                tfr     a,dp            ; for access to the direct page
+                .
+                .
+                .setdp  0x100,DIRECT    ; direct page area
+                ldd     #DIRECT+0x100   ; load the direct page register
+                tfr     a,dp            ; for access to the direct page
+
+        The  linker  will  verify that subsequent direct page references
+        are in the specified area and offset address range.  It  is  the
+        programmers responsibility to load the dp register with the cor-
+        rect page segment  corresponding  to  the  .setdp  base  address
+        specified.  
+
+           For  those  cases  where a single piece of code must access a
+        defined data structure within a direct page and there  are  many
+        pages,  define  a  dumby  direct page linked at address 0.  This
+        dumby page is used only to define  the  variable  labels.   Then
+
+
+        THE ASSEMBLER                                          PAGE 1-29
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        load  the dp register with the real base address but donot use a
+        .setdp directive.  This method is equivalent to indexed address-
+        ing,  where the dp register is the index register and the direct
+        addressing is the offset.  
+
+
+        1.4.24  .16bit, .24bit, and .32bit Directives 
+
+        Format:  
+
+                .16bit          ;specify 16-bit addressing
+                .24bit          ;specify 24-bit addressing
+                .32bit          ;specify 32-bit addressing
+
+
+           The  .16bit, .24bit, and .32bit directives are special direc-
+        tives for assembler configuration when default  values  are  not
+        used.  (Currently only the as8xCxxx assembler can use the .16bit
+        and .24bit directives in special mode.) 
+
+
+        THE ASSEMBLER                                          PAGE 1-30
+        GENERAL ASSEMBLER DIRECTIVES
+
+
+        1.5  INVOKING ASXXXX 
+
+
+           The ASxxxx assemblers are command line oriented.  Most sytems
+        require the option(s) and file(s) arguments to follow the ASxxxx
+        assembler name:  
+
+        as6809 [-dqxgalopswzff] file1 [file2 file3 ...  file6] 
+
+
+        Some  systems  may  request the arguments after the assembler is
+        started at a system specific prompt:  
+
+        as6809 
+        argv:  [-dqxgalopswzff] file1 [file2 file3 ...  file6] 
+
+
+        The options are:  
+
+                d       decimal listing
+                q       octal   listing
+                x       hex     listing (default)
+        
+                        The listing radix affects the
+                        .lst, .rel, and .sym files.
+        
+                g       undefined symbols made global
+                a       all user symbols made global
+        
+                l       create list   output file1.lst
+                o       create object output file1.rel
+                s       create symbol output file1.sym
+        
+                p       disable listing pagination
+                w       wide listing format for symbol table
+        
+                z       enable case sensitivity for symbols
+        
+                        relocatable reference flagging:
+        
+                f       by  `   in the listing file
+                ff      by mode in the listing file
+
+           The file name for the .lst, .rel, and .sym files is the first
+        file name specified in the command line.  All output  files  are
+        ascii  text  files which may be edited, copied, etc.  The output
+        files are the concatenation of all the input files, if files are
+        to  be  assembled  independently  invoke  the assembler for each
+        file.  
+
+
+
+        THE ASSEMBLER                                          PAGE 1-31
+        INVOKING ASXXXX
+
+
+           The  .rel  file contains a radix directive so that the linker
+        will use the proper conversion for this file.  Linked files  may
+        have different radices.  
+
+           If  the list (l) option is specified without the symbol table
+        (s) option, the symbol table is placed at the end of the listing
+        file.  
+
+
+        1.6  ERRORS 
+
+
+           The  ASxxxx assemblers provide limited diagnostic error codes
+        during the assembly process, these errors will be noted  in  the
+        listing file and printed on the stderr device.  
+
+           The assembler reports the errors on the stderr device as 
+
+                ?ASxxxx-Error-<*> in line nnn of filename
+
+        where  * is the error code, nnn is the line number, and filename
+        is the source/include file.  
+
+           The errors are:  
+
+              (.)   This  error  is caused by an absolute direct assign-
+                    ment of the current location counter 
+                          . = expression (incorrect) 
+                    rather than the correct 
+                          . = . + expression 
+
+              (a)   Indicates  a machine specific addressing or address-
+                    ing mode error.  
+
+              (b)   Indicates a direct page boundary error.  
+
+              (d)   Indicates a direct page addressing error.  
+
+              (e)   Caused by a .error or .assume directive.  
+
+              (i)   Caused  by  an  .include file error or an .if/.endif
+                    mismatch.  
+
+              (m)   Multiple  definitions  of  the  same label, multiple
+                    .module directives, or multiple  conflicting  attri-
+                    butes in an .area directive.  
+
+              (o)   Directive  or  mnemonic error or the use of the .org
+                    directive in a relocatable area.  
+
+              (p)   Phase error:  label location changing between passes
+                    2 and 3.  Normally caused by having  more  than  one
+
+
+        THE ASSEMBLER                                          PAGE 1-32
+        ERRORS
+
+
+                    level of forward referencing.  
+
+              (q)   Questionable syntax:  missing or improper operators,
+                    terminators, or delimiters.  
+
+              (r)   Relocation  error:   logic  operation attempted on a
+                    relocatable term, addition of two relocatable terms,
+                    subtraction  of two relocatable terms not within the
+                    same programming area or external symbols.  
+
+              (u)   Undefined symbol encountered during assembly.  
+
+              (z)   Divide by 0 or Modulus by 0 error:  result is 0.  
+
+
+        1.7  LISTING FILE 
+
+
+           The  (-l) option produces an ascii output listing file.  Each
+        page of output contains a five line header:  
+
+
+             1.  The ASxxxx program name and page number 
+
+             2.  Assembler Radix and Address Bits 
+
+             3.  Title from a .title directive (if any) 
+
+             4.  Subtitle from a .sbttl directive (if any) 
+
+             5.  Blank line 
+
+
+
+        Each succeeding line contains five fields:  
+
+
+             1.  Error field (first three characters of line) 
+
+             2.  Current location counter 
+
+             3.  Generated code in byte format 
+
+             4.  Source text line number 
+
+             5.  Source text 
+
+
+           The error field may contain upto 2 error flags indicating any
+        errors encountered while assembling this line of source code.  
+
+
+
+        THE ASSEMBLER                                          PAGE 1-33
+        LISTING FILE
+
+
+           The  current  location  counter  field  displays  the 16-bit,
+        24-bit, or 32-bit program position.  This field will be  in  the
+        selected radix.  
+
+           The generated code follows the program location.  The listing
+        radix determines the number of bytes that will be  displayed  in
+        this field.  Hexidecimal listing allows six bytes of data within
+        the field, decimal and octal allow four bytes within the  field.
+        If more than one field of data is generated from the assembly of
+        a single line of source code, then the data field is repeated on
+        successive lines.  
+
+           The source text line number is printed in decimal and is fol-
+        lowed by the source text.  
+
+           Two  special  cases  will  disable  the  listing of a line of
+        source text:  
+
+             1.  Source line with a .page directive is never listed.  
+
+             2.  Source  line  with  a  .include  file  directive is not
+                 listed unless the .include file cannot be opened.  
+
+
+           Two  data  field  options  are  available to flag those bytes
+        which will be relocated by the linker.   If  the  -f  option  is
+        specified  then  each  byte to be relocated will be preceeded by
+        the '`' character.  If the -ff option  is  specified  then  each
+        byte  to  be relocated will be preceeded by one of the following
+        characters:  
+
+             1.  *   paged relocation 
+
+             2.  u   low  byte of unsigned word or unsigned byte 
+
+             3.  v   high byte of unsigned word 
+
+             4.  p   PCR low  byte of word relocation or PCR byte 
+
+             5.  q   PCR high byte of word relocation 
+
+             6.  r   low  byte relocation or byte relocation 
+
+             7.  s   high byte relocation 
+
+
+           Assemblers  which  use 24-bit or 32-bit addressing use an ex-
+        tended flagging mode:  
+
+             1.  *   paged relocation 
+
+
+
+        THE ASSEMBLER                                          PAGE 1-34
+        LISTING FILE
+
+
+             2.  u   1st  byte of unsigned value 
+
+             3.  v   2nd  byte of unsigned value 
+
+             4.  U   3rd  byte of unsigned value 
+
+             5.  V   4th  byte of unsigned value 
+
+             6.  p   PCR 1st  byte of relocation value or PCR byte 
+
+             7.  q   PCR 2nd  byte of relocation value 
+
+             8.  P   PCR 3rd  byte of relocation value 
+
+             9.  Q   PCR 4th  byte of relocation value 
+
+            10.  r   1st  byte of relocation value or byte relocation 
+
+            11.  s   2nd  byte of relocation value 
+
+            12.  R   3rd  byte of relocation value 
+
+            13.  S   4th  byte of relocation value 
+
+
+
+        1.8  SYMBOL TABLE FILE 
+
+
+           The symbol table has two parts:  
+
+             1.  The alphabetically sorted list of symbols and/or labels
+                 defined or referenced in the source program.  
+
+             2.  A  list of the program areas defined during assembly of
+                 the source program.  
+
+
+           The sorted list of symbols and/or labels contains the follow-
+        ing information:  
+
+             1.  Program  area  number (none if absolute value or exter-
+                 nal) 
+
+             2.  The symbol or label 
+
+             3.  Directly assigned symbol is denoted with an (=) sign 
+
+             4.  The  value of a symbol, location of a label relative to
+                 the program area base address (=0), or a ****  indicat-
+                 ing the symbol or label is undefined.  
+
+
+
+        THE ASSEMBLER                                          PAGE 1-35
+        SYMBOL TABLE FILE
+
+
+             5.  The  characters:   G - global, R - relocatable, and X -
+                 external.  
+
+
+           The list of program areas provides the correspondence between
+        the program area numbers and the defined program areas, the size
+        of the program areas, and the area flags (attributes).  
+
+
+        1.9  OBJECT FILE 
+
+
+           The  object  file is an ascii file containing the information
+        needed by the linker to bind multiple object modules into a com-
+        plete  loadable  memory  image.   The object module contains the
+        following designators:  
+
+                [XDQ][HL][234]
+                        X       Hexidecimal radix
+                        D       Decimal radix
+                        Q       Octal radix
+        
+                        H       Most significant byte first
+                        L       Least significant byte first
+        
+                        2       16-Bit Addressing
+                        3       24-Bit Addressing
+                        4       32-Bit Addressing
+        
+                H       Header 
+                M       Module
+                A       Area
+                S       Symbol
+                T       Object code
+                R       Relocation information
+                P       Paging information
+
+           Refer to the linker for a detailed description of each of the
+        designators and the format of the information contained  in  the
+        object file.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                    CHAPTER 2
+
+                                   THE LINKER
+
+
+
+
+
+        2.1  ASLINK RELOCATING LINKER 
+
+
+           ASLINK is the companion linker for the ASxxxx assemblers.  
+
+           The  program ASLINK is a general relocating linker performing
+        the following functions:  
+
+             1.  Bind multiple object modules into a single memory image 
+
+             2.  Resolve inter-module symbol references 
+
+             3.  Combine  code  belonging to the same area from multiple
+                 object files into a single contiguous memory region 
+
+             4.  Search and import object module libraries for undefined
+                 global variables 
+
+             5.  Perform   byte   and   word  program  counter  relative
+                 (pc or pcr) addressing calculations 
+
+             6.  Define absolute symbol values at link time 
+
+             7.  Define absolute area base address values at link time 
+
+             8.  Produce Intel Hex or Motorola S output files 
+
+             9.  Produce a map of the linked memory image 
+
+            10.  Produce  an updated listing file with the relocated ad-
+                 dresses and data 
+
+
+
+
+
+        THE LINKER                                              PAGE 2-2
+        INVOKING ASLINK
+
+
+        2.2  INVOKING ASLINK 
+
+
+           Most  sytems require the options to be entered on the command
+           line:  
+
+                aslink -[options] -[option arg] files 
+
+           Some  systems  may  request the arguments after the linker is
+           started at a system specific prompt:  
+
+                aslink 
+                argv:  -[options] -[option arg] files 
+
+        The allowed linker commands are:  
+
+             1.  -c         ASlink >> prompt mode.  
+                 The  ASlink >>  prompt  mode reads linker commands from
+                 stdin.  
+
+             2.  -f  file   Command file mode.  
+                 The  command file mode imports linker commands from the
+                 specified file (extension must be  .lnk),  imported  -c
+                 and  -f  commands  are ignored.  If the directory path,
+                 for a file to be linked, is not specified in  the  com-
+                 mand  file  then  the  path  defaults  to the .lnk file
+                 directory path.  
+
+             3.  -p/-n   enable/disable echoing commands to stdout.  
+
+             4.  -i/-s   Intel  Hex  (file.i--) or Motorola S (file.s--)
+                 image output file.  
+
+             5.  -o/-v   Specifies      that      subsequent      linked
+                 files/libraries will generate object  output  (default)
+                 or  suppress  object  output.   (if option -s or -i was
+                 specified) 
+
+             6.  -z      Specifies that symbol names are case sensitive. 
+
+             7.  -m      Generate a map file (file.map).  This file con-
+                 tains a list of the symbols (by area) with absolute ad-
+                 dresses,  sizes  of  linked  areas,  and  other linking
+                 information.  
+
+             8.  -w      Specifies  that  a  wide listing format be used
+                 for the map file.  
+
+             9.  -xdq    Specifies  the  number  radix  for the map file
+                 (Hexidecimal, Decimal, or Octal).  
+
+
+
+        THE LINKER                                              PAGE 2-3
+        INVOKING ASLINK
+
+
+            10.  -u      Generate  an  updated  listing  file (file.rst)
+                 derived from the relocated addresses and data from  the
+                 linker.  
+
+            11.  file    File(s) to be linked.  Files may be on the same
+                 line as the above options or on a separate line(s)  one
+                 file  per line or multiple files separated by spaces or
+                 tabs.  
+
+            12.  -b  area=expression (one definition per line) 
+                 This  specifies  an area base address where the expres-
+                 sion may contain constants and/or defined symbols  from
+                 the linked files.  
+
+            13.  -g  symbol=expression (one definition per line) 
+                 This  specifies  the value for the symbol where the ex-
+                 pression may contain constants and/or  defined  symbols
+                 from the linked files.  
+
+            14.  -k  library directory path 
+                 (one  definition  per line) This specifies one possible
+                 path to an object library.  More than one path  is  al-
+                 lowed.  
+
+            15.  -l  library file specification 
+                 (one  definition  per  line)  This specifies a possible
+                 library file.  More than one file is allowed.  
+
+            16.  -e      or null line, terminates input to the linker.  
+
+
+
+        2.3  LIBRARY PATH(S) AND FILE(S) 
+
+
+           The process of resolving undefined symbols after scanning the
+        input object  files  includes  the  scanning  of  object  module
+        libraries.   The  linker will search through all combinations of
+        the library path specifications (input by the -k option) and the
+        library  file  specifications (input by the -l option) that lead
+        to an existing library file.  Each library file contains a  list
+        (one  file  per  line)  of  modules  included in this particular
+        library.  Each existing object module is scanned for a match  to
+        the undefined symbol.  The first module containing the symbol is
+        then linked with the previous modules to resolve the symbol  de-
+        finition.   The  library  object  modules are rescanned until no
+        more symbols can be resolved.   The  scanning  algorithm  allows
+        resolution  of  back references.  No errors are reported for non
+        existant library files or object modules.  
+
+           The  library  file  specification may be formed in one of two
+        ways:  
+
+
+        THE LINKER                                              PAGE 2-4
+        LIBRARY PATH(S) AND FILE(S)
+
+
+             1.  If  the  library  file  contained an absolute path/file
+                 specification  then  this  is   the   object   module's
+                 path/file.  
+                 (i.e.  C:\...  or C:/...) 
+
+             2.  If  the  library  file  contains  a  relative path/file
+                 specification then the concatenation of  the  path  and
+                 this  file  specification  becomes  the object module's
+                 path/file.  
+                 (i.e.  \...  or /...) 
+
+
+           As  an example, assume there exists a library file termio.lib
+        in the syslib directory specifying the following object modules: 
+
+        \6809\io_disk        first object module 
+        d:\special\io_comm   second object module 
+
+        and the following parameters were specified to the linker:  
+
+        -k c:\iosystem\    the first path 
+        -k c:\syslib\      the second path 
+
+        -l termio          the first library file 
+        -l io              the second library file (no such file) 
+
+        The  linker  will attempt to use the following object modules to
+        resolve any undefined symbols:  
+
+        c:\syslib\6809\io_disk.rel     (concatenated path/file) 
+        d:\special\io_comm.rel         (absolute path/file) 
+
+        all  other path(s)/file(s) don't exist.  (No errors are reported
+        for non existant path(s)/file(s).) 
+
+
+        2.4  ASLINK PROCESSING 
+
+
+           The  linker  processes  the  files  in  the  order  they  are
+        presented.  The first pass through the input files  is  used  to
+        define  all  program  areas, the section area sizes, and symbols
+        defined or referenced.  Undefined symbols will initiate a search
+        of any specified library file(s) and the importing of the module
+        containing the symbol definition.  After the first pass  the  -b
+        (area  base  address) definitions, if any, are processed and the
+        areas linked.  
+
+           The  area  linking proceeds by first examining the area types
+        ABS, CON, REL, OVR and PAG.  Absolute areas (ABS) from  separate
+        object modules are always overlayed and have been assembled at a
+        specific address, these are not  normally  relocated  (if  a  -b
+
+
+        THE LINKER                                              PAGE 2-5
+        ASLINK PROCESSING
+
+
+        command is used on an absolute area the area will be relocated).
+        Relative areas (normally defined as REL|CON) have a base address
+        of  0x0000  as read from the object files, the -b command speci-
+        fies the beginning address of the area.  All subsequent relative
+        areas  will  be  concatenated  with  proceeding  relative areas.
+        Where specific ordering is desired, the first linker input  file
+        should  have  the area definitions in the desired order.  At the
+        completion of the area linking all area  addresses  and  lengths
+        have  been determined.  The areas of type PAG are verified to be
+        on a 256 byte boundary and that the length does not  exceed  256
+        bytes.  Any errors are noted on stderr and in the map file.  
+
+           Next  the  global symbol definitions (-g option), if any, are
+        processed.  The symbol definitions have been delayed until  this
+        point because the absolute addresses of all internal symbols are
+        known and can be used in the expression calculations.  
+
+           Before  continuing  with the linking process the symbol table
+        is scanned to determine if any symbols have been referenced  but
+        not defined.  Undefined symbols are listed on the stderr device.
+        if a .module directive was included in the  assembled  file  the
+        module  making  the reference to this undefined variable will be
+        printed.  
+
+           Constants  defined  as global in more than one module will be
+        flagged as multiple definitions if their values are not  identi-
+        cal.  
+
+           After  the  preceeding  processes are complete the linker may
+        output a map file (-m option).  This file provides the following
+        information:  
+
+             1.  Global symbol values and label absolute addresses 
+
+             2.  Defined areas and there lengths 
+
+             3.  Remaining undefined symbols 
+
+             4.  List of modules linked 
+
+             5.  List of library modules linked 
+
+             6.  List of -b and -g definitions 
+
+
+
+
+           The final step of the linking process is performed during the
+        second pass of the input files.  As the xxx.rel files  are  read
+        the code is relocated by substituting the physical addresses for
+        the referenced symbols and areas and may be output in  Intel  or
+        Motorola  formats.   The  number  of  files  linked  and symbols
+
+
+        THE LINKER                                              PAGE 2-6
+        ASLINK PROCESSING
+
+
+        defined/referenced is limited by the processor  space  available
+        to  build  the area/symbol lists.  If the -u option is specified
+        then the listing files (file.lst) associated with the relocation
+        files  (file.rel)  are  scanned  and  used  to create a new file
+        (file.rst) which has all addresses and data relocated  to  their
+        final values.  
+
+           The  -o/-v  options  allow the simple creation of loadable or
+        overlay modules.  Loadable and overlay modules normally need  to
+        be  linked  with  a  main module(s) to resolve external symbols.
+        The -o/-v options can be used to enable object  output  for  the
+        loadable  or overlay module(s) and suppress the object code from
+        the linked main module(s).  The -o/-v  options  can  be  applied
+        repeatedly  to specify a single linked file, groups of files, or
+        libraries for object code inclusion or suppression.  
+
+
+        2.5  LINKER INPUT FORMAT 
+
+
+           The  linkers'  input  object file is an ascii file containing
+        the information needed by the linker  to  bind  multiple  object
+        modules into a complete loadable memory image.  
+
+        The object module contains the following designators:  
+
+                [XDQ][HL][234]
+                        X       Hexidecimal radix
+                        D       Decimal radix
+                        Q       Octal radix
+        
+                        H       Most significant byte first
+                        L       Least significant byte first
+        
+                        2       16-Bit Addressing
+                        3       24-Bit Addressing
+                        4       32-Bit Addressing
+        
+                H       Header 
+                M       Module
+                A       Area
+                S       Symbol
+                T       Object code
+                R       Relocation information
+                P       Paging information
+
+
+
+
+        THE LINKER                                              PAGE 2-7
+        LINKER INPUT FORMAT
+
+
+        2.5.1  Object Module Format 
+
+
+           The   first   line   of   an   object   module  contains  the
+        [XDQ][HL][234] format specifier  (i.e.   XH2  indicates  a  hex-
+        idecimal  file  with  most significant byte first and 16-bit ad-
+        dressing) for the following designators.  
+
+
+        2.5.2  Header Line 
+
+                H aa areas gg global symbols 
+
+           The  header  line  specifies  the number of areas(aa) and the
+        number of global symbols(gg) defined or referenced in  this  ob-
+        ject module segment.  
+
+
+        2.5.3  Module Line 
+
+                M name 
+
+           The  module  line  specifies  the module name from which this
+        header segment was assembled.  The module line will  not  appear
+        if the .module directive was not used in the source program.  
+
+
+        2.5.4  Symbol Line 
+
+                S string Defnnnn 
+
+                        or 
+
+                S string Refnnnn 
+
+           The  symbol line defines (Def) or references (Ref) the symbol
+        'string' with the value nnnn.  The defined value is relative  to
+        the  current area base address.  References to constants and ex-
+        ternal global symbols will always appear before the  first  area
+        definition.  References to external symbols will have a value of
+        zero.  
+
+
+
+
+        THE LINKER                                              PAGE 2-8
+        LINKER INPUT FORMAT
+
+
+        2.5.5  Area Line 
+
+                A label size ss flags ff 
+
+           The  area  line  defines the area label, the size (ss) of the
+        area in bytes, and the area flags (ff).  The area flags  specify
+        the ABS, REL, CON, OVR, and PAG parameters:  
+
+                OVR/CON  (0x04/0x00 i.e.  bit position 2) 
+
+                ABS/REL  (0x08/0x00 i.e.  bit position 3) 
+
+                PAG      (0x10 i.e.  bit position 4) 
+
+
+        2.5.6  T Line 
+
+                T xx xx nn nn nn nn nn ...  
+
+           The  T  line contains the assembled code output by the assem-
+        bler with xx xx being the offset address from the  current  area
+        base address and nn being the assembled instructions and data in
+        byte format.  
+
+
+        2.5.7  R Line 
+
+                R 0 0 nn nn n1 n2 xx xx ...  
+
+           The R line provides the relocation information to the linker.
+        The nn nn value is the current area index, i.e.  which area  the
+        current  values  were  assembled.  Relocation information is en-
+        coded in groups of 4 bytes:  
+
+             1.  n1  is  the  relocation mode and object format, for the
+                 adhoc extension modes refer to asxxxx.h or aslink.h 
+                 1.  bit 0  word(0x00)/byte(0x01) 
+                 2.  bit 1  relocatable area(0x00)/symbol(0x02) 
+                 3.  bit 2  normal(0x00)/PC relative(0x04) relocation 
+                 4.  bit 3  1-byte(0x00)/2-byte(0x08)  object format for
+                     byte data 
+                 5.  bit 4  signed(0x00)/unsigned(0x10) byte data 
+                 6.  bit 5  normal(0x00)/page '0'(0x20) reference 
+                 7.  bit 6  normal(0x00)/page 'nnn'(0x40) reference 
+                 8.  bit 7  LSB  byte(0x00)/2nd  byte(0x80)  with 2-byte
+                     mode 
+
+             2.  n2  is  a byte index into the corresponding (i.e.  pre-
+                 ceeding) T line data (i.e.  a pointer to the data to be
+                 updated  by  the  relocation).   The T line data may be
+                 1-byte or  2-byte  byte  data  format  or  2-byte  word
+                 format.  
+
+
+        THE LINKER                                              PAGE 2-9
+        LINKER INPUT FORMAT
+
+
+             3.  xx xx  is the area/symbol index for the area/symbol be-
+                 ing referenced.  the corresponding area/symbol is found
+                 in the header area/symbol lists.  
+
+
+        The groups of 4 bytes are repeated for each item requiring relo-
+        cation in the preceeding T line.  
+
+
+        2.5.8  P Line 
+
+                P 0 0 nn nn n1 n2 xx xx 
+
+           The  P  line provides the paging information to the linker as
+        specified by a .setdp directive.  The format of  the  relocation
+        information is identical to that of the R line.  The correspond-
+        ing T line has the following information:  
+                T xx xx aa aa bb bb 
+
+           Where  aa aa is the area reference number which specifies the
+        selected page area and bb bb is the base address  of  the  page.
+        bb bb will require relocation processing if the 'n1 n2 xx xx' is
+        specified in the P line.  The linker will verify that  the  base
+        address is on a 256 byte boundary and that the page length of an
+        area defined with the PAG type is not larger than 256 bytes.  
+
+           The  linker  defaults any direct page references to the first
+        area defined in the input REL file.  All ASxxxx assemblers  will
+        specify the _CODE area first, making this the default page area. 
+
+
+        2.5.9  24-Bit and 32-Bit Addressing 
+
+
+           When  24-bit  or  32-bit  addressing is specified in the file
+        format line [XDQ][HL][234] then the S and T Lines have  modified
+        formats:  
+                S string Defnnnnnn                      (24-bit)
+                S string Refnnnnnn                      (24-bit)
+                T xx xx xx nn nn nn nn nn ...           (24-bit)
+        
+                S string Defnnnnnnnn                    (32-bit)
+                S string Refnnnnnnnn                    (32-bit)
+                T xx xx xx xx nn nn nn nn nn ...        (32-bit)
+
+           The  multibyte  formats for byte data replace the 2-byte form
+        for 16-bit data with 3-byte or 4-byte data for 24-bit or  32-bit
+        data  respectively.  The 2nd byte format (also named MSB) always
+        uses the second byte of the 2, 3, or 4-byte data.  
+
+
+
+
+        THE LINKER                                             PAGE 2-10
+        LINKER ERROR MESSAGES
+
+
+        2.6  LINKER ERROR MESSAGES 
+
+
+           The linker provides detailed error messages allowing the pro-
+        grammer to quickly find the errant code.   As  the  linker  com-
+        pletes  pass 1  over  the  input  file(s)  it  reports  any page
+        boundary or page length errors as follows:  
+
+        ?ASlink-Warning-Paged Area PAGE0 Boundary Error
+        
+        and/or
+        
+        ?ASlink-Warning-Paged Area PAGE0 Length Error
+
+        where PAGE0 is the paged area.  
+
+           During  Pass  two the linker reads the T, R, and P lines per-
+        forming the necessary relocations and  outputting  the  absolute
+        code.  Various errors may be reported during this process 
+        The P line processing can produce only one possible error:  
+
+        ?ASlink-Warning-Page Definition Boundary Error
+                 file        module      pgarea      pgoffset
+          PgDef  t6809l      t6809l      PAGE0       0001
+
+        The error message specifies the file and module where the .setdp
+        direct was issued and indicates  the  page  area  and  the  page
+        offset value determined after relocation.  
+
+
+        The R line processing produces various errors:  
+
+        ?ASlink-Warning-Byte PCR relocation error for symbol  bra2
+                 file        module      area        offset
+          Refby  t6809l      t6809l      TEST        00FE
+          Defin  tconst      tconst      .  .ABS.    0080
+
+        ?ASlink-Warning-Unsigned Byte error for symbol  two56
+                 file        module      area        offset
+          Refby  t6800l      t6800l      DIRECT      0015
+          Defin  tconst      tconst      .  .ABS.    0100
+
+        ?ASlink-Warning-Page0 relocation error for symbol  ltwo56
+                 file        module      area        offset
+          Refby  t6800l      t6800l      DIRECT      000D
+          Defin  tconst      tconst      DIRECT      0100
+
+        ?ASlink-Warning-Page Mode relocation error for symbol  two56
+                 file        module      area        offset
+          Refby  t6809l      t6809l      DIRECT      0005
+          Defin  tconst      tconst      .  .ABS.    0100
+
+
+        THE LINKER                                             PAGE 2-11
+        LINKER ERROR MESSAGES
+
+
+        ?ASlink-Warning-Page Mode relocation error
+                 file        module      area        offset
+          Refby  t           Pagetest    PROGRAM     0006
+          Defin  t           Pagetest    DIRECT      0100
+
+        ?ASlink-Warning-2K Page relocation error
+                 file        module      area        offset
+          Refby  t           Pagetest    A           0000
+          Defin  t           Pagetest    A           0800
+
+        ?ASlink-Warning-512K Page relocation error
+                 file        module      area        offset
+          Refby  t           Pagetest    A           000000
+          Defin  t           Pagetest    A           080000
+
+        These  error messages specify the file, module, area, and offset
+        within the area of the code  referencing  (Refby)  and  defining
+        (Defin) the symbol.  If the symbol is defined in the same module
+        as the reference the linker is unable to report the symbol name.
+        The  assembler  listing file(s) should be examined at the offset
+        from the specified area to locate the offending code.  
+
+           The errors are:  
+
+             1.  The  byte PCR error is caused by exceeding the pc rela-
+                 tive byte branch range.  
+
+             2.  The Unsigned byte error indicates an indexing value was
+                 negative or larger than 255.  
+
+             3.  The  Page0  error is generated if the direct page vari-
+                 able is not in the page0 range of 0 to 255.  
+
+             4.  The page mode error is generated if the direct variable
+                 is not within the current direct page (6809).  
+
+             5.  The  2K  Page  relocation  error  is  generated  if the
+                 destination is not within the current  2K  page  (8051,
+                 DS8xCxxx).  
+
+             6.  The  512K  Page  relocation  error  is generated if the
+                 destination  is  not  within  the  current  512K   page
+                 (DS80C390).  
+
+
+
+        THE LINKER                                             Page 2-12
+        INTEL IHX OUTPUT FORMAT
+
+
+        2.7  INTEL IHX OUTPUT FORMAT (16-BIT) 
+
+        Record Mark Field    -  This  field  signifies  the  start  of a
+                                record, and consists of an  ascii  colon
+                                (:).  
+
+        Record Length Field  -  This   field   consists   of  two  ascii
+                                characters which indicate the number  of
+                                data   bytes   in   this   record.   The
+                                characters are the result of  converting
+                                the  number  of  bytes  in binary to two
+                                ascii characters, high digit first.   An
+                                End  of  File  record contains two ascii
+                                zeros in this field.  
+
+        Load Address Field   -  This  field  consists  of the four ascii
+                                characters which result from  converting
+                                the  the  binary value of the address in
+                                which to begin loading this record.  The
+                                order is as follows:  
+
+                                    High digit of high byte of address. 
+                                    Low digit of high byte of address.  
+                                    High digit of low byte of address.  
+                                    Low digit of low byte of address.  
+
+                                In an End of File record this field con-
+                                sists of either four ascii zeros or  the
+                                program  entry  address.   Currently the
+                                entry address option is not supported.  
+
+        Record Type Field    -  This  field  identifies the record type,
+                                which is either 0 for data records or  1
+                                for  an End of File record.  It consists
+                                of two ascii characters, with  the  high
+                                digit of the record type first, followed
+                                by the low digit of the record type.  
+
+        Data Field           -  This  field consists of the actual data,
+                                converted to two ascii characters,  high
+                                digit first.  There are no data bytes in
+                                the End of File record.  
+
+        Checksum Field       -  The  checksum  field is the 8 bit binary
+                                sum of the record length field, the load
+                                address  field,  the  record type field,
+                                and the data field.  This  sum  is  then
+                                negated  (2's  complement) and converted
+                                to  two  ascii  characters,  high  digit
+                                first.  
+
+
+        THE LINKER                                             Page 2-13
+        INTEL I86 OUTPUT FORMAT
+
+
+        2.8  INTEL I86 OUTPUT FORMAT (24 OR 32-BIT) 
+
+        Record Mark Field    -  This  field  signifies  the  start  of a
+                                record, and consists of an  ascii  colon
+                                (:).  
+
+        Record Length Field  -  This   field   consists   of  two  ascii
+                                characters which indicate the number  of
+                                data   bytes   in   this   record.   The
+                                characters are the result of  converting
+                                the  number  of  bytes  in binary to two
+                                ascii characters, high digit first.   An
+                                End  of  File  record contains two ascii
+                                zeros in this field.  
+
+        Load Address Field   -  This  field  consists  of the four ascii
+                                characters which result from  converting
+                                the  the  binary value of the address in
+                                which to begin loading this record.  The
+                                order is as follows:  
+
+                                    High digit of high byte of address. 
+                                    Low digit of high byte of address.  
+                                    High digit of low byte of address.  
+                                    Low digit of low byte of address.  
+
+                                In an End of File record this field con-
+                                sists of either four ascii zeros or  the
+                                program  entry  address.   Currently the
+                                entry address option is not supported.  
+
+        Record Type Field    -  This  field  identifies the record type,
+                                which is either 0 for  data  records,  1
+                                for  an  End  of File record, or 4 for a
+                                segment  record.   It  consists  of  two
+                                ascii characters, with the high digit of
+                                the record type first, followed  by  the
+                                low digit of the record type.  
+
+        Data Field           -  This  field consists of the actual data,
+                                converted to two ascii characters,  high
+                                digit first.  There are no data bytes in
+                                the End of File record.  
+
+        Checksum Field       -  The  checksum  field is the 8 bit binary
+                                sum of the record length field, the load
+                                address  field,  the  record type field,
+                                and the data field.  This  sum  is  then
+                                negated  (2's  complement) and converted
+                                to  two  ascii  characters,  high  digit
+                                first.  
+
+
+        THE LINKER                                             Page 2-14
+        MOTOROLA S1-S9 OUTPUT FORMAT
+
+
+        2.9  MOTORLA S1-S9 OUTPUT FORMAT (16-BIT) 
+
+        Record Type Field    -  This  field  signifies  the  start  of a
+                                record and  identifies  the  the  record
+                                type as follows:  
+
+                                    Ascii S1 - Data Record 
+                                    Ascii S9 - End of File Record 
+
+        Record Length Field  -  This  field  specifies the record length
+                                which includes the  address,  data,  and
+                                checksum   fields.   The  8  bit  record
+                                length value is converted to  two  ascii
+                                characters, high digit first.  
+
+        Load Address Field   -  This  field  consists  of the four ascii
+                                characters which result from  converting
+                                the  the  binary value of the address in
+                                which to begin loading this record.  The
+                                order is as follows:  
+
+                                    High digit of high byte of address. 
+                                    Low digit of high byte of address.  
+                                    High digit of low byte of address.  
+                                    Low digit of low byte of address.  
+
+                                In an End of File record this field con-
+                                sists of either four ascii zeros or  the
+                                program  entry  address.   Currently the
+                                entry address option is not supported.  
+
+        Data Field           -  This  field consists of the actual data,
+                                converted to two ascii characters,  high
+                                digit first.  There are no data bytes in
+                                the End of File record.  
+
+        Checksum Field       -  The  checksum  field is the 8 bit binary
+                                sum of the record length field, the load
+                                address field, and the data field.  This
+                                sum is then  complemented  (1's  comple-
+                                ment)   and   converted   to  two  ascii
+                                characters, high digit first.  
+
+
+        THE LINKER                                             Page 2-15
+        MOTOROLA S2-S8 OUTPUT FORMAT
+
+
+        2.10  MOTORLA S2-S8 OUTPUT FORMAT (24-BIT) 
+
+        Record Type Field    -  This  field  signifies  the  start  of a
+                                record and  identifies  the  the  record
+                                type as follows:  
+
+                                    Ascii S2 - Data Record 
+                                    Ascii S8 - End of File Record 
+
+        Record Length Field  -  This  field  specifies the record length
+                                which includes the  address,  data,  and
+                                checksum   fields.   The  8  bit  record
+                                length value is converted to  two  ascii
+                                characters, high digit first.  
+
+        Load Address Field   -  This  field  consists  of  the six ascii
+                                characters which result from  converting
+                                the  the  binary value of the address in
+                                which to begin loading this record.  The
+                                order is as follows:  
+
+                                    High digit of 3rd byte of address.  
+                                    Low digit of 3rd byte of address.  
+                                    High digit of high byte of address. 
+                                    Low digit of high byte of address.  
+                                    High digit of low byte of address.  
+                                    Low digit of low byte of address.  
+
+                                In an End of File record this field con-
+                                sists of either six ascii zeros  or  the
+                                program  entry  address.   Currently the
+                                entry address option is not supported.  
+
+        Data Field           -  This  field consists of the actual data,
+                                converted to two ascii characters,  high
+                                digit first.  There are no data bytes in
+                                the End of File record.  
+
+        Checksum Field       -  The  checksum  field is the 8 bit binary
+                                sum of the record length field, the load
+                                address field, and the data field.  This
+                                sum is then  complemented  (1's  comple-
+                                ment)   and   converted   to  two  ascii
+                                characters, high digit first.  
+
+
+        THE LINKER                                             Page 2-16
+        MOTOROLA S3-S7 OUTPUT FORMAT
+
+
+        2.11  MOTORLA S3-S7 OUTPUT FORMAT (32-BIT) 
+
+        Record Type Field    -  This  field  signifies  the  start  of a
+                                record and  identifies  the  the  record
+                                type as follows:  
+
+                                    Ascii S3 - Data Record 
+                                    Ascii S7 - End of File Record 
+
+        Record Length Field  -  This  field  specifies the record length
+                                which includes the  address,  data,  and
+                                checksum   fields.   The  8  bit  record
+                                length value is converted to  two  ascii
+                                characters, high digit first.  
+
+        Load Address Field   -  This  field  consists of the eight ascii
+                                characters which result from  converting
+                                the  the  binary value of the address in
+                                which to begin loading this record.  The
+                                order is as follows:  
+
+                                    High digit of 4th byte of address.  
+                                    Low digit of 4th byte of address.  
+                                    High digit of 3rd byte of address.  
+                                    Low digit of 3rd byte of address.  
+                                    High digit of high byte of address. 
+                                    Low digit of high byte of address.  
+                                    High digit of low byte of address.  
+                                    Low digit of low byte of address.  
+
+                                In an End of File record this field con-
+                                sists of either eight ascii zeros or the
+                                program  entry  address.   Currently the
+                                entry address option is not supported.  
+
+        Data Field           -  This  field consists of the actual data,
+                                converted to two ascii characters,  high
+                                digit first.  There are no data bytes in
+                                the End of File record.  
+
+        Checksum Field       -  The  checksum  field is the 8 bit binary
+                                sum of the record length field, the load
+                                address field, and the data field.  This
+                                sum is then  complemented  (1's  comple-
+                                ment)   and   converted   to  two  ascii
+                                characters, high digit first.  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                    CHAPTER 3
+
+                           BUILDING ASXXXX AND ASLINK
+
+
+
+
+           The assemblers and linker have been successfully compiled us-
+        ing GCC 2.7.2 with Linux, Symantec C/C++ V6.1/V7.2,  DJGPP  (GCC
+        2.8.2)  and  VC6  with  MS-DOS  and  Windows 3.x/95/98.  A Linux
+        makefile, DJGPP makefile, Symantec project files, and  VC6  pro-
+        ject  files  are  available  to build all the assemblers and the
+        linker.  
+
+
+        3.1  BUILDING AN ASSEMBLER 
+
+
+           The  building  of  a typical assembler (6809 for example) re-
+        quires the following files:  
+
+             1.  m6809.h 
+             2.  m09ext.c 
+             3.  m09mch.c 
+             4.  m09adr.c 
+             5.  m09pst.c 
+             6.  asxxxx.h 
+             7.  asmain.c 
+             8.  aslex.c 
+             9.  assym.c 
+            10.  assubr.c 
+            11.  asexpr.c 
+            12.  asdata.c 
+            13.  aslist.c 
+            14.  asout.c 
+
+
+           The  first  five  files are the 6809 processor dependent sec-
+        tions which contain the following:  
+
+
+             1.  m6809.h -  header  file containing the machine specific
+                 definitions of constants,  variables,  structures,  and
+                 types 
+
+
+        BUILDING ASXXXX AND ASLINK                              PAGE 3-2
+        BUILDING AN ASSEMBLER
+
+
+             2.  m09ext -  device  description, byte order, and file ex-
+                 tension information 
+
+             3.  m09pst -  a  table of the assembler general directives,
+                 special device directives, and assembler mnemonics with
+                 associated operation codes 
+
+             4.  m09mch / m09adr -  machine specific code for processing
+                 the device mnemonics,  addressing  modes,  and  special
+                 directives 
+
+
+           The  remaining nine files provide the device independent sec-
+        tions which handle the  details  of  file  input/output,  symbol
+        table  generation,  program/data areas, expression analysis, and
+        assembler directive processing.  
+
+
+        3.2  BUILDING ASLINK 
+
+
+           The building of the linker requires the following files:  
+
+             1.  aslink.h 
+             2.  lkmain.c 
+             3.  lklex.c 
+             4.  lkarea.c 
+             5.  lkhead.c 
+             6.  lksym.c 
+             7.  lkeval.c 
+             8.  lkdata.c 
+             9.  lklist.c 
+            10.  lkrloc.c 
+            11.  lklibr.c 
+            12.  lks19.c 
+            13.  lkihx.c 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX A
+
+                                AS6800 ASSEMBLER
+
+
+
+
+
+        A.1  6800 REGISTER SET 
+
+        The following is a list of the 6800 registers used by AS6800:  
+
+                a,b     -       8-bit accumulators
+                x       -       index register
+
+
+        A.2  6800 INSTRUCTION SET 
+
+
+           The following tables list all 6800/6802/6808 mnemonics recog-
+        nized by the AS6800 assembler.  The designation [] refers  to  a
+        required addressing mode argument.  The following list specifies
+        the format for each addressing mode supported by AS6800:  
+
+                #data           immediate data
+                                byte or word data
+        
+                *dir            direct page addressing
+                                (see .setdp directive)
+                                0 <= dir <= 255 
+        
+                ,x              register indirect addressing
+                                zero offset
+        
+                offset,x        register indirect addressing
+                                0 <= offset <= 255
+        
+                ext             extended addressing
+        
+                label           branch label
+
+        The  terms  data, dir, offset, ext, and label may all be expres-
+        sions.  
+
+
+
+        AS6800 ASSEMBLER                                        PAGE A-2
+        6800 INSTRUCTION SET
+
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the 6800 technical data for valid modes.  
+
+
+        A.2.1  Inherent Instructions 
+
+                aba                     cba
+                clc                     cli
+                clv                     daa
+                des                     dex
+                ins                     inx
+                nop                     rti
+                rts                     sba
+                sec                     sei
+                sev                     swi
+                tab                     tap
+                tba                     tpa
+                tsx                     txs
+                wai
+        
+                psha                    pshb
+                psh a                   psh b
+                pula                    pulb
+                pul a                   pul b
+
+
+        A.2.2  Branch Instructions 
+
+                bra     label           bhi     label
+                bls     label           bcc     label
+                bhs     label           bcs     label
+                blo     label           bne     label
+                beq     label           bvc     label
+                bvs     label           bpl     label
+                bmi     label           bge     label
+                blt     label           bgt     label
+                ble     label           bsr     label
+
+
+        AS6800 ASSEMBLER                                        PAGE A-3
+        6800 INSTRUCTION SET
+
+
+        A.2.3  Single Operand Instructions 
+
+                asla                    aslb
+                asl a                   asl b
+                asl     []
+        
+                asra                    asrb
+                asr a                   asr b
+                asr     []
+        
+                clra                    clrb
+                clr a                   clr b
+                clr     []
+        
+                coma                    comb
+                com a                   com b
+                com     []
+        
+                deca                    decb
+                dec a                   dec b
+                dec     []
+        
+                inca                    incb
+                inc a                   inc b
+                inc     []
+        
+                lsla                    lslb
+                lsl a                   lsl b
+                lsl     []
+        
+                lsra                    lsrb
+                lsr a                   lsr b
+                lsr     []
+        
+                nega                    negb
+                neg a                   neg b
+                neg     []
+        
+                rola                    rolb
+                rol a                   rol b
+                rol     []
+        
+                rora                    rorb
+                ror a                   ror b
+                ror     []
+        
+                tsta                    tstb
+                tst a                   tst b
+                tst     []
+
+
+        AS6800 ASSEMBLER                                        PAGE A-4
+        6800 INSTRUCTION SET
+
+
+        A.2.4  Double Operand Instructions 
+
+                adca    []              adcb    []
+                adc a   []              adc b   []
+        
+                adda    []              addb    []
+                add a   []              add b   []
+        
+                anda    []              andb    []
+                and a   []              and b   []
+        
+                bita    []              bitb    []
+                bit a   []              bit b   []
+        
+                cmpa    []              cmpb    []
+                cmp a   []              cmp b   []
+        
+                eora    []              eorb    []
+                eor a   []              eor b   []
+        
+                ldaa    []              ldab    []
+                lda a   []              lda b   []
+        
+                oraa    []              orab    []
+                ora a   []              ora b   []
+        
+                sbca    []              sbcb    []
+                sbc a   []              sbc b   []
+        
+                staa    []              stab    []
+                sta a   []              sta b   []
+        
+                suba    []              subb    []
+                sub a   []              sub b   []
+
+
+        A.2.5  Jump and Jump to Subroutine Instructions 
+
+                jmp     []              jsr     []
+
+
+
+
+        AS6800 ASSEMBLER                                        PAGE A-5
+        6800 INSTRUCTION SET
+
+
+        A.2.6  Long Register Instructions 
+
+                cpx     []
+                lds     []              sts     []
+                ldx     []              stx     []
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX B
+
+                                AS6801 ASSEMBLER
+
+
+
+
+
+        B.1  .hd6303 DIRECTIVE 
+
+        Format:  
+
+                .hd6303 
+
+        The  .hd6303 directive enables processing of the HD6303 specific
+        mnemonics not included in  the  6801  instruction  set.   HD6303
+        mnemonics  encountered  without  the  .hd6303  directive will be
+        flagged with an 'o' error.  
+
+
+        B.2  6801 REGISTER SET 
+
+        The following is a list of the 6801 registers used by AS6801:  
+
+                a,b     -       8-bit accumulators
+                d       -       16-bit accumulator <a:b>
+                x       -       index register
+
+
+        B.3  6801 INSTRUCTION SET 
+
+
+           The  following tables list all 6801/6303 mnemonics recognized
+        by the AS6801 assembler.  The designation []  refers  to  a  re-
+        quired  addressing  mode argument.  The following list specifies
+        the format for each addressing mode supported by AS6801:  
+
+                #data           immediate data
+                                byte or word data
+        
+                *dir            direct page addressing
+                                (see .setdp directive)
+                                0 <= dir <= 255 
+        
+
+
+        AS6801 ASSEMBLER                                        PAGE B-2
+        6801 INSTRUCTION SET
+
+
+                ,x              register indirect addressing
+                                zero offset
+        
+                offset,x        register indirect addressing
+                                0 <= offset <= 255
+        
+                ext             extended addressing
+        
+                label           branch label
+
+        The  terms  data, dir, offset, ext, and label may all be expres-
+        sions.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to  the  6801/6303  technical  data  for  valid
+        modes.  
+
+
+        B.3.1  Inherent Instructions 
+
+                aba             abx
+                cba             clc
+                cli             clv
+                daa             des
+                dex             ins
+                inx             mul
+                nop             rti
+                rts             sba
+                sec             sei
+                sev             swi
+                tab             tap
+                tba             tpa
+                tsx             txs
+                wai
+
+
+        B.3.2  Branch Instructions 
+
+                bra     label           brn     label
+                bhi     label           bls     label
+                bcc     label           bhs     label
+                bcs     label           blo     label
+                bne     label           beq     label
+                bvc     label           bvs     label
+                bpl     label           bmi     label
+                bge     label           blt     label
+                bgt     label           ble     label
+                bsr     label
+
+
+        AS6801 ASSEMBLER                                        PAGE B-3
+        6801 INSTRUCTION SET
+
+
+        B.3.3  Single Operand Instructions 
+
+                asla            aslb            asld
+                asl a           asl b           asl d
+                asl     []
+        
+                asra            asrb
+                asr a           asr b
+                asr     []
+        
+                clra            clrb
+                clr a           clr b
+                clr     []
+        
+                coma            comb
+                com a           com b
+                com     []
+        
+                deca            decb
+                dec a           dec b
+                dec     []
+        
+                eora            eorb
+                eor a           eor b
+                eor     []
+        
+                inca            incb
+                inc a           inc b
+                inc     []
+        
+                lsla            lslb            lsld
+                lsl a           lsl b           lsl d
+                lsl     []
+        
+                lsra            lsrb            lsrd
+                lsr a           lsr b           lsr d
+                lsr     []
+        
+                nega            negb
+                neg a           neg b
+                neg     []
+        
+                psha            pshb            pshx
+                psh a           psh b           psh x
+        
+                pula            pulb            pulx
+                pul a           pul b           pul x
+        
+                rola            rolb
+                rol a           rol b
+                rol     []
+        
+
+
+        AS6801 ASSEMBLER                                        PAGE B-4
+        6801 INSTRUCTION SET
+
+
+                rora            rorb
+                ror a           ror b
+                ror     []
+        
+                tsta            tstb
+                tst a           tst b
+                tst     []
+
+
+        B.3.4  Double Operand Instructions 
+
+                adca    []      adcb    []
+                adc a   []      adc b   []
+        
+                adda    []      addb    []      addd    []
+                add a   []      add b   []      add d   []
+        
+                anda    []      andb    []
+                and a   []      and b   []
+        
+                bita    []      bitb    []
+                bit a   []      bit b   []
+        
+                cmpa    []      cmpb    []
+                cmp a   []      cmp b   []
+        
+                ldaa    []      ldab    []
+                lda a   []      lda b   []
+        
+                oraa    []      orab    []
+                ora a   []      ora b   []
+        
+                sbca    []      sbcb    []
+                sbc a   []      sbc b   []
+        
+                staa    []      stab    []
+                sta a   []      sta b   []
+        
+                suba    []      subb    []      subd    []
+                sub a   []      sub b   []      sub d   []
+
+
+
+
+        AS6801 ASSEMBLER                                        PAGE B-5
+        6801 INSTRUCTION SET
+
+
+        B.3.5  Jump and Jump to Subroutine Instructions 
+
+                jmp     []      jsr     []
+
+
+        B.3.6  Long Register Instructions 
+
+                cpx     []      ldd     []
+                lds     []      ldx     []
+                std     []      sts     []
+                stx     []
+
+
+        B.3.7  6303 Specific Instructions 
+
+                aim     #data, []       eim     #data, []
+                oim     #data, []       tim     #data, []
+        
+                xgdx            slp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX C
+
+                                AS6804 ASSEMBLER
+
+
+
+
+           Requires the .setdp directive to specify the ram area.  
+
+
+        C.1  6804 REGISTER SET 
+
+        The following is a list of the 6804 registers used by AS6804:  
+
+                x,y     -       index registers
+
+
+        C.2  6804 INSTRUCTION SET 
+
+
+           The  following  tables  list all 6804 mnemonics recognized by
+        the AS6804 assembler.  The designation [] refers to  a  required
+        addressing  mode  argument.   The  following  list specifies the
+        format for each addressing mode supported by AS6804:  
+
+                #data           immediate data
+                                byte or word data
+        
+                ,x              register indirect addressing
+        
+                dir             direct addressing
+                                (see .setdp directive)
+                                0 <= dir <= 255
+        
+                ext             extended addressing
+        
+                label           branch label
+
+        The  terms data, dir, and ext may be expressions.  The label for
+        the short branchs beq, bne, bcc, and bcs must not be external.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the 6804 technical data for valid modes.  
+
+
+        AS6804 ASSEMBLER                                        PAGE C-2
+        6804 INSTRUCTION SET
+
+
+        C.2.1  Inherent Instructions 
+
+                coma            decx
+                decy            incx
+                incy            rola
+                rti             rts
+                stop            tax
+                tay             txa
+                tya             wait
+
+
+        C.2.2  Branch Instructions 
+
+                bne     label           beq     label
+                bcc     label           bcs     label
+
+
+        C.2.3  Single Operand Instructions 
+
+                add     []
+                and     []
+                cmp     []
+                dec     []
+                inc     []
+                lda     []
+                sta     []
+                sub     []
+
+
+        C.2.4  Jump and Jump to Subroutine Instructions 
+
+                jsr     []
+                jmp     []
+
+
+        C.2.5  Bit Test Instructions 
+
+                brclr   #data,[],label
+                brset   #data,[],label
+        
+                bclr    #label,[]
+                bset    #label,[]
+
+
+
+
+        AS6804 ASSEMBLER                                        PAGE C-3
+        6804 INSTRUCTION SET
+
+
+        C.2.6  Load Immediate data Instruction 
+
+                mvi     [],#data
+
+
+        C.2.7  6804 Derived Instructions 
+
+                asla
+                bam     label
+                bap     label
+                bxmi    label
+                bxpl    label
+                bymi    label
+                bypl    label
+                clra
+                clrx
+                clry
+                deca
+                decx
+                decy
+                inca
+                incx
+                incy
+                ldxi    #data
+                ldyi    #data
+                nop
+                tax
+                tay
+                txa
+                tya
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX D
+
+                                AS6805 ASSEMBLER
+
+
+
+
+
+        D.1  6805 REGISTER SET 
+
+        The following is a list of the 6805 registers used by AS6805:  
+
+                a       -       8-bit accumulator
+                x       -       index register
+
+
+        D.2  6805 INSTRUCTION SET 
+
+
+           The  following  tables  list all 6805 mnemonics recognized by
+        the AS6805 assembler.  The designation [] refers to  a  required
+        addressing  mode  argument.   The  following  list specifies the
+        format for each addressing mode supported by AS6805:  
+
+                #data           immediate data
+                                byte or word data
+        
+                *dir            direct page addressing
+                                (see .setdp directive)
+                                0 <= dir <= 255 
+        
+                ,x              register indirect addressing
+                                zero offset
+        
+                offset,x        register indirect addressing
+                                  0 <= offset <= 255   --- byte mode
+                                256 <= offset <= 65535 --- word mode
+                                (an externally defined offset uses the
+                                 word mode)
+        
+                ext             extended addressing
+        
+                label           branch label
+
+
+
+        AS6805 ASSEMBLER                                        PAGE D-2
+        6805 INSTRUCTION SET
+
+
+        The terms data, dir, offset, and ext may all be expressions.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the 6805 technical data for valid modes.  
+
+
+        D.2.1  Control Instructions 
+
+                clc             cli
+                nop             rsp
+                rti             rts
+                sec             sei
+                stop            swi
+                tax             txa
+                wait
+
+
+        D.2.2  Bit Manipulation Instructions 
+
+                brset   #data,*dir,label
+                brclr   #data,*dir,label
+        
+                bset    #data,*dir
+                bclr    #data,*dir
+
+
+        D.2.3  Branch Instructions 
+
+                bra     label           brn     label
+                bhi     label           bls     label
+                bcc     label           bcs     label
+                bne     label           beq     label
+                bhcc    label           bhcs    label
+                bpl     label           bmi     label
+                bmc     label           bms     label
+                bil     label           bih     label
+                bsr     label
+
+
+        AS6805 ASSEMBLER                                        PAGE D-3
+        6805 INSTRUCTION SET
+
+
+        D.2.4  Read-Modify-Write Instructions 
+
+                nega            negx
+                neg     []
+        
+                coma            comx
+                com     []
+        
+                lsra            lsrx
+                lsr     []
+        
+                rora            rorx
+                ror     []
+        
+                asra            asrx
+                asr     []
+        
+                lsla            lslx
+                lsl     []
+        
+                rola            rolx
+                rol     []
+        
+                deca            decx
+                dec     []
+        
+                inca            incx
+                inc     []
+        
+                tsta            tstx
+                tst     []
+        
+                clra            clrx
+                clr     []
+
+
+        D.2.5  Register\Memory Instructions 
+
+                sub     []              cmp     []
+                sbc     []              cpx     []
+                and     []              bit     []
+                lda     []              sta     []
+                eor     []              adc     []
+                ora     []              add     []
+                ldx     []              stx     []
+
+
+        AS6805 ASSEMBLER                                        PAGE D-4
+        6805 INSTRUCTION SET
+
+
+        D.2.6  Jump and Jump to Subroutine Instructions 
+
+                jmp     []              jsr     []
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX E
+
+                                AS6808 ASSEMBLER
+
+
+
+
+
+        E.1  68HC08 REGISTER SET 
+
+        The  following  is  a  list  of  the  68HC08  registers  used by
+        AS68HC08:  
+
+                a       -       8-bit accumulator
+                x       -       index register  <H:X>
+                s       -       stack pointer
+
+
+        E.2  68HC08 INSTRUCTION SET 
+
+
+           The  following tables list all 68HC08 mnemonics recognized by
+        the AS6808 assembler.  The designation [] refers to  a  required
+        addressing  mode  argument.   The  following  list specifies the
+        format for each addressing mode supported by AS6808:  
+
+                #data           immediate data
+                                byte or word data
+        
+                *dir            direct page addressing
+                                (see .setdp directive)
+                                0 <= dir <= 255 
+        
+                ,x              register indexed addressing
+                                zero offset
+        
+                offset,x        register indexed addressing
+                                  0 <= offset <= 255   --- byte mode
+                                256 <= offset <= 65535 --- word mode
+                                (an externally defined offset uses the
+                                 word mode)
+        
+                ,x+             register indexed addressing
+                                zero offset with post increment
+
+
+        AS6808 ASSEMBLER                                        PAGE E-2
+        68HC08 INSTRUCTION SET
+
+
+        
+                offset,x+       register indexed addressing
+                                unsigned byte offset with post increment
+        
+                offset,s        stack pointer indexed addressing
+                                  0 <= offset <= 255   --- byte mode
+                                256 <= offset <= 65535 --- word mode
+                                (an externally defined offset uses the
+                                 word mode)
+        
+                ext             extended addressing
+        
+                label           branch label
+
+        The terms data, dir, offset, and ext may all be expressions.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the 68HC08 technical data for valid modes.  
+
+
+        E.2.1  Control Instructions 
+
+                clc             cli             daa             div
+                mul             nop             nsa             psha
+                pshh            pshx            pula            pulh
+                pulx            rsp             rti             rts
+                sec             sei             stop            swi
+                tap             tax             tpa             tsx
+                txa             txs             wait
+
+
+        E.2.2  Bit Manipulation Instructions 
+
+                brset   #data,*dir,label
+                brclr   #data,*dir,label
+        
+                bset    #data,*dir
+                bclr    #data,*dir
+
+
+        AS6808 ASSEMBLER                                        PAGE E-3
+        68HC08 INSTRUCTION SET
+
+
+        E.2.3  Branch Instructions 
+
+                bra     label           brn     label
+                bhi     label           bls     label
+                bcc     label           bcs     label
+                bne     label           beq     label
+                bhcc    label           bhcs    label
+                bpl     label           bmi     label
+                bmc     label           bms     label
+                bil     label           bih     label
+                bsr     label           bge     label
+                blt     label           bgt     label
+                ble     label
+
+
+        E.2.4  Complex Branch Instructions 
+
+                cbeqa   [],label
+                cbeqx   [],label
+                cbeq    [],label
+                dbnza   label
+                dbnzx   label
+                dbnz    [],label
+
+
+        AS6808 ASSEMBLER                                        PAGE E-4
+        68HC08 INSTRUCTION SET
+
+
+        E.2.5  Read-Modify-Write Instructions 
+
+                nega                    negx
+                neg     []
+        
+                coma                    comx
+                com     []
+        
+                lsra                    lsrx
+                lsr     []
+        
+                rora                    rorx
+                ror     []
+        
+                asra                    asrx
+                asr     []
+        
+                asla                    aslx
+                asl     []
+        
+                lsla                    lslx
+                lsl     []
+        
+                rola                    rolx
+                rol     []
+        
+                deca                    decx
+                dec     []
+        
+                inca                    incx
+                inc     []
+        
+                tsta                    tstx
+                tst     []
+        
+                clra                    clrx
+                clr     []              clrh
+        
+                aix     #data
+        
+                ais     #data
+
+
+        AS6808 ASSEMBLER                                        PAGE E-5
+        68HC08 INSTRUCTION SET
+
+
+        E.2.6  Register\Memory Instructions 
+
+                sub     []              cmp     []
+                sbc     []              cpx     []
+                and     []              bit     []
+                lda     []              sta     []
+                eor     []              adc     []
+                ora     []              add     []
+                ldx     []              stx     []
+
+
+        E.2.7  Double Operand Move Instruction 
+
+                mov     [],[]
+
+
+        E.2.8  16-Bit <H:X> Index Register Instructions 
+
+                cphx    []
+                ldhx    []
+                sthx    []
+
+
+        E.2.9  Jump and Jump to Subroutine Instructions 
+
+                jmp     []              jsr     []
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX F
+
+                                AS6809 ASSEMBLER
+
+
+
+
+
+        F.1  6809 REGISTER SET 
+
+        The following is a list of the 6809 registers used by AS6809:  
+
+                a,b     -       8-bit accumulators
+                d       -       16-bit accumulator <a:b>
+                x,y     -       index registers
+                s,u     -       stack pointers
+                pc      -       program counter
+                cc      -       condition code
+                dp      -       direct page
+
+
+        F.2  6809 INSTRUCTION SET 
+
+
+           The  following  tables  list all 6809 mnemonics recognized by
+        the AS6809 assembler.  The designation [] refers to  a  required
+        addressing  mode  argument.   The  following  list specifies the
+        format for each addressing mode supported by AS6809:  
+
+                #data           immediate data
+                                byte or word data
+        
+                *dir            direct page addressing
+                                (see .setdp directive)
+                                0 <= dir <= 255 
+        
+                label           branch label
+        
+                r,r1,r2         registers
+                                cc,a,b,d,dp,x,y,s,u,pc
+        
+                ,-x     ,--x    register indexed
+                                autodecrement
+        
+
+
+        AS6809 ASSEMBLER                                        PAGE F-2
+        6809 INSTRUCTION SET
+
+
+                ,x+     ,x++    register indexed
+                                autoincrement
+        
+                ,x              register indexed addressing
+                                zero offset
+        
+                offset,x        register indexed addressing
+                                   -16 <= offset <= 15    ---  5-bit
+                                  -128 <= offset <= -17   ---  8-bit
+                                    16 <= offset <= 127   ---  8-bit
+                                -32768 <= offset <= -129  --- 16-bit
+                                   128 <= offset <= 32767 --- 16-bit
+                                (external definition of offset
+                                 uses 16-bit mode)
+        
+                a,x             accumulator offset indexed addressing
+        
+                ext             extended addressing
+        
+                ext,pc          pc addressing ( pc <- pc + ext )
+        
+                ext,pcr         pc relative addressing
+                                
+                [,--x]          register indexed indirect
+                                autodecrement
+        
+                [,x++]          register indexed indirect
+                                autoincrement
+        
+                [,x]            register indexed indirect addressing
+                                zero offset
+        
+                [offset,x]      register indexed indirect addressing
+                                  -128 <= offset <= 127   ---  8-bit
+                                -32768 <= offset <= -129  --- 16-bit
+                                   128 <= offset <= 32767 --- 16-bit
+                                (external definition of offset
+                                 uses 16-bit mode)
+        
+                [a,x]           accumulator offset indexed
+                                indirect addressing
+        
+                [ext]           extended indirect addressing
+        
+                [ext,pc]        pc indirect addressing
+                                ( [pc <- pc + ext] )
+        
+                [ext,pcr]       pc relative indirect addressing
+
+        The  terms  data, dir, label, offset, and ext may all be expres-
+        sions.  
+
+
+
+        AS6809 ASSEMBLER                                        PAGE F-3
+        6809 INSTRUCTION SET
+
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the 6809 technical data for valid modes.  
+
+
+        F.2.1  Inherent Instructions 
+
+                abx             daa
+                mul             nop
+                rti             rts
+                sex             swi
+                swi1            swi2
+                swi3            sync
+
+
+        F.2.2  Short Branch Instructions 
+
+                bcc     label           bcs     label
+                beq     label           bge     label
+                bgt     label           bhi     label
+                bhis    label           bhs     label
+                ble     label           blo     label
+                blos    label           bls     label
+                blt     label           bmi     label
+                bne     label           bpl     label
+                bra     label           brn     label
+                bvc     label           bvs     label
+                bsr     label
+
+
+        F.2.3  Long Branch Instructions 
+
+                lbcc    label           lbcs    label
+                lbeq    label           lbge    label
+                lbgt    label           lbhi    label
+                lbhis   label           lbhs    label
+                lble    label           lblo    label
+                lblos   label           lbls    label
+                lblt    label           lbmi    label
+                lbne    label           lbpl    label
+                lbra    label           lbrn    label
+                lbvc    label           lbvs    label
+                lbsr    label
+
+
+        AS6809 ASSEMBLER                                        PAGE F-4
+        6809 INSTRUCTION SET
+
+
+        F.2.4  Single Operand Instructions 
+
+                asla            aslb
+                asl     []
+        
+                asra            asrb
+                asr     []
+        
+                clra            clrb
+                clr     []
+        
+                coma            comb
+                com     []
+        
+                deca            decb
+                dec     []
+        
+                inca            incb
+                inc     []
+        
+                lsla            lslb
+                lsl     []
+        
+                lsra            lsrb
+                lsr     []
+        
+                nega            negb
+                neg     []
+        
+                rola            rolb
+                rol     []
+        
+                rora            rorb
+                ror     []
+        
+                tsta            tstb
+                tst     []
+
+
+        AS6809 ASSEMBLER                                        PAGE F-5
+        6809 INSTRUCTION SET
+
+
+        F.2.5  Double Operand Instructions 
+
+                adca    []              adcb    []
+        
+                adda    []              addb    []
+        
+                anda    []              andb    []
+        
+                bita    []              bitb    []
+        
+                cmpa    []              cmpb    []
+        
+                eora    []              eorb    []
+        
+                lda     []              ldb     []
+        
+                ora     []              orb     []
+        
+                sbca    []              sbcb    []
+        
+                sta     []              stb     []
+        
+                suba    []              subb    []
+
+
+        F.2.6  D-register Instructions 
+
+                addd    []              subd    []
+                cmpd    []              ldd     []
+                std     []
+
+
+        F.2.7  Index/Stack Register Instructions 
+
+                cmps    []              cmpu    []
+                cmpx    []              cmpy    []
+        
+                lds     []              ldu     []
+                ldx     []              ldy     []
+        
+                leas    []              leau    []
+                leax    []              leay    []
+        
+                sts     []              stu     []
+                stx     []              sty     []
+        
+                pshs    r               pshu    r
+                puls    r               pulu    r
+
+
+        AS6809 ASSEMBLER                                        PAGE F-6
+        6809 INSTRUCTION SET
+
+
+        F.2.8  Jump and Jump to Subroutine Instructions 
+
+                jmp     []              jsr     []
+
+
+        F.2.9  Register - Register Instructions 
+
+                exg     r1,r2           tfr     r1,r2
+
+
+        F.2.10  Condition Code Register Instructions 
+
+                andcc   #data           orcc    #data
+                cwai    #data
+
+
+        F.2.11  6800 Compatibility Instructions 
+
+                aba             cba
+                clc             cli
+                clv             des
+                dex             ins
+                inx
+                ldaa    []      ldab    []
+                oraa    []      orab    []
+                psha            pshb
+                pula            pulb
+                sba             sec
+                sei             sev
+                staa    []      stab    []
+                tab             tap
+                tba             tpa
+                tsx             txs
+                wai
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX G
+
+                                AS6811 ASSEMBLER
+
+
+
+
+
+        G.1  68HC11 REGISTER SET 
+
+        The following is a list of the 68HC11 registers used by AS6811: 
+
+                a,b     -       8-bit accumulators
+                d       -       16-bit accumulator <a:b>
+                x,y     -       index registers
+
+
+        G.2  68HC11 INSTRUCTION SET 
+
+
+           The  following tables list all 68HC11 mnemonics recognized by
+        the AS6811 assembler.  The designation [] refers to  a  required
+        addressing  mode  argument.   The  following  list specifies the
+        format for each addressing mode supported by AS6811:  
+
+                #data           immediate data
+                                byte or word data
+        
+                *dir            direct page addressing
+                                (see .setdp directive)
+                                0 <= dir <= 255 
+        
+                ,x              register indirect addressing
+                                zero offset
+        
+                offset,x        register indirect addressing
+                                0 <= offset <= 255
+        
+                ext             extended addressing
+        
+                label           branch label
+
+        The terms data, dir, offset, and ext may all be expressions.  
+
+
+
+        AS6811 ASSEMBLER                                        PAGE G-2
+        68HC11 INSTRUCTION SET
+
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the 68HC11 technical data for valid modes.  
+
+
+        G.2.1  Inherent Instructions 
+
+                aba             abx
+                aby             cba
+                clc             cli
+                clv             daa
+                des             dex
+                dey             fdiv
+                idiv            ins
+                inx             iny
+                mul             nop
+                rti             rts
+                sba             sec
+                sei             sev
+                stop            swi
+                tab             tap
+                tba             tpa
+                tsx             txs
+                wai             xgdx
+                xgdy
+        
+                psha            pshb
+                psh a           psh b
+                pshx            pshy
+                psh x           psh y
+        
+                pula            pulb
+                pul a           pul b
+                pulx            puly
+                pul x           pul y
+
+
+        G.2.2  Branch Instructions 
+
+                bra     label           brn     label
+                bhi     label           bls     label
+                bcc     label           bhs     label
+                bcs     label           blo     label
+                bne     label           beq     label
+                bvc     label           bvs     label
+                bpl     label           bmi     label
+                bge     label           blt     label
+                bgt     label           ble     label
+                bsr     label
+
+
+        AS6811 ASSEMBLER                                        PAGE G-3
+        68HC11 INSTRUCTION SET
+
+
+        G.2.3  Single Operand Instructions 
+
+                asla            aslb            asld
+                asl a           asl b           asl d
+                asl     []
+        
+                asra            asrb
+                asr a           asr b
+                asr     []
+        
+                clra            clrb
+                clr a           clr b
+                clr     label
+        
+                coma            comb
+                com a           com b
+                com     []
+        
+                deca            decb
+                dec a           dec b
+                dec     []
+        
+                inca            incb
+                inc a           inc b
+                inc     []
+        
+                lsla            lslb            lsld
+                lsl a           lsl b           lsl d
+                lsl     []
+        
+                lsra            lsrb            lsrd
+                lsr a           lsr b           lsr d
+                lsr     []
+        
+                nega            negb
+                neg a           neg b
+                neg     []
+        
+                rola            rolb
+                rol a           rol b
+                rol     []
+        
+                rora            rorb
+                ror a           ror b
+                ror     []
+        
+                tsta            tstb
+                tst a           tst b
+                tst     []
+
+
+        AS6811 ASSEMBLER                                        PAGE G-4
+        68HC11 INSTRUCTION SET
+
+
+        G.2.4  Double Operand Instructions 
+
+                adca    []              adcb    []
+                adc a   []              adc b   []
+        
+                adda    []      addb    []      addd    []
+                add a   []      add b   []      add d   []
+        
+                anda    []              andb    []
+                and a   []              and b   []
+        
+                bita    []              bitb    []
+                bit a   []              bit b   []
+        
+                cmpa    []              cmpb    []
+                cmp a   []              cmp b   []
+        
+                eora    []              eorb    []
+                eor a   []              eor b   []
+        
+                ldaa    []              ldab    []
+                lda a   []              lda b   []
+        
+                oraa    []              orab    []
+                ora a   []              ora b   []
+        
+                sbca    []              sbcb    []
+                sbc a   []              sbc b   []
+        
+                staa    []              stab    []
+                sta a   []              sta b   []
+        
+                suba    []      subb    []      subd    []
+                sub a   []      sub b   []      sub d   []
+
+
+        G.2.5  Bit Manupulation Instructions 
+
+                bclr    [],#data
+                bset    [],#data
+        
+                brclr   [],#data,label
+                brset   [],#data,label
+
+
+
+
+        AS6811 ASSEMBLER                                        PAGE G-5
+        68HC11 INSTRUCTION SET
+
+
+        G.2.6  Jump and Jump to Subroutine Instructions 
+
+                jmp     []              jsr     []
+
+
+        G.2.7  Long Register Instructions 
+
+                cpx     []              cpy     []
+        
+                ldd     []              lds     []
+                ldx     []              ldy     []
+        
+                std     []              sts     []
+                stx     []              sty     []
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX H
+
+                                AS6812 ASSEMBLER
+
+
+
+
+
+        H.1  68HC12 REGISTER SET 
+
+        The following is a list of the 68HC12 registers used by AS6812: 
+
+                a,b     -       8-bit accumulators
+                d       -       16-bit accumulator <a:b>
+                x,y     -       index registers
+                sp,s    -       stack pointer
+                pc      -       program counter
+                ccr,cc  -       condition code register
+
+
+        H.2  68HC12 INSTRUCTION SET 
+
+
+           The  following tables list all 68HC12 mnemonics recognized by
+        the AS6812 assembler.  The designation [] refers to  a  required
+        addressing  mode  argument.   The  following  list specifies the
+        format for each addressing mode supported by AS6812:  
+
+                #data           immediate data
+                                byte or word data
+        
+                ext             extended addressing
+        
+                pg              memory page number
+        
+                *dir            direct page addressing
+                                (see .setdp directive)
+                                0 <= dir <= 255 
+        
+                label           branch label
+        
+                r,r1,r2         registers
+                                ccr,a,b,d,x,y,sp,pc
+        
+
+
+        AS6812 ASSEMBLER                                        PAGE H-2
+        68HC12 INSTRUCTION SET
+
+
+                -x      x-      register indexed, pre or
+                ,-x     ,x-     post autodecrement by 1
+        
+                n,-x    n,x-    register indexed, pre or
+                                post autodecrement by 1 - 8
+        
+                +x      x+      register indexed, pre or
+                ,+x     ,x+     post autoincrement by 1
+        
+                n,+x    n,x+    register indexed, pre or
+                                post autoincrement by 1 - 8
+        
+                offset,x        register indexed addressing
+                                   -16 <= offset <= 15    ---  5-bit
+                                  -256 <= offset <= -17   ---  9-bit
+                                    16 <= offset <= 255   ---  9-bit
+                                -32768 <= offset <= -257  --- 16-bit
+                                   256 <= offset <= 32767 --- 16-bit
+                                (external definition of offset
+                                 uses 16-bit mode)
+        
+                [offset,x]      register indexed indirect addressing
+                                -32768 <= offset <= 32767 --- 16-bit
+        
+                [,x]            register indexed indirect addressing
+                                zero offset
+        
+                a,x             accumulator offset indexed addressing
+        
+                [d,x]           d accumulator offset indexed
+                                indirect addressing
+
+        The  terms  data, dir, label, offset, and ext may all be expres-
+        sions.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the 68HC12 technical data for valid modes.  
+
+
+        AS6812 ASSEMBLER                                        PAGE H-3
+        68HC12 INSTRUCTION SET
+
+
+        H.2.1  Inherent Instructions 
+
+                aba             bgnd            cba
+                daa             dex             dey
+                ediv            edivs           emul
+                emuls           fdiv            idiv
+                idivs           inx             iny
+                mem             mul             nop
+                psha            pshb            pshc
+                pshd            pshx            pshy
+                pula            pulb            pulc
+                puld            pulx            puly
+                rev             revw            rtc
+                rti             rts             sba
+                stop            swi             tab
+                tba             wai             wav
+                wavr
+
+
+        H.2.2  Short Branch Instructions 
+
+                bcc     label           bcs     label
+                beq     label           bge     label
+                bgt     label           bhi     label
+                bhis    label           bhs     label
+                ble     label           blo     label
+                blos    label           bls     label
+                blt     label           bmi     label
+                bne     label           bpl     label
+                bra     label           brn     label
+                bvc     label           bvs     label
+                bsr     label
+
+
+        H.2.3  Long Branch Instructions 
+
+                lbcc    label           lbcs    label
+                lbeq    label           lbge    label
+                lbgt    label           lbhi    label
+                lbhis   label           lbhs    label
+                lble    label           lblo    label
+                lblos   label           lbls    label
+                lblt    label           lbmi    label
+                lbne    label           lbpl    label
+                lbra    label           lbrn    label
+                lbvc    label           lbvs    label
+
+
+        AS6812 ASSEMBLER                                        PAGE H-4
+        68HC12 INSTRUCTION SET
+
+
+        H.2.4  Branch on Decrement, Test, or Increment 
+
+                dbeq    r,label         dbne    r,label
+                ibeq    r,label         ibne    r,label
+                tbeq    r,label         tbne    r,label
+
+
+        H.2.5  Bit Clear and Set Instructions 
+
+                bclr    [],#data
+                bset    [],#data
+
+
+        H.2.6  Branch on Bit Clear or Set 
+
+                brclr   [],#data,label
+                brset   [],#data,label
+
+
+        AS6812 ASSEMBLER                                        PAGE H-5
+        68HC12 INSTRUCTION SET
+
+
+        H.2.7  Single Operand Instructions 
+
+                asla            aslb
+                asl     []
+        
+                asra            asrb
+                asr     []
+        
+                clra            clrb
+                clr     []
+        
+                coma            comb
+                com     []
+        
+                deca            decb
+                dec     []
+        
+                inca            incb
+                inc     []
+        
+                lsla            lslb
+                lsl     []
+        
+                lsra            lsrb
+                lsr     []
+        
+                nega            negb
+                neg     []
+        
+                rola            rolb
+                rol     []
+        
+                rora            rorb
+                ror     []
+        
+                tsta            tstb
+                tst     []
+
+
+        AS6812 ASSEMBLER                                        PAGE H-6
+        68HC12 INSTRUCTION SET
+
+
+        H.2.8  Double Operand Instructions 
+
+                adca    []              adcb    []
+        
+                adda    []              addb    []
+        
+                anda    []              andb    []
+        
+                bita    []              bitb    []
+        
+                cmpa    []              cmpb    []
+        
+                eora    []              eorb    []
+        
+                ldaa    []      <=>     lda     []
+        
+                ldab    []      <=>     ldb     []
+        
+                oraa    []      <=>     ora     []
+        
+                orab    []      <=>     orb     []
+        
+                sbca    []              sbcb    []
+        
+                staa    []      <=>     sta     []
+        
+                stab    []      <=>     stb     []
+        
+                suba    []              subb    []
+
+
+        H.2.9  Move Instructions 
+
+                movb    [],[]           movw    [],[]
+
+
+        H.2.10  D-register Instructions 
+
+                addd    []              subd    []
+                cpd     []      <=>     cmpd    []
+                ldd     []              std     []
+
+
+        AS6812 ASSEMBLER                                        PAGE H-7
+        68HC12 INSTRUCTION SET
+
+
+        H.2.11  Index/Stack Register Instructions 
+
+                cps     []      <=>     cmps    []
+                cpx     []      <=>     cmpx    []
+                cpy     []      <=>     cmpy    []
+        
+                lds     []
+                ldx     []              ldy     []
+        
+                leas    []
+                leax    []              leay    []
+        
+                sts     []
+                stx     []              sty     []
+
+
+        H.2.12  Jump and Jump/Call to Subroutine Instructions 
+
+                call    [],pg
+                jmp     []              jsr     []
+
+
+        H.2.13  Other Special Instructions 
+
+                emacs   []
+                emaxd   []              emaxm   []
+                emind   []              eminm   []
+                etbl    []
+                maxa    []              maxm    []
+                mina    []              minm    []
+                tbl     []              trap    #data
+
+
+        H.2.14  Register - Register Instructions 
+
+                exg     r1,r2           sex     r1,r2
+                tfr     r1,r2
+
+
+        H.2.15  Condition Code Register Instructions 
+
+                andcc   #data           orcc    #data
+
+
+        AS6812 ASSEMBLER                                        PAGE H-8
+        68HC12 INSTRUCTION SET
+
+
+        H.2.16  M68HC11 Compatibility Mode Instructions 
+
+                abx             aby             clc
+                cli             clv             des
+                ins             sec             sei
+                sev             tap             tpa
+                tsx             tsy             txs
+                tys             xgdx            xgdy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX I
+
+                                AS6816 ASSEMBLER
+
+
+
+
+
+        I.1  68HC16 REGISTER SET 
+
+        The following is a list of the 68HC16 registers used by AS6816: 
+
+                a,b     -       8-bit accumulators
+                d       -       16-bit accumulator <a:b>
+                e       -       16-bit accumulator
+                x,y,z   -       index registers
+                k       -       address extension register
+                s       -       stack pointer
+                ccr     -       condition code
+
+
+        I.2  68HC16 INSTRUCTION SET 
+
+
+           The  following tables list all 68HC16 mnemonics recognized by
+        the AS6816 assembler.  The designation [] refers to  a  required
+        addressing  mode  argument.   The  following  list specifies the
+        format for each addressing mode supported by AS6816:  
+
+                #data           immediate data
+                                byte or word data
+        
+                #xo,#yo         local immediate data (mac / rmac)
+        
+                label           branch label
+        
+                r               register
+                                ccr,a,b,d,e,x,y,z,s
+        
+                ,x              zero offset register indexed addressing
+                ,x8
+                ,x16
+        
+                offset,x        register indexed addressing
+
+
+        AS6816 ASSEMBLER                                        PAGE I-2
+        68HC16 INSTRUCTION SET
+
+
+                                     0 <= offset <= 255   ---  8-bit
+                                -32768 <= offset <= -1    --- 16-bit
+                                   256 <= offset <= 32767 --- 16-bit
+                                (external definition of offset
+                                 uses 16-bit mode)
+        
+                offset,x8       unsigned 8-bit offset indexed addressing
+                offset,x16      signed 16-bit offset indexed addressing
+        
+                e,x             accumulator offset indexed addressing
+        
+                ext             extended addressing
+        
+                bank            64K bank number (jmp / jsr)
+
+        The  terms data, label, offset, bank, and ext may all be expres-
+        sions.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the 6816 technical data for valid modes.  
+
+
+        I.2.1  Inherent Instructions 
+
+                aba             abx             aby             abz
+                ace             aced            ade             adx
+                ady             adz             aex             aey
+                aez             bgnd            cba             daa
+                ediv            edivs           emul            emuls
+                fdiv            fmuls           idiv            ldhi
+                lpstop          mul             nop             psha
+                pshb            pshmac          pula            pulb
+                pulmac          rtr             rts             sba
+                sde             sted            swi             sxt
+                tab             tap             tba             tbek
+                tbsk            tbxk            tbyk            tbzk
+                tde             tdmsk           tdp             ted
+                tedm            tekb            tem             tmer
+                tmet            tmxed           tpa             tpd
+                tskb            tsx             tsy             tsz
+                txkb            txs             txy             txz
+                tykb            tys             tyx             tyz
+                tzkb            tzs             tzx             tzy
+                wai             xgab            xgde            xgdx
+                xgdy            xgdz            xgex            xgey
+                xgez
+
+
+        AS6816 ASSEMBLER                                        PAGE I-3
+        68HC16 INSTRUCTION SET
+
+
+        I.2.2  Push/Pull Multiple Register Instructions 
+
+                pshm    r,...           pulm    r,...
+
+
+        I.2.3  Short Branch Instructions 
+
+                bcc     label           bcs     label
+                beq     label           bge     label
+                bgt     label           bhi     label
+                bhis    label           bhs     label
+                ble     label           blo     label
+                blos    label           bls     label
+                blt     label           bmi     label
+                bne     label           bpl     label
+                bra     label           brn     label
+                bvc     label           bvs     label
+                bsr     label
+
+
+        I.2.4  Long Branch Instructions 
+
+                lbcc    label           lbcs    label
+                lbeq    label           lbge    label
+                lbgt    label           lbhi    label
+                lbhis   label           lbhs    label
+                lble    label           lblo    label
+                lblos   label           lbls    label
+                lblt    label           lbmi    label
+                lbne    label           lbpl    label
+                lbra    label           lbrn    label
+                lbvc    label           lbvs    label
+                lbsr    label
+
+
+        I.2.5  Bit Manipulation Instructions 
+
+                bclr    [],#data
+                bset    [],#data
+        
+                brclr   [],#data,label
+                brset   [],#data,label
+
+
+        AS6816 ASSEMBLER                                        PAGE I-4
+        68HC16 INSTRUCTION SET
+
+
+        I.2.6  Single Operand Instructions 
+
+                asla                    aslb
+                asld                    asle
+                aslm
+                asl     []              aslw    []
+        
+                asra                    asrb
+                asrd                    asre
+                asrm
+                asr     []              asrw    []
+        
+                clra                    clrb
+                clrd                    clre
+                                        clrm
+                clr     []              clrw    []
+        
+                coma                    comb
+                comd                    come
+                com     []              comw    []
+        
+                deca                    decb
+                dec     []              decw    []
+        
+                inca                    incb
+                inc     []              incw    []
+        
+                lsla                    lslb
+                lsld                    lsle
+                lslm
+                lsl     []              lslw    []
+        
+                lsra                    lsrb
+                lsrd                    lsre
+                lsr     []              lsrw    []
+        
+                nega                    negb
+                negd                    nege
+                neg     []              negw    []
+        
+                rola                    rolb
+                rold                    role
+                rol     []              rolw    []
+        
+                rora                    rorb
+                rord                    rore
+                ror     []              rorw    []
+        
+                tsta                    tstb
+                tsta                    tste
+                tst     []              tstw    []
+
+
+        AS6816 ASSEMBLER                                        PAGE I-5
+        68HC16 INSTRUCTION SET
+
+
+        I.2.7  Double Operand Instructions 
+
+                adca    []              adcb    []
+                adcd    []              adce    []
+        
+                adda    []              addb    []
+                addd    []              adde    []
+        
+                anda    []              andb    []
+                andd    []              ande    []
+        
+                bita    []              bitb    []
+        
+                cmpa    []              cmpb    []
+                cpd     []              cpe     []
+        
+                eora    []              eorb    []
+                eord    []              eore    []
+        
+                ldaa    []              ldab    []
+                ldd     []              lde     []
+        
+                oraa    []              orab    []
+                ord     []              ore     []
+        
+                sbca    []              sbcb    []
+                sbcd    []              sbce    []
+        
+                staa    []              stab    []
+                std     []              ste     []
+        
+                suba    []              subb    []
+                subd    []              sube    []
+
+
+        I.2.8  Index/Stack Register Instructions 
+
+                cps     []              cpx     []
+                cpy     []              cpz     []
+        
+                lds     []              ldx     []
+                ldy     []              ldz     []
+        
+                sts     []              stx     []
+                sty     []              stz     []
+
+
+        AS6816 ASSEMBLER                                        PAGE I-6
+        68HC16 INSTRUCTION SET
+
+
+        I.2.9  Jump and Jump to Subroutine Instructions 
+
+                jmp     bank,[]         jsr     bank,[]
+
+
+        I.2.10  Condition Code Register Instructions 
+
+                andp    #data           orp     #data
+
+
+        I.2.11  Multiply and Accumulate Instructions 
+
+                mac     #data           rmac    #data
+                mac     #xo,#yo         rmac    #xo,#yo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX J
+
+                                 ASH8 ASSEMBLER
+
+
+
+
+
+        J.1  H8/3XX REGISTER SET 
+
+        The following is a list of the H8 registers used by ASH8:  
+
+                r0  -  r7,sp            16-bit accumulators
+                r0L -  r7L,spL          8-bit accumulators
+                r0H -  r7H,spH          8-bit accumulators
+                spL,spH,sp              stack pointers
+                ccr                     condition code
+
+
+        J.2  H8/3XX INSTRUCTION SET 
+
+
+           The  following tables list all H8/3xx mnemonics recognized by
+        the ASH8 assembler.  The designation [] refers to a required ad-
+        dressing mode argument.  The following list specifies the format
+        for each addressing mode supported by ASH8:  
+
+                #xx:3           immediate data (3  bit)
+                #xx:8           immediate data (8  bit)
+                #xx:16          immediate data (16 bit)
+        
+                *dir            direct page addressing
+                                (see .setdp directive)
+                                0xFF00 <= dir <= 0xFFFF
+        
+                label           branch label
+        
+        
+                rn              registers (16 bit)
+                                r0-r7,sp
+        
+                rnB             registers (8 bit)
+                                r0H-r7H,r0L-r7L,spH,spL
+        
+
+
+        ASH8 ASSEMBLER                                          PAGE J-2
+        H8/3XX INSTRUCTION SET
+
+
+                ccr             condition code register
+        
+                @rn             register indirect
+        
+                @-rn            register indirect (auto pre-decrement)
+        
+                @rn+            register indirect (auto post-increment)
+        
+                @[offset,rn]    register indirect, 16-bit displacement
+        
+                @@offset        memory indirect, (8-bit address)
+        
+                ext             extended addressing (16-bit)
+
+        The  terms  data, dir, label, offset, and ext may all be expres-
+        sions.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the H8/3xx technical data for valid modes.  
+
+
+        J.2.1  Inherent Instructions 
+
+                eepmov
+                nop
+                sleep
+                rte
+                rts
+
+
+        J.2.2  Branch Instructions 
+
+                bcc     label                   bcs     label
+                beq     label                   bf      label
+                bge     label                   bgt     label
+                bhi     label                   bhis    label
+                bhs     label                   ble     label
+                blo     label                   blos    label
+                bls     label                   blt     label
+                bmi     label                   bne     label
+                bpl     label                   bra     label
+                brn     label                   bt      label
+                bvc     label                   bvs     label
+                bsr     label
+
+
+        ASH8 ASSEMBLER                                          PAGE J-3
+        H8/3XX INSTRUCTION SET
+
+
+        J.2.3  Single Operand Instructions 
+
+                Free Form
+        
+                daa     rnB                     das     rnB
+        
+                dec     rnB                     inc     rnB
+        
+                neg     rnB                     not     rnB
+        
+                rotxl   rnB                     rotxr   rnB
+        
+                rotl    rnB                     rotr    rnB
+        
+                shal    rnB                     shar    rnB
+        
+                shll    rnB                     shlr    rnB
+        
+                push    rn                      pop     rn
+        
+        
+                Byte / Word Form
+        
+                daa.b   rnB                     das.b   rnB
+        
+                dec.b   rnB                     inc.b   rnB
+        
+                neg.b   rnB                     not.b   rnB
+        
+                rotxl.b rnB                     rotxr.b rnB
+        
+                rotl.b  rnB                     rotr.b  rnB
+        
+                shal.b  rnB                     shar.b  rnB
+        
+                shll.b  rnB                     shlr.b  rnB
+        
+                push.w  rn                      pop.w   rn
+
+
+        ASH8 ASSEMBLER                                          PAGE J-4
+        H8/3XX INSTRUCTION SET
+
+
+        J.2.4  Double Operand Instructions 
+
+                Free Form
+        
+                add     rnB,rnB                 add     #xx:8,rnB
+                add     rn,rn
+                adds    #1,rn                   adds    #2,rn
+                addx    rnB,rnB                 addx    #xx:8,rnB
+        
+                cmp     rnB,rnB                 cmp     #xx:8,rnB
+                cmp     rn,rn
+        
+                sub     rnB,rnB
+                sub     rn,rn
+                subs    #1,rn                   subs    #2,rn
+                subx    rnB,rnB                 subx    #xx:8,rnB
+        
+                and     rnB,rnB                 and     #xx:8,rnB
+                                                and     #xx:8,ccr
+        
+                or      rnB,rnB                 or      #xx:8,rnB
+                                                or      #xx:8,ccr
+        
+                xor     rnB,rnB                 xor     #xx:8,rnB
+                                                xor     #xx:8,ccr
+        
+        
+                Byte / Word Form
+        
+                add.b   rnB,rnB                 add.b   #xx:8,rnB
+                add.w   rn,rn
+        
+                cmp.b   rnB,rnB                 cmp.b   #xx:8,rnB
+                cmp.w   rn,rn
+        
+                sub.b   rnB,rnB
+                sub.w   rn,rn
+        
+                addx.b  rnB,rnB                 addx.b  #xx:8,rnB
+        
+                and.b   rnB,rnB                 and.b   #xx:8,rnB
+                                                and.b   #xx:8,ccr
+        
+                or.b    rnB,rnB                 or.b    #xx:8,rnB
+                                                or.b    #xx:8,ccr
+        
+                subx.b  rnB,rnB                 subx.b  #xx:8,rnB
+        
+                xor.b   rnB,rnB                 xor.b   #xx:8,rnB
+                                                xor.b   #xx:8,ccr
+
+
+        ASH8 ASSEMBLER                                          PAGE J-5
+        H8/3XX INSTRUCTION SET
+
+
+        J.2.5  Mov Instructions 
+
+                Free Form
+        
+                mov     rnB,rnB                 mov     rn,rn
+                mov     #xx:8,rnB               mov     #xx:16,rn
+                mov     @rn,rnB                 mov     @rn,rn
+                mov     @[offset,rn],rnB        mov     @[offset,rn],rn
+                mov     @rn+,rnB                mov     @rn+,rn
+                mov     @dir,rnB
+                mov     dir,rnB
+                mov     *@dir,rnB
+                mov     *dir,rnB
+                mov     @label,rnB              mov     @label,rn
+                mov     label,rnB               mov     label,rn
+                mov     rnB,@rn                 mov     rn,@rn
+                mov     rnB,@[offset,rn]        mov     rn,@[offset,rn]
+                mov     rnB,@-rn                mov     rn,@-rn
+                mov     rnB,@dir
+                mov     rnB,dir
+                mov     rnB,*@dir
+                mov     rnB,*dir
+                mov     rnB,@label              mov     rn,@label
+                mov     rnB,label               mov     rn,label
+        
+        
+                Byte / Word Form
+        
+                mov.b   rnB,rnB                 mov.w   rn,rn
+                mov.b   #xx:8,rnB               mov.w   #xx:16,rn
+                mov.b   @rn,rnB                 mov.w   @rn,rn
+                mov.b   @[offset,rn],rnB        mov.w   @[offset,rn],rn
+                mov.b   @rn+,rnB                mov.w   @rn+,rn
+                mov.b   @dir,rnB
+                mov.b   dir,rnB
+                mov.b   *@dir,rnB
+                mov.b   *dir,rnB
+                mov.b   @label,rnB              mov.w   @label,rn
+                mov.b   label,rnB               mov.w   label,rn
+                mov.b   rnB,@rn                 mov.w   rn,@rn
+                mov.b   rnB,@[offset,rn]        mov.w   rn,@[offset,rn]
+                mov.b   rnB,@-rn                mov.w   rn,@-rn
+                mov.b   rnB,@dir
+                mov.b   rnB,dir
+                mov.b   rnB,*@dir
+                mov.b   rnB,*dir
+                mov.b   rnB,@label              mov.w   rn,@label
+                mov.b   rnB,label               mov.w   rn,label
+
+
+        ASH8 ASSEMBLER                                          PAGE J-6
+        H8/3XX INSTRUCTION SET
+
+
+        J.2.6  Bit Manipulation Instructions 
+
+                bld     #xx:3,rnB               bld     #xx:3,@rn
+                bld     #xx:3,@dir              bld     #xx:3,dir
+                bld     #xx:3,*@dir             bld     #xx:3,*dir
+        
+                bild    #xx:3,rnB               bild    #xx:3,@rn
+                bild    #xx:3,@dir              bild    #xx:3,dir
+                bild    #xx:3,*@dir             bild    #xx:3,*dir
+        
+                bst     #xx:3,rnB               bst     #xx:3,@rn
+                bst     #xx:3,@dir              bst     #xx:3,dir
+                bst     #xx:3,*@dir             bst     #xx:3,*dir
+        
+                bist    #xx:3,rnB               bist    #xx:3,@rn
+                bist    #xx:3,@dir              bist    #xx:3,dir
+                bist    #xx:3,*@dir             bist    #xx:3,*dir
+        
+                band    #xx:3,rnB               band    #xx:3,@rn
+                band    #xx:3,@dir              band    #xx:3,dir
+                band    #xx:3,*@dir             band    #xx:3,*dir
+        
+                biand   #xx:3,rnB               biand   #xx:3,@rn
+                biand   #xx:3,@dir              biand   #xx:3,dir
+                biand   #xx:3,*@dir             biand   #xx:3,*dir
+        
+                bor     #xx:3,rnB               bor     #xx:3,@rn
+                bor     #xx:3,@dir              bor     #xx:3,dir
+                bor     #xx:3,*@dir             bor     #xx:3,*dir
+        
+                bior    #xx:3,rnB               bior    #xx:3,@rn
+                bior    #xx:3,@dir              bior    #xx:3,dir
+                bior    #xx:3,*@dir             bior    #xx:3,*dir
+        
+                bxor    #xx:3,rnB               bxor    #xx:3,@rn
+                bxor    #xx:3,@dir              bxor    #xx:3,dir
+                bxor    #xx:3,*@dir             bxor    #xx:3,*dir
+        
+                bixor   #xx:3,rnB               bixor   #xx:3,@rn
+                bixor   #xx:3,@dir              bixor   #xx:3,dir
+                bixor   #xx:3,*@dir             bixor   #xx:3,*dir
+
+
+        ASH8 ASSEMBLER                                          PAGE J-7
+        H8/3XX INSTRUCTION SET
+
+
+        J.2.7  Extended Bit Manipulation Instructions 
+
+                bset    #xx:3,rnB               bset    #xx:3,@rn
+                bset    #xx:3,@dir              bset    #xx:3,dir
+                bset    #xx:3,*@dir             bset    #xx:3,*dir
+                bset    rnB,rnB                 bset    rnB,@rn
+                bset    rnB,@dir                bset    rnB,dir
+                bset    rnB,*@dir               bset    rnB,*dir
+        
+                bclr    #xx:3,rnB               bclr    #xx:3,@rn
+                bclr    #xx:3,@dir              bclr    #xx:3,dir
+                bclr    #xx:3,*@dir             bclr    #xx:3,*dir
+                bclr    rnB,rnB                 bclr    rnB,@rn
+                bclr    rnB,@dir                bclr    rnB,dir
+                bclr    rnB,*@dir               bclr    rnB,*dir
+        
+                bnot    #xx:3,rnB               bnot    #xx:3,@rn
+                bnot    #xx:3,@dir              bnot    #xx:3,dir
+                bnot    #xx:3,*@dir             bnot    #xx:3,*dir
+                bnot    rnB,rnB                 bnot    rnB,@rn
+                bnot    rnB,@dir                bnot    rnB,dir
+                bnot    rnB,*@dir               bnot    rnB,*dir
+        
+                btst    #xx:3,rnB               btst    #xx:3,@rn
+                btst    #xx:3,@dir              btst    #xx:3,dir
+                btst    #xx:3,*@dir             btst    #xx:3,*dir
+                btst    rnB,rnB                 btst    rnB,@rn
+                btst    rnB,@dir                btst    rnB,dir
+                btst    rnB,*@dir               btst    rnB,*dir
+
+
+        J.2.8  Condition Code Instructions 
+
+                andc    #xx:8,ccr               andc    #xx:8
+                and     #xx:8,ccr               and.b   #xx:8,ccr
+        
+                ldc     #xx:8,ccr               ldc     #xx:8
+                ldc     rnB,ccr                 ldc     rnB
+        
+                orc     #xx:8,ccr               orc     #xx:8
+                or      #xx:8,ccr               or.b    #xx:8,ccr
+        
+                xorc    #xx:8,ccr               xorc    #xx:8
+                xor     #xx:8,ccr               xor.b   #xx:8,ccr
+        
+                stc     ccr,rnB                 stc     rnB
+
+
+        ASH8 ASSEMBLER                                          PAGE J-8
+        H8/3XX INSTRUCTION SET
+
+
+        J.2.9  Other Instructions 
+
+                divxu   rnB,rn                  divxu.b rnB,rn
+        
+                mulxu   rnB,rn                  mulxu.b rnB,rn
+        
+                movfpe  @label,rnB              movfpe  label,rnB
+                movfpe.b  @label,rnB            movfpe.b  label,rnB
+        
+                movtpe  @label,rnB              movtpe  label,rnB
+                movtpe.b  @label,rnB            movtpe.b  label,rnB
+
+
+        J.2.10  Jump and Jump to Subroutine Instructions 
+
+                jmp     @rn                     jmp     @@dir
+                jmp     @label                  jmp     label
+        
+                jsr     @rn                     jsr     @@dir
+                jsr     @label                  jsr     label
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX K
+
+                                AS8051 ASSEMBLER
+
+
+
+
+
+        K.1  ACKNOWLEDGMENT 
+
+
+           Thanks  to  John  Hartman  for his contribution of the AS8051
+        cross assembler.  
+
+                John L. Hartman
+                jhartman@compuserve.com
+
+
+        K.2  8051 REGISTER SET 
+
+        The following is a list of the 8051 registers used by AS8051:  
+
+                a,b             -       8-bit accumulators
+                r0,r1,r2,r3     -       8-bit registers
+                r4,r5,r6,r7
+                dptr            -       data pointer
+                sp              -       stack pointer
+                pc              -       program counter
+                psw             -       status word
+                c               -       carry (bit in status word)
+
+
+        AS8051 ASSEMBLER                                        PAGE K-2
+        8051 REGISTER SET
+
+
+        K.3  8051 INSTRUCTION SET 
+
+
+           The  following  tables  list all 8051 mnemonics recognized by
+        the AS8051 assembler.  The following list specifies  the  format
+        for each addressing mode supported by AS8051:  
+
+                #data           immediate data
+                                byte or word data
+        
+                r,r1,r2         register r0,r1,r2,r3,r4,r5,r6, or r7
+        
+                @r              indirect on register r0 or r1
+                @dptr           indirect on data pointer
+                @a+dptr         indirect on accumulator
+                                plus data pointer
+                @a+pc           indirect on accumulator
+                                plus program counter
+        
+                addr            direct memory address
+        
+                bitaddr         bit address
+        
+                label           call or jump label
+
+        The terms data, addr, bitaddr, and label may all be expressions. 
+
+           Note  that  not all addressing modes are valid with every in-
+        struction.  Refer to the 8051 technical data for valid modes.  
+
+
+        K.3.1  Inherent Instructions 
+
+                nop
+
+
+        AS8051 ASSEMBLER                                        PAGE K-3
+        8051 INSTRUCTION SET
+
+
+        K.3.2  Move Instructions 
+
+                mov     a,#data         mov     a,addr
+                mov     a,r             mov     a,@r
+        
+                mov     r,#data         mov     r,addr
+                mov     r,a
+        
+                mov     addr,a          mov     addr,#data
+                mov     addr,r          mov     addr,@r
+                mov     addr1,addr2     mov     bitaddr,c
+        
+                mov     @r,#data        mov     @r,addr
+                mov     @r,a
+        
+                mov     c,bitaddr
+                mov     dptr,#data
+        
+                movc    a,@a+dptr       movc    a,@a+pc
+                movx    a,@dptr         movx    a,@r
+                movx    @dptr,a         movx    @r,a
+
+
+        K.3.3  Single Operand Instructions 
+
+                clr     a               clr     c
+                clr     bitaddr
+                cpl     a               cpl     c
+                cpl     bitaddr
+                setb    c               setb    bitaddr
+        
+                da      a               
+                rr      a               rrc     a
+                rl      a               rlc     a
+                swap    a
+        
+                dec     a               dec     r
+                dec     @r
+                inc     a               inc     r
+                inc     dptr            inc     @r
+        
+                div     ab              mul     ab
+        
+                pop     addr            push    addr
+
+
+        AS8051 ASSEMBLER                                        PAGE K-4
+        8051 INSTRUCTION SET
+
+
+        K.3.4  Two Operand Instructions 
+
+                add     a,#data         add     a,addr
+                add     a,r             add     a,@r
+                addc    a,#data         addc    a,addr
+                addc    a,r             addc    a,@r
+                subb    a,#data         subb    a,addr
+                subb    a,r             subb    a,@r
+                orl     a,#data         orl     a,addr
+                orl     a,r             orl     a,@r
+                orl     addr,a          orl     addr,#data
+                orl     c,bitaddr       orl     c,/bitaddr
+                anl     a,#data         anl     a,addr
+                anl     a,r             anl     a,@r
+                anl     addr,a          anl     addr,#data
+                anl     c,bitaddr       anl     c,/bitaddr
+                xrl     a,#data         xrl     a,addr
+                xrl     a,r             xrl     a,@r
+                xrl     addr,a          xrl     addr,#data
+                xrl     c,bitaddr       xrl     c,/bitaddr
+                xch     a,addr          xch     a,r
+                xch     a,@r            xchd    a,@r
+
+
+        K.3.5  Call and Return Instructions 
+
+                acall   label           lcall   label
+                ret                     reti
+                in      data
+                out     data
+                rst     data
+
+
+        K.3.6  Jump Instructions 
+
+                ajmp    label
+                cjne    a,#data,label   cjne    a,addr,label
+                cjne    r,#data,label   cjne    @r,#data,label
+                djnz    r,label         djnz    addr,label
+                jbc     bitadr,label
+                jb      bitadr,label    jnb     bitadr,label
+                jc      label           jnc     label
+                jz      label           jnz     label
+                jmp     @a+dptr
+                ljmp    label           sjmp    label
+
+
+        AS8051 ASSEMBLER                                        PAGE K-5
+        8051 INSTRUCTION SET
+
+
+        K.3.7  Predefined Symbols:  SFR Map 
+
+                        --------- 4 Bytes ----------
+                        ----    ----    ----    ----
+                FC                                          FF
+                F8                                          FB
+                F4                                          F7
+                F0      B                                   F3
+                EC                                          EF
+                E8                                          EB
+                E4                                          E7
+                E0      ACC                                 E3
+                DC                                          DF
+                D8                                          DB
+                D4                                          D7
+                D0      PSW                                 D3
+                CC   [  TL2     TH2                     ]   CF
+                C8   [  T2CON           RCAP2L  RCAP2H  ]   CB
+                C4                                          C7
+                C0                                          C3
+                BC                                          BF
+                B8      IP                                  BB
+                B4                                          B7
+                B0      P3                                  B3
+                AC                                          AF
+                A8      IE                                  AB
+                A4                                          A7
+                A0      P2                                  A3
+                9C                                          9F
+                98      SCON    SBUF                        9B
+                94                                          97
+                90      P1                                  93
+                8C      TH0     TH1                         8F
+                88      TCON    TMOD    TL0     TL1         8B
+                84                              PCON        87
+                80      P0      SP      DPL     DPH         83
+        
+                [...] Indicates Resident in 8052, not 8051
+
+
+        AS8051 ASSEMBLER                                        PAGE K-6
+        8051 INSTRUCTION SET
+
+
+        K.3.8  Predefined Symbols:  SFR Bit Addresses 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                FC                                          FF
+                F8                                          FB
+                F4      B.4     B.5     B.6     B.7         F7
+                F0      B.0     B.1     B.2     B.3         F3
+                EC                                          EF
+                E8                                          EB
+                E4      ACC.4   ACC.5   ACC.6   ACC.7       E7
+                E0      ACC.0   ACC.1   ACC.2   ACC.3       E3
+                DC                                          DF
+                D8                                          DB
+                D4      PSW.4   PSW.5   PSW.6   PSW.7       D7
+                D0      PSW.0   PSW.1   PSW.2   PSW.3       D3
+                CC   [  T2CON.4 T2CON.5 T2CON.6 T2CON.7 ]   CF
+                C8   [  T2CON.0 T2CON.1 T2CON.2 T2CON.3 ]   CB
+                C4                                          C7
+                C0                                          C3
+                BC      IP.4    IP.5    IP.6    IP.7        BF
+                B8      IP.0    IP.1    IP.2    IP.3        BB
+                B4      P3.4    P3.5    P3.6    P3.7        B7
+                B0      P3.0    P3.1    P3.2    P3.3        B3
+                AC      IE.4    IE.5    EI.6    IE.7        AF
+                A8      IE.0    IE.1    IE.2    IE.3        AB
+                A4      P2.4    P2.5    P2.6    P2.7        A7
+                A0      P2.0    P2.1    P2.2    P2.3        A3
+                9C      SCON.4  SCON.5  SCON.6  SCON.7      9F
+                98      SCON.0  SCON.1  SCON.2  SCON.3      9B
+                94      P1.4    P1.5    P1.6    P1.7        97
+                90      P1.0    P1.1    P1.2    P1.3        93
+                8C      TCON.4  TCON.5  TCON.6  TCON.7      8F
+                88      TCON.0  TCON.1  TCON.2  TCON.3      8B
+                84      P0.4    P0.5    P0.6    P0.7        87
+                80      P0.0    P0.1    P0.2    P0.3        83
+        
+                [...] Indicates Resident in 8052, not 8051
+
+
+        AS8051 ASSEMBLER                                        PAGE K-7
+        8051 INSTRUCTION SET
+
+
+        K.3.9  Predefined Symbols:  Control Bits 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                FC                                          FF
+                F8                                          FB
+                F4                                          F7
+                F0                                          F3
+                EC                                          EF
+                E8                                          EB
+                E4                                          E7
+                E0                                          E3
+                DC                                          DF
+                D8                                          DB
+                D4      RS1     F0      AC      CY          D7
+                D0      P               OV      RS0         D3
+                CC   [  TLCK    RCLK    EXF2    TF2     ]   CF
+                C8   [  CPRL2   CT2     TR2     EXEN2   ]   CB
+                C4                                          C7
+                C0                                          C3
+                BC      PS      PT2                         BF
+                B8      PX0     PT0     PX1     PT1         BB
+                B4                                          B7
+                B0      RXD     TXD     INT0    INT1        B3
+                AC      ES      ET2             EA          AF
+                A8      EX0     ET0     EX1     ET1         AB
+                A4                                          A7
+                A0                                          A3
+                9C      REN     SM2     SM1     SM0         9F
+                98      RI      TI      RB8     TB8         9B
+                94                                          97
+                90                                          93
+                8C      TR0     TF0     TR1     TF1         8F
+                88      IT0     IE0     IT1     IE1         8B
+                84                                          87
+                80                                          83
+        
+                [...] Indicates Resident in 8052, not 8051
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX L
+
+                                AS8085 ASSEMBLER
+
+
+
+
+
+        L.1  8085 REGISTER SET 
+
+        The  following  is  a  list  of  the 8080/8085 registers used by
+        AS8085:  
+
+                a,b,c,d,e,h,l   -       8-bit accumulators
+                m               -       memory through (hl)
+                sp              -       stack pointer
+                psw             -       status word
+
+
+        L.2  8085 INSTRUCTION SET 
+
+
+           The  following tables list all 8080/8085 mnemonics recognized
+        by the AS8085  assembler.   The  following  list  specifies  the
+        format for each addressing mode supported by AS8085:  
+
+                #data           immediate data
+                                byte or word data
+        
+                r,r1,r2         register or register pair
+                                psw,a,b,c,d,e,h,l
+                                bc,de,hl,sp,pc
+        
+                m               memory address using (hl)
+        
+                addr            direct memory addressing
+        
+                label           call or jump label
+
+        The terms data, m, addr, and label may be expressions.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to  the  8080/8085  technical  data  for  valid
+        modes.  
+
+
+        AS8085 ASSEMBLER                                        PAGE L-2
+        8085 INSTRUCTION SET
+
+
+        L.2.1  Inherent Instructions 
+
+                cma             cmc
+                daa             di
+                ei              hlt
+                nop             pchl
+                ral             rar
+                ret             rim
+                rrc             rlc
+                sim             sphl
+                stc             xchg
+                xthl
+
+
+        L.2.2  Register/Memory/Immediate Instructions 
+
+                adc     r       adc     m       aci     #data
+                add     r       add     m       adi     #data
+                ana     r       ana     m       ani     #data
+                cmp     r       cmp     m       cpi     #data
+                ora     r       ora     m       ori     #data
+                sbb     r       sbb     m       sbi     #data
+                sub     r       sub     m       sui     #data
+                xra     r       xra     m       xri     #data
+
+
+        L.2.3  Call and Return Instructions 
+
+                cc      label           rc
+                cm      label           rm
+                cnc     label           rnc
+                cnz     label           rnz
+                cp      label           rp
+                cpe     label           rpe
+                cpo     label           rpo
+                cz      label           rz
+                call    label
+
+
+        L.2.4  Jump Instructions 
+
+                jc      label
+                jm      label
+                jnc     label
+                jnz     label
+                jp      label
+                jpe     label
+                jpo     label
+                jz      label
+                jmp     label
+
+
+        AS8085 ASSEMBLER                                        PAGE L-3
+        8085 INSTRUCTION SET
+
+
+        L.2.5  Input/Output/Reset Instructions 
+
+                in      data
+                out     data
+                rst     data
+
+
+        L.2.6  Move Instructions 
+
+                mov     r1,r2
+                mov     r,m
+                mov     m,r
+        
+                mvi     r,#data
+                mvi     m,#data
+
+
+        L.2.7  Other Instructions 
+
+                dcr     r               dcr     m
+                inr     r               inr     m
+        
+                dad     r               dcx     r
+                inx     r               ldax    r
+                pop     r               push    r
+                stax    r
+        
+                lda     addr            lhld    addr
+                shld    addr            sta     addr
+        
+                lxi     r,#data
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX M
+
+                               AS8XCXXX ASSEMBLER
+
+
+
+
+
+        M.1  ACKNOWLEDGMENTS 
+
+
+           Thanks to Bill McKinnon for his contributions to the AS8XCXXX
+        cross assembler.  
+
+                Bill McKinnon
+                w_mckinnon@conknet.com
+
+           This  assembler  was  derived from the AS8051 cross assembler
+        contributed by John Hartman.  
+
+                John L. Hartman
+                jhartman@compuserve.com
+
+
+        M.2  DS8XCXXX ASSEMBLER DIRECTIVES 
+
+
+           The  AS8XCXXX  assembler  contains  directives to specify the
+        particular SFR (Special Function Registers) to be enabled during
+        the assembly process.  The following directives are supported:  
+
+                .DS8XCXXX               ;80C32 core
+                .DS80C310               ;Dallas Semiconductor
+                .DS80C320               ;Microprocessors
+                .DS80C323
+                .DS80C390
+                .DS83C520
+                .DS83C530
+                .DS83C550
+                .DS87C520
+                .DS87C530
+                .DS87C550
+
+        If  the  microprocessor  selector  directive  is  followed  by a
+
+
+        AS8XCXXX ASSEMBLER                                      PAGE M-2
+        DS8XCXXX ASSEMBLER DIRECTIVES
+
+
+        non-zero argument then the SFR register bit values will also  be
+        defined.  
+
+           If  a microprocessor selector directive is not specified then
+        no SFR or SFR register bit values will be  defined.   This  mode
+        allows  the  SFR  to  be  defined by an external assembly source
+        file.  The file DS8XCXXX.SFR contains the SFR and  SFR  register
+        bit values for all the microprocessor selector directives.  This
+        file may be modified to create a new SFR for other  microproces-
+        sor types.  
+
+           Also, if a microprocessor selector directive is not specified
+        then the  following  address  length  assembler  directives  are
+        accepted:  
+
+                .16bit                  ;16-Bit Addressing
+                .24bit                  ;24-Bit Addressing
+                .32bit                  ;32-Bit Addressing
+
+        These  directives specify the assembler addressing space and ef-
+        fect the output format for the .lst, .sym, and .rel files.  
+
+           The  default  addressing space for defined microprocessors is
+        16-Bit except for the DS80C390 microprocessor which is 24-Bit.  
+
+
+        M.2.1  DS80C390 Addressing Mode Directive 
+
+
+           The  DS80C390  microprocessor  supports 16-Bit and 24-Bit ad-
+        dressing modes.   The  .amode  assembler  directive  provides  a
+        method  to  select  the addressing mode used by the ajmp, acall,
+        ljmp, and lcall instructions.  These four  instructions  support
+        16  and  24 bit addressing modes selected by bits AM0 and AM1 in
+        the ACON register.  The assembler is 'informed'  about  the  ad-
+        dressing mode selected by using the .amode directive:  
+
+                .amode  2       ;mode 2 is 24-bit addressing
+
+        If  a  second  argument  is specified and its value is non-zero,
+        then a three instruction sequence is inserted at the .amode  lo-
+        cation loading the mode bits into the ACON register:  
+
+                .amode  2,1     ;mode 2 is 24-bit addressing, load ACON
+                ;mov    ta,#0xAA
+                ;mov    ta,#0x55
+                ;mov    acon,#amode
+
+
+
+        AS8XCXXX ASSEMBLER                                      PAGE M-3
+        DS8XCXXX ASSEMBLER DIRECTIVES
+
+
+        M.3  DS8XCXXX REGISTER SET 
+
+        The  AS8XCXXX  cross assembler supports the Dallas Semiconductor
+        DS8XCXXX series of 8051-compatible devices.  These  microproces-
+        sors  retain  instruction set and object code compatability with
+        the 8051 microprocessor.  The DS8XCXXX family  is  updated  with
+        several   new  peripherals  while  providing  all  the  standard
+        features of the 80C32 microprocessor.  
+
+           The following is a list of the registers used by AS8XCXXX:  
+
+                a,b             -       8-bit accumulators
+                r0,r1,r2,r3     -       8-bit registers
+                r4,r5,r6,r7
+                dptr            -       data pointer
+                sp              -       stack pointer
+                pc              -       program counter
+                psw             -       status word
+                c               -       carry (bit in status word)
+
+
+        M.4  DS8XCXXX INSTRUCTION SET 
+
+
+           The  following  tables list all DS8XCXXX mnemonics recognized
+        by the AS8XCXXX assembler.  The  following  list  specifies  the
+        format for each addressing mode supported by AS8XCXXX:  
+
+                #data           immediate data
+                                byte or word data
+        
+                r,r1,r2         register r0,r1,r2,r3,r4,r5,r6, or r7
+        
+                @r              indirect on register r0 or r1
+                @dptr           indirect on data pointer
+                @a+dptr         indirect on accumulator
+                                plus data pointer
+                @a+pc           indirect on accumulator
+                                plus program counter
+        
+                addr            direct memory address
+        
+                bitaddr         bit address
+        
+                label           call or jump label
+
+        The terms data, addr, bitaddr, and label may all be expressions. 
+
+           Note  that  not all addressing modes are valid with every in-
+        struction.  Refer to  the  DS8XCXXX  technical  data  for  valid
+        modes.  
+
+
+        AS8XCXXX ASSEMBLER                                      PAGE M-4
+        DS8XCXXX INSTRUCTION SET
+
+
+        M.4.1  Inherent Instructions 
+
+                nop
+
+
+        M.4.2  Move Instructions 
+
+                mov     a,#data         mov     a,addr
+                mov     a,r             mov     a,@r
+        
+                mov     r,#data         mov     r,addr
+                mov     r,a
+        
+                mov     addr,a          mov     addr,#data
+                mov     addr,r          mov     addr,@r
+                mov     addr1,addr2     mov     bitaddr,c
+        
+                mov     @r,#data        mov     @r,addr
+                mov     @r,a
+        
+                mov     c,bitaddr
+                mov     dptr,#data
+        
+                movc    a,@a+dptr       movc    a,@a+pc
+                movx    a,@dptr         movx    a,@r
+                movx    @dptr,a         movx    @r,a
+
+
+        M.4.3  Single Operand Instructions 
+
+                clr     a               clr     c
+                clr     bitaddr
+                cpl     a               cpl     c
+                cpl     bitaddr
+                setb    c               setb    bitaddr
+        
+                da      a               
+                rr      a               rrc     a
+                rl      a               rlc     a
+                swap    a
+        
+                dec     a               dec     r
+                dec     @r
+                inc     a               inc     r
+                inc     dptr            inc     @r
+        
+                div     ab              mul     ab
+        
+                pop     addr            push    addr
+
+
+        AS8XCXXX ASSEMBLER                                      PAGE M-5
+        DS8XCXXX INSTRUCTION SET
+
+
+        M.4.4  Two Operand Instructions 
+
+                add     a,#data         add     a,addr
+                add     a,r             add     a,@r
+                addc    a,#data         addc    a,addr
+                addc    a,r             addc    a,@r
+                subb    a,#data         subb    a,addr
+                subb    a,r             subb    a,@r
+                orl     a,#data         orl     a,addr
+                orl     a,r             orl     a,@r
+                orl     addr,a          orl     addr,#data
+                orl     c,bitaddr       orl     c,/bitaddr
+                anl     a,#data         anl     a,addr
+                anl     a,r             anl     a,@r
+                anl     addr,a          anl     addr,#data
+                anl     c,bitaddr       anl     c,/bitaddr
+                xrl     a,#data         xrl     a,addr
+                xrl     a,r             xrl     a,@r
+                xrl     addr,a          xrl     addr,#data
+                xrl     c,bitaddr       xrl     c,/bitaddr
+                xch     a,addr          xch     a,r
+                xch     a,@r            xchd    a,@r
+
+
+        M.4.5  Call and Return Instructions 
+
+                acall   label           lcall   label
+                ret                     reti
+                in      data
+                out     data
+                rst     data
+
+
+        M.4.6  Jump Instructions 
+
+                ajmp    label
+                cjne    a,#data,label   cjne    a,addr,label
+                cjne    r,#data,label   cjne    @r,#data,label
+                djnz    r,label         djnz    addr,label
+                jbc     bitadr,label
+                jb      bitadr,label    jnb     bitadr,label
+                jc      label           jnc     label
+                jz      label           jnz     label
+                jmp     @a+dptr
+                ljmp    label           sjmp    label
+
+
+        AS8XCXXX ASSEMBLER                                      PAGE M-6
+        DS8XCXXX INSTRUCTION SET
+
+
+        M.5  DS8XCXXX SPECIAL FUNCTION REGISTERS 
+
+
+           The  80C32 core Special Function Registers are selected using
+        the .DS8xCxxx assembler directive.  
+
+
+        M.5.1  SFR Map 
+
+                        --------- 4 Bytes ----------
+                        ----    ----    ----    ----
+                80              SP      DPL     DPH         83
+                84                              PCON        87
+                88      TCON    TMOD    TL0     TL1         8B
+                8C      TH0     TH1                         8F
+                90      P1                                  93
+                94                                          97
+                98      SCON    SBUF                        9B
+                9C                                          9F
+                A0      P2                                  A3
+                A4                                          A7
+                A8      IE      SADDR0                      AB
+                AC                                          AF
+                B0      P3                                  B3
+                B4                                          B7
+                B8      IP      SADEN0                      BB
+                BC                                          BF
+                C0                                          C3
+                C4              STATUS                      C7
+                C8      T2CON   T2MOD   RCAP2L  RCAP2H      CB
+                CC      TL2     TH2                         CF
+                D0      PSW                                 D3
+                D4                                          D7
+                D8                                          DB
+                DC                                          DF
+                E0      ACC                                 E3
+                E4                                          E7
+                E8                                          EB
+                EC                                          EF
+                F0      B                                   F3
+                F4                                          F7
+                F8                                          FB
+                FC                                          FF
+
+
+        AS8XCXXX ASSEMBLER                                      PAGE M-7
+        DS8XCXXX SPECIAL FUNCTION REGISTERS
+
+
+        M.5.2  Bit Addressable Registers:  Generic 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      TCON.0  TCON.1  TCON.2  TCON.3      8B
+                8C      TCON.4  TCON.5  TCON.6  TCON.7      8F
+        P1      90      P1.0    P1.1    P1.2    P1.3        93
+                94      P1.4    P1.5    P1.6    P1.7        97
+        SCON    98      SCON.0  SCON.1  SCON.2  SCON.3      9B
+                9C      SCON.4  SCON.5  SCON.6  SCON.7      9F
+        P2      A0      P2.0    P2.1    P2.2    P2.3        A3
+                A4      P2.4    P2.5    P2.6    P2.7        A7
+        IE      A8      IE.0    IE.1    IE.2    IE.3        AB
+                AC      IE.4    IE.5    EI.6    IE.7        AF
+        P3      B0      P3.0    P3.1    P3.2    P3.3        B3
+                B4      P3.4    P3.5    P3.6    P3.7        B7
+        IP      B8      IP.0    IP.1    IP.2    IP.3        BB
+                BC      IP.4    IP.5    IP.6    IP.7        BF
+                C0                                          C3
+                C4                                          C7
+        T2CON   C8      T2CON.0 T2CON.1 T2CON.2 T2CON.3     CB
+                CC      T2CON.4 T2CON.5 T2CON.6 T2CON.7     CF
+        PSW     D0      PSW.0   PSW.1   PSW.2   PSW.3       D3
+                D4      PSW.4   PSW.5   PSW.6   PSW.7       D7
+                D8                                          DB
+                DC                                          DF
+        ACC     E0      ACC.0   ACC.1   ACC.2   ACC.3       E3
+                E4      ACC.4   ACC.5   ACC.6   ACC.7       E7
+                E8                                          EB
+                EC                                          EF
+        B       F0      B.0     B.1     B.2     B.3         F3
+                F4      B.4     B.5     B.6     B.7         F7
+                F8                                          FB
+                FC                                          FF
+
+
+        AS8XCXXX ASSEMBLER                                      PAGE M-8
+        DS8XCXXX SPECIAL FUNCTION REGISTERS
+
+
+        M.5.3  Bit Addressable Registers:  Specific 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      IT0     IE0     IT1     IE1         8B
+                8C      TR0     TF0     TR1     TF1         8F
+                90                                          93
+                94                                          97
+        SCON    98      RI      TI      RB8     TB8         9B
+                9C      REN     SM2     SM1     SMO         9F
+                A0                                          A3
+                A4                                          A7
+        IE      A8      EX0     ET0     EX1     ET1         AB
+                AC      ES0     ET2             EA          AF
+                B0                                          B3
+                B4                                          B7
+        IP      B8      PX0     PT0     PX1     PT1         BB
+                BC      PS0     PT2                         BF
+                C0                                          C3
+                C4                                          C7
+        T2CON   C8      CPRL2   CT2     TR2     EXEN2       CB
+                CC      TCLK    RCLK    EXF2    TF2         CF
+        PSW     D0      P       FL      OV      RS0         D3
+                D4      RS1     F0      AC      CY          D7
+                D8                                          DB
+                DC                                          DF
+                E0                                          E3
+                E4                                          E7
+                E8                                          EB
+                EC                                          EF
+                F0                                          F3
+                F4                                          F7
+                F8                                          FB
+                FC                                          FF
+        
+                Alternates:
+        
+        SCON    98                                          9B
+                9C                              FE          9F
+        T2CON   C8      CP_RL2  C_T2                        CB
+                CC                                          CF
+
+
+        AS8XCXXX ASSEMBLER                                      PAGE M-9
+        DS8XCXXX SPECIAL FUNCTION REGISTERS
+
+
+        M.5.4  Optional Symbols:  Control Bits 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                        0x80    0x40    0x20    0x10
+                        0x08    0x04    0x02    0x10
+                        ----    ----    ----    ----
+        PCON    0x80    SMOD    SMOD0                       0x10
+                0x08    GF1     GF0     STOP    IDLE        0x01
+        TMOD    0x80    T1GATE  T1C_T   T1M1    T1M0        0x10
+                0x08    T0GATE  T0C_T   T0M1    T0M0        0x01
+        STATUS  0x80            HIP     LIP                 0x10
+                0x08                                        0x01
+        T2MOD   0x80                                        0x10
+                0x08                    T2OE    DCEN        0x01
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-10
+        DS8XCXXX SPECIAL FUNCTION REGISTERS
+
+
+        M.6  DS80C310 SPECIAL FUNCTION REGISTERS 
+
+
+           The  DS80C310  Special  Function Registers are selected using
+        the .DS80C310 assembler directive.  
+
+
+        M.6.1  SFR Map 
+
+                        --------- 4 Bytes ----------
+                        ----    ----    ----    ----
+                80              SP      DPL     DPH         83
+                84      DPL1    DPH1    DPS     PCON        87
+                88      TCON    TMOD    TL0     TL1         8B
+                8C      TH0     TH1     CKCON               8F
+                90      P1      EXIF                        93
+                94                                          97
+                98      SCON    SBUF                        9B
+                9C                                          9F
+                A0      P2                                  A3
+                A4                                          A7
+                A8      IE      SADDR0                      AB
+                AC                                          AF
+                B0      P3                                  B3
+                B4                                          B7
+                B8      IP      SADEN0                      BB
+                BC                                          BF
+                C0                                          C3
+                C4              STATUS                      C7
+                C8      T2CON   T2MOD   RCAP2L  RCAP2H      CB
+                CC      TL2     TH2                         CF
+                D0      PSW                                 D3
+                D4                                          D7
+                D8      WDCON                               DB
+                DC                                          DF
+                E0      ACC                                 E3
+                E4                                          E7
+                E8      EIE                                 EB
+                EC                                          EF
+                F0      B                                   F3
+                F4                                          F7
+                F8      EIP                                 FB
+                FC                                          FF
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-11
+        DS80C310 SPECIAL FUNCTION REGISTERS
+
+
+        M.6.2  Bit Addressable Registers:  Generic 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      TCON.0  TCON.1  TCON.2  TCON.3      8B
+                8C      TCON.4  TCON.5  TCON.6  TCON.7      8F
+        P1      90      P1.0    P1.1    P1.2    P1.3        93
+                94      P1.4    P1.5    P1.6    P1.7        97
+        SCON    98      SCON.0  SCON.1  SCON.2  SCON.3      9B
+                9C      SCON.4  SCON.5  SCON.6  SCON.7      9F
+        P2      A0      P2.0    P2.1    P2.2    P2.3        A3
+                A4      P2.4    P2.5    P2.6    P2.7        A7
+        IE      A8      IE.0    IE.1    IE.2    IE.3        AB
+                AC      IE.4    IE.5    EI.6    IE.7        AF
+        P3      B0      P3.0    P3.1    P3.2    P3.3        B3
+                B4      P3.4    P3.5    P3.6    P3.7        B7
+        IP      B8      IP.0    IP.1    IP.2    IP.3        BB
+                BC      IP.4    IP.5    IP.6    IP.7        BF
+                C0                                          C3
+                C4                                          C7
+        T2CON   C8      T2CON.0 T2CON.1 T2CON.2 T2CON.3     CB
+                CC      T2CON.4 T2CON.5 T2CON.6 T2CON.7     CF
+        PSW     D0      PSW.0   PSW.1   PSW.2   PSW.3       D3
+                D4      PSW.4   PSW.5   PSW.6   PSW.7       D7
+        WDCON   D8      WDCON.0 WDCON.1 WDCON.2 WDCON.3     DB
+                DC      WDCON.4 WDCON.5 WDCON.6 WDCON.7     DF
+        ACC     E0      ACC.0   ACC.1   ACC.2   ACC.3       E3
+                E4      ACC.4   ACC.5   ACC.6   ACC.7       E7
+        EIE     E8      EIE.0   EIE.1   EIE.2   EIE.3       EB
+                EC      EIE.4   EIE.5   EIE.6   EIE.7       EF
+        B       F0      B.0     B.1     B.2     B.3         F3
+                F4      B.4     B.5     B.6     B.7         F7
+        EIP     F8      EIP.0   EIP.1   EIP.2   EIP.3       FB
+                FC      EIP.4   EIP.5   EIP.6   EIP.7       FF
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-12
+        DS80C310 SPECIAL FUNCTION REGISTERS
+
+
+        M.6.3  Bit Addressable Registers:  Specific 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      IT0     IE0     IT1     IE1         8B
+                8C      TR0     TF0     TR1     TF1         8F
+                90                                          93
+                94                                          97
+        SCON    98      RI      TI      RB8     TB8         9B
+                9C      REN     SM2     SM1     SMO         9F
+                A0                                          A3
+                A4                                          A7
+        IE      A8      EX0     ET0     EX1     ET1         AB
+                AC      ES0     ET2             EA          AF
+                B0                                          B3
+                B4                                          B7
+        IP      B8      PX0     PT0     PX1     PT1         BB
+                BC      PS0     PT2                         BF
+                C0                                          C3
+                C4                                          C7
+        T2CON   C8      CPRL2   CT2     TR2     EXEN2       CB
+                CC      TCLK    RCLK    EXF2    TF2         CF
+        PSW     D0      P       FL      OV      RS0         D3
+                D4      RS1     F0      AC      CY          D7
+        WDCON   D8                                          DB
+                DC                      POR                 DF
+                E0                                          E3
+                E4                                          E7
+        EIE     E8      EX2     EX3     EX4     EX5         EB
+                EC                                          EF
+                F0                                          F3
+                F4                                          F7
+        EIP     F8      PX2     PX3     PX4     PX5         FB
+                FC                                          FF
+        
+                Alternates:
+        
+        SCON    98                                          9B
+                9C                              FE          9F
+        T2CON   C8      CP_RL2  C_T2                        CB
+                CC                                          CF
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-13
+        DS80C310 SPECIAL FUNCTION REGISTERS
+
+
+        M.6.4  Optional Symbols:  Control Bits 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                        0x80    0x40    0x20    0x10
+                        0x08    0x04    0x02    0x10
+                        ----    ----    ----    ----
+        DPS     0x80                                        0x10
+                0x08                            SEL         0x01
+        PCON    0x80    SMOD    SMOD0                       0x10
+                0x08    GF1     GF0     STOP    IDLE        0x01
+        TMOD    0x80    T1GATE  T1C_T   T1M1    T1M0        0x10
+                0x08    T0GATE  T0C_T   T0M1    T0M0        0x01
+        CKCON   0x80                    T2M     T1M         0x10
+                0x08    T0M     MD2     MD1     MD0         0x01
+        EXIF    0x80    IE5     IE4     IE3     IE2         0x10
+                0x08                                        0x01
+        STATUS  0x80            HIP     LIP                 0x10
+                0x08                                        0x01
+        T2MOD   0x80                                        0x10
+                0x08                    T2OE    DCEN        0x01
+        
+                Alternates:
+        
+        PCON    0x80    SMOD_0                              0x10
+                0x08                                        0x01
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-14
+        DS80C310 SPECIAL FUNCTION REGISTERS
+
+
+        M.7  DS80C320/DS80C323 SPECIAL FUNCTION REGISTERS 
+
+
+           The DS80C320/DS80C323 Special Function Registers are selected
+        using the .DS80C320 or DS80C323 assembler directives.  
+
+
+        M.7.1  SFR Map 
+
+                        --------- 4 Bytes ----------
+                        ----    ----    ----    ----
+                80              SP      DPL     DPH         83
+                84      DPL1    DPH1    DPS     PCON        87
+                88      TCON    TMOD    TL0     TL1         8B
+                8C      TH0     TH1     CKCON               8F
+                90      P1      EXIF                        93
+                94                                          97
+                98      SCON0   SBUF0                       9B
+                9C                                          9F
+                A0      P2                                  A3
+                A4                                          A7
+                A8      IE      SADDR0                      AB
+                AC                                          AF
+                B0      P3                                  B3
+                B4                                          B7
+                B8      IP      SADEN0                      BB
+                BC                                          BF
+                C0      SCON1   SBUF1                       C3
+                C4              STATUS          TA          C7
+                C8      T2CON   T2MOD   RCAP2L  RCAP2H      CB
+                CC      TL2     TH2                         CF
+                D0      PSW                                 D3
+                D4                                          D7
+                D8      WDCON                               DB
+                DC                                          DF
+                E0      ACC                                 E3
+                E4                                          E7
+                E8      EIE                                 EB
+                EC                                          EF
+                F0      B                                   F3
+                F4                                          F7
+                F8      EIP                                 FB
+                FC                                          FF
+        
+                Alternates:
+        
+                98      SCON    SBUF                        9B
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-15
+        DS80C320/DS80C323 SPECIAL FUNCTION REGISTERS
+
+
+        M.7.2  Bit Addressable Registers:  Generic 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      TCON.0  TCON.1  TCON.2  TCON.3      8B
+                8C      TCON.4  TCON.5  TCON.6  TCON.7      8F
+        P1      90      P1.0    P1.1    P1.2    P1.3        93
+                94      P1.4    P1.5    P1.6    P1.7        97
+        SCON0   98      SCON0.0 SCON0.1 SCON0.2 SCON0.3     9B
+                9C      SCON0.4 SCON0.5 SCON0.6 SCON0.7     9F
+        P2      A0      P2.0    P2.1    P2.2    P2.3        A3
+                A4      P2.4    P2.5    P2.6    P2.7        A7
+        IE      A8      IE.0    IE.1    IE.2    IE.3        AB
+                AC      IE.4    IE.5    EI.6    IE.7        AF
+        P3      B0      P3.0    P3.1    P3.2    P3.3        B3
+                B4      P3.4    P3.5    P3.6    P3.7        B7
+        IP      B8      IP.0    IP.1    IP.2    IP.3        BB
+                BC      IP.4    IP.5    IP.6    IP.7        BF
+        SCON1   C0      SCON1.0 SCON1.1 SCON1.2 SCON1.3     C3
+                C4      SCON1.4 SCON1.5 SCON1.6 SCON1.7     C7
+        T2CON   C8      T2CON.0 T2CON.1 T2CON.2 T2CON.3     CB
+                CC      T2CON.4 T2CON.5 T2CON.6 T2CON.7     CF
+        PSW     D0      PSW.0   PSW.1   PSW.2   PSW.3       D3
+                D4      PSW.4   PSW.5   PSW.6   PSW.7       D7
+        WDCON   D8      WDCON.0 WDCON.1 WDCON.2 WDCON.3     DB
+                DC      WDCON.4 WDCON.5 WDCON.6 WDCON.7     DF
+        ACC     E0      ACC.0   ACC.1   ACC.2   ACC.3       E3
+                E4      ACC.4   ACC.5   ACC.6   ACC.7       E7
+        EIE     E8      EIE.0   EIE.1   EIE.2   EIE.3       EB
+                EC      EIE.4   EIE.5   EIE.6   EIE.7       EF
+        B       F0      B.0     B.1     B.2     B.3         F3
+                F4      B.4     B.5     B.6     B.7         F7
+        EIP     F8      EIP.0   EIP.1   EIP.2   EIP.3       FB
+                FC      EIP.4   EIP.5   EIP.6   EIP.7       FF
+        
+                        Alternates:
+        
+        SCON    98      SCON.0  SCON.1  SCON.2  SCON.3      9B
+                9C      SCON.4  SCON.5  SCON.6  SCON.7      9F
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-16
+        DS80C320/DS80C323 SPECIAL FUNCTION REGISTERS
+
+
+        M.7.3  Bit Addressable Registers:  Specific 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      IT0     IE0     IT1     IE1         8B
+                8C      TR0     TF0     TR1     TF1         8F
+                90                                          93
+                94                                          97
+        SCON0   98      RI_0    TI_0    RB8_0   TB8_0       9B
+                9C      REN_0   SM2_0   SM1_0   SMO_0       9F
+                A0                                          A3
+                A4                                          A7
+        IE      A8      EX0     ET0     EX1     ET1         AB
+                AC      ES0     ET2             EA          AF
+                B0                                          B3
+                B4                                          B7
+        IP      B8      PX0     PT0     PX1     PT1         BB
+                BC      PS0     PT2                         BF
+        SCON1   C0      RI_1    TI_1    RB8_1   TB8_1       C3
+                C4      REN_1   SM2_1   SM1_1   SMO_1       C7
+        T2CON   C8      CPRL2   CT2     TR2     EXEN2       CB
+                CC      TCLK    RCLK    EXF2    TF2         CF
+        PSW     D0      P       FL      OV      RS0         D3
+                D4      RS1     F0      AC      CY          D7
+        WDCON   D8      RWT     EWT     WTRF    WDIF        DB
+                DC      PFI     EPFI    POR     SMOD_1      DF
+                E0                                          E3
+                E4                                          E7
+        EIE     E8      EX2     EX3     EX4     EX5         EB
+                EC      EWDI                                EF
+                F0                                          F3
+                F4                                          F7
+        EIP     F8      PX2     PX3     PX4     PX5         FB
+                FC      PWDI                                FF
+        
+                Alternates:
+        
+        SCON    98      RI      TI      RB8     TB8         9B
+                9C      REN     SM2     SM1     SMO         9F
+        SCON    98                                          9B
+                9C                              FE          9F
+        SCON0   98                                          9B
+                9C                              FE_0        9F
+        SCON1   C0                                          C3
+                C4                              FE_1        C7
+        T2CON   C8      CP_RL2  C_T2                        CB
+                CC                                          CF
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-17
+        DS80C320/DS80C323 SPECIAL FUNCTION REGISTERS
+
+
+        M.7.4  Optional Symbols:  Control Bits 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                        0x80    0x40    0x20    0x10
+                        0x08    0x04    0x02    0x10
+                        ----    ----    ----    ----
+        DPS     0x80                                        0x10
+                0x08                            SEL         0x01
+        PCON    0x80    SMOD_0  SMOD0                       0x10
+                0x08    GF1     GF0     STOP    IDLE        0x01
+        TMOD    0x80    T1GATE  T1C_T   T1M1    T1M0        0x10
+                0x08    T0GATE  T0C_T   T0M1    T0M0        0x01
+        CKCON   0x80    WD1     WD0     T2M     T1M         0x10
+                0x08    T0M     MD2     MD1     MD0         0x01
+        EXIF    0x80    IE5     IE4     IE3     IE2         0x10
+                0x08            RGMD    RGSL    BGS         0x01
+        STATUS  0x80    PIP     HIP     LIP                 0x10
+                0x08                                        0x01
+        T2MOD   0x80                                        0x10
+                0x08                    T2OE    DCEN        0x01
+        
+                Alternates:
+        
+        PCON    0x80    SMOD                                0x10
+                0x08                                        0x01
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-18
+        DS80C320/DS80C323 SPECIAL FUNCTION REGISTERS
+
+
+        M.8  DS80C390 SPECIAL FUNCTION REGISTERS 
+
+
+           The  DS80C390  Special  Function Registers are selected using
+        the .DS80C390 assembler directive.  
+
+
+        M.8.1  SFR Map 
+
+                        --------- 4 Bytes ----------
+                        ----    ----    ----    ----
+                80      P4      SP      DPL     DPH         83
+                84      DPL1    DPH1    DPS     PCON        87
+                88      TCON    TMOD    TL0     TL1         8B
+                8C      TH0     TH1     CKCON               8F
+                90      P1      EXIF    P4CNT   DPX         93
+                94              DPX1    C0RMS0  C0RMS1      97
+                98      SCON0   SBUF0           ESP         9B
+                9C      AP      ACON    C0TMA0  C0TMA1      9F
+                A0      P2      P5      P5CNT   C0C         A3
+                A4      C0S     C0IR    C0TE    C0RE        A7
+                A8      IE      SADDR0  SADDR1  C0M1C       AB
+                AC      C0M2C   C0M3C   C0M4C   C0M5C       AF
+                B0      P3                      C0M6C       B3
+                B4      C0M7C   C0M8C   C0M9C   C0M10C      B7
+                B8      IP      SADEN0  SADEN1  C0M11C      BB
+                BC      C0M12C  C0M13C  C0M14C  C0M15C      BF
+                C0      SCON1   SBUF1                       C3
+                C4      PMR     STATUS  MCON    TA          C7
+                C8      T2CON   T2MOD   RCAP2L  RCAP2H      CB
+                CC      TL2     TH2     COR                 CF
+                D0      PSW     MCNT0   MCNT1   MA          D3
+                D4      MB      MC      C1RMS0  C1RMS1      D7
+                D8      WDCON                               DB
+                DC                      C1TMA0  C1TMA1      DF
+                E0      ACC                     C1C         E3
+                E4      C1S     C1IR    C1TE    C1RE        E7
+                E8      EIE             MXAX    C1M1C       EB
+                EC      C1M2C   C1M3C   C1M4C   C1M5C       EF
+                F0      B                       C1M6C       F3
+                F4      C1M7C   C1M8C   C1M9C   C1M10C      F7
+                F8      EIP                     C1M11C      FB
+                FC      C1M12C  C1M13C  C1M14C  C1M15C      FF
+        
+                Alternates:
+        
+                98      SCON    SBUF                        9B
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-19
+        DS80C390 SPECIAL FUNCTION REGISTERS
+
+
+        M.8.2  Bit Addressable Registers:  Generic 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+        P4      80      P4.0    P4.1    P4.2    P4.3        83
+                84      P4.4    P4.5    P4.6    P4.7        87
+        TCON    88      TCON.0  TCON.1  TCON.2  TCON.3      8B
+                8C      TCON.4  TCON.5  TCON.6  TCON.7      8F
+        P1      90      P1.0    P1.1    P1.2    P1.3        93
+                94      P1.4    P1.5    P1.6    P1.7        97
+        SCON0   98      SCON0.0 SCON0.1 SCON0.2 SCON0.3     9B
+                9C      SCON0.4 SCON0.5 SCON0.6 SCON0.7     9F
+        P2      A0      P2.0    P2.1    P2.2    P2.3        A3
+                A4      P2.4    P2.5    P2.6    P2.7        A7
+        IE      A8      IE.0    IE.1    IE.2    IE.3        AB
+                AC      IE.4    IE.5    EI.6    IE.7        AF
+        P3      B0      P3.0    P3.1    P3.2    P3.3        B3
+                B4      P3.4    P3.5    P3.6    P3.7        B7
+        IP      B8      IP.0    IP.1    IP.2    IP.3        BB
+                BC      IP.4    IP.5    IP.6    IP.7        BF
+        SCON1   C0      SCON1.0 SCON1.1 SCON1.2 SCON1.3     C3
+                C4      SCON1.4 SCON1.5 SCON1.6 SCON1.7     C7
+        T2CON   C8      T2CON.0 T2CON.1 T2CON.2 T2CON.3     CB
+                CC      T2CON.4 T2CON.5 T2CON.6 T2CON.7     CF
+        PSW     D0      PSW.0   PSW.1   PSW.2   PSW.3       D3
+                D4      PSW.4   PSW.5   PSW.6   PSW.7       D7
+        WDCON   D8      WDCON.0 WDCON.1 WDCON.2 WDCON.3     DB
+                DC      WDCON.4 WDCON.5 WDCON.6 WDCON.7     DF
+        ACC     E0      ACC.0   ACC.1   ACC.2   ACC.3       E3
+                E4      ACC.4   ACC.5   ACC.6   ACC.7       E7
+        EIE     E8      EIE.0   EIE.1   EIE.2   EIE.3       EB
+                EC      EIE.4   EIE.5   EIE.6   EIE.7       EF
+        B       F0      B.0     B.1     B.2     B.3         F3
+                F4      B.4     B.5     B.6     B.7         F7
+        EIP     F8      EIP.0   EIP.1   EIP.2   EIP.3       FB
+                FC      EIP.4   EIP.5   EIP.6   EIP.7       FF
+        
+                        Alternates:
+        
+        SCON    98      SCON.0  SCON.1  SCON.2  SCON.3      9B
+                9C      SCON.4  SCON.5  SCON.6  SCON.7      9F
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-20
+        DS80C390 SPECIAL FUNCTION REGISTERS
+
+
+        M.8.3  Bit Addressable Registers:  Specific 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      IT0     IE0     IT1     IE1         8B
+                8C      TR0     TF0     TR1     TF1         8F
+        P1      90      T2      T2EX    RXD1    TXD1        93
+                94      INT2    INT3    INT4    INT5        97
+        SCON0   98      RI_0    TI_0    RB8_0   TB8_0       9B
+                9C      REN_0   SM2_0   SM1_0   SMO_0       9F
+                A0                                          A3
+                A4                                          A7
+        IE      A8      EX0     ET0     EX1     ET1         AB
+                AC      ES0     ET2     ES1     EA          AF
+        P3      B0      RXD0    TXD0    INT0    INT1        B3
+                B4      T0      T1                          B7
+        IP      B8      PX0     PT0     PX1     PT1         BB
+                BC      PS0     PT2     PS1                 BF
+        SCON1   C0      RI_1    TI_1    RB8_1   TB8_1       C3
+                C4      REN_1   SM2_1   SM1_1   SMO_1       C7
+        T2CON   C8      CPRL2   CT2     TR2     EXEN2       CB
+                CC      TCLK    RCLK    EXF2    TF2         CF
+        PSW     D0      P       FL      OV      RS0         D3
+                D4      RS1     F0      AC      CY          D7
+        WDCON   D8      RWT     EWT     WTRF    WDIF        DB
+                DC      PFI     EPFI    POR     SMOD_1      DF
+                E0                                          E3
+                E4                                          E7
+        EIE     E8      EX2     EX3     EX4     EX5         EB
+                EC      EWDI    C1IE    C0IE    CANBIE      EF
+                F0                                          F3
+                F4                                          F7
+        EIP     F8      PX2     PX3     PX4     PX5         FB
+                FC      PWDI    C1IP    C0IP    CANBIP      FF
+        
+                Alternates:
+        
+        SCON    98      RI      TI      RB8     TB8         9B
+                9C      REN     SM2     SM1     SMO         9F
+        SCON    98                                          9B
+                9C                              FE          9F
+        SCON0   98                                          9B
+                9C                              FE_0        9F
+        SCON1   C0                                          C3
+                C4                              FE_1        C7
+        T2CON   C8      CP_RL2  C_T2                        CB
+                CC                                          CF
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-21
+        DS80C390 SPECIAL FUNCTION REGISTERS
+
+
+        M.8.4  Optional Symbols:  Control Bits 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                        0x80    0x40    0x20    0x10
+                        0x08    0x04    0x02    0x10
+                        ----    ----    ----    ----
+        DPS     0x80    ID1     ID0     TSL                 0x10
+                0x08                            SEL         0x01
+        PCON    0x80    SMOD_0  SMOD0   OFDF    OFDE        0x10
+                0x08    GF1     GF0     STOP    IDLE        0x01
+        TMOD    0x80    T1GATE  T1C_T   T1M1    T1M0        0x10
+                0x08    T0GATE  T0C_T   T0M1    T0M0        0x01
+        CKCON   0x80    WD1     WD0     T2M     T1M         0x10
+                0x08    T0M     MD2     MD1     MD0         0x01
+        EXIF    0x80    IE5     IE4     IE3     IE2         0x10
+                0x08    CKRY    RGMD    RGSL    BGS         0x01
+        P4CNT   0x80            SBCAN                       0x10
+                0x08                                        0x01
+        ESP     0x80                                        0x10
+                0x08                    ESP.1   ESP.0       0x01
+        ACON    0x80                                        0x10
+                0x08            SA      AM1     AM0         0x01
+        P5      0x80    P5.7    P5.6    P5.5    P5.4        0x10
+                0x08    P5.3    P5.2    P5.1    P5.0        0x01
+        P5CNT   0x80    CAN1BA  CAN0BA  SP1EC   C1_IO       0x10
+                0x08    C0_IO   P5CNT.2 P5CNT.1 P5CNT.0     0x01
+        CxC     0x80    ERIE    STIE    PDE     SIESTA      0x10
+                0x08    CRST    AUTOB   ERCS    SWINT       0x01
+        CxS     0x80    BSS   EC96_128  WKS     RXS         0x10
+                0x08    TXS     ER2     ER1     ER0         0x01
+        CxIR    0x80    INTIN7  INTIN6  INTIN5  INTIN4      0x10
+                0x08    INTIN3  INTIN2  INTIN1  INTIN0      0x01
+        CxCxxC  0x80    MSRDY   ET1     ER1     INTRQ       0x10
+                0x08    EXTRQ   MTRQ    ROW_TIH DTUP        0x01
+        PMR     0x80    CD1     CD0     SWB     CTM         0x10
+                0x08    4X_2X   ALEOFF                      0x01
+        STATUS  0x80    PIP     HIP     LIP                 0x10
+                0x08    SPTA1   SPRA1   SPTA0   SPRA0       0x01
+        MCON    0x80    IDM1    IDM0    CMA                 0x10
+                0x08    PDCE3   PDCE2   PDCE1   PDCE0       0x01
+        T2MOD   0x80                            D13T1       0x10
+                0x08    D13T2           T2OE    DCEN        0x01
+        COR     0x80    IRDACK  C1BPR7  C1BPR6  C0BPR7      0x10
+                0x08    C0BPR6  COD1    COD0    CLKOE       0x01
+        MCNT0   0x80    _LSHIFT CSE     SCB     MAS4        0x10
+                0x08    MAS3    MAS2    MAS1    MAS0        0x01
+        MCNT1   0x80    MST     MOF             CLM         0x10
+                0x08                                        0x01
+        
+                Alternates:
+        
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-22
+        DS80C390 SPECIAL FUNCTION REGISTERS
+
+
+        PCON    0x80    SMOD                                0x10
+                0x08                                        0x01
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-23
+        DS80C390 SPECIAL FUNCTION REGISTERS
+
+
+        M.9  DS83C520/DS87C520 SPECIAL FUNCTION REGISTERS 
+
+
+           The DS83C520/DS87C520 Special Function Registers are selected
+        using the .DS83C520 or DS87C520 assembler directives.  
+
+
+        M.9.1  SFR Map 
+
+                        --------- 4 Bytes ----------
+                        ----    ----    ----    ----
+                80      P0      SP      DPL     DPH         83
+                84      DPL1    DPH1    DPS     PCON        87
+                88      TCON    TMOD    TL0     TL1         8B
+                8C      TH0     TH1     CKCON               8F
+                90      PORT1   EXIF                        93
+                94                                          97
+                98      SCON0   SBUF0                       9B
+                9C                                          9F
+                A0      P2                                  A3
+                A4                                          A7
+                A8      IE      SADDR0  SADDR1              AB
+                AC                                          AF
+                B0      P3                                  B3
+                B4                                          B7
+                B8      IP      SADEN0  SADEN1              BB
+                BC                                          BF
+                C0      SCON1   SBUF1   ROMSIZE             C3
+                C4      PMR     STATUS          TA          C7
+                C8      T2CON   T2MOD   RCAP2L  RCAP2H      CB
+                CC      TL2     TH2                         CF
+                D0      PSW                                 D3
+                D4                                          D7
+                D8      WDCON                               DB
+                DC                                          DF
+                E0      ACC                                 E3
+                E4                                          E7
+                E8      EIE                                 EB
+                EC                                          EF
+                F0      B                                   F3
+                F4                                          F7
+                F8      EIP                                 FB
+                FC                                          FF
+        
+                Alternates:
+        
+                98      SCON    SBUF                        9B
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-24
+        DS83C520/DS87C520 SPECIAL FUNCTION REGISTERS
+
+
+        M.9.2  Bit Addressable Registers:  Generic 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+        P0      80      P0.7    P0.6    P0.5    P0.4        83
+                84      P0.3    P0.2    P0.1    P0.0        87
+        TCON    88      TCON.0  TCON.1  TCON.2  TCON.3      8B
+                8C      TCON.4  TCON.5  TCON.6  TCON.7      8F
+        PORT1   90      P1.0    P1.1    P1.2    P1.3        93
+                94      P1.4    P1.5    P1.6    P1.7        97
+        SCON0   98      SCON0.0 SCON0.1 SCON0.2 SCON0.3     9B
+                9C      SCON0.4 SCON0.5 SCON0.6 SCON0.7     9F
+        P2      A0      P2.0    P2.1    P2.2    P2.3        A3
+                A4      P2.4    P2.5    P2.6    P2.7        A7
+        IE      A8      IE.0    IE.1    IE.2    IE.3        AB
+                AC      IE.4    IE.5    EI.6    IE.7        AF
+        P3      B0      P3.0    P3.1    P3.2    P3.3        B3
+                B4      P3.4    P3.5    P3.6    P3.7        B7
+        IP      B8      IP.0    IP.1    IP.2    IP.3        BB
+                BC      IP.4    IP.5    IP.6    IP.7        BF
+        SCON1   C0      SCON1.0 SCON1.1 SCON1.2 SCON1.3     C3
+                C4      SCON1.4 SCON1.5 SCON1.6 SCON1.7     C7
+        T2CON   C8      T2CON.0 T2CON.1 T2CON.2 T2CON.3     CB
+                CC      T2CON.4 T2CON.5 T2CON.6 T2CON.7     CF
+        PSW     D0      PSW.0   PSW.1   PSW.2   PSW.3       D3
+                D4      PSW.4   PSW.5   PSW.6   PSW.7       D7
+        WDCON   D8      WDCON.0 WDCON.1 WDCON.2 WDCON.3     DB
+                DC      WDCON.4 WDCON.5 WDCON.6 WDCON.7     DF
+        ACC     E0      ACC.0   ACC.1   ACC.2   ACC.3       E3
+                E4      ACC.4   ACC.5   ACC.6   ACC.7       E7
+        EIE     E8      EIE.0   EIE.1   EIE.2   EIE.3       EB
+                EC      EIE.4   EIE.5   EIE.6   EIE.7       EF
+        B       F0      B.0     B.1     B.2     B.3         F3
+                F4      B.4     B.5     B.6     B.7         F7
+        EIP     F8      EIP.0   EIP.1   EIP.2   EIP.3       FB
+                FC      EIP.4   EIP.5   EIP.6   EIP.7       FF
+        
+                        Alternates:
+        
+        PORT1   90      PORT1.0 PORT1.1 PORT1.2 PORT1.3     93
+                94      PORT1.4 PORT1.5 PORT1.6 PORT1.7     97
+        SCON    98      SCON.0  SCON.1  SCON.2  SCON.3      9B
+                9C      SCON.4  SCON.5  SCON.6  SCON.7      9F
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-25
+        DS83C520/DS87C520 SPECIAL FUNCTION REGISTERS
+
+
+        M.9.3  Bit Addressable Registers:  Specific 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      IT0     IE0     IT1     IE1         8B
+                8C      TR0     TF0     TR1     TF1         8F
+                90                                          93
+                94                                          97
+        SCON0   98      RI_0    TI_0    RB8_0   TB8_0       9B
+                9C      REN_0   SM2_0   SM1_0   SMO_0       9F
+                A0                                          A3
+                A4                                          A7
+        IE      A8      EX0     ET0     EX1     ET1         AB
+                AC      ES0     ET2     ES1     EA          AF
+                B0                                          B3
+                B4                                          B7
+        IP      B8      PX0     PT0     PX1     PT1         BB
+                BC      PS0     PT2     PS1                 BF
+        SCON1   C0      RI_1    TI_1    RB8_1   TB8_1       C3
+                C4      REN_1   SM2_1   SM1_1   SMO_1       C7
+        T2CON   C8      CPRL2   CT2     TR2     EXEN2       CB
+                CC      TCLK    RCLK    EXF2    TF2         CF
+        PSW     D0      P       FL      OV      RS0         D3
+                D4      RS1     F0      AC      CY          D7
+        WDCON   D8      RWT     EWT     WTRF    WDIF        DB
+                DC      PFI     EPFI    POR     SMOD_1      DF
+                E0                                          E3
+                E4                                          E7
+        EIE     E8      EX2     EX3     EX4     EX5         EB
+                EC      EWDI                                EF
+                F0                                          F3
+                F4                                          F7
+        EIP     F8      PX2     PX3     PX4     PX5         FB
+                FC      PWDI                                FF
+        
+                Alternates:
+        
+        SCON    98      RI      TI      RB8     TB8         9B
+                9C      REN     SM2     SM1     SMO         9F
+        SCON    98                                          9B
+                9C                              FE          9F
+        SCON0   98                                          9B
+                9C                              FE_0        9F
+        SCON1   C0                                          C3
+                C4                              FE_1        C7
+        T2CON   C8      CP_RL2  C_T2                        CB
+                CC                                          CF
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-26
+        DS83C520/DS87C520 SPECIAL FUNCTION REGISTERS
+
+
+        M.9.4  Optional Symbols:  Control Bits 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                        0x80    0x40    0x20    0x10
+                        0x08    0x04    0x02    0x10
+                        ----    ----    ----    ----
+        DPS     0x80                                        0x10
+                0x08                            SEL         0x01
+        PCON    0x80    SMOD_0  SMOD0                       0x10
+                0x08    GF1     GF0     STOP    IDLE        0x01
+        TMOD    0x80    T1GATE  T1C_T   T1M1    T1M0        0x10
+                0x08    T0GATE  T0C_T   T0M1    T0M0        0x01
+        CKCON   0x80    WD1     WD0     T2M     T1M         0x10
+                0x08    T0M     MD2     MD1     MD0         0x01
+        EXIF    0x80    IE5     IE4     IE3     IE          0x10
+                0x08    XT_RG   RGMD    RGSL    BGS         0x01
+        SBUF1   0x80    SB7     SB6     SB5     SB4         0x10
+                0x08    SB3     SB2     SB1     SB0         0x01
+        ROMSIZE 0x80                                        0x10
+                0x08            RMS2    RMS1    RMS0        0x01
+        PMR     0x80    CD1     CD0     SWB                 0x10
+                0x08    XTOFF   ALEOFF  DME1    DME0        0x01
+        STATUS  0x80    PIP     HIP     LIP     XTUP        0x10
+                0x08    SPTA1   SPRA1   SPTA0   SPRA0       0x01
+        T2MOD   0x80                                        0x10
+                0x08                    T2OE    DCEN        0x01
+        
+                Alternates:
+        
+        PCON    0x80    SMOD                                0x10
+                0x08                                        0x01
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-27
+        DS83C520/DS87C520 SPECIAL FUNCTION REGISTERS
+
+
+        M.10  DS83C530/DS87C530 SPECIAL FUNCTION REGISTERS 
+
+
+           The DS83C530/DS87C530 Special Function Registers are selected
+        using the .DS83C530 or DS87C530 assembler directives.  
+
+
+        M.10.1  SFR Map 
+
+                        --------- 4 Bytes ----------
+                        ----    ----    ----    ----
+                80      P0      SP      DPL     DPH         83
+                84      DPL1    DPH1    DPS     PCON        87
+                88      TCON    TMOD    TL0     TL1         8B
+                8C      TH0     TH1     CKCON               8F
+                90      P1      EXIF                        93
+                94                      TRIM                97
+                98      SCON0   SBUF0                       9B
+                9C                                          9F
+                A0      P2                                  A3
+                A4                                          A7
+                A8      IE      SADDR0  SADDR1              AB
+                AC                                          AF
+                B0      P3                                  B3
+                B4                                          B7
+                B8      IP      SADEN0  SADEN1              BB
+                BC                                          BF
+                C0      SCON1   SBUF1   ROMSIZE             C3
+                C4      PMR     STATUS          TA          C7
+                C8      T2CON   T2MOD   RCAP2L  RCAP2H      CB
+                CC      TL2     TH2                         CF
+                D0      PSW                                 D3
+                D4                                          D7
+                D8      WDCON                               DB
+                DC                                          DF
+                E0      ACC                                 E3
+                E4                                          E7
+                E8      EIE                                 EB
+                EC                                          EF
+                F0      B               RTASS   RTAS        F3
+                F4      RTAM    RTAH                        F7
+                F8      EIP     RTCC    RTCSS   RTCS        FB
+                FC      RTCM    RTCH    RTCD0   RTCD1       FF
+        
+                Alternates:
+        
+                98      SCON    SBUF                        9B
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-28
+        DS83C530/DS87C530 SPECIAL FUNCTION REGISTERS
+
+
+        M.10.2  Bit Addressable Registers:  Generic 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+        P0      80      P0.7    P0.6    P0.5    P0.4        83
+                84      P0.3    P0.2    P0.1    P0.0        87
+        TCON    88      TCON.0  TCON.1  TCON.2  TCON.3      8B
+                8C      TCON.4  TCON.5  TCON.6  TCON.7      8F
+        P1      90      P1.0    P1.1    P1.2    P1.3        93
+                94      P1.4    P1.5    P1.6    P1.7        97
+        SCON0   98      SCON0.0 SCON0.1 SCON0.2 SCON0.3     9B
+                9C      SCON0.4 SCON0.5 SCON0.6 SCON0.7     9F
+        P2      A0      P2.0    P2.1    P2.2    P2.3        A3
+                A4      P2.4    P2.5    P2.6    P2.7        A7
+        IE      A8      IE.0    IE.1    IE.2    IE.3        AB
+                AC      IE.4    IE.5    EI.6    IE.7        AF
+        P3      B0      P3.0    P3.1    P3.2    P3.3        B3
+                B4      P3.4    P3.5    P3.6    P3.7        B7
+        IP      B8      IP.0    IP.1    IP.2    IP.3        BB
+                BC      IP.4    IP.5    IP.6    IP.7        BF
+        SCON1   C0      SCON1.0 SCON1.1 SCON1.2 SCON1.3     C3
+                C4      SCON1.4 SCON1.5 SCON1.6 SCON1.7     C7
+        T2CON   C8      T2CON.0 T2CON.1 T2CON.2 T2CON.3     CB
+                CC      T2CON.4 T2CON.5 T2CON.6 T2CON.7     CF
+        PSW     D0      PSW.0   PSW.1   PSW.2   PSW.3       D3
+                D4      PSW.4   PSW.5   PSW.6   PSW.7       D7
+        WDCON   D8      WDCON.0 WDCON.1 WDCON.2 WDCON.3     DB
+                DC      WDCON.4 WDCON.5 WDCON.6 WDCON.7     DF
+        ACC     E0      ACC.0   ACC.1   ACC.2   ACC.3       E3
+                E4      ACC.4   ACC.5   ACC.6   ACC.7       E7
+        EIE     E8      EIE.0   EIE.1   EIE.2   EIE.3       EB
+                EC      EIE.4   EIE.5   EIE.6   EIE.7       EF
+        B       F0      B.0     B.1     B.2     B.3         F3
+                F4      B.4     B.5     B.6     B.7         F7
+        EIP     F8      EIP.0   EIP.1   EIP.2   EIP.3       FB
+                FC      EIP.4   EIP.5   EIP.6   EIP.7       FF
+        
+                        Alternates:
+        
+        SCON    98      SCON.0  SCON.1  SCON.2  SCON.3      9B
+                9C      SCON.4  SCON.5  SCON.6  SCON.7      9F
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-29
+        DS83C530/DS87C530 SPECIAL FUNCTION REGISTERS
+
+
+        M.10.3  Bit Addressable Registers:  Specific 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      IT0     IE0     IT1     IE1         8B
+                8C      TR0     TF0     TR1     TF1         8F
+                90                                          93
+                94                                          97
+        SCON0   98      RI_0    TI_0    RB8_0   TB8_0       9B
+                9C      REN_0   SM2_0   SM1_0   SMO_0       9F
+                A0                                          A3
+                A4                                          A7
+        IE      A8      EX0     ET0     EX1     ET1         AB
+                AC      ES0     ET2     ES1     EA          AF
+                B0                                          B3
+                B4                                          B7
+        IP      B8      PX0     PT0     PX1     PT1         BB
+                BC      PS0     PT2     PS1                 BF
+        SCON1   C0      RI_1    TI_1    RB8_1   TB8_1       C3
+                C4      REN_1   SM2_1   SM1_1   SMO_1       C7
+        T2CON   C8      CPRL2   CT2     TR2     EXEN2       CB
+                CC      TCLK    RCLK    EXF2    TF2         CF
+        PSW     D0      P       FL      OV      RS0         D3
+                D4      RS1     F0      AC      CY          D7
+        WDCON   D8      RWT     EWT     WTRF    WDIF        DB
+                DC      PFI     EPFI    POR     SMOD_1      DF
+                E0                                          E3
+                E4                                          E7
+        EIE     E8      EX2     EX3     EX4     EX5         EB
+                EC      EWDI    ERTCI                       EF
+                F0                                          F3
+                F4                                          F7
+        EIP     F8      PX2     PX3     PX4     PX5         FB
+                FC      PWDI    PRTCI                       FF
+        
+                Alternates:
+        
+        SCON    98      RI      TI      RB8     TB8         9B
+                9C      REN     SM2     SM1     SMO         9F
+        SCON    98                                          9B
+                9C                              FE          9F
+        SCON0   98                                          9B
+                9C                              FE_0        9F
+        SCON1   C0                                          C3
+                C4                              FE_1        C7
+        T2CON   C8      CP_RL2  C_T2                        CB
+                CC                                          CF
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-30
+        DS83C530/DS87C530 SPECIAL FUNCTION REGISTERS
+
+
+        M.10.4  Optional Symbols:  Control Bits 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                        0x80    0x40    0x20    0x10
+                        0x08    0x04    0x02    0x10
+                        ----    ----    ----    ----
+        DPS     0x80                                        0x10
+                0x08                            SEL         0x01
+        PCON    0x80    SMOD_0  SMOD0                       0x10
+                0x08    GF1     GF0     STOP    IDLE        0x01
+        TMOD    0x80    T1GATE  T1C_T   T1M1    T1M0        0x10
+                0x08    T0GATE  T0C_T   T0M1    T0M0        0x01
+        CKCON   0x80    WD1     WD0     T2M     T1M         0x10
+                0x08    T0M     MD2     MD1     MD0         0x01
+        EXIF    0x80    IE5     IE4     IE3     IE          0x10
+                0x08    XT_RG   RGMD    RGSL    BGS         0x01
+        TRIM    0x80    E4K     X12_6   TRM2    _TRM2       0x10
+                0x08    TRM1    _TRM1   TRM0    _TRM0       0x01
+        SBUF1   0x80    SB7     SB6     SB5     SB4         0x10
+                0x08    SB3     SB2     SB1     SB0         0x01
+        ROMSIZE 0x80                                        0x10
+                0x08            RMS2    RMS1    RMS0        0x01
+        PMR     0x80    CD1     CD0     SWB                 0x10
+                0x08    XTOFF   ALEOFF  DME1    DME0        0x01
+        STATUS  0x80    PIP     HIP     LIP     XTUP        0x10
+                0x08    SPTA1   SPRA1   SPTA0   SPRA0       0x01
+        T2MOD   0x80                                        0x10
+                0x08                    T2OE    DCEN        0x01
+        RTCC    0x80    SSCE    SCE     MCE     HCE         0x10
+                0x08    RTCRE   RTCWE   RTCIF   RTCE        0x01
+        
+                Alternates:
+        
+        PCON    0x80    SMOD                                0x10
+                0x08                                        0x01
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-31
+        DS83C530/DS87C530 SPECIAL FUNCTION REGISTERS
+
+
+        M.11  DS83C550/DS87C550 SPECIAL FUNCTION REGISTERS 
+
+
+           The DS83C550/DS87C550 Special Function Registers are selected
+        using the .DS83C550 or DS87C550 assembler directives.  
+
+
+        M.11.1  SFR Map 
+
+                        --------- 4 Bytes ----------
+                        ----    ----    ----    ----
+                80      PORT0   SP      DPL     DPH         83
+                84      DPL1    DPH1    DPS     PCON        87
+                88      TCON    TMOD    TL0     TL1         8B
+                8C      TH0     TH1     CKCON               8F
+                90      PORT1   RCON                        93
+                94                                          97
+                98      SCON0   SBUF0                       9B
+                9C                              PMR         9F
+                A0      PORT2   SADDR0  SADDR1              A3
+                A4                                          A7
+                A8      IE      CMPL0   CMPL1   CMPL2       AB
+                AC      CPTL0   CPTL1   CPTL2   CPTL3       AF
+                B0      PORT3           ADCON1  ADCON2      B3
+                B4      ADMSB   ADLSD   WINHI   WINLO       B7
+                B8      IP      SADEN0  SADEN1              BB
+                BC                      T2CON   T2MOD       BF
+                C0      PORT4           ROMSIZE             C3
+                C4      PORT5   STATUS          TA          C7
+                C8      T2IR    CMPH0   CMPH1   CMPH2       CB
+                CC      CPTH0   CPTH1   CPTH2   CPTH3       CF
+                D0      PSW             PW0FG   PW1FG       D3
+                D4      PW2FG   PW3FG   PWMADR              D7
+                D8      SCON1   SBUF1                       DB
+                DC      PWM0    PWM1    PWM2    PWM3        DF
+                E0      ACC     PW01CS  PW23CS  PW01CON     E3
+                E4      PW23CON         RLOADL  RLOADH      E7
+                E8      EIE             T2SEL   CTCON       EB
+                EC      TL2     TH2     SETR    RSTR        EF
+                F0      B       PORT6                       F3
+                F4                                          F7
+                F8      EIP                                 FB
+                FC                              WDCON       FF
+        
+                Alternates:
+        
+                80      P0                                  83
+                90      P1                                  93
+                98      SCON    SBUF                        9B
+                A0      P2                                  A3
+                B0      P3                                  B3
+                C0      P4                                  C3
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-32
+        DS83C550/DS87C550 SPECIAL FUNCTION REGISTERS
+
+
+                C4      P5                                  C7
+                F0              PORT6                       F3
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-33
+        DS83C550/DS87C550 SPECIAL FUNCTION REGISTERS
+
+
+        M.11.2  Bit Addressable Registers:  Generic 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+        PORT0   80      P0.7    P0.6    P0.5    P0.4        83
+                84      P0.3    P0.2    P0.1    P0.0        87
+        TCON    88      TCON.0  TCON.1  TCON.2  TCON.3      8B
+                8C      TCON.4  TCON.5  TCON.6  TCON.7      8F
+        PORT1   90      P1.0    P1.1    P1.2    P1.3        93
+                94      P1.4    P1.5    P1.6    P1.7        97
+        SCON0   98      SCON0.0 SCON0.1 SCON0.2 SCON0.3     9B
+                9C      SCON0.4 SCON0.5 SCON0.6 SCON0.7     9F
+        PORT2   A0      P2.0    P2.1    P2.2    P2.3        A3
+                A4      P2.4    P2.5    P2.6    P2.7        A7
+        IE      A8      IE.0    IE.1    IE.2    IE.3        AB
+                AC      IE.4    IE.5    EI.6    IE.7        AF
+        PORT3   B0      P3.0    P3.1    P3.2    P3.3        B3
+                B4      P3.4    P3.5    P3.6    P3.7        B7
+        IP      B8      IP.0    IP.1    IP.2    IP.3        BB
+                BC      IP.4    IP.5    IP.6    IP.7        BF
+        PORT4   C0      P4.0    P4.1    P4.2    P4.3        C3
+                C4      P4.4    P4.5    P4.6    P4.7        C7
+        T2IR    C8      T2IR.0  T2IR.1  T2IR.2  T2IR.3      CB
+                CC      T2IR.4  T2IR.5  T2IR.6  T2IR.7      CF
+        PSW     D0      PSW.0   PSW.1   PSW.2   PSW.3       D3
+                D4      PSW.4   PSW.5   PSW.6   PSW.7       D7
+        SCON1   D8      SCON1.0 SCON1.1 SCON1.2 SCON1.3     DB
+                DC      SCON1.4 SCON1.5 SCON1.6 SCON1.7     DF
+        ACC     E0      ACC.0   ACC.1   ACC.2   ACC.3       E3
+                E4      ACC.4   ACC.5   ACC.6   ACC.7       E7
+        EIE     E8      EIE.0   EIE.1   EIE.2   EIE.3       EB
+                EC      EIE.4   EIE.5   EIE.6   EIE.7       EF
+        B       F0      B.0     B.1     B.2     B.3         F3
+                F4      B.4     B.5     B.6     B.7         F7
+        EIP     F8      EIP.0   EIP.1   EIP.2   EIP.3       FB
+                FC      EIP.4   EIP.5   EIP.6   EIP.7       FF
+        
+                        Alternates:
+        
+        PORT0   80      PORT0.7 PORT0.6 PORT0.5 PORT0.4     83
+                84      PORT0.3 PORT0.2 PORT0.1 PORT0.0     87
+        PORT1   90      PORT1.0 PORT1.1 PORT1.2 PORT1.3     93
+                94      PORT1.4 PORT1.5 PORT1.6 PORT1.7     97
+        SCON    98      SCON.0  SCON.1  SCON.2  SCON.3      9B
+                9C      SCON.4  SCON.5  SCON.6  SCON.7      9F
+        PORT2   A0      PORT2.0 PORT2.1 PORT2.2 PORT2.3     A3
+                A4      PORT2.4 PORT2.5 PORT2.6 PORT2.7     A7
+        PORT3   B0      PORT3.0 PORT3.1 PORT3.2 PORT3.3     B3
+                B4      PORT3.4 PORT3.5 PORT3.6 PORT3.7     B7
+        PORT4   C0      PORT4.0 PORT4.1 PORT4.2 PORT4.3     C3
+                C4      PORT4.4 PORT4.5 PORT4.6 PORT4.7     C7
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-34
+        DS83C550/DS87C550 SPECIAL FUNCTION REGISTERS
+
+
+        M.11.3  Bit Addressable Registers:  Specific 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                80                                          83
+                84                                          87
+        TCON    88      IT0     IE0     IT1     IE1         8B
+                8C      TR0     TF0     TR1     TF1         8F
+                90                                          93
+                94                                          97
+        SCON0   98      RI_0    TI_0    RB8_0   TB8_0       9B
+                9C      REN_0   SM2_0   SM1_0   SMO_0       9F
+                A0                                          A3
+                A4                                          A7
+        IE      A8      EX0     ET0     EX1     ET1         AB
+                AC      ES0     ET2     ES1     EA          AF
+                B0                                          B3
+                B4                                          B7
+        IP      B8      PX0     PT0     PX1     PT1         BB
+                BC      PS0     PS1     PAD                 BF
+        PORT4   C0      CMSR0   CMSR1   CMSR2   CMSR3       C3
+                C4      CMSR4   CMSR5   CMT0    CMT1        C7
+        T2IR    C8      CF0     CF1     CF2     CF3         CB
+                CC      CM0F    CM1F    CM2F                CF
+        PSW     D0      P       FL      OV      RS0         D3
+                D4      RS1     F0      AC      CY          D7
+        SCON1   D8      RI_1    TI_1    RB8_1   TB8_1       DB
+                DC      REN_1   SM2_1   SM1_1   SMO_1       DF
+                E0                                          E3
+                E4                                          E7
+        EIE     E8      EX2     EX3     EX4     EX5         EB
+                EC      ECM0    ECM1    ECM2    ET2         EF
+                F0                                          F3
+                F4                                          F7
+        EIP     F8      PX2     PX3     PX4     PX5         FB
+                FC      PCM0    PCM1    PCM2    PT2         FF
+        
+                Alternates:
+        
+        SCON    98      RI      TI      RB8     TB8         9B
+                9C      REN     SM2     SM1     SMO         9F
+        SCON    98                                          9B
+                9C                              FE          9F
+        SCON0   98                                          9B
+                9C                              FE_0        9F
+        T2IR    C8      IE2     IE3     IE4     IE5         CB
+                CC                                          CF
+        SCON1   D8                                          DB
+                DC                              FE_1        DF
+        EIE     E8      EC0     EC1     EC2     EC3         EB
+                EC                                          EF
+        EIP     F8      PC0     PC1     PC2     PC3         FB
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-35
+        DS83C550/DS87C550 SPECIAL FUNCTION REGISTERS
+
+
+                FC                                          FF
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-36
+        DS83C550/DS87C550 SPECIAL FUNCTION REGISTERS
+
+
+        M.11.4  Optional Symbols:  Control Bits 
+
+                        ---------- 4 BITS ----------
+                        ----    ----    ----    ----
+                        0x80    0x40    0x20    0x10
+                        0x08    0x04    0x02    0x10
+                        ----    ----    ----    ----
+        DPS     0x80    ID1     ID0     TSL                 0x10
+                0x08                            SEL         0x01
+        PCON    0x80    SMOD_0  SMOD0                       0x10
+                0x08    GF1     GF0     STOP    IDLE        0x01
+        TMOD    0x80    T1GATE  T1C_T   T1M1    T1M0        0x10
+                0x08    T0GATE  T0C_T   T0M1    T0M0        0x01
+        CKCON   0x80    WD1     WD0     T2M     T1M         0x10
+                0x08    T0M     MD2     MD1     MD0         0x01
+        RCON    0x80                                        0x10
+                0x08    CKRDY   RGMD    RGSL    BGS         0x01
+        PMR     0x80    CD1     CD0     SWB     CTM         0x10
+                0x08    4X_2X   ALEOFF  DEM1    DEM0        0x01
+        ADCON1  0x80   STRT_BSY EOC     CONT_SS ADEX        0x10
+                0x08    WCQ     WCM     ADON    WCIO        0x01
+        ADCON2  0x80    OUTCF   MUX2    MUX1    MUX0        0x10
+                0x08    APS3    APS2    APS1    APS0        0x01
+        T2CON   0x80    TF2     EXF2    RCLK    TCLK        0x10
+                0x08    EXEN2   TR2     CT2     CPRL2       0x01
+        T2MOD   0x80                                        0x10
+                0x08                    T2OE    DCEN        0x01
+        PORT5   0x80    ADC7    ADC6    ADC5    ADC4        0x10
+                0x08    ADC3    ADC2    ADC1    ADC0        0x01
+        ROMSIZE 0x80                                        0x10
+                0x08            RMS2    RMS1    RMS0        0x01
+        STATUS  0x80    PIP     HIP     LIP     XTUP        0x10
+                0x08    SPTA1   SPRA1   SPTA0   SPRA0       0x01
+        PWMADR  0x80    ADRS                                0x10
+                0x08                    PWE1    PWE0        0x01
+        PW01CS  0x80    PW0S2   PW0S1   PW0S0   PW0EN       0x10
+                0x08    PW1S2   PW1S1   PW1S0   PW1EN       0x01
+        PW23CS  0x80    PW2S2   PW2S1   PW2S0   PW2EN       0x10
+                0x08    PW3S2   PW3S1   PW3S0   PW3EN       0x01
+        PW01CON 0x80    PW0F    PW0DC   PW0OE   PW0T_C      0x10
+                0x08    PW1F    PW1DC   PW1OE   PW1T_C      0x01
+        PW23CON 0x80    PW2F    PW2DC   PW2OE   PW2T_C      0x10
+                0x08    PW3F    PW3DC   PW3OE   PW3T_C      0x01
+        T2SEL   0x80    TF2S    TF2BS           TF2B        0x10
+                0x08                    T2P1    T2P0        0x01
+        CTCON   0x80    _CT3    CT3     _CT2    CT2         0x10
+                0x08    _CT1    CT1     _CT0    CT0         0x01
+        SETR    0x80    TGFF1   TGFF0   CMS5    CMS4       0x10
+                0x08    CMS3    CMS2    CMS1    CMS0        0x01
+        RSTR    0x80    CMTE1   CMTE0   CMR5    CMR4        0x10
+                0x08    CMR3    CMR2    CMR1    CMR0        0x01
+        PORT6   0x80    STADC           PWMC1   PWMC0       0x10
+
+
+        AS8XCXXX ASSEMBLER                                     PAGE M-37
+        DS83C550/DS87C550 SPECIAL FUNCTION REGISTERS
+
+
+                0x08    PWMO3   PWMO2   PWMO1   PWMO0       0x01
+        WDCON   0x80    SMOD_1  POR     EPF1    PF1         0x10
+                0x08    WDIF    WTRF    EWT     RWT         0x01
+        
+                Alternates:
+        
+        PCON    0x80    SMOD                                0x10
+                0x08                                        0x01
+        T2CON   0x80                                        0x10
+                0x08                    C_T2    _RL2        0x01
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX N
+
+                                 ASZ80 ASSEMBLER
+
+
+
+
+
+        N.1  .hd64 DIRECTIVE 
+
+        Format:  
+
+                .hd64 
+
+        The  .hd64  directive enables processing of the HD64180 specific
+        mnemonics not included in  the  Z80  instruction  set.   HD64180
+        mnemonics  encountered  without  the  .hd64  directive  will  be
+        flagged with an 'o' error.  
+
+
+        N.2  Z80 REGISTER SET AND CONDITIONS 
+
+
+           The following is a complete list of register designations and
+        condition mnemonics:  
+
+                byte registers  -       a,b,c,d,e,h,l,i,r
+                register pairs  -       af,af',bc,de,hl
+                word registers  -       pc,sp,ix,iy
+        
+                C -     carry bit set
+                M -     sign bit set
+                NC -    carry bit clear
+                NZ -    zero bit clear
+                P -     sign bit clear
+                PE -    parity even
+                PO -    parity odd
+                Z -     zero bit set
+
+
+
+
+        ASZ80 ASSEMBLER                                         PAGE N-2
+        Z80 INSTRUCTION SET
+
+
+        N.3  Z80 INSTRUCTION SET 
+
+
+           The  following  tables  list all Z80/HD64180 mnemonics recog-
+        nized by the ASZ80 assembler.  The designation []  refers  to  a
+        required addressing mode argument.  The following list specifies
+        the format for each addressing mode supported by ASZ80:  
+
+                #data           immediate data
+                                byte or word data
+        
+                n               byte value
+        
+                rg              a byte register
+                                a,b,c,d,e,h,l
+        
+                rp              a register pair
+                                bc,de,hl
+        
+                (hl)            implied addressing or
+                                register indirect addressing
+        
+                (label)         direct addressing
+        
+                offset(ix)      indexed addressing with
+                                an offset
+        
+                label           call/jmp/jr label
+
+        The  terms  data,  dir,  offset, and ext may all be expressions.
+        The terms dir and offset are not allowed to be  external  refer-
+        ences.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction, refer to the Z80/HD64180  technical  data  for  valid
+        modes.  
+
+
+        ASZ80 ASSEMBLER                                         PAGE N-3
+        Z80 INSTRUCTION SET
+
+
+        N.3.1  Inherent Instructions 
+
+                ccf             cpd
+                cpdr            cpi
+                cpir            cpl
+                daa             di
+                ei              exx
+                halt            neg
+                nop             reti
+                retn            rla
+                rlca            rld
+                rra             rrca
+                rrd             scf
+
+
+        N.3.2  Implicit Operand Instructions 
+
+                adc     a,[]            adc     []
+                add     a,[]            add     []
+                and     a,[]            and     []
+                cp      a,[]            cp      []
+                dec     a,[]            dec     []
+                inc     a,[]            inc     []
+                or      a,[]            or      []
+                rl      a,[]            rl      []
+                rlc     a,[]            rlc     []
+                rr      a,[]            rr      []
+                rrc     a,[]            rrc     []
+                sbc     a,[]            sbc     []
+                sla     a,[]            sla     []
+                sra     a,[]            sra     []
+                srl     a,[]            srl     []
+                sub     a,[]            sub     []
+                xor     a,[]            xor     []
+
+
+        ASZ80 ASSEMBLER                                         PAGE N-4
+        Z80 INSTRUCTION SET
+
+
+        N.3.3  Load Instruction 
+
+                ld      rg,[]           ld      [],rg
+                ld      (bc),a          ld      a,(bc)
+                ld      (de),a          ld      a,(de)
+                ld      (label),a       ld      a,(label)
+                ld      (label),rp      ld      rp,(label)
+                ld      i,a             ld      r,a
+                ld      a,i             ld      a,r
+                ld      sp,hl           ld      sp,ix
+                ld      sp,iy           ld      rp,#data
+        
+                ldd                     lddr
+                ldi                     ldir
+
+
+        N.3.4  Call/Return Instructions 
+
+                call    C,label         ret     C
+                call    M,label         ret     M
+                call    NC,label        ret     NC
+                call    NZ,label        ret     NZ
+                call    P,label         ret     P
+                call    PE,label        ret     PE
+                call    PO,label        ret     PO
+                call    Z,label         ret     Z
+                call    label           ret
+
+
+        N.3.5  Jump and Jump to Subroutine Instructions 
+
+                jp      C,label         jp      M,label
+                jp      NC,label        jp      NZ,label
+                jp      P,label         jp      PE,label
+                jp      PO,label        jp      Z,label
+        
+                jp      (hl)            jp      (ix)
+                jp      (iy)            jp      label
+        
+                djnz    label
+        
+                jr      C,label         jr      NC,label
+                jr      NZ,label        jr      Z,label
+                jr      label
+
+
+        ASZ80 ASSEMBLER                                         PAGE N-5
+        Z80 INSTRUCTION SET
+
+
+        N.3.6  Bit Manipulation Instructions 
+
+                bit     n,[]
+                res     n,[]
+                set     n,[]
+
+
+        N.3.7  Interrupt Mode and Reset Instructions 
+
+                im      n
+                im      n
+                im      n
+                rst     n
+
+
+        N.3.8  Input and Output Instructions 
+
+                in      a,(n)           in      rg,(c)
+                ind                     indr
+                ini                     inir
+        
+                out     (n),a           out     (c),rg
+                outd                    otdr
+                outi                    otir
+
+
+        N.3.9  Register Pair Instructions 
+
+                add     hl,rp           add     ix,rp
+                add     iy,rp
+        
+                adc     hl,rp           sbc     hl,rp
+        
+                ex      (sp),hl         ex      (sp),ix
+                ex      (sp),iy
+                ex      de,hl
+                ex      af,af'
+        
+                push    rp              pop     rp
+
+
+        ASZ80 ASSEMBLER                                         PAGE N-6
+        Z80 INSTRUCTION SET
+
+
+        N.3.10  HD64180 Specific Instructions 
+
+                in0     rg,(n)
+                out0    (n),rg
+        
+                otdm                    otdmr
+                otim                    otimr
+        
+                mlt     bc              mlt     de
+                mlt     hl              mlt     sp
+        
+                slp
+        
+                tst     a
+                tstio   #data
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX O
+
+                                 ASGB ASSEMBLER
+
+
+
+
+
+        O.1  ACKNOWLEDGEMENT 
+
+
+           Thanks  to  Roger Ivie for his contribution of the ASGB cross
+        assembler.  
+
+                Roger Ivie
+                ivie@cc.usu.edu
+
+
+        O.2  INTRODUCTION 
+
+
+           The  Gameboy uses an 8-bit processor which is closely related
+        to the 8080.  It is usually described as a modified Z80, but may
+        be more closely understood as an enhanced 8080;  it has the 8080
+        register set and many, but not all, enhanced  Z80  instructions.
+        However,  even  this is not accurate, for the Gameboy also lacks
+        some basic 8080 instructions (most annoyingly  SHLD  and  LHLD).
+        ASGB is based on ASZ80 and therefore uses the Z80 mnemonic set. 
+
+
+        O.3  GAMEBOY REGISTER SET AND CONDITIONS 
+
+
+           The following is a complete list of register designations and
+        condition mnemonics:  
+
+                byte registers - a,b,c,d,e,h,l
+                register pairs - af, bc, de, hl
+                word registers - pc, sp
+        
+                C  - carry bit set
+                NC - carry bit clear
+                NZ - zero bit clear
+                Z  - zero bit set
+
+
+        ASGB ASSEMBLER                                          PAGE O-2
+        GAMEBOY INSTRUCTION SET
+
+
+        O.4  GAMEBOY INSTRUCTION SET 
+
+
+           The following tables list all Gameboy mnemnoics recognized by
+        the ASGB assembler.  The designation [] refers to a required ad-
+        dressing mode argument.  The following list specifies the format
+        for each addressing mode supported by ASGB:  
+
+                #data           immediate data
+                                byte or word data
+        
+                n               byte value
+        
+                rg              a byte register
+                                a,b,c,d,e,h,l
+        
+                rp              a register pair or 16-bit register
+                                bc,de,hl
+        
+                (hl)            implied addressing or
+                                register indirect addressing
+        
+                (label)         direct addressing
+        
+                label           call/jmp/jr label
+
+
+           The terms data, dir, and ext may all be expression.  The term
+        dir is not allowed to be an external reference.  
+
+           Note  that  not all addressing modes are valid with every in-
+        struction.  Although official information is not, as  far  as  I
+        know, publically available for the Gameboy processor, many unof-
+        ficial sources are available on the internet.  
+
+
+        O.4.1  .tile Directive 
+
+
+        Format: .tile /string/ 
+
+        where:  string  is  a  string of ascii characters taken from the
+                        set ' ', '.', '+', '*', '0', '1', '2', and  '3'.
+                        The   string   must   be  a  multiple  of  eight
+                        characters long.  
+
+                /  /     represent  the  delimiting  characters.   These
+                        delimiters   may   be   any   paired    printing
+                        characters,  as  long  as the characters are not
+                        contained within  the  string  itself.   If  the
+                        delimiting  characters  do  not match, the .tile
+                        directive will give the (q) error.  
+
+
+        ASGB ASSEMBLER                                          PAGE O-3
+        GAMEBOY INSTRUCTION SET
+
+
+             The Gameboy displays information on the screen using a pro-
+        grammable character set (referred to as  "tiles"  among  Gameboy
+        developers).   The ASGB cross assembler has a processor-specific
+        assembler directive  to  aid  in  the  creation  of  the  game's
+        character set.  
+
+             Each  character is created from an 8x8 grid of pixels, each
+        pixel of which is composed of two bits.  The .tile directive ac-
+        cepts  a single string argument which is processed to create the
+        byte  values  corresponding  to  the  lines  of  pixels  in  the
+        character.   The  string  argument  must  be  some multiple of 8
+        characters long, and be one of these characters:  
+
+                ' ' or '0' - for the pixel value 00
+                '.' or '1' - for the pixel value 01
+                '+' or '2' - for the pixel value 10
+                '*' or '3' - for the pixel value 11
+
+             The .tile directive processes each 8-character group of its
+        string argument to create the two-byte  value  corresponding  to
+        that  line of pixels.  The example in the popular extant litera-
+        ture could be done using ASGB like this:  
+
+           0000 7C 7C                 1         .tile " *****  "
+           0002 00 C6                 2         .tile "++   ++ "
+           0004 C6 00                 3         .tile "..   .. "
+           0006 00 FE                 4         .tile "+++++++ "
+           0008 C6 C6                 5         .tile "**   ** "
+           000A 00 C6                 6         .tile "++   ++ "
+           000C C6 00                 7         .tile "..   .. "
+           000E 00 00                 8         .tile "        "
+
+             Or, using the synonym character set, as:  
+
+           0010 7C 7C                10         .tile "03333300"
+           0012 00 C6                11         .tile "22000220"
+           0014 C6 00                12         .tile "11000110"
+           0016 00 FE                13         .tile "22222220"
+           0018 C6 C6                14         .tile "33000330"
+           001A 00 C6                15         .tile "22000220"
+           001C C6 00                16         .tile "11000110"
+           001E 00 00                17         .tile "00000000"
+
+             Since .tile is perfectly willing to assemble multiple lines
+        of a character at once (as long as it is given complete rows  of
+        pixels), it could even be done as:  
+
+                .tile " *****  ++   ++ ..   .. +++++++ "
+                .tile "**   ** ++   ++ ..   ..         "
+
+
+
+
+        ASGB ASSEMBLER                                          PAGE O-4
+        GAMEBOY INSTRUCTION SET
+
+
+        O.4.2  Potentially Controversial Mnemonic Selection 
+
+
+             Although the Gameboy processor is based on the Z80, it does
+        include some features which are not present in the Z80.  The Z80
+        mnemonic  set  is  not  sufficient  to describe these additional
+        operations;  mnemonics must be created for the  new  operations.
+        The  mnemonics ASGB uses are not the same as those used by other
+        publically-available Gameboy assemblers.  
+
+
+        O.4.2.1  Auto-Indexing Loads  - 
+
+             The  Gameboy provides instructions to load or store the ac-
+        cumulator indirectly via HL and then subsequently  increment  or
+        decrement HL.  ASGB uses the mnemonic 'ldd' for the instructions
+        which decrement HL and 'ldi' for the instructions  which  incre-
+        ment  HL.   Because the Gameboy lacks the Z80's block moves, the
+        mnemonics are not otherwise needed by ASGB.  
+
+                ldd a,(hl)      ldd (hl),a
+                ldi a,(hl)      ldi (hl),a
+
+
+        O.4.2.2  Input and Output Operations  - 
+
+             The  Gameboy  replaces the Z80's separate address space for
+        I/O with a mechanism similar to the zero page addressing of pro-
+        cessors  such  as  the  6800  or 6502.  All I/O registers in the
+        Gameboy reside in the address range between 0xff00  and  0xffff.
+        The  Gameboy adds special instructions to load and store the ac-
+        cumulator from and into this page of memory.   The  instructions
+        are  analogous to the Z80's in and out instructions and ASGB re-
+        tains the 'in' and 'out' mnemonics for them.  
+
+                in a,(n)        out (n),a
+                in a,(c)        out (c),a
+
+             From  ASGB's  perspective,  the  RAM  available from 0xff80
+        through 0xffff is composed of unused I/O locations  rather  than
+        direct-page RAM.  
+
+
+
+
+        ASGB ASSEMBLER                                          PAGE O-5
+        GAMEBOY INSTRUCTION SET
+
+
+        O.4.2.3  The 'stop' Instruction  - 
+
+             The  publically-available  documentation  for  the  Gameboy
+        lists the 'stop' instruction as the two-byte instruction 10  00,
+        and the other freely-available Gameboy assemblers assemble it in
+        that manner.  As far as I can tell, the only rationale for  this
+        is  that  the  corresponding Z80 instruction ('djnz label') is a
+        two-byte instruction.  ASGB assembles 'stop' as the one-byte in-
+        struction 10.  
+
+
+        O.4.3  Inherent Instructions 
+
+
+                ccf             cpl
+                daa             di
+                ei              nop
+                halt            rla
+                rlca            rra
+                rrca            scf
+                reti            stop
+                swap
+
+
+        O.4.4  Implicit Operand Instructions 
+
+
+                adc a,[]        adc []
+                add a,[]        add []
+                and a,[]        and []
+                cp a,[]         cp []
+                dec a,[]        dec []
+                inc a,[]        inc []
+                or a,[]         or []
+                rl a,[]         rl []
+                rlc a,[]        rlc []
+                rr a,[]         rr []
+                rrc a,[]        rrc []
+                sbc a,[]        sbc []
+                sla a,[]        sla []
+                sra a,[]        sra []
+                srl a,[]        srl []
+                sub a,[]        sub []
+                xor a,[]        xor []
+
+
+
+
+        ASGB ASSEMBLER                                          PAGE O-6
+        GAMEBOY INSTRUCTION SET
+
+
+        O.4.5  Load Instructions 
+
+
+                ld rg,[]        ld [],rg
+                ld (bc),a       ld a,(bc)
+                ld (de),a       ld a,(de)
+                ld (label),a    ld a,(label)
+                ld (label),sp   ld rp,#data
+                ld sp,hl        ld hl,sp
+        
+                ldd a,(hl)      ldd (hl),a
+                ldi a,(hl)      ldi (hl),a
+
+
+        O.4.6  Call/Return Instructions 
+
+
+                call C,label    ret C
+                call NC,label   ret NC
+                call Z,label    ret Z
+                call NZ,label   ret NZ
+                call label      ret
+        
+                rst n
+
+
+        O.4.7  Jump Instructions 
+
+
+                jp C,label      jp NC,label
+                jp Z,label      jp NZ,label
+        
+                jp (hl)         jp label
+        
+                jr C,label      jr NC,label
+                jr Z,label      jr NZ,label
+                jr label
+
+
+        O.4.8  Bit Manipulation Instructions 
+
+
+                bit n,[]
+                res n,[]
+                set n,[]
+
+
+
+
+        ASGB ASSEMBLER                                          PAGE O-7
+        GAMEBOY INSTRUCTION SET
+
+
+        O.4.9  Input and Output Instructions 
+
+
+                in a,(n)        in a,(c)
+                out (n),a       out (c),a
+
+
+        O.4.10  Register Pair Instructions 
+
+
+                add hl,rp       add hl,sp
+                add sp,#data
+        
+                push rp         pop rp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                   APPENDIX P
+
+                                AS6500 ASSEMBLER
+
+
+
+
+
+        P.1  ACKNOWLEDGMENT 
+
+
+             Thanks  to  Marko Makela for his contribution of the AS6500
+        cross assembler.  
+
+                Marko Makela
+                Sillitie 10 A
+                01480 Vantaa
+                Finland
+                Internet: Marko.Makela@Helsinki.Fi
+                EARN/BitNet: msmakela@finuh
+
+             Several  additions  and modifications were made to his code
+        to support the following families of 6500 processors:  
+
+                (1)     650X and 651X processor family
+                (2)     65F11 and 65F12 processor family
+                (3)     65C00/21 and 65C29 processor family
+                (4)     65C02, 65C102, and 65C112 processor family
+
+             The instruction syntax of this cross assembler contains two
+        peculiarities:  (1) the addressing indirection is denoted by the
+        square  brackets  []  and (2) the `bbrx' and `bbsx' instructions
+        are written `bbr0 memory,label'.  
+
+
+
+
+        AS6500 ASSEMBLER                                        PAGE P-2
+        6500 REGISTER SET
+
+
+        P.2  6500 REGISTER SET 
+
+        The following is a list of the 6500 registers used by AS6500:  
+
+                a       -       8-bit accumulator
+                x,y     -       index registers
+
+
+        P.3  6500 INSTRUCTION SET 
+
+
+             The  following tables list all 6500 family mnemonics recog-
+        nized by the AS6500 assembler.  The designation [] refers  to  a
+        required addressing mode argument.  The following list specifies
+        the format for each addressing mode supported by AS6500:  
+
+                #data           immediate data
+                                byte or word data
+        
+                *dir            direct page addressing
+                                (see .setdp directive)
+                                0 <= dir <= 255 
+        
+                offset,x        indexed addressing
+                offset,y        indexed addressing
+                                address = (offset + (x or y))
+        
+                [offset,x]      pre-indexed indirect addressing
+                                0 <= offset <= 255
+                                address = contents of location
+                                    (offset + (x or y)) mod 256
+        
+                [offset],y      post-indexed indirect addressing
+                                address = contents of location at offset
+                                    plus the value of the y register
+        
+                [address]       indirect addressing
+        
+                ext             extended addressing
+        
+                label           branch label
+        
+                address,label   direct page memory location
+                                branch label
+                                bbrx and bbsx instruction addressing
+
+        The  terms data, dir, offset, address, ext, and label may all be
+        expressions.  
+
+             Note that not all addressing modes are valid with every in-
+        struction, refer to the 65xx technical data for valid modes.  
+
+
+        AS6500 ASSEMBLER                                        PAGE P-3
+        6500 INSTRUCTION SET
+
+
+        P.3.1  Processor Specific Directives 
+
+
+             The  AS6500 cross assembler has four (4) processor specific
+        assembler directives which  define  the  target  65xx  processor
+        family:  
+
+                .r6500          Core 650X and 651X family (default)
+                .r65f11         Core plus 65F11 and 65F12
+                .r65c00         Core plus 65C00/21 and 65C29
+                .r65c02         Core plus 65C02, 65C102, and 65C112
+
+
+        P.3.2  65xx Core Inherent Instructions 
+
+                brk                     clc
+                cld                     cli
+                clv                     dex
+                dey                     inx
+                iny                     nop
+                pha                     php
+                pla                     plp
+                rti                     rts
+                sec                     sed
+                sei                     tax
+                tay                     tsx
+                txa                     txs
+                tya
+
+
+        P.3.3  65xx Core Branch Instructions 
+
+                bcc     label           bhs     label
+                bcs     label           blo     label
+                beq     label           bmi     label
+                bne     label           bpl     label
+                bvc     label           bvs     label
+
+
+        P.3.4  65xx Core Single Operand Instructions 
+
+                asl     []
+                dec     []
+                inc     []
+                lsr     []
+                rol     []
+                ror     []
+
+
+        AS6500 ASSEMBLER                                        PAGE P-4
+        6500 INSTRUCTION SET
+
+
+        P.3.5  65xx Core Double Operand Instructions 
+
+                adc     []
+                and     []
+                bit     []
+                cmp     []
+                eor     []
+                lda     []
+                ora     []
+                sbc     []
+                sta     []
+
+
+        P.3.6  65xx Core Jump and Jump to Subroutine Instructions 
+
+                jmp     []              jsr     []
+
+
+        P.3.7  65xx Core Miscellaneous X and Y Register Instructions 
+
+                cpx     []
+                cpy     []
+                ldx     []
+                stx     []
+                ldy     []
+                sty     []
+
+
+        AS6500 ASSEMBLER                                        PAGE P-5
+        6500 INSTRUCTION SET
+
+
+        P.3.8  65F11 and 65F12 Specific Instructions 
+
+                bbr0    [],label                bbr1    [],label
+                bbr2    [],label                bbr3    [],label
+                bbr4    [],label                bbr5    [],label
+                bbr6    [],label                bbr7    [],label
+        
+                bbs0    [],label                bbs1    [],label
+                bbs2    [],label                bbs3    [],label
+                bbs4    [],label                bbs5    [],label
+                bbs6    [],label                bbs7    [],label
+        
+                rmb0    []                      rmb1    []
+                rmb2    []                      rmb3    []
+                rmb4    []                      rmb5    []
+                rmb6    []                      rmb7    []
+        
+                smb0    []                      smb1    []
+                smb2    []                      smb3    []
+                smb4    []                      smb5    []
+                smb6    []                      smb7    []
+
+
+        P.3.9  65C00/21 and 65C29 Specific Instructions 
+
+                bbr0    [],label                bbr1    [],label
+                bbr2    [],label                bbr3    [],label
+                bbr4    [],label                bbr5    [],label
+                bbr6    [],label                bbr7    [],label
+        
+                bbs0    [],label                bbs1    [],label
+                bbs2    [],label                bbs3    [],label
+                bbs4    [],label                bbs5    [],label
+                bbs6    [],label                bbs7    [],label
+        
+                bra     label
+        
+                phx                             phy
+                plx                             ply
+        
+                rmb0    []                      rmb1    []
+                rmb2    []                      rmb3    []
+                rmb4    []                      rmb5    []
+                rmb6    []                      rmb7    []
+        
+                smb0    []                      smb1    []
+                smb2    []                      smb3    []
+                smb4    []                      smb5    []
+                smb6    []                      smb7    []
+
+
+        AS6500 ASSEMBLER                                        PAGE P-6
+        6500 INSTRUCTION SET
+
+
+        P.3.10  65C02, 65C102, and 65C112 Specific Instructions 
+
+                bbr0    [],label                bbr1    [],label
+                bbr2    [],label                bbr3    [],label
+                bbr4    [],label                bbr5    [],label
+                bbr6    [],label                bbr7    [],label
+        
+                bbs0    [],label                bbs1    [],label
+                bbs2    [],label                bbs3    [],label
+                bbs4    [],label                bbs5    [],label
+                bbs6    [],label                bbs7    [],label
+        
+                bra     label
+        
+                phx                             phy
+                plx                             ply
+        
+                rmb0    []                      rmb1    []
+                rmb2    []                      rmb3    []
+                rmb4    []                      rmb5    []
+                rmb6    []                      rmb7    []
+        
+                smb0    []                      smb1    []
+                smb2    []                      smb3    []
+                smb4    []                      smb5    []
+                smb6    []                      smb7    []
+        
+                stz     []
+                trb     []
+                tsb     []
+
+             Additional addressing modes for the following core instruc-
+        tions are also available with the 65C02, 65C102, and 65C112 pro-
+        cessors.  
+
+                adc     []                      and     []
+                cmp     []                      eor     []
+                lda     []                      ora     []
+                sbc     []                      sta     []
+        
+                bit     []                      jmp     []
+        
+                dec                             inc
+
+


+

Go to the +Documentation Index

+

+

... Exit ASxxxx Documentation

+

... Home Page

diff --git a/doc/ASxxxx Cross Assembler Documentation_files/home.gif b/doc/ASxxxx Cross Assembler Documentation_files/home.gif new file mode 100755 index 0000000000000000000000000000000000000000..48e92ec3c4feb21f45d4702bc44d7ac2d0f1ca07 GIT binary patch literal 1536 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 P2ZQyniNsNlkP-p_U=V;M_hgpo@r zipvn$(oI*i(NsjT(|v!h{*2%Kem>9heb4ip^F8N0pXa=`1RFymPj{RVETMpb^2;c{ zh=PqMlvWI*t!3S_6p95{SO5hD3+xNsFqDEZ1tZL`1jRxgc;Fi)832ap2~i{li{trkG}J!Xj5b)qoJ-%mD;WNJ#7?QD}hh142j9_kdIZ@)SEW ziq-(q4u~Eg{V3`Q$WE{v1tb)^3s`bd^a&vIfJg#z0FXRDM8OhAipSx^?6DJ4r1&;U zfq}^j%z6L|K$HL!fGGw7F0gYB%aAT}Hhh97Kv;-ZJMfzWVznU!$FT|kVv3@{B#I1p zBw*8&8$r3%ktz?8{f<=4ESv=J?c~AYyy@zgr=A1qNnZeoILH1tXAR}fP%8Z_HV3DX z2G9!739yXQ-~j6`04L75fvl{~R-fXd8i-a+ioV7K{*QsK&C=Y*FV=@B9NehD#+v{EEF&n5uc1GQ7ucb4ic?e6M%^w)%){3f|8-qbCvcQgThf^X zhm)lVb){VyO3pXeIdzO@cQm~NT?p*5-dw|Qp0qA@d0*ka2%){i`ig-}iwqSH;~y3M zF^(m~d@0w$Vdimm;G6CUrgM>fTk`bE@Y$gos6(9y}cnYZ~SD0M9I!AjGxgCD8StntV<`+zHjs7G_mTyWplnViRuP;_K~mt?Op z;3pHl_=Y-;tm#!aMBTtCy-Rq_(3J^R+FMZ+EEw7N@`|HThS-VqL&;gchguuDL>WGW+athDWxla zOGAn*f1aSyR2p&gno%C@>|w%0vb$F{Q83`we zo@G_UuFuSTSya3bU$oCqrLy3s_ZPQ{)p!p=+tvATJT&AeS8)_ngPiJL8jrK&ar#bt zz^nhN+AXP61dcOoosud!upMek+qz9XPkaOgD(A?@l+@5I&_Dq?2J+gV#>YRc|t$Njb^f!rxodW@;&|m9nG6N2}9M>rMUO zt{I)dPNjRn3&W!Y!F8vQKc}=ovoAU${L%2eONu^3xDz4(et zZyvlI7*AYYc;(mky6=sS^Eckahx?~Pqb+m_dG_oQ%kE*BP5nq4(tlYy*rgF$wkLb@ zG{62+%d+_OwcdY){U9E=`cE5Hd$woZRmzbx$XcJdlO2-x(Sbu$Hr7dLCOeAJ>? zn~Jxic3ia#3vR5Zv*7a4x^{NRy>kiyUQfOJ&E_9j#TZOEZY#GItF%}1krkGmYWIJ% zJ;yi2cm3^r_e8tG;J2jacsc1#30tdUwaHtfCBGZetWWhO+BAR3l)0o=Hnw{%?a%}7 zl`3xQp~;fey{jdmJVqR1Y-L(v&&P?KD-F9>t;lKi*X2=;xLr=VmBV1EN;!wns5O^C zUmsQSJ0VUin7eH+_FUxxx!g^tH-nZm!TR^&9WSXLS)AssqUa_~2Q`&H+T?w;%L%=K zu|C;7riD5Syhqdq(r<@7VHoaa?>n87VLxK!RStpmw z&4b+Mlg&E{zSBM_e-3cCR2H7UR_|oaT5xdcu%=(hbF}>W*-qvFO+#tG{r6kC%85>a zt~>M;#a+)I+vVe;xo2X~({%M%+O_kU7p({cEm}IwMp5_Rjf|wz-F7{K{$=hj-kFzY z3?0Z%EPwdo)Deoxz1%Qbh4m5f)Tr)A{o8aQZdTidWuEl4P9=}>l`p4QI3xHZ_OD!{68(N*uh+(AvgXUC;f s7HiWyg1r@UhdC!BD`~w|zQX55n4ybo`c{@dNo+fq$jEH`_Wxt}AAtP4;{X5v literal 0 HcmV?d00001 diff --git a/doc/ASxxxx Cross Assemblers.htm b/doc/ASxxxx Cross Assemblers.htm new file mode 100755 index 00000000..e97d02b6 --- /dev/null +++ b/doc/ASxxxx Cross Assemblers.htm @@ -0,0 +1,90 @@ + + +ASxxxx Cross Assemblers + + + +

ASxxxx Cross Assemblers

+

ASxxxx Cross Assemblers, Version 3.11, January 2002 
+
+Submitted by Alan R.  Baldwin, 
+Kent State University, Kent, Ohio 
+
+Operating System:  MS-DOS, Windows, Linux 
+or other supporting K&R C.  
+
+Source Langauge:  C 
+
+Abstract:  
+
+   The  ASxxxx  assemblers are a series of microprocessor assem-
+blers written in the C programming  language.   This  collection
+contains cross assemblers for the 6800(6802/6808), 6801(hd6303),
+6804,  6805,  68HC08,  6809,  68HC11,  68HC12,   68HC16,   8051,
+8085(8080),  z80(hd64180),  GameBoy(Z80),  H8/3xx,  DS8xCxxx and
+6500  series  microprocessors.   Each  assembler  has  a  device
+specific  section  which includes:  (1) device description, byte
+order, and file extension information, (2) a table of  assembler
+general  directives, special directives, assembler mnemonics and
+associated operation codes, (3) machine specific code  for  pro-
+cessing  the  device  mnemonics,  addressing  modes, and special
+directives.  
+
+   The assemblers have a common device independent section which
+handles the details of file input/output, symbol  table  genera-
+tion,  program/data  areas,  expression  analysis, and assembler
+directive processing.  
+
+   The  assemblers  provide  the following features:  (1) alpha-
+betized, formatted symbol table listings, (2) relocatable object
+modules, (3) global symbols for linking object modules, (4) con-
+ditional assembly directives, (5) reusable  local  symbols,  and
+(6) include-file processing.  
+
+   The  companion program ASLINK is a relocating linker perform-
+ing the following functions:  (1) bind multiple  object  modules
+into  a  single  memory  image,  (2) resolve inter-module symbol
+references,  (3)  resolve  undefined  symbols   from   specified
+librarys of object modules, (4) process absolute, relative, con-
+catenated, and overlay attributes in data and program  sections,
+(5)  perform  byte and word program-counter relative (pc or pcr)
+addressing calculations, (6) define absolute  symbol  values  at
+link  time, (7) define absolute area base address values at link
+time, (8) produce Intel Hex or Motorola S  record  output  file,
+(9)  produce  a  map of the linked memory image, and (10) update
+the ASxxxx assembler listing files with the absolute linked  ad-
+dresses and data.  
+
+   The  assemblers  and  linker  have  been  tested using Linux,
+DJGPP,  Cygwin-1.3.x,  Sun   Solaris   (GCC),   Symantec   C/C++
+V6.1/V7.2,  and VC6 with MS-DOS/Windows 3.x/9x/NT/2000/XP.  Com-
+plete source code  and  documentation  for  the  assemblers  and
+linker  is  included  with the distribution.  Additionally, test
+code for each assembler and several  microprocessor  monitors  (
+ASSIST05  for  the  6805,  MONDEB and ASSIST09 for the 6809, and
+BUFFALO 2.5 for the 6811) are included as  working  examples  of
+use of these assemblers.  
+

+

+

+... View documentation for the ASxxxx Assemblers and Linker

+

+... Recent updates to the ASxxxx Assemblers and Linker

+

+... Get the "ASxxxx Cross Assemblers"

+

+... Reported Bugs / Fixes / ...

+

... +About the Author

+

... Home +Page

diff --git a/doc/ASxxxx Cross Assemblers_files/bug.gif b/doc/ASxxxx Cross Assemblers_files/bug.gif new file mode 100755 index 0000000000000000000000000000000000000000..f0dde00446e07842d53de280dc9bcfe8f8cc7d89 GIT binary patch literal 1536 zcmZ?wbhEHbRA5kG_|5^0u@5fzNF{orPPznnxePfa44jno2&2r&u2&Qa`!&B zO1+*LpAIxmVViz!&&!L;uTE6Xuj{G0py|;ozPw5#v~@q zXdc`e5TB+R8K!z+m+f4s8^6upgdTD&v=YrRFFe1mS#bZ+onaedHu9D_eUlW^J$9=5 zbDWB0(dLYkoc7WYGPmAmEM@lH?e_P>I{(v)j6dn@*tz7=wA!s=dNKkG*25<9Mm<7K G2mk;fK6|eK literal 0 HcmV?d00001 diff --git a/doc/ASxxxx Cross Assemblers_files/home.gif b/doc/ASxxxx Cross Assemblers_files/home.gif new file mode 100755 index 0000000000000000000000000000000000000000..48e92ec3c4feb21f45d4702bc44d7ac2d0f1ca07 GIT binary patch literal 1536 zcmZ?wbhEHb)L_tH_|5lCW#h)yUAYmPlvq5=+f#V;;e@+>X4GRu7bFe@1KCwa3sfPQ%>x}qd6`*leozmWg8J1}VX0QKT%ifq*C!laCsQrh z5VajCkWvg%QD4cn&w`1#D`yCZiUu~7xvi|72MrMAtuBrKVI~#<KzxeBQND_0(<$q6T&7Ldl&OFa2(jR_4V})@y4=ew{ClTdx!SyBWr%$Z@Pb=nOpqd z_N1&6``WeTciD$2(;k+2mAeEC-nIf0T%)GedK+R8vHFJJm zdh9#LqIA}i$jOiW7dW)msbq;TT$v+Oo| z&bO02{Y5)!Yr)cOybYgq?`)Nx8Md_g+w0hkPG8@xef|C2fjz0_Ob@cf3%rhmh#Kqh zm_A9~G*MNUkL$oE#$LmZoMu)#H>X}G68^m;+e#&?f3dZm+25+{wE0fX(|dZW*W}L9 rY3>fwt0S^dHSE7xUbEJV`%`^@U)_Ew0jJhLJ+^jygEb?A!o(+wEgRo@6d ccibIs9<^o7&dtxyFL18r<6y7``GODt073nCNdN!< literal 0 HcmV?d00001 diff --git a/doc/ASxxxx Cross Assemblers_files/notes.gif b/doc/ASxxxx Cross Assemblers_files/notes.gif new file mode 100755 index 0000000000000000000000000000000000000000..47254e6ca52d8e203bd1425f5ca6f9029669db89 GIT binary patch literal 1536 zcmZ?wbhEHbRA5kG_|5dm!9s_VcsEgbK=6Yvn~7=E&2Ir z{`vV1wTD;=6jc1DGJMdC-StKN@MOlmZ#-UKSK7}uj`d18b@ipoB8DY>EDl>=1z5Jtf;4*>xERGeD? literal 0 HcmV?d00001 diff --git a/doc/ASxxxx Cross Assemblers_files/questn.gif b/doc/ASxxxx Cross Assemblers_files/questn.gif new file mode 100755 index 0000000000000000000000000000000000000000..79220a5dc2014a01de5b6e2e1839b4e4369e3397 GIT binary patch literal 1024 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 ir9$7WR@x?>_H=V;M_hgpo@r zipvn$(oI*i(NsjT(|v!h{*2%Kem>9heb4ip^F8N0pXa=`1RFymPj{RVETMpb^2;c{ zh=PqMlvWI*t!3S_6p95{SO5hD3+xNsFqDEZ1tZL`1jRxgc;Fi)832ap2~i{li{trkG}J!Xj5b)qoJ-%mD;WNJ#7?QD}hh142j9_kdIZ@)SEW ziq-(q4u~Eg{V3`Q$WE{v1tb)^3s`bd^a&vIfJg#z0FXRDM8OhAipSx^?6DJ4r1&;U zfq}^j%z6L|K$HL!fGGw7F0gYB%aAT}Hhh97Kv;-ZJMfzWVznU!$FT|kVv3@{B#I1p zBw*8&8$r3%ktz?8{f<=4ESv=J?c~AYyy@zgr=A1qNnZeoILH1tXAR}fP%8Z_HV3DX z2G9!739yXQ-~j6`04L75fvl{~R-fXd8i-a+ioV7K{*QsK&C=Y*FV=@B9NehD#+v{EEF&n5uc1GQ7ucb4ic?e6M%^w)%){3f|8-qbCvcQgThf^X zhm)lVb){VyO3pXeIdzO@cQm~NT?p*5-dw|Qp0qA@d0*ka2%){i`ig-}iwqSH;~y3M zF^(m~d@0w$Vdimm;G6CUrgM>fTk`bE@Y$gos6(9y}cnYZ~SD0M9I!AjGxgCD8StntV<`+zHjs7G_mTyWplnViRuP;_K~mt?Op z;3pHl_=Y-;tm#!aMBTtCy-Rq_(3J^R+FMZ+EEw7N@`|HThS-VqL&;gchguuDL>WGW+athDWxla zOGAn*f1aSyR2p&gno%C@>|w%0vb$F{Q83`we zo@G_UuFuSTSya3bU$oCqrLy3s_ZPQ{)p!p=+tvATJT&AeS8)_ngPiJL8jrK&ar#bt zz^nhN+AXP61dcOoosud!upMek+qz9XPkaOgD(A?@l+@5I&_Dq?2J+gV#>YRc|t$Njb^f!rxodW@;&|m9nG6N2}9M>rMUO zt{I)dPNjRn3&W!Y!F8vQKc}=ovoAU${L%2eONu^3xDz4(et zZyvlI7*AYYc;(mky6=sS^Eckahx?~Pqb+m_dG_oQ%kE*BP5nq4(tlYy*rgF$wkLb@ zG{62+%d+_OwcdY){U9E=`cE5Hd$woZRmzbx$XcJdlO2-x(Sbu$Hr7dLCOeAJ>? zn~Jxic3ia#3vR5Zv*7a4x^{NRy>kiyUQfOJ&E_9j#TZOEZY#GItF%}1krkGmYWIJ% zJ;yi2cm3^r_e8tG;J2jacsc1#30tdUwaHtfCBGZetWWhO+BAR3l)0o=Hnw{%?a%}7 zl`3xQp~;fey{jdmJVqR1Y-L(v&&P?KD-F9>t;lKi*X2=;xLr=VmBV1EN;!wns5O^C zUmsQSJ0VUin7eH+_FUxxx!g^tH-nZm!TR^&9WSXLS)AssqUa_~2Q`&H+T?w;%L%=K zu|C;7riD5Syhqdq(r<@7VHoaa?>n87VLxK!RStpmw z&4b+Mlg&E{zSBM_e-3cCR2H7UR_|oaT5xdcu%=(hbF}>W*-qvFO+#tG{r6kC%85>a zt~>M;#a+)I+vVe;xo2X~({%M%+O_kU7p({cEm}IwMp5_Rjf|wz-F7{K{$=hj-kFzY z3?0Z%EPwdo)Deoxz1%Qbh4m5f)Tr)A{o8aQZdTidWuEl4P9=}>l`p4QI3xHZ_OD!{68(N*uh+(AvgXUC;f s7HiWyg1r@UhdC!BD`~w|zQX55n4ybo`c{@dNo+fq$jEH`_Wxt}AAtP4;{X5v literal 0 HcmV?d00001 diff --git a/doc/Betriebssystem UNIX - Literatur.htm b/doc/Betriebssystem UNIX - Literatur.htm new file mode 100755 index 00000000..1c73caa7 --- /dev/null +++ b/doc/Betriebssystem UNIX - Literatur.htm @@ -0,0 +1,618 @@ + + +Betriebssystem UNIX - Literatur + + + +
+ + + +
  +

9 Literatur und Anhang

+

9.1 Literatur

+

Diese Literaturliste bietet nur eine kleine Auswahl + aus einer großen Zahl von UNIX-Büchern:

+

Rainer Krienke:
UNIX für + Einsteiger
Hanser-Verlag

+

Peter Kuo:
UNIX Kompendium
Verlag Markt + & Technik

+

Arne Burmeister:
Der Einstieg un + UNIX
Hanser-Verlag

+

Levine/Young:
UNIX für + Anfänger
iwt-Verlag

+

Abrahams/Larson:
UNIX for the Impatient +
Verlag Addison-Wesley

+

Nemeth/Snyder/Seebass:
Systemadministration + unter UNIX
Verlag Prentice-Hall

+

Aeleen Frisch:
Essential System + Administration
Verlag O'Reilly

+

Helmut Herold:
UNIX-Grundlagen
Verlag + Addison-Wesley

+

Helmut Herold:
UNIX-Shells
Verlag + Addison-Wesley

+

Rainer Krienke:
UNIX + Shell-Programmierung
Hanser-Verlag

+

Rosen/Rosinski/Faber:
UNIX System V Rel. + 4
tewi-Verlag

+

Boss/Reimann:
UNIX System V
bhv + Verlag

+

Jessica Perry Hekman:
LINUX in a + Nutshell
Verlag O'Reilly

+

Garfinkel/Spafford:
Practical UNIX + Security
Verlag O'Reilly

+

Zu einzelnen Spezialthemen (TCP/IP, DNS, sendmail, + termcap, Internet-Server, etc.) gibt es eine breite Buchpalette vom Verlag + O'Reilly. Die Bücher sind teilweise in deutscher Sprache, teils im + englischen Original lieferbar.

+

+

9.2 Erfinder von UNIX und C geben zu: Alles + Quatsch!

+

In einer Ankündigung, die die Computerindustie + verblüffte, haben Ken Thompson. Dennis Ritchie und Brian Kernighan + zugegeben, daß das von ihnen geschaffene Betriebsystem Unix und die + Programmiersprache C ein raffinierter Aprilscherz sind, der sich über 20 + Jahre am Leben erhalten hat. Bei einem Vortrag vor dem letzten + UnixWorld-Software-Entwicklungsforum enthüllte Thompson:

+

"1969 hatte AT&T gerade die Arbeit am + GE/Honeywell/AT&T-Multics-Projekt beendet. Brian und ich + experimentierten zu diesem Zeitpunkt mit einer frühen Pascal-Version von + Professor Niklaus Wirth vom ETH-Laboratorium in der Schweiz und waren + beeindruckt von seiner Einfachheit und Mächtigkeit. Dennis hatte gerade + "Der Herr der Klinge" gelesen, eine spöttische Parodie auf Tolkiens + Trilogie "Der Herr der Ringe". Im Übermut beschlossen wir, Parodien zur + Multics-Umgebung und zu Pascal zu verfassen. Dennis und ich waren für die + Betriebsystemumgebung verantwortlich. Wir sahen uns Multics an und + entwarfen ein neues System, das so komplex und kryptisch wie möglich sein + sollte, um die Frustation der gelegentlichen User zu maximieren. Wir + nannten es "Unix" in Anspielung auf "Multics" und fanden es auch nicht + gewagter als andere Verballhornungen. Danach entwickelten Dennis und Brian + eine wirklich perverse Pascal-Version namens "A". Als wir bemerkten, daß + einige Leute tatsächlich versuchten, in "A" zu programmmieren, fügten wir + schnell einige zusätzliche Fallstricke hinzu und nannten es "B", "BCPL" + und schließlich "C". Wir hörten damit auf, als wir eine saubere + Uebersetzung der folgenden Konstruktion erhielten:


+
+ for(;P("\n"),R--;P("|"))
+
+ for(e=C;e--;P("_"+(*u++/8)%2)) 
+
+ P("|"+(*u/4)%2)
+
+
+

Der Gedanke, daß moderne Programmierer eine Sprache + benutzen würden, die solch eine Anweisung zuließ, lag jenseits unseres + Vorstellungsvermögens. Wir dachten allerdings daran, alles den Sowjets zu + verkaufen, um ihren Computerfortschritt 20 Jahre und mehr zu behindern. + Unsere Ueberraschung war groß, als dann AT&T und andere US-Unternehmen + tatsächlich begannen, Unix und C zu verwenden! Sie haben 20 weitere Jahre + gebraucht, genügend Erfahrungen zu sammeln, um einige bedeutungslose + Programme in C zu entwickeln, und das mit einer Parodie auf die Technik + der 60er Jahre! Dennoch sind wir beeindruckt von der Hartnäckigkeit (falls + nicht doch Gemeinsinn) des gewöhnlichen Unix-und C-Anwenders. Jedenfalls + haben Brian, Dennis und ich in den letzten Jahren nur in Pascal und einem + Apple Macintosh programmiert und wir fühlten uns echt schuldig an dem + Chaos, der Verwirrung und dem wirklich schlechten Programmierstil, der von + unserem verückten Einfall vor so langer Zeit ausging."

+

Namhafte Unix- und C-Anbieter und Benutzer, + einschließlich AT&T, Microsoft, Hewlett-Packard, GTE, NCR und DEC + haben vorläufig jede Stellungnahme abgelehnt. Borland International, ein + führender Anbieter von Pascal- und C-Werkzeugen, einschließlich der + polulären Turbo Pascal, Turbo C und Turbo C++, meinte, sie hätten diesen + Verdacht schon seit Jahren gehegt und würden nun dazu übergehen, ihre + Pascal-Produkte zu verbessern und weitere Bemühungen um die C-Entwicklung + stoppen. Ein IBM-Sprecher brach in unkontrolliertes Gelächter aus. +

+

(Quelle: Bernhard L. Hayes, NetNews-Gruppe) +

+

+

9.3 The UNIX Acrony List

+

Compiled by Wolfram Roesler +
Additional contributions by:

+
+

Marcel Waldvogel + <Marcel.Waldvogel@nice.usergroup.ethz.ch>
Martin P. Ibert + <martini@heaven7.in-berlin.de>
Oliver Laumann + <net@cs.tu-berlin.de>
Peter Funk + <pf@artcom0.north.de>
Volker Lausch + <volli@cs.tu-berlin.de>
Ulf Moeller + <um@ulf.mali.sub.org>
Stefan Stapelberg + <stefan@rent-a-guru.de>
Christopher J. Calabrese + <cjc@ulysses.att.com>
Chris Siebenmann + <cks@hawkwind.utcs.toronto.edu>
Casper H.S. Dik + <casper@fwi.uva.nl>
Ken Keys <kkeys@ucsd.edu>
Peter da + Silva <peter@nmti.com>
Michael P Urban + <urban@sideshow.jpl.nasa.gov>
Drew Sullivan + <drew@lethe.hades.gts.org>

+

Last change: 01-Jun-93
All comments are + welcome.
All mail comments are subject to be included in the list + without further asking for permission. Please include a note if you + object. Does not include names that are no abbreviations, like `basename' + or `sort'. "?" indicates guesses. Types:

+

C command
B shell built-in
D directory
E + shell/environment variable
S special file
O other


+
+NAME    TYPE    MEANING
+
+------- ------- ------------------------------------------------------------
+
+adb       C       algol _or_ absolute _or_ assembly _or_ advanced debugger
+
+ar        C       archiver
+
+as        C       assembler
+
+awk       C       Aho, Weinberger, Kernighan (program authors)
+
+bash      C       Bourne again shell ("born again shell")
+
+bin       D       binaries
+
+bsh       C       Bourne shell (program author)
+
+bc        C       better calculator
+
+c89       C       1989 Ansi-C compiler
+
+cal       C       calender
+
+cat       C       concatenate
+
+cc        C       C compiler
+
+cd        B       change directory
+
+chgrp     C       change group
+
+chmod     C       change mode
+
+chown     C       change owner
+
+ci        C       check in
+
+cmp       C       compare
+
+co        C       check out
+
+cp        C       copy
+
+cpio      C       copy (archive files) in and out
+
+cpp       C       C pre-processor
+
+cron      C       Chronos (greek god)
+
+csh       C       C shell
+
+...d      C       daemon (e.g. inetd = internet daemon)
+
+dbx       C       extended debugger (?) _or_ dbx (=extended decibel, noise reduction system)
+
+dc        C       desk caculator
+
+dd        C       (opinion 1) Dataset Definition (named after the OS/3x0 JCL DD command
+
+                  who's syntax it also ripped off as a joke)
+
+dd        C       (opinion 2) copy and convert (called `dd' because `cc' is the   C compiler)
+
+dd        C       (opinions 3-n) data, device, disk, dump in various combinations
+
+dev       D       devices
+
+df        C       disk free
+
+diff      C       difference
+
+dirname   C       directory name
+
+du        C       disk usage
+
+ed        C       editor
+
+egrep     C       extended grep
+
+elm       C       electronic mail
+
+emacs     C       editing macros
+
+                  Sometimes: Eight megabytes and constantly swapping
+
+                  _or_: Escape Meta Alternate Control Shift
+
+                  _or_: Emacs makes any computer slow
+
+env       B       environment
+
+eqn       C       equation
+
+esac      B       case (reversed)
+
+etc       D       et cetera
+
+ex        C       extended editor (?)
+
+expr      C       expression
+
+fd        S       floppy disk
+
+fd        D       file descriptors (as in /dev/fd)
+
+fgrep     C       fixed-string grep
+
+fi        B       if (reversed)
+
+fmt       C       format
+
+fsck      C       file system check
+
+ftp       C       file transfer protocol
+
+g...      C       GNU (e.g. gawk = GNU awk) (GNU = "GNU is not Unix")
+
+getty     C       get tty
+
+grep      C       global regular expression print (from the ed subcommand "g/RE/p"
+
+                  where RE is a regular expression)
+
+hd        S       hard disk
+
+id        C       identity
+
+IFS       E       internal field seperators
+
+inode     O       index (or indirection) node
+
+irc       C       internet relay chat
+
+jsh       C       job-control shell
+
+kmem      S       kernel memory
+
+ksh       C       Korn shell (program author)
+
+LANG      E       language
+
+ld        C       link editor _or_ loader
+
+lex       C       lexical analyser
+
+lib       D       library
+
+ln        C       link
+
+lp        S       line printer
+
+lpp       D       licensed program products
+
+lpq       C       (display) line printer queue
+
+lpr       C       line print
+
+ls        C       list
+
+mem       S       memory
+
+mkfs      C       make file system
+
+mv        C       move
+
+mvdir     C       move directory
+
+nawk      C       new awk
+
+nfs       O       network file system
+
+                  _or_: nightmare file system
+
+nm        C       names
+
+nn        C       no news
+
+nohup     C       no hang-up
+
+nroff     C       new roff (roff = program's ancestor)
+
+od        C       octal dump
+
+passwd    C       password
+
+pcc       C       portable C compiler
+
+pg        C       pager
+
+pr        C       prepare (for printing)
+
+ps        C       process status
+
+PS1       E       prompt string 1 (same for PS2 etc.)
+
+pty       S       pseudo teletype
+
+pwd       C       print work directory
+
+qdaemon   C       queue daemon
+
+r...      S       raw (e.g. rfd0 = raw floppy disk 0)
+
+r...      C       remote (e.g. rsh = remote shell)
+
+rm        C       remove
+
+rmdir     C       remove directory
+
+rmt       S       raw magnetic tape
+
+rmt       C       remote magnetic tape
+
+roff      C       run-off (similar program)
+
+sdb       C       symbolic debugger
+
+sed       C       stream editor
+
+sh        C       (Bourne) shell
+
+stty      C       set tty
+
+su        C       superuser
+
+tar       C       tape archive(r)
+
+tbl       C       table
+
+tcsh      C       Tenex C shell
+
+tee       C       T pipe fitting (plumbing device)
+
+telnet    C       telephone network
+
+tex       C       tau epsilon chi
+
+tmp       D       temporary
+
+tr        C       translate
+
+troff     C       typesetter roff
+
+tsh       C       trusted shell
+
+tty       S       teletype
+
+TZ        E       time zone
+
+rcp       C       remote copy
+
+rcs       C       revision control system
+
+rlogin    C       remote login
+
+rm        C       remove
+
+rmdir     C       remove directory
+
+rsh       C       remote shell _or_ restricted shell (sometimes Rsh)
+
+sccs      O       source code control system
+
+termcap   D       terminal capability
+
+terminfo  D       terminal information
+
+u         D       user
+
+ucb       D       University of California at Berkeley
+
+uniq      C       unique
+
+usr       D       user
+
+uucp      C       unix-to-unix copy
+
+vi        C       visual (from the ex subcommand "vi" that switches into visual mode)
+
+wall      C       write all
+
+wc        C       word count
+
+xargs     C       extended arguments
+
+yacc      C       yet another compiler compiler
+
+yp        O       yellow pages
+
+
+

+

9.4 The ABCs of Unix

+

A is for Awk, which runs like a snail, and
B is for + Biff, which reads all your mail.

+

C is for CC, as hackers recall, while
D is for DD, + the command that does all.

+

E is for Emacs, which rebinds your keys, and
F is + for Fsck, which rebuilds your trees.

+

G is for Grep, a clever detective, while
H is for + Halt, which may seem defective.

+

I is for Indent, which rarely amuses, and
J is for + Join, which nobody uses.

+

K is for Kill, which makes you the boss, while
L is + for Lex, which is missing from DOS.

+

M is for More, from which Less was begot, and
N is + for Nice, which it really is not.

+

O is for Od, which prints out things nice, while
P + is for Passwd, which reads in strings twice.

+

Q is for Quota, a Berkeley-type fable, and
R is for + Ranlib, for sorting ar [sic] table.

+

S is for Spell, which attempts to belittle, while
T + is for True, which does very little.

+

U is for Uniq, which is used after Sort, and
V is + for Vi, which is hard to abort.

+

W is for Whoami, which tells you your name, while
X + is, well, X, of dubious fame.

+

Y is for Yes, which makes an impression, and
Z is + for Zcat, which handles compression.

+

+

9.5 vi Short Quick Reference Guide


+
+Getting Started                     Commands
+
+
+
+vi filename    - normal mode         - return to command mode
+
+vedit filename - user friendly edit
+
+                                     Inserting
+
+
+
+Saving and Quiting                       o  - insert a line after cursor
+
+                                         O  - insert a line before cursor
+
+ZZ  - save and exit                      i  - insert test at cursor
+
+:w  - save without exiting               a  - insert text after cursor
+
+:w! - save write protected file          I  - insert text at start of line
+
+:q  - quit editor                        A  - insert test at eol
+
+:q! - quit without saving
+
+                                     Deleting 
+
+
+
+                                         dd - delete current line
+
+Cursor Movement                           x - delete char at cursor
+
+                                          X - delete char before cursor
+
+         k                               dw - delete word
+
+         ^                                D - erase from cursor to eol
+
+      h <> l
+
+         v                           Replacing / Changing
+
+         j
+
+                                          R - replace till eol
+
+Moving About                              r - replace one character
+
+                                          C - change all text after cursor
+
+ f  - page forward                 cw - change a word
+
+ b  - page back
+
+ d  - 1/2 page forward         Moving Text
+
+ u  - 1/2 page back
+
+       w  - next word                To move n lines of text from A to B
+
+       b  - previous word                 1. move cursor to A
+
+       $  - end of line                   2. ndd - delete n lines
+
+       ^  - start of line (shift 6)       3. move cursor to B
+
+       G  - go to end of file             4. P - pull text in after cursor
+
+       1G - go to beginning of file          p - pull text in before cursor
+
+       nG - go to nth line
+
+ g  - show position in file     Copying Text
+
+
+
+Searching                             To copy n lines of text from A to B
+
+                                           1. move cursor to A
+
+ /abc - search for string "abc"            2. nyy - yank n lines
+
+    n - find next occurrence               3. move cursor to B
+
+    N - find previous occurrence           4. P - pull text in after cursor
+
+                                              p - pull text in before cursor
+
+
+
+                               Useful commands
+
+
+
+                         . - repeat last command
+
+                         u - undo last command
+
+                         U - undo changes made to current line
+
+                         J - join the next line to the current line
+
+
+
+           :1,$s/old/new/g - global search and replace old with new *
+
+           :.,$d           - delete from current line to eof
+
+           :r filename     - read filename into this vi buffer
+
+           :n,mw filename  - write lines n through m to filename
+
+
+
+* special characters prefix with \ (backslash)
+
+
+

+

9.6 An amusing photo

+

Here's a publicity photo from about 1972, showing Ken + Thompson and me (Dennis Ritchie) in front of a PDP-11 with two Teletype 33 + terminals. In front, we have Ken (sitting) and me (standing), both with + more luxuriant and darker hair than we have now.

+

Ken and Dennis by PDP-11 +

+

From the right, the major items of equipment are + +

    +
  • At the far right, on the table, are what someone + discerned was a VT01A storage-tube display (based on Tek 611) and a + small keyboard for it. Slightly hard to make out. +
  • A main CPU cabinet, partly behind the table. The + processor is a PDP-11/20; it must have been our second one, with the + Digital Special Systems KS-11 memory management unit. The very first + just said "PDP11," not "11/20." The arrays of distorted rectangles above + it and in other cabinets are the labels on DECtape canisters. +
  • Another cabinet with DECtape drive at the top. + Careful examination of the image by Steve Westin detects the top of the + bezel of an 11/45 CPU just peeking above the TTY that Ken is typing at. + The paper tape reader is above. +
  • A cabinet with another DECtape drive, probably also + containing BA-11 extension boxes within. +
  • A cabinet with RK03 disk drives. These were made by + Diablo (subsumed by Xerox) and OEMed to Digital. Digital later began + manufacturing their own version (RK05). +
  • A cabinet probably containing RF11/RS11 controller + and fixed-head disks. +
  • On top of the machine are what look like magtapes. + A probable TU10 transport is barely visible just below Ken's chin, at + least if you have the monitor brightness and contrast adjusted + favorably.
+

Das Letzte: UNIX-Camping

+

( unzip; strip; touch; finger; mount; gasp; yes; + umount; sleep )

+

 

+

Zum + Inhaltsverzeichnis

+

diff --git a/doc/Betriebssystem UNIX - Literatur_files/kd14.jpg b/doc/Betriebssystem UNIX - Literatur_files/kd14.jpg new file mode 100755 index 0000000000000000000000000000000000000000..23e20dc0985ff742fbf85939bb0a1974ca366194 GIT binary patch literal 79006 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%0DHh&Xx(@#GNfQ)&T;iKZX)-%7qR_f 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 literal 0 HcmV?d00001 diff --git a/doc/C-history.htm b/doc/C-history.htm new file mode 100755 index 00000000..5d55400b --- /dev/null +++ b/doc/C-history.htm @@ -0,0 +1,1221 @@ + + +C-history + + + +
+ + + +
  +

The Development of the C Language*

+
+
Dennis M. Ritchie
Bell Labs/Lucent + Technologies
Murray Hill, NJ 07974 + USA


dmr@bell-labs.com
+
+
+

ABSTRACT

+

The C programming language was devised in the early + 1970s as a system implementation language for the nascent Unix operating + system. Derived from the typeless language BCPL, it evolved a type + structure; created on a tiny machine as a tool to improve a meager + programming environment, it has become one of the dominant languages of + today. This paper studies its evolution.

+

Introduction

+
+
+
NOTE: *Copyright 1993 Association for Computing + Machinery, Inc. This electronic reprint made available by the author as + a courtesy. For further publication rights contact ACM or the author. + This article was presented at Second History of Programming Languages + conference, Cambridge, Mass., April, 1993. +
+


This paper is about the development of the C + programming language, the influences on it, and the conditions under which + it was created. For the sake of brevity, I omit full descriptions of C + itself, its parent B [Johnson 73] and its grandparent BCPL [Richards 79], + and instead concentrate on characteristic elements of each language and + how they evolved.

+

C came into being in the years 1969-1973, in parallel + with the early development of the Unix operating system; the most creative + period occurred during 1972. Another spate of changes peaked between 1977 + and 1979, when portability of the Unix system was being demonstrated. In + the middle of this second period, the first widely available description + of the language appeared: The C Programming Language, often called + the `white book' or `K&R' [Kernighan 78]. Finally, in the middle + 1980s, the language was officially standardized by the ANSI X3J11 + committee, which made further changes. Until the early 1980s, although + compilers existed for a variety of machine architectures and operating + systems, the language was almost exclusively associated with Unix; more + recently, its use has spread much more widely, and today it is among the + languages most commonly used throughout the computer industry.

+

History: the setting

+

The late 1960s were a turbulent era for computer + systems research at Bell Telephone Laboratories [Ritchie 78] [Ritchie 84]. + The company was pulling out of the Multics project [Organick 75], which + had started as a joint venture of MIT, General Electric, and Bell Labs; by + 1969, Bell Labs management, and even the researchers, came to believe that + the promises of Multics could be fulfilled only too late and too + expensively. Even before the GE-645 Multics machine was removed from the + premises, an informal group, led primarily by Ken Thompson, had begun + investigating alternatives.

+

Thompson wanted to create a comfortable computing + environment constructed according to his own design, using whatever means + were available. His plans, it is evident in retrospect, incorporated many + of the innovative aspects of Multics, including an explicit notion of a + process as a locus of control, a tree-structured file system, a command + interpreter as user-level program, simple representation of text files, + and generalized access to devices. They excluded others, such as unified + access to memory and to files. At the start, moreover, he and the rest of + us deferred another pioneering (though not original) element of Multics, + namely writing almost exclusively in a higher-level language. PL/I, the + implementation language of Multics, was not much to our tastes, but we + were also using other languages, including BCPL, and we regretted losing + the advantages of writing programs in a language above the level of + assembler, such as ease of writing and clarity of understanding. At the + time we did not put much weight on portability; interest in this arose + later.

+

Thompson was faced with a hardware environment cramped + and spartan even for the time: the DEC PDP-7 on which he started in 1968 + was a machine with 8K 18-bit words of memory and no software useful to + him. While wanting to use a higher-level language, he wrote the original + Unix system in PDP-7 assembler. At the start, he did not even program on + the PDP-7 itself, but instead used a set of macros for the GEMAP assembler + on a GE-635 machine. A postprocessor generated a paper tape readable by + the PDP-7.

+

These tapes were carried from the GE machine to the + PDP-7 for testing until a primitive Unix kernel, an editor, an assembler, + a simple shell (command interpreter), and a few utilities (like the Unix + rm, cat, cp commands) were completed. After this point, the + operating system was self-supporting: programs could be written and tested + without resort to paper tape, and development continued on the PDP-7 + itself.

+

Thompson's PDP-7 assembler outdid even DEC's in + simplicity; it evaluated expressions and emitted the corresponding bits. + There were no libraries, no loader or link editor: the entire source of a + program was presented to the assembler, and the output file­with a + fixed name­that emerged was directly executable. (This name, + a.out, explains a bit of Unix etymology; it is the output of the + assembler. Even after the system gained a linker and a means of specifying + another name explicitly, it was retained as the default executable result + of a compilation.)

+

Not long after Unix first ran on the PDP-7, in 1969, + Doug McIlroy created the new system's first higher-level language: an + implementation of McClure's TMG [McClure 65]. TMG is a language for + writing compilers (more generally, TransMoGrifiers) in a top-down, + recursive-descent style that combines context-free syntax notation with + procedural elements. McIlroy and Bob Morris had used TMG to write the + early PL/I compiler for Multics.

+

Challenged by McIlroy's feat in reproducing TMG, + Thompson decided that Unix­possibly it had not even been named + yet­needed a system programming language. After a rapidly scuttled + attempt at Fortran, he created instead a language of his own, which he + called B. B can be thought of as C without types; more accurately, it is + BCPL squeezed into 8K bytes of memory and filtered through Thompson's + brain. Its name most probably represents a contraction of BCPL, though an + alternate theory holds that it derives from Bon [Thompson 69], an + unrelated language created by Thompson during the Multics days. Bon in + turn was named either after his wife Bonnie, or (according to an + encyclopedia quotation in its manual), after a religion whose rituals + involve the murmuring of magic formulas.

+

Origins: the languages

+

BCPL was designed by Martin Richards in the mid-1960s + while he was visiting MIT, and was used during the early 1970s for several + interesting projects, among them the OS6 operating system at Oxford [Stoy + 72], and parts of the seminal Alto work at Xerox PARC [Thacker 79]. We + became familiar with it because the MIT CTSS system [Corbato 62] on which + Richards worked was used for Multics development. The original BCPL + compiler was transported both to Multics and to the GE-635 GECOS system by + Rudd Canaday and others at Bell Labs [Canaday 69]; during the final throes + of Multics's life at Bell Labs and immediately after, it was the language + of choice among the group of people who would later become involved with + Unix.

+

BCPL, B, and C all fit firmly in the traditional + procedural family typified by Fortran and Algol 60. They are particularly + oriented towards system programming, are small and compactly described, + and are amenable to translation by simple compilers. They are `close to + the machine' in that the abstractions they introduce are readily grounded + in the concrete data types and operations supplied by conventional + computers, and they rely on library routines for input-output and other + interactions with an operating system. With less success, they also use + library procedures to specify interesting control constructs such as + coroutines and procedure closures. At the same time, their abstractions + lie at a sufficiently high level that, with care, portability between + machines can be achieved.

+

BCPL, B and C differ syntactically in many details, + but broadly they are similar. Programs consist of a sequence of global + declarations and function (procedure) declarations. Procedures can be + nested in BCPL, but may not refer to non-static objects defined in + containing procedures. B and C avoid this restriction by imposing a more + severe one: no nested procedures at all. Each of the languages (except for + earliest versions of B) recognizes separate compilation, and provides a + means for including text from named files.

+

Several syntactic and lexical mechanisms of BCPL are + more elegant and regular than those of B and C. For example, BCPL's + procedure and data declarations have a more uniform structure, and it + supplies a more complete set of looping constructs. Although BCPL programs + are notionally supplied from an undelimited stream of characters, clever + rules allow most semicolons to be elided after statements that end on a + line boundary. B and C omit this convenience, and end most statements with + semicolons. In spite of the differences, most of the statements and + operators of BCPL map directly into corresponding B and C.

+

Some of the structural differences between BCPL and B + stemmed from limitations on intermediate memory. For example, BCPL + declarations may take the form +

+

+
+let P1 be command
+
+and P2 be command
+
+and P3 be command
+
+ ...
+
+
+

where the program text represented by the commands + contains whole procedures. The subdeclarations connected by and + occur simultaneously, so the name P3 is known inside procedure + P1. Similarly, BCPL can package a group of declarations and + statements into an expression that yields a value, for example +

+

+
+E1 := valof $( declarations ; commands ; resultis E2 $) + 1
+
+
+

The BCPL compiler readily handled such constructs by + storing and analyzing a parsed representation of the entire program in + memory before producing output. Storage limitations on the B compiler + demanded a one-pass technique in which output was generated as soon as + possible, and the syntactic redesign that made this possible was carried + forward into C.

+

Certain less pleasant aspects of BCPL owed to its own + technological problems and were consciously avoided in the design of B. + For example, BCPL uses a `global vector' mechanism for communicating + between separately compiled programs. In this scheme, the programmer + explicitly associates the name of each externally visible procedure and + data object with a numeric offset in the global vector; the linkage is + accomplished in the compiled code by using these numeric offsets. B evaded + this inconvenience initially by insisting that the entire program be + presented all at once to the compiler. Later implementations of B, and all + those of C, use a conventional linker to resolve external names occurring + in files compiled separately, instead of placing the burden of assigning + offsets on the programmer.

+

Other fiddles in the transition from BCPL to B were + introduced as a matter of taste, and some remain controversial, for + example the decision to use the single character = for assignment + instead of :=. Similarly, B uses /**/ to enclose + comments, where BCPL uses //, to ignore text up to the end of the + line. The legacy of PL/I is evident here. (C++ has resurrected the BCPL + comment convention.) Fortran influenced the syntax of declarations: B + declarations begin with a specifier like auto or static, + followed by a list of names, and C not only followed this style but + ornamented it by placing its type keywords at the start of declarations. +

+

Not every difference between the BCPL language + documented in Richards's book [Richards 79] and B was deliberate; we + started from an earlier version of BCPL [Richards 67]. For example, the + endcase that escapes from a BCPL switchon statement was + not present in the language when we learned it in the 1960s, and so the + overloading of the break keyword to escape from the B and C + switch statement owes to divergent evolution rather than + conscious change.

+

In contrast to the pervasive syntax variation that + occurred during the creation of B, the core semantic content of + BCPL­its type structure and expression evaluation rules­remained + intact. Both languages are typeless, or rather have a single data type, + the `word,' or `cell,' a fixed-length bit pattern. Memory in these + languages consists of a linear array of such cells, and the meaning of the + contents of a cell depends on the operation applied. The + + operator, for example, simply adds its operands using the machine's + integer add instruction, and the other arithmetic operations are equally + unconscious of the actual meaning of their operands. Because memory is a + linear array, it is possible to interpret the value in a cell as an index + in this array, and BCPL supplies an operator for this purpose. In the + original language it was spelled rv, and later !, while + B uses the unary *. Thus, if p is a cell containing the + index of (or address of, or pointer to) another cell, *p refers + to the contents of the pointed-to cell, either as a value in an expression + or as the target of an assignment.

+

Because pointers in BCPL and B are merely integer + indices in the memory array, arithmetic on them is meaningful: if + p is the address of a cell, then p+1 is the address of + the next cell. This convention is the basis for the semantics of arrays in + both languages. When in BCPL one writes +

+

+
+let V = vec 10
+
+
+

or in B, +

+

+
+auto V[10];
+
+
+

the effect is the same: a cell named V is + allocated, then another group of 10 contiguous cells is set aside, and the + memory index of the first of these is placed into V. By a general + rule, in B the expression +

+

+
+*(V+i)
+
+
+

adds V and i, and refers to the + i-th location after V. Both BCPL and B each add special + notation to sweeten such array accesses; in B an equivalent expression is + +

+

+
+V[i]
+
+
+

and in BCPL +

+

+
+V!i
+
+
+

This approach to arrays was unusual even at the time; + C would later assimilate it in an even less conventional way.

+

None of BCPL, B, or C supports character data strongly + in the language; each treats strings much like vectors of integers and + supplements general rules by a few conventions. In both BCPL and B a + string literal denotes the address of a static area initialized with the + characters of the string, packed into cells. In BCPL, the first packed + byte contains the number of characters in the string; in B, there is no + count and strings are terminated by a special character, which B spelled + `*e'. This change was made partially to avoid the limitation on + the length of a string caused by holding the count in an 8- or 9-bit slot, + and partly because maintaining the count seemed, in our experience, less + convenient than using a terminator.

+

Individual characters in a BCPL string were usually + manipulated by spreading the string out into another array, one character + per cell, and then repacking it later; B provided corresponding routines, + but people more often used other library functions that accessed or + replaced individual characters in a string.

+

More History

+

After the TMG version of B was working, Thompson + rewrote B in itself (a bootstrapping step). During development, he + continually struggled against memory limitations: each language addition + inflated the compiler so it could barely fit, but each rewrite taking + advantage of the feature reduced its size. For example, B introduced + generalized assignment operators, using x=+y to add y to + x. The notation came from Algol 68 [Wijngaarden 75] via McIlroy, + who had incorporated it into his version of TMG. (In B and early C, the + operator was spelled =+ instead of += ; this mistake, + repaired in 1976, was induced by a seductively easy way of handling the + first form in B's lexical analyzer.)

+

Thompson went a step further by inventing the + ++ and -- operators, which increment or decrement; their + prefix or postfix position determines whether the alteration occurs before + or after noting the value of the operand. They were not in the earliest + versions of B, but appeared along the way. People often guess that they + were created to use the auto-increment and auto-decrement address modes + provided by the DEC PDP-11 on which C and Unix first became popular. This + is historically impossible, since there was no PDP-11 when B was + developed. The PDP-7, however, did have a few `auto-increment' memory + cells, with the property that an indirect memory reference through them + incremented the cell. This feature probably suggested such operators to + Thompson; the generalization to make them both prefix and postfix was his + own. Indeed, the auto-increment cells were not used directly in + implementation of the operators, and a stronger motivation for the + innovation was probably his observation that the translation of + ++x was smaller than that of x=x+1.

+

The B compiler on the PDP-7 did not generate machine + instructions, but instead `threaded code' [Bell 72], an interpretive + scheme in which the compiler's output consists of a sequence of addresses + of code fragments that perform the elementary operations. The operations + typically­in particular for B­act on a simple stack machine. +

+

On the PDP-7 Unix system, only a few things were + written in B except B itself, because the machine was too small and too + slow to do more than experiment; rewriting the operating system and the + utilities wholly into B was too expensive a step to seem feasible. At some + point Thompson relieved the address-space crunch by offering a `virtual B' + compiler that allowed the interpreted program to occupy more than 8K bytes + by paging the code and data within the interpreter, but it was too slow to + be practical for the common utilities. Still, some utilities written in B + appeared, including an early version of the variable-precision calculator + dc familiar to Unix users [McIlroy 79]. The most ambitious + enterprise I undertook was a genuine cross-compiler that translated B to + GE-635 machine instructions, not threaded code. It was a small tour de + force: a full B compiler, written in its own language and generating + code for a 36-bit mainframe, that ran on an 18-bit machine with 4K words + of user address space. This project was possible only because of the + simplicity of the B language and its run-time system.

+

Although we entertained occasional thoughts about + implementing one of the major languages of the time like Fortran, PL/I, or + Algol 68, such a project seemed hopelessly large for our resources: much + simpler and smaller tools were called for. All these languages influenced + our work, but it was more fun to do things on our own.

+

By 1970, the Unix project had shown enough promise + that we were able to acquire the new DEC PDP-11. The processor was among + the first of its line delivered by DEC, and three months passed before its + disk arrived. Making B programs run on it using the threaded technique + required only writing the code fragments for the operators, and a simple + assembler which I coded in B; soon, dc became the first interesting + program to be tested, before any operating system, on our PDP-11. Almost + as rapidly, still waiting for the disk, Thompson recoded the Unix kernel + and some basic commands in PDP-11 assembly language. Of the 24K bytes of + memory on the machine, the earliest PDP-11 Unix system used 12K bytes for + the operating system, a tiny space for user programs, and the remainder as + a RAM disk. This version was only for testing, not for real work; the + machine marked time by enumerating closed knight's tours on chess boards + of various sizes. Once its disk appeared, we quickly migrated to it after + transliterating assembly-language commands to the PDP-11 dialect, and + porting those already in B.

+

By 1971, our miniature computer center was beginning + to have users. We all wanted to create interesting software more easily. + Using assembler was dreary enough that B, despite its performance + problems, had been supplemented by a small library of useful service + routines and was being used for more and more new programs. Among the more + notable results of this period was Steve Johnson's first version of the + yacc parser-generator [Johnson 79a].

+

The Problems of B

+

The machines on which we first used BCPL and then B + were word-addressed, and these languages' single data type, the `cell,' + comfortably equated with the hardware machine word. The advent of the + PDP-11 exposed several inadequacies of B's semantic model. First, its + character-handling mechanisms, inherited with few changes from BCPL, were + clumsy: using library procedures to spread packed strings into individual + cells and then repack, or to access and replace individual characters, + began to feel awkward, even silly, on a byte-oriented machine.

+

Second, although the original PDP-11 did not provide + for floating-point arithmetic, the manufacturer promised that it would + soon be available. Floating-point operations had been added to BCPL in our + Multics and GCOS compilers by defining special operators, but the + mechanism was possible only because on the relevant machines, a single + word was large enough to contain a floating-point number; this was not + true on the 16-bit PDP-11.

+

Finally, the B and BCPL model implied overhead in + dealing with pointers: the language rules, by defining a pointer as an + index in an array of words, forced pointers to be represented as word + indices. Each pointer reference generated a run-time scale conversion from + the pointer to the byte address expected by the hardware.

+

For all these reasons, it seemed that a typing scheme + was necessary to cope with characters and byte addressing, and to prepare + for the coming floating-point hardware. Other issues, particularly type + safety and interface checking, did not seem as important then as they + became later.

+

Aside from the problems with the language itself, the + B compiler's threaded-code technique yielded programs so much slower than + their assembly-language counterparts that we discounted the possibility of + recoding the operating system or its central utilities in B.

+

In 1971 I began to extend the B language by adding a + character type and also rewrote its compiler to generate PDP-11 machine + instructions instead of threaded code. Thus the transition from B to C was + contemporaneous with the creation of a compiler capable of producing + programs fast and small enough to compete with assembly language. I called + the slightly-extended language NB, for `new B.'

+

Embryonic C

+

NB existed so briefly that no full description of it + was written. It supplied the types int and char, arrays + of them, and pointers to them, declared in a style typified by +

+

+
+int i, j;
+
+char c, d;
+
+int iarray[10];
+
+int ipointer[];
+
+char carray[10];
+
+char cpointer[];
+
+
+

The semantics of arrays remained exactly as in B and + BCPL: the declarations of iarray and carray create cells + dynamically initialized with a value pointing to the first of a sequence + of 10 integers and characters respectively. The declarations for + ipointer and cpointer omit the size, to assert that no + storage should be allocated automatically. Within procedures, the + language's interpretation of the pointers was identical to that of the + array variables: a pointer declaration created a cell differing from an + array declaration only in that the programmer was expected to assign a + referent, instead of letting the compiler allocate the space and + initialize the cell.

+

Values stored in the cells bound to array and pointer + names were the machine addresses, measured in bytes, of the corresponding + storage area. Therefore, indirection through a pointer implied no run-time + overhead to scale the pointer from word to byte offset. On the other hand, + the machine code for array subscripting and pointer arithmetic now + depended on the type of the array or the pointer: to compute + iarray[i] or ipointer+i implied scaling the addend + i by the size of the object referred to.

+

These semantics represented an easy transition from B, + and I experimented with them for some months. Problems became evident when + I tried to extend the type notation, especially to add structured (record) + types. Structures, it seemed, should map in an intuitive way onto memory + in the machine, but in a structure containing an array, there was no good + place to stash the pointer containing the base of the array, nor any + convenient way to arrange that it be initialized. For example, the + directory entries of early Unix systems might be described in C as +

+

+
+struct {
+
+	int	inumber;
+
+	char	name[14];
+
+};
+
+
+

I wanted the structure not merely to characterize an + abstract object but also to describe a collection of bits that might be + read from a directory. Where could the compiler hide the pointer to + name that the semantics demanded? Even if structures were thought + of more abstractly, and the space for pointers could be hidden somehow, + how could I handle the technical problem of properly initializing these + pointers when allocating a complicated object, perhaps one that specified + structures containing arrays containing structures to arbitrary depth? +

+

The solution constituted the crucial jump in the + evolutionary chain between typeless BCPL and typed C. It eliminated the + materialization of the pointer in storage, and instead caused the creation + of the pointer when the array name is mentioned in an expression. The + rule, which survives in today's C, is that values of array type are + converted, when they appear in expressions, into pointers to the first of + the objects making up the array.

+

This invention enabled most existing B code to + continue to work, despite the underlying shift in the language's + semantics. The few programs that assigned new values to an array name to + adjust its origin­possible in B and BCPL, meaningless in C­were + easily repaired. More important, the new language retained a coherent and + workable (if unusual) explanation of the semantics of arrays, while + opening the way to a more comprehensive type structure.

+

The second innovation that most clearly distinguishes + C from its predecessors is this fuller type structure and especially its + expression in the syntax of declarations. NB offered the basic types + int and char, together with arrays of them, and pointers + to them, but no further ways of composition. Generalization was required: + given an object of any type, it should be possible to describe a new + object that gathers several into an array, yields it from a function, or + is a pointer to it.

+

For each object of such a composed type, there was + already a way to mention the underlying object: index the array, call the + function, use the indirection operator on the pointer. Analogical + reasoning led to a declaration syntax for names mirroring that of the + expression syntax in which the names typically appear. Thus, +

+

+
+int i, *pi, **ppi;
+
+
+

declare an integer, a pointer to an integer, a pointer + to a pointer to an integer. The syntax of these declarations reflects the + observation that i, *pi, and **ppi all yield an + int type when used in an expression. Similarly, +

+

+
+int f(), *f(), (*f)();
+
+
+

declare a function returning an integer, a function + returning a pointer to an integer, a pointer to a function returning an + integer; +

+

+
+int *api[10], (*pai)[10];
+
+
+

declare an array of pointers to integers, and a + pointer to an array of integers. In all these cases the declaration of a + variable resembles its usage in an expression whose type is the one named + at the head of the declaration.

+

The scheme of type composition adopted by C owes + considerable debt to Algol 68, although it did not, perhaps, emerge in a + form that Algol's adherents would approve of. The central notion I + captured from Algol was a type structure based on atomic types (including + structures), composed into arrays, pointers (references), and functions + (procedures). Algol 68's concept of unions and casts also had an influence + that appeared later.

+

After creating the type system, the associated syntax, + and the compiler for the new language, I felt that it deserved a new name; + NB seemed insufficiently distinctive. I decided to follow the + single-letter style and called it C, leaving open the question whether the + name represented a progression through the alphabet or through the letters + in BCPL.

+

Neonatal C

+

Rapid changes continued after the language had been + named, for example the introduction of the && and + || operators. In BCPL and B, the evaluation of expressions + depends on context: within if and other conditional statements + that compare an expression's value with zero, these languages place a + special interpretation on the and (&) and + or (|) operators. In ordinary contexts, they operate + bitwise, but in the B statement +

+

+
+if (e1 & e2) ...
+
+
+

the compiler must evaluate e1 and if it is + non-zero, evaluate e2, and if it too is non-zero, elaborate the + statement dependent on the if. The requirement descends + recursively on & and | operators within e1 + and e2. The short-circuit semantics of the Boolean operators in + such `truth-value' context seemed desirable, but the overloading of the + operators was difficult to explain and use. At the suggestion of Alan + Snyder, I introduced the && and || operators to + make the mechanism more explicit.

+

Their tardy introduction explains an infelicity of C's + precedence rules. In B one writes +

+

+
+if (a==b & c) ...
+
+
+

to check whether a equals b and + c is non-zero; in such a conditional expression it is better that + & have lower precedence than ==. In converting from + B to C, one wants to replace & by && in such + a statement; to make the conversion less painful, we decided to keep the + precedence of the & operator the same relative to + ==, and merely split the precedence of && + slightly from &. Today, it seems that it would have been + preferable to move the relative precedences of & and + ==, and thereby simplify a common C idiom: to test a masked value + against another value, one must write +

+

+
+if ((a&mask) == b) ...
+
+
+

where the inner parentheses are required but easily + forgotten.

+

Many other changes occurred around 1972-3, but the + most important was the introduction of the preprocessor, partly at the + urging of Alan Snyder [Snyder 74], but also in recognition of the utility + of the the file-inclusion mechanisms available in BCPL and PL/I. Its + original version was exceedingly simple, and provided only included files + and simple string replacements: #include and #define of + parameterless macros. Soon thereafter, it was extended, mostly by Mike + Lesk and then by John Reiser, to incorporate macros with arguments and + conditional compilation. The preprocessor was originally considered an + optional adjunct to the language itself. Indeed, for some years, it was + not even invoked unless the source program contained a special signal at + its beginning. This attitude persisted, and explains both the incomplete + integration of the syntax of the preprocessor with the rest of the + language and the imprecision of its description in early reference + manuals.

+

Portability

+

By early 1973, the essentials of modern C were + complete. The language and compiler were strong enough to permit us to + rewrite the Unix kernel for the PDP-11 in C during the summer of that + year. (Thompson had made a brief attempt to produce a system coded in an + early version of C­before structures­in 1972, but gave up the + effort.) Also during this period, the compiler was retargeted to other + nearby machines, particularly the Honeywell 635 and IBM 360/370; because + the language could not live in isolation, the prototypes for the modern + libraries were developed. In particular, Lesk wrote a `portable I/O + package' [Lesk 72] that was later reworked to become the C `standard I/O' + routines. In 1978 Brian Kernighan and I published The C Programming + Language [Kernighan 78]. Although it did not describe some additions + that soon became common, this book served as the language reference until + a formal standard was adopted more than ten years later. Although we + worked closely together on this book, there was a clear division of labor: + Kernighan wrote almost all the expository material, while I was + responsible for the appendix containing the reference manual and the + chapter on interfacing with the Unix system.

+

During 1973-1980, the language grew a bit: the type + structure gained unsigned, long, union, and enumeration types, and + structures became nearly first-class objects (lacking only a notation for + literals). Equally important developments appeared in its environment and + the accompanying technology. Writing the Unix kernel in C had given us + enough confidence in the language's usefulness and efficiency that we + began to recode the system's utilities and tools as well, and then to move + the most interesting among them to the other platforms. As described in + [Johnson 78a], we discovered that the hardest problems in propagating Unix + tools lay not in the interaction of the C language with new hardware, but + in adapting to the existing software of other operating systems. Thus + Steve Johnson began to work on pcc, a C compiler intended to be + easy to retarget to new machines [Johnson 78b], while he, Thompson, and I + began to move the Unix system itself to the Interdata 8/32 computer. +

+

The language changes during this period, especially + around 1977, were largely focused on considerations of portability and + type safety, in an effort to cope with the problems we foresaw and + observed in moving a considerable body of code to the new Interdata + platform. C at that time still manifested strong signs of its typeless + origins. Pointers, for example, were barely distinguished from integral + memory indices in early language manuals or extant code; the similarity of + the arithmetic properties of character pointers and unsigned integers made + it hard to resist the temptation to identify them. The unsigned + types were added to make unsigned arithmetic available without confusing + it with pointer manipulation. Similarly, the early language condoned + assignments between integers and pointers, but this practice began to be + discouraged; a notation for type conversions (called `casts' from the + example of Algol 68) was invented to specify type conversions more + explicitly. Beguiled by the example of PL/I, early C did not tie structure + pointers firmly to the structures they pointed to, and permitted + programmers to write pointer->member almost without regard to + the type of pointer; such an expression was taken uncritically as + a reference to a region of memory designated by the pointer, while the + member name specified only an offset and a type.

+

Although the first edition of K&R described most + of the rules that brought C's type structure to its present form, many + programs written in the older, more relaxed style persisted, and so did + compilers that tolerated it. To encourage people to pay more attention to + the official language rules, to detect legal but suspicious constructions, + and to help find interface mismatches undetectable with simple mechanisms + for separate compilation, Steve Johnson adapted his pcc compiler to + produce lint [Johnson 79b], which scanned a set of files and + remarked on dubious constructions.

+

Growth in Usage

+

The success of our portability experiment on the + Interdata 8/32 soon led to another by Tom London and John Reiser on the + DEC VAX 11/780. This machine became much more popular than the Interdata, + and Unix and the C language began to spread rapidly, both within AT&T + and outside. Although by the middle 1970s Unix was in use by a variety of + projects within the Bell System as well as a small group of + research-oriented industrial, academic, and government organizations + outside our company, its real growth began only after portability had been + achieved. Of particular note were the System III and System V versions of + the system from the emerging Computer Systems division of AT&T, based + on work by the company's development and research groups, and the BSD + series of releases by the University of California at Berkeley that + derived from research organizations in Bell Laboratories.

+

During the 1980s the use of the C language spread + widely, and compilers became available on nearly every machine + architecture and operating system; in particular it became popular as a + programming tool for personal computers, both for manufacturers of + commercial software for these machines, and for end-users interesting in + programming. At the start of the decade, nearly every compiler was based + on Johnson's pcc; by 1985 there were many independently-produced + compiler products.

+

Standardization

+

By 1982 it was clear that C needed formal + standardization. The best approximation to a standard, the first edition + of K&R, no longer described the language in actual use; in particular, + it mentioned neither the void or enum types. While it + foreshadowed the newer approach to structures, only after it was published + did the language support assigning them, passing them to and from + functions, and associating the names of members firmly with the structure + or union containing them. Although compilers distributed by AT&T + incorporated these changes, and most of the purveyors of compilers not + based on pcc quickly picked up them up, there remained no complete, + authoritative description of the language.

+

The first edition of K&R was also insufficiently + precise on many details of the language, and it became increasingly + impractical to regard pcc as a `reference compiler;' it did not + perfectly embody even the language described by K&R, let alone + subsequent extensions. Finally, the incipient use of C in projects subject + to commercial and government contract meant that the imprimatur of an + official standard was important. Thus (at the urging of M. D. McIlroy), + ANSI established the X3J11 committee under the direction of CBEMA in the + summer of 1983, with the goal of producing a C standard. X3J11 produced + its report [ANSI 89] at the end of 1989, and subsequently this standard + was accepted by ISO as ISO/IEC 9899-1990.

+

From the beginning, the X3J11 committee took a + cautious, conservative view of language extensions. Much to my + satisfaction, they took seriously their goal: `to develop a clear, + consistent, and unambiguous Standard for the C programming language which + codifies the common, existing definition of C and which promotes the + portability of user programs across C language environments.' [ANSI 89] + The committee realized that mere promulgation of a standard does not make + the world change.

+

X3J11 introduced only one genuinely important change + to the language itself: it incorporated the types of formal arguments in + the type signature of a function, using syntax borrowed from C++ + [Stroustrup 86]. In the old style, external functions were declared like + this: +

+

+
+double sin();
+
+
+

which says only that sin is a function + returning a double (that is, double-precision floating-point) + value. In the new style, this better rendered +

+

+
+double sin(double);
+
+
+

to make the argument type explicit and thus encourage + better type checking and appropriate conversion. Even this addition, + though it produced a noticeably better language, caused difficulties. The + committee justifiably felt that simply outlawing `old-style' function + definitions and declarations was not feasible, yet also agreed that the + new forms were better. The inevitable compromise was as good as it could + have been, though the language definition is complicated by permitting + both forms, and writers of portable software must contend with compilers + not yet brought up to standard.

+

X3J11 also introduced a host of smaller additions and + adjustments, for example, the type qualifiers const and + volatile, and slightly different type promotion rules. + Nevertheless, the standardization process did not change the character of + the language. In particular, the C standard did not attempt to specify + formally the language semantics, and so there can be dispute over fine + points; nevertheless, it successfully accounted for changes in usage since + the original description, and is sufficiently precise to base + implementations on it.

+

Thus the core C language escaped nearly unscathed from + the standardization process, and the Standard emerged more as a better, + careful codification than a new invention. More important changes took + place in the language's surroundings: the preprocessor and the library. + The preprocessor performs macro substitution, using conventions distinct + from the rest of the language. Its interaction with the compiler had never + been well-described, and X3J11 attempted to remedy the situation. The + result is noticeably better than the explanation in the first edition of + K&R; besides being more comprehensive, it provides operations, like + token concatenation, previously available only by accidents of + implementation.

+

X3J11 correctly believed that a full and careful + description of a standard C library was as important as its work on the + language itself. The C language itself does not provide for input-output + or any other interaction with the outside world, and thus depends on a set + of standard procedures. At the time of publication of K&R, C was + thought of mainly as the system programming language of Unix; although we + provided examples of library routines intended to be readily transportable + to other operating systems, underlying support from Unix was implicitly + understood. Thus, the X3J11 committee spent much of its time designing and + documenting a set of library routines required to be available in all + conforming implementations.

+

By the rules of the standards process, the current + activity of the X3J11 committee is confined to issuing interpretations on + the existing standard. However, an informal group originally convened by + Rex Jaeschke as NCEG (Numerical C Extensions Group) has been officially + accepted as subgroup X3J11.1, and they continue to consider extensions to + C. As the name implies, many of these possible extensions are intended to + make the language more suitable for numerical use: for example, + multi-dimensional arrays whose bounds are dynamically determined, + incorporation of facilities for dealing with IEEE arithmetic, and making + the language more effective on machines with vector or other advanced + architectural features. Not all the possible extensions are specifically + numerical; they include a notation for structure literals.

+

Successors

+

C and even B have several direct descendants, though + they do not rival Pascal in generating progeny. One side branch developed + early. When Steve Johnson visited the University of Waterloo on sabbatical + in 1972, he brought B with him. It became popular on the Honeywell + machines there, and later spawned Eh and Zed (the Canadian answers to + `what follows B?'). When Johnson returned to Bell Labs in 1973, he was + disconcerted to find that the language whose seeds he brought to Canada + had evolved back home; even his own yacc program had been rewritten + in C, by Alan Snyder.

+

More recent descendants of C proper include Concurrent + C [Gehani 89], Objective C [Cox 86], C* [Thinking 90], and especially C++ + [Stroustrup 86]. The language is also widely used as an intermediate + representation (essentially, as a portable assembly language) for a wide + variety of compilers, both for direct descendents like C++, and + independent languages like Modula 3 [Nelson 91] and Eiffel [Meyer 88]. +

+

Critique

+

Two ideas are most characteristic of C among languages + of its class: the relationship between arrays and pointers, and the way in + which declaration syntax mimics expression syntax. They are also among its + most frequently criticized features, and often serve as stumbling blocks + to the beginner. In both cases, historical accidents or mistakes have + exacerbated their difficulty. The most important of these has been the + tolerance of C compilers to errors in type. As should be clear from the + history above, C evolved from typeless languages. It did not suddenly + appear to its earliest users and developers as an entirely new language + with its own rules; instead we continually had to adapt existing programs + as the language developed, and make allowance for an existing body of + code. (Later, the ANSI X3J11 committee standardizing C would face the same + problem.)

+

Compilers in 1977, and even well after, did not + complain about usages such as assigning between integers and pointers or + using objects of the wrong type to refer to structure members. Although + the language definition presented in the first edition of K&R was + reasonably (though not completely) coherent in its treatment of type + rules, that book admitted that existing compilers didn't enforce them. + Moreover, some rules designed to ease early transitions contributed to + later confusion. For example, the empty square brackets in the function + declaration +

+

+
+int f(a) int a[]; { ... }
+
+
+

are a living fossil, a remnant of NB's way of + declaring a pointer; a is, in this special case only, interpreted + in C as a pointer. The notation survived in part for the sake of + compatibility, in part under the rationalization that it would allow + programmers to communicate to their readers an intent to pass f a + pointer generated from an array, rather than a reference to a single + integer. Unfortunately, it serves as much to confuse the learner as to + alert the reader.

+

In K&R C, supplying arguments of the proper type + to a function call was the responsibility of the programmer, and the + extant compilers did not check for type agreement. The failure of the + original language to include argument types in the type signature of a + function was a significant weakness, indeed the one that required the + X3J11 committee's boldest and most painful innovation to repair. The early + design is explained (if not justified) by my avoidance of technological + problems, especially cross-checking between separately-compiled source + files, and my incomplete assimilation of the implications of moving + between an untyped to a typed language. The lint program, mentioned + above, tried to alleviate the problem: among its other functions, + lint checks the consistency and coherency of a whole program by + scanning a set of source files, comparing the types of function arguments + used in calls with those in their definitions.

+

An accident of syntax contributed to the perceived + complexity of the language. The indirection operator, spelled * + in C, is syntactically a unary prefix operator, just as in BCPL and B. + This works well in simple expressions, but in more complex cases, + parentheses are required to direct the parsing. For example, to + distinguish indirection through the value returned by a function from + calling a function designated by a pointer, one writes *fp() and + (*pf)() respectively. The style used in expressions carries + through to declarations, so the names might be declared +

+

+
+int *fp();
+
+int (*pf)();
+
+
+

In more ornate but still realistic cases, things + become worse: +

+

+
+int *(*pfp)();
+
+
+

is a pointer to a function returning a pointer to an + integer. There are two effects occurring. Most important, C has a + relatively rich set of ways of describing types (compared, say, with + Pascal). Declarations in languages as expressive as C­Algol 68, for + example­describe objects equally hard to understand, simply because + the objects themselves are complex. A second effect owes to details of the + syntax. Declarations in C must be read in an `inside-out' style that many + find difficult to grasp [Anderson 80]. Sethi [Sethi 81] observed that many + of the nested declarations and expressions would become simpler if the + indirection operator had been taken as a postfix operator instead of + prefix, but by then it was too late to change.

+

In spite of its difficulties, I believe that the C's + approach to declarations remains plausible, and am comfortable with it; it + is a useful unifying principle.

+

The other characteristic feature of C, its treatment + of arrays, is more suspect on practical grounds, though it also has real + virtues. Although the relationship between pointers and arrays is unusual, + it can be learned. Moreover, the language shows considerable power to + describe important concepts, for example, vectors whose length varies at + run time, with only a few basic rules and conventions. In particular, + character strings are handled by the same mechanisms as any other array, + plus the convention that a null character terminates a string. It is + interesting to compare C's approach with that of two nearly + contemporaneous languages, Algol 68 and Pascal [Jensen 74]. Arrays in + Algol 68 either have fixed bounds, or are `flexible:' considerable + mechanism is required both in the language definition, and in compilers, + to accommodate flexible arrays (and not all compilers fully implement + them.) Original Pascal had only fixed-sized arrays and strings, and this + proved confining [Kernighan 81]. Later, this was partially fixed, though + the resulting language is not yet universally available.

+

C treats strings as arrays of characters + conventionally terminated by a marker. Aside from one special rule about + initialization by string literals, the semantics of strings are fully + subsumed by more general rules governing all arrays, and as a result the + language is simpler to describe and to translate than one incorporating + the string as a unique data type. Some costs accrue from its approach: + certain string operations are more expensive than in other designs because + application code or a library routine must occasionally search for the end + of a string, because few built-in operations are available, and because + the burden of storage management for strings falls more heavily on the + user. Nevertheless, C's approach to strings works well.

+

On the other hand, C's treatment of arrays in general + (not just strings) has unfortunate implications both for optimization and + for future extensions. The prevalence of pointers in C programs, whether + those declared explicitly or arising from arrays, means that optimizers + must be cautious, and must use careful dataflow techniques to achieve good + results. Sophisticated compilers can understand what most pointers can + possibly change, but some important usages remain difficult to analyze. + For example, functions with pointer arguments derived from arrays are hard + to compile into efficient code on vector machines, because it is seldom + possible to determine that one argument pointer does not overlap data also + referred to by another argument, or accessible externally. More + fundamentally, the definition of C so specifically describes the semantics + of arrays that changes or extensions treating arrays as more primitive + objects, and permitting operations on them as wholes, become hard to fit + into the existing language. Even extensions to permit the declaration and + use of multidimensional arrays whose size is determined dynamically are + not entirely straightforward [MacDonald 89] [Ritchie 90], although they + would make it much easier to write numerical libraries in C. Thus, C + covers the most important uses of strings and arrays arising in practice + by a uniform and simple mechanism, but leaves problems for highly + efficient implementations and for extensions.

+

Many smaller infelicities exist in the language and + its description besides those discussed above, of course. There are also + general criticisms to be lodged that transcend detailed points. Chief + among these is that the language and its generally-expected environment + provide little help for writing very large systems. The naming structure + provides only two main levels, `external' (visible everywhere) and + `internal' (within a single procedure). An intermediate level of + visibility (within a single file of data and procedures) is weakly tied to + the language definition. Thus, there is little direct support for + modularization, and project designers are forced to create their own + conventions.

+

Similarly, C itself provides two durations of storage: + `automatic' objects that exist while control resides in or below a + procedure, and `static,' existing throughout execution of a program. + Off-stack, dynamically-allocated storage is provided only by a library + routine and the burden of managing it is placed on the programmer: C is + hostile to automatic garbage collection.

+

Whence Success?

+

C has become successful to an extent far surpassing + any early expectations. What qualities contributed to its widespread use? +

+

Doubtless the success of Unix itself was the most + important factor; it made the language available to hundreds of thousands + of people. Conversely, of course, Unix's use of C and its consequent + portability to a wide variety of machines was important in the system's + success. But the language's invasion of other environments suggests more + fundamental merits.

+

Despite some aspects mysterious to the beginner and + occasionally even to the adept, C remains a simple and small language, + translatable with simple and small compilers. Its types and operations are + well-grounded in those provided by real machines, and for people used to + how computers work, learning the idioms for generating time- and + space-efficient programs is not difficult. At the same time the language + is sufficiently abstracted from machine details that program portability + can be achieved.

+

Equally important, C and its central library support + always remained in touch with a real environment. It was not designed in + isolation to prove a point, or to serve as an example, but as a tool to + write programs that did useful things; it was always meant to interact + with a larger operating system, and was regarded as a tool to build larger + tools. A parsimonious, pragmatic approach influenced the things that went + into C: it covers the essential needs of many programmers, but does not + try to supply too much.

+

Finally, despite the changes that it has undergone + since its first published description, which was admittedly informal and + incomplete, the actual C language as seen by millions of users using many + different compilers has remained remarkably stable and unified compared to + those of similarly widespread currency, for example Pascal and Fortran. + There are differing dialects of C­most noticeably, those described by + the older K&R and the newer Standard C­but on the whole, C has + remained freer of proprietary extensions than other languages. Perhaps the + most significant extensions are the `far' and `near' pointer + qualifications intended to deal with peculiarities of some Intel + processors. Although C was not originally designed with portability as a + prime goal, it succeeded in expressing programs, even including operating + systems, on machines ranging from the smallest personal computers through + the mightiest supercomputers.

+

C is quirky, flawed, and an enormous success. While + accidents of history surely helped, it evidently satisfied a need for a + system implementation language efficient enough to displace assembly + language, yet sufficiently abstract and fluent to describe algorithms and + interactions in a wide variety of environments.

+

Acknowledgments

+

It is worth summarizing compactly the roles of the + direct contributors to today's C language. Ken Thompson created the B + language in 1969-70; it was derived directly from Martin Richards's BCPL. + Dennis Ritchie turned B into C during 1971-73, keeping most of B's syntax + while adding types and many other changes, and writing the first compiler. + Ritchie, Alan Snyder, Steven C. Johnson, Michael Lesk, and Thompson + contributed language ideas during 1972-1977, and Johnson's portable + compiler remains widely used. During this period, the collection of + library routines grew considerably, thanks to these people and many others + at Bell Laboratories. In 1978, Brian Kernighan and Ritchie wrote the book + that became the language definition for several years. Beginning in 1983, + the ANSI X3J11 committee standardized the language. Especially notable in + keeping its efforts on track were its officers Jim Brodie, Tom Plum, and + P. J. Plauger, and the successive draft redactors, Larry Rosler and Dave + Prosser.

+

I thank Brian Kernighan, Doug McIlroy, Dave Prosser, + Peter Nelson, Rob Pike, Ken Thompson, and HOPL's referees for advice in + the preparation of this paper.

+

References

+



+

+
+
[ANSI 89] +
American National Standards Institute, American + National Standard for Information Systems&#173;Programming Language + C, X3.159-1989. +
+
[Anderson 80] +
B. Anderson, `Type syntax in the language C: an + object lesson in syntactic innovation,' SIGPLAN Notices 15 (3), + March, 1980, pp. 21-27. +
+
[Bell 72] +
J. R. Bell, `Threaded Code,' C. ACM 16 (6), + pp. 370-372. +
+
[Canaday 69] +
R. H. Canaday and D. M. Ritchie, `Bell Laboratories + BCPL,' AT&T Bell Laboratories internal memorandum, May, 1969. + +
+
[Corbato 62] +
F. J. Corbato, M. Merwin-Dagget, R. C. Daley, `An + Experimental Time-sharing System,' AFIPS Conf. Proc. SJCC, 1962, pp. + 335-344. +
+
[Cox 86] +
B. J. Cox and A. J. Novobilski, Object-Oriented + Programming: An Evolutionary Approach, Addison-Wesley: Reading, + Mass., 1986. Second edition, 1991. +
+
[Gehani 89] +
N. H. Gehani and W. D. Roome, Concurrent C, + Silicon Press: Summit, NJ, 1989. +
+
[Jensen 74] +
K. Jensen and N. Wirth, Pascal User Manual and + Report, Springer-Verlag: New York, Heidelberg, Berlin. Second + Edition, 1974. +
+
[Johnson 73] +
S. C. Johnson and B. W. Kernighan, `The Programming + Language B,' Comp. Sci. Tech. Report #8, AT&T Bell Laboratories + (January 1973). +
+
[Johnson 78a] +
S. C. Johnson and D. M. Ritchie, `Portability of C + Programs and the UNIX System,' Bell Sys. Tech. J. 57 (6) (part + 2), July-Aug, 1978. +
+
[Johnson 78b] +
S. C. Johnson, `A Portable Compiler: Theory and + Practice,' Proc. 5th ACM POPL Symposium (January 1978). +
+
[Johnson 79a] +
S. C. Johnson, `Yet another compiler-compiler,' in + Unix Programmer's Manual, Seventh Edition, Vol. 2A, M. D. McIlroy + and B. W. Kernighan, eds. AT&T Bell Laboratories: Murray Hill, NJ, + 1979. +
+
[Johnson 79b] +
S. C. Johnson, `Lint, a Program Checker,' in + Unix Programmer's Manual, Seventh Edition, Vol. 2B, M. D. McIlroy + and B. W. Kernighan, eds. AT&T Bell Laboratories: Murray Hill, NJ, + 1979. +
+
[Kernighan 78] +
B. W. Kernighan and D. M. Ritchie, The C + Programming Language, Prentice-Hall: Englewood Cliffs, NJ, 1978. + Second edition, 1988. +
+
[Kernighan 81] +
B. W. Kernighan, `Why Pascal is not my favorite + programming language,' Comp. Sci. Tech. Rep. #100, AT&T Bell + Laboratories, 1981. +
+
[Lesk 73] +
M. E. Lesk, `A Portable I/O Package,' AT&T Bell + Laboratories internal memorandum ca. 1973. +
+
[MacDonald 89] +
T. MacDonald, `Arrays of variable length,' J. C + Lang. Trans 1 (3), Dec. 1989, pp. 215-233. +
+
[McClure 65] +
R. M. McClure, `TMG­A Syntax Directed + Compiler,' Proc. 20th ACM National Conf. (1965), pp. 262-274. +
+
[McIlroy 60] +
M. D. McIlroy, `Macro Instruction Extensions of + Compiler Languages,' C. ACM 3 (4), pp. 214-220. +
+
[McIlroy 79] +
M. D. McIlroy and B. W. Kernighan, eds, Unix + Programmer's Manual, Seventh Edition, Vol. I, AT&T Bell + Laboratories: Murray Hill, NJ, 1979. +
+
[Meyer 88] +
B. Meyer, Object-oriented Software + Construction, Prentice-Hall: Englewood Cliffs, NJ, 1988. +
+
[Nelson 91] +
G. Nelson, Systems Programming with + Modula-3, Prentice-Hall: Englewood Cliffs, NJ, 1991. +
+
[Organick 75] +
E. I. Organick, The Multics System: An + Examination of its Structure, MIT Press: Cambridge, Mass., 1975. + +
+
[Richards 67] +
M. Richards, `The BCPL Reference Manual,' MIT + Project MAC Memorandum M-352, July 1967. +
+
[Richards 79] +
M. Richards and C. Whitbey-Strevens, BCPL: The + Language and its Compiler, Cambridge Univ. Press: Cambridge, 1979. + +
+
[Ritchie 78] +
D. M. Ritchie, `UNIX: A Retrospective,' Bell Sys. + Tech. J. 57 (6) (part 2), July-Aug, 1978. +
+
[Ritchie 84] +
D. M. Ritchie, `The Evolution of the UNIX + Time-sharing System,' AT&T Bell Labs. Tech. J. 63 (8) (part + 2), Oct. 1984. +
+
[Ritchie 90] +
D. M. Ritchie, `Variable-size arrays in C,' J. C + Lang. Trans. 2 (2), Sept. 1990, pp. 81-86. +
+
[Sethi 81] +
R. Sethi, `Uniform syntax for type expressions and + declarators,' Softw. Prac. and Exp. 11 (6), June 1981, pp. + 623-628. +
+
[Snyder 74] +
A. Snyder, A Portable Compiler for the Language + C, MIT: Cambridge, Mass., 1974. +
+
[Stoy 72] +
J. E. Stoy and C. Strachey, `OS6­An + experimental operating system for a small computer. Part I: General + principles and structure,' Comp J. 15, (Aug. 1972), pp. 117-124. + +
+
[Stroustrup 86] +
B. Stroustrup, The C++ Programming Language, + Addison-Wesley: Reading, Mass., 1986. Second edition, 1991. +
+
[Thacker 79] +
C. P. Thacker, E. M. McCreight, B. W. Lampson, R. + F. Sproull, D. R. Boggs, `Alto: A Personal Computer,' in Computer + Structures: Principles and Examples, D. Sieworek, C. G. Bell, A. + Newell, McGraw-Hill: New York, 1982. +
+
[Thinking 90] +
C* Programming Guide, Thinking Machines + Corp.: Cambridge Mass., 1990. +
+
[Thompson 69] +
K. Thompson, `Bon­an Interactive Language,' + undated AT&T Bell Laboratories internal memorandum (ca. 1969). + +
+
[Wijngaarden 75] +
A. van Wijngaarden, B. J. Mailloux, J. E. Peck, C. + H. Koster, M. Sintzoff, C. Lindsey, L. G. Meertens, R. G. Fisker, + `Revised report on the algorithmic language Algol 68,' Acta Informatica + 5, pp. 1-236.
+

 

diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History.htm b/doc/The UNIX System -- History and Timeline -- UNIX History.htm new file mode 100755 index 00000000..2f37e370 --- /dev/null +++ b/doc/The UNIX System -- History and Timeline -- UNIX History.htm @@ -0,0 +1,455 @@ + + +The UNIX System -- History and Timeline -- UNIX History + + + + + + + + + + + +
+

UNIX System + Home  •   The Single UNIX + Specification  •   UNIX 98  •   UNIX.net  •   Mailing Lists  •   White Papers
+

+

History and Timeline


+ + + +
+ +
+ + + + +
+
History + & Timeline
+
The + Single UNIX Specification
+
Registered + Products
+
The UNIX + Brand
+
What + About All Those "Flavors"
+
Version 2 of the Single UNIX + Specification
+
Version 3 of the Single UNIX + Specification
+
UNIX API Tables
+
Why + This is Different
+

UNIX Past

+

+

+

"...the number of UNIX installations has grown to 10, with more expected..."
+
+

+

- Dennis Ritchie and Ken Thompson, June 1972

+

"... When BTL withdrew from the project, they needed to rewrite an operating
+system (OS) in order to play space war on another smaller machine (a DEC
+PDP-7 [Programmed Data Processor] with 4K memory for user
+programs). The result was a system which a punning colleague called
+UNICS (UNiplexed Information and Computing Service)--an
+'emasculated Multics'; no one recalls whose idea the change to UNIX
+was"
+

+

Source: A brief look at + the early history

+

+

Resources: Dennis Ritchie's home page + | Ken Thompson's home + page +


+ +

+

Since it began to escape from AT&T's Bell Laboratories in the early + 1970's, the success of the UNIX operating system has led to many different + versions: recipients of the (at that time free) UNIX system code all began + developing their own different versions in their own, different, ways for + use and sale. Universities, research institutes, government bodies + and computer companies all began using the powerful UNIX system to develop + many of the technologies which today are part of a UNIX system.

+

Computer aided design, manufacturing control  systems, laboratory + simulations, even the Internet itself, all began life with and because of + UNIX systems. Today, without UNIX systems, the Internet would come to a + screeching halt. Most telephone calls could not be made, electronic + commerce would grind to a halt and there would have never been "Jurassic + Park"!

+

By the late 1970's, a ripple effect had come into play. By now the + under- and post-graduate students whose lab work had pioneered these new + applications of technology were attaining management and decision-making + positions inside the computer system suppliers and among its customers. + And they wanted to continue using UNIX systems.

+

Soon all the large vendors, and many smaller ones, were marketing their + own, diverging, versions of the UNIX system optimized for their own + computer architectures and boasting many different strengths and features. + Customers found that, although UNIX systems were available everywhere, + they seldom were able to interwork or co-exist without significant + investment of time and effort to make them work effectively. The trade + mark UNIX was ubiquitous, but it was applied to a multitude of different, + incompatible products.

+

In the early 1980's, the market for UNIX systems had grown enough to be + noticed  by industry analysts and researchers. Now the question was + no longer "What is a UNIX system?" but "Is a UNIX system suitable for + business and commerce?"

+

Throughout the early and mid-1980's, the debate about the strengths and + weaknesses of UNIX systems raged, often fuelled by the utterances of the + vendors themselves who sought to protect their profitable proprietary + system sales by talking UNIX systems down. And, in an effort to further + differentiate their competing UNIX system products, they kept developing + and adding features of their own.

+

In 1984, another factor brought added attention to UNIX systems. A + group of vendors concerned about the continuing encroachment into their + markets and control of system interfaces by the larger companies, + developed the concept of "open systems."

+

Open systems were those that would meet agreed specifications or + standards. This resulted in the formation of X/Open Company Ltd whose + remit was, and today in the guise of The Open Group remains, to define a + comprehensive open systems environment. Open systems, they declared, would + save on costs, attract a wider portfolio of applications and competition + on equal terms. X/Open chose the UNIX system as the platform for the basis + of open systems.

+

Although UNIX was still owned by AT&T, the company did little + commercially with it until the mid-1980's. Then the spotlight of X/Open + showed clearly that a single, standard version of the UNIX system would be + in the wider interests of  the industry and its customers. The + question now was, "which version?".

+

In a move intended to unify the market in 1987, AT&T announced a + pact with Sun Microsystems, the leading proponent of the Berkeley derived + strain of UNIX. However, the rest of the industry viewed the development + with considerable concern. Believing that their own markets were under + threat they clubbed together to develop their own "new" open systems + operating system. Their new organization was called the Open Software + Foundation (OSF). In response to this, the AT&T/Sun faction formed + UNIX International.

+

The ensuing "UNIX wars" divided the system vendors between these two + camps clustered around the two dominant UNIX system technologies: + AT&T's System V and the OSF system called OSF/1. In the meantime, + X/Open Company held the center ground. It continued the process of + standardizing the APIs necessary for an open operating system + specification.

+

In addition, it looked at areas of the system beyond the operating + system level where a standard approach would add value for supplier and + customer alike, developing or adopting specifications for languages, + database connectivity, networking and mainframe interworking. The results + of this work were published in successive X/Open Portability Guides.

+

XPG 4 was released in October 1992. During this time, X/Open had put in + place a brand program based on vendor guarantees and supported by testing. + Since the publication of XPG4, X/Open has continued to broaden the scope + of open systems specifications in line with market requirements. As the + benefits of the X/Open brand became known and understood, many large + organizations began using X/Open as the basis for system design and + procurement. By 1993, over $7 billion had been spent on X/Open branded + systems. By the start of 1997 that figure has risen to over $23 billion. + To date, procurements referencing the Single UNIX Specification amount to + over $5.2 billion.

+

In early 1993, AT&T sold it UNIX System Laboratories to Novell + which was looking for a heavyweight operating system to link to its + NetWare product range. At the same time, the company recognized that + vesting control of the definition (specification) and trademark with a + vendor-neutral organization would further facilitate the value of UNIX as + a foundation of open systems. So the constituent parts of the UNIX System, + previously owned by a single entity are now quite separate

+

In 1995 SCO bought the UNIX Systems business from Novell, and UNIX + system source code and technology continues to be developed by SCO.

+

In 1995 X/Open introduced the UNIX 95 brand for computer systems + guaranteed to meet the Single UNIX Specification. The Single UNIX + Specification brand program has now achieved critical mass: vendors whose + products have met the demanding criteria now account for the majority of + UNIX systems by value.

+

For over ten years, since the inception of X/Open, UNIX had been + closely linked with open systems. X/Open, now part of The Open Group, + continues to develop and evolve the Single UNIX Specification and + associated brand program on behalf of the IT community. The freeing of the + specification of the interfaces from the technology is allowing many + systems to support the UNIX philosophy of small, often simple tools , that + can be combined in many ways to perform often complex tasks. The stability + of the core interfaces preserves existing investment, and is allowing + development of a rich set of software tools. The Open Source movement is building on + this stable foundation and is creating a resurgence of enthusiasm for the + UNIX philosophy. In many ways Open Source can be seen as the true delivery + of Open Systems that will ensure it continues to go from strength to + strength. +


+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1969The BeginningThe history of UNIX starts back in 1969, when + Ken Thompson, Dennis Ritchie and others started working on the + "little-used PDP-7 in a corner" at Bell Labs and what was to become + UNIX.
1971First EditionIt had a assembler for a PDP-11/20, file system, + fork(), roff and ed. It was used for text processing of patent + documents.
1973Fourth EditionIt was rewritten in C. This made it portable and + changed the history of OS's.
1975Sixth EditionUNIX leaves home. Also widely known as Version + 6, this is the first to be widely available out side of Bell Labs. + The first BSD version (1.x) was derived from V6.
1979Seventh EditionIt was a "improvement over all preceding and + following Unices" [Bourne]. It had C, UUCP and the Bourne shell. It + was ported to the VAX and the kernel was more than 40 Kilobytes + (K).
1980XenixMicrosoft introduces Xenix. 32V and 4BSD + introduced.
1982System IIIAT&T's UNIX System Group (USG) release + System III, the first public release outside Bell +Laboratories.
1983System VComputer Research Group (CRG), UNIX System Group + (USG) and a third group merge to become UNIX System Development Lab. + AT&T announces UNIX System V, the first supported release.
19844.2BSDUniversity of California at Berkeley releases + 4.2BSD, includes TCP/IP, new signals and much more.
1984SVR2System V Release 2 introduced. At this time + there are 100,000 UNIX installations around the world.
19864.3BSD4.3BSD released, including internet name server +
1987SVR3System V Release 3 including STREAMS, TLI, RFS. + At this time there are 750,000 UNIX installations around the + world.
1988 POSIX.1 published. Open Software Foundation + (OSF) and UNIX International (UI) formed.
1989 AT&T UNIX Software Operation formed in + preparation for spinoff of USL.
1989SVR4UNIX System V Release 4 ships, unifying System + V, BSD and Xenix
1990XPG3X/Open launches XPG3 Brand
1991 UNIX System Laboratories (USL) becomes a company + - majority-owned by AT&T. Linus Torvalds commences Linux + development
1992SVR4.2USL releases UNIX System V Release 4.2 + (Destiny). October - XPG4 Brand launched by X/Open. December 22nd + Novell announces intent to acquire USL.
19934.4BSD4.4BSD the final release from Berkeley. June 16 + Novell acquires USL
Late 1993SVR4.2MPNovell transfers rights to the "UNIX" trademark + and the Single UNIX Specification to X/Open. In December Novell + ships SVR4.2MP , the final USL OEM release of System V
19944.4-LiteBSD 4.4-Lite eliminated all code claimed to + infringe on USL/Novell
1995UNIX 95X/Open introduces the UNIX 95 branding + programme. Novell sells UnixWare business to SCO.
1996 The Open Group forms as a merger of OSF and + X/Open.
1997Single UNIX Specification, Version 2The Open Group introduces Version 2 of the + Single UNIX Specification, including support for realtime, threads + and 64-bit and larger processors. The specification is made freely + available on the web.
1998UNIX 98The Open Group introduces the UNIX 98 family of + brands, including Base, Workstation and Server. First UNIX 98 + registered products shipped by Sun, IBM and NCR. The Open Source + movement starts to take off with announcements from Netscape and + IBM
1999UNIX at 30The UNIX system reaches its 30th anniversary. + Linux 2.2 kernel released. The Open Group and the IEEE commence + joint development of a revision to POSIX and the Single UNIX + Specification. First LinuxWorld conferences. Several Open Source + companies launch successfully on the stock markets.
2001Version 3 of the Single UNIX + SpecificationVersion 3 of the Single UNIX Specification + unites IEEE POSIX, The Open Group and the industry efforts. Linux + 2.4 kernel released. IT stocks face a hard time at the markets. +
2002ISO/IEC 9945:2002The core volumes of Version 3 of the Single UNIX + Specification are approved as an international standard. +
+

 

+
+
+
+
+ +
HomeContacts +• LegalCopyright Members  News
+
+
© The Open Group 1995-2003  Updated on Wednesday, 29 January 2003
+ + + + + +
+
+ +
+ +
+ + + + + + +

+

diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History_files/b.gif b/doc/The UNIX System -- History and Timeline -- UNIX History_files/b.gif new file mode 100755 index 0000000000000000000000000000000000000000..f4a2493a1f8939a9731429423fed62dca96d6f38 GIT binary patch literal 43 scmZ?wbhEHbWMW`qXkcLY|NlP&1B2pE7Dgb&paUX6G7L;iErATy0Lu0UjQ{`u literal 0 HcmV?d00001 diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History_files/background.gif b/doc/The UNIX System -- History and Timeline -- UNIX History_files/background.gif new file mode 100755 index 0000000000000000000000000000000000000000..e106710266c0ee995e2b334a40ef55ed6355ae6d GIT binary patch literal 106 zcmZ?wbhEHbbYNp-Si}GV|NsAI=vc$i;mFb9#L;F4;xaHO{$ycfU|?g=0jU6~Wnk8i zaOU}>f5LP1UW?afcmGe&=u63*m$7PH&g*>zI_FDr?^mpQU-SO|fdvH~I#T@ySs1JV D9Wf`- literal 0 HcmV?d00001 diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History_files/code b/doc/The UNIX System -- History and Timeline -- UNIX History_files/code new file mode 100755 index 00000000..7244ebd4 --- /dev/null +++ b/doc/The UNIX System -- History and Timeline -- UNIX History_files/code @@ -0,0 +1,69 @@ +var s_un,s_ios=0,s_code='',code='',pageName,server,channel,pageType, +pageValue,product,prop1,prop2,prop3,prop4,prop5,prop6,prop7,prop8, +prop9,prop10,prop11,prop12,prop13,prop14,prop15,prop16,prop17,prop18, +prop19,prop20, +s_vb,s_e=false,s_n=navigator,s_u=s_n.userAgent,s_apn=s_n.appName,s_w= +s_n.appVersion,s_apv,s_i,s_ie=s_w.indexOf('MSIE '),s_ns6=s_u.indexOf( +'Netscape6/');if(s_w.indexOf('Opera')>=0||s_u.indexOf('Opera')>=0) +s_apn='Opera';if(s_ie>0){s_apv=parseInt(s_i=s_w.substring(s_ie+5));if( +s_apv>3)s_apv=parseFloat(s_i);}else if(s_ns6>0)s_apv=parseFloat( +s_u.substring(s_ns6+10));else s_apv=parseFloat(s_w);if(s_apv>=4&&s_apn +!='Opera'&&(s_ns6<0||s_apv>=6.1))s_ios=1;function s_it(un){var imn= +'s_i_'+un;if(s_ios&&!document.images[imn])document.write('')}function s_rep(s,o,n){var c= +s.indexOf(o);while(c>=0){s=s.substr(0,c)+n+s.substr(c+1,s.length);c= +s.indexOf(o)}return s}function s_esc(s){return s_rep(escape(s),'+', +'%2B')}function s_et(){window.onerror=window.oe;s_e=1;s_code=s_dc( +s_un);if(s_code)document.write(s_code);s_e=0;return true} +function s_dc(un){s_un=un;var unc=s_rep(un,'_','-'),imn='s_i_'+un,r='' +,r_d=0;if(!s_e){ +/*@cc_on@if(@_jscript_version>=5){try{r=parent.document.referrer;}catch(e){s_e=1}r_d=1}@end@*/ +if(!r_d){if(s_u.indexOf('Mac')>=0&&s_u.indexOf('MSIE 4')>=0)r= +document.referrer;else{window.oe=window.onerror;window.onerror=s_et;r= +parent.document.referrer}}}r=r?r:(s_e?'External Frame Referrer':'NULL' +);document.cookie='s_cc=true';var tm=new Date,sess='ss'+Math.floor( +tm.getTime()/10800000)%10+tm.getTime()%10000000000000,s='',c='',v='', +p='',bw='',bh='',j='1.0',vb=s_vb?s_vb:'',a=s_apn+' '+s_apv,g= +window.location.href,o=navigator.platform,yr=tm.getYear(),t= +tm.getDate()+'/'+tm.getMonth()+'/'+(yr<1900?yr+1900:yr)+' ' ++tm.getHours()+':'+tm.getMinutes()+':'+tm.getSeconds()+' '+tm.getDay() ++' '+tm.getTimezoneOffset(),k=document.cookie.indexOf('s_cc=')>=0?'Y': +'N',hp='',ct='';if(s_apv>=4)s=screen.width+'x'+screen.height;if(s_apn +=='Netscape'||s_apn=='Opera'){if(s_apv>=3){j='1.1';var i1=0,i2=0,sta; +while(i2<30&&i1100)sta=sta.substring(0,100); +sta+=';';if(p.indexOf(sta)<0)p+=sta;i1++;i2++}v=navigator.javaEnabled( +)?'Y':'N'}if(s_apv>=4){j='1.2';c=screen.pixelDepth;bw= +window.innerWidth;bh=window.innerHeight}if(s_apv>=4.06)j='1.3'}else if +(s_apn=='Microsoft Internet Explorer'){if(s_apv<4)r='NULL';if(s_apv>=4 +){v=navigator.javaEnabled()?'Y':'N';j='1.2';c=screen.colorDepth}if( +s_apv>=5){bw=document.documentElement.offsetWidth;bh= +document.documentElement.offsetHeight;j='1.3';if(s_u.indexOf('Mac')<0) +{document.body.addBehavior("#default#homePage");hp= +document.body.isHomePage(location.href)?"Y":"N"; +document.body.addBehavior("#default#clientCaps");ct= +document.body.connectionType}}} +code='http://stats.superstats.com/b/ss/'+un+'/1/c4.3/' ++sess+'?'+(s_apn!='Opera'?'[AQB]':'')+'&box=code.superstats.com' ++(r?'&r='+s_esc(r):'')+(s?'&s='+s_esc(s):'')+(c?'&c='+s_esc(c):'')+(o? +'&o='+s_esc(o):'')+(j?'&j='+j:'')+(v?'&v='+v:'')+(k?'&k='+k:'')+(bw? +'&bw='+bw:'')+(bh?'&bh='+bh:'')+(t?'&t='+s_esc(t):'')+(vb?'&vb='+vb:'' +)+(ct?'&ct='+s_esc(ct):'')+(hp?'&hp='+hp:'')+(pageName?'&pageName=' ++s_esc(pageName):'')+(server?'&server='+s_esc(server):'')+(channel? +'&ch='+s_esc(channel):'')+(pageType?'&pageType='+s_esc(pageType):'')+( +pageValue?'&pageValue='+s_esc(pageValue):'')+(product?'&product=' ++s_esc(product):'')+(prop1?'&c1='+s_esc(prop1):'')+(prop2?'&c2=' ++s_esc(prop2):'')+(prop3?'&c3='+s_esc(prop3):'')+(prop4?'&c4='+s_esc( +prop4):'')+(prop5?'&c5='+s_esc(prop5):'')+(prop6?'&c6='+s_esc(prop6): +'')+(prop7?'&c7='+s_esc(prop7):'')+(prop8?'&c8='+s_esc(prop8):'')+( +prop9?'&c9='+s_esc(prop9):'')+(prop10?'&c10='+s_esc(prop10):'')+( +prop11?'&c11='+s_esc(prop11):'')+(prop12?'&c12='+s_esc(prop12):'')+( +prop13?'&c13='+s_esc(prop13):'')+(prop14?'&c14='+s_esc(prop14):'')+( +prop15?'&c15='+s_esc(prop15):'')+(prop16?'&c16='+s_esc(prop16):'')+( +prop17?'&c17='+s_esc(prop17):'')+(prop18?'&c18='+s_esc(prop18):'')+( +prop19?'&c19='+s_esc(prop19):'')+(prop20?'&c20='+s_esc(prop20):'') ++(g?'&g='+s_esc(g):'')+(a?'&a='+s_esc(a):'')+(p?'&p='+s_esc(p):'')+( +s_apn!='Opera'?'[AQE]':'');if(s_ios&&document.images[imn]){ +document.images[imn].src=code;code=''}else code='';return code} +s_it('johnbligh');s_code=code=s_dc('johnbligh') diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History_files/info1.css b/doc/The UNIX System -- History and Timeline -- UNIX History_files/info1.css new file mode 100755 index 00000000..ef19252b --- /dev/null +++ b/doc/The UNIX System -- History and Timeline -- UNIX History_files/info1.css @@ -0,0 +1,105 @@ +A:link { + COLOR: #0000ff +} +A:visited { + COLOR: #0000ff +} +A:active { + COLOR: #0000ff +} +A:hover { + COLOR: #ff0000; TEXT-DECORATION: underline +} +H1 { + COLOR: #006600; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 20pt +} +H2 { + COLOR: #006600; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 15pt +} +H3 { + COLOR: #006600; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 12pt +} +H4 { + COLOR: #006600; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 11pt; FONT-STYLE: italic +} +H5 { + COLOR: #006600; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 10pt +} +H6 { + COLOR: #006666; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; FONT-WEIGHT: bold +} +NORMAL { + COLOR: #000000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +BODY { + COLOR: #000000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +P.certificate { + FONT-FAMILY: Courier New, Courier,monospace; FONT-SIZE: 12pt; MARGIN-LEFT: 5%; MARGIN-RIGHT: 5%; TEXT-ALIGN: left; WORD-SPACING: 8pt +} +.small { + COLOR: #000000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 8pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +.biggreen { + COLOR: #006600; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 11pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +.h6 { + COLOR: #006600; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; FONT-WEIGHT: bold +} +.h5 { + COLOR: #006600; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 10pt; FONT-WEIGHT: bold +} +.h1 { + COLOR: #006600; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 20pt; FONT-WEIGHT: bold +} +.h2 { + COLOR: #006600; FONT-FAMILY: Arial, Helvetica, sans-serif; FONT-SIZE: 15pt; FONT-WEIGHT: bold +} +.norm { + COLOR: #000000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +.green { + COLOR: #006600; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +.red { + COLOR: #ff0000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +.greenback { + BACKGROUND-COLOR: #99ff99 +} +.blueback { + BACKGROUND-COLOR: #ccccff +} +.whiteback { + BACKGROUND-COLOR: white +} +P { + COLOR: #000000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +BLOCKQUOTE.body { + FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; MARGIN-BOTTOM: 0pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt; TEXT-INDENT: 10px +} +TABLE { + COLOR: #000000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +TD { + COLOR: #000000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt; MARGIN-LEFT: 0pt; MARGIN-TOP: 0pt +} +UL { + COLOR: #000000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt +} +LI { + COLOR: #000000; FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif; FONT-SIZE: 9pt +} +HR { + COLOR: #009900; LINE-HEIGHT: 1px +} +.mandatory { + COLOR: red +} +.red { + COLOR: red +} +.blue { + COLOR: blue +} diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History_files/opengroup-logo.gif b/doc/The UNIX System -- History and Timeline -- UNIX History_files/opengroup-logo.gif new file mode 100755 index 0000000000000000000000000000000000000000..0796cfbd5c3a7ce698e0a85ad3cc63bfa3af919d GIT binary patch literal 3921 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 XOs}3Tum0R#{qf6}W+B;fUb7T=oM literal 0 HcmV?d00001 diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History_files/topcell.gif b/doc/The UNIX System -- History and Timeline -- UNIX History_files/topcell.gif new file mode 100755 index 0000000000000000000000000000000000000000..a4fa1d62a592d0cc6f24bb7538960383d423d91d GIT binary patch literal 374 zcmV-+0g3)cNk%w1VHyMs0HOc@00030|Nj7ptO$rg|Ns900000000000A^8LW000C4 zEC2ui02%}g000C3NV?qqFv>}*y*TT=hyP$Gj$~<`XsWJk>%MR-&vb3yc&_h!@BhG{ za7c`Cj>x2P$!s2r(5Q4uty-_xtai)odcP#6cuX#vnc%c~&2GEj@VIs;jK6uCK7M zva__cwzs&sy1Tr+zQ4f1!o$SDoX5z?%F7G_&d<=%($mz{*4NnC+S}aS-rwNi;^XAy z=I7|?>g(+7?(gvN^3Kfl_V@Tr^ZWe${{H|23LHqVpuvL(5$0RSu%SZ*2_s6JNU@^D zix@L%+?eh=p~sIPGjSYAvZTqAC{wCjDKDhUmoUY!oJq5$&6_xL>Kqrdr_Yzgf(ji< Uw5ZXeNRujE%CxD|VhI2MJHk=RJpcdz literal 0 HcmV?d00001 diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History_files/under-logo2.gif b/doc/The UNIX System -- History and Timeline -- UNIX History_files/under-logo2.gif new file mode 100755 index 0000000000000000000000000000000000000000..539e691ebc04f6b4705ec13302912fd06958e538 GIT binary patch literal 222 zcmV<403rWJNk%w1VHyMm0FeLy00030|Nj7ptpET2A^8LW00093EC2ui02%}a00087 zoR0&`?GK}zwAzca-n{z{hT=$;=82~2%C_zc$MQ_qc9Z17&iDQg3<`(DqVb4KDwTnz z^9hYgr_`$Tip^@b+^+Wv4vWX+viXcotJmzd`wfrF=k#eVvCQlD{Jy_m7brMLSZH{N zn5ekO*y#8O>2-(jS7~{PnduYB+3EQS8Y((UT55VaHhG}Q+Uokci7GowTWfoZo2$DE YrfL8S94xHITWoxcoUFXed|UtkI}0dpCIA2c literal 0 HcmV?d00001 diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History_files/unix_plate-small.jpg b/doc/The UNIX System -- History and Timeline -- UNIX History_files/unix_plate-small.jpg new file mode 100755 index 0000000000000000000000000000000000000000..f17b4e79eb1a5d349a6c33becba9b5dbfb16c73d GIT binary patch literal 20958 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 literal 0 HcmV?d00001 diff --git a/doc/The UNIX System -- History and Timeline -- UNIX History_files/what_is_unix.htm b/doc/The UNIX System -- History and Timeline -- UNIX History_files/what_is_unix.htm new file mode 100755 index 00000000..0abff050 --- /dev/null +++ b/doc/The UNIX System -- History and Timeline -- UNIX History_files/what_is_unix.htm @@ -0,0 +1,530 @@ + + +The UNIX System -- The Single UNIX Specification + + + + + + + + + + + + + + + +

+
+UNIX System Home + •   +The Single UNIX Specification + •   +UNIX 98 + •   +UNIX.net + •   +Mailing Lists + •   +White Papers +
+

+ + +

The Single UNIX Specification

+
+ + +
+ + + + + + +
+ +
+
+ + + + + +
+ + +
History & Timeline
+
The Single UNIX Specification
+
Registered Products
+
The UNIX Brand
+
What About All Those "Flavors"
+
Version 2 of the Single UNIX Specification
+
Version 3 of the Single UNIX Specification
+
UNIX API Tables
+
Why This is Different
+ + + +
+ + + + Introduction
+History
+Structure and Contents
+The 1170 Initiative
+Platform Vendors Supporting the Single UNIX Specification
+ISVs and User Organizations Supporting the Common API Specification
+The Single UNIX Specification
+System Interfaces and Headers (XSH)
+Corrigenda
+

+ +
+  + +

Introduction
+Many names have been applied to the work that has culminated in the Single UNIX +Specification and its attendant X/Open UNIX brand. It began as the Common API +Specification, became Spec 1170, and is now the Single UNIX Specification published in a +number of X/Open Common Applications Environment (CAE) volumes.
+
+This paper briefly describes the history of Spec 1170, and its journey to becoming the +Single UNIX Specification, along with the organization of that specification.
+
+ History
+Previously the UNIX operating system has been a product with four elements (Figure 1); the +specification (e.g. SVID) , the technology (e.g. SVR4), the registered trade mark (UNIX), +and the product (e.g. UNIXWare).
+
+
+Figure 1
+
+With the Single UNIX Specification, there is now a single, open, consensus specification +that defines a product. There is also a mark, or brand, that is used to identify those +products that conform to the Single UNIX specification. Both the specification and the +trade mark are now managed and held in trust for the industry by X/Open Company.
+
+There will be many competing products, all implemented against the Single UNIX +Specification, ensuring competition and vendor choice. There will be a limited number of +technology suppliers, which vendors can license and build there own product, all of them +implementing the Single UNIX Specification. . Buyers can expect each of these products to +carry the X/open UNIX brand as an guarantee of conformance to the specification and that +the vendor stands behind a quality product.
+
+UNIX is now no longer just the operating system product from AT&T (later, Novell), +documented by the System V Interface Definition (SVID), controlled and licensed from a +single point. Neither is it a collection of slightly different products from different +vendors, each extended in slightly different ways. The UNIX specification has been +separated from its licensed source-code product, and "UNIX'' has become a single +stable specification to be used to develop portable applications that run on systems +conforming to the Single UNIX Specification
+
+ Structure and Contents
+The Single UNIX Specification is a collection of documents that are part of the X/Open +Common Applications Environment (CAE), and include:
+
+

+ + + +


+A UNIX 95 branded product is built from a number of components (in X/Open language) and +includes:
+
+ +

    +
  • XPG4 Internationalized System Calls and Libraries (Extended), covering POSIX.1 and + POSIX.2 callable interfaces, the ISO C library and Multibyte Support Extension addendum, + the Single UNIX Specification extension including STREAMS, the Shared Memory calls, + application internationalization interfaces, and a wealth of other application interfaces.
  • +
  • XPG4 Commands and Utilities V2, covering the POSIX.2 Shell and Utilities, and a large + number of additional commands and development utilities.
  • +
  • XPG4 C Language
  • +
  • XPG4 Sockets
  • +
  • XPG4 Transport Interfaces (XTI)
  • +
  • XPG4 Internationalized Terminal Interfaces including the new extensions to support color + and multibyte characters.
  • +
+ +


+The Single UNIX Specification is supported by the X/Open UNIX brand, which in turn is +supported by a verification program. The X/Open brand provides the guarantee that products +adhere to the relevant X/Open specification. Systems that provide the Single UNIX +Specification interfaces can be X/Open UNIX branded as proof to the marketplace. The +Single UNIX Specification is the programmer's reference to the portability environment +provided on X/Open UNIX branded systems.
+
+It is important for application developers to realize that in committing to the brand, the +vendor is obligating themselves to conform. X/Open conformance verification suites are +vendors' ways of measuring their implementation against the specification, providing a +guarantee that they have implemented the specification correctly.
+
+And the X/Open brand commitment goes even deeper than this. It is a promise by the vendor +to conform to the specification, not to the test suite. If a user of a branded system +discovers an interface that does not behave according to the specification, regardless of +whether or not a test case in the verification suite passed in this area, the vendor is +obliged to correct the defect within explicit time frames.
+
+The base is now in place to better support portable applications development by:
+
+ +

    +
  • Providing a rich set of interfaces that cover a broad range of "historical UNIX + systems" practice, simplifying the porting of existing applications, and protecting + current application development investments.
  • +
  • Providing a stable specification against which to write applications that will be + portable to many platforms, and a stable methodology to evolve the specification in a + manner that is not under the control of any single vendor or vendor consortium.
  • +
  • Ensuring that the portability model embodied in the specifications is based as much as + possible on standards.
  • +
  • Supporting the specification with an X/Open branding program to provide both halves of + the portability formula, where application developers can write source code to the + specification, and purchase products branded to the specification with the confidence that + the application will port in a very straightforward manner.
  • +
+ +


+ The Spec 1170 Initiative
+The Common API Specification project started when several vendors (Sun Microsystems, IBM, +Hewlett-Packard, Novell/USL and OSF) organized together to provide a single unified +specification of the UNIX system services. By implementing a single common definition of +the UNIX system services, third-party independent software vendors (ISVs) would be able to +more easily deliver strategic applications on all of these vendors' platforms at once.
+
+The focus of this initiative was to deliver the core application interfaces used by +current programs. The economic driver that initiated the project was to ease the porting +of existing successful applications. While the work was led by a central group of vendors, +it received widespread support within the industry.
+
+ Platform Vendors Supporting the Single UNIX +Specification:1
+Acer; Amdahl; Apple; AT&T GIS; Bull; Convex; Cray; Data General; Compaq; Encore; 88 +Open; Fuji Xerox; Fujitsu Ossi; Hal; Hewlett-Packard; Hitachi; IBM; ICL; Matsushita; Mips +ABI; Mitsubishi; Motorola; NEC; Novell/USL; Oki; Olivetti; OSF; PowerOpen; Precision RISC; +Pyramid; SCO; Sequent; Sequoia; Sharp; Siemens-Nixdorf; Silicon Graphics; Sony; Sparc +International; Stratus; Sun Microsystems; Tadpole; Tandem; +Thompson/Cetia; Toshiba; Unisys; Wang Labs.
+
+ ISVs and User Organizations Supporting the Common API +Specification:
+AutoDesk; Banyan; Bellcore; Bentley; Cadence; Cadre; Chorus; Computer Associates; DHL; EDS +Unigraphics; Frame Tech; Informix; Island Software; Lachman Tech; Locus; Lotus; +McDonald's; Mentor; Oracle; Pencom Systems; SDRC; Software AG; Shell Oil; Veritas; +Wal-Mart; WordPerfect.
+
+A two-pronged approach was used to develop the Common API Specification. First, a set of +formal industry specifications was chosen to form the overall base for the work. This +would provide stability, vendor neutrality, and lay a well charted course for future +application development, taking advantage of the careful work that has gone into +developing these specifications. It would also preserve the portability of existing +applications already developed to these core models.
+
+X/Open Company's XPG4 Base was chosen as the stable functional base from which to start. +XPG4 Base supports the POSIX.1 system interface and the ANSI/ISO C standards at its core. +It provides a rich set of 174 commands and utilities.
+
+Many UNIX systems already conform to this specification. To this base was added the +traditional UNIX System V Interface Definition, (SVID) Edition 3, Level 1 calls, and the +OSF Application Environment Specification Full Use interface definitions. This represented +the stable central core of the latter two specifications.
+
+The second part of the approach was to incorporate interfaces that are acknowledged common +practice but have not yet been incorporated into any formal specification or standard. The +intent was to ensure existing applications running on UNIX systems would port with +relative ease to a platform supporting the Common API Specification. A survey of real +world applications was used to determine what additional interfaces would be required in +the specification.
+
+Fifty successful application packages were chosen to be analyzed using the following +criteria:
+
+ +

    +
  • Ranked in International Data Corp's. 1992, 'Survey of Leading UNIX Applications',
  • +
  • The application's domain of applicability was checked to ensure that no single + application type (for example, databases) was overly represented,
  • +
  • The application had to be available for analysis either as source code, or as a shared + or dynamic linked library.
  • +
+ +

From the group of fifty, the top ten were selected carefully, ensuring that no more +than two representative application packages in a particular problem space were chosen. +The ten chosen applications were:
+
+AutoCAD; Cadence; FrameMaker; Informix; Island Write/Paint; Lotus 1-2-3; SAS (4GL); +Sybase; Teamwork; WordPerfect
+
+APIs used by the applications that were not part of the base specifications were analyzed:
+
+ +

    +
  • If an API was used by any of the top ten applications, it was considered for inclusion.
  • +
  • If an API was not used by one of the top ten, but was used by any three of the remaining + 40 applications, it was considered for inclusion.
  • +
  • While the investigation of these 50 applications was representative of large complex + applications, it still was not considered as a broad enough survey, so an additional 3500 + modules were scanned. If an API was used at least seven times in modules that came from at + least two platforms (to screen out vendor specific libraries), then the interface was + considered for inclusion.
  • +
+ +

The goal was to ensure that APIs in common use were included, even if they were not in +the formal specifications that made up the base. Making the Common API Specification a +superset of existing base specifications ensured any existing applications should work +unmodified. The sponsors of the work considered pruning the Common API Specification of +interfaces from the base specifications that were not found to be in common use in the +application survey.
+
+This idea was rejected for two reasons. While some of the interfaces in the base +specifications are not yet considered common practice, their inclusion in the overall +specification meant there existed clear sign-posts for future applications development +work. As well, it was recognized that the applications chosen for the survey were still +only a representative sample, and that many other applications not surveyed may use these +interfaces.
+
+When the survey was complete, there were 130 interfaces that did not already appear in the +base specification. These interfaces seem to be predominantly Berkeley UNIX calls that had +never been covered in XPG4 Base, the SVID, or the AES, but did represent common practice +in UNIX system applications developed originally on BSD-derived platforms. Such things as +sockets and the 4.3BSD memory management calls were commonly used in many applications.
+
+The resulting Common API Specification was impressive in its coverage. The top ten +applications surveyed were completely covered. Of the remaining 40 application packages, +the next 25 were within 5% of complete coverage. The software vendors involved all +acknowledged that it would be fairly straightforward for them to modify the 5% of the +application to conform fully to the specification.
+
+There were 1170 interfaces in the complete specification when the work was done (926 +programming interfaces, 70 headers, 174 commands and utilities), and the name of Spec 1170 +was born.
+
+Because of the breadth and origins of the specification, duplication of functionality +existed. There were similar interfaces for doing the same thing in such areas as memory +management (bcopy versus memmove) and creating temporary filenames (tmpnam versus mktemp). +This duplication was allowed as it would increase the number of existing applications that +would be portable in the new model. At the same time, certain functions have been +identified as the recommended practice for future development. There are cases where the +duplicated functionality cannot co-exist in the same application (for example, conflicting +signals models), and it is important to ensure that the is correctly configured if the +expected behavior is to be observed.
+
+In December 1993, Spec 1170 was delivered to X/Open for fast-track processing into a +proper industry supported specification. This work progressed through 1994 and culminated +in the publication of the Spec 1170 work as the Single UNIX Specification in October 1994. +There are now more than 1170 interfaces in the specification as the review process shaped +the document accordingly. (The new internationalized curses specification contributed a +large number of interfaces.)
+
+The Single UNIX Specification documents are part of the X/Open CAE (Common Applications +Environment) document set.
+
+ The Single UNIX Specification
+Five X/Open CAE documents make up the Single UNIX Specification. These are:
+
+ +

    +
  • System Interface Definitions, Issue 4, + Version 2 (XBD)
    + The XBD document outlines the common definitions used by both the System Interfaces and + Headers, and the Commands and Utilities documents. Such items as locales and regular + expression grammars appear here, along with a large glossary defining common terms and + concepts.
  • +
  • System Interfaces and Headers, Issue 4, Version + 2 (XSH)
    + The XSH document describes all of the programming interfaces and headers available in the + Single UNIX Specification with the exception of the networking and terminal interfaces + (contained in their own documents). The front section introduces general concerns with + respect to usage guidelines, the compilation environment, error numbers, types, standard + streams and STREAMS. The rest of the document is the reference pages describing each + interface (in alphabetical order) and its use, and each header and its contents.
  • +
  • Commands and Utilities, Issue 4, Version 2 (XCU)
    + The XCU document describes all of the commands and utilities available in the Single UNIX + Specification. The first section describes the syntax and functionality of the shell in + depth. The rest of the document is the reference pages describing each command and utility + (in alphabetic order) and its use.
  • +
  • Networking Services, Issue 4
    + Three sets of networking services are defined in the Single UNIX Specification, X/Open + Transport Interface (XTI), XPG4 Sockets, and IP Address Resolution interfaces. These + services are described in the Networking Services document, along with appendices + containing useful additional protocol information and examples.
  • +
  • X/Open Curses, Issue 4
    + The X/Open Curses interfaces are described in this document. It is an upwardly compatible + version of X/Open Curses, Version 3, extended to support internationalization, enhanced + character sets, and different writing directions.
  • +
+ + +

+The System Interfaces and Headers (XSH)
+System Interfaces and Headers specification contains the base interfaces and several +"feature" groups. Interfaces that are part of a feature group have a feature +group specific label that appears in the header of the interface's reference page.
+
+XSH (System Interfaces and Headers) contains the following feature groups:
+
+ +

    +
  • POSIX.2 C-language binding covering regular expression matching, word expansion, and + filename matching. The label POSIX.2 CLB appears in the header of each of these function's + reference page.
  • +
  • Single UNIX Specification Extension covering all the functions that have been added to + XPG4 to create the Single UNIX Specification. The label SINGLE UNIX SPECIFICATION appears + in the header of each of these function's reference page.
  • +
  • Shared Memory covering the SVID 3 kernel extension calls to manage shared memory. The + label SHARED MEM appears in the header of each of these function's reference page.
  • +
  • Enhanced Internationalization adding functions that are not yet in wide use for + internationalizing applications, but will hopefully provide future direction and a + converging path for functionality of this type. The label ENHANCED I18N appears in the + header of each of these function's reference page.
  • +
  • Encryption covering the functions crypt, encrypt, and setkey. The label CRYPT appears in + the header of each of these function's reference page. Anything that does not fall into + the feature groups listed above is considered to be base functionality, and marked with + the label BASE in the reference page heading.
  • +
+ +

XPG4 Base did not require all of the feature groups for conforming implementations. +Only the base interfaces were mandatory. To conform to Single UNIX Specification, an +implementation will need to support all of the feature groups with the exception of the +encryption interfaces. (There are U.S. government export restrictions on this technology +that may disallow some vendors from shipping it.)
+
+The Commands and Utilities (XCU) specification describes all of the utilities required in +the environment. Some of these utilities do not need to be present, being contained in +``packages'' that need not be implemented.
+
+ +

    +
  • DEVELOPMENT utilities are those required in a software development environment.
  • +
  • FORTRAN utilities are required in a FORTRAN-77 development environment, and essentially + consists of the compiler, fort77.
  • +
  • A number of utilities are considered to be "possibly insupportable", and need + not be implemented. These include such commands as lpstat and uulog.
  • +
+ +

The only real effect that the Single UNIX Specification had on the XCU +(Commands and Utilities) document from Issue 4, was to modify the cc and c89 C compiler +commands.
+
+A programmer developing applications on an Single UNIX Specification system has at their +disposal all of the functions, commands and utilities described in the Single UNIX +Specification document set. This functional superset of consensus-based specifications and +historical practice also creates a straightforward environment for porting existing +applications running on UNIX systems.
+
+Products that implement Single UNIX Specification and qualify for the X/Open UNIX brand +will compile and run applications built or ported according to this model.
+
+***Edited from "Go Solo - +How to Implement and Utilize the Single UNIX Specification"; published by X/Open +and Prentice Hall PTR.
+Information about this, and other X/Open publications may be obtained from any X/Open +office or by sending e-mail to: XoPubs@xopen.org
+X/Open is a registered trade mark, and the "X" device is a trade mark of X/Open +Company Limited. UNIX is a registered trade mark in the United States and other countries, +licensed exclusively through X/Open Company Limited
+
+  +Footnote 1: +This is a list of vendors who have expressed support for the +specification and does not constitute any endorsement by The +Open Group of the company or their products. + + + + + +

 

+
+
+
+
+
Home + • Contacts + • Legal + • Copyright + Members +  News +
+
+
© The Open Group 1995-2003 + +  Updated on + Monday, 25 June 2001 +
+ + + + + + + +
+ +
+ +
+
+ + + + +

+ +

+ + diff --git a/doc/UNIX Evolution.htm b/doc/UNIX Evolution.htm new file mode 100755 index 00000000..c17ac115 --- /dev/null +++ b/doc/UNIX Evolution.htm @@ -0,0 +1,861 @@ + + +UNIX Evolution + + + +
+ + + +
  +

The Evolution of the Unix Time-sharing System* +

+
+
Dennis M. Ritchie
Bell Laboratories, Murray + Hill, NJ, 07974
+
+
+

ABSTRACT

+

This paper presents a brief history of the early + development of the Unix operating system. It concentrates on the + evolution of the file system, the process-control mechanism, and the + idea of pipelined commands. Some attention is paid to social conditions + during the development of the system.

+



+

+
NOTE: *This paper was first presented at the + Language Design and Programming Methodology conference at Sydney, + Australia, September 1979. The conference proceedings were published as + Lecture Notes in Computer Science #79: Language Design and + Programming Methodology, Springer-Verlag, 1980. This rendition is + based on a reprinted version appearing in AT&T Bell Laboratories + Technical Journal 63 No. 6 Part 2, October 1984, pp. 1577-93. + +
+


+

Introduction

+

During the past few years, the Unix operating system + has come into wide use, so wide that its very name has become a trademark + of Bell Laboratories. Its important characteristics have become known to + many people. It has suffered much rewriting and tinkering since the first + publication describing it in 1974 [1], but few fundamental changes. + However, Unix was born in 1969 not 1974, and the account of its + development makes a little-known and perhaps instructive story. This paper + presents a technical and social history of the evolution of the system. +

+

Origins

+

For computer science at Bell Laboratories, the period + 1968-1969 was somewhat unsettled. The main reason for this was the slow, + though clearly inevitable, withdrawal of the Labs from the Multics + project. To the Labs computing community as a whole, the problem was the + increasing obviousness of the failure of Multics to deliver promptly any + sort of usable system, let alone the panacea envisioned earlier. For much + of this time, the Murray Hill Computer Center was also running a costly GE + 645 machine that inadequately simulated the GE 635. Another shake-up that + occurred during this period was the organizational separation of computing + services and computing research.

+

From the point of view of the group that was to be + most involved in the beginnings of Unix (K. Thompson, Ritchie, M. D. + McIlroy, J. F. Ossanna), the decline and fall of Multics had a directly + felt effect. We were among the last Bell Laboratories holdouts actually + working on Multics, so we still felt some sort of stake in its success. + More important, the convenient interactive computing service that Multics + had promised to the entire community was in fact available to our limited + group, at first under the CTSS system used to develop Multics, and later + under Multics itself. Even though Multics could not then support many + users, it could support us, albeit at exorbitant cost. We didn't want to + lose the pleasant niche we occupied, because no similar ones were + available; even the time-sharing service that would later be offered under + GE's operating system did not exist. What we wanted to preserve was not + just a good environment in which to do programming, but a system around + which a fellowship could form. We knew from experience that the essence of + communal computing, as supplied by remote-access, time-shared machines, is + not just to type programs into a terminal instead of a keypunch, but to + encourage close communication.

+

Thus, during 1969, we began trying to find an + alternative to Multics. The search took several forms. Throughout 1969 we + (mainly Ossanna, Thompson, Ritchie) lobbied intensively for the purchase + of a medium-scale machine for which we promised to write an operating + system; the machines we suggested were the DEC PDP-10 and the SDS (later + Xerox) Sigma 7. The effort was frustrating, because our proposals were + never clearly and finally turned down, but yet were certainly never + accepted. Several times it seemed we were very near success. The final + blow to this effort came when we presented an exquisitely complicated + proposal, designed to minimize financial outlay, that involved some + outright purchase, some third-party lease, and a plan to turn in a DEC + KA-10 processor on the soon-to-be-announced and more capable KI-10. The + proposal was rejected, and rumor soon had it that W. O. Baker (then + vice-president of Research) had reacted to it with the comment `Bell + Laboratories just doesn't do business this way!'

+

Actually, it is perfectly obvious in retrospect (and + should have been at the time) that we were asking the Labs to spend too + much money on too few people with too vague a plan. Moreover, I am quite + sure that at that time operating systems were not, for our management, an + attractive area in which to support work. They were in the process of + extricating themselves not only from an operating system development + effort that had failed, but from running the local Computation Center. + Thus it may have seemed that buying a machine such as we suggested might + lead on the one hand to yet another Multics, or on the other, if we + produced something useful, to yet another Comp Center for them to be + responsible for.

+

Besides the financial agitations that took place in + 1969, there was technical work also. Thompson, R. H. Canaday, and Ritchie + developed, on blackboards and scribbled notes, the basic design of a file + system that was later to become the heart of Unix. Most of the design was + Thompson's, as was the impulse to think about file systems at all, but I + believe I contributed the idea of device files. Thompson's itch for + creation of an operating system took several forms during this period; he + also wrote (on Multics) a fairly detailed simulation of the performance of + the proposed file system design and of paging behavior of programs. In + addition, he started work on a new operating system for the GE-645, going + as far as writing an assembler for the machine and a rudimentary operating + system kernel whose greatest achievement, so far as I remember, was to + type a greeting message. The complexity of the machine was such that a + mere message was already a fairly notable accomplishment, but when it + became clear that the lifetime of the 645 at the Labs was measured in + months, the work was dropped.

+

Also during 1969, Thompson developed the game of + `Space Travel.' First written on Multics, then transliterated into Fortran + for GECOS (the operating system for the GE, later Honeywell, 635), it was + nothing less than a simulation of the movement of the major bodies of the + Solar System, with the player guiding a ship here and there, observing the + scenery, and attempting to land on the various planets and moons. The + GECOS version was unsatisfactory in two important respects: first, the + display of the state of the game was jerky and hard to control because one + had to type commands at it, and second, a game cost about $75 for CPU time + on the big computer. It did not take long, therefore, for Thompson to find + a little-used PDP-7 computer with an excellent display processor; the + whole system was used as a Graphic-II terminal. He and I rewrote Space + Travel to run on this machine. The undertaking was more ambitious than it + might seem; because we disdained all existing software, we had to write a + floating-point arithmetic package, the pointwise specification of the + graphic characters for the display, and a debugging subsystem that + continuously displayed the contents of typed-in locations in a corner of + the screen. All this was written in assembly language for a + cross-assembler that ran under GECOS and produced paper tapes to be + carried to the PDP-7.

+

Space Travel, though it made a very attractive game, + served mainly as an introduction to the clumsy technology of preparing + programs for the PDP-7. Soon Thompson began implementing the paper file + system (perhaps `chalk file system' would be more accurate) that had been + designed earlier. A file system without a way to exercise it is a sterile + proposition, so he proceeded to flesh it out with the other requirements + for a working operating system, in particular the notion of processes. + Then came a small set of user-level utilities: the means to copy, print, + delete, and edit files, and of course a simple command interpreter + (shell). Up to this time all the programs were written using GECOS and + files were transferred to the PDP-7 on paper tape; but once an assembler + was completed the system was able to support itself. Although it was not + until well into 1970 that Brian Kernighan suggested the name `Unix,' in a + somewhat treacherous pun on `Multics,' the operating system we know today + was born.

+

The PDP-7 Unix file system

+

Structurally, the file system of PDP-7 Unix was nearly + identical to today's. It had +

+
1) +
An i-list: a linear array of i-nodes each + describing a file. An i-node contained less than it does now, but the + essential information was the same: the protection mode of the file, its + type and size, and the list of physical blocks holding the contents. + +
2) +
Directories: a special kind of file containing a + sequence of names and the associated i-number. +
3) +
Special files describing devices. The device + specification was not contained explicitly in the i-node, but was + instead encoded in the number: specific i-numbers corresponded to + specific files.
+

The important file system calls were also present from + the start. Read, write, open, creat (sic), close: with one very important + exception, discussed below, they were similar to what one finds now. A + minor difference was that the unit of I/O was the word, not the byte, + because the PDP-7 was a word-addressed machine. In practice this meant + merely that all programs dealing with character streams ignored null + characters, because null was used to pad a file to an even number of + characters. Another minor, occasionally annoying difference was the lack + of erase and kill processing for terminals. Terminals, in effect, were + always in raw mode. Only a few programs (notably the shell and the editor) + bothered to implement erase-kill processing.

+

In spite of its considerable similarity to the current + file system, the PDP-7 file system was in one way remarkably different: + there were no path names, and each file-name argument to the system was a + simple name (without `/') taken relative to the current directory. Links, + in the usual Unix sense, did exist. Together with an elaborate set of + conventions, they were the principal means by which the lack of path names + became acceptable.

+

The link call took the form +

+

+
+link(dir, file, newname)
+
+
+

where dir was a directory file in the current + directory, file an existing entry in that directory, and + newname the name of the link, which was added to the current + directory. Because dir needed to be in the current directory, it is + evident that today's prohibition against links to directories was not + enforced; the PDP-7 Unix file system had the shape of a general directed + graph.

+

So that every user did not need to maintain a link to + all directories of interest, there existed a directory called dd + that contained entries for the directory of each user. Thus, to make a + link to file x in directory ken, I might do +

+

+
+ln dd ken ken
+
+ln ken x x
+
+rm ken
+
+
+

This scheme rendered subdirectories sufficiently hard + to use as to make them unused in practice. Another important barrier was + that there was no way to create a directory while the system was running; + all were made during recreation of the file system from paper tape, so + that directories were in effect a nonrenewable resource.

+

The dd convention made the chdir command + relatively convenient. It took multiple arguments, and switched the + current directory to each named directory in turn. Thus +

+

+
+chdir dd ken
+
+
+

would move to directory ken. (Incidentally, + chdir was spelled ch; why this was expanded when we went to + the PDP-11 I don't remember.)

+

The most serious inconvenience of the implementation + of the file system, aside from the lack of path names, was the difficulty + of changing its configuration; as mentioned, directories and special files + were both made only when the disk was recreated. Installation of a new + device was very painful, because the code for devices was spread widely + throughout the system; for example there were several loops that visited + each device in turn. Not surprisingly, there was no notion of mounting a + removable disk pack, because the machine had only a single fixed-head + disk.

+

The operating system code that implemented this file + system was a drastically simplified version of the present scheme. One + important simplification followed from the fact that the system was not + multi-programmed; only one program was in memory at a time, and control + was passed between processes only when an explicit swap took place. So, + for example, there was an iget routine that made a named i-node + available, but it left the i-node in a constant, static location rather + than returning a pointer into a large table of active i-nodes. A precursor + of the current buffering mechanism was present (with about 4 buffers) but + there was essentially no overlap of disk I/O with computation. This was + avoided not merely for simplicity. The disk attached to the PDP-7 was fast + for its time; it transferred one 18-bit word every 2 microseconds. On the + other hand, the PDP-7 itself had a memory cycle time of 1 microsecond, and + most instructions took 2 cycles (one for the instruction itself, one for + the operand). However, indirectly addressed instructions required 3 + cycles, and indirection was quite common, because the machine had no index + registers. Finally, the DMA controller was unable to access memory during + an instruction. The upshot was that the disk would incur overrun errors if + any indirectly-addressed instructions were executed while it was + transferring. Thus control could not be returned to the user, nor in fact + could general system code be executed, with the disk running. The + interrupt routines for the clock and terminals, which needed to be + runnable at all times, had to be coded in very strange fashion to avoid + indirection.

+

Process control

+

By `process control,' I mean the mechanisms by which + processes are created and used; today the system calls fork, + exec, wait, and exit implement these mechanisms. + Unlike the file system, which existed in nearly its present form from the + earliest days, the process control scheme underwent considerable mutation + after PDP-7 Unix was already in use. (The introduction of path names in + the PDP-11 system was certainly a considerable notational advance, but not + a change in fundamental structure.)

+

Today, the way in which commands are executed by the + shell can be summarized as follows: +

+
1) +
The shell reads a command line from the terminal. + +
2) +
It creates a child process by fork. +
3) +
The child process uses exec to call in the + command from a file. +
4) +
Meanwhile, the parent shell uses wait to + wait for the child (command) process to terminate by calling + exit. +
5) +
The parent shell goes back to step 1). +
+

Processes (independently executing entities) existed + very early in PDP-7 Unix. There were in fact precisely two of them, one + for each of the two terminals attached to the machine. There was no + fork, wait, or exec. There was an exit, but + its meaning was rather different, as will be seen. The main loop of the + shell went as follows. +

+
1) +
The shell closed all its open files, then opened + the terminal special file for standard input and output (file + descriptors 0 and 1). +
2) +
It read a command line from the terminal. +
3) +
It linked to the file specifying the command, + opened the file, and removed the link. Then it copied a small bootstrap + program to the top of memory and jumped to it; this bootstrap program + read in the file over the shell code, then jumped to the first location + of the command (in effect an exec). +
4) +
The command did its work, then terminated by + calling exit. The exit call caused the system to read in a + fresh copy of the shell over the terminated command, then to jump to its + start (and thus in effect to go to step 1).
+

The most interesting thing about this primitive + implementation is the degree to which it anticipated themes developed more + fully later. True, it could support neither background processes nor shell + command files (let alone pipes and filters); but IO redirection (via + `<' and `>') was soon there; it is discussed below. The + implementation of redirection was quite straightforward; in step 3) above + the shell just replaced its standard input or output with the appropriate + file. Crucial to subsequent development was the implementation of the + shell as a user-level program stored in a file, rather than a part of the + operating system.

+

The structure of this process control scheme, with one + process per terminal, is similar to that of many interactive systems, for + example CTSS, Multics, Honeywell TSS, and IBM TSS and TSO. In general such + systems require special mechanisms to implement useful facilities such as + detached computations and command files; Unix at that stage didn't bother + to supply the special mechanisms. It also exhibited some irritating, + idiosyncratic problems. For example, a newly recreated shell had to close + all its open files both to get rid of any open files left by the command + just executed and to rescind previous IO redirection. Then it had to + reopen the special file corresponding to its terminal, in order to read a + new command line. There was no /dev directory (because no path + names); moreover, the shell could retain no memory across commands, + because it was reexecuted afresh after each command. Thus a further file + system convention was required: each directory had to contain an entry + tty for a special file that referred to the terminal of the process + that opened it. If by accident one changed into some directory that lacked + this entry, the shell would loop hopelessly; about the only remedy was to + reboot. (Sometimes the missing link could be made from the other + terminal.)

+

Process control in its modern form was designed and + implemented within a couple of days. It is astonishing how easily it + fitted into the existing system; at the same time it is easy to see how + some of the slightly unusual features of the design are present precisely + because they represented small, easily-coded changes to what existed. A + good example is the separation of the fork and exec + functions. The most common model for the creation of new processes + involves specifying a program for the process to execute; in Unix, a + forked process continues to run the same program as its parent until it + performs an explicit exec. The separation of the functions is + certainly not unique to Unix, and in fact it was present in the Berkeley + time-sharing system [2], which was well-known to Thompson. Still, it seems + reasonable to suppose that it exists in Unix mainly because of the ease + with which fork could be implemented without changing much else. + The system already handled multiple (i.e. two) processes; there was a + process table, and the processes were swapped between main memory and the + disk. The initial implementation of fork required only +

+
1) +
Expansion of the process table +
2) +
Addition of a fork call that copied the current + process to the disk swap area, using the already existing swap IO + primitives, and made some adjustments to the process table. +
+

In fact, the PDP-7's fork call required + precisely 27 lines of assembly code. Of course, other changes in the + operating system and user programs were required, and some of them were + rather interesting and unexpected. But a combined fork-exec would + have been considerably more complicated, if only because exec as + such did not exist; its function was already performed, using explicit IO, + by the shell.

+

The exit system call, which previously read in + a new copy of the shell (actually a sort of automatic exec but + without arguments), simplified considerably; in the new version a process + only had to clean out its process table entry, and give up control. +

+

Curiously, the primitives that became wait were + considerably more general than the present scheme. A pair of primitives + sent one-word messages between named processes: +

+

+
+smes(pid, message)
+
+(pid, message) = rmes()
+
+
+

The target process of smes did not need to have + any ancestral relationship with the receiver, although the system provided + no explicit mechanism for communicating process IDs except that + fork returned to each of the parent and child the ID of its + relative. Messages were not queued; a sender delayed until the receiver + read the message.

+

The message facility was used as follows: the parent + shell, after creating a process to execute a command, sent a message to + the new process by smes; when the command terminated (assuming it + did not try to read any messages) the shell's blocked smes call + returned an error indication that the target process did not exist. Thus + the shell's smes became, in effect, the equivalent of wait. +

+

A different protocol, which took advantage of more of + the generality offered by messages, was used between the initialization + program and the shells for each terminal. The initialization process, + whose ID was understood to be 1, created a shell for each of the + terminals, and then issued rmes; each shell, when it read the end + of its input file, used smes to send a conventional `I am + terminating' message to the initialization process, which recreated a new + shell process for that terminal.

+

I can recall no other use of messages. This explains + why the facility was replaced by the wait call of the present + system, which is less general, but more directly applicable to the desired + purpose. Possibly relevant also is the evident bug in the mechanism: if a + command process attempted to use messages to communicate with other + processes, it would disrupt the shell's synchronization. The shell + depended on sending a message that was never received; if a command + executed rmes, it would receive the shell's phony message, and + cause the shell to read another input line just as if the command had + terminated. If a need for general messages had manifested itself, the bug + would have been repaired.

+

At any rate, the new process control scheme instantly + rendered some very valuable features trivial to implement; for example + detached processes (with `&') and recursive use of the shell as a + command. Most systems have to supply some sort of special `batch job + submission' facility and a special command interpreter for files distinct + from the one used interactively.

+

Although the multiple-process idea slipped in very + easily indeed, there were some aftereffects that weren't anticipated. The + most memorable of these became evident soon after the new system came up + and apparently worked. In the midst of our jubilation, it was discovered + that the chdir (change current directory) command had stopped + working. There was much reading of code and anxious introspection about + how the addition of fork could have broken the chdir call. + Finally the truth dawned: in the old system chdir was an ordinary + command; it adjusted the current directory of the (unique) process + attached to the terminal. Under the new system, the chdir command + correctly changed the current directory of the process created to execute + it, but this process promptly terminated and had no effect whatsoever on + its parent shell! It was necessary to make chdir a special command, + executed internally within the shell. It turns out that several + command-like functions have the same property, for example login. +

+

Another mismatch between the system as it had been and + the new process control scheme took longer to become evident. Originally, + the read/write pointer associated with each open file was stored within + the process that opened the file. (This pointer indicates where in the + file the next read or write will take place.) The problem with this + organization became evident only when we tried to use command files. + Suppose a simple command file contains +

+

+
+ls
+
+who
+
+
+

and it is executed as follows: +

+

+
+sh comfile >output
+
+
+

The sequence of events was +

+
1) +
The main shell creates a new process, which opens + outfile to receive the standard output and executes the shell + recursively. +
2) +
The new shell creates another process to execute + ls, which correctly writes on file output and then + terminates. +
3) +
Another process is created to execute the next + command. However, the IO pointer for the output is copied from that of + the shell, and it is still 0, because the shell has never written on its + output, and IO pointers are associated with processes. The effect is + that the output of who overwrites and destroys the output of the + preceding ls command.
+

Solution of this problem required creation of a new + system table to contain the IO pointers of open files independently of the + process in which they were opened.

+

IO Redirection

+

The very convenient notation for IO redirection, using + the `>' and `<' characters, was not present from the very beginning + of the PDP-7 Unix system, but it did appear quite early. Like much else in + Unix, it was inspired by an idea from Multics. Multics has a rather + general IO redirection mechanism [3] embodying named IO streams that can + be dynamically redirected to various devices, files, and even through + special stream-processing modules. Even in the version of Multics we were + familiar with a decade ago, there existed a command that switched + subsequent output normally destined for the terminal to a file, and + another command to reattach output to the terminal. Where under Unix one + might say +

+

+
+ls >xx
+
+
+

to get a listing of the names of one's files in + xx, on Multics the notation was +

+

+
+iocall attach user_output file xx
+
+list
+
+iocall attach user_output syn user_i/o
+
+
+

Even though this very clumsy sequence was used often + during the Multics days, and would have been utterly straightforward to + integrate into the Multics shell, the idea did not occur to us or anyone + else at the time. I speculate that the reason it did not was the sheer + size of the Multics project: the implementors of the IO system were at + Bell Labs in Murray Hill, while the shell was done at MIT. We didn't + consider making changes to the shell (it was their program); + correspondingly, the keepers of the shell may not even have known of the + usefulness, albeit clumsiness, of iocall. (The 1969 Multics manual + [4] lists iocall as an `author-maintained,' that is non-standard, + command.) Because both the Unix IO system and its shell were under the + exclusive control of Thompson, when the right idea finally surfaced, it + was a matter of an hour or so to implement it.

+

The advent of the PDP-11

+

By the beginning of 1970, PDP-7 Unix was a going + concern. Primitive by today's standards, it was still capable of providing + a more congenial programming environment than its alternatives. + Nevertheless, it was clear that the PDP-7, a machine we didn't even own, + was already obsolete, and its successors in the same line offered little + of interest. In early 1970 we proposed acquisition of a PDP-11, which had + just been introduced by Digital. In some sense, this proposal was merely + the latest in the series of attempts that had been made throughout the + preceding year. It differed in two important ways. First, the amount of + money (about $65,000) was an order of magnitude less than what we had + previously asked; second, the charter sought was not merely to write some + (unspecified) operating system, but instead to create a system + specifically designed for editing and formatting text, what might today be + called a `word-processing system.' The impetus for the proposal came + mainly from J. F. Ossanna, who was then and until the end of his life + interested in text processing. If our early proposals were too vague, this + one was perhaps too specific; at first it too met with disfavor. Before + long, however, funds were obtained through the efforts of L. E. McMahon + and an order for a PDP-11 was placed in May.

+

The processor arrived at the end of the summer, but + the PDP-11 was so new a product that no disk was available until December. + In the meantime, a rudimentary, core-only version of Unix was written + using a cross-assembler on the PDP-7. Most of the time, the machine sat in + a corner, enumerating all the closed Knight's tours on a 6×8 chess + board­a three-month job.

+

The first PDP-11 system

+

Once the disk arrived, the system was quickly + completed. In internal structure, the first version of Unix for the PDP-11 + represented a relatively minor advance over the PDP-7 system; writing it + was largely a matter of transliteration. For example, there was no + multi-programming; only one user program was present in core at any + moment. On the other hand, there were important changes in the interface + to the user: the present directory structure, with full path names, was in + place, along with the modern form of exec and wait, and + conveniences like character-erase and line-kill processing for terminals. + Perhaps the most interesting thing about the enterprise was its small + size: there were 24K bytes of core memory (16K for the system, 8K for user + programs), and a disk with 1K blocks (512K bytes). Files were limited to + 64K bytes.

+

At the time of the placement of the order for the + PDP-11, it had seemed natural, or perhaps expedient, to promise a system + dedicated to word processing. During the protracted arrival of the + hardware, the increasing usefulness of PDP-7 Unix made it appropriate to + justify creating PDP-11 Unix as a development tool, to be used in writing + the more special-purpose system. By the spring of 1971, it was generally + agreed that no one had the slightest interest in scrapping Unix. + Therefore, we transliterated the roff text formatter into PDP-11 + assembler language, starting from the PDP-7 version that had been + transliterated from McIlroy's BCPL version on Multics, which had in turn + been inspired by J. Saltzer's runoff program on CTSS. In early + summer, editor and formatter in hand, we felt prepared to fulfill our + charter by offering to supply a text-processing service to the Patent + department for preparing patent applications. At the time, they were + evaluating a commercial system for this purpose; the main advantages we + offered (besides the dubious one of taking part in an in-house experiment) + were two in number: first, we supported Teletype's model 37 terminals, + which, with an extended type-box, could print most of the math symbols + they required; second, we quickly endowed roff with the ability to + produce line-numbered pages, which the Patent Office required and which + the other system could not handle.

+

During the last half of 1971, we supported three + typists from the Patent department, who spent the day busily typing, + editing, and formatting patent applications, and meanwhile tried to carry + on our own work. Unix has a reputation for supplying interesting services + on modest hardware, and this period may mark a high point in the + benefit/equipment ratio; on a machine with no memory protection and a + single .5 MB disk, every test of a new program required care and boldness, + because it could easily crash the system, and every few hours' work by the + typists meant pushing out more information onto DECtape, because of the + very small disk.

+

The experiment was trying but successful. Not only did + the Patent department adopt Unix, and thus become the first of many groups + at the Laboratories to ratify our work, but we achieved sufficient + credibility to convince our own management to acquire one of the first PDP + 11/45 systems made. We have accumulated much hardware since then, and + labored continuously on the software, but because most of the interesting + work has already been published, (e.g. on the system itself [1, 5, 6, 7, + 8, 9]) it seems unnecessary to repeat it here.

+

Pipes

+

One of the most widely admired contributions of Unix + to the culture of operating systems and command languages is the + pipe, as used in a pipeline of commands. Of course, the fundamental + idea was by no means new; the pipeline is merely a specific form of + coroutine. Even the implementation was not unprecedented, although we + didn't know it at the time; the `communication files' of the Dartmouth + Time-Sharing System [10] did very nearly what Unix pipes do, though they + seem not to have been exploited so fully.

+

Pipes appeared in Unix in 1972, well after the PDP-11 + version of the system was in operation, at the suggestion (or perhaps + insistence) of M. D. McIlroy, a long-time advocate of the non-hierarchical + control flow that characterizes coroutines. Some years before pipes were + implemented, he suggested that commands should be thought of as binary + operators, whose left and right operand specified the input and output + files. Thus a `copy' utility would be commanded by +

+

+
+inputfile copy outputfile
+
+
+

To make a pipeline, command operators could be stacked + up. Thus, to sort input, paginate it neatly, and print the result + off-line, one would write +

+

+
+input sort paginate offprint
+
+
+

In today's system, this would correspond to +

+

+
+sort input | pr | opr
+
+
+

The idea, explained one afternoon on a blackboard, + intrigued us but failed to ignite any immediate action. There were several + objections to the idea as put: the infix notation seemed too radical (we + were too accustomed to typing `cp x y' to copy x to y); and + we were unable to see how to distinguish command parameters from the input + or output files. Also, the one-input one-output model of command execution + seemed too confining. What a failure of imagination!

+

Some time later, thanks to McIlroy's persistence, + pipes were finally installed in the operating system (a relatively simple + job), and a new notation was introduced. It used the same characters as + for I/O redirection. For example, the pipeline above might have been + written +

+

+
+sort input >pr>opr>
+
+
+

The idea is that following a `>' may be either a + file, to specify redirection of output to that file, or a command into + which the output of the preceding command is directed as input. The + trailing `>' was needed in the example to specify that the + (nonexistent) output of opr should be directed to the console; + otherwise the command opr would not have been executed at all; + instead a file opr would have been created.

+

The new facility was enthusiastically received, and + the term `filter' was soon coined. Many commands were changed to make them + usable in pipelines. For example, no one had imagined that anyone would + want the sort or pr utility to sort or print its standard + input if given no explicit arguments.

+

Soon some problems with the notation became evident. + Most annoying was a silly lexical problem: the string after `>' was + delimited by blanks, so, to give a parameter to pr in the example, + one had to quote: +

+

+
+sort input >"pr -2">opr>
+
+
+

Second, in attempt to give generality, the pipe + notation accepted `<' as an input redirection in a way corresponding to + `>'; this meant that the notation was not unique. One could also write, + for example, +

+

+
+opr <pr<"sort input"<
+
+
+

or even +

+

+
+pr <"sort input"< >opr>
+
+
+

The pipe notation using `<' and `>' survived + only a couple of months; it was replaced by the present one that uses a + unique operator to separate components of a pipeline. Although the old + notation had a certain charm and inner consistency, the new one is + certainly superior. Of course, it too has limitations. It is unabashedly + linear, though there are situations in which multiple redirected inputs + and outputs are called for. For example, what is the best way to compare + the outputs of two programs? What is the appropriate notation for invoking + a program with two parallel output streams?

+

I mentioned above in the section on IO redirection + that Multics provided a mechanism by which IO streams could be directed + through processing modules on the way to (or from) the device or file + serving as source or sink. Thus it might seem that stream-splicing in + Multics was the direct precursor of Unix pipes, as Multics IO redirection + certainly was for its Unix version. In fact I do not think this is true, + or is true only in a weak sense. Not only were coroutines well-known + already, but their embodiment as Multics spliceable IO modules required + that the modules be specially coded in such a way that they could be used + for no other purpose. The genius of the Unix pipeline is precisely that it + is constructed from the very same commands used constantly in simplex + fashion. The mental leap needed to see this possibility and to invent the + notation is large indeed.

+

High-level languages

+

Every program for the original PDP-7 Unix system was + written in assembly language, and bare assembly language it was­for + example, there were no macros. Moreover, there was no loader or + link-editor, so every program had to be complete in itself. The first + interesting language to appear was a version of McClure's TMG [11] that + was implemented by McIlroy. Soon after TMG became available, Thompson + decided that we could not pretend to offer a real computing service + without Fortran, so he sat down to write a Fortran in TMG. As I recall, + the intent to handle Fortran lasted about a week. What he produced instead + was a definition of and a compiler for the new language B [12]. B was much + influenced by the BCPL language [13]; other influences were Thompson's + taste for spartan syntax, and the very small space into which the compiler + had to fit. The compiler produced simple interpretive code; although it + and the programs it produced were rather slow, it made life much more + pleasant. Once interfaces to the regular system calls were made available, + we began once again to enjoy the benefits of using a reasonable language + to write what are usually called `systems programs:' compilers, + assemblers, and the like. (Although some might consider the PL/I we used + under Multics unreasonable, it was much better than assembly language.) + Among other programs, the PDP-7 B cross-compiler for the PDP-11 was + written in B, and in the course of time, the B compiler for the PDP-7 + itself was transliterated from TMG into B.

+

When the PDP-11 arrived, B was moved to it almost + immediately. In fact, a version of the multi-precision `desk calculator' + program dc was one of the earliest programs to run on the PDP-11, + well before the disk arrived. However, B did not take over instantly. Only + passing thought was given to rewriting the operating system in B rather + than assembler, and the same was true of most of the utilities. Even the + assembler was rewritten in assembler. This approach was taken mainly + because of the slowness of the interpretive code. Of smaller but still + real importance was the mismatch of the word-oriented B language with the + byte-addressed PDP-11.

+

Thus, in 1971, work began on what was to become the C + language [14]. The story of the language developments from BCPL through B + to C is told elsewhere [15], and need not be repeated here. Perhaps the + most important watershed occurred during 1973, when the operating system + kernel was rewritten in C. It was at this point that the system assumed + its modern form; the most far-reaching change was the introduction of + multi-programming. There were few externally-visible changes, but the + internal structure of the system became much more rational and general. + The success of this effort convinced us that C was useful as a nearly + universal tool for systems programming, instead of just a toy for simple + applications.

+

Today, the only important Unix program still written + in assembler is the assembler itself; virtually all the utility programs + are in C, and so are most of the applications programs, although there are + sites with many in Fortran, Pascal, and Algol 68 as well. It seems certain + that much of the success of Unix follows from the readability, + modifiability, and portability of its software that in turn follows from + its expression in high-level languages.

+

Conclusion

+

One of the comforting things about old memories is + their tendency to take on a rosy glow. The programming environment + provided by the early versions of Unix seems, when described here, to be + extremely harsh and primitive. I am sure that if forced back to the PDP-7 + I would find it intolerably limiting and lacking in conveniences. + Nevertheless, it did not seem so at the time; the memory fixes on what was + good and what lasted, and on the joy of helping to create the improvements + that made life better. In ten years, I hope we can look back with the same + mixed impression of progress combined with continuity.

+

Acknowledgements

+

I am grateful to S. P. Morgan, K. Thompson, and M. D. + McIlroy for providing early documents and digging up recollections. +

+

Because I am most interested in describing the + evolution of ideas, this paper attributes ideas and work to individuals + only where it seems most important. The reader will not, on the average, + go far wrong if he reads each occurrence of `we' with unclear antecedent + as `Thompson, with some assistance from me.'

+

References

+



+

+
1. +
D. M. Ritchie and K. Thompson, `The Unix + Time-sharing System, C. ACM 17 No. 7 (July 1974), pp 365-37. + +
2. +
L. P. Deutch and B. W. Lampson, `SDS 930 + Time-sharing System Preliminary Reference Manual,' Doc. 30.10.10, + Project Genie, Univ. Cal. at Berkeley (April 1965). +
3. +
R. J. Feiertag and E. I. Organick, `The Multics + input-output system,' Proc. Third Symposium on Operating Systems + Principles, October 18-20, 1971, pp. 35-41. +
4. +
The Multiplexed Information and Computing + Service: Programmers' Manual, Mass. Inst. of Technology, Project + MAC, Cambridge MA, (1969). +
5. +
K. Thompson, `Unix Implementation,' Bell System + Tech J. 57 No. 6, (July-August 1978), pp. 1931-46. +
6. +
S. C. Johnson and D. M. Ritchie, Portability of C + Programs and the Unix System,' Bell System Tech J. 57 No. 6, + (July-August 1978), pp. 2021-48. +
7. +
B. W. Kernighan, M. E. Lesk, and J. F. Ossanna. + `Document Preparation,' Bell Sys. Tech. J., 57 No. 6, pp. + 2115-2135. +
8. +
B. W. Kernighan and L. L. Cherry, `A System for + Typesetting Mathematics,' J. Comm. Assoc. Comp. Mach. 18, pp. + 151-157 (March 1975). +
9. +
M. E. Lesk and B. W. Kernighan, `Computer + Typesetting of Technical Journals on Unix,' Proc. AFIPS NCC 46 + (1977), pp. 879-88. +
10. +
Systems Programmers Manual for the Dartmouth + Time Sharing System for the GE 635 Computer, Dartmouth College, + Hanover, New Hampshire, 1971. +
11. +
R. M. McClure, `TMG--A Syntax-Directed Compiler,' + Proc 20th ACM National Conf. (1968), pp. 262-74. +
12. +
S. C. Johnson and B. W. Kernighan, `The Programming + Language B,' Comp. Sci. Tech. Rep. #8, Bell Laboratories, Murray Hill NJ + (1973). +
13. +
M. Richards, `BCPL: A Tool for Compiler Writing and + Systems Programming,' Proc. AFIPS SJCC 34 (1969), pp. 557-66. + +
14. +
B. W. Kernighan and D. M. Ritchie, The C + Programming Language, Prentice-Hall, Englewood Cliffs NJ, 1978. + Second Edition, 1979. +
15. +
D. M. Ritchie, S. C. Johnson, and M. E. Lesk, `The + C Programming Language,' Bell Sys. Tech. J. 57 No. 6 (July-August + 1978) pp. 1991-2019.
+

 

diff --git a/doc/UNIX.htm b/doc/UNIX.htm new file mode 100755 index 00000000..db0d6e7c --- /dev/null +++ b/doc/UNIX.htm @@ -0,0 +1,1120 @@ + + +UNIX + + + +
+ + + +
  +

The UNIX Time-Sharing System*

+
+
D. M. Ritchie and K. + Thompson
+
+
+

ABSTRACT

+

Unix is a general-purpose, multi-user, interactive + operating system for the larger Digital Equipment Corporation PDP-11 and + the Interdata 8/32 computers. It offers a number of features seldom + found even in larger operating systems, including +

+
i +
A hierarchical file system incorporating + demountable volumes, +
ii +
Compatible file, device, and inter-process I/O, + +
iii +
The ability to initiate asynchronous processes, + +
iv +
System command language selectable on a per-user + basis, +
v +
Over 100 subsystems including a dozen languages, + +
vi +
High degree of portability.
+



This paper discusses the nature and + implementation of the file system and of the user command interface. +

+
+
NOTE: * Copyright 1974, Association for + Computing Machinery, Inc., reprinted by permission. This electronic + edition of this paper is a reprint of the version appearing in The Bell + System Technical Journal 57 no. 6, part 2 (July-August 1978). In + turn, that was a revised version of an article that appeared in + Communications of the ACM, 17, No. 7 (July 1974), pp. 365-375. + That article was a revised version of a paper presented at the Fourth + ACM Symposium on Operating Systems Principles, IBM Thomas J. Watson + Research Center, Yorktown Heights, New York, October 15-17, 1973. Most + of the differences between versions occur between the C. ACM version and + the BSTJ printing; we incorporated updated numbers and material on + portability. +
+


+

I. INTRODUCTION

+

There have been four versions of the Unix time-sharing + system. 12 The earliest (circa 1969-70) ran on the Digital Equipment + Corporation PDP-7 and -9 computers. The second version ran on the + unprotected PDP-11/20 computer. The third incorporated multiprogramming + and ran on the PDP-11/34, /40, /45, /60, and /70 computers; it is the one + described in the previously published version of this paper, and is also + the most widely used today. This paper describes only the fourth, current + system that runs on the PDP-11/70 and the Interdata 8/32 computers. In + fact, the differences among the various systems is rather small; most of + the revisions made to the originally published version of this paper, + aside from those concerned with style, had to do with details of the + implementation of the file system.

+

Since PDP-11 Unix became operational in February, + 1971, over 600 installations have been put into service. Most of them are + engaged in applications such as computer science education, the + preparation and formatting of documents and other textual material, the + collection and processing of trouble data from various switching machines + within the Bell System, and recording and checking telephone service + orders. Our own installation is used mainly for research in operating + systems, languages, computer networks, and other topics in computer + science, and also for document preparation.

+

Perhaps the most important achievement of Unix is to + demonstrate that a powerful operating system for interactive use need not + be expensive either in equipment or in human effort: it can run on + hardware costing as little as $40,000, and less than two man-years were + spent on the main system software. We hope, however, that users find that + the most important characteristics of the system are its simplicity, + elegance, and ease of use.

+

Besides the operating system proper, some major + programs available under Unix are +

+

+
+C compiler
+
+Text editor based on QED[1];
+
+Assembler, linking loader, symbolic debugger
+
+Phototypesetting and equation setting programs[2, 3]
+
+
+


Dozens of languages including Fortran 77, Basic, + Snobol, APL, Algol 68, M6, TMG, Pascal There is a host of maintenance, + utility, recreation and novelty programs, all written locally. The Unix + user community, which numbers in the thousands, has contributed many more + programs and languages. It is worth noting that the system is totally + self-supporting. All Unix software is maintained on the system; likewise, + this paper and all other documents in this issue were generated and + formatted by the Unix editor and text formatting programs.

+

II. HARDWARE AND SOFTWARE ENVIRONMENT

+

The PDP-11/70 on which the Research Unix system is + installed is a 16-bit word (8-bit byte) computer with 768K bytes of core + memory; the system kernel occupies 90K bytes about equally divided between + code and data tables. This system, however, includes a very large number + of device drivers and enjoys a generous allotment of space for I/O buffers + and system tables; a minimal system capable of running the software + mentioned above can require as little as 96K bytes of core altogether. + There are even larger installations; see the description of the PWB/UNIX + systems [4, 5], for example. There are also much smaller, though somewhat + restricted, versions of the system [6].

+

Our own PDP-11 has two 200-Mb moving-head disks for + file system storage and swapping. There are 20 variable-speed + communications interfaces attached to 300- and 1200-baud data sets, and an + additional 12 communication lines hard-wired to 9600-baud terminals and + satellite computers. There are also several 2400- and 4800-baud + synchronous communication interfaces used for machine-to-machine file + transfer. Finally, there is a variety of miscellaneous devices including + nine-track magnetic tape, a line printer, a voice synthesizer, a + phototypesetter, a digital switching network, and a chess machine. +

+

The preponderance of Unix software is written in the + abovementioned C language [7]. Early versions of the operating system were + written in assembly language, but during the summer of 1973, it was + rewritten in C. The size of the new system was about one-third greater + than that of the old. Since the new system not only became much easier to + understand and to modify but also included many functional improvements, + including multiprogramming and the ability to share reentrant code among + several user programs, we consider this increase in size quite acceptable. +

+

III. THE FILE SYSTEM

+

The most important role of the system is to provide a + file system. From the point of view of the user, there are three kinds of + files: ordinary disk files, directories, and special files.

+

3.1 Ordinary files

+

A file contains whatever information the user places + on it, for example, symbolic or binary (object) programs. No particular + structuring is expected by the system. A file of text consists simply of a + string of characters, with lines demarcated by the newline character. + Binary programs are sequences of words as they will appear in core memory + when the program starts executing. A few user programs manipulate files + with more structure; for example, the assembler generates, and the loader + expects, an object file in a particular format. However, the structure of + files is controlled by the programs that use them, not by the system. +

+

3.2 Directories

+

Directories provide the mapping between the names of + files and the files themselves, and thus induce a structure on the file + system as a whole. Each user has a directory of his own files; he may also + create subdirectories to contain groups of files conveniently treated + together. A directory behaves exactly like an ordinary file except that it + cannot be written on by unprivileged programs, so that the system controls + the contents of directories. However, anyone with appropriate permission + may read a directory just like any other file.

+

The system maintains several directories for its own + use. One of these is the root directory. All files in the system + can be found by tracing a path through a chain of directories until the + desired file is reached. The starting point for such searches is often the + root. Other system directories contain all the programs provided + for general use; that is, all the commands. As will be seen, + however, it is by no means necessary that a program reside in one of these + directories for it to be executed.

+

Files are named by sequences of 14 or fewer + characters. When the name of a file is specified to the system, it may be + in the form of a path name, which is a sequence of directory + names separated by slashes, ``/'', and ending in a file name. If the + sequence begins with a slash, the search begins in the root directory. The + name /alpha/beta/gamma causes the system to search the root for + directory alpha, then to search alpha for beta, + finally to find gamma in beta. gamma may be an + ordinary file, a directory, or a special file. As a limiting case, the + name ``/'' refers to the root itself.

+

A path name not starting with ``/'' causes the system + to begin the search in the user's current directory. Thus, the name + alpha/beta specifies the file named beta in subdirectory + alpha of the current directory. The simplest kind of name, for + example, alpha, refers to a file that itself is found in the + current directory. As another limiting case, the null file name refers to + the current directory.

+

The same non-directory file may appear in several + directories under possibly different names. This feature is called + linking; a directory entry for a file is sometimes called a link. + The Unix system differs from other systems in which linking is permitted + in that all links to a file have equal status. That is, a file does not + exist within a particular directory; the directory entry for a file + consists merely of its name and a pointer to the information actually + describing the file. Thus a file exists independently of any directory + entry, although in practice a file is made to disappear along with the + last link to it.

+

Each directory always has at least two entries. The + name ``.'' in each directory refers to the directory itself. Thus a + program may read the current directory under the name ``.'' without + knowing its complete path name. The name ``..'' by convention + refers to the parent of the directory in which it appears, that is, to the + directory in which it was created.

+

The directory structure is constrained to have the + form of a rooted tree. Except for the special entries ``.'' and + ``..'', each directory must appear as an entry in exactly one other + directory, which is its parent. The reason for this is to simplify the + writing of programs that visit subtrees of the directory structure, and + more important, to avoid the separation of portions of the hierarchy. If + arbitrary links to directories were permitted, it would be quite difficult + to detect when the last connection from the root to a directory was + severed.

+

3.3 Special files

+

Special files constitute the most unusual feature of + the Unix file system. Each supported I/O device is associated with at + least one such file. Special files are read and written just like ordinary + disk files, but requests to read or write result in activation of the + associated device. An entry for each special file resides in directory + /dev, although a link may be made to one of these files just as it + may to an ordinary file. Thus, for example, to write on a magnetic tape + one may write on the file /dev/mt. Special files exist for each + communication line, each disk, each tape drive, and for physical main + memory. Of course, the active disks and the memory special file are + protected from indiscriminate access.

+

There is a threefold advantage in treating I/O devices + this way: file and device I/O are as similar as possible; file and device + names have the same syntax and meaning, so that a program expecting a file + name as a parameter can be passed a device name; finally, special files + are subject to the same protection mechanism as regular files.

+

3.4 Removable file systems

+

Although the root of the file system is always stored + on the same device, it is not necessary that the entire file system + hierarchy reside on this device. There is a mount system request + with two arguments: the name of an existing ordinary file, and the name of + a special file whose associated storage volume (e.g., a disk pack) should + have the structure of an independent file system containing its own + directory hierarchy. The effect of mount is to cause references to + the heretofore ordinary file to refer instead to the root directory of the + file system on the removable volume. In effect, mount replaces a + leaf of the hierarchy tree (the ordinary file) by a whole new subtree (the + hierarchy stored on the removable volume). After the mount, there + is virtually no distinction between files on the removable volume and + those in the permanent file system. In our installation, for example, the + root directory resides on a small partition of one of our disk drives, + while the other drive, which contains the user's files, is mounted by the + system initialization sequence. A mountable file system is generated by + writing on its corresponding special file. A utility program is available + to create an empty file system, or one may simply copy an existing file + system.

+

There is only one exception to the rule of identical + treatment of files on different devices: no link may exist between one + file system hierarchy and another. This restriction is enforced so as to + avoid the elaborate bookkeeping that would otherwise be required to assure + removal of the links whenever the removable volume is dismounted. +

+

3.5 Protection

+

Although the access control scheme is quite simple, it + has some unusual features. Each user of the system is assigned a unique + user identification number. When a file is created, it is marked with the + user ID of its owner. Also given for new files is a set of ten protection + bits. Nine of these specify independently read, write, and execute + permission for the owner of the file, for other members of his group, and + for all remaining users.

+

If the tenth bit is on, the system will temporarily + change the user identification (hereafter, user ID) of the current user to + that of the creator of the file whenever the file is executed as a + program. This change in user ID is effective only during the execution of + the program that calls for it. The set-user-ID feature provides for + privileged programs that may use files inaccessible to other users. For + example, a program may keep an accounting file that should neither be read + nor changed except by the program itself. If the set-user-ID bit is on for + the program, it may access the file although this access might be + forbidden to other programs invoked by the given program's user. Since the + actual user ID of the invoker of any program is always available, + set-user-ID programs may take any measures desired to satisfy themselves + as to their invoker's credentials. This mechanism is used to allow users + to execute the carefully written commands that call privileged system + entries. For example, there is a system entry invokable only by the + ``super-user'' (below) that creates an empty directory. As indicated + above, directories are expected to have entries for ``.'' and + ``..''. The command which creates a directory is owned by the + super-user and has the set-user-ID bit set. After it checks its invoker's + authorization to create the specified directory, it creates it and makes + the entries for ``.'' and ``..''.

+

Because anyone may set the set-user-ID bit on one of + his own files, this mechanism is generally available without + administrative intervention. For example, this protection scheme easily + solves the MOO accounting problem posed by ``Aleph-null.'' [8]

+

The system recognizes one particular user ID (that of + the ``super-user'') as exempt from the usual constraints on file access; + thus (for example), programs may be written to dump and reload the file + system without unwanted interference from the protection system. +

+

3.6 I/O calls

+

The system calls to do I/O are designed to eliminate + the differences between the various devices and styles of access. There is + no distinction between ``random'' and ``sequential'' I/O, nor is any + logical record size imposed by the system. The size of an ordinary file is + determined by the number of bytes written on it; no predetermination of + the size of a file is necessary or possible.

+

To illustrate the essentials of I/O, some of the basic + calls are summarized below in an anonymous language that will indicate the + required parameters without getting into the underlying complexities. Each + call to the system may potentially result in an error return, which for + simplicity is not represented in the calling sequence.

+

To read or write a file assumed to exist already, it + must be opened by the following call: +

+

+
+filep = open(name, flag)
+
+
+

where name indicates the name of the file. An + arbitrary path name may be given. The flag argument indicates + whether the file is to be read, written, or ``updated,'' that is, read and + written simultaneously.

+

The returned value filep is called a file + descriptor. It is a small integer used to identify the file in + subsequent calls to read, write, or otherwise manipulate the file. +

+

To create a new file or completely rewrite an old one, + there is a create system call that creates the given file if it + does not exist, or truncates it to zero length if it does exist; + create also opens the new file for writing and, like open, + returns a file descriptor.

+

The file system maintains no locks visible to the + user, nor is there any restriction on the number of users who may have a + file open for reading or writing. Although it is possible for the contents + of a file to become scrambled when two users write on it simultaneously, + in practice difficulties do not arise. We take the view that locks are + neither necessary nor sufficient, in our environment, to prevent + interference between users of the same file. They are unnecessary because + we are not faced with large, single-file data bases maintained by + independent processes. They are insufficient because locks in the ordinary + sense, whereby one user is prevented from writing on a file that another + user is reading, cannot prevent confusion when, for example, both users + are editing a file with an editor that makes a copy of the file being + edited.

+

There are, however, sufficient internal interlocks to + maintain the logical consistency of the file system when two users engage + simultaneously in activities such as writing on the same file, creating + files in the same directory, or deleting each other's open files. +

+

Except as indicated below, reading and writing are + sequential. This means that if a particular byte in the file was the last + byte written (or read), the next I/O call implicitly refers to the + immediately following byte. For each open file there is a pointer, + maintained inside the system, that indicates the next byte to be read or + written. If n bytes are read or written, the pointer advances by + n bytes.

+

Once a file is open, the following calls may be used: + +

+

+
+n = read(filep, buffer, count)
+
+n = write(filep, buffer, count)
+
+
+

Up to count bytes are transmitted between the + file specified by filep and the byte array specified by + buffer. The returned value n is the number of bytes actually + transmitted. In the write case, n is the same as + count except under exceptional conditions, such as I/O errors or + end of physical medium on special files; in a read, however, + n may without error be less than count. If the read pointer + is so near the end of the file that reading count characters would + cause reading beyond the end, only sufficient bytes are transmitted to + reach the end of the file; also, typewriter-like terminals never return + more than one line of input. When a read call returns with n + equal to zero, the end of the file has been reached. For disk files this + occurs when the read pointer becomes equal to the current size of the + file. It is possible to generate an end-of-file from a terminal by use of + an escape sequence that depends on the device used.

+

Bytes written affect only those parts of a file + implied by the position of the write pointer and the count; no other part + of the file is changed. If the last byte lies beyond the end of the file, + the file is made to grow as needed.

+

To do random (direct-access) I/O it is only necessary + to move the read or write pointer to the appropriate location in the file. + +

+

+
+location = lseek(filep, offset, base)
+
+
+

The pointer associated with filep is moved to a + position offset bytes from the beginning of the file, from the + current position of the pointer, or from the end of the file, depending on + base. offset may be negative. For some devices (e.g., paper + tape and terminals) seek calls are ignored. The actual offset from the + beginning of the file to which the pointer was moved is returned in + location.

+

There are several additional system entries having to + do with I/O and with the file system that will not be discussed. For + example: close a file, get the status of a file, change the protection + mode or the owner of a file, create a directory, make a link to an + existing file, delete a file.

+

IV. IMPLEMENTATION OF THE FILE SYSTEM

+

As mentioned in Section 3.2 above, a directory entry + contains only a name for the associated file and a pointer to the file + itself. This pointer is an integer called the i-number (for index + number) of the file. When the file is accessed, its i-number is used as an + index into a system table (the i-list) stored in a known part of + the device on which the directory resides. The entry found thereby (the + file's i-node) contains the description of the file: +

+
i +
the user and group-ID of its owner +
ii +
its protection bits +
iii +
the physical disk or tape addresses for the file + contents +
iv +
its size +
v +
time of creation, last use, and last modification + +
vi +
the number of links to the file, that is, the + number of times it appears in a directory +
vii +
a code indicating whether the file is a directory, + an ordinary file, or a special file.
+



The purpose of an open or create + system call is to turn the path name given by the user into an i-number by + searching the explicitly or implicitly named directories. Once a file is + open, its device, i-number, and read/write pointer are stored in a system + table indexed by the file descriptor returned by the open or + create. Thus, during a subsequent call to read or write the file, + the descriptor may be easily related to the information necessary to + access the file.

+

When a new file is created, an i-node is allocated for + it and a directory entry is made that contains the name of the file and + the i-node number. Making a link to an existing file involves creating a + directory entry with the new name, copying the i-number from the original + file entry, and incrementing the link-count field of the i-node. Removing + (deleting) a file is done by decrementing the link-count of the i-node + specified by its directory entry and erasing the directory entry. If the + link-count drops to 0, any disk blocks in the file are freed and the + i-node is de-allocated.

+

The space on all disks that contain a file system is + divided into a number of 512-byte blocks logically addressed from 0 up to + a limit that depends on the device. There is space in the i-node of each + file for 13 device addresses. For nonspecial files, the first 10 device + addresses point at the first 10 blocks of the file. If the file is larger + than 10 blocks, the 11 device address points to an indirect block + containing up to 128 addresses of additional blocks in the file. Still + larger files use the twelfth device address of the i-node to point to a + double-indirect block naming 128 indirect blocks, each pointing to 128 + blocks of the file. If required, the thirteenth device address is a + triple-indirect block. Thus files may conceptually grow to + [(10+128+128^2+128^3)*512] bytes. Once opened, bytes numbered below 5120 + can be read with a single disk access; bytes in the range 5120 to 70,656 + require two accesses; bytes in the range 70,656 to 8,459,264 require three + accesses; bytes from there to the largest file (1,082,201,088) require + four accesses. In practice, a device cache mechanism (see below) proves + effective in eliminating most of the indirect fetches.

+

The foregoing discussion applies to ordinary files. + When an I/O request is made to a file whose i-node indicates that it is + special, the last 12 device address words are immaterial, and the first + specifies an internal device name, which is interpreted as a pair + of numbers representing, respectively, a device type and subdevice number. + The device type indicates which system routine will deal with I/O on that + device; the subdevice number selects, for example, a disk drive attached + to a particular controller or one of several similar terminal interfaces. +

+

In this environment, the implementation of the + mount system call (Section 3.4) is quite straightforward. + mount maintains a system table whose argument is the i-number and + device name of the ordinary file specified during the mount, and + whose corresponding value is the device name of the indicated special + file. This table is searched for each i-number/device pair that turns up + while a path name is being scanned during an open or create; + if a match is found, the i-number is replaced by the i-number of the root + directory and the device name is replaced by the table value.

+

To the user, both reading and writing of files appear + to be synchronous and unbuffered. That is, immediately after return from a + read call the data are available; conversely, after a write + the user's workspace may be reused. In fact, the system maintains a rather + complicated buffering mechanism that reduces greatly the number of I/O + operations required to access a file. Suppose a write call is made + specifying transmission of a single byte. The system will search its + buffers to see whether the affected disk block currently resides in main + memory; if not, it will be read in from the device. Then the affected byte + is replaced in the buffer and an entry is made in a list of blocks to be + written. The return from the write call may then take place, + although the actual I/O may not be completed until a later time. + Conversely, if a single byte is read, the system determines whether the + secondary storage block in which the byte is located is already in one of + the system's buffers; if so, the byte can be returned immediately. If not, + the block is read into a buffer and the byte picked out.

+

The system recognizes when a program has made accesses + to sequential blocks of a file, and asynchronously pre-reads the next + block. This significantly reduces the running time of most programs while + adding little to system overhead.

+

A program that reads or writes files in units of 512 + bytes has an advantage over a program that reads or writes a single byte + at a time, but the gain is not immense; it comes mainly from the avoidance + of system overhead. If a program is used rarely or does no great volume of + I/O, it may quite reasonably read and write in units as small as it + wishes.

+

The notion of the i-list is an unusual feature of + Unix. In practice, this method of organizing the file system has proved + quite reliable and easy to deal with. To the system itself, one of its + strengths is the fact that each file has a short, unambiguous name related + in a simple way to the protection, addressing, and other information + needed to access the file. It also permits a quite simple and rapid + algorithm for checking the consistency of a file system, for example, + verification that the portions of each device containing useful + information and those free to be allocated are disjoint and together + exhaust the space on the device. This algorithm is independent of the + directory hierarchy, because it need only scan the linearly organized + i-list. At the same time the notion of the i-list induces certain + peculiarities not found in other file system organizations. For example, + there is the question of who is to be charged for the space a file + occupies, because all directory entries for a file have equal status. + Charging the owner of a file is unfair in general, for one user may create + a file, another may link to it, and the first user may delete the file. + The first user is still the owner of the file, but it should be charged to + the second user. The simplest reasonably fair algorithm seems to be to + spread the charges equally among users who have links to a file. Many + installations avoid the issue by not charging any fees at all.

+

V. PROCESSES AND IMAGES

+

An image is a computer execution environment. + It includes a memory image, general register values, status of open files, + current directory and the like. An image is the current state of a + pseudo-computer.

+

A process is the execution of an image. While + the processor is executing on behalf of a process, the image must reside + in main memory; during the execution of other processes it remains in main + memory unless the appearance of an active, higher-priority process forces + it to be swapped out to the disk.

+

The user-memory part of an image is divided into three + logical segments. The program text segment begins at location 0 in the + virtual address space. During execution, this segment is write-protected + and a single copy of it is shared among all processes executing the same + program. At the first hardware protection byte boundary above the program + text segment in the virtual address space begins a non-shared, writable + data segment, the size of which may be extended by a system call. Starting + at the highest address in the virtual address space is a stack segment, + which automatically grows downward as the stack pointer fluctuates. +

+

5.1 Processes

+

Except while the system is bootstrapping itself into + operation, a new process can come into existence only by use of the + fork system call: +

+

+
+processid = fork()
+
+
+

When fork is executed, the process splits into + two independently executing processes. The two processes have independent + copies of the original memory image, and share all open files. The new + processes differ only in that one is considered the parent process: in the + parent, the returned processid actually identifies the child + process and is never 0, while in the child, the returned value is always + 0.

+

Because the values returned by fork in the + parent and child process are distinguishable, each process may determine + whether it is the parent or child.

+

5.2 Pipes

+

Processes may communicate with related processes using + the same system read and write calls that are used for + file-system I/O. The call: +

+

+
+filep = pipe()
+
+
+

returns a file descriptor filep and creates an + inter-process channel called a pipe. This channel, like other open + files, is passed from parent to child process in the image by the + fork call. A read using a pipe file descriptor waits until + another process writes using the file descriptor for the same pipe. At + this point, data are passed between the images of the two processes. + Neither process need know that a pipe, rather than an ordinary file, is + involved.

+

Although inter-process communication via pipes is a + quite valuable tool (see Section 6.2), it is not a completely general + mechanism, because the pipe must be set up by a common ancestor of the + processes involved.

+

5.3 Execution of programs

+

Another major system primitive is invoked by +

+

+
+execute(file, arg1, arg2, ... , argn)
+
+
+

which requests the system to read in and execute the + program named by file, passing it string arguments arg1, + arg2, ..., argn. All the code and data in the process + invoking execute is replaced from the file, but open files, + current directory, and inter-process relationships are unaltered. Only if + the call fails, for example because file could not be found or + because its execute-permission bit was not set, does a return take place + from the execute primitive; it resembles a ``jump'' machine + instruction rather than a subroutine call.

+

5.4 Process synchronization

+

Another process control system call: +

+

+
+processid = wait(status)
+
+
+

causes its caller to suspend execution until one of + its children has completed execution. Then wait returns the + processid of the terminated process. An error return is taken if + the calling process has no descendants. Certain status from the child + process is also available.

+

5.5 Termination

+

Lastly: +

+

+
+exit(status)
+
+
+

terminates a process, destroys its image, closes its + open files, and generally obliterates it. The parent is notified through + the wait primitive, and status is made available to it. + Processes may also terminate as a result of various illegal actions or + user-generated signals (Section VII below).

+

VI. THE SHELL

+

For most users, communication with the system is + carried on with the aid of a program called the shell. The shell is a + command-line interpreter: it reads lines typed by the user and interprets + them as requests to execute other programs. (The shell is described fully + elsewhere [9], so this section will discuss only the theory of its + operation.) In simplest form, a command line consists of the command name + followed by arguments to the command, all separated by spaces: +

+

+
+command arg1 arg2 ... argn
+
+
+

The shell splits up the command name and the arguments + into separate strings. Then a file with name command is sought; + command may be a path name including the ``/'' character to specify + any file in the system. If command is found, it is brought into + memory and executed. The arguments collected by the shell are accessible + to the command. When the command is finished, the shell resumes its own + execution, and indicates its readiness to accept another command by typing + a prompt character.

+

If file command cannot be found, the shell + generally prefixes a string such as /bin/ to command and + attempts again to find the file. Directory /bin contains commands + intended to be generally used. (The sequence of directories to be searched + may be changed by user request.)

+

6.1 Standard I/O

+

The discussion of I/O in Section III above seems to + imply that every file used by a program must be opened or created by the + program in order to get a file descriptor for the file. Programs executed + by the shell, however, start off with three open files with file + descriptors 0, 1, and 2. As such a program begins execution, file 1 is + open for writing, and is best understood as the standard output file. + Except under circumstances indicated below, this file is the user's + terminal. Thus programs that wish to write informative information + ordinarily use file descriptor 1. Conversely, file 0 starts off open for + reading, and programs that wish to read messages typed by the user read + this file.

+

The shell is able to change the standard assignments + of these file descriptors from the user's terminal printer and keyboard. + If one of the arguments to a command is prefixed by ``>'', file + descriptor 1 will, for the duration of the command, refer to the file + named after the ``>''. For example: +

+

+
+ls
+
+
+

ordinarily lists, on the typewriter, the names of the + files in the current directory. The command: +

+

+
+ls >there
+
+
+

creates a file called there and places the + listing there. Thus the argument >there means ``place output on + there.'' On the other hand: +

+

+
+ed
+
+
+

ordinarily enters the editor, which takes requests + from the user via his keyboard. The command +

+

+
+ed <script
+
+
+

interprets script as a file of editor commands; + thus ``<script'' means ``take input from script.''

+

Although the file name following ``<'' or ``>'' + appears to be an argument to the command, in fact it is interpreted + completely by the shell and is not passed to the command at all. Thus no + special coding to handle I/O redirection is needed within each command; + the command need merely use the standard file descriptors 0 and 1 where + appropriate.

+

File descriptor 2 is, like file 1, ordinarily + associated with the terminal output stream. When an output-diversion + request with ``>'' is specified, file 2 remains attached to the + terminal, so that commands may produce diagnostic messages that do not + silently end up in the output file.

+

6.2 Filters

+

An extension of the standard I/O notion is used to + direct output from one command to the input of another. A sequence of + commands separated by vertical bars causes the shell to execute all the + commands simultaneously and to arrange that the standard output of each + command be delivered to the standard input of the next command in the + sequence. Thus in the command line: +

+

+
+ls | pr -2 | opr
+
+
+

ls lists the names of the files in the current + directory; its output is passed to pr, which paginates its input + with dated headings. (The argument ``-2'' requests double-column output.) + Likewise, the output from pr is input to opr; this command + spools its input onto a file for off-line printing.

+

This procedure could have been carried out more + clumsily by: +

+

+
+ls >temp1
+
+pr -2 <temp1 >temp2
+
+opr <temp2
+
+
+

followed by removal of the temporary files. In the + absence of the ability to redirect output and input, a still clumsier + method would have been to require the ls command to accept user + requests to paginate its output, to print in multi-column format, and to + arrange that its output be delivered off-line. Actually it would be + surprising, and in fact unwise for efficiency reasons, to expect authors + of commands such as ls to provide such a wide variety of output + options.

+

A program such as pr which copies its standard + input to its standard output (with processing) is called a filter. + Some filters that we have found useful perform character transliteration, + selection of lines according to a pattern, sorting of the input, and + encryption and decryption.

+

6.3 Command separators; multitasking

+

Another feature provided by the shell is relatively + straightforward. Commands need not be on different lines; instead they may + be separated by semicolons: +

+

+
+ls; ed
+
+
+

will first list the contents of the current directory, + then enter the editor.

+

A related feature is more interesting. If a command is + followed by ``&,'' the shell will not wait for the command to + finish before prompting again; instead, it is ready immediately to accept + a new command. For example: +

+

+
+as source >output &
+
+
+

causes source to be assembled, with diagnostic + output going to output; no matter how long the assembly takes, the + shell returns immediately. When the shell does not wait for the completion + of a command, the identification number of the process running that + command is printed. This identification may be used to wait for the + completion of the command or to terminate it. The ``&'' may be + used several times in a line: +

+

+
+as source >output & ls >files &
+
+
+

does both the assembly and the listing in the + background. In these examples, an output file other than the terminal was + provided; if this had not been done, the outputs of the various commands + would have been intermingled.

+

The shell also allows parentheses in the above + operations. For example: +

+

+
+(date; ls) >x &
+
+
+

writes the current date and time followed by a list of + the current directory onto the file x. The shell also returns + immediately for another request.

+

6.4 The shell as a command; command files +

+

The shell is itself a command, and may be called + recursively. Suppose file tryout contains the lines: +

+

+
+as source
+
+mv a.out testprog
+
+testprog
+
+
+

The mv command causes the file a.out to + be renamed testprog. a.out is the (binary) output of the + assembler, ready to be executed. Thus if the three lines above were typed + on the keyboard, source would be assembled, the resulting program + renamed testprog, and testprog executed. When the lines are + in tryout, the command: +

+

+
+sh <tryout
+
+
+

would cause the shell sh to execute the + commands sequentially.

+

The shell has further capabilities, including the + ability to substitute parameters and to construct argument lists from a + specified subset of the file names in a directory. It also provides + general conditional and looping constructions.

+

6.5 Implementation of the shell

+

The outline of the operation of the shell can now be + understood. Most of the time, the shell is waiting for the user to type a + command. When the newline character ending the line is typed, the shell's + read call returns. The shell analyzes the command line, putting the + arguments in a form appropriate for execute. Then fork is + called. The child process, whose code of course is still that of the + shell, attempts to perform an execute with the appropriate + arguments. If successful, this will bring in and start execution of the + program whose name was given. Meanwhile, the other process resulting from + the fork, which is the parent process, waits for the child + process to die. When this happens, the shell knows the command is + finished, so it types its prompt and reads the keyboard to obtain another + command.

+

Given this framework, the implementation of background + processes is trivial; whenever a command line contains ``&,'' + the shell merely refrains from waiting for the process that it created to + execute the command.

+

Happily, all of this mechanism meshes very nicely with + the notion of standard input and output files. When a process is created + by the fork primitive, it inherits not only the memory image of its + parent but also all the files currently open in its parent, including + those with file descriptors 0, 1, and 2. The shell, of course, uses these + files to read command lines and to write its prompts and diagnostics, and + in the ordinary case its children­the command programs­inherit + them automatically. When an argument with ``<'' or ``>'' is given, + however, the offspring process, just before it performs execute, + makes the standard I/O file descriptor (0 or 1, respectively) refer to the + named file. This is easy because, by agreement, the smallest unused file + descriptor is assigned when a new file is opened (or + created); it is only necessary to close file 0 (or 1) and open the + named file. Because the process in which the command program runs simply + terminates when it is through, the association between a file specified + after ``<'' or ``>'' and file descriptor 0 or 1 is ended + automatically when the process dies. Therefore the shell need not know the + actual names of the files that are its own standard input and output, + because it need never reopen them.

+

Filters are straightforward extensions of standard I/O + redirection with pipes used instead of files.

+

In ordinary circumstances, the main loop of the shell + never terminates. (The main loop includes the branch of the return from + fork belonging to the parent process; that is, the branch that does + a wait, then reads another command line.) The one thing that causes + the shell to terminate is discovering an end-of-file condition on its + input file. Thus, when the shell is executed as a command with a given + input file, as in: +

+

+
+sh <comfile
+
+
+

the commands in comfile will be executed until + the end of comfile is reached; then the instance of the shell + invoked by sh will terminate. Because this shell process is the + child of another instance of the shell, the wait executed in the + latter will return, and another command may then be processed.

+

6.6 Initialization

+

The instances of the shell to which users type + commands are themselves children of another process. The last step in the + initialization of the system is the creation of a single process and the + invocation (via execute) of a program called init. The role + of init is to create one process for each terminal channel. The + various subinstances of init open the appropriate terminals for + input and output on files 0, 1, and 2, waiting, if necessary, for carrier + to be established on dial-up lines. Then a message is typed out requesting + that the user log in. When the user types a name or other identification, + the appropriate instance of init wakes up, receives the log-in + line, and reads a password file. If the user's name is found, and if he is + able to supply the correct password, init changes to the user's + default current directory, sets the process's user ID to that of the + person logging in, and performs an execute of the shell. At this + point, the shell is ready to receive commands and the logging-in protocol + is complete.

+

Meanwhile, the mainstream path of init (the + parent of all the subinstances of itself that will later become shells) + does a wait. If one of the child processes terminates, either + because a shell found an end of file or because a user typed an incorrect + name or password, this path of init simply recreates the defunct + process, which in turn reopens the appropriate input and output files and + types another log-in message. Thus a user may log out simply by typing the + end-of-file sequence to the shell.

+

6.7 Other programs as shell

+

The shell as described above is designed to allow + users full access to the facilities of the system, because it will invoke + the execution of any program with appropriate protection mode. Sometimes, + however, a different interface to the system is desirable, and this + feature is easily arranged for.

+

Recall that after a user has successfully logged in by + supplying a name and password, init ordinarily invokes the shell to + interpret command lines. The user's entry in the password file may contain + the name of a program to be invoked after log-in instead of the shell. + This program is free to interpret the user's messages in any way it + wishes.

+

For example, the password file entries for users of a + secretarial editing system might specify that the editor ed is to + be used instead of the shell. Thus when users of the editing system log + in, they are inside the editor and can begin work immediately; also, they + can be prevented from invoking programs not intended for their use. In + practice, it has proved desirable to allow a temporary escape from the + editor to execute the formatting program and other utilities.

+

Several of the games (e.g., chess, blackjack, 3D + tic-tac-toe) available on the system illustrate a much more severely + restricted environment. For each of these, an entry exists in the password + file specifying that the appropriate game-playing program is to be invoked + instead of the shell. People who log in as a player of one of these games + find themselves limited to the game and unable to investigate the + (presumably more interesting) offerings of the Unix system as a whole. +

+

VII. TRAPS

+

The PDP-11 hardware detects a number of program + faults, such as references to non-existent memory, unimplemented + instructions, and odd addresses used where an even address is required. + Such faults cause the processor to trap to a system routine. Unless other + arrangements have been made, an illegal action causes the system to + terminate the process and to write its image on file core in the + current directory. A debugger can be used to determine the state of the + program at the time of the fault.

+

Programs that are looping, that produce unwanted + output, or about which the user has second thoughts may be halted by the + use of the interrupt signal, which is generated by typing the + ``delete'' character. Unless special action has been taken, this signal + simply causes the program to cease execution without producing a + core file. There is also a quit signal used to force an + image file to be produced. Thus programs that loop unexpectedly may be + halted and the remains inspected without prearrangement.

+

The hardware-generated faults and the interrupt and + quit signals can, by request, be either ignored or caught by a process. + For example, the shell ignores quits to prevent a quit from logging the + user out. The editor catches interrupts and returns to its command level. + This is useful for stopping long printouts without losing work in progress + (the editor manipulates a copy of the file it is editing). In systems + without floating-point hardware, unimplemented instructions are caught and + floating-point instructions are interpreted.

+

VIII. PERSPECTIVE

+

Perhaps paradoxically, the success of the Unix system + is largely due to the fact that it was not designed to meet any predefined + objectives. The first version was written when one of us (Thompson), + dissatisfied with the available computer facilities, discovered a + little-used PDP-7 and set out to create a more hospitable environment. + This (essentially personal) effort was sufficiently successful to gain the + interest of the other author and several colleagues, and later to justify + the acquisition of the PDP-11/20, specifically to support a text editing + and formatting system. When in turn the 11/20 was outgrown, the system had + proved useful enough to persuade management to invest in the PDP-11/45, + and later in the PDP-11/70 and Interdata 8/32 machines, upon which it + developed to its present form. Our goals throughout the effort, when + articulated at all, have always been to build a comfortable relationship + with the machine and to explore ideas and inventions in operating systems + and other software. We have not been faced with the need to satisfy + someone else's requirements, and for this freedom we are grateful. +

+

Three considerations that influenced the design of + Unix are visible in retrospect.

+

First: because we are programmers, we naturally + designed the system to make it easy to write, test, and run programs. The + most important expression of our desire for programming convenience was + that the system was arranged for interactive use, even though the original + version only supported one user. We believe that a properly designed + interactive system is much more productive and satisfying to use than a + ``batch'' system. Moreover, such a system is rather easily adaptable to + noninteractive use, while the converse is not true.

+

Second: there have always been fairly severe size + constraints on the system and its software. Given the partially + antagonistic desires for reasonable efficiency and expressive power, the + size constraint has encouraged not only economy, but also a certain + elegance of design. This may be a thinly disguised version of the + ``salvation through suffering'' philosophy, but in our case it worked. +

+

Third: nearly from the start, the system was able to, + and did, maintain itself. This fact is more important than it might seem. + If designers of a system are forced to use that system, they quickly + become aware of its functional and superficial deficiencies and are + strongly motivated to correct them before it is too late. Because all + source programs were always available and easily modified on-line, we were + willing to revise and rewrite the system and its software when new ideas + were invented, discovered, or suggested by others.

+

The aspects of Unix discussed in this paper exhibit + clearly at least the first two of these design considerations. The + interface to the file system, for example, is extremely convenient from a + programming standpoint. The lowest possible interface level is designed to + eliminate distinctions between the various devices and files and between + direct and sequential access. No large ``access method'' routines are + required to insulate the programmer from the system calls; in fact, all + user programs either call the system directly or use a small library + program, less than a page long, that buffers a number of characters and + reads or writes them all at once.

+

Another important aspect of programming convenience is + that there are no ``control blocks'' with a complicated structure + partially maintained by and depended on by the file system or other system + calls. Generally speaking, the contents of a program's address space are + the property of the program, and we have tried to avoid placing + restrictions on the data structures within that address space.

+

Given the requirement that all programs should be + usable with any file or device as input or output, it is also desirable to + push device-dependent considerations into the operating system itself. The + only alternatives seem to be to load, with all programs, routines for + dealing with each device, which is expensive in space, or to depend on + some means of dynamically linking to the routine appropriate to each + device when it is actually needed, which is expensive either in overhead + or in hardware.

+

Likewise, the process-control scheme and the command + interface have proved both convenient and efficient. Because the shell + operates as an ordinary, swappable user program, it consumes no + ``wired-down'' space in the system proper, and it may be made as powerful + as desired at little cost. In particular, given the framework in which the + shell executes as a process that spawns other processes to perform + commands, the notions of I/O redirection, background processes, command + files, and user-selectable system interfaces all become essentially + trivial to implement.

+

Influences

+

The success of Unix lies not so much in new inventions + but rather in the full exploitation of a carefully selected set of fertile + ideas, and especially in showing that they can be keys to the + implementation of a small yet powerful operating system.

+

The fork operation, essentially as we + implemented it, was present in the GENIE time-sharing system [10]. On a + number of points we were influenced by Multics, which suggested the + particular form of the I/O system calls [11], and both the name of the + shell and its general functions. The notion that the shell should create a + process for each command was also suggested to us by the early design of + Multics, although in that system it was later dropped for efficiency + reasons. A similar scheme is used by TENEX [12].

+

References

+



+

+
1. +
L. P. Deutsch and B. W. Lampson, `An online + editor,' J. Comm. Assoc. Comp. Mach. 10 12, December 1967 pp. + 793-799, 803 +
2. +
B. W. Kernighan and L. L. Cherry, `A System for + Typesetting Mathematics,' J. Comm. Assoc. Comp. Mach. 18, pp. + 151-157, March 1975. +
3. +
B. W. Kernighan, M. E. Lesk and J. F. Ossanna, + `Document Preparation,' Bell Sys. Tech. J. 57 6 part 2, pp. + 2115-2135, July-August 1978. +
4. +
T. A. Dolotta and J. R. Mashey, `An Introduction to + the Programmer's Workbench,' Proc. 2nd Int. Conf. on Software + Engineering, October 13-15, 1976, pp. 164-168. +
5. +
T. A. Dolotta, R. C. Haight, and J. R. Mashey, `The + Programmer's Workbench,' Bell Sys. Tech. J. 57 6, pp. 2177-2200, + July-August, 1978. +
6. +
H. Lycklama, `UNIX on a Microprocessor,' Bell Sys. + Tech. J., 57 6, pp. 2087-2101. July-August 1978. +
7. +
B. W. Kernighan and D. M. Ritchie, The C + Programming Language, Prentice-Hall, Englewood Cliffs, New Jersey, + 1978. Second edition, 1988. +
8. +
Aleph-null, `Computer Recreations,' Software + Practice and Experience, 1 2, April-June 1971, pp. 201-204. + +
9. +
S. R. Bourne, `The UNIX Shell,' Bell Sys. Tech. J. + 57 6, pp. 1971-1990, July-August 1978. +
10. +
L. P. Deutsch and B. W. Lampson, `SDS 930 + time-sharing system preliminary reference manual,' Doc. 30.10.10, + Project GENIE, Univ. Cal. at Berkeley, April 1965. +
11. +
R. J. Feiertag and E. I. Organick, `The Multics + input-output system,' Proc. Third Symposium on Operating Systems + Principles, October 18-20, 1971, pp. 35-41. +
12. +
D. G. Bobrow, J. D. Burchfiel, D. L. Murphy, and R. + S. Tomlinson, `TENEX, a Paged Time Sharing System for the PDP-10,' Comm. + Assoc. Comp. Mach., 15 3, March 1972, pp. 135-143. +
+

 

diff --git a/doc/cmx-lic.p b/doc/cmx-lic.p new file mode 100755 index 00000000..eba3bd37 --- /dev/null +++ b/doc/cmx-lic.p @@ -0,0 +1,31 @@ +CMX Systems, Inc., Software License + +The enclosed software and documentation are the exclusive property of CMX Systems, Inc. (CMX) and CMX Company, a division of CMX Systems, Inc., protected under the copyrights laws of the United States of America and under international treaty provisions. LICENSOR is an authorized licensor of CMX software products (herein referred to as the "SOFTWARE"). LICENSOR agrees to grant LICENSEE a license to use the SOFTWARE and LICENSEE agrees to pay for this license in accordance to the terms specified. By using the SOFTWARE, the LICENSEE has agreed to the terms set forth in this Agreement whether or not this Agreement is read. + +GRANT OF LICENSE: LICENSOR grants to licensee a nontransferable license to use the SOFTWARE. LICENSEE acknowledges that by virtue of this Agreement, LICENSEE acquires only the right to use the SOFTWARE and does not acquire any right of ownership in the SOFTWARE. LICENSOR offers a PER USER PER SITE license or a PER PRODUCT PER SITE license based upon the SOFTWARE purchase terms and as defined below: + +PER USER PER SITE LICENSE: CMX authorizes the purchaser to make backup copies of the SOFTWARE for archival purposes only. CMX authorizes the purchaser to have only a single user use the SOFTWARE as a "single seat license" on a royalty free basis. For each "single seat license", only one (1) person may use this software at a specified site and CMX will only support that single person. The SOFTWARE or its accompanying documentation must not be copied or distributed to others in any way. This license is effective until terminated. You may terminate it by destroying the SOFTWARE and documentation and all copies thereof. The license will also terminate if you fail to comply with any terms or condition of this agreement. You agree upon such termination to destroy all copies of the SOFTWARE and documentation. + +PER PRODUCT PER SITE LICENSE: The CMX software is licensed on a SINGLE LICENSEE DEVELOPED PRODUCT BASIS for ONE CPU and ONE DEVELOPMENT FACILITY on a royalty free basis. If the LICENSEE develops and sells additional LICENSEE DEVELOPED PRODUCT(s), then the LICENSEE must pay CMX the full purchase price of the SOFTWARE, for EACH additional LICENSEE DEVELOPED PRODUCT. CMX authorizes the purchaser to have as many users at a single facility use this software, but only one user may be the point of contact for technical support and CMX will only support that single person. If additional technical support is required by more than one person, then the LICENSEE may purchase SUPPORT licenses for those additional people. The SOFTWARE or its accompanying documentation may be copied and distributed to others only within the same facility. + +This license is effective until terminated. You may terminate it by destroying the SOFTWARE and documentation and all copies thereof. The license will also terminate if you fail to comply with any terms or condition of this agreement. You agree upon such termination to destroy all copies of the SOFTWARE and documentation. + +TERMS OF SOFTWARE: LICENSEE agrees not to distribute the SOFTWARE source code to any third party in any manner. LICENSEE'S use of the SOFTWARE shall be limited to integrating the SOFTWARE as an integral component within the LICENSEE'S own product (PER PRODUCT PER SITE) or products (PER USER PER SITE), depending upon the type of license acquired from LICENSOR. LICENSEE shall have the right to distribute the SOFTWARE as an integral component of the LICENSEE'S own products as long as the SOFTWARE is in absolute machine readable format (e.g., HEX file). The LICENSEE can NOT sell a product that allows the user(s) of the licensee product(s) to be able to indirectly call the CMX functions (e.g., The licensee product contains an API [Application Program Interface] that allows the user(s) to indirectly call and use the CMX functions), without the user(s) of the licensee's product(s) also purchasing a license to use the SOFTWARE. + +LIMITATION OF LICENSOR'S LIABILITY: LICENSOR shall not be liable for any damages, including but not limited to, interruption of business, loss of profit, incidental, consequential or any other claims either by LICENSEE or any other party. LICENSOR shall not be liable for any damages incurred by LICENSEE or any other person as a result of LICENSEE'S use or misuse of the SOFTWARE, even if LICENSOR had been advised of the possibility of such damage. + +SEVERABILITY: If any provision of this Agreement shall be held illegal, unenforceable or in conflict with any law governing this Agreement, the validity of remaining portions shall not be effected thereby. + +NON-WAIVER: Failure of LICENSOR at any time to require performance of this Agreement shall not limit LICENSOR'S right to enforce the provision, nor shall any waiver by LICENSOR of any breach of provision constitute a waiver of or prejudice LICENSOR'S right otherwise to demand strict performance or the provision or any other provision. + +U.S. GOVERMENT RESTRICTED RIGHTS: This SOFTWARE and documentation are restricted computer software and are provided with RESTRICTED RIGHTS. Use, duplication, or disclosure by the Government is subject to restrictions of the sort set forth in subparagraph (c) (1) (ii) of the Rights in Technical Data and Computer Software Clause at DFARS 252.227-7013. + +LIFE SUPPORT APPLICATIONS: CMX SOFTWARE is not designed for use in life support appliances, devices or systems where malfunction of the SOFTWARE can reasonably be expected to result in a personal injury. CMX customers using or selling CMX SOFTWARE for use in such applications do so at their own risk and agree to fully indemnify CMX for any damages resulting from such improper use or sale. + +WARRANTIES: LICENSOR represents and warrants the following: That LICENSOR has the right to grant LICENSEE a license to use the SOFTWARE and to enter into this Agreement. That the physical media, on which the SOFTWARE is shipped, is free from defects and that if a defect is found, a replacement copy will be provided. This limited warranty gives you specific legal rights. You may have others which vary from state to state. + +LICENSEE EXPRESSLY AGREES AND ACKNOWLEDGES THAT THE FOREGOING WARRANTIES ARE IN LIEU OF ALL OTHER WARRANTIES EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO AN IMPLIED WARRANTY OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +GOVERNING LAW: This Agreement shall be governed by the laws of the Commonwealth of Massachusetts. + +Some states do not allow limitations on the duration of an implied warranty, so the above limitations may not apply to you. This limited warranty gives you specific legal rights. You may have others, which vary from state to state. Because some states do not allow the exclusion or limitation of liability for consequential or incidental damages, the above limitations may not apply to you. diff --git a/doc/cmx-lic.txt b/doc/cmx-lic.txt new file mode 100755 index 00000000..ebeaf222 --- /dev/null +++ b/doc/cmx-lic.txt @@ -0,0 +1,112 @@ +CMX Systems, Inc., Software License + +The enclosed software and documentation are the exclusive property of CMX +Systems, Inc. (CMX) and CMX Company, a division of CMX Systems, Inc., protected +under the copyrights laws of the United States of America and under +international treaty provisions. LICENSOR is an authorized licensor of CMX +software products (herein referred to as the "SOFTWARE"). LICENSOR agrees to +grant LICENSEE a license to use the SOFTWARE and LICENSEE agrees to pay for +this license in accordance to the terms specified. By using the SOFTWARE, the +LICENSEE has agreed to the terms set forth in this Agreement whether or not +this Agreement is read. + +GRANT OF LICENSE: LICENSOR grants to licensee a nontransferable license to use +the SOFTWARE. LICENSEE acknowledges that by virtue of this Agreement, LICENSEE +acquires only the right to use the SOFTWARE and does not acquire any right of +ownership in the SOFTWARE. LICENSOR offers a PER USER PER SITE license or a +PER PRODUCT PER SITE license based upon the SOFTWARE purchase terms and as +defined below: + +PER USER PER SITE LICENSE: CMX authorizes the purchaser to make backup copies +of the SOFTWARE for archival purposes only. CMX authorizes the purchaser to +have only a single user use the SOFTWARE as a "single seat license" on a +royalty free basis. For each "single seat license", only one (1) person may use +this software at a specified site and CMX will only support that single person. +The SOFTWARE or its accompanying documentation must not be copied or +distributed to others in any way. This license is effective until terminated. +You may terminate it by destroying the SOFTWARE and documentation and all +copies thereof. The license will also terminate if you fail to comply with any +terms or condition of this agreement. You agree upon such termination to +destroy all copies of the SOFTWARE and documentation. + +PER PRODUCT PER SITE LICENSE: The CMX software is licensed on a SINGLE LICENSEE +DEVELOPED PRODUCT BASIS for ONE CPU and ONE DEVELOPMENT FACILITY on a royalty +free basis. If the LICENSEE develops and sells additional LICENSEE DEVELOPED +PRODUCT(s), then the LICENSEE must pay CMX the full purchase price of the +SOFTWARE, for EACH additional LICENSEE DEVELOPED PRODUCT. CMX authorizes the +purchaser to have as many users at a single facility use this software, but +only one user may be the point of contact for technical support and CMX will +only support that single person. If additional technical support is required by +more than one person, then the LICENSEE may purchase SUPPORT licenses for those +additional people. The SOFTWARE or its accompanying documentation may be copied +and distributed to others only within the same facility. + +This license is effective until terminated. You may terminate it by destroying +the SOFTWARE and documentation and all copies thereof. The license will also +terminate if you fail to comply with any terms or condition of this agreement. +You agree upon such termination to destroy all copies of the SOFTWARE and +documentation. + +TERMS OF SOFTWARE: LICENSEE agrees not to distribute the SOFTWARE source code +to any third party in any manner. LICENSEE'S use of the SOFTWARE shall be +limited to integrating the SOFTWARE as an integral component within the +LICENSEE'S own product (PER PRODUCT PER SITE) or products (PER USER PER SITE), +depending upon the type of license acquired from LICENSOR. LICENSEE shall have +the right to distribute the SOFTWARE as an integral component of the LICENSEE'S +own products as long as the SOFTWARE is in absolute machine readable format +(e.g., HEX file). The LICENSEE can NOT sell a product that allows the user(s) +of the licensee product(s) to be able to indirectly call the CMX functions +(e.g., The licensee product contains an API [Application Program Interface] +that allows the user(s) to indirectly call and use the CMX functions), without +the user(s) of the licensee's product(s) also purchasing a license to use the +SOFTWARE. + +LIMITATION OF LICENSOR'S LIABILITY: LICENSOR shall not be liable for any +damages, including but not limited to, interruption of business, loss of +profit, incidental, consequential or any other claims either by LICENSEE or any +other party. LICENSOR shall not be liable for any damages incurred by LICENSEE +or any other person as a result of LICENSEE'S use or misuse of the SOFTWARE, +even if LICENSOR had been advised of the possibility of such damage. + +SEVERABILITY: If any provision of this Agreement shall be held illegal, +unenforceable or in conflict with any law governing this Agreement, the +validity of remaining portions shall not be effected thereby. + +NON-WAIVER: Failure of LICENSOR at any time to require performance of this +Agreement shall not limit LICENSOR'S right to enforce the provision, nor shall +any waiver by LICENSOR of any breach of provision constitute a waiver of or +prejudice LICENSOR'S right otherwise to demand strict performance or the +provision or any other provision. + +U.S. GOVERMENT RESTRICTED RIGHTS: This SOFTWARE and documentation are +restricted computer software and are provided with RESTRICTED RIGHTS. Use, +duplication, or disclosure by the Government is subject to restrictions of the +sort set forth in subparagraph (c) (1) (ii) of the Rights in Technical Data and +Computer Software Clause at DFARS 252.227-7013. + +LIFE SUPPORT APPLICATIONS: CMX SOFTWARE is not designed for use in life support +appliances, devices or systems where malfunction of the SOFTWARE can reasonably +be expected to result in a personal injury. CMX customers using or selling CMX +SOFTWARE for use in such applications do so at their own risk and agree to +fully indemnify CMX for any damages resulting from such improper use or sale. + +WARRANTIES: LICENSOR represents and warrants the following: That LICENSOR has +the right to grant LICENSEE a license to use the SOFTWARE and to enter into +this Agreement. That the physical media, on which the SOFTWARE is shipped, is +free from defects and that if a defect is found, a replacement copy will be +provided. This limited warranty gives you specific legal rights. You may have +others which vary from state to state. + +LICENSEE EXPRESSLY AGREES AND ACKNOWLEDGES THAT THE FOREGOING WARRANTIES ARE IN +LIEU OF ALL OTHER WARRANTIES EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO +AN IMPLIED WARRANTY OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +GOVERNING LAW: This Agreement shall be governed by the laws of the Commonwealth +of Massachusetts. + +Some states do not allow limitations on the duration of an implied warranty, so +the above limitations may not apply to you. This limited warranty gives you +specific legal rights. You may have others, which vary from state to state. +Because some states do not allow the exclusion or limitation of liability for +consequential or incidental damages, the above limitations may not apply to +you. diff --git a/doc/index.htm b/doc/index.htm new file mode 100755 index 00000000..98e02108 --- /dev/null +++ b/doc/index.htm @@ -0,0 +1,15 @@ + + +Hytech Scales Pty Ltd + + + +

+This page is under construction.

+Please see http://www.hytech-international.com +

+

+For internal documentation please see http://www.hytechscales.com/doc +

+ + \ No newline at end of file diff --git a/doc/lcd0.txt b/doc/lcd0.txt new file mode 100755 index 00000000..028f914e --- /dev/null +++ b/doc/lcd0.txt @@ -0,0 +1,34 @@ +ESCAPE SEQUENCES WHICH CAN BE TRANSMITTED TO THE TOUCHSCREEN + +$1B $1B REGULAR_CHAR +$1B '.' s ll hh data... CHARACTER_SET_DOWNLOAD (s=set '0'-'7', hhll = count) +$1B '/' f CROSSED_ZEROS (f=even: open zeros, f=odd: crossed zeros) +$1B '?' s CHARACTER_SET_QUERY (s=character set, digit from '0' thru '7') +$1B 'B' d BUZZER (d=duration) +$1B 'b' d f BUZZ_AT_FREQ (d=duration 0-ff, f=frequency 0-f) +$1B 'C' x y CLEAR_RECTANGLE (x=horiz. size pixels, y=vert. size pixels) +$1B 'D' m DRAW_MODE (m='0' xor mode, m='1' or mode) +$1B 'E' f ENABLE_CNTRL (f=even: disable display, f=odd: enable display) +$1B 'F' x y FILLED_RECTNC (x=horiz. size pixels, y=vert. size pix) +$1B 'G' f INTERPRET_MODE (f=even: literal, f=odd: interpret ctrl chr) +$1B 'K' CLR_DISP (also homes the cursor) +$1B 'L' d c x y SCROLL_REGION (d=direction, c=count, x=horiz. size, y=vert. sz) +$1B 'M' f MOSFET_CONTROL (f='0' turn off power to terminal) +$1B 'N' x y DRAW_RECTNC (x=horiz. size pixels, y=vert. size pixels) +$1B 'P' f PROP_FIXED_MODE (f=even: fixed spacing, f=odd: proportional) +$1B 'R' x y DRAW_RECT (x=horiz. size pixels, y=vert. size pixels) +$1B 'S' x y SET_CURSOR (x=top left x coordinate, y=top left y coordinate) +$1B 'T' h m s mm dd yy SET_TIME (hour, minute, second, month, day, year-1980) +$1B 'U' f NULLSUB (doesn't do anything... parameter 'f' doesn't matter) +$1B 'V' f CONTRAST_CONTROL (f=even 1 step darker, f=odd 1 step lighter) +$1B 'W' f NULLSUB (doesn't do anything... parameter 'f' doesn't matter) +$1B 'X' f SAVE_STATE (f=even save state, f=odd restore state) +$1B 'Z' r x y xx yy TOUCH_ZONE (return value, top left x/y, size xx/yy pixels) +$1B s SET_CHSET_A (s=character set, digit from '0' thru '7') + +ESCAPE SEQUENCES WHICH CAN BE RECEIVED FROM THE TOUCHSCREEN + +$1B $1B REGULAR_CHAR +$1B 'T' h m s mm dd yy CUR_TIME (hour, minute, second, month, day, year-1980) +$1B '?' s aaaa QUERY_RESPONSE (s=set '0'-'7', aaaa = CRC in hex, ascii style) + diff --git a/doc/overview.txt b/doc/overview.txt new file mode 100755 index 00000000..dad000a4 --- /dev/null +++ b/doc/overview.txt @@ -0,0 +1,231 @@ +HYTECH CMX/UZI IMPLEMENTATION - OVERVIEW + +The already-existing components of the system are as follows: + + EPROM To run Hytech CMX/UZI on the Hytech 1000 / 1500 terminals, + the standard Hytech EPROM version 5.531 or later is required. + + Prerequisites: None. + + In: Please see c:\sys, c:\sys\romfls, and in particular, the + files c:\sys\bootldr.mac and its dependencies (bootldf.mac !!) + + By: I.M.Cumming, N.Downing. Hytech owns all rights to this. + + BOOT Since version 5.529 the Hytech EPROM has provided a "hook" so + that loadable programs are allowed to intercept and customise + the boot process. This is done by putting a CRC-protected + file named BOOT.BIN onto CP/M disk A: in the 4:0000 - 7:FFFF + physical memory region. The EPROM loads this at 3:0000 and + runs it. This contains a customised boot process as follows: + + 1. Find a further file named KERNEL.BIN on CP/M disk A: + 2. Load the file, 16 kbytes at a time, to physical 8:0000 + 3. Map the physical 8:0000 memory to logical address 4000 + 4. Jump to logical address 4000 (the start of KERNEL.BIN) + + In: Please see c:\uzi\boot for the boot loader sources. + + By: N.Downing. Hytech owns all rights to this. + + CMX Real time operating system. Responsible for multitasking, + interprocess communication, and priority based scheduling. + The CMX functions are only available for private use within + the kernel. CMX does not provide for loadable programs or + system calls. It's only designed for a monolithic program. + Basic device drivers for the built-in devices (serial ports + and API BUS) are provided, based on the example serial port + routines written by CMX. These have to be "compiled in" + to the monolithic kernel, and so can't be loaded at runtime. + + Prerequisites: BOOT. + + In: Please see c:\uzi\cmx for the CMX kernel sources. + + By: CMX Systems. Binaries are redistributable, source not. + + UZI Small clone of the Unix operating system. Responsible for + disk operations (RAM disk and flash card), and responsible + for managing non-kernel tasks and memory. Also contains + its own Unix-style multitasking, interprocess communication + and priority based scheduling mechanisms. These are useful + to non-kernel tasks, so they can't be eliminated, although + they are redundant since CMX also provides such functionality. + + Thus UZI's scheduler is "slaved" to CMX's scheduler, ie. + Unix is the lowest priority CMX task and can be pre-empted + at any time. Unix is not allowed to pre-empt CMX. From the + viewpoint of CMX, Unix is just one task, so CMX doesn't care + which Unix "process" happens to be active, and CMX doesn't + care whether Unix is running user or kernel code. The CMX + scheduler just allocates the available time slices to the Unix + task, whereupon UZI's scheduler further subdivides those time + slices and allocates them as required to each Unix task. + + It makes sense for UZI's scheduler to be "slave" and CMX to + be "master" because Unix is not a real-time operating system, + and therefore it's possible for one Unix task to affect the + running of another. For example if you are running one Unix + task and you start another, the first Unix task will slow down + to half speed. CMX provides perfect insulation against this + effect, which is useful for writing device drivers. Unix is + only intended to provide the best "average" performance and + doesn't provide any guarantees about "worst case" performance. + + Prerequisites: CMX. + + In: Please see c:\uzi\kernel for the UZI kernel sources. The + folder c:\uzi\ihex2bin also has an important utility which is + needed to create the final kernel image (IAR outputs hex only). + + By: H.F.Bower, D.Braun, S.Nitschke. Source and binaries are + redistributable. However the terms of the GPL require us to + post source code for our changes on our website (no problem). + + LIBC Standard "C" library for interfacing to the kernel. Provides + services on behalf of user programs. Some of these services + are low-level system calls, such as open(), read(), write(). + However the majority of services provided by the "C" library + are derived from the lower-level calls, for example fopen(). + + Remaining services are general utility routines, some based + on the lower level system services, eg. getpwent() and some + are completely self contained eg. atoi(). Source code to all + library functions is available. The library can be rebuilt + at any time. The library management is done with IAR tools. + + Prerequisites: UZI. + + In: Please see c:\uzi\libc for C-language sources. Please + see c:\uzi\libc\syscalls for assembly-language sources. Also + see c:\uzi\include which has the matching C-language headers! + + By: Adriano Cunha. Originally based on the Linux-8086 C + library. Obtained from www.uzix.org (UZIX is another variant + of UZI, targeted to a bank switched Z80 processor, not Z180!). + As these are all GPL'd we must post any changes on our site. + + INIT Under Unix, "init" is always the first non-kernel task to be + loaded. Since all further Unix tasks are created by forking, + "init" is referred to as the "mother of all processes". The + init program can be very simple (just loading a shell) or it + can be quite complex (allocate a TTY, provide a login prompt, + verify the user's password, find the user's home directory, + etc). For now, we are using a very simple version of "init" + which was written by D.Braun and S.Nitschke for UZI-280. It + doesn't support using the user file "/etc/passwd" so we will + need to change to something more sophisticated. The UZIX + version of the init program is much better but needs work. + + Prerequisites: LIBC. + + In: Please see c:\uzi\simple for most of the user-level code, + including this particular program (the file is called init.c). + + By: D.Braun, S.Nitschke. License is GPL. + + SHELL Under Unix, the "shell" is usually invoked by "init" once + the user's login details have been verified. The shell is + the first point of contact with the user. The main purpose + of the shell is to allow the user to start other programs as + necessary, but there are usually some built-in functions too. + Process control is also important: A good shell is able to + monitor the tasks that have been started, report completion, + and stop them as necessary. Most flavours of unix use their + own particular shell eg. the "Bourne Shell" is very popular. + Other shells include the "C Shell" and the "Korn Shell". + + At the moment we have a very simple and basic shell called + SASH or "Stand Alone SHell for system maintenance". We have + available another shell called FSH or "Fudeba SHell" which + is small enough to compile under our system, and works, but + this FSH has so few commands as to be almost useless. Nick + is planning to implement a banked memory model for user code, + which would allow us to use a more standard interface such as + the Bourne shell. Please note that the shell is only an issue + for remote maintenance, since our users will be expecting a + GUI interface and will never interact with the shell directly. + + We have source code to the Bourne shell, written by Stephen + R. Bourne, but it needs work to compile under the IAR compiler, + and there are licensing issues meaning we are not allowed to + distribute the resulting code. So instead we are going to use + the "Minix Bourne Shell" written by Andrew S. Tanenbaum and + others. This has slightly cleaner code than the original, and + has been successfully compiled by Nick using IAR. However we + can't link the resulting executable as it would be > 32kbytes. + + Prerequisites: LIBC. + + In: See c:\uzi\bsh, c:\uzi\fsh, c:\uzi\msh, c:\uzi\sash for + the source codes to all the shell variants mentioned here. + + By: (SASH) Robert I. Bell, Adriano Cunha. License is GPL. + + UTILS Several small programs which run under Windows 2000. These + allow us to prepare a flash card which is capable of booting + UZI, and some other diagnostic tasks. The utilities are very + basic and will not be the subject of much further development. + + Prerequisites: UZI. For best maintainability, definitions + regarding the flash card format are kept in c:\uzi\kernel, + so the utility tools must include "unix.h" to obtain these. + However the utilities have their own slightly older version + of the UZI operating system, which doesn't need CMX. So the + c:\uzi\cmx folder is not required for compiling c:\uzi\utils. + + In: Please see c:\uzi\utils for the UZI utility sources. + + By: H.F.Bower, D.Braun, S.Nitschke. License is GPL. + +Before releasing the system we need to add the following extra components: + + APP Application code. This is to be written by Joost and will + make use of the services provided by LIBC. Once the "shell" + issues have been resolved, we'll also provide a shell script + so that the application gets run when starting the terminal. + + Prerequisites: LIBC. + + In: Nick suggests c:\uzi\app if all agree? + + By: J.Morsink. Hytech owns all rights to this. + + PPPD Point to Point Protocol Daemon. This will be based on some + existing PPPD and needs a bit of research. The UZI kernel + will need to be upgraded to provide baud rate setting and + serial port initialisation calls (perhaps via an ioctl + interface). The nature of this upgrade depends on what PPPD + we decide to use. We also need a program such as "CHAT" + which gets loaded by PPPD each time a call has to be made. + The "CHAT" program is responsible for sending AT commands. + + Prerequisites: LIBC. + + Further details of the implementation are not yet known. + + FTPD File Transfer Protocol Daemon. This will be based on some + existing FTPD and needs a bit of research. The UZI kernel + will need to be upgraded to provide socket calls, but the + nature of this upgrade depends on what FTPD we decide to use. + + The FTP daemon will allow our central servers to dial in via + the ISDN modem, and retrieve transaction data or send updates. + + Prerequisites: PPPD, LIBC. + + Further details of the implementation are not yet known. + + TELNETD Telnet Protocol Daemon. This will be based on some existing + TELNETD and needs a bit of research. The UZI kernel will need + to be upgraded to provide socket calls, but the nature of this + upgrade depends on what TELNETD we decide to use. + + The TELNET daemon will allow our maintenane staff to dial in + manually via the ISDN modem, and perform troubleshooting and + diagnostics. In effect it provides a remote "shell" prompt. + + Prerequisites: PPPD, LIBC. + + Further details of the implementation are not yet known. + diff --git a/doc/stdlib.txt b/doc/stdlib.txt new file mode 100755 index 00000000..4ef3fe0d --- /dev/null +++ b/doc/stdlib.txt @@ -0,0 +1,230 @@ +UZI STANDARD LIBRARY INTERFACE SUMMARY + +; ----------------------------------------------------------------------------- + +CONTENTS + +extern void exit (int); +extern void abort (void); +extern unsigned int sleep (unsigned int seconds); +extern int rand (void); +extern void srand (uint seed); +extern char *__longtoa (unsigned long, char *, int, char, char); +extern char *itoa (int value, char *strP, int radix); +extern char *ultoa (unsigned long value, char *strP, int radix); +extern char *ltoa (long value, char *strP, int radix); +extern int atoi (char *str); +extern long atol (char *strP); +extern char *_itoa (int value); +extern char *_ltoa (long value); +extern char *_ultoa (unsigned long value); +extern char *ultostr (unsigned long value, int radix); +extern char *ltostr (long value, int radix); +extern long strtol (char * nptr, char ** endptr, int base); +extern unsigned long strtoul (char * nptr, char ** endptr, int base); +extern double strtod (char * nptr, char ** endptr); +extern char **environ; +extern char *getenv (char *); +extern int putenv (char *); +extern int setenv (char *, char *, int); +extern void unsetenv (char *); +typedef void (*atexit_t) (int); +typedef void (*onexit_t) (int, void *); +extern int atexit (atexit_t); +extern int on_exit (onexit_t, void *arg); +extern onexit_t __cleanup; +extern char *crypt (char *__key, char *__salt); +extern int _bsearch; +extern void *bsearch (void *key, void *base, size_t num, + size_t size, cmp_func_t cmp); +extern void *lfind (void *key, void *base, size_t *num, size_t size, + cmp_func_t cmp); +extern void *lsearch (void *key, void *base, size_t *num, size_t size, + cmp_func_t cmp); +extern void *_qbuf; +extern void qsort (void *base, size_t num, size_t size, cmp_func_t cmp); +extern int opterr; +extern int optind; +extern char *optarg; +extern int getopt (int argc, char *argv[], char *optstring); +extern char *getpass(char *prompt); +extern int _argc; +extern char **_argv; + +; ----------------------------------------------------------------------------- + +extern void exit (int); + +; ----------------------------------------------------------------------------- + +extern void abort (void); + +; ============================================================================= + +extern unsigned int sleep (unsigned int seconds); + +; ============================================================================= + +extern int rand (void); + +; ----------------------------------------------------------------------------- + +extern void srand (uint seed); + +; ============================================================================= + +extern char *__longtoa (unsigned long, char *, int, char, char); + +; ----------------------------------------------------------------------------- + +extern char *itoa (int value, char *strP, int radix); + +; ----------------------------------------------------------------------------- + +extern char *ultoa (unsigned long value, char *strP, int radix); + +; ----------------------------------------------------------------------------- + +extern char *ltoa (long value, char *strP, int radix); + +; ============================================================================= + +extern int atoi (char *str); + +; ----------------------------------------------------------------------------- + +extern long atol (char *strP); + +; ============================================================================= + +extern char *_itoa (int value); + +; ----------------------------------------------------------------------------- + +extern char *_ltoa (long value); + +; ----------------------------------------------------------------------------- + +extern char *_ultoa (unsigned long value); + +; ============================================================================= + +extern char *ultostr (unsigned long value, int radix); + +; ----------------------------------------------------------------------------- + +extern char *ltostr (long value, int radix); + +; ============================================================================= + +extern long strtol (char * nptr, char ** endptr, int base); + +; ----------------------------------------------------------------------------- + +extern unsigned long strtoul (char * nptr, char ** endptr, int base); + +; ----------------------------------------------------------------------------- + +extern double strtod (char * nptr, char ** endptr); + +; ============================================================================= + +extern char **environ; + +; ----------------------------------------------------------------------------- + +extern char *getenv (char *); + +; ----------------------------------------------------------------------------- + +extern int putenv (char *); + +; ----------------------------------------------------------------------------- + +extern int setenv (char *, char *, int); + +; ----------------------------------------------------------------------------- + +extern void unsetenv (char *); + +; ============================================================================= + +typedef void (*atexit_t) (int); + +; ----------------------------------------------------------------------------- + +typedef void (*onexit_t) (int, void *); + +; ----------------------------------------------------------------------------- + +extern int atexit (atexit_t); + +; ----------------------------------------------------------------------------- + +extern int on_exit (onexit_t, void *arg); + +; ----------------------------------------------------------------------------- + +extern onexit_t __cleanup; + +; ============================================================================= + +extern char *crypt (char *__key, char *__salt); + +; ============================================================================= + +extern int _bsearch; + +; ----------------------------------------------------------------------------- + +extern void *bsearch (void *key, void *base, size_t num, + size_t size, cmp_func_t cmp); + +; ----------------------------------------------------------------------------- + +extern void *lfind (void *key, void *base, size_t *num, size_t size, + cmp_func_t cmp); + +; ----------------------------------------------------------------------------- + +extern void *lsearch (void *key, void *base, size_t *num, size_t size, + cmp_func_t cmp); + +; ----------------------------------------------------------------------------- + +extern void *_qbuf; + +; ----------------------------------------------------------------------------- + +extern void qsort (void *base, size_t num, size_t size, cmp_func_t cmp); + +; ============================================================================= + +extern int opterr; + +; ----------------------------------------------------------------------------- + +extern int optind; + +; ----------------------------------------------------------------------------- + +extern char *optarg; + +; ----------------------------------------------------------------------------- + +extern int getopt (int argc, char *argv[], char *optstring); + +; ============================================================================= + +extern char *getpass(char *prompt); + +; ============================================================================= + +extern int _argc; + +; ----------------------------------------------------------------------------- + +extern char **_argv; + +; ----------------------------------------------------------------------------- + diff --git a/doc/syscalls.p b/doc/syscalls.p new file mode 100755 index 00000000..ecca46f2 --- /dev/null +++ b/doc/syscalls.p @@ -0,0 +1,1106 @@ +UZI SYSTEM CALL INTERFACE SUMMARY + +; ----------------------------------------------------------------------------- + +CONTENTS + +int errno; +void _exit (int val); +int access (char *path, int mode); +int alarm (uint secs); +int brk (char *addr); +int chdir (char *dir); +int chroot (char *dir); +int chmod (char *path, mode_t mode); +int chown (char *path, int owner, int group); +int close (int uindex); +int creat (char *name, mode_t mode); +int dup (int oldd); +int dup2 (int oldd, int newd); +int execve (char *name, char *argv[], char *envp[]); +int fork (void); +int fstat (int fd, void *buf); +int getfsys (int dev, void *buf); +int getgid (void); +int getpid (void); +int getppid (void); +int getuid (void); +int geteuid (void); +int getegid (void); +int getprio (void); +int ioctl (int fd, int request, ...); +int kill (int pid, int sig); +int link (char *oldname, char *newname); +int symlink (char *oldname, char *newname); +int mknod (char *name, mode_t mode, int dev); +int mkfifo (char *name, mode_t mode); +int mount (char *spec, char *dir, int rwflag); +int open (char *name, uint flag, ...); +int pause (void); +int pipe (int fildes[2]); +int read (int fd, void *buf, uint nbytes); +int sbrk (uint incr); +int seek (int fd, int offset, int whence); +off_t lseek (int fd, off_t offset, int whence); +int setgid (int gid); +int setuid (int uid); +int setprio (int pid, char prio); +sig_t signal (signal_t sig, sig_t func); +int stat (char *path, void *buf); +int stime (time_t *tvec); +int sync (void); +time_t time (time_t *tvec); +int times (struct tms *buf); +int utime (char *path, struct utimbuf *buf); +int umask (int mask); +int umount (char *spec); +int unlink (char *path); +int wait (int *statloc); +int write (int fd, void *buf, uint nbytes); +int reboot (char p1, char p2); +int systrace (int onoff); + +; ----------------------------------------------------------------------------- + +int errno; + +If any system call fails, it returns -1 (this is why most of the calls below +are listed as having an 'int' return value). In this case the errno variable +will give the reason for the error. Possible error codes are as follows: + +# Start /usr/lib/liberror.txt + +1 Operation not permitted (EPERM) +2 No such file or directory (ENOENT) +3 No such process (ESRCH) +4 Interrupted system call (EINTR) +5 I/O error (EIO) +6 No such device or address (ENXIO) +7 Arg list too long (E2BIG) +8 Exec format error (ENOEXEC) +9 Bad file number (EBADF) +10 No child processes (ECHILD) +11 Try again (EAGAIN) +12 Out of memory (ENOMEM) +13 Permission denied (EACCES) +14 Bad address (EFAULT) +15 Block device required (ENOTBLK) +16 Device or resource busy (EBUSY) +17 File exists (EEXIST) +18 Cross-device link (EXDEV) +19 No such device (ENODEV) +20 Not a directory (ENOTDIR) +21 Is a directory (EISDIR) +22 Invalid argument (EINVAL) +23 File table overflow (ENFILE) +24 Too many open files (EMFILE) +25 Not a typewriter (ENOTTY) +26 Text file busy (ETXTBSY) +27 File too large (EFBIG) +28 No space left on device (ENOSPC) +29 Illegal seek (ESPIPE) +30 Read-only file system (EROFS) +31 Too many links (EMLINK) +32 Broken pipe (EPIPE) +33 Math argument out of domain of func (EDOM) +34 Math result not representable (ERANGE) +35 Resource deadlock would occur (EDEADLK) +36 File name too long (ENAMETOOLONG) +37 No record locks available (ENOLCK) +38 Function not implemented (EINVFNC) +39 Directory not empty (ENOTEMPTY) +40 Too many symbolic links encountered (ELOOP) +41 It's a shell script (ESHELL) + +# End /usr/lib/liberror.txt + +; ----------------------------------------------------------------------------- + +void _exit (int val); + +Returns control to the system, terminating the current process. Some other +eligible process will then run instead. The memory belonging to the current +process is released and all files are closed. The function call does not +return, hence the void return value (normally all system calls return 'int'). + +Please note that _exit does not perform any user exit processing, hence the +name '_exit' rather than 'exit'. The standard C library provides the functions +exit() and atexit() allowing any user hooks to execute before making the _exit +system call. For example, files opened by fopen() are flushed and closed at +exit, by a special cleanup function that gets registered during 'C' startup. + +; ----------------------------------------------------------------------------- + +int access (char *path, int mode); + +Tests whether the current user (or effective user) is allowed to access the +given file. If so, returns 0. If not, returns -1, and errno filled in. + +Note: The test is equivalent to opening the file with the specified mode, and +then closing it again without doing anything. Because the kernel uses this +sequence of actions to determine whether access is granted, any existing file +of the given name, will have its last-access time and date updated by the call. + +; ----------------------------------------------------------------------------- + +int alarm (uint secs); + +Requests that the current process receive an "alarm" signal after the given +number of seconds has expired. As there is only one "alarm" counter per +process, any previous active "alarm" request will be overridden by the call. + +; ----------------------------------------------------------------------------- + +int brk (char *addr); + +Sets the top of the process's memory to the given address. On entry to the +program, "brk" is set to the top of the loaded program image, and therefore +must be adjusted slightly higher if the program is going to use extra memory +for data. This is normally done at least once, by the 'C' startup code, to +inform the kernel of how much uninitialised data the program wishes to use. + +The kernel checks if the "brk" value is getting too close to the process's +stack pointer (ie. if there would not be enough stack space left to process a +system call or an interrupt). In this case the call fails and returns -1. + +The 'C' library also provides a malloc() and free() implementation, which is +based on the brk() and sbrk() system calls. Please see the sbrk() description. + +; ----------------------------------------------------------------------------- + +int chdir (char *dir); + +Sets the current process's directory to the given path. This is equivalent to +"opening" the directory (execute permission is required, and the file-time is +updated), and so it is also useful to prevent any other processes from trying +to remove the directory or dismount the drive which contains the directory. + +Of course, subsequent system calls such as open() or access() or even chdir() +will then use the selected directory as the starting point for relative path +specification, for example if you are in directory "/usr/lib" and you create +the file "foo.txt" this is the same as creating the file "/usr/lib/foo.txt". + +; ----------------------------------------------------------------------------- + +int chroot (char *dir); + +Sets the current process's root directory to the given path. This is referred +to as a "jail", because while the chroot is active, the current process cannot +access any files or directories higher than the given root directory. + +For example, after calling chroot("/usr"), if the user tries to create a file +"/lib/foo.txt" this will really create a file called "/usr/lib/foo.txt". This +can be a useful security measure for programs such as email daemons, etc. + +; ----------------------------------------------------------------------------- + +int chmod (char *path, mode_t mode); + +Allows file permissions to be altered. Mode is normally a 3-digit octal value, +with the digits representing "user, group, other" respectively. For example +644 would mean permissions of '6' for the user who owns the file, '4' for users +in the same group as the file, and '4' for everyone else. + +The octal digits can be any of the following: (1=Execute, 2=Write, 4=Read) + + EXECUTE WRITE READ + 0 No No No + 1 Yes No No + 2 No Yes No + 3 Yes Yes No + 4 No No Yes + 5 Yes No Yes + 6 No Yes Yes + 7 Yes Yes Yes + +In addition a fourth octal digit can be prepended, interpreted as follows: + + VTX (??) SETGID SETUID + 0 No No No + 1 Yes No No + 2 No Yes No + 3 Yes Yes No + 4 No No Yes + 5 Yes No Yes + 6 No Yes Yes + 7 Yes Yes Yes + +The SETGID and SETUID features are useful for allowing users to access certain +superuser functions but not others. In this case a file's owner would be set +to "root" and the SETUID bit would be set. The file is usually an executable. + +For example the "login" program runs as SETUID 0, meaning anyone who can run +"login" will temporarily become the superuser while this trusted program is +executed. It's up to the system administrator to make sure that the "login" +program can't do anything malicious, before granting it SETUID permissions. + +To make things easier, the following definitions are provided by sys/stat.h: + +#define S_UMASK 07777 /* bits modifiable by chmod */ + +#define S_ISUID 04000 /* set euid to file uid */ +#define S_ISGID 02000 /* set egid to file gid */ +#define S_ISVTX 01000 /* */ + +#define S_IREAD 0400 /* owner may read */ +#define S_IWRITE 0200 /* owner may write */ +#define S_IEXEC 0100 /* owner may execute */ + +#define S_IGREAD 0040 /* group may read */ +#define S_IGWRITE 0020 /* group may write */ +#define S_IGEXEC 0010 /* group may execute */ + +#define S_IOREAD 0004 /* other may read */ +#define S_IOWRITE 0002 /* other may write */ +#define S_IOEXEC 0001 /* other may execute */ + +See "c:\uzi\include\sys\stat.h" for further handy macros, for example the +S_IRWXU macro returns a mask which contains all of the "read, write, execute" +bits for "user" set. This is handy for isolating a particular set of bits. + +; ----------------------------------------------------------------------------- + +int chown (char *path, int owner, int group); + +Changes the owner and group of the given file. The owner and group are 16 bit +integer numbers which correspond to entries in "/etc/passwd" and "/etc/group" +respectively. The user "root" is normally 0 and often is in group 0 as well. + +Superuser permissions are required in order to make this call. In other words +it's not permitted for a user to create a file and then assign ownership to +anyone else. (Assigning ownership to "root" could cause a security problem). + +; ----------------------------------------------------------------------------- + +int close (int uindex); + +Closes the given file handle. The file handle must previously have been opened +with open() or creat(), or created using dup() or dup2(). If the caller is the +last process with a handle to this file, the kernel will also close the file. + +When the kernel really closes the file, the file's last-modification and/or +last-access times are updated. Any unwritten data is flushed, and the disk is +synchronised. The in-core inode table entry is marked as free for later use. + +; ----------------------------------------------------------------------------- + +int creat (char *name, mode_t mode); + +Creates a file of the given name, and opens it in the given mode. Normally +mode would be one of the write modes such as O_WRONLY or possibly O_RDWR. Any +existing file of the same name is deleted first, so the caller to creat() can +be assured of getting a zero-length file before beginning to write data. + +It's not possible to specify the access permissions for the file during this +call. Instead, the user must call the umask() function to set the default file +creation permissions, then call creat() as described here. The argument to +umask() is specified in 'inverse', for example if the file was to be created +with octal permissions '755' you would call umask(022) followed by creat(). + +If creat() is successful, a file handle is returned. This opaque "token" is +used for further access to the file, eg. by read(), write() or close(). Each +process has its own file table, so handles are not unique across processes. + +To make things easier, the following definitions are provided by fcntl.h: + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +/* Flag values for open only */ +#define O_CREAT 0x0100 /* create and open file */ +#define O_TRUNC 0x0200 /* open with truncation */ +#define O_NEW 0x0400 /* create only if not exist */ +#define O_SYMLINK 0x0800 /* open symlink as file */ + +/* a file in append mode may be written to only at its end. */ +#define O_APPEND 0x2000 /* to end of file */ +#define O_EXCL 0x4000 /* exclusive open */ +#define O_BINARY 0x8000 /* not used in unix */ + +; ----------------------------------------------------------------------------- + +int dup (int oldd); + +Duplicates the given file handle. The file handle must previously have been +opened with open() or creat(), or created using dup() or dup2(). Any free +location in the process's file table can be used to create the duplicate. + +So "oldd" is copied into a new spot in order to create the duplicate reference. +Both handles then refer to the same inode (each in-core inode has a reference +count indicating how many duplicated or inherited handles refer to the file). + +If dup() is successful, a file handle is returned. This opaque "token" is used +for further access to the file, eg. by read(), write() or close(). + +; ----------------------------------------------------------------------------- + +int dup2 (int oldd, int newd); + +Duplicates the given file handle. The file handle must previously have been +opened with open() or creat(), or created using dup() or dup2(). The caller +specifies a particular location in the process's file table, using "newd". + +If "newd" was previously open, it is closed using the close() system call. +Then "oldd" is copied into "newd" in order to create the duplicate reference. +Both handles then refer to the same inode (each in-core inode has a reference +count indicating how many duplicated or inherited handles refer to the file). + +If dup2() is successful, a file handle is returned. This opaque "token" is +used for further access to the file, eg. by read(), write() or close(). Of +course, this return value is always equal to the value of "newd" passed in. + +; ----------------------------------------------------------------------------- + +int execve (char *name, char *argv[], char *envp[]); + +Loads a program from the disk and executes it. The current user must have +execute permission for the file specified by "name". Information is passed to +the executed program using the argv[] and envp[] arrays. The execve() call +does not return, because the program is loaded into the same memory as the +caller of execve(). Instead, the executed program will execute forever, or at +least until it calls execve() again or exits with the _exit system call. + +The kernel allocates some temporary storage in order to save your argv[] and +envp[] arrays while the new program is being loaded. They are compacted into +kernel memory, and then copied back out into user memory after loading the +program. The 'C' startup saves the envp[] pointer for use by the getenv() and +setenv() library calls, and then passes the argv[] and argc into your main(). + +Note that execve() can return in one situation: If the file can't be executed. +In this case execve() returns -1 and errno gives the reason why. + +; ----------------------------------------------------------------------------- + +int fork (void); + +Creates a new process, by duplicating the current process. This is the only +way to create a new process under Unix. The created process will return from +fork() a value of 0, which tells the subsequent code that it should behave as +the child of the fork() rather than the parent. Often it would then execve(). + +The originally existing process will return from fork() a value indicating how +to find the new process just created. So subsequent code knows that it should +behave as the parent of the fork() rather than the child. Using the PID value +returned, the process which forked is able to keep track of the progress of the +child, and obtain an exitcode when the child exits. See the wait() call. + +All memory belonging to the process is copied. Of course there must be enough +free memory for the new process's code and data (32 kbytes). It's also quite a +lengthy operation, since the entire 32 kbytes must be copied byte for byte. + +All file handles belonging to the process are duplicated. This doesn't require +any files to be opened in reality, instead the in-core inodes simply have their +reference count increased by one, to show that someone has inherited a handle. + +Of course, if there is not enough memory or there is no free process table +entry available, fork() will fail and return -1. Errno gives the reason why. + +; ----------------------------------------------------------------------------- + +int fstat (int fd, void *buf); + +Checks whether the file exists, and if so, returns information about it. Note +that the user doesn't need to have any access to the file in order to make this +call. The user only needs execute permission on the directory containing it. + +Calling fstat does not update the file's last accessed time. It's completely +benign and therefore would be used by a directory listing program (for example) +in preference to the stat() system call. (Both return the same information). + +The structure of "buf" is defined in types.h and contains the following fields: + +/* data structure for stat() */ +struct stat { /* USER! Really only used by users */ + uint st_dev; /* device number */ + uint st_ino; /* inode number */ + mode_t st_mode; /* file mode */ + uint st_nlink; /* number of links */ + uint st_uid; /* owner id */ + uint st_gid; /* owner group */ + uint st_rdev; /* */ + blkoff_t st_size; /* Nick changed off_t to blkoff_t file size */ + time_t st_atime; /* last access time */ + time_t st_mtime; /* last modification time */ + time_t st_ctime; /* file creation time */ +}; + +The relevant types "mode_t", "blkoff_t" and "time_t" are defined by types.h: + +typedef unsigned int mode_t; + +typedef struct blkoff_t { + uint o_blkno; /* Block number */ + int o_offset; /* Offset within block 0-511 */ +} blkoff_t; + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int getfsys (int dev, void *buf); + +Returns information about the filesystem mounted on the given device. This is +a copy of the superblock for the filesystem, and thus can be used by a utility +such as "df" to show information about the free space on the filesystem. + +; ----------------------------------------------------------------------------- + +int getgid (void); + +Returns the GID or "group ID" of the current process. This is a unique integer +referring to a line in the file "/etc/group" and is initialised at login time. + +; ----------------------------------------------------------------------------- + +int getpid (void); + +Returns the PID or "process ID" of the current process. This is a unique +integer generated when a process forks and is allocated a process table entry. + +; ----------------------------------------------------------------------------- + +int getppid (void); + +Returns the PID or "process ID" of the parent process. This is a unique +integer generated at the time the parent process was created. The parent +process is the process which forked to create this (the current) process. + +; ----------------------------------------------------------------------------- + +int getuid (void); + +Returns the UID or "user ID" of the current process. This is a unique integer +referring to a line in the file "/etc/passwd" and is initialised at login time. + +; ----------------------------------------------------------------------------- + +int geteuid (void); + +Returns the effective UID or "user ID" of the current process. This would +normally be equal to the value returned by getuid(), except that the user may +have executed a binary program with the SETUID bit set. If so, the effective +user ID will be the user ID of the owner of that program. For example, when +executing the "login" utility, the effective user ID is always "root". + +; ----------------------------------------------------------------------------- + +int getegid (void); + +Returns the effective GID or "group ID" of the current process. This would +normally be equal to the value returned by getgid(), except that the user may +have executed a binary program with the SETGID bit set. If so, the effective +user ID will be the user ID of the group of that program. For example, when +executing email daemons, the effective group ID is often "mail". + +; ----------------------------------------------------------------------------- + +int getprio (void); + +Returns the priority of the current process. This is an integer indicating how +many system "ticks" should be allocated to the process each time it runs. When +this number of "ticks" expires each time, some other process is allowed to run. + +; ----------------------------------------------------------------------------- + +int ioctl (int fd, int request, ...); + +Allows arbitrary control of devices. The handle "fd" must have been opened +with the open() system call or created with dup() or dup2(). Only special +files referring to devices can be manipulated with the ioctl() system call. + +The caller must know what kind of device the handle refers to, for example a +TTY device will respond to certain kinds of ioctl() requests, whereas a block +device will respond to different ones. Unix doesn't inspect the "request" or +subsequent parameters given. These are simply passed on to the device driver. + +; ----------------------------------------------------------------------------- + +int kill (int pid, int sig); + +Sends a signal to a process. If the process does not catch the signal, it will +be killed, hence the name "kill". The kill() system call can also be used to +communicate with a child in a more benign way. The "pid" is often obtained as +the return value from fork(), or else by using the getpid() system call. + +The "sig" argument can be one of the following values defined by signal.h: + +#define SIGHUP 1 /* Hangup detected on controlling terminal + or death of a controlling process */ +#define SIGINT 2 /* Interrupt from keyboard */ +#define SIGQUIT 3 /* Quit from keyboard */ +#define SIGILL 4 /* Illegal instruction */ +#define SIGTRAP 5 /* Trace/breakpoint trap */ +#define SIGIOT 6 /* IOT trap. A synonym for SIGABRT */ +#define SIGABRT SIGIOT /* Abort signal from abort */ +#define SIGUSR1 7 /* User's signal 1 */ +#define SIGUSR2 8 /* User's signal 2 */ +#define SIGKILL 9 /* Kill signal */ +#define SIGPIPE 10 /* Broken pipe: write to pipe with no reader */ +#define SIGALRM 11 /* Timer signal from alarm */ +#define SIGTERM 12 /* Termination signal */ +#define SIGURG 13 /* Urgent signal */ +#define SIGCONT 14 /* Continue process */ +#define SIGSTOP 15 /* Stop process */ + +/* this signals defined only for compatibility */ +#define SIGBUS 16 /* Bus error */ +#define SIGFPE 17 /* Floating point exception */ +#define SIGSEGV 18 /* Invalid memory reference */ +#define SIGSYS 19 /* Bad argument to routine */ +#define SIGTTIN 20 +#define SIGTOUT 21 + +When any process sends a signal to a sleeping process, its state will change to +P_READY. As the process is now eligible, it will be selected in due course by +the scheduler, at which time the signal is processed (its handler is called). +If the signal handler subsequently returns, normal execution resumes for the +process, just after the point where it went to sleep. + +; ----------------------------------------------------------------------------- + +int link (char *oldname, char *newname); + +Creates a new file in the directory structure, named "newname", which refers to +the same inode as the already existing file named "oldname". Note that both +aliases really refer to the same file, so writing or appending to the file, or +truncating it, will affect both files identically. + +Linking is achieved by making the new file refer to the same "inode" as the +original file, and increasing that inode's "link count" by one. Directory +entries consist of "name" and "inode". When files are deleted (unlinked), +inodes will not be destroyed until all of their aliases have been deleted. + +; ----------------------------------------------------------------------------- + +int symlink (char *oldname, char *newname); + +Similar to the link() function call, except that symlinks are easily identified +as such, whereas the file created by the link() system call cannot easily be +distinguished from the original. Symlinks are more manageable for this reason. + +Symlinks also have the property that they can traverse mount points and so they +are useful when aliasing files on some other media (for example a network or +removeable drive). This property is achieved because the symlink is just a +small file containing a short string which is appended to the path. For +example I could symlink "/usr/etc" to "../etc" and the symlink, when accessed, +would correctly find the "/usr/../etc" directory, even if the /usr directory +had been mounted from a completely different drive than the /etc directory. + +If the original file is deleted or moved somewhere temporarily, the symlink is +"broken" and thus can't be accessed. (ENOENT errors would result). However +this can be a valuable property, as symlinks can be archived and used again +later, and/or the original files could be temporarily deleted, and restored +again later. Symlinks only need to be valid at the time of opening a file. + +; ----------------------------------------------------------------------------- + +int mknod (char *name, mode_t mode, int dev); + +Creates a special device file. This would usually be placed in the "/dev" +subdirectory, although it can be placed anywhere. The file doesn't contain any +data, but its inode is marked as "special" by setting the "block special" or +"character special" bits in the "mode". The "mode" is the same 16-bit integer +which holds the access permissions for "user, group, other" as described for +the chmod() system call, but only the lower 12 bits are modifiable by chmod. +The upper 4 bits must be set when the file is created using the mknod() call. + +To make things easier, the following definitions are provided by sys/stat.h: + +#define S_IFMT 0170000 /* file type mask */ +#define S_IFLNK 0110000 /* symbolic link */ +#define S_IFREG 0100000 /* or just 000000, regular */ +#define S_IFBLK 0060000 /* block special */ +#define S_IFDIR 0040000 /* directory */ +#define S_IFCHR 0020000 /* character special */ +#define S_IFPIPE 0010000 /* pipe */ + +See "c:\uzi\include\sys\stat.h" for further handy macros, for example the +S_ISLNK macro returns true if some file's mode indicates a symbolic link. + +In addition to providing a "mode" parameter which has the "block special" or +"character special" bits set, the user also provides a device number in "major, +minor" format. The "major" device number indicates which device driver will +perform the work. The "minor" device number is passed in to this device driver +to do what it wants with. For example a hard disk device might provide "minor" +device numbers of 0 and 1 for two different hard disks attached to the system. +A TTY device driver might provide "minor" device numbers of 0 thru 3 for four +different serial ports attached to the system. So the creator of the device +special files is going to need to know something about the underlying driver! + +The following major and minor device number combinations have been allocated: + + /* minor open close read write ioctl */ + /*-----------------------------------------------------*/ + { 0, wd_open, ok, wd_read, wd_write, nogood }, /* 0 HD0 */ + { 0, fd_open, ok, fd_read, fd_write, nogood }, /* 1 floppy */ + { 1, wd_open, ok, wd_read, wd_write, nogood }, /* 2 HD1 */ + { 2, wd_open, ok, wd_read, wd_write, nogood }, /* 3 Swap */ + { 0, lpr_open, lpr_close, nogood, lpr_write, nogood }, /* 4 printer */ + { 1, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 5 tty */ + { 0, ok, ok, ok, null_write, nogood }, /* 6 null */ + { 0, ok, ok, mem_read, mem_write, nogood }, /* 7 mem */ + { 0, mt_open, mt_close, mt_read, mt_write, nogood }, /* 8 mt */ + { 2, tty_open, tty_close, tty_read, tty_write, tty_ioctl } /* 9 tty1 */ + /* Add more tty channels here if available, incrementing minor# */ + +See the file "c:\uzi\kernel\config.h" for the most up to date version of this. + +; ----------------------------------------------------------------------------- + +int mkfifo (char *name, mode_t mode); + +Creates a special "pipe" file. This can be placed anywhere in the directory +structure of the drive which is to hold the piped data. The file is like a +regular file, except it is always written by appending to the file, and is read +from the start. Blocks are freed from the start of the file as they are read. + +The file is marked as a "pipe" by setting the "pipe" bit in the file's "mode". +The "mode" is the same 16-bit integer which holds the access permissions for +"user, group, other" as described for the chmod() system call, but only the +lower 12 bits are modifiable by chmod. The upper 4 bits must be set when the +file is created using the mkfifo() call. You must be sure to set the S_IFPIPE +bit in the passed mode, and also any necessary access permissions for the pipe. + +If any process tries to write to a pipe which doesn't have any handles open to +read it, it will receive a signal which would normally kill the program. The +signal can be caught if you need to write to broken pipes for some reason. + +; ----------------------------------------------------------------------------- + +int mount (char *spec, char *dir, int rwflag); + +Mounts the filesystem found on a given device, onto a given mount point. The +device referred to by "spec" must be a special device file with the "block +special" bit set. The mount point referred to by "dir" must be an already­ +existing directory (usually empty). "rwflag" indicates whether the mounted +filesystem should be writeable. (If the filesystem is mounted read-only, not +even the superuser is allowed to make changes). + +The filesystem on the device must be an UZI filesystem. This is verified by +reading the superblock of the filesystem and checking for the correct "magic +number" in the header. If this is found, the root directory of the filesystem +is opened and remains open. This is saved in the "mounts" table so that any +further system calls such as open() can correctly traverse the mount point. + +; ----------------------------------------------------------------------------- + +int open (char *name, uint flag, ...); + +Searches for a file of the given name, and if found, opens it in the given +mode. Mode can be any of the read or write modes such as O_RDONLY or O_RDWR. + +If open() is successful, a file handle is returned. This opaque "token" is +used for further access to the file, eg. by read(), write() or close(). Each +process has its own file table, so handles are not unique across processes. + +To make things easier, the following definitions are provided by fcntl.h: + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +/* Flag values for open only */ +#define O_CREAT 0x0100 /* create and open file */ +#define O_TRUNC 0x0200 /* open with truncation */ +#define O_NEW 0x0400 /* create only if not exist */ +#define O_SYMLINK 0x0800 /* open symlink as file */ + +/* a file in append mode may be written to only at its end. */ +#define O_APPEND 0x2000 /* to end of file */ +#define O_EXCL 0x4000 /* exclusive open */ +#define O_BINARY 0x8000 /* not used in unix */ + +; ----------------------------------------------------------------------------- + +int pause (void); + +Pauses the current process until a signal is received (any signal). The +process must have installed a signal handler for the anticipated signal, +because the default behaviour would be to terminate the process on receipt. + +While the current process is paused, any other eligible processes will run. +When one of them sends a signal to the paused process, its state will change +from P_PAUSE to P_READY. As the process is now eligible, it will be selected +in due course by the scheduler, at which time the signal is processed (its +handler is called). If the signal handler returns, normal execution resumes. + +; ----------------------------------------------------------------------------- + +int pipe (int fildes[2]); + +Creates an unnamed pipe on the root filesystem. The pipe is a temporary file +which is not in any directory, similar to the result of creating a file using +creat(), using unlink() to delete it, then continuing to access the file. + +When temporary files are created like this, all is well, but as there is no +reference to the file anywhere in the directory structure, its inode and data +space will be freed immediately on closure. + +Separate file handles are returned for the "read" and "write" sides of the +pipe. Assuming the pipe can be created, fildes[0] is given a handle opened in +O_RDONLY mode, and fildes[1] is given a handle opened in O_WRONLY mode. + +If the operation fails, fildes[0] and fildes[1] are both set to -1, the return +value is -1 and errno says why the pipe could not be created. + +; ----------------------------------------------------------------------------- + +int read (int fd, void *buf, uint nbytes); + +Reads from the given file handle. The file handle must previously have been +opened with open() or creat(), or created using dup() or dup2(). The handle +can refer to a file, in which case bytes will be read from the current file +position, and the file position will be incremented. Or "fd" can refer to a +device, in which case the bytes are read from the associated device driver. + +Whether the handle refers to a file or a device, read() will read as much as +possible, to address "buf" onwards, up to the limit specified by "nbytes". The +return value from read() is the actual number of bytes read, or -1 if some kind +of catastrophic error occurred (eg. disk I/O error). EOF is not considered an +error, and simply results in less than the expected number of bytes being read. + +; ----------------------------------------------------------------------------- + +int sbrk (uint incr); + +Increases the top of the process's memory by the given amount. On entry to the +program, "brk" is set to the top of the loaded program image, and therefore +must be adjusted slightly higher if the program is going to use extra memory +for data. This is normally done at least once, by the 'C' startup code, to +inform the kernel of how much uninitialised data the program wishes to use. + +The kernel checks if the "brk" value is getting too close to the process's +stack pointer (ie. if there would not be enough stack space left to process a +system call or an interrupt). In this case the call fails and returns -1. + +The 'C' library also provides a malloc() and free() implementation, which is +based on the brk() and sbrk() system calls. Normally sbrk() is called from +within malloc() each time malloc() wishes to extend the size of the pool. This +might not be very often since the user might be requesting small blocks and +freeing them often. An appropriate increment is usally determined in advance. + +Or, sbrk() can be used as a direct replacement for malloc(), since it returns +the previous brk address (ie. the start of the extra portion just allocated). + +; ----------------------------------------------------------------------------- + +int seek (int fd, int offset, int whence); + +Sets the file position for the given file handle. Ordinary files and devices +can be seeked, but seek() will return an error if the file handle refers to a +pipe or a file opened in append mode. On failure, errno indicates why. + +The file position is set absolutely (SEEK_OSET/SEEK_BSET), or relative to the +current file position (SEEK_OCUR/SEEK_BCUR), or relative to the end of the file +(SEEK_OEND/SEEK_BEND). Negative offsets for relative seek are not implemented. + +The "whence" argument can be one of the following values from seek.h: + +#define SEEK_OSET 0 +#define SEEK_OCUR 1 +#define SEEK_OEND 2 +#define SEEK_BSET 3 +#define SEEK_BCUR 4 +#define SEEK_BEND 5 + +Since a file can be larger than the integer value represented in "offset", it's +necessary to set the file position in two steps. Firstly set the byte position +in the current block, using one of the SEEK_Oxxx calls. Then set the block +number using one of the SEEK_Bxxx calls. The resulting file position can be +inferred by recombining the return values from each function. When converting +block/offset to "long" or vice versa, use a hard coded block size of 512 bytes. + +; ----------------------------------------------------------------------------- + +off_t lseek (int fd, off_t offset, int whence); + +Not yet implemented by the kernel. Instead it's done as a library call, based +on the seek() function call which is implemented by the kernel. As we can only +pass 16-bit parameters into the kernel for the moment, and the return value can +only be 16-bit as well, it's quite convenient to provide an lseek() routine in +the 'C' library, which decodes the "off_t" value into sector and byte offsets. + +The "whence" argument can be one of the following values from seek.h: + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +; ----------------------------------------------------------------------------- + +int setgid (int gid); + +Sets the GID or "group ID" of the current process. This is a unique integer +referring to a line in the file "/etc/group" and is initialised at login time. + +Superuser permissions are required to make this call. Therefore the "login" +utility usually runs "setuid" so that you can temporarily become root to do it. + +; ----------------------------------------------------------------------------- + +int setuid (int uid); + +Sets the UID or "user ID" of the current process. This is a unique integer +referring to a line in the file "/etc/passwd" and is initialised at login time. + +Superuser permissions are required to make this call. Therefore the "login" +utility usually runs "setuid" so that you can temporarily become root to do it. + +; ----------------------------------------------------------------------------- + +int setprio (int pid, char prio); + +Sets the priority of the current process. This is an integer indicating how +many system "ticks" should be allocated to the process each time it runs. When +this number of "ticks" expires each time, some other process is allowed to run. + +; ----------------------------------------------------------------------------- + +sig_t signal (signal_t sig, sig_t func); + +Install a signal handler to catch a particular signal. Signals can be sent by +any process, by device drivers, or by the kernel in response to certain events. +The default behaviour on receipt of a signal is to kill the receiving process, +but if the process has "caught" the signal by calling signal() to register a +handler for the anticipated signal, the given signal handler executes instead. + +The "sig" argument can be one of the following values defined by signal.h: + +#define SIGHUP 1 /* Hangup detected on controlling terminal + or death of a controlling process */ +#define SIGINT 2 /* Interrupt from keyboard */ +#define SIGQUIT 3 /* Quit from keyboard */ +#define SIGILL 4 /* Illegal instruction */ +#define SIGTRAP 5 /* Trace/breakpoint trap */ +#define SIGIOT 6 /* IOT trap. A synonym for SIGABRT */ +#define SIGABRT SIGIOT /* Abort signal from abort */ +#define SIGUSR1 7 /* User's signal 1 */ +#define SIGUSR2 8 /* User's signal 2 */ +#define SIGKILL 9 /* Kill signal */ +#define SIGPIPE 10 /* Broken pipe: write to pipe with no reader */ +#define SIGALRM 11 /* Timer signal from alarm */ +#define SIGTERM 12 /* Termination signal */ +#define SIGURG 13 /* Urgent signal */ +#define SIGCONT 14 /* Continue process */ +#define SIGSTOP 15 /* Stop process */ + +/* this signals defined only for compatibility */ +#define SIGBUS 16 /* Bus error */ +#define SIGFPE 17 /* Floating point exception */ +#define SIGSEGV 18 /* Invalid memory reference */ +#define SIGSYS 19 /* Bad argument to routine */ +#define SIGTTIN 20 +#define SIGTOUT 21 + +The "func" argument is a function pointer, but the sig_t type is provided by +types.h for convenience. The definition is: typedef void (*sig_t) (signal_t); +which means that the signal handler will be told which signal it's handling, as +its first argument is a "signal_t", and the function does not return a value. + +In fact the signal handler doesn't need to return at all, it may exit using the +exit() call, or restore execution to an earlier saved state using the longjmp() +library routine. If the signal handler does return, then execution continues +in the process which recieved the signal. (If it was asleep, it will have been +woken at the time the signal was originally sent, so it now executes again). + +; ----------------------------------------------------------------------------- + +int stat (char *path, void *buf); + +Checks whether the file exists, and if so, returns information about it. Note +that the user does need to have read access to the file in order to make this +call. The user also needs execute permission on the directory containing it. + +Calling stat will update the file's last accessed time. It should therefore be +used with caution by directory listing or disk cataloguing programs. For most +purposes you would not want to corrupt the file's last-access time unless you +were about to access the file yourself. Use fstat() for a non-intrusive call. + +; ----------------------------------------------------------------------------- + +int stime (time_t *tvec); + +Not yet implemented. Sets the system real time clock. The buffer pointed to +by "tvec" contains the time and date. Superuser permission is required to set +the system real time clock. + +time_t is currently in the following format, defined by types.h: + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int sync (void); + +Synchronises the file system, possibly in preparation for a reboot or system +shutdown (or just to ensure that an important file's data is really flushed). + +The kernel writes any modified inodes to disk (for example, updating the length +of any open files to the correct value), updates the superblock (this ensures +the 'blocks free' and 'blocks used' counters are at their correct values), then +finally any unwritten disk buffers are written out to disk before returning. + +; ----------------------------------------------------------------------------- + +time_t time (time_t *tvec); + +Returns the system real time clock. The buffer pointed to by "tvec" receives +the time. No special permissions are required to do this. + +time_t is currently in the following format, defined by types.h: + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int times (struct tms *buf); + +Returns information about the running time of the current process and its +children. The information is returned in a structure containing various +fields. The fields of the structure are as follows, defined by types.h: + +/* User's structure for times() system call */ +struct tms { + time_t tms_utime; /* Elapsed ticks in user mode */ + time_t tms_stime; /* Elapsed ticks in system mode */ + time_t tms_cutime; /* Total childrens ticks (user mode) */ + time_t tms_cstime; /* Total childrens ticks (system mode) */ + time_t tms_etime; /* Elapsed real time */ +}; + +time_t is currently in the following format, defined by types.h: + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int utime (char *path, struct utimbuf *buf); + +Checks whether the file exists, and if so, returns information about it. Note +that the user doesn't need to have any access to the file in order to make this +call. The user only needs execute permission on the directory containing it. + +The structure of "buf" is defined in types.h and contains the following fields: + +/* User's structure for utime() system call */ +struct utimbuf { + time_t actime; /* last accessed time */ + time_t modtime; /* last modified time */ +}; + +time_t is currently in the following format, defined by types.h: + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int umask (int mask); + +Sets the default file creation permissions for the current process (this +setting will also be inherited by any child processes). + +The argument to umask() is specified in 'inverse', for example if some file was +to be created with octal permissions '755' you would call umask(022) followed +by creat(). Thus the argument to umask() tells the system which bits to turn +off, hence the name "mask". The usual value of 022 specifies that new files +should not be writeable by "group" and "other" users, but only by the owner. + +; ----------------------------------------------------------------------------- + +int umount (char *spec); + +Unmounts the filesystem found on a given device, from its mount point. Only +the device containing the filesystem needs to be specified. The device +referred to by "spec" must be a special device file with the "block special" +bit set. The filesystem must earlier have been mounted using the mount() +system call. It is not possible to unmount the root filesystem. + +The filesystem on the device must be an UZI filesystem. The call will fail if +any files on the device are still open. The root directory of the filesystem, +whose inode is obtained from the mounts table, is closed. All unwritten data, +including modified inodes and changes to the superblock, are written out. The +mounts table is updated to show that the filesystem is no longer mounted. + +; ----------------------------------------------------------------------------- + +int unlink (char *path); + +Searches for the given path. If the file is found, and the user has write +permission for the directory containing the file, the found entry is removed +from the directory structure. + +In the process the directory entry is inspected. Directory entries consist of +"name" and "inode". The associated inode is also inspected, and its "link +count" is decreased by one. The inode will also be destroyed, if its "link +count" has reached zero, meaning all aliases to the file have been unlinked. + +; ----------------------------------------------------------------------------- + +int wait (int *statloc); + +Waits for a child process to die (any child of the current process). If there +are no children, wait() returns an error ECHILD. If there are some children, +the current process goes to sleep having indicated it wants to be notified when +a child exits. Some other eligible program runs, and eventually, if a child +does exit, the sleeping process is woken up and wait() returns the child's PID. +At the buffer pointed to by statloc, the process receives the child's exitcode. + +; ----------------------------------------------------------------------------- + +int write (int fd, void *buf, uint nbytes); + +Writes to the given file handle. The file handle must previously have been +opened with open() or creat(), or created using dup() or dup2(). The handle +can refer to a file, in which case bytes will be written to the current file +position, and the file position will be incremented. Or "fd" can refer to a +device, in which case the bytes are written to the associated device driver. + +Whether the handle refers to a file or a device, write() will write as much as +possible, using data from address "buf" onwards, up to the limit specified by +"nbytes". The return value from write() is the actual number of bytes written, +or -1 if some kind of catastrophic error occurred (eg. disk I/O error). + +; ----------------------------------------------------------------------------- + +int reboot (char p1, char p2); + +Not yet implemented. This call would be passed two special values, p1 = 'm' +and p2 = 'e'. The parameters are checked to guard against accidental reboots. + +Only the superuser is allowed to reboot the system. The reboot() system call +would be used by a shutdown program, so that you could type "shutdown -r now". + +; ----------------------------------------------------------------------------- + +int systrace (int onoff); + +Enables or disables system call tracing. When system call tracing is active +for a process, the kernel will print diagnostic log information to the console, +so that you can see exactly which system calls a program is making, and which +ones were successful and which ones were not. This system call might be used +by a version of the "systrace" program, which turns on system tracing, executes +a command line given by the user, and then turns off tracing before exiting. + +; ----------------------------------------------------------------------------- + diff --git a/doc/syscalls.txt b/doc/syscalls.txt new file mode 100755 index 00000000..a2e407a4 --- /dev/null +++ b/doc/syscalls.txt @@ -0,0 +1,1106 @@ +UZI SYSTEM CALL INTERFACE SUMMARY + +; ----------------------------------------------------------------------------- + +CONTENTS + +int errno; +void _exit (int val); +int access (char *path, int mode); +int alarm (uint secs); +int brk (char *addr); +int chdir (char *dir); +int chroot (char *dir); +int chmod (char *path, mode_t mode); +int chown (char *path, int owner, int group); +int close (int uindex); +int creat (char *name, mode_t mode); +int dup (int oldd); +int dup2 (int oldd, int newd); +int execve (char *name, char *argv[], char *envp[]); +int fork (void); +int fstat (int fd, void *buf); +int getfsys (int dev, void *buf); +int getgid (void); +int getpid (void); +int getppid (void); +int getuid (void); +int geteuid (void); +int getegid (void); +int getprio (void); +int ioctl (int fd, int request, ...); +int kill (int pid, int sig); +int link (char *oldname, char *newname); +int symlink (char *oldname, char *newname); +int mknod (char *name, mode_t mode, int dev); +int mkfifo (char *name, mode_t mode); +int mount (char *spec, char *dir, int rwflag); +int open (char *name, uint flag, ...); +int pause (void); +int pipe (int fildes[2]); +int read (int fd, void *buf, uint nbytes); +int sbrk (uint incr); +int seek (int fd, int offset, int whence); +off_t lseek (int fd, off_t offset, int whence); +int setgid (int gid); +int setuid (int uid); +int setprio (int pid, char prio); +sig_t signal (signal_t sig, sig_t func); +int stat (char *path, void *buf); +int stime (time_t *tvec); +int sync (void); +time_t time (time_t *tvec); +int times (struct tms *buf); +int utime (char *path, struct utimbuf *buf); +int umask (int mask); +int umount (char *spec); +int unlink (char *path); +int wait (int *statloc); +int write (int fd, void *buf, uint nbytes); +int reboot (char p1, char p2); +int systrace (int onoff); + +; ----------------------------------------------------------------------------- + +int errno; + +If any system call fails, it returns -1 (this is why most of the calls below +are listed as having an 'int' return value). In this case the errno variable +will give the reason for the error. Possible error codes are as follows: + +# Start /usr/lib/liberror.txt + +1 Operation not permitted (EPERM) +2 No such file or directory (ENOENT) +3 No such process (ESRCH) +4 Interrupted system call (EINTR) +5 I/O error (EIO) +6 No such device or address (ENXIO) +7 Arg list too long (E2BIG) +8 Exec format error (ENOEXEC) +9 Bad file number (EBADF) +10 No child processes (ECHILD) +11 Try again (EAGAIN) +12 Out of memory (ENOMEM) +13 Permission denied (EACCES) +14 Bad address (EFAULT) +15 Block device required (ENOTBLK) +16 Device or resource busy (EBUSY) +17 File exists (EEXIST) +18 Cross-device link (EXDEV) +19 No such device (ENODEV) +20 Not a directory (ENOTDIR) +21 Is a directory (EISDIR) +22 Invalid argument (EINVAL) +23 File table overflow (ENFILE) +24 Too many open files (EMFILE) +25 Not a typewriter (ENOTTY) +26 Text file busy (ETXTBSY) +27 File too large (EFBIG) +28 No space left on device (ENOSPC) +29 Illegal seek (ESPIPE) +30 Read-only file system (EROFS) +31 Too many links (EMLINK) +32 Broken pipe (EPIPE) +33 Math argument out of domain of func (EDOM) +34 Math result not representable (ERANGE) +35 Resource deadlock would occur (EDEADLK) +36 File name too long (ENAMETOOLONG) +37 No record locks available (ENOLCK) +38 Function not implemented (EINVFNC) +39 Directory not empty (ENOTEMPTY) +40 Too many symbolic links encountered (ELOOP) +41 It's a shell script (ESHELL) + +# End /usr/lib/liberror.txt + +; ----------------------------------------------------------------------------- + +void _exit (int val); + +Returns control to the system, terminating the current process. Some other +eligible process will then run instead. The memory belonging to the current +process is released and all files are closed. The function call does not +return, hence the void return value (normally all system calls return 'int'). + +Please note that _exit does not perform any user exit processing, hence the +name '_exit' rather than 'exit'. The standard C library provides the functions +exit() and atexit() allowing any user hooks to execute before making the _exit +system call. For example, files opened by fopen() are flushed and closed at +exit, by a special cleanup function that gets registered during 'C' startup. + +; ----------------------------------------------------------------------------- + +int access (char *path, int mode); + +Tests whether the current user (or effective user) is allowed to access the +given file. If so, returns 0. If not, returns -1, and errno filled in. + +Note: The test is equivalent to opening the file with the specified mode, and +then closing it again without doing anything. Because the kernel uses this +sequence of actions to determine whether access is granted, any existing file +of the given name, will have its last-access time and date updated by the call. + +; ----------------------------------------------------------------------------- + +int alarm (uint secs); + +Requests that the current process receive an "alarm" signal after the given +number of seconds has expired. As there is only one "alarm" counter per +process, any previous active "alarm" request will be overridden by the call. + +; ----------------------------------------------------------------------------- + +int brk (char *addr); + +Sets the top of the process's memory to the given address. On entry to the +program, "brk" is set to the top of the loaded program image, and therefore +must be adjusted slightly higher if the program is going to use extra memory +for data. This is normally done at least once, by the 'C' startup code, to +inform the kernel of how much uninitialised data the program wishes to use. + +The kernel checks if the "brk" value is getting too close to the process's +stack pointer (ie. if there would not be enough stack space left to process a +system call or an interrupt). In this case the call fails and returns -1. + +The 'C' library also provides a malloc() and free() implementation, which is +based on the brk() and sbrk() system calls. Please see the sbrk() description. + +; ----------------------------------------------------------------------------- + +int chdir (char *dir); + +Sets the current process's directory to the given path. This is equivalent to +"opening" the directory (execute permission is required, and the file-time is +updated), and so it is also useful to prevent any other processes from trying +to remove the directory or dismount the drive which contains the directory. + +Of course, subsequent system calls such as open() or access() or even chdir() +will then use the selected directory as the starting point for relative path +specification, for example if you are in directory "/usr/lib" and you create +the file "foo.txt" this is the same as creating the file "/usr/lib/foo.txt". + +; ----------------------------------------------------------------------------- + +int chroot (char *dir); + +Sets the current process's root directory to the given path. This is referred +to as a "jail", because while the chroot is active, the current process cannot +access any files or directories higher than the given root directory. + +For example, after calling chroot("/usr"), if the user tries to create a file +"/lib/foo.txt" this will really create a file called "/usr/lib/foo.txt". This +can be a useful security measure for programs such as email daemons, etc. + +; ----------------------------------------------------------------------------- + +int chmod (char *path, mode_t mode); + +Allows file permissions to be altered. Mode is normally a 3-digit octal value, +with the digits representing "user, group, other" respectively. For example +644 would mean permissions of '6' for the user who owns the file, '4' for users +in the same group as the file, and '4' for everyone else. + +The octal digits can be any of the following: (1=Execute, 2=Write, 4=Read) + + EXECUTE WRITE READ + 0 No No No + 1 Yes No No + 2 No Yes No + 3 Yes Yes No + 4 No No Yes + 5 Yes No Yes + 6 No Yes Yes + 7 Yes Yes Yes + +In addition a fourth octal digit can be prepended, interpreted as follows: + + VTX (??) SETGID SETUID + 0 No No No + 1 Yes No No + 2 No Yes No + 3 Yes Yes No + 4 No No Yes + 5 Yes No Yes + 6 No Yes Yes + 7 Yes Yes Yes + +The SETGID and SETUID features are useful for allowing users to access certain +superuser functions but not others. In this case a file's owner would be set +to "root" and the SETUID bit would be set. The file is usually an executable. + +For example the "login" program runs as SETUID 0, meaning anyone who can run +"login" will temporarily become the superuser while this trusted program is +executed. It's up to the system administrator to make sure that the "login" +program can't do anything malicious, before granting it SETUID permissions. + +To make things easier, the following definitions are provided by sys/stat.h: + +#define S_UMASK 07777 /* bits modifiable by chmod */ + +#define S_ISUID 04000 /* set euid to file uid */ +#define S_ISGID 02000 /* set egid to file gid */ +#define S_ISVTX 01000 /* */ + +#define S_IREAD 0400 /* owner may read */ +#define S_IWRITE 0200 /* owner may write */ +#define S_IEXEC 0100 /* owner may execute */ + +#define S_IGREAD 0040 /* group may read */ +#define S_IGWRITE 0020 /* group may write */ +#define S_IGEXEC 0010 /* group may execute */ + +#define S_IOREAD 0004 /* other may read */ +#define S_IOWRITE 0002 /* other may write */ +#define S_IOEXEC 0001 /* other may execute */ + +See "c:\uzi\include\sys\stat.h" for further handy macros, for example the +S_IRWXU macro returns a mask which contains all of the "read, write, execute" +bits for "user" set. This is handy for isolating a particular set of bits. + +; ----------------------------------------------------------------------------- + +int chown (char *path, int owner, int group); + +Changes the owner and group of the given file. The owner and group are 16 bit +integer numbers which correspond to entries in "/etc/passwd" and "/etc/group" +respectively. The user "root" is normally 0 and often is in group 0 as well. + +Superuser permissions are required in order to make this call. In other words +it's not permitted for a user to create a file and then assign ownership to +anyone else. (Assigning ownership to "root" could cause a security problem). + +; ----------------------------------------------------------------------------- + +int close (int uindex); + +Closes the given file handle. The file handle must previously have been opened +with open() or creat(), or created using dup() or dup2(). If the caller is the +last process with a handle to this file, the kernel will also close the file. + +When the kernel really closes the file, the file's last-modification and/or +last-access times are updated. Any unwritten data is flushed, and the disk is +synchronised. The in-core inode table entry is marked as free for later use. + +; ----------------------------------------------------------------------------- + +int creat (char *name, mode_t mode); + +Creates a file of the given name, and opens it in the given mode. Normally +mode would be one of the write modes such as O_WRONLY or possibly O_RDWR. Any +existing file of the same name is deleted first, so the caller to creat() can +be assured of getting a zero-length file before beginning to write data. + +It's not possible to specify the access permissions for the file during this +call. Instead, the user must call the umask() function to set the default file +creation permissions, then call creat() as described here. The argument to +umask() is specified in 'inverse', for example if the file was to be created +with octal permissions '755' you would call umask(022) followed by creat(). + +If creat() is successful, a file handle is returned. This opaque "token" is +used for further access to the file, eg. by read(), write() or close(). Each +process has its own file table, so handles are not unique across processes. + +To make things easier, the following definitions are provided by fcntl.h: + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +/* Flag values for open only */ +#define O_CREAT 0x0100 /* create and open file */ +#define O_TRUNC 0x0200 /* open with truncation */ +#define O_NEW 0x0400 /* create only if not exist */ +#define O_SYMLINK 0x0800 /* open symlink as file */ + +/* a file in append mode may be written to only at its end. */ +#define O_APPEND 0x2000 /* to end of file */ +#define O_EXCL 0x4000 /* exclusive open */ +#define O_BINARY 0x8000 /* not used in unix */ + +; ----------------------------------------------------------------------------- + +int dup (int oldd); + +Duplicates the given file handle. The file handle must previously have been +opened with open() or creat(), or created using dup() or dup2(). Any free +location in the process's file table can be used to create the duplicate. + +So "oldd" is copied into a new spot in order to create the duplicate reference. +Both handles then refer to the same inode (each in-core inode has a reference +count indicating how many duplicated or inherited handles refer to the file). + +If dup() is successful, a file handle is returned. This opaque "token" is used +for further access to the file, eg. by read(), write() or close(). + +; ----------------------------------------------------------------------------- + +int dup2 (int oldd, int newd); + +Duplicates the given file handle. The file handle must previously have been +opened with open() or creat(), or created using dup() or dup2(). The caller +specifies a particular location in the process's file table, using "newd". + +If "newd" was previously open, it is closed using the close() system call. +Then "oldd" is copied into "newd" in order to create the duplicate reference. +Both handles then refer to the same inode (each in-core inode has a reference +count indicating how many duplicated or inherited handles refer to the file). + +If dup2() is successful, a file handle is returned. This opaque "token" is +used for further access to the file, eg. by read(), write() or close(). Of +course, this return value is always equal to the value of "newd" passed in. + +; ----------------------------------------------------------------------------- + +int execve (char *name, char *argv[], char *envp[]); + +Loads a program from the disk and executes it. The current user must have +execute permission for the file specified by "name". Information is passed to +the executed program using the argv[] and envp[] arrays. The execve() call +does not return, because the program is loaded into the same memory as the +caller of execve(). Instead, the executed program will execute forever, or at +least until it calls execve() again or exits with the _exit system call. + +The kernel allocates some temporary storage in order to save your argv[] and +envp[] arrays while the new program is being loaded. They are compacted into +kernel memory, and then copied back out into user memory after loading the +program. The 'C' startup saves the envp[] pointer for use by the getenv() and +setenv() library calls, and then passes the argv[] and argc into your main(). + +Note that execve() can return in one situation: If the file can't be executed. +In this case execve() returns -1 and errno gives the reason why. + +; ----------------------------------------------------------------------------- + +int fork (void); + +Creates a new process, by duplicating the current process. This is the only +way to create a new process under Unix. The created process will return from +fork() a value of 0, which tells the subsequent code that it should behave as +the child of the fork() rather than the parent. Often it would then execve(). + +The originally existing process will return from fork() a value indicating how +to find the new process just created. So subsequent code knows that it should +behave as the parent of the fork() rather than the child. Using the PID value +returned, the process which forked is able to keep track of the progress of the +child, and obtain an exitcode when the child exits. See the wait() call. + +All memory belonging to the process is copied. Of course there must be enough +free memory for the new process's code and data (32 kbytes). It's also quite a +lengthy operation, since the entire 32 kbytes must be copied byte for byte. + +All file handles belonging to the process are duplicated. This doesn't require +any files to be opened in reality, instead the in-core inodes simply have their +reference count increased by one, to show that someone has inherited a handle. + +Of course, if there is not enough memory or there is no free process table +entry available, fork() will fail and return -1. Errno gives the reason why. + +; ----------------------------------------------------------------------------- + +int fstat (int fd, void *buf); + +Checks whether the file exists, and if so, returns information about it. Note +that the user doesn't need to have any access to the file in order to make this +call. The user only needs execute permission on the directory containing it. + +Calling fstat does not update the file's last accessed time. It's completely +benign and therefore would be used by a directory listing program (for example) +in preference to the stat() system call. (Both return the same information). + +The structure of "buf" is defined in types.h and contains the following fields: + +/* data structure for stat() */ +struct stat { /* USER! Really only used by users */ + uint st_dev; /* device number */ + uint st_ino; /* inode number */ + mode_t st_mode; /* file mode */ + uint st_nlink; /* number of links */ + uint st_uid; /* owner id */ + uint st_gid; /* owner group */ + uint st_rdev; /* */ + blkoff_t st_size; /* Nick changed off_t to blkoff_t file size */ + time_t st_atime; /* last access time */ + time_t st_mtime; /* last modification time */ + time_t st_ctime; /* file creation time */ +}; + +The relevant types "mode_t", "blkoff_t" and "time_t" are defined by types.h: + +typedef unsigned int mode_t; + +typedef struct blkoff_t { + uint o_blkno; /* Block number */ + int o_offset; /* Offset within block 0-511 */ +} blkoff_t; + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int getfsys (int dev, void *buf); + +Returns information about the filesystem mounted on the given device. This is +a copy of the superblock for the filesystem, and thus can be used by a utility +such as "df" to show information about the free space on the filesystem. + +; ----------------------------------------------------------------------------- + +int getgid (void); + +Returns the GID or "group ID" of the current process. This is a unique integer +referring to a line in the file "/etc/group" and is initialised at login time. + +; ----------------------------------------------------------------------------- + +int getpid (void); + +Returns the PID or "process ID" of the current process. This is a unique +integer generated when a process forks and is allocated a process table entry. + +; ----------------------------------------------------------------------------- + +int getppid (void); + +Returns the PID or "process ID" of the parent process. This is a unique +integer generated at the time the parent process was created. The parent +process is the process which forked to create this (the current) process. + +; ----------------------------------------------------------------------------- + +int getuid (void); + +Returns the UID or "user ID" of the current process. This is a unique integer +referring to a line in the file "/etc/passwd" and is initialised at login time. + +; ----------------------------------------------------------------------------- + +int geteuid (void); + +Returns the effective UID or "user ID" of the current process. This would +normally be equal to the value returned by getuid(), except that the user may +have executed a binary program with the SETUID bit set. If so, the effective +user ID will be the user ID of the owner of that program. For example, when +executing the "login" utility, the effective user ID is always "root". + +; ----------------------------------------------------------------------------- + +int getegid (void); + +Returns the effective GID or "group ID" of the current process. This would +normally be equal to the value returned by getgid(), except that the user may +have executed a binary program with the SETGID bit set. If so, the effective +user ID will be the user ID of the group of that program. For example, when +executing email daemons, the effective group ID is often "mail". + +; ----------------------------------------------------------------------------- + +int getprio (void); + +Returns the priority of the current process. This is an integer indicating how +many system "ticks" should be allocated to the process each time it runs. When +this number of "ticks" expires each time, some other process is allowed to run. + +; ----------------------------------------------------------------------------- + +int ioctl (int fd, int request, ...); + +Allows arbitrary control of devices. The handle "fd" must have been opened +with the open() system call or created with dup() or dup2(). Only special +files referring to devices can be manipulated with the ioctl() system call. + +The caller must know what kind of device the handle refers to, for example a +TTY device will respond to certain kinds of ioctl() requests, whereas a block +device will respond to different ones. Unix doesn't inspect the "request" or +subsequent parameters given. These are simply passed on to the device driver. + +; ----------------------------------------------------------------------------- + +int kill (int pid, int sig); + +Sends a signal to a process. If the process does not catch the signal, it will +be killed, hence the name "kill". The kill() system call can also be used to +communicate with a child in a more benign way. The "pid" is often obtained as +the return value from fork(), or else by using the getpid() system call. + +The "sig" argument can be one of the following values defined by signal.h: + +#define SIGHUP 1 /* Hangup detected on controlling terminal + or death of a controlling process */ +#define SIGINT 2 /* Interrupt from keyboard */ +#define SIGQUIT 3 /* Quit from keyboard */ +#define SIGILL 4 /* Illegal instruction */ +#define SIGTRAP 5 /* Trace/breakpoint trap */ +#define SIGIOT 6 /* IOT trap. A synonym for SIGABRT */ +#define SIGABRT SIGIOT /* Abort signal from abort */ +#define SIGUSR1 7 /* User's signal 1 */ +#define SIGUSR2 8 /* User's signal 2 */ +#define SIGKILL 9 /* Kill signal */ +#define SIGPIPE 10 /* Broken pipe: write to pipe with no reader */ +#define SIGALRM 11 /* Timer signal from alarm */ +#define SIGTERM 12 /* Termination signal */ +#define SIGURG 13 /* Urgent signal */ +#define SIGCONT 14 /* Continue process */ +#define SIGSTOP 15 /* Stop process */ + +/* this signals defined only for compatibility */ +#define SIGBUS 16 /* Bus error */ +#define SIGFPE 17 /* Floating point exception */ +#define SIGSEGV 18 /* Invalid memory reference */ +#define SIGSYS 19 /* Bad argument to routine */ +#define SIGTTIN 20 +#define SIGTOUT 21 + +When any process sends a signal to a sleeping process, its state will change to +P_READY. As the process is now eligible, it will be selected in due course by +the scheduler, at which time the signal is processed (its handler is called). +If the signal handler subsequently returns, normal execution resumes for the +process, just after the point where it went to sleep. + +; ----------------------------------------------------------------------------- + +int link (char *oldname, char *newname); + +Creates a new file in the directory structure, named "newname", which refers to +the same inode as the already existing file named "oldname". Note that both +aliases really refer to the same file, so writing or appending to the file, or +truncating it, will affect both files identically. + +Linking is achieved by making the new file refer to the same "inode" as the +original file, and increasing that inode's "link count" by one. Directory +entries consist of "name" and "inode". When files are deleted (unlinked), +inodes will not be destroyed until all of their aliases have been deleted. + +; ----------------------------------------------------------------------------- + +int symlink (char *oldname, char *newname); + +Similar to the link() function call, except that symlinks are easily identified +as such, whereas the file created by the link() system call cannot easily be +distinguished from the original. Symlinks are more manageable for this reason. + +Symlinks also have the property that they can traverse mount points and so they +are useful when aliasing files on some other media (for example a network or +removeable drive). This property is achieved because the symlink is just a +small file containing a short string which is appended to the path. For +example I could symlink "/usr/etc" to "../etc" and the symlink, when accessed, +would correctly find the "/usr/../etc" directory, even if the /usr directory +had been mounted from a completely different drive than the /etc directory. + +If the original file is deleted or moved somewhere temporarily, the symlink is +"broken" and thus can't be accessed. (ENOENT errors would result). However +this can be a valuable property, as symlinks can be archived and used again +later, and/or the original files could be temporarily deleted, and restored +again later. Symlinks only need to be valid at the time of opening a file. + +; ----------------------------------------------------------------------------- + +int mknod (char *name, mode_t mode, int dev); + +Creates a special device file. This would usually be placed in the "/dev" +subdirectory, although it can be placed anywhere. The file doesn't contain any +data, but its inode is marked as "special" by setting the "block special" or +"character special" bits in the "mode". The "mode" is the same 16-bit integer +which holds the access permissions for "user, group, other" as described for +the chmod() system call, but only the lower 12 bits are modifiable by chmod. +The upper 4 bits must be set when the file is created using the mknod() call. + +To make things easier, the following definitions are provided by sys/stat.h: + +#define S_IFMT 0170000 /* file type mask */ +#define S_IFLNK 0110000 /* symbolic link */ +#define S_IFREG 0100000 /* or just 000000, regular */ +#define S_IFBLK 0060000 /* block special */ +#define S_IFDIR 0040000 /* directory */ +#define S_IFCHR 0020000 /* character special */ +#define S_IFPIPE 0010000 /* pipe */ + +See "c:\uzi\include\sys\stat.h" for further handy macros, for example the +S_ISLNK macro returns true if some file's mode indicates a symbolic link. + +In addition to providing a "mode" parameter which has the "block special" or +"character special" bits set, the user also provides a device number in "major, +minor" format. The "major" device number indicates which device driver will +perform the work. The "minor" device number is passed in to this device driver +to do what it wants with. For example a hard disk device might provide "minor" +device numbers of 0 and 1 for two different hard disks attached to the system. +A TTY device driver might provide "minor" device numbers of 0 thru 3 for four +different serial ports attached to the system. So the creator of the device +special files is going to need to know something about the underlying driver! + +The following major and minor device number combinations have been allocated: + + /* minor open close read write ioctl */ + /*-----------------------------------------------------*/ + { 0, wd_open, ok, wd_read, wd_write, nogood }, /* 0 HD0 */ + { 0, fd_open, ok, fd_read, fd_write, nogood }, /* 1 floppy */ + { 1, wd_open, ok, wd_read, wd_write, nogood }, /* 2 HD1 */ + { 2, wd_open, ok, wd_read, wd_write, nogood }, /* 3 Swap */ + { 0, lpr_open, lpr_close, nogood, lpr_write, nogood }, /* 4 printer */ + { 1, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 5 tty */ + { 0, ok, ok, ok, null_write, nogood }, /* 6 null */ + { 0, ok, ok, mem_read, mem_write, nogood }, /* 7 mem */ + { 0, mt_open, mt_close, mt_read, mt_write, nogood }, /* 8 mt */ + { 2, tty_open, tty_close, tty_read, tty_write, tty_ioctl } /* 9 tty1 */ + /* Add more tty channels here if available, incrementing minor# */ + +See the file "c:\uzi\kernel\config.h" for the most up to date version of this. + +; ----------------------------------------------------------------------------- + +int mkfifo (char *name, mode_t mode); + +Creates a special "pipe" file. This can be placed anywhere in the directory +structure of the drive which is to hold the piped data. The file is like a +regular file, except it is always written by appending to the file, and is read +from the start. Blocks are freed from the start of the file as they are read. + +The file is marked as a "pipe" by setting the "pipe" bit in the file's "mode". +The "mode" is the same 16-bit integer which holds the access permissions for +"user, group, other" as described for the chmod() system call, but only the +lower 12 bits are modifiable by chmod. The upper 4 bits must be set when the +file is created using the mkfifo() call. You must be sure to set the S_IFPIPE +bit in the passed mode, and also any necessary access permissions for the pipe. + +If any process tries to write to a pipe which doesn't have any handles open to +read it, it will receive a signal which would normally kill the program. The +signal can be caught if you need to write to broken pipes for some reason. + +; ----------------------------------------------------------------------------- + +int mount (char *spec, char *dir, int rwflag); + +Mounts the filesystem found on a given device, onto a given mount point. The +device referred to by "spec" must be a special device file with the "block +special" bit set. The mount point referred to by "dir" must be an already +existing directory (usually empty). "rwflag" indicates whether the mounted +filesystem should be writeable. (If the filesystem is mounted read-only, not +even the superuser is allowed to make changes). + +The filesystem on the device must be an UZI filesystem. This is verified by +reading the superblock of the filesystem and checking for the correct "magic +number" in the header. If this is found, the root directory of the filesystem +is opened and remains open. This is saved in the "mounts" table so that any +further system calls such as open() can correctly traverse the mount point. + +; ----------------------------------------------------------------------------- + +int open (char *name, uint flag, ...); + +Searches for a file of the given name, and if found, opens it in the given +mode. Mode can be any of the read or write modes such as O_RDONLY or O_RDWR. + +If open() is successful, a file handle is returned. This opaque "token" is +used for further access to the file, eg. by read(), write() or close(). Each +process has its own file table, so handles are not unique across processes. + +To make things easier, the following definitions are provided by fcntl.h: + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +/* Flag values for open only */ +#define O_CREAT 0x0100 /* create and open file */ +#define O_TRUNC 0x0200 /* open with truncation */ +#define O_NEW 0x0400 /* create only if not exist */ +#define O_SYMLINK 0x0800 /* open symlink as file */ + +/* a file in append mode may be written to only at its end. */ +#define O_APPEND 0x2000 /* to end of file */ +#define O_EXCL 0x4000 /* exclusive open */ +#define O_BINARY 0x8000 /* not used in unix */ + +; ----------------------------------------------------------------------------- + +int pause (void); + +Pauses the current process until a signal is received (any signal). The +process must have installed a signal handler for the anticipated signal, +because the default behaviour would be to terminate the process on receipt. + +While the current process is paused, any other eligible processes will run. +When one of them sends a signal to the paused process, its state will change +from P_PAUSE to P_READY. As the process is now eligible, it will be selected +in due course by the scheduler, at which time the signal is processed (its +handler is called). If the signal handler returns, normal execution resumes. + +; ----------------------------------------------------------------------------- + +int pipe (int fildes[2]); + +Creates an unnamed pipe on the root filesystem. The pipe is a temporary file +which is not in any directory, similar to the result of creating a file using +creat(), using unlink() to delete it, then continuing to access the file. + +When temporary files are created like this, all is well, but as there is no +reference to the file anywhere in the directory structure, its inode and data +space will be freed immediately on closure. + +Separate file handles are returned for the "read" and "write" sides of the +pipe. Assuming the pipe can be created, fildes[0] is given a handle opened in +O_RDONLY mode, and fildes[1] is given a handle opened in O_WRONLY mode. + +If the operation fails, fildes[0] and fildes[1] are both set to -1, the return +value is -1 and errno says why the pipe could not be created. + +; ----------------------------------------------------------------------------- + +int read (int fd, void *buf, uint nbytes); + +Reads from the given file handle. The file handle must previously have been +opened with open() or creat(), or created using dup() or dup2(). The handle +can refer to a file, in which case bytes will be read from the current file +position, and the file position will be incremented. Or "fd" can refer to a +device, in which case the bytes are read from the associated device driver. + +Whether the handle refers to a file or a device, read() will read as much as +possible, to address "buf" onwards, up to the limit specified by "nbytes". The +return value from read() is the actual number of bytes read, or -1 if some kind +of catastrophic error occurred (eg. disk I/O error). EOF is not considered an +error, and simply results in less than the expected number of bytes being read. + +; ----------------------------------------------------------------------------- + +int sbrk (uint incr); + +Increases the top of the process's memory by the given amount. On entry to the +program, "brk" is set to the top of the loaded program image, and therefore +must be adjusted slightly higher if the program is going to use extra memory +for data. This is normally done at least once, by the 'C' startup code, to +inform the kernel of how much uninitialised data the program wishes to use. + +The kernel checks if the "brk" value is getting too close to the process's +stack pointer (ie. if there would not be enough stack space left to process a +system call or an interrupt). In this case the call fails and returns -1. + +The 'C' library also provides a malloc() and free() implementation, which is +based on the brk() and sbrk() system calls. Normally sbrk() is called from +within malloc() each time malloc() wishes to extend the size of the pool. This +might not be very often since the user might be requesting small blocks and +freeing them often. An appropriate increment is usally determined in advance. + +Or, sbrk() can be used as a direct replacement for malloc(), since it returns +the previous brk address (ie. the start of the extra portion just allocated). + +; ----------------------------------------------------------------------------- + +int seek (int fd, int offset, int whence); + +Sets the file position for the given file handle. Ordinary files and devices +can be seeked, but seek() will return an error if the file handle refers to a +pipe or a file opened in append mode. On failure, errno indicates why. + +The file position is set absolutely (SEEK_OSET/SEEK_BSET), or relative to the +current file position (SEEK_OCUR/SEEK_BCUR), or relative to the end of the file +(SEEK_OEND/SEEK_BEND). Negative offsets for relative seek are not implemented. + +The "whence" argument can be one of the following values from seek.h: + +#define SEEK_OSET 0 +#define SEEK_OCUR 1 +#define SEEK_OEND 2 +#define SEEK_BSET 3 +#define SEEK_BCUR 4 +#define SEEK_BEND 5 + +Since a file can be larger than the integer value represented in "offset", it's +necessary to set the file position in two steps. Firstly set the byte position +in the current block, using one of the SEEK_Oxxx calls. Then set the block +number using one of the SEEK_Bxxx calls. The resulting file position can be +inferred by recombining the return values from each function. When converting +block/offset to "long" or vice versa, use a hard coded block size of 512 bytes. + +; ----------------------------------------------------------------------------- + +off_t lseek (int fd, off_t offset, int whence); + +Not yet implemented by the kernel. Instead it's done as a library call, based +on the seek() function call which is implemented by the kernel. As we can only +pass 16-bit parameters into the kernel for the moment, and the return value can +only be 16-bit as well, it's quite convenient to provide an lseek() routine in +the 'C' library, which decodes the "off_t" value into sector and byte offsets. + +The "whence" argument can be one of the following values from seek.h: + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +; ----------------------------------------------------------------------------- + +int setgid (int gid); + +Sets the GID or "group ID" of the current process. This is a unique integer +referring to a line in the file "/etc/group" and is initialised at login time. + +Superuser permissions are required to make this call. Therefore the "login" +utility usually runs "setuid" so that you can temporarily become root to do it. + +; ----------------------------------------------------------------------------- + +int setuid (int uid); + +Sets the UID or "user ID" of the current process. This is a unique integer +referring to a line in the file "/etc/passwd" and is initialised at login time. + +Superuser permissions are required to make this call. Therefore the "login" +utility usually runs "setuid" so that you can temporarily become root to do it. + +; ----------------------------------------------------------------------------- + +int setprio (int pid, char prio); + +Sets the priority of the current process. This is an integer indicating how +many system "ticks" should be allocated to the process each time it runs. When +this number of "ticks" expires each time, some other process is allowed to run. + +; ----------------------------------------------------------------------------- + +sig_t signal (signal_t sig, sig_t func); + +Install a signal handler to catch a particular signal. Signals can be sent by +any process, by device drivers, or by the kernel in response to certain events. +The default behaviour on receipt of a signal is to kill the receiving process, +but if the process has "caught" the signal by calling signal() to register a +handler for the anticipated signal, the given signal handler executes instead. + +The "sig" argument can be one of the following values defined by signal.h: + +#define SIGHUP 1 /* Hangup detected on controlling terminal + or death of a controlling process */ +#define SIGINT 2 /* Interrupt from keyboard */ +#define SIGQUIT 3 /* Quit from keyboard */ +#define SIGILL 4 /* Illegal instruction */ +#define SIGTRAP 5 /* Trace/breakpoint trap */ +#define SIGIOT 6 /* IOT trap. A synonym for SIGABRT */ +#define SIGABRT SIGIOT /* Abort signal from abort */ +#define SIGUSR1 7 /* User's signal 1 */ +#define SIGUSR2 8 /* User's signal 2 */ +#define SIGKILL 9 /* Kill signal */ +#define SIGPIPE 10 /* Broken pipe: write to pipe with no reader */ +#define SIGALRM 11 /* Timer signal from alarm */ +#define SIGTERM 12 /* Termination signal */ +#define SIGURG 13 /* Urgent signal */ +#define SIGCONT 14 /* Continue process */ +#define SIGSTOP 15 /* Stop process */ + +/* this signals defined only for compatibility */ +#define SIGBUS 16 /* Bus error */ +#define SIGFPE 17 /* Floating point exception */ +#define SIGSEGV 18 /* Invalid memory reference */ +#define SIGSYS 19 /* Bad argument to routine */ +#define SIGTTIN 20 +#define SIGTOUT 21 + +The "func" argument is a function pointer, but the sig_t type is provided by +types.h for convenience. The definition is: typedef void (*sig_t) (signal_t); +which means that the signal handler will be told which signal it's handling, as +its first argument is a "signal_t", and the function does not return a value. + +In fact the signal handler doesn't need to return at all, it may exit using the +exit() call, or restore execution to an earlier saved state using the longjmp() +library routine. If the signal handler does return, then execution continues +in the process which recieved the signal. (If it was asleep, it will have been +woken at the time the signal was originally sent, so it now executes again). + +; ----------------------------------------------------------------------------- + +int stat (char *path, void *buf); + +Checks whether the file exists, and if so, returns information about it. Note +that the user does need to have read access to the file in order to make this +call. The user also needs execute permission on the directory containing it. + +Calling stat will update the file's last accessed time. It should therefore be +used with caution by directory listing or disk cataloguing programs. For most +purposes you would not want to corrupt the file's last-access time unless you +were about to access the file yourself. Use fstat() for a non-intrusive call. + +; ----------------------------------------------------------------------------- + +int stime (time_t *tvec); + +Not yet implemented. Sets the system real time clock. The buffer pointed to +by "tvec" contains the time and date. Superuser permission is required to set +the system real time clock. + +time_t is currently in the following format, defined by types.h: + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int sync (void); + +Synchronises the file system, possibly in preparation for a reboot or system +shutdown (or just to ensure that an important file's data is really flushed). + +The kernel writes any modified inodes to disk (for example, updating the length +of any open files to the correct value), updates the superblock (this ensures +the 'blocks free' and 'blocks used' counters are at their correct values), then +finally any unwritten disk buffers are written out to disk before returning. + +; ----------------------------------------------------------------------------- + +time_t time (time_t *tvec); + +Returns the system real time clock. The buffer pointed to by "tvec" receives +the time. No special permissions are required to do this. + +time_t is currently in the following format, defined by types.h: + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int times (struct tms *buf); + +Returns information about the running time of the current process and its +children. The information is returned in a structure containing various +fields. The fields of the structure are as follows, defined by types.h: + +/* User's structure for times() system call */ +struct tms { + time_t tms_utime; /* Elapsed ticks in user mode */ + time_t tms_stime; /* Elapsed ticks in system mode */ + time_t tms_cutime; /* Total childrens ticks (user mode) */ + time_t tms_cstime; /* Total childrens ticks (system mode) */ + time_t tms_etime; /* Elapsed real time */ +}; + +time_t is currently in the following format, defined by types.h: + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int utime (char *path, struct utimbuf *buf); + +Checks whether the file exists, and if so, returns information about it. Note +that the user doesn't need to have any access to the file in order to make this +call. The user only needs execute permission on the directory containing it. + +The structure of "buf" is defined in types.h and contains the following fields: + +/* User's structure for utime() system call */ +struct utimbuf { + time_t actime; /* last accessed time */ + time_t modtime; /* last modified time */ +}; + +time_t is currently in the following format, defined by types.h: + +/* file's timestamp structure (non UNIX-standard) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +; ----------------------------------------------------------------------------- + +int umask (int mask); + +Sets the default file creation permissions for the current process (this +setting will also be inherited by any child processes). + +The argument to umask() is specified in 'inverse', for example if some file was +to be created with octal permissions '755' you would call umask(022) followed +by creat(). Thus the argument to umask() tells the system which bits to turn +off, hence the name "mask". The usual value of 022 specifies that new files +should not be writeable by "group" and "other" users, but only by the owner. + +; ----------------------------------------------------------------------------- + +int umount (char *spec); + +Unmounts the filesystem found on a given device, from its mount point. Only +the device containing the filesystem needs to be specified. The device +referred to by "spec" must be a special device file with the "block special" +bit set. The filesystem must earlier have been mounted using the mount() +system call. It is not possible to unmount the root filesystem. + +The filesystem on the device must be an UZI filesystem. The call will fail if +any files on the device are still open. The root directory of the filesystem, +whose inode is obtained from the mounts table, is closed. All unwritten data, +including modified inodes and changes to the superblock, are written out. The +mounts table is updated to show that the filesystem is no longer mounted. + +; ----------------------------------------------------------------------------- + +int unlink (char *path); + +Searches for the given path. If the file is found, and the user has write +permission for the directory containing the file, the found entry is removed +from the directory structure. + +In the process the directory entry is inspected. Directory entries consist of +"name" and "inode". The associated inode is also inspected, and its "link +count" is decreased by one. The inode will also be destroyed, if its "link +count" has reached zero, meaning all aliases to the file have been unlinked. + +; ----------------------------------------------------------------------------- + +int wait (int *statloc); + +Waits for a child process to die (any child of the current process). If there +are no children, wait() returns an error ECHILD. If there are some children, +the current process goes to sleep having indicated it wants to be notified when +a child exits. Some other eligible program runs, and eventually, if a child +does exit, the sleeping process is woken up and wait() returns the child's PID. +At the buffer pointed to by statloc, the process receives the child's exitcode. + +; ----------------------------------------------------------------------------- + +int write (int fd, void *buf, uint nbytes); + +Writes to the given file handle. The file handle must previously have been +opened with open() or creat(), or created using dup() or dup2(). The handle +can refer to a file, in which case bytes will be written to the current file +position, and the file position will be incremented. Or "fd" can refer to a +device, in which case the bytes are written to the associated device driver. + +Whether the handle refers to a file or a device, write() will write as much as +possible, using data from address "buf" onwards, up to the limit specified by +"nbytes". The return value from write() is the actual number of bytes written, +or -1 if some kind of catastrophic error occurred (eg. disk I/O error). + +; ----------------------------------------------------------------------------- + +int reboot (char p1, char p2); + +Not yet implemented. This call would be passed two special values, p1 = 'm' +and p2 = 'e'. The parameters are checked to guard against accidental reboots. + +Only the superuser is allowed to reboot the system. The reboot() system call +would be used by a shutdown program, so that you could type "shutdown -r now". + +; ----------------------------------------------------------------------------- + +int systrace (int onoff); + +Enables or disables system call tracing. When system call tracing is active +for a process, the kernel will print diagnostic log information to the console, +so that you can see exactly which system calls a program is making, and which +ones were successful and which ones were not. This system call might be used +by a version of the "systrace" program, which turns on system tracing, executes +a command line given by the user, and then turns off tracing before exiting. + +; ----------------------------------------------------------------------------- + diff --git a/doc/uzi-lic.txt b/doc/uzi-lic.txt new file mode 100755 index 00000000..b528e99a --- /dev/null +++ b/doc/uzi-lic.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/doc/uzi-summ.txt b/doc/uzi-summ.txt new file mode 100755 index 00000000..8343440b --- /dev/null +++ b/doc/uzi-summ.txt @@ -0,0 +1,199 @@ + UZI: UNIX Z-80 IMPLEMENTATION + + Written by Douglas Braun + + +Introduction: + +UZI is an implementation of the Unix kernel written for a Z-80 based +computer. It implements almost all of the functionality of the +7th Edition Unix kernel. UZI was written to run on one specific +collection of custom-built hardware, but since it can easily have device +drivers added to it, and it does not use any memory management hardware, +it should be possible to port it to numerous computers that currently use +the CP/M operating system. The source code is written mostly in C, +and was compiled with The Code Works' Q/C compiler. UZI's code was +written from scratch, and contains no AT&T code, so it is not subject +to any of AT&T's copyright or licensing restrictions. Numerous 7th +Edition programs have been ported to UZI with little or no difficulty, +including the complete Bourne shell, ed, sed, dc, cpp, etc. + + +How it works: + +Since there is no standard memory management hardware on 8080-family +computers, UZI uses "total swapping" to achieve multiprocessing. +This has two implications: First, UZI requires a reasonably fast +hard disk. Second, there is no point in running a different process +while a process is waiting for disk I/O. This simplifies the design +of the block device drivers, since they do not have to be interrupt-based. + +UZI itself occupies the upper 32K of memory, and the currently running +process occupies the lower 32K. Since UZI currently barely fits in 32K, +a full 64K of RAM is necessary. + +UZI does need some additional hardware support. First, there must be +some sort of clock or timer that can provide a periodic interrupt. +Also, the current implementation uses an additional real-time clock +to get the time for file timestamps, etc. The current TTY driver assumes +an interrupt-driven keyboard, which should exist on most systems. +The distribution contains code for hard and floppy disk drivers, but +since these were written for custom hardware, they are provided only +as templates to write new ones. + + +How UZI is different than real Unix: + +UZI implements almost all of the 7th Edition functionality. +All file I/O, directories, mountable file systems, user and group IDs, +pipes, and applicable device I/O are supported. Process control +(fork(), execve(), signal(), kill(), pause(), alarm(), and wait()) are fully +supported. The number of processes is limited only by the swap space +available. As mentioned above, UZI implements Unix well enough to +run the Bourne shell in its full functionality. The only changes made +to the shell's source code were to satisfy the limitations of the C compiler. + +Here is a (possibly incomplete) list of missing features and limitations: + + The debugger- and profiler-related system calls do not exist. + + The old 6th edition seek() was implemented, instead of lseek(). + + The supplied TTY driver is bare-bones. It supports only one port, + and most IOCTLs are not supported. + + Inode numbers are only 16-bit, so filesystems are 32 Meg or less. + + File dates are not in the standard format. Instead they look like + those used by MS-DOS. + + The 4.2BSD execve() was implemented. Additional flavors of exec() + are supported by the library. + + The format of the device driver switch table is unlike that of + the 7th Edition. + + The necessary semaphores and locking mechanisms to implement + reentrant disk I/O are not there. This would make it harder to + implement interrupt-driven disk I/O without busy-waiting. + + +A Description of this Release: + +Here is a list of the files supplied, and a brief description of each: + + +intro: What you are reading + +config.h: Setup parameters, such as table sizes, and the device + driver switch table. + +unix.h: All strcuture declarations, typedefs and defines. + (Includes things like errno.h). + +extern.h: Declarations of all global variables and tables. + +data.c: Dummy to source extern.h and devine globals. + +dispatch.c: System call dispatch table. + +scall1.c: System calls, mostly file-related. + +scall2.c: Rest of system calls. + +filesys.c: Routines for managing file system. + +process.c: Routines for process management and context switching. + Somewhat machine-dependent. + +devio.c: Generic I/O routines, including queue routines. + +devtty.c: Simple TTY driver, slightly-machine dependent. + +devwd.c: Hard disk driver. Very machine-dependent. + +devflop.c: Floppy disk driver. Very machine-dependent. + +devmisc.c: Simple device drivers, such as /dev/mem. + +machdep.c: Machine-dependent code, especially real-time-clock and + interrupt handling code. + +extras.c: Procedures missing from the Q/C compiler's library. + +filler.mac: Dummy to make linker load UZI at correct address. + +makeunix.sub: CP/M SUBMIT file to compile everything. + +loadunix.sub: CP/M SUBMIT file to load everything. + + +Miscellaneous Notes: + +UZI was compiled with the Code Works Q/C C compiler and the Microsoft +M80 assembler under the CP/M operating system, on the same hardware +it runs on. Also used was a version of cpp ported to CP/M, since +the Q/C compiler does not handle macros with arguments. However, there +are only a couple of these in the code, and they could easily be removed. + +Because UZI occupies the upper 32K of memory, the standard L80 linker +could not be used to link it. Instead, a homebrew L80 replacement linker +was used. This generated a 64K-byte CP/M .COM file, which has the lower +32K pruned by the CP/M PIP utility. This is the reason for appearance +of the string "MOMBASSA" in filler.mac and loadunix.sub. + +To boot UZI, a short CP/M program was run that reads in the UZI image, +copies it to the upper 32K of memory, and jumps to its start address. +Other CP/M programs were written to build, inspect, and check UZI filesystems +under CP/M. These made it possible to have a root file system made before +starting up UZI. If the demand exists, these programs can be included +in another release. + + +Running programs under UZI: + +A number of 7th Edition, System V, and 4.2BSD programs were ported to +UZI. Most notably, the Bourne shell and ed run fine under UZI. +In addition the 4.2BSD stdio library was also ported. This, along +with the Code Works Q/C library and miscellaneous System V library +functions, was used when porting programs. + +Due to obvious legal reasons, the source or executables for most of these +programs cannot be released. However, some kernel-dependent programs +such as ps and fsck were written from scratch and can be included in future +releases. Also, a package was created that can be linked to CP/M .COM +files that will allow them to run under UZI. This was used to get +the M80 assembler and L80 linker to run under UZI. Cpp was also +ported to UZI. However, it was not possible to fit the Q/C compiler +into 32K, so all programs (and UZI itself) were cross-compiled under CP/M. + +The Minix operating system, written for PCs by Andrew Tanenbaum et al, +contains many programs that should compile and run under UZI. Since +Minix is much less encumbered by licensing provisions than real Unix, +it would make sense to port Minix programs to UZI. In fact, UZI itself +could be ported to the PC, and used as a replacement for the Minix kernel. + + +######################################################################### + + +UZI-280 is in the process of being written. My computer system +now has a Z280 with 128K of memory. The kernel and user processes +now run in seperate address spaces, but total swapping is still used +at present. The various hardware traps of the Z280 (privileged instruction, +system stack overflow, access violation) are handled correctly. +There is proper protection, in the sense that a user process cannot munch +kernel data, like in the original UZI. Current plans include allowing +user processes to run seperated I and D address spaces (thus allowing +64K of code and 64K of data), and implementing demand paging instead of total +swapping. UZI280 will then have the power and functionality (more or less) of +a PDP-11/34 or PDP-11/60 running 7th Edition Unix. + +By the way, I have modified The Code Works' Q/C Compiler to generate Z280 +instructions and also handle a few more syntactic constructs (like +initalization of automatics). Does anyone know if The Code Works still +sells this compiler (or is even in business)? Any input on how I might +legally distribute this would be appreciated. + +P.S. You do NOT need my Z280 compiler to compile UZI280, just some assembler +macros to define special Z280 instructions. diff --git a/doc/uzi-tech.txt b/doc/uzi-tech.txt new file mode 100755 index 00000000..69a8d3b8 --- /dev/null +++ b/doc/uzi-tech.txt @@ -0,0 +1,548 @@ + UZI180 - Unix Z80 Implementation for the Z-180 (UZI180) + Adapted from UZI by Doug Braun and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + + Portions Copyright (C) 1995 by Stefan Nitschke + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 + General Public License (file LICENSE.TXT) for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +UZI180 is a multi-tasking, multi-user operating for the Zilog Z180 family +of microprocessors. It is a port of the original UZI incorporating many +fixes from UZI280 and some additional features. Significant changes +include an updated floppy disk driver based on a NEC765 derivative cont- +roller, a restructuring and reorganization of the various kernel modules +to ease porting to different hardware platforms, a simpler loading +structure from CP/M, and an integral (albeit minimal) CP/M 2.2 emulator. +The task was undertaken to learn more about the Unix operating system and +the C programming language with an eye to using it to replace several +aging CP/M systems. + +Like the original UZI, this system is based on Unix Edition 7 which was +one of the direct predecessors of Unix System V. UZI180 incorporates the +original system calls and the UZI280 extensions added by Stefan Nitschke. +Some minor additions were also added to provide additional System V compa- +tible features. As stated in the original documentation, there are only a +few significant differences in the UZI kernel calls. The principal +deviations are: + + - 32-bit return values are not provided, so data structures are passed + via pointers to pass essential information. "seek" is therefore incor- + porated as a kernel function with "lseek" provided as a library call. + NOTE: NICK THINKS THIS WILL NOT NEED TO BE CHANGED FOR THE MOMENT. + + - The system "times" are reported in a different format than the standard + 32-bit count of seconds since 1 January 1970. 32-bit Date/Time struc- + tures are in the packed binary form used in IBM PCs, therefore + resulting in 2-second granularity. As a convention, the 0-99 year + should be interpreted as: 70-99 implying 1970-1999, and 0-69 being + 2000-2069 to provide Year 2000 compliance. Standard functions are + available as library routines. + NOTE: NICK IS PLANNING TO CHANGE "TIMES" TO A UNIX STANDARD FORMAT. + + - The "stat" call has a different file length format due to the 32-bit + length omission and use of only 16-bit block and inode numbers. A data + structure is used to contain the information (see library source for + details). + NOTE: NICK THINKS THIS WILL NOT NEED TO BE CHANGED FOR THE MOMENT. + +ARCHITECTURE: + +UZI180 makes extensive use of the Memory Management (MMU) of the Z180 core +to provide as much process isolation as possible with the chip. Since the +MMU granularity is 4k, this establishes the basic process structure. + +The "logical" memory map is as follows: + + 0000 - 3FFF Common Area 0 (CA0) + This is shared memory accessible by all processes. The + interrupt handlers, etc, are placed in here. See below. + (Always mapped to 0:0000 - 0:3FFF in physical memory, + no matter whether user code or kernel code is running) + + 4000 - 7FFF Bank Area (BA) + This is mapped as required, to access executable code. + The IAR "banked" memory model requires this. Every time + we call a subroutine, the IAR library will take care of + remapping the bank area to access the called routine. + The interrupt routines also use this technique, as most + of the interrupt handlers in CA0 are just small stub + programs, which save registers then call a banked routine. + All code is kept in physical memory from 4:0000 to F:FFFF. + + 8000 - FFFF Common Area 1 (CA1) + This is mapped as required, to access read/write data. + In fact CA1 can be used for whatever purpose the currently + running code wants to use it for. Each UZI-180 process + has a dedicated 32-kbyte data segment and this would usually + be mapped in via CA1 while the process is executing. Also, + the kernel has its own data segment (at 0:8000 - 0:FFFF), + which is usually mapped in via CA1 while kernel code is + active, ie. while processing a system call or an interrupt. + All read/write data is kept in physical 0:0000 to 3:FFFF. + +In the CA0 region (Common Area 0), we also keep various read/write data +which is needed all the time. For example, when an interrupt or system +call occurs, we save various information, such as the interrupted task's +stack pointer, into CA0. Thus the information is still available to the +kernel after banks have been switched to access the kernel data segment. + +Some of the key elements placed in the Common Area 0 memory space are: + + - Interrupt Handlers + - Process Swapper + - System and Interrupt Stack Space + - User Process Data Structure + - Kernel Service Handler + +Nick has modified the original UZI-180 memory map, so that 32 kbytes is +allocated to each process (formerly 64 kbytes). In the original UZI-180, +this was divided into 60 kytes of code+data, and 4 kbytes of common area. +With Nick's modifications we have 16 kbytes of common area (always mapped +in to the same physical memory), 16 kbytes of code, and 32 kbytes of data. + +As a temporary measure, for minimal change to the original UZI-180 code, +a full 64 kbytes of PHYSICAL memory is allocated to each process, with +only the upper 32 kbytes being accessible (the process's data segment, +mapped into Common Area 1). Most of the lower 32 kbytes is wasted, but +a small 768-byte area is used to save the kernel's state when pre-empted. + +This organization permits one 64k bank for the kernel/common memory and +three process banks on our system where 256 kbytes of RAM is usable for +read/write data. The remaining 3/4 Megabyte is protected from accidental +writes, so this upper 3/4 Mbyte can only be used for RAM disks or similar. + +The UZI180 memory map therefore appears as: + + First 64k Subsequent 64k banks + 0:FFFF +------------+ +------------+ + CA1 | Kernel | | Process |+ + | data | | data ||+ + | read/write | | read/write |||| + 0:8000 +------------+ +------------+||| + BA | Not used | | Not used |+|| + | | | ||+| + 0:3FFF +------------+ +------------+||+ + CA0 | Common | | Only 768 |+|| + | read/write | | bytes used ||+| + 0:0000 +------------+ +------------+||+ + +------------+|| + +------------+| + +------------+ + +Areas marked as "Reserved" are used for Restart and Interrupt vectors, +and to host the required Page 0 storage elements for the CP/M Emulator. +Constructing executable code modules starting at 100H also allows use of +normal CP/M tools without conflicting memory use. NOTE: WITH NICK'S +MODIFICATIONS WE CAN'T USE THE CP/M EMULATOR, BUT WE HAVE THE ADVANTAGE +THAT RESTART AND INTERRUPT VECTORS ARE NATURALLY "COMMON" (CA0 REGION). + +The algorithm for computing true 20-bit addresses in a Z180 (for DMA) is: + + CBR 7654 3210 + Addr hhhhhhhh llllllll + ---------------------- + bbbb xxxxxxxx yyyyyyyy + +An initial check should be made for common area access (assumed to be the +lower 32k) which will be addresses of the form "0hhhhhhh llllllll" ie. +less than 8000 hex. For these addresses, the raw BBR value for the first +64k of usable RAM is added. (Zero). As an example, the last byte of CA0 +(Common Area 0) is computed for DMA use on a Hytech 1000 or Hytech 1500: + + CBR 0000 0000 00 + Addr 00111111 11111111 3FFF + ---------------------- ----- + 0000 00111111 11111111 03FFF + +A kernel variable (osBank) for the Common Area holds the CBR value for the +kernel's data segment. It is used to specify the source address when data +needs to be copied "out" from kernel to user, and for the destination when +data needs to be copied "in" from user to kernel. The CBR value associated +with each process space is stored both in the kernel process table, and in +each process' 768-byte user data block. This value is used for the other +address when copying data to/from the user. (This happens during syscalls). + +Task switching consists of saving the current process status in the User +stack and data area, block moving the user data area and stacks to the +respective process area in the reserved lower 32k (via DMA), restoring the +new task's data into common memory (also via DMA), changing the CA1 Base +Register in the Z180 MMU to bring the new task in context, resetting the +new process' stack pointer, restoring processor status and continuing as +before. This results in relatively rapid response since the bulk of time +required is due to two 768-byte DMA transfers which consume 1536 * 6 T- +states or 9216 / 18,432,000 = .0005 Sec = 500 microseconds on a 18.432 MHz +Z8S180. This ignores any additional time due to insertion of memory wait +states (zero) and the relatively insignificant overhead associated with +housekeeping. (Transfers are broken into chunks, making it a bit slower). + +Time slices were initially set to 50 mS (20 ticks per second) based on one +of the internal Z180 Programmable Reload Timers. At that rate, less than +4% of a time slice was consumed in swapping processes. The development +systems have subsequently shortened the slice time to 20 mS to minimize +data loss from polled serial ports. A disadvantage of shortening the time +is that a greater percentage of CPU time is consumed during process swaps +with a subsequent lengthening of task run times. This may be adjusted by +appropriately setting parameters in the C and Assembly include files and +re-building the kernel. + +Since peripherals in small systems often are not capable of Interrupt- +driven operation, UZI180 implements polling of such ports during timer +interrupt cycles. Unfortunately, this can lead to inaccurate timekeeping +if the timer is the sole source of Real Time in the system. A prime +example of this is in the Floppy Disk Driver. Polled operation often +dictates that interrupts be disabled during disk accesses to avoid data +loss and/or corruption. During the comparively long time which may elapse +(up to one revolution of 200 milliseconds for 3.5" drives), several clock +ticks may be lost before timekeeping resumes. +NOTE: NICK IS PLANNING TO LOOK INTO THIS. ALL OF OUR PERIPHERALS ARE +INTERRUPT DRIVEN (NOT POLLED) AND WE NEED TO MAKE SURE THAT NO INTERRUPTS +ARE EVER LOST - THIS WOULD NOT BE ACCEPTABLE FOR THE ISDN MODEM AND ALSO, +DISABLING INTERRUPTS FOR TOO LONG CAUSES THE API BUS TO LOCK UP AND SHOW +THE "BAD COMMAND" MESSAGE. NICK HAS FOUND A FEW TEMPORARY SOLUTIONS, BUT +WE REALLY NEED TO ADD SOME KERNEL SEMAPHORES TO AVOID DISABLING INTERRUPTS. + +Wall-Time is corrected automatically by reading the Real-Time Clock every +time the number of ticks-per-second (set by a constant in include files) +elapses and updating a global kernel variable. This variable is then used +by kernel functions when necessary to perform such tasks as time stamping +files and returning current time-of-day. +NOTE: THIS IS NOT YET IMPLEMENTED, BUT WE NEED TO USE THE "RTC" FUNCTION +BUILT INTO THE TOUCHSCREEN, FOR TIME STAMPING. NICK IS GOING TO PROVIDE +A TOUCHSCREEN HANDLER WHICH INTERPRETS THE "TIME OF DAY" MESSAGES, AND A +FEW CONVERSION ROUTINES TO PUT THEM INTO THE STANDARD UNIX TIME FORMAT. + +Polled IO sampling on timer interrupts is not so easily handled and data +loss may be significant. For systems which must operate in this manner, +it is recommended that low-priority processes be placed on those inter- +faces. Also, use of peripherals that disable interrupts for long periods, +such as polled Floppy Disk drivers, should be minimized. +NOTE: WE DON'T USE POLLED IO SAMPLING, AND WE ARE NOT ALLOWED TO DISABLE +INTERRUPTS FOR LONG PERIODS. PLEASE SEE NOTES EARLIER IN THIS SECTION. + + +OPERATION: + +The UZI180 kernel is Process 0 and executes in the lowest 64k of RAM in +the system as a standalone CP/M executable program. Several stages of +initialization occur when first started. The code and initial data which +is destined for the Common Memory is moved into position, having been +linked to an executable image during the link process. After initializing +various kernel data elements, Process 1 is initialized in the upper 32k of +the next higher 64k memory region. Normally Process 1 is "init" which +logs in users and starts (forks) a shell or other user interface. Each +consecutive fork without termination of a previous process is loaded into +the upper 32k of successively higher 64k increments. + +When a new process is initiated, data in the process' address is prepared +with several pieces of data. Necessary arguments and environment +variables are copied into high addresses along with the pointer arrays per +standard UZI definitions. Location 0H is initialized with a jump to a +TRAP (illegal instruction fetch) error handler, and location 0030H (RST +30H) with a jump to the kernel service handler. Both of these handlers +reside in CA0, always accessible in the lower 16 kbytes. Version-specific +locations may also be initialized at this phase such as the Interrupt +Vector at 0038H (RST 38) and the Non-Maskable Interrupt at 0066H. +NOTE: WITH NICK'S CHANGES, LOCATIONS 0000H (TRAP) AND 0030H (RST 30H) ARE +NOW COMMON AND THEREFORE MUST BE THE SAME FOR ALL PROCESSES. HOWEVER, WHEN +STARTING EACH NEW PROCESS WE REDUNDANTLY INITIALISE THEM AS ABOVE. THIS +IS BECAUSE THE ORIGINAL UZI-180 CODE DIDN'T REALLY NEED TO BE CHANGED IN +THIS CASE. IN GENERAL, NO ATTEMPT HAS BEEN MADE TO OPTIMISE THE SYSTEM YET. +AIMING AT A QUICK DEMONSTRATION, NICK HAS ONLY MADE CHANGES WHERE ESSENTIAL. + +Process swaps are initiated by a simple timeout of a per-process counter +which is decremented. When a process is initiated (via an execve kernel +call) or the process is swapped into context, the counter is initiated to +a defined priority value. Each "tick" of the periodic clock interrupt +decrements the counter until it reaches zero. At that time, the User data +and associated stacks (User, Swap and Kernel) are copied to the lower 32k +of the respective process' memory space via DMA, data for the next +runnable process is loaded into Common Area 0, and the new process is +swapped into context by remapping the Common Area 1 Base value of the Z180's +Memory Management Unit (ie. the CBR register is pointed at the user's data). + +UZI180 kernel service calls are initiated by pushing necessary parameters +and the desired function number on the stack and executing a Restart 30H. +A jump to the service handler in common memory was placed at 0030H during +process initialization. Since a Restart functions as a one-byte CALL, a +return address is placed on the stack below the function number. The +Service handler obtains the stack address, switches to a kernel stack in +common memory, extracts information (function number and parameters) from +the user stack, switches the kernel in context, and passes control to the +kernel function process handler. When the function completes (except for +_exit), status information is passed to the kernel exit code in common +memory, the user process is restored to context along with the user stack, +and the Restart "returns" to the user code. Parameters are pushed onto +the stack in standard C form of right to left as specified in the function +declaration (contrary to UZI and UZI280). This places the left-most +declared parameter immediately above the return address on the user stack. +NOTE: WITH THE IAR COMPILER, PARAMETERS ARE PUSHED FROM RIGHT TO LEFT, +WHICH IS GOOD BECAUSE IT DIDN'T NEED TO BE CHANGED. HOWEVER, THE IAR +COMPILER USES A REGISTER-PASSING MECHANISM WHICH CAN'T EASILY BE DISABLED, +SO THE SYSTEM CALL PROTOCOL HAD TO BE MODIFIED. IN THE ORIGINAL UZI-180, +THE SYSCALL'S FUNCTION NUMBER WAS EXPECTED TO BE FOUND AT SP+22H AFTER ALL +REGISTERS WERE PUSHED. WITH NICK'S MODIFICATIONS, THE SYSCALL'S FUNCTION +NUMBER IS PASSED IN A REGISTER (DE), AND ALSO, ANOTHER REGISTER (BC) GIVES +THE ADDRESS OF THE FIRST PUSHED PARAMETER. THIS IS QUITE ELEGANT SINCE +A HARD CODED OFFSET OF SP+22H DOESN'T NEED TO BE USED IN THE KERNEL, AND +IT GIVES THE USER PROGRAM MAXIMUM FLEXIBILITY IN PASSING THE ARGUMENTS. +(ARGUMENTS DON'T NEED TO BE ON THE STACK AT ALL, OR ELSE, THE SYSTEM CALL +COULD BE ENCLOSED IN SEVERAL SUBROUTINES WITH THE PARAMETERS HAVING BEEN +PUSHED AT AN OUTER LEVEL. PLEASE SEE c:\uzi\libc\syscalls\syscalls.s01) + +Executable programs in UZI display the CP/M roots of the system in that +all programs begin execution at 100H. In melding the original Unix tech- +nique of testing the first character(s) of a file for "magic numbers" with +CP/M, all executable programs in UZI require that the first instruction be +a long jump (JP xxxx, opcode 0C3H). For native UZI applications, this +header is contained in the crt.obj file linked with all executable files. +UZI180 modifies this file to follow the jump with a text string containing +the three letters 'UZI'. If these three letters are missing but the +"magic number" 0C3H is present, then a CP/M executable is assumed and +execution commences under a CP/M emulator described below. +NOTE: WITH NICK'S MODIFICATIONS ALL PROGRAMS BEGIN EXECUTING AT 8100H. +AS A VERY TEMPORARY MEASURE, USER PROGRAMS ARE COMPILED WITH AN UNBANKED +MEMORY MODEL, SO ALL CODE AND DATA NEEDS TO BE SQUEEZED INTO 32 KBYTES +AT 8000 - FFFF. (IE. CODE IS TEMPORARILY PLACED IN THE DATA SEGMENT). +NICK ALSO RESERVED THE FIRST 100H BYTES OF THIS DATA SEGMENT FOR FUTURE +USE BY THE BANK-SWITCHING ROUTINES (NOT YET IMPLEMENTED, BUT THIS WILL +EASE THE TRANSITION TO USING A BANKED MEMORY MODEL FOR THE USER PROGRAMS). + + +EMULATOR: + +In addition to the UZI kernel service calls used by native applications, a +minimal CP/M 2.2 emulator is built into UZI180 to allow many existing CP/M +and Z-System utilities to run under UZI180 without modification. The +emulator intercepts CP/M Bios and Bdos function requests and interprets +them into equivalent UZI kernel calls, or processes them directly. To +minimize the amount of memory consumed, only essential functions are +included, and not all programs will function correctly. Some of the more +significant limitations of the emulator are: + + - No Z-System data structures (ENV, IOP, RCP, FCP) are included + - Only Drive A:, User 0 (as the current directory) is available + - No ALV bits are included so Directory programs will be unable + to report free space + - The Bdos size is smaller than 3.5k so programs assuming standard + components by subtracting from Bios WB address will be wrong + - No Command Processor is included + +When needed, the emulator is moved into high process memory below the env +and arg parameters. Instead of transferring execution to the program at +100H as an UZI executable, the process begins by executing the base code +of the emulator. Code at this location is later overwritten by the CP/M +stack since it is only used during process initialization. This sequence +sets up CP/M vectors at 0H (Bios Warm Boot), 5H (Bdos service vector), +catenates argv parameters into a capitalized command line tail in the +default buffer starting at 0080H, and initializes other storage locations +(Current Drive/User, FCBs, etc) before beginning execution at 100H. CP/M +program termination by executing either a Bios Warm Boot or Bdos function +0 will trigger an UZI _exit kernel function and terminate the process. + +In the initial form, env parameters are not used by the emulator, but use +of the PATH variable is planned to make the system more usable. +NOTE: THE CP/M EMULATOR IS CURRENTLY NOT USABLE BECAUSE OF CONFLICTS WITH +IAR'S BANKED MEMORY MODEL. THE PROBLEM IS THAT CP/M PROGRAMS EXPECT TO BE +LOADED AT ADDRESS 100H, WHEREAS THE Z180'S MEMORY MANAGEMENT UNIT EXPECTS +ADDRESS 100H TO BE IN COMMON AREA 0 (ALWAYS SHARED BETWEEN ALL PROCESSES). +IT WAS MORE IMPORTANT TO MAKE GOOD USE OF THE THREE REGIONS (CA0, BA, CA1) +PROVIDED BY THE Z180, RATHER THAN HAVING CP/M COMPATIBILITY. THE ORIGINAL +UZI-180 COULD NOT USE CA0 FOR THIS REASON, AND ONLY USED THE BA/CA1 AREAS. + + +DEVELOPMENT ENVIRONMENT. + +The bulk of UZI is programmed in the C language, under Windows 2000 or a +compatible operating system. Doug Braun's original UZI was written with +the Codeworks' QC compiler which resulted in some odd interfaces since +parameters were passed the system stack in backwards order (left-to-right) +instead of the conventional right-to-left ordering used in the C program- +ming language. UZI280 and UZI180 were both written for the Hi-Tech ANSI +Standard compiler Version 3.09 released for non-commercial use in 1987 and +included in Walnut Creek's CP/M CD-ROM. The Hi-Tech package also included +a Z80/Z180 assembler, linker, librarian and source code for the CP/M run- +time library. This system forms the complete development environment +(less text editor) for UZI180. +NOTE: WE DON'T USE THE HITECH COMPILER, ALTHOUGH IT'S FREE, BECAUSE IT'S +VERY LIMITED COMPARED WITH THE IAR COMPILER. FORTUNATELY THE IAR COMPILER +IS QUITE SIMILAR TO THE HITECH COMPILER, SINCE BOTH ARE ANSI COMPATIBLE, +BUT ALL THE ASSEMBLY LANGUAGE MODULES HAD TO BE MODIFIED FOR IAR'S REGISTER +PASSING MECHANISM. THIS WAS QUITE A LOT OF WORK, AND LED TO SOME RATHER +SUBTLE BUGS, NOW FIXED. THERE MAY STILL BE ISSUES. SOME OF THE UZI-180 +CODE, FOR EXAMPLE THE TTY INTERRUPT HANDLER, WAS REMOVED AND NOT CONVERTED. +NICK IS ALSO PLANNING TO GO THROUGH THE 'C' MODULES CONVERTING THEM TO ANSI, +SINCE THE ORIGINAL "K&R" CODE HAS NOT BEEN FULLY CONVERTED. FOR THE MOMENT, +ONLY THE ABSOLUTELY ESSENTIAL CHANGES HAVE BEEN MADE, BUT THERE COULD BE +SUBTLE BUGS. THE USE OF FUNCTION PROTOTYPES WOULD IMPROVE MAINTAINABILITY +AND RELIABILITY, BY ENSURING THAT ALL FUNCTION PARAMETERS ARE TYPE CHECKED! + +The Hi-Tech Compiler requires a rather large Transient Program Area to +compile the UZI sources. Consequently, users normally operating with the +Z-System may need to remove several of the standard ZCPR3.x components to +free up enough memory to compile the system. UZI180 was developed on the +author's Banked and Portable (B/P) Bios system with banked ZSDOS2 and +generated using autosizing of the system (BDOS and ZCPR) with no RCP or +IOP. Since the compiler overwrites the Command Processor, the base of +BDOS forms the upper limit of Transient Program Area which is 0E486H in +the author's system. The BIOS Warm Boot vector is at 0EE03H. This is +only slightly larger than a standard 62k CP/M system where the BDOS vector +is at 0E405H and BIOS WB vector at 0F203H. A standard 62k CP/M system +should be sufficient since the majority of initial work occured on a +slightly smaller system. +NOTE: IGNORE THIS. THE IAR COMPILER HAS ACCESS TO ALL OF YOUR SYSTEM +RAM, SINCE IT RUNS UNDER WINDOWS 2000 USING A LINEAR PAGED ADDRESS SPACE. + +Following Stefan Nitschke's lead with UZI280, assembly-language modules +were added to several portions of kernel code to provide platform- +dependant interfaces where necessary. Assembly code modules were also +added to improve performance, particularly to minimize context switches +and change parameter passing to the standard 'C' conventions of placing +parameters on the stack from right-to-left. In some cases, these assembly +modules were necessitated by apparent problems with the Hi-Tech compiler's +ability to handle inline assembly with optimization turned on. To avoid +severe performance penalties and code bloat, all modules were compiled +with optimization turned ON. +NOTE: THE IAR COMPILER DOESN'T HAVE OPTIMIZATION SO THERE WAS NO ISSUE. +THE IAR COMPILER MAKES SLIGHTLY LARGER CODE THAN THE ORIGINAL, BUT THIS +DOESN'T MATTER BECAUSE WE HAVE A 3/4 MEGABYTE BANK SWITCHED CODE SPACE +THE ORIGINAL UZI-180 WAS LIMITED TO 32 KBYTES OF KERNEL CODE, BUT WE CAN +HAVE MUCH MORE. CURRENTLY OUR CMX/UZI KERNEL IS ABOUT 128 KBYTES. + +When bringing up UZI180 for the first time, you must first extract all +member files in the basic Kernel library module, and member files for the +specific version for your platform. Begin by tailoring values in the +version-specific files to reflect your needs, particularly the Hard Disk +parameters in HDCONF.H. Check the Z180 initialization values in both +Z180ASM.ASZ and ASMDEF.I to insure that such items as Serial Data rates +and CPU clock frequency are accurate. +NOTE: HDCONF.H HAS BEEN MODIFIED TO REFLECT THE STARTING POSITION OF +UZI'S DATA ON THE FLASH CARD. THIS MAY NEED TO BE MODIFIED FOR THE +PARTICULAR FLASH CARD GEOMETRY IN USE, OR WE COULD MAKE SURE WE ONLY +USE A 32 MBYTE FLASH CARD AS I HAVE USED. NICK WILL LOOK INTO THIS. + +You must next Compile/Assemble all source code C and Assembly modules for +the kernel. The simplest way to perform this is to execute the batch +file N.BAT. Use the Windows 2000 command interpreter (CMD.EXE) for this. +An example compile command line from N.BAT is: + + iccz80 -S -w -mb -v1 -z -A -Ic:\iar\ew23\z80\inc\ -I..\cmx\ + -DDEBUG process -l process + +After each module is compiled/assembled, either manually or via the N.BAT +script, the components must be linked into a loadable kernel image. A +script is provided for this purpose, which is read into the IAR linker. +The script is set to produce an output file of UZI.IHX which then needs +to be converted from Intel Hex format to binary. We use Jason Nunn's +"ihex2bin" utility for this. Nick has made some modifications so that +"banks" generated by the IAR linker are concatenated smoothly into one +binary file with no gaps between banks. (See c:\uzi\ihex2bin\ihex2bin.c) + +The linker script is kept in the file N.XCL and will automatically be +"linked" by the N.BAT batch file using a command line as follows: + + xlink -S -f n + +To aid in system maintenance and debugging, a symbol table (UZI.MAP) as +well as the UZI.IHX kernel image is also generated in this step. + + +TOOLKIT. + +Doug Braun provided several utilities which allow you to make an UZI file- +system and prepare it for use. These must be compiled and linked with +modified versions of UZI kernel modules to form Windows 2000 executables. + +Some of the kernel modules are simply compiled with the utility include +files, while others such as the process and call modules are actually +older versions of the kernel code with some modifications to run as Windows +programs instead of assuming total control of the computer. In the case +of the core Floppy Disk driver, XFLOPASM.ASZ, hardware timeout via the +Interrupt timer is removed for utilities in favor of countdown timers and +letting the Floppy Disk motors remain running after the initial spinup. +NOTE: IN THE c:\cmx\utils FOLDER, FLOPPY DISK DRIVERS ARE NOT LINKED, AS +WE CAN'T COMPILE Z80 CODE TO RUN UNDER WINDOWS. THE HARD DISK DRIVER IS +A SMALL "C" PROGRAM WHICH OPENS A 1.5 MEGABYTE FILE ON THE WINDOWS SYSTEM +FOR USE AS A "VIRTUAL" HARD DRIVE, SO NO ASSEMBLY NEEDED TO BE USED. SEE +c:\cmx\utils\hdasm.c (THE NAME REFLECTS THE FACT THAT IT WAS FORMERLY ASM). + +The basic tools are: + +MKFS - Make an UZI file system on a block device (HDx, FDx) and prepare it + for use. + +UDP - Display specified UZI File System Block Number on the Screen in Hex. + +FSCK - Check an UZI file system on a block device for consistency. + +UCP - Copy files between CP/M and an UZI storage device, type files to + the CP/M Console, mount/umount another device into the UZI file- + system and delete files. If you are running ZSDOS with file + date/time stamping, this program also adds date/time stamps to + the UZI file system when copying files to the UZI file system. + +Portions of the UCP utility were extracted into stand-alone UZI applica- +tions during UZI180 development to test various functions of the kernel, +and to form the necessary core suite of utilities to make the system +"feel" like a Unix system. These are also provided along with a re- +written LIBC library containing the UZI180 interfaces. A separate .DOC +file details the steps needed to compile and link applications to form +native UZI180 executables under CP/M. UCP may then be used to move the +resulting executables into an UZI file system from where they may be +executed. +NOTE: THIS IS DONE BY c:\cmx\bin\loadall.bat WITH CONTENTS AS FOLLOWS: + ucp < loadall.ucp + copy uzidisk.dat e:\ +AS YOU CAN SEE, A SCRIPT FILE IS FED INTO THE UCP UTILITY, WHICH COPIES +THE REQUIRED BINARY FILES INTO A VIRTUAL UZI-180 DISK, THEN COPIES THE +RESULTING DISK IMAGE DIRECTLY ONTO THE FLASH CARD. THIS ASSUMES YOU +ARE USING A LAPTOP WITH A PCMCIA FLASH CARD ADAPTER, AND YOU MUST HAVE +INSERTED THE FLASH CARD BEFORE STARTING THE loadall.bat SCRIPT. AFTER +COMPLETING THE SCRIPT, YOUR FLASH CARD MUST BE "STOPPED" USING WINDOWS +2000'S CONTROL PANEL, THEN YOU MUST PUT THE FLASH CARD IN THE TERMINAL. + + +THINGS TO DO. (Beta Notes, 18 August 1998 - HFB) + +- Add complete hardware initialization (probably in MACHASM.ASZ) to set + all system parameters. Currently, UZI180 relies on settings performed + by CP/M or compatible OS/BIOS prior to booting UZI. + NOTE: VARIOUS USEFUL INITIALISATION IS PERFORMED BY OUR SYSTEM EPROM, + VERSION 5.531 AND ABOVE, SO THERE'S NO NEED TO CHANGE THIS FOR NOW! + +- Add TTYASM.ASZ module for setting the TTY port parameters when changed. + Currently, the serial port parameters (Data rate, # Bits, Parity, etc) + are whatever was set prior to booting UZI. + NOTE: THIS WILL BE DONE VIA CMX FUNCTION CALLS (SEE c:\uzi\cmx\cmxio3.c). + NICK STILL NEEDS TO ADD SUPPORT FOR BAUD RATE SETTING (NOT ESSENTIAL YET). + +- Polish the Floppy Driver (FLOPASM.ASZ) to add variable formats (auto- + sense on mount?), local bufffering for 1k sector sizes, and accomodate + disk formats with CP/M Boot Tracks. The module is currently locked + into a pseudo-MSDOS 1.44 MB High-Density 3.5" disk format. + NOTE: NICK IS PLANNING TO REMOVE THE FLOPPY DISK DRIVER (FLOPASM.S01) + AS IT WOULD PROBABLY CRASH IF ACCESSED. (DOESN'T REALLY MATTER FOR NOW). + +- Refine the Emulator a bit and massage the addresses to provide full + Environment space (512 bytes) and Argument area (512 bytes max). Also + add path default to a defined CP/M directory for accessing overlays, + libraries, etc. + NOTE: WE COULD RE-IMPLEMENT THE CP/M EMULATOR, BY ALLOWING USER PROGRAMS + TO DISABLE CA0, AND PROVIDING SPECIAL INTERRUPT HANDLERS WHICH RESTORE + CA0 BEFORE PROCESSING THE INTERRUPT FOR REAL. THIS WAS TOO MUCH WORK FOR + THE MOMENT, BUT IT'S WORTH CONSIDERING, AS WE COULD THEN "PORT" THE BASIC + CODE FOR THE "EXPERT SYSTEM" WITHOUT CHANGE. HOWEVER THIS WOULD BE A LOT + OF WORK, SO I PREFER TO REWRITE THE EXPERT SYSTEM IN "C" INSTEAD. WE CAN + ALSO MAKE IT MORE ELEGANT AND REMOVE A LOT OF DEAD CODE AT THE SAME TIME. + diff --git a/doc/z180-mem.p b/doc/z180-mem.p new file mode 100755 index 00000000..3f4357be --- /dev/null +++ b/doc/z180-mem.p @@ -0,0 +1,588 @@ +Z180 Memory Management + +The Z180 MMU is confusing, but quite useful when well understood. + +Published in Circuit Cellar Ink, February 1990 + +World Wide Web editor's note: This discussion of the MMU is still appropriate +today. Change the processor name from 64180 to Z180, as Zilog now dominates +this market, and change Archimedes (the compiler guys) to IAR, and most of the +article is still correct. + +Programs are getting big! Part of today's shift towards 16 and 32 bit +processors comes from the need for correspondingly huge address spaces, since +conventional wisdom holds that a 512kb program just cannot fit in the 64k +address space of most 8 bit CPUs. Where performance is the overriding concern, +a 32 bit CPU may be the only solution. It does seem a shame to abandon all the +accumulated knowledge and code gleaned from two decades of 8 bit +microprocessors just to get more programming elbow room. + +For the past few years some 8 bit CPUs have been equipped with memory +management units (MMU) that free programs from most memory limitations. It's +tedious and complex to control a MMU manually; now, many languages and other +tools include built-in MMU support. + +Logical -> Physical + +The problem of memory management is easy to define: we need some way of +connecting lots of memory to a processor that just cannot handle or address it. +For example, we might want to put 512kb on a Z80. Since the Z80 only generates +16 bit addresses, it can only directly address 64k of RAM. Somehow, though +memory management, we must expand this capability. + +For now let's assume that magic hardware gives us more address lines. Perhaps +it is as simple as an I/O port loaded by the CPU with an extra upper 8 address +lines (A16 to A23), giving us a potential address space of 24 mb. Or, it can +be hideously complex, providing some ability to access different sections of +address space in wild and wonderful ways. + +In any event, as soon as some external mechanism is added to translate +addresses in some fashion, the programmer suddenly must contend with two very +different sorts of address spaces. + +"Physical" memory is that actually connected to the hardware. For example, the +512kb we attach to the sadly-overloaded Z80 is physical memory. Its address +ranges from 00000 to 80000 hex in a linear manner. + +"Logical" memory is the memory currently located in the processor's address +space. Obviously, if the computer can only issue addresses in the range of +0000 to FFFF (0 to 64k), then some of the physical memory is visible and some +is not. As the code changes the memory manager's settings different memory +becomes visible. That which is addressable at any time is the logical memory. + +Thus, addresses generated by the program are always logical addresses - they +get translated by some yet undefined hardware into real physical addresses. + +So, at one time address 1000 logical might be translated into 28000 physical. +Later, in the same code, 1000 could correspond to 80000 physical. The old one­ +to-one mapping of addresses we're all familiar with is gone! + +In summary, addresses used by the code are logical; the memory array sees +physical. Between these two the memory management unit (MMU) falls. Standard +Architectures + +Several years ago Hitachi introduced the 64180, a high integration version of +the venerable Z80. While other vendors were trying to push new proprietary +architectures, Hitachi took what might seem a step backwards towards the Z80. +They realized an important fact of the industry - customers had a fortune +invested in Z80 code and were unwilling to switch to an incompatible +instruction set. + +The 64180 is a Z80 at heart. The designers resisted the temptation to add +fancy new instructions and addressing modes that could have made it +incompatible with the Z80. Rather, they integrated timers, serial ports, and +DMA controllers onto the chip. Even better, they added a memory management +unit to translate 64k logical addresses into a 1 mb physical address space. + +Now Hitachi sells several other versions of the part. The 64180S is designed +especially for telecommunications. The 647180X is a microcontroller version, +containing a 64180 core, ROM, RAM, and parallel I/O. Zilog stepped into the +act, offering the Z180 (a second source of the 64180) and Z280, a very high +performance Z80 upgrade. Zilog is just now announcing the Z181 and will soon +offer a microcontroller version of the part, probably a 647180X look-alike. + +The most important peripheral on the 64180-family processors is the memory +management unit (MMU). The MMU is a hardware device built onto the processor's +silicon. The MMU translates every memory address from 16 to 20 bits. + +The 64180's MMU uses three internal control registers. In keeping with the +chip's design philosophy, on reset the MMU gives a straight logical to physical +mapping, simulating the Z80 and, of course, limiting the address space to 64k. + +You can divide the 64180's logical address space into one, two, or three areas. +The logical space itself is unaltered; even when divided it is still a +contiguous 64k. + +CBAR is an 8 bit I/O port that can be accessed by the processor's OUT and IN +instructions. The lower 4 bits specify the starting address of the bank area, +and the upper 4 give the start of common 1. These bits determine the upper +four bits of the address. If CBAR were A8, then the base area starts at 8000 +logical, and common 1 starts at A000. + +Common 0, if it exists, always starts at logical 0000 and runs up to the bank +area. The bank area then runs to the start of common 1. + +Therefore, you can always understand the logical address space by examining the +contents of CBAR by itself. No other information is needed. + +The logical address is only part of the problem. How does logical space get +mapped to physical? Two other ports provide the rest of the answer. + +BBR (the Base Area Bank Register) specifies the starting physical address of +the base area (remember, the logical start is in CBAR). CBR (Common Bank +Register) provides the same information for common 1. Both of these specify +the upper 8 bits of the 20 bit physical address. + +A simple formula gives the translation from logical to physical address for the +bank area: + + Physical = Logical + (BBR * 4096) + +The same formula gives Common 1: + + Physical = Logical + (CBR * 4096) + +BBR and CBR gives the upper 8 address bit only - hence the 4096 multiplier. +The lower 12 bits come from the logical address. Thus, the translation only +affects the upper 8 bits; the lower 12 physical bits are always identical to +the lower 12 logical. + +On reset, the 64180 sets CBAR to F0, and CBR=BBR=0. This maps logical to +physical exactly, with no translation; the bank area starts at logical 0 and +common 1 at F000 (since CBAR=F0), the bank area physically starts at 0000 +(BBR=0), as does common 1 (CBR=0). If the logical address is 1000, then the +MMU allocates this to the bank area (CBAR=F0; 1000 is less than the start of +common 1 at F000), and adds the physical base of bank to it (0), giving a +translated address of 01000. Similarly, logical F800 is in common 1, and +translates to 0F800. + +The most important point that can be made about the MMU is that it does not +provide the 1mb linear address space we all crave. After all, Z80 instructions +use 16 bit address operands and 16 bit register pointers - there is no way to +address a number larger than 64k. A jump instruction will always have an +argument that is 16 bits long - the logical destination address. The MMU +translates this logical address to a possibly large physical number, but the +software still operates in a 64k space. + +This has a subtle implication - logical address space is a valuable commodity +that must be conserved. Wasting physical memory isn't so bad, since the 64180 +can deal with up to 1mb. As an example, suppose that your program will have +three banks (COMMON 0, BANK, and COMMON 1). If the program is large you might +want to bank it in and out of the BANK area, leaving COMMON 1 for data. If +BANK is too large, you could be left with little data space - it is important +to make BANK as small as feasible to maximize the (in this case) unbanked data. + +Language Support + +Despite the fabulous extra power offered by the 64180's MMU, we've all been +making do with Z80 assemblers and compilers. Sure, some claim to support the +new processor's extended features, but in truth, until recently, that support +has been minimal. + +Just what features are important in a 64180 assembler or compiler? Certainly it +should be fast, efficient, and all that, but more than anything else the +language should give you some sort of way of handling the MMU. + +There are two related but different aspects to MMU management. The first is to +provide some sort of mechanism to control the MMU with as little programer help +as possible. An ideal solution would be a smart compiler that simulates a +nearly linear huge address space. The second is to provide output files that +contain compiled code and debugging records in some manner that supports +current 8 bit tools (like the PROM programmer), but that accounts for the large +address spaces. + +Taking these two criterion separately, especially with a C compiler we'd really +like some method of compiling an ordinary C program in multiple banks. Sure, +you might have to tell the compiler or linker about your memory configuration, +but ideally the tools should segment and package functions into memory banks as +needed. Even better, we'd want it to remap the MMU automatically. Just like +working with Turbo C, we would like to be able to invoke a function through a +conventional function call, without worrying about its location in memory. + +The second requirement is not quite so obvious. How will you burn ROMs for the +final project? If the compiled/assembled code exceeds 64k, there may be a +problem with using standard Intel hex records for output. Every ROM programmer +in the world takes Intel hex input, but the format only supports 16 bit +addresses. + +One solution is to divide the source program into many separately compiled +small pieces. This is especially hard in C, since the linker will not be able +to resolve calls between pieces. Another approach is to insure that the +compiler or assembler can produce "Type 2" Intel records. Whenever the code +crosses a 64k bank the linker could output a type 2 record to specify a new +segment address (physical address shifted right 4 bits). This does imply that +the linker can handle large physical addresses, and the PROM programmer can +accept type 2 records. + +Decent debugging files are just as important as useful PROM files. You can't +use an emulator, simulator, or monitor to debug the code if the debug records +are inadequate. Suppose you wish to display the value of a variable. The +debugger must know the physical address of that quantity, since only the +physical address is constant. Remapping the MMU changes its logical address, +and at times no logical address might correspond to the variable. + +This implies that the software packages must maintain both logical and physical +addresses for all lines and symbols. Compiling, say, jumps requires logical +addresses. All jumps and calls take logical addresses as arguments (since they +can only support a 16 bit number). Physical addresses are needed in the +debugging records so debuggers can unambiguously resolve the location of +symbols, functions, and line numbers, all whose logical address changes with +the current MMU setting. + +Assemblers + +Most 64180 programs written in assembly language control the memory manager by +tediously issuing many MMU control instructions. The programmer must first +decide exactly what configuration logical memory will assume, and then come up +with CBAR, BBR, and CBR values for every possible combination of banks. Then, +the code must send these values out to change maps. Needless to say, this +takes a lot of work. + +Softools (8770 Manahan Drive, Ellicott City, MD 21043, (301) 750-3733) came up +with an interesting approach that eliminates most of the work. Their SASM +assembler and linker will automatically drop in all the code needed to bank a +program. In effect, this means you can write code as if the 64180 had a 1 mb +linear address space. + +Like most good assemblers, SASM supports lots of named segments - up to 256. +Most of the time we assembly programmers just need a CODE, DATA, and ASEG +segment, but SASM's segmentation lets us break a program into mapped and +unmapped sections. When using SASM on large programs, you can assign any +segment or segments to have a "mapped" attribute, identifying those that +require some MMU manipulation to bring them into the address space. +NOTE: SASM IS QUITE SIMILAR TO IAR'S AZ80 ASSEMBLER, SO CHANGED SASM TO AZ80 +IN THE FOLLOWING DISCUSSION. HOWEVER, AZ80 USES THE SEGMENT NAME 'CODE' FOR +ALL BANKED CODE, KNOWING THAT THE SEGMENT'S CODE CAN BE SPLIT INTO BANKS WHERE +THERE IS A MODULE BOUNDARY. SO ACCESSES OUTSIDE THE MODULE MUST USE BANKED +CALLING CONVENTIONS!! WITHIN THE MODULE THERE IS SOME FREEDOM TO USE PRIVATE +ROUTINES WITH THEIR OWN CALLING CONVENTIONS (AS YOU KNOW EACH MODULE FITS INTO +A BANK AND CAN'T SPAN MULTIPLE BANKS). USE THE LWRD OPERATOR WHEN DOING THIS. + +Segments are the key to IAR AZ80's mapping scheme. The linker identifies how +much data the program uses and the number of bytes used for unmapped code (that +which must never be mapped out). It computes CBAR to define the +characteristics of the runtime logical address space: COMMON 0 being just big +enough to hold all the unmapped code, COMMON 1 containing the data, and the +rest, the BANK area, is allocated to mapped routines. + +The linker groups all mapped segments together and starts to assign both +logical and physical addresses to each routine. Whenever a routine will exceed +the size of the BANK area the linker moves it to the start of a new BANK area. +It then converts all jumps and calls between banked areas to transfers to code +that manages the MMU in COMMON 0. + +When finally linked, the program has three parts - a COMMON 0 non-mapped (i.e., +always in the address space) area which typically contains startup code, +frequently-used routines, and AZ80's banking code. COMMON 1 is usually your +data area. The BANK area contains most of the program code. Calls between +these banked routines will cause remapping as needed to bring in ones that are +not currently visible in the address space. + +For example, suppose the program is as follows: + + routine length characteristics + main 3700h not banked + vectors 80h not banked + sub1 4000h banked + sub2 38f0h banked + sub3 1200h banked + sub4 6f00h banked + sub5 800h banked + data 3200h not banked + +On a 64180 the reset jump is at 0, so it makes sense to put the unbanked code +(vectors and main) at 0. The data area cannot be banked (especially the +stack!) and is traditionally in high memory. Suppose the code that starts at +physical location 0 is to go into ROM, and the data that starts at physical +40000h is in RAM. The linker will first divide the logical address space based +on the unmapped memory requirements: main and vectors need 3780h bytes starting +at location 0, and data occupies 3200h at the end of the logical space. +Bearing in mind that the mapping resolution of the 64180 is 4k, memory thus +looks like: + + Logical Physical Area + 0000 00000 unbanked (main and vectors) + 4000 04000 start of banked routines + c000 40000 start of RAM data + +All the logical address space from 4000 to bfff is available to routines that +can be banked. If the sum of the banked sizes is less than the BANK logical +area, then no mapping need take place. In our example, however, banked +routines need some 64k, much more than the available logical space. If CBAR is +C4 (COMMON 1 at c000 and BANK at 4000), AZ80 will assign addresses as follows: + + Logical Physical Routine length BBR + 0000 00000 main 3700 -- + 3780 03780 vectors 80 -- + 4000 04000 sub1 4000 00 + 8000 08000 sub2 38f0 00 + 4000 0c000 sub3 1200 08 + 4000 0e000 sub4 6f00 0a + af00 14f00 sub5 800 0a + c000 40000 data 3200 -- + +For sub1 AZ80 assigned a logical and physical address of 4000 - reasonable, +since this is the first free spot after COMMON 0. sub1 is in BANK, so a BBR +value is required. BBR=0 will map 4000 to 04000. sub2 follows sub1, again +with BBR=0. So far, no surprises. + +sub2 ends at b8f0, practically right before the logical start of data (c000). +There is no way sub3 can fit, since sub3 is 1200 bytes long. AZ80 therefore +put sub3 at logical address 4000 (the same as sub1). sub3 follows in physical +memory at 0c000 (the next physical address rounded up to a 4k boundary). BBR +equals 08. sub1 and sub3 occupy the same place in logical address space +(4000), but different physical addresses. To get to sub3, BBR must be set to +08 and a logical address of 4000 issued. + +While sub3 is very short, leaving plenty of room for code in the same bank map, +sub4 is not. sub3 and sub4 will not both fit into BANK together, so AZ80 once +again reset the logical address to 4000. sub4 comes after sub3, rounded up 4k, +and a BBR of 0a is assigned. (Remember the math - BBR * 4096 + logical = +physical, so 0a * 4096 + 4000 = e000). sub5 fits into the space between the +end of sub4 and COMMON 1, and is so assigned. + +IAR XLINK generates address assignments as we've just seen, but how are calls +and jumps between subroutines handled? Obviously, if sub1, sub3, and sub4 all +reside at logical address 4000, a simple CALL 4000 will not always resolve +properly. As mentioned earlier, XLINK converts all inter-BANK calls and jumps +to a transfer to a jump table which is usually linked into COMMON 0. In +particular, if sub4 were to call sub1, the following will be automatically +substituted for the call instruction: + + call bank_table+x ; invoke MMU handler + db BBR ; BBR of sub1 + DW sub1 ; address of routine to call + +The code in bank_table stores the current BBR value and return address on a +local stack, remaps the MMU by outputting the indicated BBR, and then transfers +to the logical address supplied as a parameter. Returns operate in a reverse +procedure, being vectored to another Softools-supplied routine to reverse the +mapping. + +What might not be entirely obvious is that AZ80 does it all. Once you tell +XLINK where ROM and RAM are (which has to be done for any linker) it +automatically allocates logical and physical addresses. The linker also +replaces the calls and jumps as shown above. AZ80 does offer options to +control memory allocation and the like, but in most cases these are not needed. + +This means that you can write large programs without ever considering the MMU. +AZ80 takes care of it all. There's an interesting subtle implication - you can +link a 256k program to take up only 8k or so of logical space! Assign 4k for +COMMON 0 and 56k for data. AZ80 will bravely partition the 256k code into 50 +or more sections, each of which will get remapped through the 4k BANK area. +The mapping overhead might get high, but logical address space will be +conserved. + +Since AZ80 partitions the program during the link phase, it can save the +addresses of all symbols, line numbers and other parameters in a debug file. +Symbols' physical addresses are stored in the debug file, maintaining true +addresses regardless of the MMU mapping. If the debugger (emulator or monitor) +can handle physical addresses, then you can access any routine, variable, or +source line number at any time, without manually remapping to bring the desired +value into logical address space. + +C Compilers + +As we write this, only three compilers currently support 64180 bank switching. +Archimedes Software's C180, Whitesmiths' C, and Software Development System's C +all automatically generate code for large memory models. Manx (MANX Software +Systems, P.O. Box 55, Shrewsbury, NJ 07701) will soon have a compiler, and no +doubt others are on the way. + +Archimedes (2159 Union Street, San Francisco, CA, 94123 (415) 567-4010) +approach to memory management is much like that used by AZ80. As you write +your C code you do not need to be especially concerned with the MMU. There are +no special procedures to use or functions to invoke. + +Before linking the compiled object files various parameters must be passed to +the linker in its indirect command file. The first are values for CBAR and +CBR. It is the programmer's responsibility to determine exactly the memory +configuration, and to compute these simple values. +NOTE: THE IAR ICCZ80 WORKS LIKE THIS. FOR THE MOMENT THE VALUES ARE HARD +CODED BUT THE DEFAULT SETUP PROVIDED BY IAR ALLOWS YOU TO PASS THEM IN THE +LINKER CONTROL FILE. OUR CSTARTUP IS HEAVILY CUSTOMISED SO I DIDN'T BOTHER. + +In addition to the MMU register settings, the programmer must provide the +linker with a table of modules (i.e., file of source code, each of which may +contain several functions) and names. If the module is not to be banked, that +must be indicated as well. +NOTE: THE IAR XLINK DETERMINES AUTOMATICALLY WHICH FUNCTIONS ARE BANKED AND +WHICH ARE NON_BANKED USING INFORMATION EMBEDDED IN THE OBJECT FILES. BANKED +AND NON_BANKED CALLING SEQUENCES HAVE BEEN DETERMINED AT COMPILE TIME, SO THE +LINKER DOESN'T NEED ANY SPECIAL SYMBOL TABLE INFORMATION TO DO ITS WORK. + +The memory model supported by the compiler puts all non-banked functions into +COMMON 0, the banked code into BANK, and data areas into COMMON 1. +NOTE: THIS IS IDENTICAL TO IAR'S SCHEME WHICH WE ARE USING FOR HYTECH CMX/UZI. + +The linker generates a table ("FLIST") of data about every mapped function in +the program. For each function, FLIST gives an encrypted BBR value, logical +start address, and bank number. FLIST is a sort of global cheat sheet, located +in COMMON 0 so it is never mapped out, that describes every function's logical +and physical address. + +The linker replaces all mapped function calls with: + + ld hl,FLIST entry for the function + call remap_code + +The remap_code extracts pertinent data from the FLIST entry and remaps the MMU +as needed before branching to the function's logical address. + +The beauty of using an FLIST table is that pointers to functions will work - +the pointer becomes an FLIST pointer. With FLIST always mapped in, indirect +function invocations will work even to mapped functions. + +The Archimedes compiler does produce a good debugging file, which contains +useful information about the physical address of every function. The +information is stored in FLIST. A conversion routine easily extracts the real +physical address of each function, line number, and global symbol. +NOTE: IAR DOES NOT USE AN FLIST, BUT NICK IS PLANNING TO ADD AN FLIST OR +SIMILAR STRUCTURE FOR A "SHARED LIBRARY IMPLEMENTATION" - SO THAT UTILITY +ROUTINES SUCH AS LIBC CAN BE COMPILED IN ADVANCE AND MADE AVAILABLE AS A SHARED +EXECUTABLES, RATHER THAN HAVING TO BE STATICALLY LINKED INTO EVERY PROGRAM. + +Whitesmiths (733 Concord Ave., Cambridge, MA 02138, (617) 661-0072) took a +somewhat different approach to using the MMU. When writing C code for this +compiler, all calls to mapped functions must be specified as FAR calls. This +directs the compiler to generate the proper code to bring the function into the +map and execute it. + +The called function needs no special handling, since it can be called as either +a FAR or as a near. For example, if a function in one module invokes another +in the same module, it can use a conventional call structure. Only if a +different function, possibly located outside of this bank, calls the same +function, does the extra call overhead have to be inserted. + +A typical call sequence looks like: + + @far int sub(); + + main() + { + sub1(); + } + +The function is FAR in the definitions, and then all references to it within +that module generate banked calls. +NOTE: THIS IS SIMILAR TO THE OLD 'WINVEC' SYSTEM USED BY THE HYTECH OPERATING +SYSTEM PRIOR TO CMX/UZI. IT WAS QUITE NICE BEING ABLE TO CALL EACH SUBROUTINE +AS EITHER NEAR OR FAR DEPENDING ON WHERE YOU WERE CALLING FROM. BUT THERE'S A +PENALTY IN TERMS OF STACK SPACE AND IT DOESN'T LEND ITSELF TO STACK PARAMETERS. + +All banked calls do produce overhead, both in code size and speed. The +Whitesmiths approach eliminates the overhead in cases where it is not needed. +Archimedes, on the other hand, vectors all banked function calls through FLIST, +even if both the caller and callee are co-resident in BANK. +NOTE: THE IAR ICCZ80 ALSO DOES THIS: FUNCTIONS ARE SPECIFIED AS 'BANKED' +CALLING CONVENTION OR 'NON_BANKED' AND SO THE CORRECT CALLING CONVENTION HAS TO +BE USED REGARDLESS OF WHETHER THE FUNCTIONS HAPPEN TO BE IN THE SAME BANK. + +Whitesmiths uses the indirect linker command file to indicate the location of +every banked function. The programmer provides both the logical and physical +addresses of each of these functions. Again, the peril here is having to go +through iterative modifications of these parameters during development. + +To date, no compiler is smart enough to automatically set banked addresses. +Perhaps soon this will change. + +The compiler generates a call to library routine c.libc to do the bank +switching. Space is allocated on the stack for the return address and return +BBR. c.libc gets a "far pointer" to the function so it can reset BBR and the +logical address. + +Uniware, from Software Development Systems (4248 Belle Aire Lane, Downers +Grove, IL 60515 (800) 448-7733) implements bank switching by simulating linker +overlays. In other words, the compiler and linker are not even aware that the +64180 processor has an MMU; each mapped function appears to be an overlay. +NOTE: THIS IS SIMILAR TO THE SCHEME USED BY IAR, EXCEPT THAT IAR SIMULATES A +LARGE LINEAR ADDRESS SPACE IN WHICH ALL BANKED MODULES CAN BE LINKED TOGETHER. +A SPECIAL "BANKED SEGMENT" COMMAND TO THE LINKER INSTRUCTS IT TO PUT GAPS IN +THIS LARGE LINEAR ADDRESS SPACE SO LOGICAL AND PHYSICAL ADDRESSES ARE EQUAL. + +Like the other compilers, the IAR ICCZ80 compiler breaks memory into three +sections. Only the middle area is mapped dynamically. Your initialization +code must preset CBAR and CBR to their static values. + +The special pragma "#pragma function = {banked|non_banked}" specifies which +functions are to be mapped, and each function's logical address and BBR value +is determined by at link time. The compiler uses the following call sequence: + + ld hl, + ld a, + call ?BANKED_CALL_DIRECT_L08 + +_call is a low level routine in COMMON 0 that remaps the MMU and vectors off to +the function. + +You must give the linker much more information than for the Archimedes product, +so ICCZ80 is a bit harder to use. One of the nice side benefits of this +approach, though, is that it is directly applicable to Z80 bank switched +applications. You just have to modify the _call code to handle your +proprietary hardware. + +The Emulator + +In the embedded world generating code is only a small part of the development +battle. Somehow it must be tested and debugged. The only suitable tool for +embedded debugging code is an In Circuit Emulator, since only the emulator lets +you interactively isolate bugs in a ROMed environment. + +Like compilers, 64180 emulators are all basically extensions of technology +developed for the Z80. After all, the timing is similar and the software is +practically the same. Unfortunately, the extra four address bits found on the +64180 can cause lots of emulation problems. + +On a Z80 the logical and physical address space is the same. Not so for the +64180 - only by knowing the MMU values can the translation take place. It's +therefore crucial that the emulator can handle physical addresses, since only +physical ones never change. + +While this seems fairly obvious it can be difficult to implement. Emulators +use the 64180 for all target memory accesses, so the machine cycles are +identical to those expected with a processor in the socket. A translation from +desired physical address back to logical, CBAR, CBR, and BBR must take place, +since the 64180's code can only issue logical addresses. + +In other words, if memory at physical address 20000 is to be displayed, then +some routine has to figure out settings for all three MMU registers, plus a +logical address, that the 64180 can use to access the memory. Not a trivial +task. + +As users we don't care what the emulator does or how it works. All we're +concerned with is the debugging interface - the source level debugger (SLD) +that runs on a PC and communicates with the emulator over RS-232. If we type +DISPLAY SYMBOL FOO, then we want to see the value of FOO, no matter where it is +or how the MMU is setup. The SLD must therefore know about FOO's physical +address. + +Fortunately, all the products mentioned generate physical symbol addresses in +the debugging files. The SLD can send these values down to the emulator and +let it deal with coming up with the proper address. + +This does mean that the SLD/emulator interface is completely linear, like the +68000's. You can randomly access any location in the target's memory just by +typing in the right address. + +What if you wish to see a logical address? Is this important? Herein lies a +source of confusion. Only physical addresses unambiguously identify each +public symbol and line number. Your program works through logical addresses - +the two are not the same or even similar. Looking at disassembled code, you +might see a LD A,(1000). The 1000 is logical - its physical equivalent depends +on the current MMU mapping. + +Softaid's emulators get around this problem by letting you suffix any address +with a tilde to indicate that the logical address is needed, rather than the +default physical. Of course, the emulator will use the current MMU setting to +access the memory, so if the MMU is not set up as it would be when executing +that instruction, the data may not be correct. Normally this is not a problem +- you debug in your execution context, rather than randomly hunting through +code. + +64180 registers are 16 bits long. When used as pointers, they form logical +addresses, creating the same sort of problem just mentioned. Again, when +displaying the contents of a register pointer, that will be logical. If you +ask for a dump of memory at the address in HL, what will result? The correct +solution is to use indirect register references as logical (saving the bother +of suffixing a tilde all the time), since this is what the programmer really +wants. + +In C, an automatic pointer will be stored as a 16 bit value on the stack. +Suppose, while debugging, you wish to dump *ptr? In other words, display the +data pointed to by ptr, which is presumably on the stack. Again, only one +correct solution exists: get the stack pointer, convert it to physical using +the current MMU, extract the 16 bit value of ptr from the stack, make that +physical, and then access the destination address. + +Conclusion + +The 64180 family solves a long standing Z80 problem - that of handling more +memory. Lots of current Z80 applications can be easily ported to the 64180 to +take advantage of the larger memory model and high integration peripherals. +Don't try to get away with Z80-style development tools - select assemblers, +compilers, and debuggers that exploit the 64180's resources to ease your +development efforts. + +The Ganssle Group PO Box 38346, Baltimore, MD 21231 Email info@ganssle.com +(C) 2000,2001, 2002 The Ganssle Group + diff --git a/doc/z180-mem.txt b/doc/z180-mem.txt new file mode 100755 index 00000000..fb16fdae --- /dev/null +++ b/doc/z180-mem.txt @@ -0,0 +1,588 @@ +Z180 Memory Management + +The Z180 MMU is confusing, but quite useful when well understood. + +Published in Circuit Cellar Ink, February 1990 + +World Wide Web editor's note: This discussion of the MMU is still appropriate +today. Change the processor name from 64180 to Z180, as Zilog now dominates +this market, and change Archimedes (the compiler guys) to IAR, and most of the +article is still correct. + +Programs are getting big! Part of today's shift towards 16 and 32 bit +processors comes from the need for correspondingly huge address spaces, since +conventional wisdom holds that a 512kb program just cannot fit in the 64k +address space of most 8 bit CPUs. Where performance is the overriding concern, +a 32 bit CPU may be the only solution. It does seem a shame to abandon all the +accumulated knowledge and code gleaned from two decades of 8 bit +microprocessors just to get more programming elbow room. + +For the past few years some 8 bit CPUs have been equipped with memory +management units (MMU) that free programs from most memory limitations. It's +tedious and complex to control a MMU manually; now, many languages and other +tools include built-in MMU support. + +Logical -> Physical + +The problem of memory management is easy to define: we need some way of +connecting lots of memory to a processor that just cannot handle or address it. +For example, we might want to put 512kb on a Z80. Since the Z80 only generates +16 bit addresses, it can only directly address 64k of RAM. Somehow, though +memory management, we must expand this capability. + +For now let's assume that magic hardware gives us more address lines. Perhaps +it is as simple as an I/O port loaded by the CPU with an extra upper 8 address +lines (A16 to A23), giving us a potential address space of 24 mb. Or, it can +be hideously complex, providing some ability to access different sections of +address space in wild and wonderful ways. + +In any event, as soon as some external mechanism is added to translate +addresses in some fashion, the programmer suddenly must contend with two very +different sorts of address spaces. + +"Physical" memory is that actually connected to the hardware. For example, the +512kb we attach to the sadly-overloaded Z80 is physical memory. Its address +ranges from 00000 to 80000 hex in a linear manner. + +"Logical" memory is the memory currently located in the processor's address +space. Obviously, if the computer can only issue addresses in the range of +0000 to FFFF (0 to 64k), then some of the physical memory is visible and some +is not. As the code changes the memory manager's settings different memory +becomes visible. That which is addressable at any time is the logical memory. + +Thus, addresses generated by the program are always logical addresses - they +get translated by some yet undefined hardware into real physical addresses. + +So, at one time address 1000 logical might be translated into 28000 physical. +Later, in the same code, 1000 could correspond to 80000 physical. The old one +to-one mapping of addresses we're all familiar with is gone! + +In summary, addresses used by the code are logical; the memory array sees +physical. Between these two the memory management unit (MMU) falls. Standard +Architectures + +Several years ago Hitachi introduced the 64180, a high integration version of +the venerable Z80. While other vendors were trying to push new proprietary +architectures, Hitachi took what might seem a step backwards towards the Z80. +They realized an important fact of the industry - customers had a fortune +invested in Z80 code and were unwilling to switch to an incompatible +instruction set. + +The 64180 is a Z80 at heart. The designers resisted the temptation to add +fancy new instructions and addressing modes that could have made it +incompatible with the Z80. Rather, they integrated timers, serial ports, and +DMA controllers onto the chip. Even better, they added a memory management +unit to translate 64k logical addresses into a 1 mb physical address space. + +Now Hitachi sells several other versions of the part. The 64180S is designed +especially for telecommunications. The 647180X is a microcontroller version, +containing a 64180 core, ROM, RAM, and parallel I/O. Zilog stepped into the +act, offering the Z180 (a second source of the 64180) and Z280, a very high +performance Z80 upgrade. Zilog is just now announcing the Z181 and will soon +offer a microcontroller version of the part, probably a 647180X look-alike. + +The most important peripheral on the 64180-family processors is the memory +management unit (MMU). The MMU is a hardware device built onto the processor's +silicon. The MMU translates every memory address from 16 to 20 bits. + +The 64180's MMU uses three internal control registers. In keeping with the +chip's design philosophy, on reset the MMU gives a straight logical to physical +mapping, simulating the Z80 and, of course, limiting the address space to 64k. + +You can divide the 64180's logical address space into one, two, or three areas. +The logical space itself is unaltered; even when divided it is still a +contiguous 64k. + +CBAR is an 8 bit I/O port that can be accessed by the processor's OUT and IN +instructions. The lower 4 bits specify the starting address of the bank area, +and the upper 4 give the start of common 1. These bits determine the upper +four bits of the address. If CBAR were A8, then the base area starts at 8000 +logical, and common 1 starts at A000. + +Common 0, if it exists, always starts at logical 0000 and runs up to the bank +area. The bank area then runs to the start of common 1. + +Therefore, you can always understand the logical address space by examining the +contents of CBAR by itself. No other information is needed. + +The logical address is only part of the problem. How does logical space get +mapped to physical? Two other ports provide the rest of the answer. + +BBR (the Base Area Bank Register) specifies the starting physical address of +the base area (remember, the logical start is in CBAR). CBR (Common Bank +Register) provides the same information for common 1. Both of these specify +the upper 8 bits of the 20 bit physical address. + +A simple formula gives the translation from logical to physical address for the +bank area: + + Physical = Logical + (BBR * 4096) + +The same formula gives Common 1: + + Physical = Logical + (CBR * 4096) + +BBR and CBR gives the upper 8 address bit only - hence the 4096 multiplier. +The lower 12 bits come from the logical address. Thus, the translation only +affects the upper 8 bits; the lower 12 physical bits are always identical to +the lower 12 logical. + +On reset, the 64180 sets CBAR to F0, and CBR=BBR=0. This maps logical to +physical exactly, with no translation; the bank area starts at logical 0 and +common 1 at F000 (since CBAR=F0), the bank area physically starts at 0000 +(BBR=0), as does common 1 (CBR=0). If the logical address is 1000, then the +MMU allocates this to the bank area (CBAR=F0; 1000 is less than the start of +common 1 at F000), and adds the physical base of bank to it (0), giving a +translated address of 01000. Similarly, logical F800 is in common 1, and +translates to 0F800. + +The most important point that can be made about the MMU is that it does not +provide the 1mb linear address space we all crave. After all, Z80 instructions +use 16 bit address operands and 16 bit register pointers - there is no way to +address a number larger than 64k. A jump instruction will always have an +argument that is 16 bits long - the logical destination address. The MMU +translates this logical address to a possibly large physical number, but the +software still operates in a 64k space. + +This has a subtle implication - logical address space is a valuable commodity +that must be conserved. Wasting physical memory isn't so bad, since the 64180 +can deal with up to 1mb. As an example, suppose that your program will have +three banks (COMMON 0, BANK, and COMMON 1). If the program is large you might +want to bank it in and out of the BANK area, leaving COMMON 1 for data. If +BANK is too large, you could be left with little data space - it is important +to make BANK as small as feasible to maximize the (in this case) unbanked data. + +Language Support + +Despite the fabulous extra power offered by the 64180's MMU, we've all been +making do with Z80 assemblers and compilers. Sure, some claim to support the +new processor's extended features, but in truth, until recently, that support +has been minimal. + +Just what features are important in a 64180 assembler or compiler? Certainly it +should be fast, efficient, and all that, but more than anything else the +language should give you some sort of way of handling the MMU. + +There are two related but different aspects to MMU management. The first is to +provide some sort of mechanism to control the MMU with as little programer help +as possible. An ideal solution would be a smart compiler that simulates a +nearly linear huge address space. The second is to provide output files that +contain compiled code and debugging records in some manner that supports +current 8 bit tools (like the PROM programmer), but that accounts for the large +address spaces. + +Taking these two criterion separately, especially with a C compiler we'd really +like some method of compiling an ordinary C program in multiple banks. Sure, +you might have to tell the compiler or linker about your memory configuration, +but ideally the tools should segment and package functions into memory banks as +needed. Even better, we'd want it to remap the MMU automatically. Just like +working with Turbo C, we would like to be able to invoke a function through a +conventional function call, without worrying about its location in memory. + +The second requirement is not quite so obvious. How will you burn ROMs for the +final project? If the compiled/assembled code exceeds 64k, there may be a +problem with using standard Intel hex records for output. Every ROM programmer +in the world takes Intel hex input, but the format only supports 16 bit +addresses. + +One solution is to divide the source program into many separately compiled +small pieces. This is especially hard in C, since the linker will not be able +to resolve calls between pieces. Another approach is to insure that the +compiler or assembler can produce "Type 2" Intel records. Whenever the code +crosses a 64k bank the linker could output a type 2 record to specify a new +segment address (physical address shifted right 4 bits). This does imply that +the linker can handle large physical addresses, and the PROM programmer can +accept type 2 records. + +Decent debugging files are just as important as useful PROM files. You can't +use an emulator, simulator, or monitor to debug the code if the debug records +are inadequate. Suppose you wish to display the value of a variable. The +debugger must know the physical address of that quantity, since only the +physical address is constant. Remapping the MMU changes its logical address, +and at times no logical address might correspond to the variable. + +This implies that the software packages must maintain both logical and physical +addresses for all lines and symbols. Compiling, say, jumps requires logical +addresses. All jumps and calls take logical addresses as arguments (since they +can only support a 16 bit number). Physical addresses are needed in the +debugging records so debuggers can unambiguously resolve the location of +symbols, functions, and line numbers, all whose logical address changes with +the current MMU setting. + +Assemblers + +Most 64180 programs written in assembly language control the memory manager by +tediously issuing many MMU control instructions. The programmer must first +decide exactly what configuration logical memory will assume, and then come up +with CBAR, BBR, and CBR values for every possible combination of banks. Then, +the code must send these values out to change maps. Needless to say, this +takes a lot of work. + +Softools (8770 Manahan Drive, Ellicott City, MD 21043, (301) 750-3733) came up +with an interesting approach that eliminates most of the work. Their SASM +assembler and linker will automatically drop in all the code needed to bank a +program. In effect, this means you can write code as if the 64180 had a 1 mb +linear address space. + +Like most good assemblers, SASM supports lots of named segments - up to 256. +Most of the time we assembly programmers just need a CODE, DATA, and ASEG +segment, but SASM's segmentation lets us break a program into mapped and +unmapped sections. When using SASM on large programs, you can assign any +segment or segments to have a "mapped" attribute, identifying those that +require some MMU manipulation to bring them into the address space. +NOTE: SASM IS QUITE SIMILAR TO IAR'S AZ80 ASSEMBLER, SO CHANGED SASM TO AZ80 +IN THE FOLLOWING DISCUSSION. HOWEVER, AZ80 USES THE SEGMENT NAME 'CODE' FOR +ALL BANKED CODE, KNOWING THAT THE SEGMENT'S CODE CAN BE SPLIT INTO BANKS WHERE +THERE IS A MODULE BOUNDARY. SO ACCESSES OUTSIDE THE MODULE MUST USE BANKED +CALLING CONVENTIONS!! WITHIN THE MODULE THERE IS SOME FREEDOM TO USE PRIVATE +ROUTINES WITH THEIR OWN CALLING CONVENTIONS (AS YOU KNOW EACH MODULE FITS INTO +A BANK AND CAN'T SPAN MULTIPLE BANKS). USE THE LWRD OPERATOR WHEN DOING THIS. + +Segments are the key to IAR AZ80's mapping scheme. The linker identifies how +much data the program uses and the number of bytes used for unmapped code (that +which must never be mapped out). It computes CBAR to define the +characteristics of the runtime logical address space: COMMON 0 being just big +enough to hold all the unmapped code, COMMON 1 containing the data, and the +rest, the BANK area, is allocated to mapped routines. + +The linker groups all mapped segments together and starts to assign both +logical and physical addresses to each routine. Whenever a routine will exceed +the size of the BANK area the linker moves it to the start of a new BANK area. +It then converts all jumps and calls between banked areas to transfers to code +that manages the MMU in COMMON 0. + +When finally linked, the program has three parts - a COMMON 0 non-mapped (i.e., +always in the address space) area which typically contains startup code, +frequently-used routines, and AZ80's banking code. COMMON 1 is usually your +data area. The BANK area contains most of the program code. Calls between +these banked routines will cause remapping as needed to bring in ones that are +not currently visible in the address space. + +For example, suppose the program is as follows: + + routine length characteristics + main 3700h not banked + vectors 80h not banked + sub1 4000h banked + sub2 38f0h banked + sub3 1200h banked + sub4 6f00h banked + sub5 800h banked + data 3200h not banked + +On a 64180 the reset jump is at 0, so it makes sense to put the unbanked code +(vectors and main) at 0. The data area cannot be banked (especially the +stack!) and is traditionally in high memory. Suppose the code that starts at +physical location 0 is to go into ROM, and the data that starts at physical +40000h is in RAM. The linker will first divide the logical address space based +on the unmapped memory requirements: main and vectors need 3780h bytes starting +at location 0, and data occupies 3200h at the end of the logical space. +Bearing in mind that the mapping resolution of the 64180 is 4k, memory thus +looks like: + + Logical Physical Area + 0000 00000 unbanked (main and vectors) + 4000 04000 start of banked routines + c000 40000 start of RAM data + +All the logical address space from 4000 to bfff is available to routines that +can be banked. If the sum of the banked sizes is less than the BANK logical +area, then no mapping need take place. In our example, however, banked +routines need some 64k, much more than the available logical space. If CBAR is +C4 (COMMON 1 at c000 and BANK at 4000), AZ80 will assign addresses as follows: + + Logical Physical Routine length BBR + 0000 00000 main 3700 -- + 3780 03780 vectors 80 -- + 4000 04000 sub1 4000 00 + 8000 08000 sub2 38f0 00 + 4000 0c000 sub3 1200 08 + 4000 0e000 sub4 6f00 0a + af00 14f00 sub5 800 0a + c000 40000 data 3200 -- + +For sub1 AZ80 assigned a logical and physical address of 4000 - reasonable, +since this is the first free spot after COMMON 0. sub1 is in BANK, so a BBR +value is required. BBR=0 will map 4000 to 04000. sub2 follows sub1, again +with BBR=0. So far, no surprises. + +sub2 ends at b8f0, practically right before the logical start of data (c000). +There is no way sub3 can fit, since sub3 is 1200 bytes long. AZ80 therefore +put sub3 at logical address 4000 (the same as sub1). sub3 follows in physical +memory at 0c000 (the next physical address rounded up to a 4k boundary). BBR +equals 08. sub1 and sub3 occupy the same place in logical address space +(4000), but different physical addresses. To get to sub3, BBR must be set to +08 and a logical address of 4000 issued. + +While sub3 is very short, leaving plenty of room for code in the same bank map, +sub4 is not. sub3 and sub4 will not both fit into BANK together, so AZ80 once +again reset the logical address to 4000. sub4 comes after sub3, rounded up 4k, +and a BBR of 0a is assigned. (Remember the math - BBR * 4096 + logical = +physical, so 0a * 4096 + 4000 = e000). sub5 fits into the space between the +end of sub4 and COMMON 1, and is so assigned. + +IAR XLINK generates address assignments as we've just seen, but how are calls +and jumps between subroutines handled? Obviously, if sub1, sub3, and sub4 all +reside at logical address 4000, a simple CALL 4000 will not always resolve +properly. As mentioned earlier, XLINK converts all inter-BANK calls and jumps +to a transfer to a jump table which is usually linked into COMMON 0. In +particular, if sub4 were to call sub1, the following will be automatically +substituted for the call instruction: + + call bank_table+x ; invoke MMU handler + db BBR ; BBR of sub1 + DW sub1 ; address of routine to call + +The code in bank_table stores the current BBR value and return address on a +local stack, remaps the MMU by outputting the indicated BBR, and then transfers +to the logical address supplied as a parameter. Returns operate in a reverse +procedure, being vectored to another Softools-supplied routine to reverse the +mapping. + +What might not be entirely obvious is that AZ80 does it all. Once you tell +XLINK where ROM and RAM are (which has to be done for any linker) it +automatically allocates logical and physical addresses. The linker also +replaces the calls and jumps as shown above. AZ80 does offer options to +control memory allocation and the like, but in most cases these are not needed. + +This means that you can write large programs without ever considering the MMU. +AZ80 takes care of it all. There's an interesting subtle implication - you can +link a 256k program to take up only 8k or so of logical space! Assign 4k for +COMMON 0 and 56k for data. AZ80 will bravely partition the 256k code into 50 +or more sections, each of which will get remapped through the 4k BANK area. +The mapping overhead might get high, but logical address space will be +conserved. + +Since AZ80 partitions the program during the link phase, it can save the +addresses of all symbols, line numbers and other parameters in a debug file. +Symbols' physical addresses are stored in the debug file, maintaining true +addresses regardless of the MMU mapping. If the debugger (emulator or monitor) +can handle physical addresses, then you can access any routine, variable, or +source line number at any time, without manually remapping to bring the desired +value into logical address space. + +C Compilers + +As we write this, only three compilers currently support 64180 bank switching. +Archimedes Software's C180, Whitesmiths' C, and Software Development System's C +all automatically generate code for large memory models. Manx (MANX Software +Systems, P.O. Box 55, Shrewsbury, NJ 07701) will soon have a compiler, and no +doubt others are on the way. + +Archimedes (2159 Union Street, San Francisco, CA, 94123 (415) 567-4010) +approach to memory management is much like that used by AZ80. As you write +your C code you do not need to be especially concerned with the MMU. There are +no special procedures to use or functions to invoke. + +Before linking the compiled object files various parameters must be passed to +the linker in its indirect command file. The first are values for CBAR and +CBR. It is the programmer's responsibility to determine exactly the memory +configuration, and to compute these simple values. +NOTE: THE IAR ICCZ80 WORKS LIKE THIS. FOR THE MOMENT THE VALUES ARE HARD +CODED BUT THE DEFAULT SETUP PROVIDED BY IAR ALLOWS YOU TO PASS THEM IN THE +LINKER CONTROL FILE. OUR CSTARTUP IS HEAVILY CUSTOMISED SO I DIDN'T BOTHER. + +In addition to the MMU register settings, the programmer must provide the +linker with a table of modules (i.e., file of source code, each of which may +contain several functions) and names. If the module is not to be banked, that +must be indicated as well. +NOTE: THE IAR XLINK DETERMINES AUTOMATICALLY WHICH FUNCTIONS ARE BANKED AND +WHICH ARE NON_BANKED USING INFORMATION EMBEDDED IN THE OBJECT FILES. BANKED +AND NON_BANKED CALLING SEQUENCES HAVE BEEN DETERMINED AT COMPILE TIME, SO THE +LINKER DOESN'T NEED ANY SPECIAL SYMBOL TABLE INFORMATION TO DO ITS WORK. + +The memory model supported by the compiler puts all non-banked functions into +COMMON 0, the banked code into BANK, and data areas into COMMON 1. +NOTE: THIS IS IDENTICAL TO IAR'S SCHEME WHICH WE ARE USING FOR HYTECH CMX/UZI. + +The linker generates a table ("FLIST") of data about every mapped function in +the program. For each function, FLIST gives an encrypted BBR value, logical +start address, and bank number. FLIST is a sort of global cheat sheet, located +in COMMON 0 so it is never mapped out, that describes every function's logical +and physical address. + +The linker replaces all mapped function calls with: + + ld hl,FLIST entry for the function + call remap_code + +The remap_code extracts pertinent data from the FLIST entry and remaps the MMU +as needed before branching to the function's logical address. + +The beauty of using an FLIST table is that pointers to functions will work - +the pointer becomes an FLIST pointer. With FLIST always mapped in, indirect +function invocations will work even to mapped functions. + +The Archimedes compiler does produce a good debugging file, which contains +useful information about the physical address of every function. The +information is stored in FLIST. A conversion routine easily extracts the real +physical address of each function, line number, and global symbol. +NOTE: IAR DOES NOT USE AN FLIST, BUT NICK IS PLANNING TO ADD AN FLIST OR +SIMILAR STRUCTURE FOR A "SHARED LIBRARY IMPLEMENTATION" - SO THAT UTILITY +ROUTINES SUCH AS LIBC CAN BE COMPILED IN ADVANCE AND MADE AVAILABLE AS A SHARED +EXECUTABLES, RATHER THAN HAVING TO BE STATICALLY LINKED INTO EVERY PROGRAM. + +Whitesmiths (733 Concord Ave., Cambridge, MA 02138, (617) 661-0072) took a +somewhat different approach to using the MMU. When writing C code for this +compiler, all calls to mapped functions must be specified as FAR calls. This +directs the compiler to generate the proper code to bring the function into the +map and execute it. + +The called function needs no special handling, since it can be called as either +a FAR or as a near. For example, if a function in one module invokes another +in the same module, it can use a conventional call structure. Only if a +different function, possibly located outside of this bank, calls the same +function, does the extra call overhead have to be inserted. + +A typical call sequence looks like: + + @far int sub(); + + main() + { + sub1(); + } + +The function is FAR in the definitions, and then all references to it within +that module generate banked calls. +NOTE: THIS IS SIMILAR TO THE OLD 'WINVEC' SYSTEM USED BY THE HYTECH OPERATING +SYSTEM PRIOR TO CMX/UZI. IT WAS QUITE NICE BEING ABLE TO CALL EACH SUBROUTINE +AS EITHER NEAR OR FAR DEPENDING ON WHERE YOU WERE CALLING FROM. BUT THERE'S A +PENALTY IN TERMS OF STACK SPACE AND IT DOESN'T LEND ITSELF TO STACK PARAMETERS. + +All banked calls do produce overhead, both in code size and speed. The +Whitesmiths approach eliminates the overhead in cases where it is not needed. +Archimedes, on the other hand, vectors all banked function calls through FLIST, +even if both the caller and callee are co-resident in BANK. +NOTE: THE IAR ICCZ80 ALSO DOES THIS: FUNCTIONS ARE SPECIFIED AS 'BANKED' +CALLING CONVENTION OR 'NON_BANKED' AND SO THE CORRECT CALLING CONVENTION HAS TO +BE USED REGARDLESS OF WHETHER THE FUNCTIONS HAPPEN TO BE IN THE SAME BANK. + +Whitesmiths uses the indirect linker command file to indicate the location of +every banked function. The programmer provides both the logical and physical +addresses of each of these functions. Again, the peril here is having to go +through iterative modifications of these parameters during development. + +To date, no compiler is smart enough to automatically set banked addresses. +Perhaps soon this will change. + +The compiler generates a call to library routine c.libc to do the bank +switching. Space is allocated on the stack for the return address and return +BBR. c.libc gets a "far pointer" to the function so it can reset BBR and the +logical address. + +Uniware, from Software Development Systems (4248 Belle Aire Lane, Downers +Grove, IL 60515 (800) 448-7733) implements bank switching by simulating linker +overlays. In other words, the compiler and linker are not even aware that the +64180 processor has an MMU; each mapped function appears to be an overlay. +NOTE: THIS IS SIMILAR TO THE SCHEME USED BY IAR, EXCEPT THAT IAR SIMULATES A +LARGE LINEAR ADDRESS SPACE IN WHICH ALL BANKED MODULES CAN BE LINKED TOGETHER. +A SPECIAL "BANKED SEGMENT" COMMAND TO THE LINKER INSTRUCTS IT TO PUT GAPS IN +THIS LARGE LINEAR ADDRESS SPACE SO LOGICAL AND PHYSICAL ADDRESSES ARE EQUAL. + +Like the other compilers, the IAR ICCZ80 compiler breaks memory into three +sections. Only the middle area is mapped dynamically. Your initialization +code must preset CBAR and CBR to their static values. + +The special pragma "#pragma function = {banked|non_banked}" specifies which +functions are to be mapped, and each function's logical address and BBR value +is determined by at link time. The compiler uses the following call sequence: + + ld hl, + ld a, + call ?BANKED_CALL_DIRECT_L08 + +_call is a low level routine in COMMON 0 that remaps the MMU and vectors off to +the function. + +You must give the linker much more information than for the Archimedes product, +so ICCZ80 is a bit harder to use. One of the nice side benefits of this +approach, though, is that it is directly applicable to Z80 bank switched +applications. You just have to modify the _call code to handle your +proprietary hardware. + +The Emulator + +In the embedded world generating code is only a small part of the development +battle. Somehow it must be tested and debugged. The only suitable tool for +embedded debugging code is an In Circuit Emulator, since only the emulator lets +you interactively isolate bugs in a ROMed environment. + +Like compilers, 64180 emulators are all basically extensions of technology +developed for the Z80. After all, the timing is similar and the software is +practically the same. Unfortunately, the extra four address bits found on the +64180 can cause lots of emulation problems. + +On a Z80 the logical and physical address space is the same. Not so for the +64180 - only by knowing the MMU values can the translation take place. It's +therefore crucial that the emulator can handle physical addresses, since only +physical ones never change. + +While this seems fairly obvious it can be difficult to implement. Emulators +use the 64180 for all target memory accesses, so the machine cycles are +identical to those expected with a processor in the socket. A translation from +desired physical address back to logical, CBAR, CBR, and BBR must take place, +since the 64180's code can only issue logical addresses. + +In other words, if memory at physical address 20000 is to be displayed, then +some routine has to figure out settings for all three MMU registers, plus a +logical address, that the 64180 can use to access the memory. Not a trivial +task. + +As users we don't care what the emulator does or how it works. All we're +concerned with is the debugging interface - the source level debugger (SLD) +that runs on a PC and communicates with the emulator over RS-232. If we type +DISPLAY SYMBOL FOO, then we want to see the value of FOO, no matter where it is +or how the MMU is setup. The SLD must therefore know about FOO's physical +address. + +Fortunately, all the products mentioned generate physical symbol addresses in +the debugging files. The SLD can send these values down to the emulator and +let it deal with coming up with the proper address. + +This does mean that the SLD/emulator interface is completely linear, like the +68000's. You can randomly access any location in the target's memory just by +typing in the right address. + +What if you wish to see a logical address? Is this important? Herein lies a +source of confusion. Only physical addresses unambiguously identify each +public symbol and line number. Your program works through logical addresses - +the two are not the same or even similar. Looking at disassembled code, you +might see a LD A,(1000). The 1000 is logical - its physical equivalent depends +on the current MMU mapping. + +Softaid's emulators get around this problem by letting you suffix any address +with a tilde to indicate that the logical address is needed, rather than the +default physical. Of course, the emulator will use the current MMU setting to +access the memory, so if the MMU is not set up as it would be when executing +that instruction, the data may not be correct. Normally this is not a problem +- you debug in your execution context, rather than randomly hunting through +code. + +64180 registers are 16 bits long. When used as pointers, they form logical +addresses, creating the same sort of problem just mentioned. Again, when +displaying the contents of a register pointer, that will be logical. If you +ask for a dump of memory at the address in HL, what will result? The correct +solution is to use indirect register references as logical (saving the bother +of suffixing a tilde all the time), since this is what the programmer really +wants. + +In C, an automatic pointer will be stored as a 16 bit value on the stack. +Suppose, while debugging, you wish to dump *ptr? In other words, display the +data pointed to by ptr, which is presumably on the stack. Again, only one +correct solution exists: get the stack pointer, convert it to physical using +the current MMU, extract the 16 bit value of ptr from the stack, make that +physical, and then access the destination address. + +Conclusion + +The 64180 family solves a long standing Z80 problem - that of handling more +memory. Lots of current Z80 applications can be easily ported to the 64180 to +take advantage of the larger memory model and high integration peripherals. +Don't try to get away with Z80-style development tools - select assemblers, +compilers, and debuggers that exploit the 64180's resources to ease your +development efforts. + +The Ganssle Group PO Box 38346, Baltimore, MD 21231 Email info@ganssle.com +(C) 2000,2001, 2002 The Ganssle Group + diff --git a/include/!readme! b/include/!readme! new file mode 100755 index 00000000..9c2eaa15 --- /dev/null +++ b/include/!readme! @@ -0,0 +1,10 @@ +UZIX library - header files + +The header files for UZIX library were taken, adapted and inspired in many +sources, from free implementations to comercial products. Since header +files of C libraries seems to be a common thing, these are all in public +domain. + +Adriano Cunha, 12/07/2001 +http://uzix.msx.org + diff --git a/include/alloc.h b/include/alloc.h new file mode 100755 index 00000000..e396a264 --- /dev/null +++ b/include/alloc.h @@ -0,0 +1,3 @@ +#ifndef __MALLOC_H +#include +#endif diff --git a/include/ar.h b/include/ar.h new file mode 100755 index 00000000..67394111 --- /dev/null +++ b/include/ar.h @@ -0,0 +1,18 @@ +#ifndef __AR_H +#define __AR_H + +#define ARMAG "!\n" +#define SARMAG 8 +#define ARFMAG "`\n" + +struct ar_hdr { + char ar_name[16], + ar_date[12], + ar_uid[6], + ar_gid[6], + ar_mode[8], + ar_size[10], + ar_fmag[2]; +}; + +#endif /* __AR_H */ diff --git a/include/assert.h b/include/assert.h new file mode 100755 index 00000000..cedfddb8 --- /dev/null +++ b/include/assert.h @@ -0,0 +1,27 @@ +#ifndef __ASSERT_H +#define __ASSERT_H +#ifndef __TYPES_H +#include +#endif + +/* ANSI compilers only version ! */ + +/* If NDEBUG is defined, do nothing. + If not, and EXPRESSION is zero, print an error message and abort. */ + +#ifdef NDEBUG + +#define assert(expr) ((void) 0) + +#else /* NDEBUG */ + +extern void __assert __P((char *, char *, int)); + +#define assert(expr) \ + ((void) ((expr) || (__assert (__STRING(expr), __FILE__, __LINE__), 0))) + +#endif /* NDEBUG */ + +extern void __errput __P((char *)); + +#endif /* __ASSERT_H */ diff --git a/include/ctype.h b/include/ctype.h new file mode 100755 index 00000000..7e675544 --- /dev/null +++ b/include/ctype.h @@ -0,0 +1,88 @@ +/* ctype.h Character classification and conversion + */ +#ifndef __CTYPE_H +#define __CTYPE_H + +#ifdef _MSX_DOS /* HI-TECH-C/MSX-DOS CTYPE.H */ + +#define _U 0x01 +#define _L 0x02 +#define _N 0x04 +#define _S 0x08 +#define _P 0x10 +#define _C 0x20 +#define _X 0x40 + +#if 1 /* Nick */ +extern unsigned char __ctype[]; + /* in libc.lib */ +#else +extern unsigned char _ctype_[]; + /* in libc.lib */ +#endif + +#define isalpha(c) ((_ctype_+1)[c]&(_U|_L)) +#define isupper(c) ((_ctype_+1)[c]&_U) +#define islower(c) ((_ctype_+1)[c]&_L) +#define isdigit(c) ((_ctype_+1)[c]&_N) +#define isxdigit(c) ((_ctype_+1)[c]&(_N|_X)) +#define isspace(c) ((_ctype_+1)[c]&_S) +#define ispunct(c) ((_ctype_+1)[c]&_P) +#define isalnum(c) ((_ctype_+1)[c]&(_U|_L|_N)) +#define isprint(c) ((_ctype_+1)[c]&(_P|_U|_L|_N|_S)) +#define isgraph(c) ((_ctype_+1)[c]&(_P|_U|_L|_N)) +#define iscntrl(c) ((_ctype_+1)[c]&_C) +#define isascii(c) (!((c)&0xFF80)) +#define toascii(c) ((c)&0x7F) + +extern char toupper(char); +extern char tolower(char); +extern char * strupr(char *); +extern char * strlwr(char *); + +#else /* UZIX-hosted CTYPE.H */ + +extern unsigned char __ctype[]; + +#define __CT_c 0x01 /* control character */ +#define __CT_u 0x02 /* upper case */ +#define __CT_l 0x04 /* lower case */ +#define __CT_d 0x08 /* numeric digit */ +#define __CT_s 0x10 /* whitespace */ +#define __CT_p 0x20 /* punctuation */ +#define __CT_x 0x40 /* hexadecimal */ + +#define __CT_a (__CT_u|__CT_l) /* alpha */ + +/* always functions ! */ +extern int toupper __P((int)); +extern int tolower __P((int)); + +#define _toupper(c) (islower(c) ? (c)^0x20 : (c)) +#define _tolower(c) (isupper(c) ? (c)^0x20 : (c)) +#define __toupper(c) ((c)^0x20) +#define __tolower(c) ((c)^0x20) +#define toascii(c) ((c)&0x7F) + +#define _CTYPE(c) (__ctype[(unsigned char)(c)]) + +/* Note the '!!' is a cast to 'bool' and even BCC deletes it in an if() */ +#define isascii(c) (!((c)&~0x7F)) +#define isalnum(c) (!!(_CTYPE(c)&(__CT_a|__CT_d))) +#define isalpha(c) (!!(_CTYPE(c)&__CT_a)) +#define iscntrl(c) (!!(_CTYPE(c)&__CT_c)) +#define isdigit(c) (!!(_CTYPE(c)&__CT_d)) +#define isgraph(c) (! (_CTYPE(c)&(__CT_c|__CT_s))) +#define islower(c) (!!(_CTYPE(c)&__CT_l)) +#define isprint(c) (! (_CTYPE(c)&__CT_c)) +#define ispunct(c) (!!(_CTYPE(c)&__CT_p)) +#define isspace(c) (!!(_CTYPE(c)&__CT_s)) +#define isupper(c) (!!(_CTYPE(c)&__CT_u)) +#define isxdigit(c) (!!(_CTYPE(c)&__CT_x)) + +#define isdecimal(c) isdigit(c) +#define isoctal(c) ((c) >= '0' && (c) <= '7') + +#endif /* END OF CTYPE.H DEFINITION */ + +#endif /* __CTYPE_H */ diff --git a/include/curses.h b/include/curses.h new file mode 100755 index 00000000..3badca89 --- /dev/null +++ b/include/curses.h @@ -0,0 +1,229 @@ +/* curses.h - defines macros and prototypes for curses */ + +#ifndef CURSES_H + +#define _BIG_MACHINE_ + +#include +#include +#include + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +typedef int bool; + +#define TRUE 1 +#define FALSE 0 +#define ERR 1 /* general error flag */ +#define OK 0 /* general OK flag */ + +/* Macros. */ +#define box(win,vc,hc) wbox(win,0,0,0,0,vc,hc) +#define addch(ch) waddch(stdscr,ch) +#define mvaddch(y,x,ch) (wmove(stdscr,y,x)==ERR?ERR:waddch(stdscr,ch)) +#define mvwaddch(win,y,x,ch) (wmove(win,y,x)==ERR?ERR:waddch(win,ch)) +#define getch() wgetch(stdscr) +#define mvgetch(y,x) (wmove(stdscr,y,x)==ERR?ERR:wgetch(stdscr)) +#define mvwgetch(win,y,x) (wmove(win,y,x)==ERR?ERR:wgetch(win)) +#define addstr(str) waddstr(stdscr,str) +#define mvaddstr(y,x,str) (wmove(stdscr,y,x)==ERR?ERR:waddstr(stdscr,str)) +#define mvwaddstr(win,y,x,str) (wmove(win,y,x)==ERR?ERR:waddstr(win,str)) +#define getstr(str) wgetstr(stdscr,str) +#define mvgetstr(y,x,str) (wmove(stdscr,y,x)==ERR?ERR:wgetstr(stdscr,str)) +#define mvwgetstr(win,y,x,str) (wmove(win,y,x)==ERR?ERR:wgetstr(win,str)) +#define move(y,x) wmove(stdscr,y,x) +#define clear() wclear(stdscr) +#define erase() werase(stdscr) +#define clrtobot() wclrtobot(stdscr) +#define mvclrtobot(y,x) (wmove(stdscr,y,x)==ERR?ERR:wclrtobot(stdscr)) +#define mvwclrtobot(win,y,x) (wmove(win,y,x)==ERR?ERR:wclrtobot(win)) +#define clrtoeol() wclrtoeol(stdscr) +#define mvclrtoeol(y,x) (wmove(stdscr,y,x)==ERR?ERR:wclrtoeol(stdscr)) +#define mvwclrtoeol(win,y,x) (wmove(win,y,x)==ERR?ERR:wclrtoeol(win)) +#define insertln() winsertln(stdscr) +#define mvinsertln(y,x) (wmove(stdscr,y,x)==ERR?ERR:winsertln(stdscr)) +#define mvwinsertln(win,y,x) (wmove(win,y,x)==ERR?ERR:winsertln(win)) +#define deleteln() wdeleteln(stdscr) +#define mvdeleteln(y,x) (wmove(stdscr,y,x)==ERR?ERR:wdeleteln(stdscr)) +#define mvwdeleteln(win,y,x) (wmove(win,y,x)==ERR?ERR:wdeleteln(win)) +#define refresh() wrefresh(stdscr) +#define inch() winch(stdscr) +#define insch(ch) winsch(stdscr,ch) +#define mvinsch(y,x,ch) (wmove(stdscr,y,x)==ERR?ERR:winsch(stdscr,ch)) +#define mvwinsch(win,y,x,ch) (wmove(win,y,x)==ERR?ERR:winsch(win,ch)) +#define delch() wdelch(stdscr) +#define mvdelch(y,x) (wmove(stdscr,y,x)==ERR?ERR:wdelch(stdscr)) +#define mvwdelch(win,y,x) (wmove(win,y,x)==ERR?ERR:wdelch(win)) +#define standout() wstandout(stdscr) +#define wstandout(win) (win)->_attrs |= A_STANDOUT +#define standend() wstandend(stdscr) +#define wstandend(win) (win)->_attrs &= ~A_STANDOUT +#define attrset(attrs) wattrset(stdscr, attrs) +#define wattrset(win, attrs) (win)->_attrs = (attrs) +#define attron(attrs) wattron(stdscr, attrs) +#define wattron(win, attrs) (win)->_attrs |= (attrs) +#define attroff(attrs) wattroff(stdscr,attrs) +#define wattroff(win, attrs) (win)->_attrs &= ~(attrs) +#define resetty() stty(1, &_orig_tty) +#define getyx(win,y,x) (y = (win)->_cury, x = (win)->_curx) + +/* Video attribute definitions. */ +#define A_BLINK 0x0100 +#define A_BLANK 0 +#define A_BOLD 0x0200 +#define A_DIM 0 +#define A_PROTECT 0 +#define A_REVERSE 0x0400 +#define A_STANDOUT 0x0800 +#define A_UNDERLINE 0x1000 +#define A_ALTCHARSET 0x2000 + +/* Type declarations. */ +typedef struct { + int _cury; /* current pseudo-cursor */ + int _curx; + int _maxy; /* max coordinates */ + int _maxx; + int _begy; /* origin on screen */ + int _begx; + int _flags; /* window properties */ + int _attrs; /* attributes of written characters */ + int _tabsize; /* tab character size */ + bool _clear; /* causes clear at next refresh */ + bool _leave; /* leaves cursor as it happens */ + bool _scroll; /* allows window scrolling */ + bool _nodelay; /* input character wait flag */ + bool _keypad; /* flags keypad key mode active */ + int **_line; /* pointer to line pointer array */ + int *_minchng; /* First changed character in line */ + int *_maxchng; /* Last changed character in line */ + int _regtop; /* Top/bottom of scrolling region */ + int _regbottom; +} WINDOW; + +/* External variables */ +extern int LINES; /* terminal height */ +extern int COLS; /* terminal width */ +extern bool NONL; /* \n causes CR too ? */ +extern WINDOW *curscr; /* the current screen image */ +extern WINDOW *stdscr; /* the default screen window */ +extern struct sgttyb _orig_tty, _tty; + +extern unsigned int ACS_ULCORNER; /* terminal dependent block grafic */ +extern unsigned int ACS_LLCORNER; /* charcters. Forget IBM, we are */ +extern unsigned int ACS_URCORNER; /* independent of their charset. :-) */ +extern unsigned int ACS_LRCORNER; +extern unsigned int ACS_RTEE; +extern unsigned int ACS_LTEE; +extern unsigned int ACS_BTEE; +extern unsigned int ACS_TTEE; +extern unsigned int ACS_HLINE; +extern unsigned int ACS_VLINE; +extern unsigned int ACS_PLUS; +extern unsigned int ACS_S1; +extern unsigned int ACS_S9; +extern unsigned int ACS_DIAMOND; +extern unsigned int ACS_CKBOARD; +extern unsigned int ACS_DEGREE; +extern unsigned int ACS_PLMINUS; +extern unsigned int ACS_BULLET; +extern unsigned int ACS_LARROW; +extern unsigned int ACS_RARROW; +extern unsigned int ACS_DARROW; +extern unsigned int ACS_UARROW; +extern unsigned int ACS_BOARD; +extern unsigned int ACS_LANTERN; +extern unsigned int ACS_BLOCK; + +#ifdef _BIG_MACHINE_ +_PROTOTYPE( char *unctrl, (int _c) ); +_PROTOTYPE( int baudrate, (void)); +_PROTOTYPE( void beep, (void)); +_PROTOTYPE( void cbreak, (void)); +_PROTOTYPE( void clearok, (WINDOW *_win, bool _flag) ); +_PROTOTYPE( void clrscr, (void)); +_PROTOTYPE( void curs_set, (int _visibility) ); +_PROTOTYPE( void delwin, (WINDOW *_win) ); +_PROTOTYPE( void doupdate, (void)); +_PROTOTYPE( void echo, (void)); +_PROTOTYPE( int endwin, (void)); +_PROTOTYPE( int erasechar, (void)); +_PROTOTYPE( void fatal, (char *_s) ); +_PROTOTYPE( int fixterm, (void)); +_PROTOTYPE( void flash, (void)); +_PROTOTYPE( int gettmode, (void)); +_PROTOTYPE( void idlok, (WINDOW *_win, bool _flag) ); +_PROTOTYPE( WINDOW *initscr, (void)); +_PROTOTYPE( void keypad, (WINDOW *_win, bool _flag) ); +_PROTOTYPE( int killchar, (void)); +_PROTOTYPE( void leaveok, (WINDOW *_win, bool _flag) ); +_PROTOTYPE( char *longname, (void)); +_PROTOTYPE( void meta, (WINDOW *_win, bool _flag) ); +_PROTOTYPE( int mvcur, (int _oldy, int _oldx, int _newy, int _newx) ); +_PROTOTYPE( int mvinch, (int _y, int _x) ); +_PROTOTYPE( int mvprintw, (int _y, int _x, char *_fmt, ...) ); +_PROTOTYPE( int mvscanw, (int _y, int _x, char *_fmt, char *_A1, int _A2, + int _A3, int _A4, int _A5) ); +_PROTOTYPE( int mvwin, (WINDOW *_win, int _begy, int _begx) ); +_PROTOTYPE( int mvwinch, (WINDOW *_win, int _y, int _x) ); +_PROTOTYPE( int mvwprintw, (WINDOW *_win, int _y, int _x, char *_fmt, ...) ); +_PROTOTYPE( int mvwscanw, (WINDOW *_win, int _y, int _x, char *_fmt, char *_A1, + int _A2, int _A3, int _A4, int _A5) ); +_PROTOTYPE( WINDOW *newwin, (int _num_lines, int _num_cols, int _y, int _x)); +_PROTOTYPE( void nl, (void)); +_PROTOTYPE( void nocbreak, (void)); +_PROTOTYPE( void nodelay, (WINDOW *_win, bool _flag) ); +_PROTOTYPE( void noecho, (void)); +_PROTOTYPE( void nonl, (void)); +_PROTOTYPE( void noraw, (void)); +_PROTOTYPE( void outc, (int _c) ); +_PROTOTYPE( void overlay, (WINDOW *_win1, WINDOW *_win2) ); +_PROTOTYPE( void overwrite, (WINDOW *_win1, WINDOW *_win2) ); +_PROTOTYPE( void poscur, (int _r, int _c) ); +_PROTOTYPE( int printw, (char *fmt, ...) ); +_PROTOTYPE( void raw, (void)); +_PROTOTYPE( int resetterm, (void)); +_PROTOTYPE( int saveoldterm, (void)); +_PROTOTYPE( int saveterm, (void)); +_PROTOTYPE( int savetty, (void)); +_PROTOTYPE( int scanw, (char *_fmt, char *_A1, int _A2, int _A3, int _A4, + int _A5) ); +_PROTOTYPE( void scroll, (WINDOW *_win) ); +_PROTOTYPE( void scrollok, (WINDOW *_win, bool _flag) ); +_PROTOTYPE( int setscrreg, (int _top, int _bottom) ); +_PROTOTYPE( int setterm, (char *_type) ); +_PROTOTYPE( int setupterm, (void)); +_PROTOTYPE( WINDOW *subwin, (WINDOW *_orig, int _nlines, int _ncols, int _y, + int _x)); +_PROTOTYPE( int tabsize, (int _ts) ); +_PROTOTYPE( void touchwin, (WINDOW *_win) ); +_PROTOTYPE( int waddch, (WINDOW *_win, int _c) ); +_PROTOTYPE( int waddstr, (WINDOW *_win, char *_str) ); +_PROTOTYPE( int wbox, (WINDOW *_win, int _ymin, int _xmin, int _ymax, + int _xmax, unsigned int _v, unsigned int _h) ); +_PROTOTYPE( void wclear, (WINDOW *_win) ); +_PROTOTYPE( int wclrtobot, (WINDOW *_win) ); +_PROTOTYPE( int wclrtoeol, (WINDOW *_win) ); +_PROTOTYPE( int wdelch, (WINDOW *_win) ); +_PROTOTYPE( int wdeleteln, (WINDOW *_win) ); +_PROTOTYPE( void werase, (WINDOW *_win) ); +_PROTOTYPE( int wgetch, (WINDOW *_win) ); +_PROTOTYPE( int wgetstr, (WINDOW *_win, char *_str) ); +_PROTOTYPE( int winch, (WINDOW *_win) ); +_PROTOTYPE( int winsch, (WINDOW *_win, char _c) ); +_PROTOTYPE( int winsertln, (WINDOW *_win) ); +_PROTOTYPE( int wmove, (WINDOW *_win, int _y, int _x) ); +_PROTOTYPE( void wnoutrefresh, (WINDOW *_win) ); +_PROTOTYPE( int wprintw, (WINDOW *win, char *fmt, ...)); +_PROTOTYPE( void wrefresh, (WINDOW *_win) ); +_PROTOTYPE( int wscanw, (WINDOW *_win, char *_fmt, char *_A1, int _A2, int _A3, + int _A4, int _A5) ); +_PROTOTYPE( int wsetscrreg, (WINDOW *_win, int _top, int _bottom) ); +_PROTOTYPE( int wtabsize, (WINDOW *_win, int _ts) ); + +#endif +#define CURSES_H + +#endif diff --git a/include/dirent.h b/include/dirent.h new file mode 100755 index 00000000..c1e462fd --- /dev/null +++ b/include/dirent.h @@ -0,0 +1,48 @@ +#ifndef __DIRENT_H +#define __DIRENT_H +#ifndef __TYPES_H +#include +#endif + +#ifndef MAXNAMLEN +#define MAXNAMLEN DIRNAMELEN +#endif + +/* Directory stream type. */ +typedef struct { + int dd_fd; /* file descriptor */ + int dd_loc; /* offset in buffer */ + int dd_size; /* # of valid entries in buffer */ + struct dirent *dd_buf; /* -> directory buffer */ +} DIR; /* stream data from opendir() */ + +typedef int (*__dir_select_fn_t) __P ((struct dirent *)); + +typedef int (*__dir_compar_fn_t) __P ((struct dirent **, struct dirent **)); + +struct dirent { + unsigned d_ino; + unsigned d_off; /* ??? off_t - index in directory[] */ + unsigned short d_reclen; + char d_name[MAXNAMLEN+1]; +}; + +extern DIR *opendir __P ((char *__name)); +extern int closedir __P ((DIR * __dirp)); +extern struct dirent *readdir __P ((DIR * __dirp)); +extern void rewinddir __P ((DIR * __dirp)); + +extern void seekdir __P ((DIR * __dirp, off_t __pos)); +extern off_t telldir __P ((DIR * __dirp)); + +/* Scan the directory DIR, calling SELECT on each directory entry. + Entries for which SELECT returns nonzero are individually malloc'd, + sorted using qsort with CMP, and collected in a malloc'd array in + *NAMELIST. Returns the number of entries selected, or -1 on error. + */ +extern int scandir __P ((char *__dir, + struct dirent ***__namelist, + __dir_select_fn_t __select, + __dir_compar_fn_t __compar)); + +#endif /* dirent.h */ diff --git a/include/errno.h b/include/errno.h new file mode 100755 index 00000000..c9bc2101 --- /dev/null +++ b/include/errno.h @@ -0,0 +1,71 @@ +#ifndef __ERRNO_H +#define __ERRNO_H +#ifndef __TYPES_H +#include +#endif + +/* Error codes */ /*- if not used */ +#define EPERM 1 /* 1 Operation not permitted */ +#define ENOENT 2 /* 2 No such file or directory */ +#define ESRCH 3 /*-*/ /* 3 No such process */ +#define EINTR 4 /* 4 Interrupted system call */ +#define EIO 5 /* 5 I/O error */ +#define ENXIO 6 /* 6 No such device or address */ +#define E2BIG 7 /* 7 Arg list too long */ +#define ENOEXEC 8 /* 8 Exec format error */ +#define EBADF 9 /* 9 Bad file number */ +#define ECHILD 10 /* 10 No child processes */ +#define EAGAIN 11 /* 11 Try again */ +#define ENOMEM 12 /* 12 Out of memory */ +#define EACCES 13 /* 13 Permission denied */ +#define EFAULT 14 /* 14 Bad address */ +#define ENOTBLK 15 /* 15 Block device required */ +#define EBUSY 16 /* 16 Device or resource busy */ +#define EEXIST 17 /* 17 File exists */ +#define EXDEV 18 /* 18 Cross-device link */ +#define ENODEV 19 /* 19 No such device */ +#define ENOTDIR 20 /* 20 Not a directory */ +#define EISDIR 21 /* 21 Is a directory */ +#define EINVAL 22 /* 22 Invalid argument */ +#define ENFILE 23 /* 23 File table overflow */ +#define EMFILE 24 /*-*/ /* 24 Too many open files */ +#define ENOTTY 25 /*-*/ /* 25 Not a typewriter */ +#define ETXTBSY 26 /*-*/ /* 26 Text file busy */ +#define EFBIG 27 /*-*/ /* 27 File too large */ +#define ENOSPC 28 /* 28 No space left on device */ +#define ESPIPE 29 /* 29 Illegal seek */ +#define EROFS 30 /*-*/ /* 30 Read-only file system */ +#define EMLINK 31 /*-*/ /* 31 Too many links */ +#define EPIPE 32 /* 32 Broken pipe */ +#define EDOM 33 /*-*/ /* 33 Math argument out of domain of func */ +#define ERANGE 34 /*-*/ /* 34 Math result not representable */ +#define EDEADLK 35 /*-*/ /* 35 Resource deadlock would occur */ +#define ENAMETOOLONG 36 /*-*/ /* 36 File name too long */ +#define ENOLCK 37 /*-*/ /* 37 No record locks available */ +#define EINVFNC 38 /* 38 Function not implemented */ +#define ENOTEMPTY 39 /*-*/ /* 39 Directory not empty */ +#define ELOOP 40 /*-*/ /* 40 Too many symbolic links encountered */ +#define ESHELL 41 /*-*/ /* 41 It's a shell script */ +#if 1 /* Nick free bitmap */ +#define EISALIGN 42 /* 42 File is already aligned */ +#define ENOALIGN 43 /* 43 File is not aligned */ +#define ETOOSHORT 44 /* 44 File is too short, or hole */ +#define ENOREGALIGN 45 /* 42 Not a regular or aligned file */ +#define ENOLCKFS 46 /* 45 Not a locking filesystem */ +#define ECORRUPTFS 47 /* 46 Filesystem is corrupt */ +#endif +#define ENOSYS EINVFNC + +#if 1 /* Nick free bitmap */ +#define __ERRORS 46 +#else +#define __ERRORS 40 +#endif + +extern int sys_nerr; +extern char *sys_errlist[]; +extern int errno; + +extern char *strerror __P((int _errno)); + +#endif diff --git a/include/fcntl.h b/include/fcntl.h new file mode 100755 index 00000000..821438b2 --- /dev/null +++ b/include/fcntl.h @@ -0,0 +1,36 @@ +#ifndef __FCNTL_H +#define __FCNTL_H + +#ifndef __TYPES_H /* Nick, for __P and uint definitions */ +#include +#endif + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +/* Flag values for open only */ +#define O_CREAT 0x0100 /* create and open file */ +#define O_TRUNC 0x0200 /* open with truncation */ +#define O_NEW 0x0400 /* create only if not exist */ +#define O_SYMLINK 0x0800 /* open symlink as file */ + +/* a file in append mode may be written to only at its end. */ +#define O_APPEND 0x2000 /* to end of file */ +#define O_EXCL 0x4000 /* exclusive open */ +#define O_BINARY 0x8000 /* not used in unix */ + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef SKIP_SYSCALLS +/* extra prototypes added by Nick */ +/* just to make extra certain IAR doesn't use regparms */ +extern int ioctl __P((int fd, int request, ...)); +extern int open __P((char *name, uint flag, ...)); +#endif + +#endif /* __FCNTL_H */ diff --git a/include/features.h b/include/features.h new file mode 100755 index 00000000..347d9786 --- /dev/null +++ b/include/features.h @@ -0,0 +1,61 @@ +#ifndef __FEATURES_H +#define __FEATURES_H + +#if 0 /* Nick, for IAR compiler (see signal.h)... DOESN'T WORK */ +#pragma language=extended +#endif + +#ifndef __STDC__ +#ifdef HI_TECH_C +#define __STDC__ 1 +#endif +#endif + +/* Define prototypes shell for non-ANSI compilers */ +#ifdef __TURBOC__ + +#define VOID void +#define __P(a) a +#define __const const + +void __cli__(); +void __sti__(); +void __int__(int); +void __emit__(); + +#define di() __cli__() +#define ei() __sti__() + +#define geninterrupt(i) __int__(i) +#define FP_OFF(fp) ((unsigned)(fp)) +#define FP_SEG(fp) ((unsigned)((unsigned long)(fp) >> 16)) + +#else +#ifdef __STDC__ + +#ifndef VOID +#define VOID void +#endif +#ifndef __P +#define __P(a) a +#endif +#define __const const + +#else /* K&R */ + +#ifndef VOID +#define VOID +#endif +#ifndef __P +#define __P(a) () +#endif +#define __const +#define volatile +#define void char + +#endif /* __STDC__ */ +#endif /* __TURBOC__ */ + +#include + +#endif diff --git a/include/float.h b/include/float.h new file mode 100755 index 00000000..84094274 --- /dev/null +++ b/include/float.h @@ -0,0 +1,174 @@ +/* Characteristics of floating types */ + +#ifndef _FLOAT_H +#define _FLOAT_H + +#ifdef HI_TECH_C + +#define DBL_RADIX 2 /* radix of exponent for a double */ +#define DBL_ROUNDS 0 /* doubles don't round when converted to int */ +#define FLT_RADIX 2 /* radix of float exponent */ +#define FLT_ROUNDS 0 /* float also truncates to int */ + +#define FLT_MANT_DIG 24 /* 24 bits in mantissa */ +#define DBL_MANT_DIG 24 /* ditto for double */ +#define DBL_MANT_DIG 24 /* ditto long double */ +#define FLT_EPSILON 1.19209290e-07 /* smallest x, x+1.0 != 1.0 */ +#define DBL_EPSILON 1.19209290e-07 /* smallest x, x+1.0 != 1.0 */ +#define FLT_DIG 6 /* decimal significant digs */ +#define DBL_DIG 6 +#define FLT_MIN_EXP -63 /* min binary exponent */ +#define DBL_MIN_EXP -63 +#define FLT_MIN 1.0842021e-19 /* smallest floating number */ +#define DBL_MIN 1.0842021e-19 +#define FLT_MIN_10_EXP -19 +#define DBL_MIN_10_EXP -19 +#define FLT_MAX_EXP 63 /* max binary exponent */ +#define DBL_MAX_EXP 63 +#define FLT_MAX 9.223369e18 /* max floating number */ +#define DBL_MAX 9.223369e18 +#define FLT_MAX_10_EXP 18 /* max decimal exponent */ +#define DBL_MAX_10_EXP 18 + +/* long double equates to double */ + + +#define LDBL_MANT_DIG DBL_MANT_DIG +#define LDBL_EPSILON DBL_EPSILON +#define LDBL_DIG DBL_DIG +#define LDBL_MIN_EXP DBL_MIN_EXP +#define LDBL_MIN DBL_MIN +#define LDBL_MIN_10_EXP DBL_MIN_10_EXP +#define LDBL_MAX_EXP DBL_MAX_EXP +#define LDBL_MAX DBL_MAX +#define LDBL_MAX_10_EXP DBL_MAX_10_EXP + +#endif + +#ifdef __TURBO_C__ + +#if __STDC__ +#define _Cdecl +#else +#define _Cdecl cdecl +#endif + +#define FLT_RADIX 2 +#define FLT_ROUNDS 1 +#define FLT_GUARD 1 +#define FLT_NORMALIZE 1 + +#define DBL_DIG 15 +#define FLT_DIG 6 +#define LDBL_DIG 19 + +#define DBL_MANT_DIG 53 +#define FLT_MANT_DIG 24 +#define LDBL_MANT_DIG 64 + +#define DBL_EPSILON 2.2204460492503131E-16 +#define FLT_EPSILON 1.19209290E-07F +#define LDBL_EPSILON 1.084202172485504E-19 + +/* smallest positive IEEE normal numbers */ +#define DBL_MIN 2.2250738585072014E-308 +#define FLT_MIN 1.17549435E-38F +#define LDBL_MIN _tiny_ldble + +#define DBL_MAX _huge_dble +#define FLT_MAX _huge_flt +#define LDBL_MAX _huge_ldble + +#define DBL_MAX_EXP +1024 +#define FLT_MAX_EXP +128 +#define LDBL_MAX_EXP +16384 + +#define DBL_MAX_10_EXP +308 +#define FLT_MAX_10_EXP +38 +#define LDBL_MAX_10_EXP +4932 + +#define DBL_MIN_10_EXP -307 +#define FLT_MIN_10_EXP -37 +#define LDBL_MIN_10_EXP -4931 + +#define DBL_MIN_EXP -1021 +#define FLT_MIN_EXP -125 +#define LDBL_MIN_EXP -16381 + +extern float _Cdecl _huge_flt; +extern double _Cdecl _huge_dble; +extern long double _Cdecl _huge_ldble; +extern long double _Cdecl _tiny_ldble; + +unsigned int _Cdecl _clear87(void); +unsigned int _Cdecl _control87(unsigned int new, unsigned int mask); +void _Cdecl _fpreset(void); +unsigned int _Cdecl _status87(void); + +/* 8087/80287 Status Word format */ + +#define SW_INVALID 0x0001 /* Invalid operation */ +#define SW_DENORMAL 0x0002 /* Denormalized operand */ +#define SW_ZERODIVIDE 0x0004 /* Zero divide */ +#define SW_OVERFLOW 0x0008 /* Overflow */ +#define SW_UNDERFLOW 0x0010 /* Underflow */ +#define SW_INEXACT 0x0020 /* Precision (Inexact result) */ + +/* 8087/80287 Control Word format */ + +#define MCW_EM 0x003f /* interrupt Exception Masks */ +#define EM_INVALID 0x0001 /* invalid */ +#define EM_DENORMAL 0x0002 /* denormal */ +#define EM_ZERODIVIDE 0x0004 /* zero divide */ +#define EM_OVERFLOW 0x0008 /* overflow */ +#define EM_UNDERFLOW 0x0010 /* underflow */ +#define EM_INEXACT 0x0020 /* inexact (precision) */ + +#define MCW_IC 0x1000 /* Infinity Control */ +#define IC_AFFINE 0x1000 /* affine */ +#define IC_PROJECTIVE 0x0000 /* projective */ + +#define MCW_RC 0x0c00 /* Rounding Control */ +#define RC_CHOP 0x0c00 /* chop */ +#define RC_UP 0x0800 /* up */ +#define RC_DOWN 0x0400 /* down */ +#define RC_NEAR 0x0000 /* near */ + +#define MCW_PC 0x0300 /* Precision Control */ +#define PC_24 0x0000 /* 24 bits */ +#define PC_53 0x0200 /* 53 bits */ +#define PC_64 0x0300 /* 64 bits */ + +/* 8087/80287 Initial Control Word */ +/* use affine infinity, mask underflow and precision exceptions */ + +#define CW_DEFAULT (RC_NEAR+PC_64+IC_AFFINE+EM_UNDERFLOW+EM_INEXACT) + +/* + SIGFPE signal error types (for integer & float exceptions). +*/ +#define FPE_INTOVFLOW 126 /* 80x86 Interrupt on overflow */ +#define FPE_INTDIV0 127 /* 80x86 Integer divide by zero */ + +#define FPE_INVALID 129 /* 80x87 invalid operation */ +#define FPE_ZERODIVIDE 131 /* 80x87 divide by zero */ +#define FPE_OVERFLOW 132 /* 80x87 arithmetic overflow */ +#define FPE_UNDERFLOW 133 /* 80x87 arithmetic underflow */ +#define FPE_INEXACT 134 /* 80x87 precision loss */ +#define FPE_EXPLICITGEN 140 /* When SIGFPE is raise()'d */ + +/* + SIGSEGV signal error types. +*/ +#define SEGV_BOUND 10 /* A BOUND violation (SIGSEGV) */ +#define SEGV_EXPLICITGEN 11 /* When SIGSEGV is raise()'d */ + +/* + SIGILL signal error types. +*/ +#define ILL_EXECUTION 20 /* Illegal operation exception */ +#define ILL_EXPLICITGEN 21 /* When SIGILL is raise()'d */ + +#endif + +#endif \ No newline at end of file diff --git a/include/getopt.h b/include/getopt.h new file mode 100755 index 00000000..91302851 --- /dev/null +++ b/include/getopt.h @@ -0,0 +1,13 @@ +#ifndef __GETOPT_H +#define __GETOPT_H +#ifndef __TYPES_H +#include +#endif + +extern char *optarg; +extern int opterr; +extern int optind; + +extern int getopt __P((int argc, char **argv, char *shortopts)); + +#endif /* __GETOPT_H */ diff --git a/include/grp.h b/include/grp.h new file mode 100755 index 00000000..b1038859 --- /dev/null +++ b/include/grp.h @@ -0,0 +1,35 @@ +#ifndef __GRP_H +#define __GRP_H +#ifndef __TYPES_H +#include +#endif +#include + +#define GR_MAX_GROUPS 32 +#define GR_MAX_MEMBERS 16 + +/* The group structure */ +struct group { + char *gr_name; /* Group name. */ + char *gr_passwd; /* Password. */ + int gr_gid; /* Group ID. */ + char **gr_mem; /* Member list. */ +}; + +extern void setgrent __P((void)); +extern void endgrent __P((void)); +extern struct group *getgrent __P((void)); + +extern struct group *getgrgid __P((int gid)); +extern struct group *getgrnam __P((char * name)); + +extern struct group * fgetgrent __P((FILE * file)); + +extern int setgroups __P((size_t n, int *groups)); +extern int initgroups __P((char * user, int gid)); + +extern struct group * __getgrent __P((int grp_fd)); + +extern char *_path_group; + +#endif /* __GRP_H */ diff --git a/include/include.zip b/include/include.zip new file mode 100755 index 0000000000000000000000000000000000000000..3e02ec6eda35f26c358b012fb2cb8539ea3285b2 GIT binary patch literal 30570 zcmbTdQ*@@ywl*Bwwr$(CZQFJ_wr$(&*h$Cf*tX3MzVupqkGLrbS378wO^b-w2&rO$F^jpny3JqlA#u<+dpD0Cr?5!!p>84E8W6;oliB57 z$D0#E?3j~Q4ud|4h%D~}rvSvMVu%Vv^$P=He*iEK&vX|TffnJ+=DSddc65+T6GLNE zsaQhtGiVsdC`uh+Yo2Z*Ai8n$uha7I$#+;?v<)+VF zDKAkv-q2ZzrTY0lFk%%^WUFb`2Ms!6T!-y*;B{$hQNs_```wnzJkC|+xbI;reBU1G z`i?@%nYQMcvVjLS_`t`H;q0zEp^`~HAhFZx7pwk|g4T3KEpC}xNn%`0)$)9*aN!j@9?hyB z>(go#`DtecbGlZfT=LQ1cONTtz*p*5RWOIZVUxBHTc|9nRftF=Ys(*0a%}6CF+w5W z@5Hv<`!Ro6q}ky9KofCo?~zs!o%l!>t6L~OpPR2X+aEdmzy`0{ z<8egxD6`Rx+2(ylmB|`VV$KN?`Ai_Gqw2Yoyc^p=LHi%w@J5uvJ;4MRoBnzF;K;Uf z#)R#*LU0ZC?(qGKm$)8Y!($IOpI$7SIJnm51+88u4lMnnYWX4TI`Hx|gE5TRTA>+? z*_xr;#%=X5&bAzwTA>MS*=wQTwj9`*A+K8Y`d%R_dzwz&=iz30KfqCV_;jzXJ#)wO zCBld4-HQF)n9w3eEJb|9c(&_s_;cgMpBA2jhRNCpheD%R4mGiHXmIG{)NnUq21E8V z4{A0hcb9VV@h92(gR)AbDEDg=uW{&TNv!pK)R^kWVk<`C!qQPUh zk%O5=Og52-r6~z35ZiS0Es0|NgpH=!8Zxr67`g%Bsz+GIVbtupkzwe|v`d8ggFmK9 z;uO2MF{GpdI#eGUrSu1D18W$lJ-p6xG{d9dw$=eN(aW#>R<@lHXbt?ZpwO|c&>kw) zOtd>Y5N}$QozSF*775qs>d%@$^*P<~gt606jm%b5w1*!p$qoL=cAnY9&Dgs%PMVgz zRm@veRMRBdIv@?AHBb($@!R^!H-NXrZUhV zeMuzv8^!%Poq?|+#9*EyPIUsOqDz%PjW>|&346B>`^g63RWIHz-hDq!@aF2E_=`6i ze3)NlE~j&4WaARQq<@PH(iL0?5?iW~)wm_rUN>U$T`Ad<`)JQS0?$Qfx^+v+s<`qt z$~F_|UK=IpBJc4%s$OGv@i|~iXvpo`N)9g5Gho2wZ?jJU=RKbID2N>}p-9hA^V8Lu zt2=Oq*0AX7#+5alemuCfE@BkNq;~n6?@r?Xci`%F*9vOMXc$8QS!6ky2JVeH0sH0i`LVhja^TQ31iz7Nky9jtir-gqHn)4a zd`7*rbKy!$J!W{H?@l7&E3WMolA$CIE}^=G88sEeNVN7P93mK^X2l$a7Y&QN(RDZ& zIz0VdJzZbXI}Fx9VYf@``mJA9A2i`m`1roidSF8H@_q?g^wUVqrRV#PmMDd-FVctb zp&B<-yD8bd#WoDo&5zkI{W)GHK&L+M+w{-W%yu@krnV?0bgfjSAzDQL8AtHErUm!Sn<4*v zGt)jI>}+f6SDcql@7b4s?Qay1Y*Z$yg!Wo0WQ<4_=|Y#@=@mAcav=_2%De=BINeepc;|hpRUAP@q52!*P<^C*jB)wttKahEAcWISVup>E1^2IuK6v87~|^=`6jhW9MVl0+&41gF)yNiJsG zIW8Hc=`LoM@h*5-Wf77>C=HV4mzl-iXBAJd3>Pz7hZWzi@Wc>63l?YS`ZgspnYz8P z_Ohy-s-vt|>nm2*%ttDfR%}#GQ;#ER7e`1Mg_&SKvR8cX5|nS`+EGh^O(IK#Xih3K zubNy+6^bLb5#K*|>I+pT$DhQ-Ss?UGgYB1%tyd4pXk;@AcLrd}uuk&(h+oGk8kgps^&JkP=tqPt+8RqfsRtQt z5V^(4p&nK@C*TCf6&>HAAAD|HUSC~bMIH%G>(tAL$)k(+!i)Bn9j8Tc(XY6I4{FAk zV);Oq)(MKeC@1_*%VGbjvGBv@2UX@x?#q0nfI8~8V0-8J{lIMeX)q~PxoQafCIX4Z zK_0*TDNQ;jQShasOT+=ymmd8Dk8ZYHn-$0q!j@Rf=nqbgO9vwe*yBIyUVXdu=bS8( z1D(-Sqn%j^P~#yxspL7>s{qC^)Pw}WkW@W}remN$h-(|ylySSC(N;LPFr}?j50{Oa zDB=a^5=2!BJW5StM*>mNP1S?$v^TGM9)wquH4O+KN^mda za=lzr$^E-X2#aPTX@v8tl39jSk4N4;?(TFg1&T?<%ZTUn%h5+R_3*L+wYVT__?=V8 znOu}_TgN;7+lS{n%j-u!Z*sq$xCw`#HVs8Cd96^yDVw;H$AZ3Z3SxnH-7K|G8ntRD z9C;CxlelrqIPh+3!L138)2KhAe(WHnQg)I4y+synM?hkf&ub;>*b(rv%p9v;BA0k) z{sE40W1nRrXGi9wXGg?n7kEaIP5TM)%lgUD56UE$F$tRyK8&7F`=VVFF1S*7P*9^r z!umOC7I}{cTv|}Q-xT-_LM-FRf`;jkJ7@*+Iy4bNGja63&BPGUbL01HQ@1ApW*Il2 z7J?y!X(F42dE1X`%6BSL@uxHpT9ZX?_r{%`OLm_yrfWuDZUdjL4^L}Ge%mC_9%Z zJIQcG{T^sCzieTO#%?BpyooLKB+&F-j zL|JSmEH|i)^O2_@SDS$f+X-I0xk1!S;4t|8L(G0zlgTzUm6M&|gskTLbSx7JO{Cyo zqD^s;L#~8_&1RI8xe=n1)yTEmQ-(^g7|sHSM>1@HU5Wm|F7B|ewNFz&;2?d83upQv ztE)g!=*q1ecvwkWK&lAkhEYSqA~)Sth6iaLq5Qmf27J2radU~`q_VL*Hw!PA4-h4|*K9`L;BF*vOC zID2_%o75Z4z2TL^OLX(OmKzx!)s9 zbs#5cTAvidJ}VISz$6stS__d!RdFKFicy=WQn>B9=>0GZ&71>2iT}7~mx(UIMK9BR_vM5BukVeAt^jiuv?>FO+{Hm0JzAaD_f`ljIivZCU`?uVV;y%_rgnh7~`#gO~d$$%@_V zKA@ZVL4NZ*vqqR$X$d7C^0!97C$Qm9h#S?D3)^Valv|bdpM{%7s;#`7?Tsl#d`p^+ zXV1dAWe&Y1T_>$68;8fsSeTttt)2TIYQJ_%oA!I5@AOfizP!d(KjHry*L3ZU?s$C{ zWA&i_#x)|6N}_Uq3o?~{Ic!D*Ui;$rK?$5p8)2g93IPZ;DkK6CCyS7H(+ka|vk^I4 zdIYM^?){b|8=#Uji|5zw#5o5JwKP!n7f{(hN6`^# zF@O(}{OEbW%(*Os!}ve+N}ItcH7Uz9#md1ggcT=BW+!FJl?i%#Y!o&m#2&zwJ2u+WOTbE9aV9U( z^w9_-xiQ$ZulosG24ypH8N*pOnwFUPK}2u%8PuzfIB zz`k5463dV*ZO*tNDvg%R&dv_*%Lo&u65W%Aa7>!o^p$a<1yRR5my|nZJ=>wAvSSuv z(cjrL`_Y59Ilrr|joIVT%tZq28Ogwk-Yn1!Zo4j47%C%Ti(^+&gSD2Ps(Yq~h1UMw zdoo4=iI!KfD?i%l683U#d`AH~x-!>x#ftc(v7EQXG-gQF2BvRlP8Goc)PJsZDxQv- zHoS@x4R%m?RzGl1H}Zi8fMN+LWxU(2BqB`})zh#R!1jh(18B$izIY}%7W%GUpRZ5c zGpcyLAN@#C;JCZDy$hS0Qnzz)W(J}ojZg~5EQeDPV83u+{Tf-nL~75EkKXi(vBQRn zfVD8S2WYFY`8YQcBghFv^?p-sJEvtVtZw+i#k>phW#9!-Fy2Jt{S(Ww+3L{8s7qT( zXm1^^pea0f=;wp|a2=t{oy$~PBz|x2f7|CHj_?E8H`Sr?KQ*nWl9HS}orJHNuKgYd zimzMAXBhR=;IztFtK<(f*A^uFf*3F)5hm4HtB|>&AB#iND{|VOA8U*y{gW5i4bu&A z*PPFp^d_>-U7?HP`ZNO;j}CrMqQ1zHaj9_SCY;a4O(IQ&(~R$=?x<+~c3*1N=|?8M zer|qlu7G^U(ZVB6G&_4x1yxbf1lIX7LbMLGOMG#6$Dc-_@kNR|0xE{NQUex2YWSoH zbEUxv_+$|6u)jj$1In9dt0e;jakG(Qna5tP(oyNf;2}JnRY0HbZ}h>`(!1pzLYq13DX4+02O!|PgL$Zf$6Nyrw`86RAr z{qlVw6=?%&3P(?)eFK&|&e9>c36mS+Oo}eXxltihq_nW*x4Qr-YE_Q}l z(qGpi64LYYEB-11`z6lM#M8lT8`M+~z72H-HzRUo_TZB}*BlxEPBD44Ps&1Xou80K zA!4JfW*u-Kd;Wd9`v#SLfACxh^Xn`Hog`jM=@?T|lO-7*Q8&`hyh;g}e3x)PB40ZU z?0-eC=FYxenEwQZG*&2e0k0lthP6ccjE(e>-0(-vI4B?%Wl`H#tG!*5*rvzi%?7fbmUb1G=mHOM{&qBWk-lQvH^rjtt zU}0ZYGeAH?O0+0T1maz-_Wm^%8pjkpCav2M-k)|ionuP`KXs8ZQ5U}RYGR9&6^py* z`&?+@X+4IJNR`w#M;7I_CxIt})bUGmv2;vePU^=|h2ACBscLW70dHR&YH+<@HiHf2 z(5pNoIO=E8wyPv(8X^1`=e5sT2{#?}FDF|#WuDAnTN=6teT~(v;%^2=?JU^Bid@=B~H0K>PC8-zZDKd!{EKSRuKQKWXsPi-h8-2+brZj5s zW&gaq^ykSfvek&V;y@hWdu4~y(m^3$lBe(z6?$M2H}|%DmN`DylWGk~W$2AupD92E zOW~fN4rg!Usx{e;?+VpbnSO+S-d}Gbiqa~(Ew7o+#BX%vR4u-rtHbKBj@oZyUHsb4 z`}zkR28l(3D)7xUhJL5FzZ9&Pu$+nvorGSwokf+&&{IYR5XmN zsUcs2+}fqt3YHei*N0YLxQYGc*y~k$*(pHCWZMrHOcBTQ9$tRf3sll;3U}M2xnVM> z=iKc@BrWTGaeX0P`@Nl6gjCKyq0AG~wSwh93lY)^OuYjR3nf5OM~ohRhjG5!O*;iU zlMV(<)))bt*NluG;enYMEHbuT`LBS=$#;D)RIA2Bi5{`(e8mgU1ppN=H&897ik%L$cSWxb?rWNy8dA+>gGN1Yj`rWv6Jgf`)Cbe1Bx7ZxwKoid!xVpT5T=ry*%%e ztk+Ql<0~Mgdh(nfW_l!3=TEu9^lI~uU}L3UX#jbrnPH-GQGTt@>(CqQNB{3MDd+tO z-vkB#@buj)_?NBA$P0d>xDpLX`~5Z~K4yVWVOTJaBp0p-wsj_~>z&jT5#V2JIOc-- zAfkoHJ&F`@BIMKWZ-f;wS{uF|JsL*7`l=0V5gqS=*~WtKi+^>=>;8<~n0f}D)pFV{Nnb34`a$@b2?FPfb3 z5&{=Y(8q%zu0nfz^vY6{!mvp~0g8-WagNN{1a-9K$zR8lwR4i~e?7p1SvD3S`g9pV z847JXjyr(R01miTTGg7J`@tW?TJv+^EV{(P?$H3IURhu;T!k4`OLpf>E`Kg`iiMJ{ zhJwxno8rLQ1DcXd1WwDXXNNP?>Vq5$SiC_x3hBRL4A8oJ9#5e;7wexG3u9v&!{%8N z_fKsFa*SXGeWuU8Z(3vc>vRbv%rcg3e$3~-0@;O~$@{_|oZENGk z>Y%bMaqkt8lqI}+i{j?EgdtW!3{#%3zi;nb&kgQ2z1r*CrWe(9Rr{3)M>Ht+w1YQh zNJ+iYCT1f9X16m6VRyTqFTbX2=fwT+nH$r+Ut4>*Io!>o;EaUe*^hFhiT?f8)Jhu! zESHXAB+R7(tNqmK*6GGcj_UyimI*AYr4#4b3@UTAt1AKQjHkXM|IkwBsnR98dz^_J zT-fRcQ#g(hJ8o((K*Bu4x6@y<&e5HY{zzKy%bUX_;{b1`zt8)e-mN_4FwrL(j8{6Gj?>@BnXWnl<$aPnAm zM{nG=%F~Q=ORPnU4wb(#aMFJWaj@7{U|wU&S>8$|!-JJ4KGh_m2Xz7>SXLpP4cYhY z>F=LW{UP&NQ@n)>Abu56GaA4Eui)kKl$UUMyF{QUppi9#vks^He1VEd`AP6c+5&M6 zAzZ)0s7cl_bam#^gvOv#=2on=wq~_RTATR-aYGV-hs=^h@6Q&{h%C!C?KPgS{U<|) zr*d#}cd2EE$DY>%Z@47L7+M)1F{G%(rK?#M%)4l@;S7 zURQ;-0ukmf{yll3Q%k1-g1=KPtU~kzhVHdl5 z9@#XPI5twZjH3iok1fY7#TGbW5Q=$cdQKsa*AxS{XAicco!IM==fkFU@;U?i09XM` z*{R(`-)5Kxbs)@7!6)^l8~OK*^&S+!WrC!IHN}34dtfO)fI=eS4;)ffS2KW5Mdx{8 z>Um%(FMz~P5Y%igN!M5aH}FOk(SjsO#1I}q@^vOl)5L`x?^u|g>5qx?ENO^8G|J1Y z$DE%BXOY?}mH_=?1YR5aFNapQW#`r1VMIQlrdecPg9SdJg?KY+?dDqP`|5iTR9iXl zUad|($7T&Gk^sBbjhDBP#@EipxkB$JH}FWKK^&XLK;sA9 zFzKj(Bor0(4;AXDF^6EPrH~y~&o!-uIE;$*WUtJvU6epxWVpQ5RQEF0*v(z}vybHP z@e8=G->go@o9Z~IN-Pu6w)NzOD)ghX(X$8qE3Z*Xn9I(&K<5TM}_&so{b=k zm0w&EdMxhj{i*2a3gdmmW9i3bZ665o$?Ur~=hM;3<0k3G@aSNqJ1uhBql_zQ)qFfH z%<_`8)x1DBH;=Z%Vx^UU^!6Q$4i5WS$>ZQMe{r}JRD)e+RC-#fs(c<8kwkOub`$N#V(Q3V1r{zV6;wZU#_ z0Cb18C5bd~GALPaiQ<|b878r;`c?dz$8|Dg*83C})P}g+uJ66alEe?!#W6ykt%fS0 zyI(G?W@N#lg97*9QJ$@MxcHCq?_y-CB;y-aJbkafLj>ZYD)I{7iS0j{-tMrs@DLII zYJ5YP9F-JC_AiErfVF`M2j3++ODQX%+DK7BD@8prUHmZmS9iKgr%R^-m9#?C6KV`I zLKI5t6_hkW^mNH#cCrfzG+)C?5iwN5OfQl((J$V@%L-Bf$inqUC|Ec=3za6gRU=xw zGT1(f`2l)BGMcqj;M9*cF+qLkF={BSw=SK3Kv4WUuNm!cbj0It2M zaB8Z1C}X1<=9zX!p=?ufOQ)Lcbad0J1~nUM#5n}&oxtJxiS%t3Bps2El;<*y?)<=* z-)4JJA5pr_KJ4WrT}y!hVuPqsz{zI&4MDN7d$k~>=Ls%uF)!DSzE+)b3hR$QzA)+T zsYW+D5MHS-xPc?>%GO_f_Y@j9>)ZD~Y&Ejrv}pMfu;PE^Mgz5M&-4pL##*jdEtUty zJ?jU$x?+39Sy?z5K=(I~$x3!FC+)6>R!rUUhxpHY0sc2AnsBT;5dM~a{Wl`|YdkWN zvXUy_$n-Kv+B!%8C1hFo#J??G7Ky@ga?nN=%9Vi80Hp(2**p;tSI~HDrY@u5c6Qc9 z`*(`Yap&;{cP?NN4*?2~eU$qOr^nI#JOMq!H^SkThJ>uDQdjhAVgg-uF?#DZUt%J zcgds&bp-9nQcV+S_onu>k&!Le@^RIwQ!RDNV0s?P9um568teib7VbFS)yMU3w5YWM z%mK|6&r3~T zGbo`fMJovAfmm4jbZBK|tyMs^+9NnQU&jzwzvoaYZb{RvB9#(Q1cO~r94O^R7!ZDH z)z68*Od$6Ba{{F=)beQZ`x}wJUGf_+e}Air#J5i-cE%1cAc%TPe}+j|u0T)~a%; z#sYRzqvU8sg@n3kY|Q9yLpF=#mVmRQhWHmh0Mq3)Sd|9;YVbdehIS^ZA}dq@3V7K2 z9ngC$f9vqDTeJv*{Yzf*-4E!-GoCplo7%*dctZv)tJ3I_jvW!c$Tw{@xkR6hwec~s zgje^|_Rq(pbIUDE>*<(YlKYA+)k@4i;!*KDV0EzR zSdy4qY>9S>a0s5Y3Q-%2Q>@7vUa{wiP0v%Vkbw#A=dbQy&mBI|^I~8|sh_LstbTqT zD`Q#YN zO7f_OmF`0c>pUwncE-`bV;vCo%$ks+G^f>zlm7Gzk{mOHM)*t-V8CrHc%EP6gclXF zEr|B1RDk7S>|^@PeE)}bQ{CxNt#-79 zAacEj{~DuK0e^4gQ-gmO^ltyd^ziaCWgUJEr4zq=Kmi9YpE#1lY-w?r}DkN z8C(Fl|DBtdU*0=ZQcxI`rlX~jqg|Q+xbG8DvviCQDiqQ(a;pri6|yq4G>R3H>;V!g zNadqPr%!V-({qxul&TDbl^KEiN1{C&!)%B7jy^{J!}Tb9d-Zpuw@s9f3nD-mp0S;~ zHn^w>bGn{twPO`z{9K*NjaIdhM1T=;e_p3oVP6M<12Nm8r?(gTS!|Ab)!i{2$V7E! z(X@4z$?(4BWtpkx3%9M#cX9*#0!LXxpkq=>(Grg=1r0I?YRQ?!F^r~~ng>mI7-w%z zktB2OgmDS8Sj~$C7;Ge9IckVd=2%fdZTN$Mh!#DZ&and^c^jfB+!!%rMiG{26SvcY z`FVUBAI1s53h5qr!mXCV9^1+*_6GxBsAuhE9zlC%P{@uEeQ$|1v0-jD5OaGgI8s!B ztr)cm8p`l5&wvrL%pR_&_Ji`b`*z4$o%1LKBfi}ncn>wkbBXJK&9Auq%RaLY=>HDc z(_Bb`utYu)J_#|+i(bZB1rkT< zSfDNW>glMSUkQG&HJj#i79&0lRg{Yt(#7}NUhJglcEsHGP~%|K`^0ITX&74XM+(-y zCseHaqhA}E&EOSlDVz?Wk!mO9af)bC^e7>KZK`dIS_?QXn>ykn#NWhX`A3Yj1jl*{ zr$H+FUA5>=62WI*5g7v`^Ol1+>PK6K)hBL>jrsyIQ)iHb8!b=`O!_;w68ZWpAOKv4p*)4n~yjBf=+ zB_}9nyHJLG(*@l#_iRQ`G4C-AR$HM?|Hr2zwvpG>;c!0zm9G`1W&l5TvOjH(H!auv ztIZcJ1@=uPO?mdzPxH&`*D~CjBMel>wkot(jyzf$${(z{Gz_g(rp9lloL(+(616h~ zTqE~H86%^*J7CjML=goXMs8Z=|7K`*P*b7YC6zP#NJ<2Z(f@}u;4 zXC@~s^bRml9HLqXiANH^QFw#a7#ZwtTCn|d06Gamf6pNCK(L=-rsx1l81oDr->xI} zDrp5;t@}Yyjf}X_YLO^f3aiA=E}ow>}dq)|=;=qnDOKSyN1GPh3y% zfB(mH)e7pKiLE*PXZU4Ckhb?kqf>4f;4X*Xjn)wU_cq1Y!$kv8MyG1r*4-RF0+n(@ zv-r`&7J7a1NG3|OAaM;Y>ocL#;7SR0(?Oynwl{fkEF_kNwh7bn7b~_JtBZ$T2KXnU zj8zsY`B?_GZwYvM(Jc8nmoiaZi(i*lO%iE?%gsjq4GT>D3aRe?6Sg5r|jlf3^5V84|h#w1iFCTOVW6eTKYBvnV{l_>xtQA$e7)KDl) zj#7%z4oQzFC{R%j%g{-Ws3=X)s7c7ulF5z^RDe{0Jli8qGsX;x?xdWPl%lHp!BEmj z&{8N44$F$ENJ>i0k5GZ90ws#cj*m-z(9Q#&&K(~r$w|siOiHWXxVk*M9I-GkvF#oL z{UaF4PP9BWeVb40H@^96Ldv3oO2XeDr$t59`fpG7SNsor96IoM#^REYH9{WiaRO(GOFC>njDC+Z zNL>)|)-A+*!u3A+71OzammgEryi}4-VDt?7c1!Y2Nw}FE2A`Woubj7W_pC{FcI;7M zhm(JPT?a3TFk`si8ebuz2qB|MS`VqW6YFLwNLXJ^Jonm|DqCSS2->%C6-DTO!6m}fRs zNlk}tCI{q`EDn>b%=lI&JI3bM3l-rclLbRVTFB9=39DVh!E#j2y8t~W(f9jdy*a3_ zE%SMt#MGt?&rvl)mhG1FI+Z^q7s>2`_R!*?XZ36d1~5Jj$HpV*7|iwDPoHQR9ygRrZW4a)CrCfr5vyD2(xj@~TTH9oNqPL}pIj>&16$dE1VwjqyWjAIT@_ z#WB@0MnaPh$BDZP%;BT?pqp!>yl^@lNg26gi=N;wB{Ur@m~5^I3P=96Q|E+XKq} z47m7RRN7~hUt0OSugM9`u~GUEPz^ou^7Y8;KNmx$%rMG;PcP5vT0{Kmw2 zPkix4xCB1JyJ(7^nPlhRwUZHs!*j$$(}**jpqawIKm5P|KVW}x3!UcsOz7zu__K*i zd=WCM^m~;jbpC$2PAYEx{@%I16FHsER0e1@kj~hE00|^PgeJVq%`(>_)P3O??-sD+ zjM#glv;7+WO{%bzk{mU0Gbf3xt7yYCLOj_~8q?q>>vkBUtN)Lq&ApPa)ADucZj*=W zEL{?bB3cSEM5%CL)>?IDBL&4q) zGwzi@z5#JqWFi!22YrJWH$cjv_?Q8t5zkBM%HE3hdo=+`k4Y z$ui*V$>l($J^9KK?iGeud7j!LOVXz}De8>d+Ht@11Qj!|)#% zfacLJ11W-Z$$&woxr{`BLzS|dCw2kZsL;98%)L%$JY1fivnzY&T$4_n-_|MU<^58B zUbb*x#(*86CaWeKc`m|X)rIw71^?075?SGNOT{ZtHZaF^LG_r~60&G*%G2;mx%20t zL1!?$R3^sda;nW;IpbkNzK+t*u2V^5u@2+_e5f1I81EJJp?>9m=06Nf8LvytXdEptoY&{(*JJQ0a*L;yQ6LE3U+?s?&kP-Z-;eT z^TWLwEF0)8UGIA)5Q>ZVQn%%!j-B_X%f0Unm(wli9!gK_UKr)ia$z4>K(iGs+qA1% zmDthzk$0VuHdC=>p}h{5K5O8@?J1!9D`Q3dc{+de2}-g;;e0?tE`iyBkzGAXTq$^4 zX9FVwQoB^$OxJxzl#!f3A{zn@dJ;)V3R{_BCyL>RuEE zuYAPuMd8qv>`Ot5S0IZ`Vun3cIxjD3XKr#aQEXDAn`|pR6SlaBesS4snjYP zw>Avpr+cTZA_Dvt+jbB8y;*5Najb;U_lUKFH#;)&wl#`?C70QD$BrkPUv)fO5)YBi zs;<~ZOdYfsm(tv`lyHrICOp2F(2HK(rMHD~WQ*K(gXC(UyN%`GXh!{S4UDE0!W4xy zCL^YWex{!xq|78^eIt>8ItG5sF2i0u$C;gSHnMnHJ}+CEwVE|7qO~xM4ma42Zh@&~ z;fs)wIB!GiWXKabJrDZeb_cM3(|uD_g0ZsPutqU&wyy`Hb!`)Ac!cpOX!_0$77-8c7ka^=%h zzn)Xx5zdk4R3F~!=dEnh?EnbIugeuNbYEOuIh}BF%?zUKbJc(|i`T88_%fR<8y*tO zbR1-%0cEF+0KtqIg~0S6BWO8h&|`FjT%qH(#(K_R15=uIXoFBlTGT*2qU7w&pKJMQ zQpRwQQ%pPI6+k1bbTZ?CQkg|!6#_Rls-`|C#thM3wdfq4;aQ_oE+(lYt*zMO=%#=b zl8F{FvRD!z%StAg`_K#(&Sp|}Y~il}KjOutALrbJe-?+JKvK1+25DCDhv%O!on=*) z&_KgFQ#!Q`F3KomEaB>xen9A{#?q5=6I^X?4Or*#O*jZL8|YYSl4WM-S)EyIVE13A za3!+z?`Md3sY8sgT1ZBTuZAIJzg-+vrQis{FGNE3j2qGwt3L8Y7j-m6w!@@!vm-10 z`EbXbrBZ5=CErKbQi-h)dd5)^>)I^1SW3yeh~82im#3Ln>d3TOz}FS>P#WWt za16tNQrp45(PfIs7kxzTVeST@6CjekY^eI_%l!#sctSSml)O%Bu5uLjbTFsYF})Y7 z-QwCgksVt{=p(AL?G&JMjp&C1M+Bj-J`fjZJtDo~E=E4<08+q>j!YYw)4_o!!w+A# z5t3PLI~96+LaLnAd3jLL8UGYaLPRek&78{ET}l68$kjmMU`&sipFE<3th-v{xi6xg z!7z5=TO~)kMXqtdb(S=7-b>(fPQS&T*?{6S8KM&~#3^+E$#>_&I^1`eziWh`NbqlH}WxK*tE1BYs1T|vy{P^L(rqrx;{s$R0PeOK60R}SV-!T5FqESeCLE+En#1k%MGxZ@6lA0YP7JrRct^d18uPAJH&%gytmP{Ha;!&JbOHFDPS@!eLp zFe`RXi3G$brT*ftrt`}Q38%^{ts{GEt=(78s<$^Lo1XzT^}uS%DQ^Nfb45}GY@{87 z0<0zyDXrPLj5S@uxup9}D7Tnt$z_=1#4AFp?EOj>uF+&mw)4m3RAre$oxV@byQTXt zGgaEu3geb4>HvQ7bjo1sqrU@NCodPFO+lZO8m3KAd>=5A-?xQ(A>|r0&lr z$DtK zD-OpP7eD-LaM8M!Eh?o`RfNQARBY77(&zlY_RUU1{u#UnL~@2OzJs^W{}koQDk6eP z;(ux539G?x+IX4j0Ur#=OsqDEYdt>1Q3~fRaK!~V5TRuQN@;k7>^I%pWlBoezK~Y) zZwJnzcK6=`=w#}k5D8{Y7M$o~kBfa!Yvs9Si^#7?v^AMrD(E$-G$L;3qUHwRpatH4Y> zflI3SU>ND7(}8+=CZISxWK)z*M#`v;9qEA#lVR?OdnKm% zc-cGX$6G-R;5|x={BqzXl!umhox=Q*nF-MUs3HD7OU5ooq{sd)jFXW6Jt_08O3Ckm z(ija}dlYtrPoIQ4{8AyR&R=Bh0Qd^P6%x+kMWHwyI>B0zYSXpfty|+f8+)OX3Hv(U zE%a+`0wfb#{`<-O?}Tv^Y|2xDIdpsY_F#kg)zNuB6pdL{Q-Rg;`7!uDCwogmuLM>1 zIG9@bG1ZV!#ABM#Tk0Zp087V4lXm}Ve|zY&*;Z+0u$1xV&?kswdpCXsY7a3#<&h*6({HFN=cq9Gnonmr`ypcL!+Wh{q$q zWfZ$e#F}bl=X?XU)G?o#-l(!)&6&NttSn&|>m{q|!(A zV$X?|TvjbyA8kxx^k6)=921HG=IGbahZ7m-&9I6FgLd!$!=)lgj1AMDi|O6>ddLqH zM-!l-5SLQ`$z&Z0!dpjGs9+<4B`9}@H;coahgj@Os&2BBVKt-o19-=ez$ovbXT^!X znACq>)61u&Ic^a1Y1gXT(`TC%ixJ%5=w0Iq6A|B+knU2EXF^^z&+5!7lJzpdZhwrN zcq4$uvw$}JG7*jz7{!=U2F0ebGqezOiA`Lh+=s`rKuhM^`( z8$=c6w&+&QO~MEn(jbzqgzeCNa>-(m1Q%;X$RsQES+J}eiKU5DAy;E93DyvHl0>4* zDwag9m)PPCdDI+WI06Q#K{Vl-+L$)cP?1nn>OoKX# z#?i`^NMo&95(H8a!K}W+6)DLZY)?OlO2m(_ThKNn-X6}FBX!x=$6!{Kby$cq`DitD zEM-FFyduf1!oPU$Cgzrm>)kQf(q@JiUp<@b#FGrr-XyKBnWJ!=j62D>7^ce)YO~f{ zKTmJ&745Z9yc}|+PLIx^KA02=*M-Ohkpx>|r}E5x6WEl1x9RvkRyH*{Bf{*?Z01NJ zfE+qpuPlP%^ad>9m{~*c6Z`FTflFd6mLvE%Sp$~pLi9IFzg=KrERn!;MoMoSaJQ^@ zSrxy)w1fg~8*)5|)nhX{#Z*c*k-ID5rl6t9N!e5G7r0-zA(ooS3gY-PkZ`~W^Rr?s zBcxs7j875_fhXtU?8wzOlT;*|ENsC%nb;Oj)^!_e3-Yt2NkH&-1!$gRh1+Zxw4Y#- zaFWiwP{vqczudyUqqBs5dC2+t)0FAFjA&w|Zu)l@LW&j|PY{!J00-t3cn4<&~}2k#DIR z0^7bzrL_>4tdErnx<$#dPu}CeVzeU-OsX0_T*Wsemu4v84cjE?KdVxv2ozNCyo4`U zGm)f2@txF8MYoyvtH&zJ!S z!z2LS4i^QzDdl7PK@OUkmOpC0^O2chh&w98raQ1Ntm3vCqjjzuy|H&Bup^OD;W+HH zoXO`^=b;U`5-)UD1Tu}8TGK0K?wR4j9gw2rl!rUpfKbaU+~dy_VNEiKRwl z@Dld3+MM!OXIQOqWQ?0jnWmv~hqxZF3e%`QVSUuKKyZ~;#@EWnx5cykj`z09w0(M-|3utnY!>@=u?j4+PJ*D@N`Wu^)RwdJ zmGf?YG9s)HRKzE{TaZ%?8$0dBeX~+%Dt?YG15Q~vb6&SAs&%N zvK)LK{Rbm#xf9Zc^4&Cv{icKeCz;7e3VpX!)pX_88Bl!fNIwTtJn~~I`*SnM7%6}% z*0{8aW#;+EwZru0 z5_gZwMxtcf2>b_bKBZF87|-YBs;6rc&_t@$SKnq|Jv&J2f{sf77|*d1i-OT$4L- zG;>Jk`!p*15lfx?TXf|ZsV4a+{TQnXwT5gmP|F|6o}JZxC-?R^_kt0F|CWp0>0MPM z&(PbB7{|3_rcvZO=-(1-ZI=xYV2({tVCX@3Igvc3)pY)9xPpn5@MyR_c;tBv{tpIj z37;;g-g>U#_iRp^>5rQPO4?QrRwoe_H-*vzRGvLO4nJv0@Ma*$Er(R6Q_3NQGzzM# zW@2P&aQu0nIDU(gkKleUX|vJrkxS!8&D8Le!NZM_j_2Nr8S!=v-BR>1{I<0w*79ns zg@Gj~*zf$vv&G)ZI~P0PKD)sA$>TdUzeCcQ45wc{9kf=Lk7^h|D6aWU6e+Ltl?@DC zzsM+bKCawc#dk&{6lbsb!WUuVqnzY87Pto0DBS(K7jCh>{f=o^3DmS*`zAb@it2 zlV8KsDNDvPxw@P)&$S=eQ>QkoDn=~gB`t{JS{RQ5vxCLg zC{@y3h8oLTAQs#f6W05xx1*i38HBYaoVy7Up=7kIn?!c%73-2ZqXM!ibf&q@T|YEi zjGhLqdX}HxyUC@*0V@&q3;ljv0v%{X!=ex z;kB*fj3!nn*VdY<(O^f=B1lHk-YaeJMSeI-h-_kVHEBpjj`x%6@`wDq=NLbBUWGSL z(2P!He+nrnq5ENq!}(`GVS|(0=){M6p53qWwouq5_H_nSI2xCr9!4nkd)bs}m{c_< zxU+ZVeigxcER4N_k)LA`y*B%K%Mkfn-|*S9gyNj4#KHbaYW}MS`*~D=>tj@}81jGJB^gN@vLN@Wb)-dLJ8;x=HXSo8poR5^l z+(`JZk{aHO^Wfs~(d-Uj)1upb;jd!wYC!bgtA_4zQFpRy)$+}d@L@v!sSw>(<=D>X zc3kIsF*HKU5S=e?6Q0UUE+15Bn^~N+^k~K+yOOc?5!!}r>SN3LQUZfdAC49L-@5N7 zP(r&q%kl8K+Yl73VmQA0Oq|6z8>aNNvr#8)W^P7pj;Rwp)6voCv#O5IgL(YwMsfJi z-ExmMly1wfpAON#=k76ay{nXP#>vwf^TvG=ikz;SEv<%A^u^Mty=7N_gnJ@h8@I^z z{g=WSo|!j!mm&G{hr{`{I@{}Kq33!fV>(q(A}S*GhE?U;tvtamr`~YWzNc{9FK@Md z+_XL*#5qX2|A2|akl!_-&#dR$6Pxfu>3!1cJ#u>)#;+*huc8ZJCBuzy(En72;Taa6 zm0Mx)xA!evsp7fr^nwa#2KV#RxaH11*=>q;gZ5HZ4EbBW`D|{A>wU^hYOJ& zEMT%dCj$0q)xnTY2bq12ka&vF7NIzIzu6K31AgiqzsSx#S7c&+qwXC{wQy<7dcA@ID*GM$V4c^Cu_Hb@|6IWnJT+_mgr|$LaLz#iuO z)$k~rs<}Tr_aHQ9NUrWf=gnDHrIG_2A%Tqjef3f;ym0}dXkKq9sIV)c&={^3{sTd` z=ErSA?I&jbHX$o}Hbhl3kaZ$5P1BT+lquN<-{z&&*KuSyl1#Y_F*$_1uZ=h( zpX$YSkA{CBfgi}1$Iqo%c<~YU*?8Gjy9EW~_B73b4VH4jJoD?U>O?|;0*4(kObG3i`m=J~7n&JIG%9z5XT7NF=`RPT{0^k8|po1M!lj~DWGB5b4Yz)>a zDLvmU>r_}PdTx2l#>2MCAzK}B#QU!d#L}uud`QA;ce-B)T*((tpA;gv&$}I!7w&{u zHlJdIC++aPLcieM{~{V)U-^=WpM9r;vAsgn%$jL~btb-@hIyvkj<`>nlUqYhlYT67 zoUPD0`qN%jwTyeJMj!JCN!Qp{s^tSO6Y0243bR0;cNtI<Bf!ep%zIqY@{MqXpq)Op5YETD8SVf% zD`_h&PI~?0xUK7%vbx@|qqlnL8@VLif=SGSo%=$2&z0@_?b2y;MXV@ejCds35wq!= zs-#tv7~sv8HGiy@t%V5|ZJQ5vYVCTmGgD%%=<6Q=_C#TDDA!giH5MOprdM2LslMm2 zI8(=aV;mDSQxN*@wfvqn!(_=2J`HMiU1Jl!bu#Y7LUY8^@*HbCNs&mUb*UFanP&AU z*_7SP9|+uqMAS^_WDMLCuxPO{UqU*UVNb7OW~ZuHL7O4Be1GNt`ToKy?IQ-Z&7~p&N^8Y};|5@mdE);;xOOs<^V8s4&osIYzbs!*Iy{ z14!SAp&PztSD;2bkPD6$pj?M(Hhy#+ZDP;h&v&* z7u3@xy)|YM=HeDh?o*eG(WW}kqwmth)4gPx<3G!IlvA5r_nmogA?8jG-Qsg> z!S4(P?a}!Uffs%Kx_<7szWD3F)y<9J_it3dEA$*ppIcklzPO`AucD=u3I;f%A;5>4 ze`Xb+0KDZSM+?he2RDx+pTo&aSL7~0kvYX0dgpqf6hxMGuIA=hZ#?juT&zNXUr?v7 zGdZ67-UQA!XB;iAt!Gb_N~Vy!2)=gV}7e@SH!7h+?gmc$Wkb$Nits=?*zuO6LO zP}_?7$q+^hr<>z5mOy&{xw33dq^L5}^CzM#!AM?P80XKNIDMy^=D8bP8zmu*cGE33 z2t-G!*QX=<%R+UHBXsPi4hbhuHJ7ldUi?TE4H$Zvw9k)gR!^iZ*Cko>$t7C~4p5bf zPb0Tp)zR3NtSZ|dSAwNMTT|_eK>j2oSPyRxy~q=V?h7puFN~IrZNy8=^IW($lI1T4 zw(xSVSbhpF|EFqBt05sm1L(pY0V`>*i-%PKazKH#SXCq25jM1oDZm+O08MswVpSCx z2R*WHzIl>#nzj!I?B~6AGRDlM1z#;J=&y+REX>zudsQ;JA-RjCr7$afFv zC^Q1#B(uLmy==FC9G(HVhY+WM&}!B2E{(Tu1`k=hRi!D%;mPva(;}!%2|kN(nrg_x zFLPtxN2U*%gJ!37CG63-Nqvq<;o1=JCAmy6P_&bsI@q;EXk8A|XSb{RdD-$~V0oF* zjanRGQ8f{J$!kM1l2CIr26^_!{HaKgjZ);_DWUjb*GUfIzfOmNQnPb}v+c`4Z`GYA zoj&Y8E?i5#3UG@~Lu$|$TA(FlHjJ)*qZ>?LqFV-+E@~jMTK0s%0aEZjsV>S`H1ck{qd76SVFwUbCEWP>Jzb8n1CqvaXmto@urr=q-CB zS_F)9)r3+WI82QZR2v(cvbbVE+YH}FN9phpc*eao!3R6^FvS3ghF?zLQX<2+W_eW5 zTQ5~(KybPy*?G||>{+~JpEewfk#a9#m6<&5vD#YIYBVqL+ib+jZC6TB>=!agUJA|8 z`;v)OT)Xj_1dk^%yKP4&LiO>(6^g${E?6hxocYW|9-MqM;kd#jj8*htVEe|8PQUD) zy|x`=+{jsTVS55|WBhVhs95r+AEN~Wx9BWz^Z)YTfZBe*P5M$z&sK*E`DG)_PtpXO zA5n&(>xT4fC-i#L)L!e*r6>-B{zzI2m3}{@y&q51ieH|IP1|;Akwh`>Mes{fy!}!( z2!-@{f61VFMBMXmuVdXMj^HfY{F!}9c6`s69!hLt0U4S;_GgchAN^Iu>G+iqFn*!( zMwJOO#4U+DUBYYw&D$h{Evs~{;bc3^iu%hOb>^@usrQ6!%O6b z#=zk~0$LYq`WD-A_*UVA@IZd3lMO1c|-7 zGE|ZfGE)-veAv%P9O%9%;V)6R2ZTdDh!qvIfU+4zZv+gJ$|#-GRpTz&2YWsXIX>V# zh#4X@f0tK)n74xqryuu&pOMrOriFsYD#M7g>2mLpTZQ3x3eoV|b3~df{H|UPUWM8W z!}np~c~Tm#OM{=f^#t6;+80ltr}|x)ydP#M_tnO+>M^LAb}u|Ym8*Q;M_jTiD&z?t z)FpB8NNuAf4I)IA+Hwp<;is{@#g{a0egK@u0KLM&dky`ZwE{Dba1RSHYu9%hMR67K z{xHdAmnWG9K1@3gd&-<}r^V+j;Uqc@yltK&Urt!ktD$aqU>!R`VPOkWb$ULm#sdf_ zB%F}@M_Bg4iy5pg=P{3*phTNfAHIYd-OYwz-`qt|R;}#iA{JIgo=!@0H&xdZFS(k|`IF^VzMWKO%jF+q4pSU|+JdO8u4_{<@Xr6Z z%_EdAM3?X)}0z^?e%UTC}g_wT?c_ZicS6 ztzk01`poiaB}U*pV%CT_7-}`xove)w}1`UN(#Rn`Z-94s(chyIKYB1I00l-WXup>KG$#&wpEBs*(YPflVV=J>B!%!ahny1Dte4-S*e*5om8ZRk6wxrbqr#kfzw=gQNgoO-bsHML zZFvIUR`1#F>4==t97f;7x0OrnZ}MtU-rQ`ylHHi9<6BlrqFpXu$5lT-83an(JSUp; zJR+L3t{ub1bGDr2vPy8UJbD5XtwWn%<-xex2NT6E-RM}vn+CpezBENe)*16 zg7jPz*~G*5I7#}`Gq8Mue)I6@32Bnf&ZzzmLU}(8+f@Z>+ITAlb}OT8dT}EQK&7D_ zo4r(3lT>sMb<#Z*`-uM(&zB;lx1~Ixd_;G%WytJxPs3`FAZr<;Q6T%G1rsYaP~+-b zca9z(8~yljc*!JDI9}jmV*&3Jn@-9Srh@qP@Qkiksid|^dgSG^uYR)ChK(`CXbqD_ z=}qqO^_3T#ZQ9QA;E8?w^C znDc%k&(?(NjR~E{T&N-XD2>Ql0dwgLos8QAR0$Hg^dvG! zhAy)Z#RLfi%{tu(v$UR;PoALt#N|5=aUJfhX|ofjyH^35RsK!$6a~?CUqjLV0>olp zyQ{%FFA6<@PC_2=b#1ZLetQcyt&6BAy9bV;zmlGN5BHUoeCP5-DDLU{kc+r>@nq5G zAwHsxg~{u1!*>!Y9j%Y)<8Oklm|*nE{wEoF^du+jCvcTE149GX{*0RHbvb2d zjGk>08@0`(FoQI3jdoXXeH7b_C%Qr z@qt;?^YNySo2QiwgxfWHJ>bx?2x0{jUk+5MQtl7BEAa#m7f>{mB>OpI&#Hj$* zrn%8O3VI}`wJr}-qZ=|j7&@SzL*kYr1mdGGFp#jc= z<@OKMoa^Z5uzc@!!J5c7=bBFZq8LpaFNW*_4#k<3tYGQHk(EXI0)*&z_*6E|r_Mw(Y^vAOM{>hj9;q!;mK5~~K5R_Q(v*=* zyK<4f=xUl#<1Bu$8idfs+Q;U(U1dtn@ji~-6>Y5vsmAHbc+F-Gq;>3i0k^WgKd%9< ziU)t5x71WsM1{O)Q8+WExgSG?j?!AEur02%jDJO4IGO78^5;C1 z&6tPyJyi)6k)ZuYqwit16`h*5VmwAeD|%5VRoDBDZP+)k>(l&jGJP!1BsEI<54dyW z$K^JXqu2N>?3}hs-CPIkHf8p3?s4c%qx+c>sOmQC(l2@Z14U zHt_O@|6HEBurjcy1L#wM?9dm;&yk;_{_a~0zV0qYgz}rW^bytdY9$+r>VB;np{eEh zH2Af;))No;r}jadnw+C(shZNy!=O|V#b`yw$nxk|089)+QcQ!Y5SUen1d4}=mTV|= zYnUO!-iVIUUTd7vSQQ+c92`*(F+zlxQa$Bhtabbrdh){rgRyJhVIX(=9W@^+D z`=<-vvuwIzGGiBQ7Hfl~rJ5BX5q1w4C+T1D97SLBIF)l$cbwPED$tH}4ZrKZIC5d1 zUGY5jc&K+(&Nb~+%_H#k@;Te2&uOj0bT(Ir`)MWRwiTa2U+;N`E?2oA#)*88_>1yd z8@$}ucKYg81W9w#NX-@1iCmIEfKE&O@E2%%Y^&*1K(vo@3%!XSTmjrLHhcj3Xjwn= zw9I&`T;&ea2uqAX2d;wfM3l*8_A zVaw?fbxfnMM2vSu9j96n!nxDQlpH|VzkAgtggfUrGs}ooIfPQ@70Rd6L0FwgVf2j; z0noVRu=k(Gy4syYDsAAT=>lKBCXeTO^2*h7%SIVL_bn|gES0I#vCwxj(Wy%Te+(5V zOEGp20Q)|A0nFn{bPRnepLTiC`$FP zD(^TTD@*08?)1p^1OF)as7^N^#VoD%Sw>Et znMIx{Uv&`JHv;Uo>zBR9pa7JKM}2YlViz^|7$O)F2B;LT)Q*-eo)<)qxJ!mXuC5=W z1*M9b?eft}-WPzSvAk@uY|7|`kQ*xW#Vng10=uR6%f6R1Xj3ggDH97co>b!l;5|ei z?RT4uik6BfP~ZMKh@h!wJNXFfrM~wiT-r;`Cnon3zudo9#-kbf5ujMzR-1~3w_ z8%Y2-HE#0Er0dF*n$$8-UY&VS9M*njKeZ01IG z;(S~lpl}+{8_}5KG99^@!9^n`g-QH#Qp~$+fX7{P`6FkGyw7+1CEk1VA6-Zn;!?~) zPK)Dg;HKcE%ZQv*3AYzJ{7|OIoLo<5Xtzzp@qCo;ztNC-8cnb|rnX)H?fq!D^C1-@ zob5&fRNT}UgoIJ{C<)V+Vpru5YD{+ zWS(h`NgU7tKghMQ7k;|Pmh+mMq2%ejM&*_CNe*OIaoMT^!9fXbZFX-6$M&`eHgo59 zyd_~{M2Yi>xsuB2MY_u3M%EJT{SwX$2|HPYXA6U`aTZ>2Dp3=VR3zs^9wQ@cPH5X8 z`FG=z1m}8p5>1qvmA~VUCE&csl^O%cS=mNl#h@!Ha49iL3$?G46g%^hoVym26Es^U zG&2W2C+Y?IzaRS(pfur#dV6@{PYZp_ki4d(u9-H)h zW_3It9OtStO5`}U^&xpTe;*g6b4b*IJ8Zf}kk>aRTg{o{sGBPJ2THrvF;Pxi5 z!TS1g#&B87C*?e<;^m0JSK%z(ZgPseWg^{t=I*$n%F~!>CoX83_l-w!P8W=y2nu2< zeJIK#Xw0af<_}0u_57mIE9W60E#uqJ3C|LIa%NY{C&c#TO-N&Pk;uId1PBaCv!307 z5FM{L9v~vemPrhgXcW(EaG&lSpBJAmwr%t**l?sswKcb&EOe=VXsAi3h;_HeSKuTR zU#Q_2j3Qle-bZ|)07ZAK>MnjIC#&39@$?K!gEh7zb2Pap)eDnVrX(2y@H5m53ReC7 z3~csXz&e12u%Di_+#fUITj!EOdBBn#RPqnc5x_ZDBU(-?;G{(;mq-iE7%Kc((FVyk zWcNOaDs9AqOdYGj1cB0biWw_@=7ob(Q-HOim{Do^B1-x~f8GVlFt<71_4W)ZZ2I^y zj?#BQV{fVxW>GBLr=~J9Kf7W_DPpmrVP^E%;J#W*-smQ^J{y%M9=EVex*x((THY#v zXa`I(V9!O;+^t(+bq$pG<>zNWp3v_zd(NjV9WDJ{f; z?d7kW@$Y=tCJYM;&>a5zb?rl|NUEx8v54N>$ommkSblnITS@}&eIvlg+|3_Jy^IpJ zeSKY6AF)G9vnn1G6jE6gO53hRNRQV%N|;uoNrB$;As~D8)iz7+#&{+iJKt=QYd!Up zH6V@@UW~QzVdoHHL|P9MR&T8lNpthyS#}8>N%gZq^AaIPq%n= zo2C5t6YuS~MEkVSVoR`e?wsSoazlsA7A+-xe(y^lV&0yDQ{2$y_6URMeA|VI4ZZe&O>Vtc~-e!roqdM}qL}sJ*l>+!#QmCITqh+)qc7_C#Z`SEu6Z zK1(V6-rr8pP;14sJfb#Xyt_hgR<9VRD#sjNAHiOytvjqjQgZJt{OB03>)Wz)%Gw@V zT9<0#*^7sdZ97pefI?%CP;?N#OYX1TCh&7zsD6DskPu{lKBj+8c|rX18%PK|2naX2 zHmQPENQlqs%mxjukYxF1hfCG1K(&r*@=fv+{LB-}6sz{#|4tnR~aA!F7Z|$=Rq75dWwO-$kAqg1(gut^f;4mcW33_@f7V z7uZV^_Es>sJ|rmE8|PoO$h*MJrUuWLQ{#asL*10p$iz z|B-wF!~PWCmIX1$&576`*c*ckE(!vQ{XqK*`%5AOjQk%{Z%B>{LcTFX;JP57WEeUS zm5{s85V?4_qQRv=K+)Df^dDi6yTGX|1h<00B{M+5@2{Wft_3vi!U|Oq-iiemd;rCA zG2X~O+(n+_BfgakE?xji?qC9yGPsNF)k<+H(PK!2~6va^8@sz|j9)&+3$a4f^jsL{PNpBOv-uS0WfW z%&NYu_-4=$(^P+ve+A*dT8}`YJQ0tPR>1_gf+`8DKUrPz0o$vm0<8uH)8si0(ZiEHxjQdKar zCo!BHs1b!`0U_URL=hlB$((?H$iP4e82Ue-pkW9r2>Ql~f>-r{qC +#endif + +extern void free __P((void *)); +extern void *malloc __P((size_t)); +extern void *realloc __P((void *, size_t)); +extern void *calloc __P((size_t, size_t)); +extern void *alloca __P((size_t)); + +#endif diff --git a/include/math.h b/include/math.h new file mode 100755 index 00000000..5ad0f609 --- /dev/null +++ b/include/math.h @@ -0,0 +1,34 @@ +/* + */ + +#ifndef _MATH_H +#define _MATH_H + +extern double fabs(double); +extern double floor(double); +extern double ceil(double); +extern double modf(double, double *); +extern double frexp(double, int *); +extern double ldexp(double, int); +extern double atof(char *); + +extern double sqrt(double); + +extern double sin(double); +extern double cos(double); +extern double tan(double); +extern double asin(double); +extern double acos(double); +extern double atan(double); +extern double atan2(double, double); +extern double sinh(double); +extern double cosh(double); +extern double tanh(double); + +extern double log(double); +extern double log10(double); +extern double pow(double, double); +extern double exp(double); + +extern double eval_poly(double, double *, int); +#endif diff --git a/include/mem.h b/include/mem.h new file mode 100755 index 00000000..93755cba --- /dev/null +++ b/include/mem.h @@ -0,0 +1,54 @@ +#ifndef __MEM_H +#define __MEM_H +#ifndef __TYPES_H +#include +#endif +#include + +#ifdef _MSX_DOS /* HI-TECH-C/MSX-DOS MEM.H */ + +#ifndef _STDDEF +typedef int ptrdiff_t; /* result type of pointer difference */ +typedef unsigned size_t; /* type yielded by sizeof */ +#define _STDDEF +#define offsetof(ty, mem) ((int)&(((ty *)0)->mem)) +#endif /* _STDDEF Nick */ + +#ifndef NULL +#define NULL ((void *)0) +#endif /* NULL Nick */ + +extern int errno; /* system error number */ + +extern void * memcpy __P ((void *, void *, size_t)); +extern void * memmove __P ((void *, void *, size_t)); +extern int memcmp __P ((void *, void *, size_t)); +extern void * memchr __P ((void *, int, size_t)); +extern void * memset __P ((void *, int, size_t)); + +#else /* UZIX-hosted MEM.H */ + +/* Basic mem functions */ +extern void * memcpy __P ((void*, void*, size_t)); +extern void * memccpy __P ((void*, void*, int, size_t)); +extern void * memchr __P ((void*, int, size_t)); +extern void * memset __P ((void*, int, size_t)); +extern int memcmp __P ((void*, void*, size_t)); +extern void * memmove __P ((void*, void*, size_t)); + +/* BSDisms */ +#define index strchr +#define rindex strrchr +#define strcasecmp stricmp +#define strncasecmp strnicmp + +#ifdef z80 +#pragma inline(memcpy) +#pragma inline(memset) +#pragma inline(strcpy) +#pragma inline(strlen) +#pragma inline(strcmp) +#endif + +#endif /* END OF DEFINITION MEM.H */ +#endif diff --git a/include/memory.h b/include/memory.h new file mode 100755 index 00000000..05041a20 --- /dev/null +++ b/include/memory.h @@ -0,0 +1,3 @@ +#ifndef __STRING_H +#include +#endif diff --git a/include/ncurses.h b/include/ncurses.h new file mode 100755 index 00000000..5e275b74 --- /dev/null +++ b/include/ncurses.h @@ -0,0 +1,7 @@ +/* + ncurses.h + + just a fake - equal to curses.h +*/ + +#include \ No newline at end of file diff --git a/include/paths.h b/include/paths.h new file mode 100755 index 00000000..daa311a2 --- /dev/null +++ b/include/paths.h @@ -0,0 +1,32 @@ +#ifndef __PATHS_H +#define __PATHS_H + +#define _PATH_DEV "/dev/" +#define _PATH_DEVNULL "/dev/null" +#define _PATH_CONSOLE "/dev/console" +#define _PATH_TTY "/dev/tty" +#if 1 /* Nick */ +#define _PATH_PRINTER "/dev/printer" +#endif + +#define _PATH_TMP "/tmp/" +#define _PATH_UTMP "/var/run/utmp" + +#define _PATH_INIT "/bin/init" +#define _PATH_LOGIN "/bin/login" +#define _PATH_BSHELL "/bin/sh" +#define _PATH_DEFPATH ".:/bin:/usr/bin:/etc:/usr/local/bin" + +#if 1 /* Nick */ +#define _PATH_LIBERR "/lib/liberror.txt" +#else +#define _PATH_LIBERR "/usr/lib/liberror.txt" +#endif + +#define _PATH_TERMCAP "/etc/termcap" +#define _PATH_PASSWD "/etc/passwd" +#define _PATH_GROUP "/etc/group" + +#define _PATH_HOME "/home" + +#endif /* __PATHS_H */ diff --git a/include/pwd.h b/include/pwd.h new file mode 100755 index 00000000..01cacf3c --- /dev/null +++ b/include/pwd.h @@ -0,0 +1,37 @@ +#ifndef __PWD_H +#define __PWD_H +#ifndef __TYPES_H +#include +#endif +#include + +/* The passwd structure. */ +struct passwd { + char *pw_name; /* Username */ + char *pw_passwd; /* Password */ + int pw_uid; /* User ID */ + int pw_gid; /* Group ID */ + char *pw_gecos; /* Real name */ + char *pw_dir; /* Home directory */ + char *pw_shell; /* Shell program */ +}; + +extern void setpwent __P((void)); +extern void endpwent __P((void)); +extern struct passwd *getpwent __P((void)); + +extern int putpwent __P((struct passwd * __p, FILE * __f)); +extern int getpw __P((int uid, char *buf)); + +extern struct passwd *fgetpwent __P((FILE * file)); + +extern struct passwd *getpwuid __P((int __uid)); +extern struct passwd *getpwnam __P((char *)); + +extern struct passwd * __getpwent __P((int passwd_fd)); + +extern char *_path_passwd; + +#define getlogin() getpwnam(getuid()) + +#endif /* pwd.h */ diff --git a/include/regexp.h b/include/regexp.h new file mode 100755 index 00000000..263b90ad --- /dev/null +++ b/include/regexp.h @@ -0,0 +1,27 @@ +/* + * Definitions etc. for regexp(3) routines. + * + * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], + * not the System V one. + */ +#ifndef __REGEXP_H +#define __REGEXP_H + +#define NSUBEXP 10 + +typedef struct regexp { + char *startp[NSUBEXP]; + char *endp[NSUBEXP]; + char regstart; /* Internal use only. */ + char reganch; /* Internal use only. */ + char *regmust; /* Internal use only. */ + int regmlen; /* Internal use only. */ + char program[1]; /* Unwarranted chumminess with compiler. */ +} regexp; + +extern regexp *regcomp __P((char *)); +extern int regexec __P((regexp *prog, char *string)); +extern void regsub __P((regexp *prog, char *source, char *dest)); +extern void regerror __P((char *)); + +#endif diff --git a/include/regmagic.h b/include/regmagic.h new file mode 100755 index 00000000..7fd76a5d --- /dev/null +++ b/include/regmagic.h @@ -0,0 +1,5 @@ +/* + * The first byte of the regexp internal "program" is actually this magic + * number; the start node begins in the second byte. + */ +#define MAGIC 0234 diff --git a/include/search.h b/include/search.h new file mode 100755 index 00000000..fbe82287 --- /dev/null +++ b/include/search.h @@ -0,0 +1,55 @@ +#ifndef __SEARCH_H +#define __SEARCH_H +#ifndef __TYPES_H +#include +#endif +#include + +#ifndef __COMPAR_FN_T +#define __COMPAR_FN_T +typedef int (*__compar_fn_t) __P((__ptr_t, __ptr_t)); +#endif + +/* for use with hsearch(3) */ + +typedef struct entry { char *key; char *data; } ENTRY; +typedef enum { FIND, ENTER } ACTION; + +extern ENTRY * hsearch __P((ENTRY __item, ACTION __action)); +extern int hcreate __P((unsigned __nel)); +extern void hdestroy __P((void)); + +/* The tsearch routines are very interesting. They make many + * assumptions about the compiler. It assumpts that the first field + * in node must be the "key" field, which points to the datum. + * Everything depends on that. It is a very tricky stuff. H.J. + */ +/* For tsearch */ +typedef enum { preorder, postorder, endorder, leaf } VISIT; + +extern void *tsearch __P((void *__key, void **__rootp, __compar_fn_t compar)); + +extern void *tfind __P((void *__key, void ** __rootp, __compar_fn_t compar)); + +extern void *tdelete __P((void * __key, void ** __rootp, __compar_fn_t compar)); + +#ifndef __ACTION_FN_T +#define __ACTION_FN_T +/* FYI, the first argument should be a pointer to "key". + * Please read the man page for details. + */ +typedef void (*__action_fn_t) __P((void *__nodep, VISIT __value, int __level)); +#endif + +extern void twalk __P((void * __root, __action_fn_t action)); + + +extern void * lfind __P((void * __key, void * __base, + size_t * __nmemb, size_t __size, + __compar_fn_t __compar)); + +extern void * lsearch __P((void * __key, void * __base, + size_t * __nmemb, size_t __size, + __compar_fn_t __compar)); + +#endif /* search.h */ diff --git a/include/setjmp.h b/include/setjmp.h new file mode 100755 index 00000000..7a606308 --- /dev/null +++ b/include/setjmp.h @@ -0,0 +1,172 @@ +/* - SETJMP.H - + + The ANSI "setjmp" and "longjmp" function declarations. + + $Name: V3_34K V3_34J $ + + Copyright 1986 - 1999 IAR Systems. All rights reserved. +*/ + +#ifndef _SETJMP_INCLUDED +#define _SETJMP_INCLUDED + +/* #include "sysmac.h" Nick */ +/* - SYSMAC.H - + + Defines system macros to maintain source compatibility + with different IAR compilers. + + $Name: V3_34K V3_34J V3_34I V3_34H $ + + Copyright 1986 - 1999 IAR Systems. All rights reserved. +*/ + +#ifndef _SYSMAC_H_ +#define _SYSMAC_H_ + + +#if defined(__IAR_SYSTEMS_ICC) && !defined(__IAR_SYSTEMS_ICC__) +#define __IAR_SYSTEMS_ICC__ 1 +#endif + +#if __IAR_SYSTEMS_ICC__ > 4 +#error __IAR_SYSTEMS_ICC__ > 4 not available yet! +#endif + +#ifndef __CHAR_SIZE__ +#define __CHAR_SIZE__ sizeof(char) +#endif + +#ifndef __SHORT_SIZE__ +#define __SHORT_SIZE__ sizeof(short) +#endif + +#ifndef __INT_SIZE__ +#define __INT_SIZE__ sizeof(int) +#endif + +#ifndef __LONG_SIZE__ +#define __LONG_SIZE__ sizeof(long) +#endif + +#ifndef __FLOAT_SIZE__ +#define __FLOAT_SIZE__ sizeof(float) +#endif + +#ifndef __DOUBLE_SIZE__ +#define __DOUBLE_SIZE__ sizeof(double) +#endif + +#ifndef __LONG_DOUBLE_SIZE__ +#define __LONG_DOUBLE_SIZE__ sizeof(long double) +#endif + +#ifndef __SIZE_T_TYPE__ +#if sizeof((char*)0 - (char*)0) <= sizeof(int) +#define __SIZE_T_TYPE__ unsigned int +#else +#define __SIZE_T_TYPE__ unsigned long +#endif +#endif + +#ifndef __PTRDIFF_T_TYPE__ +#if sizeof((char*)0 - (char*)0) <= sizeof(int) +#define __PTRDIFF_T_TYPE__ unsigned int +#else +#define __PTRDIFF_T_TYPE__ unsigned long +#endif +#endif + +#ifndef __JMP_BUF_ELEMENT_TYPE__ +#ifndef __JMP_BUF_NUM_ELEMENTS__ +#define __JMP_BUF_ELEMENT_TYPE__ char +#ifndef __JMP_BUF__ +#define __JMP_BUF_NUM_ELEMENTS__ 8 +#else +#define __JMP_BUF_NUM_ELEMENTS__ __JMP_BUF__ +#endif +#endif +#endif + + +#define __INTRINSIC +#if __IAR_SYSTEMS_ICC__ >= 2 +#undef __INTRINSIC +#define __INTRINSIC __intrinsic +#endif + +/* Macro for frmwri and frmrd */ +#define VAPTR(T) (va_arg(ap, T *)) + +/* Typedefs put here to appear only once */ +/* typedef __SIZE_T_TYPE__ size_t; Nick */ +typedef __PTRDIFF_T_TYPE__ ptrdiff_t; + +#endif /* _SYSMAC_H_ */ +/* end of #include "sysmac.h" Nick */ + +/*==========================*/ +/* ICCH8500 ,ICCH83 and H8S */ +/* have word alignment. */ +/*==========================*/ +#if ((__TID__ >> 8) & 0x7f) == 9 \ + || ((__TID__ >> 8) & 0x7f) == 10 \ + || ((__TID__ >> 8) & 0x7f) == 27 +typedef short jmp_buf[__JMP_BUF_NUM_ELEMENTS__ >> 1]; +#else +typedef __JMP_BUF_ELEMENT_TYPE__ jmp_buf[__JMP_BUF_NUM_ELEMENTS__]; +#endif + +#if __IAR_SYSTEMS_ICC__ < 2 +#if __TID__ & 0x8000 +#pragma function=intrinsic(0) +#endif +#endif + +#ifndef MEMORY_ATTRIBUTE +#define MEMORY_ATTRIBUTE +#endif + + +/*======================*/ +/* ICCH83 can not be */ +/* completely ANSI for */ +/* the return value */ +/* type from 'setjump'. */ +/*----------------------*/ +/* Calls to 'longjmp' */ +/* and 'setjmp' must be */ +/* calls to standard */ +/* functions. */ +/*======================*/ +#if ((__TID__ & 0x7F00) >> 8) == 10 + +#if __IAR_SYSTEMS_ICC__ < 2 +#pragma function=__standard_function +MEMORY_ATTRIBUTE short setjmp(jmp_buf); +MEMORY_ATTRIBUTE void longjmp(jmp_buf, short); +#pragma function=default +#else +#error Make sure this pragma is supported when upgrading! +#endif + +/*======================*/ +/* Nothing special with */ +/* all the others. */ +/*======================*/ +#else + +__INTRINSIC MEMORY_ATTRIBUTE int setjmp(jmp_buf); +__INTRINSIC MEMORY_ATTRIBUTE void longjmp(jmp_buf, int); + +#endif + + + +#if __IAR_SYSTEMS_ICC__ < 2 +#if __TID__ & 0x8000 +#pragma function=default +#endif +#endif + +#endif /* _SETJMP_INCLUDED */ diff --git a/include/setjmp.h$ b/include/setjmp.h$ new file mode 100755 index 00000000..2a96e863 --- /dev/null +++ b/include/setjmp.h$ @@ -0,0 +1,38 @@ +#ifndef __SETJMP_H +#define __SETJMP_H +#ifndef __TYPES_H +#include +#endif + +#ifdef __TURBOC__ +/* + * I know most systems use an array of ints here, but I prefer this - RDB + */ +typedef struct { + unsigned int pc; + unsigned int sp; + unsigned int bp; + unsigned int si; + unsigned int di; +} jmp_buf[1]; +#else + +#ifdef HI_TECH_C + +typedef int jmp_buf[7]; + +#else + +#error fillin setjmp.h! + +#endif +#endif + +int setjmp __P((jmp_buf env)); +#if 1 +int longjmp __P((jmp_buf env, int rv)); /* Nick */ +#else +void longjmp __P((jmp_buf env, int rv)); +#endif + +#endif diff --git a/include/sgtty.h b/include/sgtty.h new file mode 100755 index 00000000..bc484575 --- /dev/null +++ b/include/sgtty.h @@ -0,0 +1,38 @@ +#define TIOCGETP 0 +#define TIOCSETP 1 +#define TIOCSETN 2 +/** +#define TIOCEXCL 3 +#define TIOCNXCL 4 +#define TIOCHPCL 5 +**/ +#define TIOCFLUSH 6 +#define TIOCGETC 7 +#define TIOCSETC 8 +#define TIOCTLSET 9 +#define TIOCTLRES 10 + +#define XTABS 0006000 +#define UNBUFF 0000100 /* Nick */ +#define RAW 0000040 +#define CRMOD 0000020 +#define CRLF 0000020 +#define ECHO 0000010 +#define LCASE 0000004 +#define CBREAK 0000002 +#define COOKED 0000000 + + +struct sgttyb { + char sg_ispeed, sg_ospeed; + char sg_erase, sg_kill; + int sg_flags; +}; + +struct tchars { + char t_intrc,t_quit,t_start,t_stop,t_eof; +}; + +#define stty( fd, s) (ioctl(fd, TIOCSETP, s)) +#define gtty( fd, s) (ioctl(fd, TIOCGETP, s)) + diff --git a/include/signal.h b/include/signal.h new file mode 100755 index 00000000..e30d4877 --- /dev/null +++ b/include/signal.h @@ -0,0 +1,99 @@ +#ifndef __SIGNAL_H +#define __SIGNAL_H +#ifndef __TYPES_H +#include +#endif + +#define NSIGS 16 /* Number of signals <= 16 */ + +#if 1 /* Nick, because the unix() system call needs integer parameters only */ +#define __NOTASIGNAL 0 +#define SIGHUP 1 /* Hangup detected on controlling terminal + or death of a controlling process */ +#define SIGINT 2 /* Interrupt from keyboard */ +#define SIGQUIT 3 /* Quit from keyboard */ +#define SIGILL 4 /* Illegal instruction */ +#define SIGTRAP 5 /* Trace/breakpoint trap */ +#define SIGIOT 6 /* IOT trap. A synonym for SIGABRT */ +#define SIGABRT SIGIOT /* Abort signal from abort */ +#define SIGUSR1 7 /* User's signal 1 */ +#define SIGUSR2 8 /* User's signal 2 */ +#define SIGKILL 9 /* Kill signal */ +#define SIGPIPE 10 /* Broken pipe: write to pipe with no readers */ +#define SIGALRM 11 /* Timer signal from alarm */ +#define SIGTERM 12 /* Termination signal */ +#define SIGURG 13 /* Urgent signal */ +#define SIGCONT 14 /* Continue process */ +#define SIGSTOP 15 /* Stop process */ +#define __NUMOFSIGNALS SIGSTOP +/* this signals defined only for compatibility */ +#define SIGBUS 16 /* Bus error */ +#define SIGFPE 17 /* Floating point exception */ +#define SIGSEGV 18 /* Invalid memory reference */ +#define SIGSYS 19 /* Bad argument to routine */ +#define SIGTTIN 20 +#define SIGTOUT 21 +typedef int signal_t; +#else +/* signals values */ +typedef enum { + __NOTASIGNAL = 0, + SIGHUP, /* Hangup detected on controlling terminal + or death of a controlling process */ + SIGINT, /* Interrupt from keyboard */ + SIGQUIT, /* Quit from keyboard */ + SIGILL, /* Illegal instruction */ + SIGTRAP, /* Trace/breakpoint trap */ + SIGIOT, /* IOT trap. A synonym for SIGABRT */ + SIGABRT = SIGIOT, /* Abort signal from abort */ + SIGUSR1, /* User's signal 1 */ + SIGUSR2, /* User's signal 2 */ + SIGKILL, /* Kill signal */ + SIGPIPE, /* Broken pipe: write to pipe with no readers */ + SIGALRM, /* Timer signal from alarm */ + SIGTERM, /* Termination signal */ + SIGURG, /* Urgent signal */ + SIGCONT, /* Continue process */ + SIGSTOP, /* Stop process */ +#define __NUMOFSIGNALS SIGSTOP + /* this signals defined only for compatibility */ + SIGBUS, /* Bus error */ + SIGFPE, /* Floating point exception */ + SIGSEGV, /* Invalid memory reference */ + SIGSYS, /* Bad argument to routine */ + SIGTTIN, + SIGTOUT +} signal_t; +#endif + +#if __NUMOFSIGNALS > NSIGS + error Too many signals defined +#endif + +#define sigmask(sig) (1<<((sig)-1)) /* signal mask */ + +typedef uint sigset_t; /* at least 16 bits */ + +/* Type of a signal handler. */ +#if 1 /* Nick, for IAR compiler large or banked memory model */ +typedef long sig_t; +#else +typedef void (*sig_t) __P((signal_t)); +#endif + +#define SIG_DFL ((sig_t)0) /* default signal handling */ +#define SIG_IGN ((sig_t)1) /* ignore signal */ +#define SIG_ERR ((sig_t)-1) /* error return from signal */ + +#if 0 +struct sigaction { + sig_t sa_handler; + sigset_t sa_mask; + uint sa_flags; + void (*sa_restorer)( /*void*/ ); +}; +#endif + +extern char *sys_siglist[]; + +#endif diff --git a/include/stdarg.h b/include/stdarg.h new file mode 100755 index 00000000..d918fd86 --- /dev/null +++ b/include/stdarg.h @@ -0,0 +1,23 @@ +#ifndef __STDARG_H +#define __STDARG_H + +#ifndef __VARARGS_H +#ifdef HI_TECH_C /* HTC-MSDOS STDARG.H */ + +typedef void *va_list[1]; +#define _STACK_ALIGN 2 +#define va_start(ap, parmn) *ap = (char *)&parmn + ((sizeof(parmn)+_STACK_ALIGN-1)&~(_STACK_ALIGN-1)) +#define va_arg(ap, type) (*(*(type **)ap)++) +#define va_end(ap) + +#else /* STDARG.H (TC2.0) */ + +typedef void *va_list; +#define va_start(ap, p) (ap = (char *) (&(p)+1)) +#define va_arg(ap, type) ((type *) (((char *)ap) += sizeof(type)))[-1] +#define va_end(ap) + +#endif +#endif + +#endif /* __STDARG_H */ diff --git a/include/stddef.h b/include/stddef.h new file mode 100755 index 00000000..69ed6f4a --- /dev/null +++ b/include/stddef.h @@ -0,0 +1,13 @@ +#ifndef __STDDEF_H +#define __STDDEF_H + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#endif /* __STDDEF_H */ diff --git a/include/stdio.h b/include/stdio.h new file mode 100755 index 00000000..ed57dabf --- /dev/null +++ b/include/stdio.h @@ -0,0 +1,160 @@ +#ifndef __STDIO_H +#define __STDIO_H +#ifndef __TYPES_H +#include +#endif +#include + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#define _IOFBF 0x00 /* full buffering */ +#define _IOLBF 0x01 /* line buffering */ +#define _IONBF 0x02 /* no buffering */ +#define __MODE_BUF 0x03 /* Modal buffering dependent on isatty */ + +#define __MODE_FREEBUF 0x04 /* Buffer allocated with malloc, can free */ +#define __MODE_FREEFIL 0x08 /* FILE allocated with malloc, can free */ + +#define __MODE_READ 0x10 /* Opened in read only */ +#define __MODE_WRITE 0x20 /* Opened in write only */ +#define __MODE_RDWR 0x30 /* Opened in read/write */ + +#define __MODE_READING 0x40 /* Buffer has pending read data */ +#define __MODE_WRITING 0x80 /* Buffer has pending write data */ + +#define __MODE_EOF 0x100 /* EOF status */ +#define __MODE_ERR 0x200 /* Error status */ +#define __MODE_UNGOT 0x400 /* Buffer has been polluted by ungetc */ + +#ifdef __MSDOS__ +#define __MODE_IOTRAN 0x1000 /* MSDOS nl <-> cr,nl translation */ +#else +#define __MODE_IOTRAN 0 +#endif + +/* when you add or change fields here, be sure to change the initialization + * in stdio_init and fopen */ +struct __stdio_file { + uchar *bufpos; /* the next byte to write to or read from */ + uchar *bufread; /* the end of data returned by last read() */ + uchar *bufwrite; /* highest address writable by macro */ + uchar *bufstart; /* the start of the buffer */ + uchar *bufend; /* the end of the buffer; ie the byte after + the last malloc()ed byte */ + int fd; /* the file descriptor associated with the stream */ + int mode; + char unbuf[8]; /* The buffer for 'unbuffered' streams */ + struct __stdio_file * next; +}; + +#define EOF (-1) +#ifndef NULL +#define NULL (0) +#endif + +typedef struct __stdio_file FILE; + +extern FILE stdin[1]; +extern FILE stdout[1]; +extern FILE stderr[1]; + +#if 1 /* Nick, we want smaller code size, and "Inline_init", def x__MSDOS__ */ +#define putc(c, fp) fputc(c, fp) +#define getc(fp) fgetc(fp) +#else +#define putc(c, stream) \ + (((stream)->bufpos >= (stream)->bufwrite) ? \ + fputc((c), (stream)) : \ + (uchar) (*(stream)->bufpos++ = (c))) +#define getc(stream) \ + (((stream)->bufpos >= (stream)->bufread) ? \ + fgetc(stream) : \ + (*(stream)->bufpos++)) +#endif + +#define putchar(c) putc((c), stdout) +#define getchar() getc(stdin) + +extern char *gets __P((char *)); + +extern int _putchar __P((int)); +extern int _getchar __P((void)); + +#define ferror(fp) (((fp)->mode&__MODE_ERR) != 0) +#define feof(fp) (((fp)->mode&__MODE_EOF) != 0) +#define clearerr(fp) ((fp)->mode &= ~(__MODE_EOF|__MODE_ERR)) +#define fileno(fp) ((fp)->fd) + +/* These two call malloc */ +extern int setvbuf __P((FILE*, char*, int, size_t)); +#define setlinebuf(__fp) setvbuf((__fp), (char*)0, _IOLBF, 0) + +/* These don't */ +extern void setbuffer __P((FILE*, char*, size_t)); +#define setbuf(__fp, __buf) setbuffer((__fp), (__buf), BUFSIZ) + +extern int fgetc __P((FILE*)); +extern int fputc __P((int, FILE*)); +extern int ungetc __P((int, FILE*)); + +extern int fclose __P((FILE*)); +extern int fflush __P((FILE*)); +#define stdio_pending(fp) ((fp)->bufread > (fp)->bufpos) +extern char *fgets __P((char*, size_t, FILE*)); +extern FILE *__fopen __P((char*, int, FILE*, char*)); + +#if 1 +#define fopen(__file, __mode) __fopen((__file), -1, (FILE*)0, (__mode)) +#define freopen(__file, __mode, __fp) __fopen((__file), -1, (__fp), (__mode)) +#define fdopen(__file, __mode) __fopen((char*)0, (__file), (FILE*)0, (__mode)) +#else +extern FILE * fopen __P((char *__file, char *__mode)); +extern FILE * freopen __P((char *__file, char *__mode, int __fp)); +extern FILE * fdopen __P((int __fd, char *__mode)); +#endif + +extern int fputs __P((void *, FILE*)); +extern int puts __P((void *)); + +extern int fread __P((void *, size_t, size_t, FILE *)); +extern int fwrite __P((void *, size_t, size_t, FILE *)); + +extern int fseek __P((FILE *fp, long offset, int whence)); +extern long ftell __P((FILE *fp)); + +extern int printf __P((char*, ...)); +extern int fprintf __P((FILE*, char*, ...)); +extern int sprintf __P((char*, char*, ...)); + +extern int vprintf __P((char*, va_list)); +extern int vfprintf __P((FILE*, char*, va_list)); +extern int vsprintf __P((char*, char*, va_list)); + +#if 0 +typedef int (*_printer_func_t) __P((int, void *)); +extern int _vprinter(_printer_func_t prt, void *, char *, ...)); +#endif + +extern int scanf __P((char*, ...)); +extern int fscanf __P((FILE*, char*, ...)); +extern int sscanf __P((char*, char*, ...)); + +extern int vscanf __P((char*, va_list)); +extern int vfscanf __P((FILE*, char*, va_list)); +extern int vsscanf __P((char*, char*, va_list)); + +extern void perror __P((char *__s)); +extern char *strerror __P((int __errno)); + +extern char *tmpnam __P((char *buf)); + +extern int rename __P((char *oldname, char *newname)); +extern void rewind __P((FILE *fp)); +extern FILE *popen __P((char *, char *)); +extern int pclose __P((FILE *)); + +#endif /* __STDIO_H */ diff --git a/include/stdlib.h b/include/stdlib.h new file mode 100755 index 00000000..54c13963 --- /dev/null +++ b/include/stdlib.h @@ -0,0 +1,93 @@ +#ifndef __STDLIB_H +#define __STDLIB_H +#ifndef __TYPES_H +#include +#endif +#include + +/* Don't overwrite user definitions of NULL */ +#ifndef NULL +#define NULL ((void *) 0) +#endif + +/* Returned by `div' */ +typedef struct { + int quot; /* Quotient */ + int rem; /* Remainder */ +} div_t; + +/* Returned by `ldiv' */ +typedef struct { + long int quot; /* Quotient */ + long int rem; /* Remainder */ +} ldiv_t; + +/* For program termination */ +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +extern void _exit __P((int)); +extern void exit __P((int)); +extern void abort __P((void)); + +extern unsigned int sleep __P((unsigned int seconds)); + +extern int rand __P((void)); +extern void srand __P((uint seed)); + +extern char *__longtoa __P((unsigned long, char *, int, char, char)); +extern char *itoa __P((int value, char *strP, int radix)); +extern char *ultoa __P((unsigned long value, char *strP, int radix)); +extern char *ltoa __P((long value, char *strP, int radix)); + +extern int atoi __P((char *str)); +extern long atol __P((char *strP)); + +extern char *_itoa __P((int value)); +extern char *_ltoa __P((long value)); +extern char *_ultoa __P((unsigned long value)); + +extern char *ultostr __P((unsigned long value, int radix)); +extern char *ltostr __P((long value, int radix)); + +extern long strtol __P ((char * nptr, char ** endptr, int base)); +extern unsigned long strtoul __P ((char * nptr, + char ** endptr, int base)); +#ifndef __HAS_NO_FLOATS__ +extern double strtod __P ((char * nptr, char ** endptr)); +#endif + +extern char **environ; +extern char *getenv __P((char *)); +extern int putenv __P((char *)); +extern int setenv __P((char *, char *, int)); +extern void unsetenv __P((char *)); + +typedef void (*atexit_t) __P((int)); +typedef void (*onexit_t) __P((int, void *)); +extern int atexit __P((atexit_t)); +extern int on_exit __P((onexit_t, void *arg)); +extern onexit_t __cleanup; + +extern char *crypt __P((char *__key, char *__salt)); + +typedef int (*cmp_func_t) __P((void *, void *)); + +extern int _bsearch; +extern void *bsearch __P((void *key, void *base, size_t num, size_t size, cmp_func_t cmp)); +extern void *lfind __P((void *key, void *base, size_t *num, size_t size, cmp_func_t cmp)); +extern void *lsearch __P((void *key, void *base, size_t *num, size_t size, cmp_func_t cmp)); +extern void *_qbuf; +extern void qsort __P((void *base, size_t num, size_t size, cmp_func_t cmp)); + +extern int opterr; +extern int optind; +extern char *optarg; +extern int getopt __P((int argc, char *argv[], char *optstring)); + +extern char *getpass(char *prompt); + +extern int _argc; +extern char **_argv; + +#endif /* __STDLIB_H */ diff --git a/include/string.h b/include/string.h new file mode 100755 index 00000000..f1176e82 --- /dev/null +++ b/include/string.h @@ -0,0 +1,99 @@ +#ifndef __STRING_H +#define __STRING_H +#ifndef __TYPES_H +#include +#endif +#include + +#ifdef _MSX_DOS /* HI-TECH-C/MSX-DOS STRING.H */ + +/* String functions */ + +#ifndef _STDDEF +typedef int ptrdiff_t; /* result type of pointer difference */ +typedef unsigned size_t; /* type yielded by sizeof */ +#define _STDDEF +#define offsetof(ty, mem) ((int)&(((ty *)0)->mem)) +#endif /* _STDDEF Nick */ + +#ifndef NULL +#define NULL ((void *)0) +#endif /* NULL Nick */ + +extern int errno; /* system error number */ + +extern void * memcpy __P ((void *, void *, size_t)); +extern void * memmove __P ((void *, void *, size_t)); +extern char * strcpy __P ((char*, char*)); +extern char * strncpy __P ((char *, char *, size_t)); +extern char * strcat __P ((char*, char*)); +extern char * strncat __P ((char *, char *, size_t)); +extern int memcmp __P ((void *, void *, size_t)); +extern int strcmp __P ((char*, char*)); +extern int strncmp __P ((char *, char *, size_t)); +extern size_t strcoll __P ((char *, size_t, char *)); +extern void * memchr __P ((void *, int, size_t)); +extern size_t strcspn __P ((char *, char *)); +extern char * strpbrk __P ((char *, char *)); +extern size_t strspn __P ((char *, char *)); +extern char * strstr __P ((char *, char *)); +extern char * strtok __P ((char *, char *)); +extern void * memset __P ((void *, int, size_t)); +extern char * strerror __P ((int)); +extern size_t strlen __P ((char *)); +extern char * strchr __P ((char *, int)); +extern char * strrchr __P ((char *, int)); + +#else /* UZIX-hosted STRING.H */ + +/* Basic string functions */ +extern size_t strlen __P ((char* __str)); + +extern char * strcat __P ((char*, char*)); +extern char * strcpy __P ((char*, char*)); +extern int strcmp __P ((char*, char*)); + +extern char * strncat __P ((char*, char*, size_t)); +extern char * strncpy __P ((char*, char*, size_t)); +extern int strncmp __P((char*, char*, size_t)); + +extern int stricmp __P((char*, char*)); +extern strnicmp __P((char*, char*, size_t)); + +extern char * strchr __P ((char*, int)); +extern char * strrchr __P ((char*, int)); +extern char * strdup __P ((char*)); + +/* Basic mem functions */ +extern void * memcpy __P ((void*, void*, size_t)); +extern void * memccpy __P ((void*, void*, int, size_t)); +extern void * memchr __P ((void*, int, size_t)); +extern void * memset __P ((void*, int, size_t)); +extern int memcmp __P ((void*, void*, size_t)); + +extern void * memmove __P ((void*, void*, size_t)); + +/* BSDisms */ +#define index strchr +#define rindex strrchr +#define strcasecmp stricmp +#define strncasecmp strnicmp + +/* Other common BSD functions */ +char *strpbrk __P ((char *, char *)); +char *strsep __P ((char **, char *)); +char *strstr __P ((char *, char *)); +char *strtok __P ((char *, char *)); +size_t strcspn __P ((char *, char *)); +size_t strspn __P ((char *, char *)); + +#ifdef z80 +#pragma inline(memcpy) +#pragma inline(memset) +#pragma inline(strcpy) +#pragma inline(strlen) +#pragma inline(strcmp) +#endif + +#endif /* END OF DEFINITION STRING.H */ +#endif diff --git a/include/strings.h b/include/strings.h new file mode 100755 index 00000000..05041a20 --- /dev/null +++ b/include/strings.h @@ -0,0 +1,3 @@ +#ifndef __STRING_H +#include +#endif diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h new file mode 100755 index 00000000..8bf22d29 --- /dev/null +++ b/include/sys/cdefs.h @@ -0,0 +1,24 @@ +#ifndef _SYS_CDEFS_H +#define _SYS_CDEFS_H +#ifndef __FEATURES_H +#include +#endif + +#ifdef __TURBOC__ +#define __CONCAT(x,y) x ## y +#define __STRING(x) #x +#else +#ifdef __STDC__ +#define __CONCAT(x,y) x ## y +#define __STRING(x) #x +#else +#define __CONCAT(x,y) x/**/y +#define __STRING(x) "x" +#endif /* __STDC__ */ +#endif /* __TURBOC__ */ + +/* This is not a typedef so `const __ptr_t' does the right thing */ +/* For K&R 'void' defined as 'char' */ +#define __ptr_t void * + +#endif diff --git a/include/sys/exec.h b/include/sys/exec.h new file mode 100755 index 00000000..e96f9483 --- /dev/null +++ b/include/sys/exec.h @@ -0,0 +1,4 @@ +#ifndef _SYS_EXEC_H +#define _SYS_EXEC_H + +#endif diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h new file mode 100755 index 00000000..c1d308c9 --- /dev/null +++ b/include/sys/ioctl.h @@ -0,0 +1,38 @@ +#ifndef _SYS_IOCTL_H +#define _SYS_IOCTL_H + +typedef enum { + GI_PTAB = -1, /* processes table */ + GI_ITAB = -2, /* inodes table */ + GI_BTAB = -3, /* buffers table */ + GI_FTAB = -4, /* filesystems table */ + GI_UDAT = -5, /* process user data */ + GI_UTAB = -6, /* current process table */ + GI_PDAT = -7, /* process info */ + GI_KDAT = -8 /* kernel info */ +} getinfo_t; + +/* control of /dev/mem device */ +#define MEM_INFO 0 + +#if 0 /* Nick, it conflicts with TIOCSETP etc, see c:\uzi\include\sgtty.h */ +/* control of /dev/tty device */ +#define TTY_COOKED 0 /* buffered */ +#define TTY_RAW 1 /* unbuffered, wait */ +#define TTY_RAW_UNBUFF 2 /* unbuffered, no wait */ +#endif + +struct swap_mmread { + uchar mm[2]; + uint offset; + uint size; + uchar *buf; +}; + +typedef struct { + getinfo_t req; + size_t size; + void *ptr; +} info_t; + +#endif diff --git a/include/sys/seek.h b/include/sys/seek.h new file mode 100755 index 00000000..a5d740ce --- /dev/null +++ b/include/sys/seek.h @@ -0,0 +1,19 @@ +#ifndef _SYS_SEEK_H +#define _SYS_SEEK_H + +#ifndef SEEK_OSET +#define SEEK_OSET 0 +#define SEEK_OCUR 1 +#define SEEK_OEND 2 +#define SEEK_BSET 3 +#define SEEK_BCUR 4 +#define SEEK_BEND 5 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#endif /* _SYS_SEEK_H */ diff --git a/include/sys/stat.h b/include/sys/stat.h new file mode 100755 index 00000000..953a73d9 --- /dev/null +++ b/include/sys/stat.h @@ -0,0 +1,79 @@ +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#define S_IFMT 0170000 /* file type mask */ +#if 1 /* Nick */ +#define S_IFALIGN 0120000 /* regular file, XIP aligned */ +#endif +#define S_IFLNK 0110000 /* symbolic link */ +#define S_IFREG 0100000 /* or just 000000, regular */ +#define S_IFBLK 0060000 /* block special */ +#define S_IFDIR 0040000 /* directory */ +#define S_IFCHR 0020000 /* character special */ +#define S_IFPIPE 0010000 /* pipe */ + +#define S_UMASK 07777 /* bits modifiable by chmod */ + +#define S_ISUID 04000 /* set euid to file uid */ +#define S_ISGID 02000 /* set egid to file gid */ +#define S_ISVTX 01000 /* */ + +#define S_IREAD 0400 /* owner may read */ +#define S_IWRITE 0200 /* owner may write */ +#define S_IEXEC 0100 /* owner may execute */ + +#define S_IGREAD 0040 /* group may read */ +#define S_IGWRITE 0020 /* group may write */ +#define S_IGEXEC 0010 /* group may execute */ + +#define S_IOREAD 0004 /* other may read */ +#define S_IOWRITE 0002 /* other may write */ +#define S_IOEXEC 0001 /* other may execute */ + +#define S_IRWXU 00700 +#define S_IRUSR 00400 +#define S_IWUSR 00200 +#define S_IXUSR 00100 + +#define S_IRWXG 00070 +#define S_IRGRP 00040 +#define S_IWGRP 00020 +#define S_IXGRP 00010 + +#define S_IRWXO 00007 +#define S_IROTH 00004 +#define S_IWOTH 00002 +#define S_IXOTH 00001 + +#ifdef __KERNEL__ +#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO) +#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO) +#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH) +#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH) +#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH) +#endif + +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISPIPE(m) (((m) & S_IFMT) == S_IFPIPE) + +#if 1 /* Nick */ +#define S_ISDEV(m) (S_ISCHR(m) || S_ISBLK(m)) +#else +#define S_ISDEV(m) (((m) & S_IFMT) & S_IFCHR) +#endif + +#if 1 /* Nick */ +#define S_ISALIGN(m) (((m) & S_IFMT) == S_IFALIGN) +#define S_ISREGALIGN(m) (S_ISREG(m) || S_ISALIGN(m)) +#endif + +#if 1 /* Nick free bitmap */ +#define XIP_ALIGN 0 +#define XIP_UALIGN 1 +#endif + +#endif diff --git a/include/sys/utsname.h b/include/sys/utsname.h new file mode 100755 index 00000000..0219cd58 --- /dev/null +++ b/include/sys/utsname.h @@ -0,0 +1,18 @@ +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H +#ifndef __TYPES_H +#include +#endif + +struct utsname { + char sysname[14]; + char nodename[14]; + char release[8]; + char version[8]; + char machine[8]; + char domainname[14]; +}; + +extern int uname __P ((struct utsname * __utsbuf)); + +#endif diff --git a/include/sys/wait.h b/include/sys/wait.h new file mode 100755 index 00000000..0271de5f --- /dev/null +++ b/include/sys/wait.h @@ -0,0 +1,48 @@ +#ifndef _SYS_WAIT_H +#define _SYS_WAIT_H +#ifndef __TYPES_H +#include +#endif + +/* Bits in the third argument to `waitpid'. */ +#define WNOHANG 1 /* Don't block waiting. */ +#define WUNTRACED 2 /* Report status of stopped children. */ + +/* Everything extant so far uses these same bits. */ +/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */ +#define WEXITSTATUS(status) (((status) & 0xff00) >> 8) + +/* If WIFSIGNALED(STATUS), the terminating signal. */ +#define WTERMSIG(status) ((status) & 0x7f) + +/* If WIFSTOPPED(STATUS), the signal that stopped the child. */ +#define WSTOPSIG(status) WEXITSTATUS(status) + +/* Nonzero if STATUS indicates normal termination. */ +#define WIFEXITED(status) (((status) & 0xff) == 0) + +/* Nonzero if STATUS indicates termination by a signal. */ +#define WIFSIGNALED(status) (((unsigned int)((status)-1) & 0xFFFF) < 0xFF) + +/* Nonzero if STATUS indicates the child is stopped. */ +#define WIFSTOPPED(status) (((status) & 0xff) == 0x7f) + +/* Nonzero if STATUS indicates the child dumped core. */ +#define WCOREDUMP(status) ((status) & 0200) + +/* Macros for constructing status values. */ +#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) +#define W_STOPCODE(sig) ((sig) << 8 | 0x7f) + +/* Special values for the PID argument to `waitpid' and `wait4'. */ +#define WAIT_ANY (-1) /* Any process. */ +#define WAIT_MYPGRP 0 /* Any process in my process group. */ + +extern int waitpid __P((int pid, int *__stat_loc, int options)); + +/* Wait for a child to die. When one does, put its status in *STAT_LOC + and return its process ID. For errors, return (pid_t) -1. + */ +#define wait(statloc) waitpid(WAIT_ANY, statloc, 0) + +#endif diff --git a/include/sys/wait.h% b/include/sys/wait.h% new file mode 100755 index 00000000..fdbae9a3 --- /dev/null +++ b/include/sys/wait.h% @@ -0,0 +1,37 @@ +/* wait.h dummy added by Nick, as UZI180 implements wait(), not waitpid() */ + +#ifndef _SYS_WAIT_H +#define _SYS_WAIT_H + +/* Bits in the third argument to `waitpid'. */ +#define WNOHANG 1 /* Don't block waiting. */ +#define WUNTRACED 2 /* Report status of stopped children. */ + +/* Everything extant so far uses these same bits. */ +/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */ +#define WEXITSTATUS(status) (((status) & 0xff00) >> 8) + +/* If WIFSIGNALED(STATUS), the terminating signal. */ +#define WTERMSIG(status) ((status) & 0x7f) + +/* If WIFSTOPPED(STATUS), the signal that stopped the child. */ +#define WSTOPSIG(status) WEXITSTATUS(status) + +/* Nonzero if STATUS indicates normal termination. */ +#define WIFEXITED(status) (((status) & 0xff) == 0) + +/* Nonzero if STATUS indicates termination by a signal. */ +#define WIFSIGNALED(status) (((unsigned int)((status)-1) & 0xFFFF) < 0xFF) + +/* Nonzero if STATUS indicates the child is stopped. */ +#define WIFSTOPPED(status) (((status) & 0xff) == 0x7f) + +/* Nonzero if STATUS indicates the child dumped core. */ +#define WCOREDUMP(status) ((status) & 0200) + +/* Macros for constructing status values. */ +#define W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) +#define W_STOPCODE(sig) ((sig) << 8 | 0x7f) + +#endif + diff --git a/include/sys/z8.pmm b/include/sys/z8.pmm new file mode 100755 index 00000000..ea3f3d3b --- /dev/null +++ b/include/sys/z8.pmm @@ -0,0 +1,12 @@ +; z8.pmm + +; strips ctrl-z from files, run in buffer 8 + +xfCDEFS.H .9 xe +xfEXEC.H .9 xe +xfIOCTL.H .9 xe +xfSEEK.H .9 xe +xfSTAT.H .9 xe +xfUTSNAME.H .9 xe +xfWAIT.H .9 xe + diff --git a/include/sys/z9.pmm b/include/sys/z9.pmm new file mode 100755 index 00000000..573b3fc9 --- /dev/null +++ b/include/sys/z9.pmm @@ -0,0 +1,6 @@ +; z9.pmm + +; strips ctrl-z from files, run in buffer 9 + +ua e us @e=0[-m t uz #k] qr + diff --git a/include/syscalls.h b/include/syscalls.h new file mode 100755 index 00000000..21ef8305 --- /dev/null +++ b/include/syscalls.h @@ -0,0 +1,132 @@ +/* SYSCALLS.H + */ +#ifndef __SYSCALLS_H +#define __SYSCALLS_H +#ifndef __TYPES_H +#include +#endif +#ifndef __SIGNAL_H +#include +#endif + +#ifndef __VENDOR_H /* Nick */ +#include /* Nick */ +#endif /* Nick */ + +#ifndef __DOS__ + +extern int errno; + +#ifndef __STDLIB_H +extern void _exit __P((int val)); +#endif + +extern int access __P((char *path, int mode)); +extern int alarm __P((uint secs)); +extern int brk __P((char *addr)); +extern int chdir __P((char *dir)); +extern int chroot __P((char *dir)); +extern int chmod __P((char *path, mode_t mode)); +extern int chown __P((char *path, int owner, int group)); +extern int close __P((int uindex)); +extern int creat __P((char *name, mode_t mode)); +extern int dup __P((int oldd)); +extern int dup2 __P((int oldd, int newd)); +extern int execve __P((char *name, char *argv[], char *envp[])); +extern int fork __P((void)); +extern int fstat __P((int fd, void *buf)); +#if 1 /* Nick free bitmap */ +extern int falign __P((int fd, int parm)); +#endif +extern int getfsys __P((int dev, void *buf)); +extern int getgid __P((void)); +extern int getpid __P((void)); +extern int getppid __P((void)); +extern int getuid __P((void)); +extern int geteuid __P((void)); +extern int getegid __P((void)); +extern int getprio __P((void)); +#ifndef SKIP_SYSCALLS +extern int ioctl __P((int fd, int request, ...)); +#endif +extern int kill __P((int pid, int sig)); +extern int link __P((char *oldname, char *newname)); +extern int symlink __P((char *oldname, char *newname)); +extern int mknod __P((char *name, mode_t mode, int dev)); +extern int mkfifo __P((char *name, mode_t mode)); +extern int mount __P((char *spec, char *dir, int rwflag)); +#ifndef SKIP_SYSCALLS +extern int open __P((char *name, uint flag, ...)); +#endif +extern int pause __P((void)); +extern int pipe __P((int fildes[2])); +extern int read __P((int d, void *buf, uint nbytes)); +extern int sbrk __P((uint incr)); +extern off_t lseek __P((int file, off_t offset, int whence)); +extern int setgid __P((int gid)); +extern int setuid __P((int uid)); +extern int setprio __P((int pid, char prio)); +extern sig_t signal __P((signal_t sig, sig_t func)); +extern int stat __P((char *path, void *buf)); +extern int stime __P((time_t *tvec)); +extern int sync __P((void)); +extern time_t time __P((time_t *tvec)); +extern int times __P((struct tms *buf)); +extern int utime __P((char *path, struct utimbuf *buf)); +extern int umask __P((int mask)); +extern int umount __P((char *spec)); +extern int unlink __P((char *path)); +extern int wait __P((int *statloc)); +extern int write __P((int d, void *buf, uint nbytes)); +extern int reboot __P((char p1, char p2)); +extern int systrace __P((int onoff)); +extern int unix __P((int callno, ...)); /* ensures IAR doesn't use regparms */ +extern long unix_long __P((int callno, ...)); /* ensures IAR doesn't use reg */ + +#ifdef UZIX_MODULE +extern int modulereg __P((uint sig, int (*func)())); +extern int moduledereg __P((uint sig)); +extern int modulecall __P((uint sig, uint fcn, char *args, int argsize)); +extern int modulereply __P((uint sig, int fcn, char *repladdr)); +extern int modulesendreply __P((int pid, int fcn, char *repladdr, int replysize)); +#endif + +#else /* running under MS-DOS */ + +#include "types.h" +#include +#include +#include +#include +#include +#include + +extern int alarm(uint secs); +extern int chown(char *path, int owner, int group); +extern int fork(void); +extern int getfsys(int dev, void *buf); +extern int getgid(void); +extern int getppid(void); +extern int getuid(void); +extern int geteuid(void); +extern int getegid(void); +extern int getprio(void); +extern int kill(int pid, int sig); +extern int link(char *name1, char *name2); +extern int mknod(char *name, mode_t mode, int dev); +extern int mount(char *spec, char *dir, int rwflag); +extern int pause(void); +extern int pipe(int fildes[2]); +extern int setgid(int gid); +extern int setuid(int uid); +extern int stime(time_t *tvec); +extern int sync(void); +extern time_t time(time_t *tvec); +extern int times(struct tms *buf); +extern int umount(char *spec); +extern int wait(int *statloc); +extern int reboot(char p1, char p2); +extern int systrace(int onoff); + +#endif /* __DOS__ */ +#endif /* __SYSCALLS_H */ diff --git a/include/tcpip.h b/include/tcpip.h new file mode 100755 index 00000000..77eb88d6 --- /dev/null +++ b/include/tcpip.h @@ -0,0 +1,120 @@ +/* UZIX TCP/IP Stack + * (c) 2000 A&L Software + * Adriano C. R. da Cunha + */ + +/* Protocol numbers */ +#define ICMP_PROTOCOL 1 +#define TCP_PROTOCOL 6 +#define UDP_PROTOCOL 17 + +/* TCP/IP open modes */ +#define TCP_ACTIVE_OPEN 255 +#define TCP_PASSIVE_OPEN 0 + +/* data size */ +#define DOMSIZE 128 + +/* protocols */ +#define IPV4_TCP 0x01 +#define IPV4_UDP 0x02 +#define IPV4_ICMP 0x03 + +/* UDP modes */ +#define UDPMODE_ASC 1 +#define UDPMODE_CKSUM 2 + +/* error codes */ +#define ECONTIMEOUT 0x80 +#define ECONREFUSED 0x81 +#define ENOPERM 0x82 +#define ENOPORT 0x83 +#define ENOROUTE 0x84 +#define ENOSOCK 0x85 +#define ENOTIMP 0x86 +#define EPROT 0x87 +#define EPORTINUSE 0x88 + +/* TCP socket status + bits: 76543210 + ^^ ^^^^ state + |+-------listen state + +--------write enable +*/ + +#define TCP_CLOSED 0x00 +#define TCP_LISTEN 0x01 +#define TCP_SYN_SENT 0x42 +#define TCP_SYN_RECEIVED 0x43 +#define TCP_ESTABLISHED 0xc4 +#define TCP_FIN_WAIT1 0x45 +#define TCP_FIN_WAIT2 0x46 +#define TCP_CLOSE_WAIT 0x87 +#define TCP_CLOSING 0x08 +#define TCP_LAST_ACK 0x09 +#define TCP_TIMEWAIT 0x0a + +/* UDP socket status */ +#define UDP_LISTEN 0x91 +#define UDP_ESTABLISHED 0x94 + +/* some structures used */ +typedef struct s_ip_struct { /* TCP/UDP connection info data */ + uchar remote_ip[4]; + uint remote_port; + uint local_port; +} ip_struct_t; + +typedef struct s_icmpdata { /* ICMP packet data */ + uchar type; + uchar icmpcode; + unsigned long unused; /* Used for various things */ + uchar data[28]; /* Make up to 64 bytes */ + uint len; + uchar sourceIP[4]; + uchar ttl; +} icmpdata_t; + +typedef struct { /* TCP/IP stack info */ + uchar IP[4]; + uchar dns1ip[4]; + uchar dns2ip[4]; + char datalink[5]; + char domainname[DOMSIZE]; + int used_sockets; + int avail_sockets; + int used_buffers; + int avail_buffers; + int IP_chksum_errors; +} tcpinfo_t; + +typedef struct { /* socket info */ + int localport; + int remoteport; + uchar remote_ip[4]; + char socketstatus; /* bit 7: listen, bits 3-0: closed...timewait */ + char sockettype; /* IPV4_UDP or IPV4_TCP */ + char sockerr; /* error code (if any) */ + int pid; +} sockinfo_t; + +/* user calls: TCP/IP */ +int ipconnect(char mode, ip_struct_t *ipstruct); +int ipclose(uchar socknum); +int iplisten(int aport, uchar protocol); +int ipunlisten(int aport); +int ipaccept(ip_struct_t *ipstruct, int aport, uchar block); +int ping(uchar *IP, unsigned long *unused, uint len); +int setsocktimeout(uchar socknum, uint timeout); +icmpdata_t *ipgetpingreply(void); +int ipwrite(uchar socknum, uchar *bytes, int len); +int ipread(uchar socknum, uchar *bytes, int len); +int ipgetc(uchar socknum); +int ipputc(uchar socknum, uchar byte); +tcpinfo_t *gettcpinfo(void); +sockinfo_t *getsockinfo(uchar socknum); + +/* user calls: DNS */ +int local_lookup(char *ip_name, uchar *ipaddr); +int resolve(char *name, uchar *ipaddr); +int reverse_lookup(char *name, char *ipaddr); diff --git a/include/termcap.h b/include/termcap.h new file mode 100755 index 00000000..a37fea61 --- /dev/null +++ b/include/termcap.h @@ -0,0 +1,21 @@ +#ifndef __TERMCAP_H +#define __TERMCAP_H +#ifndef __TYPES_H +#include +#endif + +extern char PC; +extern char *UP; +extern char *BC; +extern int ospeed; + +extern int tgetent __P((char *, char *)); +extern int tgetflag __P((char *)); +extern int tgetnum __P((char *)); +extern char *tgetstr __P((char *, char **)); + +extern void tputs __P((char *, int, int (*)(int))); +extern char *tgoto __P((char *, int, int)); +extern char *tparam(); /* VARARGS */ + +#endif /* _TERMCAP_H */ diff --git a/include/termio.h b/include/termio.h new file mode 100755 index 00000000..67a0b1e7 --- /dev/null +++ b/include/termio.h @@ -0,0 +1,3 @@ +#ifndef __TERMIOS_H +#include +#endif diff --git a/include/termios.h b/include/termios.h new file mode 100755 index 00000000..9a2159be --- /dev/null +++ b/include/termios.h @@ -0,0 +1,23 @@ +#ifndef __TERMIOS_H +#define __TERMIOS_H +#ifndef __TYPES_H +#include +#endif + +extern int cfgetispeed __P ((struct termios *__termios_p)); +extern int cfgetospeed __P ((struct termios *__termios_p)); +extern int cfsetispeed __P ((struct termios *__termios_p, int __speed)); +extern int cfsetospeed __P ((struct termios *__termios_p, int __speed)); + +extern void cfmakeraw __P ((struct termios *__t)); + +extern int tcsetattr __P ((int __fd, int __opt, struct termios *__termios_p)); +extern int tcgetattr __P ((int __fildes, struct termios *__termios_p)); +extern int tcdrain __P ((int __fildes)); +extern int tcflow __P ((int __fildes, int __action)); +extern int tcflush __P ((int __fildes, int __queue_selector)); +extern int tcsendbreak __P ((int __fildes, int __duration)); +extern int tcgetpgrp __P ((int __fildes)); +extern int tcsetpgrp __P ((int __fildes, int __pgrp_id)); + +#endif diff --git a/include/time.h b/include/time.h new file mode 100755 index 00000000..9938d86f --- /dev/null +++ b/include/time.h @@ -0,0 +1,61 @@ +#ifndef __TIME_H +#define __TIME_H +#ifndef __TYPES_H +#include +#endif +#include + +#if (defined(MSX) || defined(MSX_UZIX_TARGET)) +#define CLOCKS_PER_SEC *(uchar *)63220 /* Must agree with kernel EXTERN.H */ +#define CLK_TCK *(uchar *)63220 /* That must be the same as HZ ???? */ +#else +#define CLOCKS_PER_SEC 18 +#define CLK_TCK 18 /* That must be the same as HZ ???? */ +#endif + +#ifndef CLOCK_T +#define CLOCK_T +typedef long clock_t; +#endif + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +struct timezone { + int tz_minuteswest; /* minutes west of Greenwich */ + int tz_dsttime; /* type of dst correction */ +}; + +#define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) + +extern char *tzname[2]; +extern int daylight; +extern long timezone; + +extern long clock __P ((void)); +extern time_t mktime __P ((struct tm * __tp)); +extern long difftime __P ((time_t *__time2, time_t *__time1)); + +extern time_t time __P((time_t *tvec)); + +extern void __tm_conv __P((struct tm *tmbuf, time_t *t, int offset)); +extern void __asctime __P((char *, struct tm *)); +extern char *asctime __P ((struct tm * __tp)); +extern char *ctime __P ((time_t * __tp)); +extern void tzset __P ((void)); + +extern struct tm *gmtime __P ((time_t *__tp)); +extern struct tm *localtime __P ((time_t * __tp)); +extern unsigned long convtime __P ((time_t *time_field)); + +#endif diff --git a/include/types.h b/include/types.h new file mode 100755 index 00000000..9f8518ba --- /dev/null +++ b/include/types.h @@ -0,0 +1,106 @@ +#ifndef __TYPES_H +#define __TYPES_H + +#ifndef __FEATURES_H +#include "features.h" +#endif + +/* USER! basic data types */ +/* ! uchar & uint is counterparts and must be declared simultaneously */ +#ifndef uchar_is_defined +#define uchar_is_defined +typedef unsigned char uchar; +typedef unsigned int uint; +#endif + +typedef uchar bool_t; /* boolean value */ +typedef uint count_t; /* counter for anything */ +#ifndef _SIZE_T +#define _SIZE_T +typedef uint size_t; +#endif + +typedef unsigned int mode_t; +#if 0 /* Nick, see unix.h !! */ +typedef struct blkoff_t { + uint/*16*/ o_blkno; /* Block number */ + int/*16*/ o_offset; /* Offset within block 0-511 */ +} blkoff_t; +#endif +typedef long off_t; + +/* file's timestamp structure (non UNIX-standart) */ +typedef struct s_time { + uint t_time; + uint t_date; +} time_t; + +/* User's structure for times() system call */ +struct tms { + time_t tms_utime; + time_t tms_stime; + time_t tms_cutime; + time_t tms_cstime; + time_t tms_etime; /* Elapsed real time */ +}; + +#ifndef utimbuf_is_defined +#define utimbuf_is_defined +/* User's structure for utime() system call */ +struct utimbuf { + time_t actime; + time_t modtime; +}; +#endif + +/* data structure for stat() */ +struct stat { /* USER! Really only used by users */ + uint st_dev; /* device number */ + uint st_ino; /* inode number */ + mode_t st_mode; /* file mode */ + uint st_nlink; /* number of links */ + uint st_uid; /* owner id */ + uint st_gid; /* owner group */ + uint st_rdev; /* */ + off_t st_size; /* Nick changed blkoff_t to off_t file size */ + time_t st_atime; /* last access time */ + time_t st_mtime; /* last modification time */ + time_t st_ctime; /* file creation time */ +}; + +#define DIRNAMELEN 14 + +/* device directory entry */ +typedef struct direct { + unsigned int d_ino; /* file's inode */ + uchar d_name[DIRNAMELEN]; /* file name */ +} direct_t; + +#ifndef NULL +#define NULL 0 +#endif + +#define BUFSIZE 512 /* uzix buffer/block size */ +#define BUFSIZELOG 9 /* uzix buffer/block size log2 */ + +#if 1 /* Nick free bitmap */ +#define REGION_LOG 14 +#define REGION_BYTES (1< +#endif +#include + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +extern int mkdir __P((char *, mode_t)); +extern int rmdir __P((char *)); + +extern long tell __P((int)); +extern off_t lseek __P((int, off_t, int)); + +extern int isatty __P((int)); + +extern int lstat __P((char *, void *)); +extern int readlink __P((char *, char *, int)); + +extern char **environ; + +extern char * _findPath __P((char *pathname)); +extern int execl __P((char *pathname, char *arg0, ...)); +extern int execle __P((char *pathname, char *arg0, ...)); +extern int execlp __P((char *pathname, char *arg0, ...)); +extern int execlpe __P((char *pathname, char *arg0, ...)); +extern int execv __P((char *pathname, char *argv[])); +extern int exect __P((char *pathname, char *argv[], char *envp[])); +extern int execvp __P((char *pathname, char *argv[])); +extern int execvpe __P((char *pathname, char *argv[], char *envp[])); + +extern char *ttyname __P((int)); +extern int system __P((char *)); +extern int pause __P((void)); +extern int fork __P((void)); +extern char *getcwd __P((char *, int)); + +#ifndef __STDLIB_H +extern void exit __P((int)); +#endif + +#ifndef R_OK +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define X_OK 1 /* Test for execute permission. */ +#define F_OK 0 /* Test for existence. */ +#endif + +#endif /* __UNISTD_H */ diff --git a/include/utime.h b/include/utime.h new file mode 100755 index 00000000..5d1cee55 --- /dev/null +++ b/include/utime.h @@ -0,0 +1,9 @@ +#ifndef __UTIME_H +#define __UTIME_H +#ifndef __TYPES_H +#include +#endif + +extern int utime __P ((char *__filename, struct utimbuf *__utimebuf)); + +#endif diff --git a/include/utmp.h b/include/utmp.h new file mode 100755 index 00000000..6c1c6602 --- /dev/null +++ b/include/utmp.h @@ -0,0 +1,45 @@ +#ifndef __UTMP_H +#define __UTMP_H +#ifndef __TYPES_H +#include +#endif +#include +#include + +#define UT_UNKNOWN 0 +#define UT_LINESIZE 12 +#define UT_NAMESIZE 8 +#define UT_HOSTSIZE 16 + +#define RUN_LVL 1 +#define BOOT_TIME 2 +#define NEW_TIME 3 +#define OLD_TIME 4 + +#define INIT_PROCESS 5 +#define LOGIN_PROCESS 6 +#define USER_PROCESS 7 +#define DEAD_PROCESS 8 + +struct utmp { + short ut_type; /* type of login */ + int ut_pid; /* pid of login-process */ + char ut_line[UT_LINESIZE]; /* devicename of tty -"/dev/", null-term */ + char ut_id[2]; /* abbrev. ttyname, as 01, s1 etc. */ + time_t ut_time; /* login time */ + char ut_user[UT_NAMESIZE]; /* username, not null-term */ + char ut_host[UT_HOSTSIZE]; /* hostname for remote login... */ + long ut_addr; /* IP addr of remote host */ +}; + +extern void setutent __P((void)); +extern void utmpname __P((char *)); +extern struct utmp * getutent __P((void)); +extern struct utmp * getutid __P((struct utmp *)); +extern struct utmp * getutline __P((struct utmp *)); +extern struct utmp * pututline __P((struct utmp *)); +extern void endutent __P((void)); + +struct utmp * __getutent __P((int)); + +#endif /* __UTMP_H */ diff --git a/include/utsname.h b/include/utsname.h new file mode 100755 index 00000000..df17b347 --- /dev/null +++ b/include/utsname.h @@ -0,0 +1,18 @@ +#ifndef __UTSNAME_H +#define __UTSNAME_H +#ifndef __TYPES_H +#include +#endif + +struct utsname { + char sysname[14]; + char nodename[14]; + char release[8]; + char version[8]; + char machine[8]; + char domainname[14]; +}; + +extern int uname __P ((struct utsname * __utsbuf)); + +#endif diff --git a/include/varargs.h b/include/varargs.h new file mode 100755 index 00000000..bdab9db0 --- /dev/null +++ b/include/varargs.h @@ -0,0 +1,13 @@ +#ifndef __VARARGS_H +#define __VARARGS_H + +#ifndef __STDARG_H +typedef void *va_list; + +#define va_dcl va_list va_alist; +#define va_start(ap) (ap) = (va_list)&va_alist +#define va_arg(ap,t) ((t *)(((char *)(ap)) += sizeof(t)))[-1] +#define va_end(ap) (ap) = NULL + +#endif +#endif diff --git a/include/vendor.h b/include/vendor.h new file mode 100755 index 00000000..1b7e8281 --- /dev/null +++ b/include/vendor.h @@ -0,0 +1,11 @@ +/* vendor.h for IAR by Nick, puts underscores on externs where necessary */ + +#ifndef __VENDOR_H +#define __VENDOR_H + +#define read _read +#define write _write +/* #define symlink link */ + +#endif /* __VENDOR.H */ + diff --git a/include/z8.pmm b/include/z8.pmm new file mode 100755 index 00000000..ef69d9ca --- /dev/null +++ b/include/z8.pmm @@ -0,0 +1,49 @@ +; z8.pmm + +; strips ctrl-z from files, run in buffer 8 + +xfALLOC.H .9 xe +xfAR.H .9 xe +xfASSERT.H .9 xe +xfCTYPE.H .9 xe +xfCURSES.H .9 xe +xfDIRENT.H .9 xe +xfERRNO.H .9 xe +xfFCNTL.H .9 xe +xfFEATURES.H .9 xe +xfFLOAT.H .9 xe +xfGETOPT.H .9 xe +xfGRP.H .9 xe +xfLIMITS.H .9 xe +xfMALLOC.H .9 xe +xfMATH.H .9 xe +xfMEM.H .9 xe +xfMEMORY.H .9 xe +xfNCURSES.H .9 xe +xfPATHS.H .9 xe +xfPWD.H .9 xe +xfREGEXP.H .9 xe +xfREGMAGIC.H .9 xe +xfSEARCH.H .9 xe +xfSETJMP.H .9 xe +xfSGTTY.H .9 xe +xfSIGNAL.H .9 xe +xfSTDARG.H .9 xe +xfSTDDEF.H .9 xe +xfSTDIO.H .9 xe +xfSTDLIB.H .9 xe +xfSTRING.H .9 xe +xfSTRINGS.H .9 xe +xfSYSCALLS.H .9 xe +xfTCPIP.H .9 xe +xfTERMCAP.H .9 xe +xfTERMIO.H .9 xe +xfTERMIOS.H .9 xe +xfTIME.H .9 xe +xfTYPES.H .9 xe +xfUNISTD.H .9 xe +xfUTIME.H .9 xe +xfUTMP.H .9 xe +xfUTSNAME.H .9 xe +xfVARARGS.H .9 xe + diff --git a/include/z9.pmm b/include/z9.pmm new file mode 100755 index 00000000..573b3fc9 --- /dev/null +++ b/include/z9.pmm @@ -0,0 +1,6 @@ +; z9.pmm + +; strips ctrl-z from files, run in buffer 9 + +ua e us @e=0[-m t uz #k] qr + diff --git a/lib/libcb.lib b/lib/libcb.lib new file mode 100755 index 00000000..83adbbd2 --- /dev/null +++ b/lib/libcb.lib @@ -0,0 +1,142 @@ +relcb\abort.rel +relcb\alloca.rel +relcb\asctime.rel +relcb\assert.rel +relcb\atexit.rel +relcb\atoi.rel +relcb\atol.rel +relcb\bsearch.rel +relcb\c0l.rel +relcb\calloc.rel +relcb\clock.rel +relcb\closedir.rel +relcb\convtime.rel +relcb\crypt.rel +relcb\ctime.rel +relcb\ctype.rel +relcb\difftime.rel +relcb\error.rel +relcb\etime.rel +relcb\execl.rel +relcb\execle.rel +relcb\execlp.rel +relcb\execlpe.rel +relcb\exect.rel +relcb\execv.rel +relcb\execvp.rel +relcb\execvpe.rel +relcb\exit.rel +relcb\fclose.rel +relcb\fflush.rel +relcb\fgetc.rel +relcb\fgetgren.rel +relcb\fgetpwen.rel +relcb\fgets.rel +relcb\fopen.rel +relcb\fprintf.rel +relcb\fputc.rel +relcb\fputs.rel +relcb\fread.rel +relcb\free.rel +relcb\fscanf.rel +relcb\ftell.rel +relcb\fwrite.rel +relcb\getcwd.rel +relcb\getenv.rel +relcb\getgrent.rel +relcb\getgrgid.rel +relcb\getgrnam.rel +relcb\getopt.rel +relcb\getpass.rel +relcb\getpw.rel +relcb\getpwent.rel +relcb\getpwnam.rel +relcb\getpwuid.rel +relcb\gets.rel +relcb\gmtime.rel +relcb\initgrup.rel +relcb\isatty.rel +relcb\itoa.rel +relcb\localtim.rel +relcb\longjmpb.rel +relcb\lsearch.rel +relcb\lstat.rel +relcb\ltoa.rel +relcb\ltostr.rel +relcb\malloc.rel +relcb\memccpy.rel +relcb\memchr.rel +relcb\memcmp.rel +relcb\memcpy.rel +relcb\memmove.rel +relcb\memset.rel +relcb\mkdir.rel +relcb\mktime.rel +relcb\opendir.rel +relcb\perror.rel +relcb\popen.rel +relcb\printf.rel +relcb\putenv.rel +relcb\putgetch.rel +relcb\putpwent.rel +relcb\qsort.rel +relcb\rand.rel +relcb\readdir.rel +relcb\readlink.rel +relcb\realloc.rel +relcb\regerror.rel +relcb\regexp.rel +relcb\regsub.rel +relcb\rename.rel +relcb\rewind.rel +relcb\rewindir.rel +relcb\rmdir.rel +relcb\scanf.rel +relcb\setbuff.rel +relcb\setenv.rel +relcb\setgrent.rel +relcb\setjmpb.rel +relcb\setpwent.rel +relcb\setvbuff.rel +relcb\sleep.rel +relcb\sprintf.rel +relcb\sscanf.rel +relcb\stdio0.rel +relcb\strcat.rel +relcb\strchr.rel +relcb\strcmp.rel +relcb\strcpy.rel +relcb\strcspn.rel +relcb\strdup.rel +relcb\stricmp.rel +relcb\strlen.rel +relcb\strncat.rel +relcb\strncmp.rel +relcb\strncpy.rel +relcb\strnicmp.rel +relcb\strpbrk.rel +relcb\strrchr.rel +relcb\strsep.rel +relcb\strspn.rel +relcb\strstr.rel +relcb\strtod.rel +relcb\strtok.rel +relcb\strtol.rel +relcb\strtoul.rel +relcb\system.rel +relcb\termcap.rel +relcb\tmpnam.rel +relcb\tparam.rel +relcb\ttyname.rel +relcb\tzset.rel +relcb\ultoa.rel +relcb\ungetc.rel +relcb\utsname.rel +relcb\vfprintf.rel +relcb\vfscanf.rel +relcb\vprintf.rel +relcb\vscanf.rel +relcb\vsprintf.rel +relcb\vsscanf.rel +relcb\xitoa.rel +relcb\xltoa.rel diff --git a/lib/libcl.lib b/lib/libcl.lib new file mode 100755 index 00000000..8f2ff799 --- /dev/null +++ b/lib/libcl.lib @@ -0,0 +1,142 @@ +relcl\abort.rel +relcl\alloca.rel +relcl\asctime.rel +relcl\assert.rel +relcl\atexit.rel +relcl\atoi.rel +relcl\atol.rel +relcl\bsearch.rel +relcl\c0l.rel +relcl\calloc.rel +relcl\clock.rel +relcl\closedir.rel +relcl\convtime.rel +relcl\crypt.rel +relcl\ctime.rel +relcl\ctype.rel +relcl\difftime.rel +relcl\error.rel +relcl\etime.rel +relcl\execl.rel +relcl\execle.rel +relcl\execlp.rel +relcl\execlpe.rel +relcl\exect.rel +relcl\execv.rel +relcl\execvp.rel +relcl\execvpe.rel +relcl\exit.rel +relcl\fclose.rel +relcl\fflush.rel +relcl\fgetc.rel +relcl\fgetgren.rel +relcl\fgetpwen.rel +relcl\fgets.rel +relcl\fopen.rel +relcl\fprintf.rel +relcl\fputc.rel +relcl\fputs.rel +relcl\fread.rel +relcl\free.rel +relcl\fscanf.rel +relcl\ftell.rel +relcl\fwrite.rel +relcl\getcwd.rel +relcl\getenv.rel +relcl\getgrent.rel +relcl\getgrgid.rel +relcl\getgrnam.rel +relcl\getopt.rel +relcl\getpass.rel +relcl\getpw.rel +relcl\getpwent.rel +relcl\getpwnam.rel +relcl\getpwuid.rel +relcl\gets.rel +relcl\gmtime.rel +relcl\initgrup.rel +relcl\isatty.rel +relcl\itoa.rel +relcl\localtim.rel +relcl\longjmpl.rel +relcl\lsearch.rel +relcl\lstat.rel +relcl\ltoa.rel +relcl\ltostr.rel +relcl\malloc.rel +relcl\memccpy.rel +relcl\memchr.rel +relcl\memcmp.rel +relcl\memcpy.rel +relcl\memmove.rel +relcl\memset.rel +relcl\mkdir.rel +relcl\mktime.rel +relcl\opendir.rel +relcl\perror.rel +relcl\popen.rel +relcl\printf.rel +relcl\putenv.rel +relcl\putgetch.rel +relcl\putpwent.rel +relcl\qsort.rel +relcl\rand.rel +relcl\readdir.rel +relcl\readlink.rel +relcl\realloc.rel +relcl\regerror.rel +relcl\regexp.rel +relcl\regsub.rel +relcl\rename.rel +relcl\rewind.rel +relcl\rewindir.rel +relcl\rmdir.rel +relcl\scanf.rel +relcl\setbuff.rel +relcl\setenv.rel +relcl\setgrent.rel +relcl\setjmpl.rel +relcl\setpwent.rel +relcl\setvbuff.rel +relcl\sleep.rel +relcl\sprintf.rel +relcl\sscanf.rel +relcl\stdio0.rel +relcl\strcat.rel +relcl\strchr.rel +relcl\strcmp.rel +relcl\strcpy.rel +relcl\strcspn.rel +relcl\strdup.rel +relcl\stricmp.rel +relcl\strlen.rel +relcl\strncat.rel +relcl\strncmp.rel +relcl\strncpy.rel +relcl\strnicmp.rel +relcl\strpbrk.rel +relcl\strrchr.rel +relcl\strsep.rel +relcl\strspn.rel +relcl\strstr.rel +relcl\strtod.rel +relcl\strtok.rel +relcl\strtol.rel +relcl\strtoul.rel +relcl\system.rel +relcl\termcap.rel +relcl\tmpnam.rel +relcl\tparam.rel +relcl\ttyname.rel +relcl\tzset.rel +relcl\ultoa.rel +relcl\ungetc.rel +relcl\utsname.rel +relcl\vfprintf.rel +relcl\vfscanf.rel +relcl\vprintf.rel +relcl\vscanf.rel +relcl\vsprintf.rel +relcl\vsscanf.rel +relcl\xitoa.rel +relcl\xltoa.rel diff --git a/lib/libiar.lib b/lib/libiar.lib new file mode 100755 index 00000000..e7125850 --- /dev/null +++ b/lib/libiar.lib @@ -0,0 +1,195 @@ +reliar\BANKCALLDIRECT.rel +reliar\BANKCALLDIRECTEXAF.rel +reliar\BANKLEAVE32.rel +reliar\BANKLEAVEDIRECT.rel +reliar\BFCANDASG.rel +reliar\BFCLSHASG.rel +reliar\BFCMULASG.rel +reliar\BFCORASG.rel +reliar\BFCRETVAL.rel +reliar\BFCSHIFTUP.rel +reliar\BFCXORASG.rel +reliar\BFMASKEDLD.rel +reliar\BFMASKEDST.rel +reliar\BFSADDASG.rel +reliar\BFSANDASG.rel +reliar\BFSCDIVASG.rel +reliar\BFSCEXT.rel +reliar\BFSCLDSHIFTDOWN.rel +reliar\BFSCMODASG.rel +reliar\BFSCRSHASG.rel +reliar\BFSLSHASG.rel +reliar\BFSMULASG.rel +reliar\BFSNEGASG.rel +reliar\BFSORASG.rel +reliar\BFSPOSTDEC.rel +reliar\BFSPOSTINC.rel +reliar\BFSPREDEC.rel +reliar\BFSPREINC.rel +reliar\BFSRETVAL.rel +reliar\BFSSDIVASG.rel +reliar\BFSSEXT.rel +reliar\BFSSHIFTUP.rel +reliar\BFSSLDSHIFTDOWN.rel +reliar\BFSSMODASG.rel +reliar\BFSSRSHASG.rel +reliar\BFSSUBASG.rel +reliar\BFSXORASG.rel +reliar\BFUCDIVASG.rel +reliar\BFUCLDSHIFTDOWN.rel +reliar\BFUCMODASG.rel +reliar\BFUCRSHASG.rel +reliar\BFUSDIVASG.rel +reliar\BFUSLDSHIFTDOWN.rel +reliar\BFUSMODASG.rel +reliar\BFUSRSHASG.rel +reliar\CALLIND.rel +reliar\CDIVMOD.rel +reliar\CFINDSIGN.rel +reliar\CLSH.rel +reliar\CLSHASG.rel +reliar\CMUL.rel +reliar\CMULASG.rel +reliar\CSSWITCH.rel +reliar\CVSWITCH.rel +reliar\ENTAUTODIRECT.rel +reliar\ENTPARMDIRECT.rel +reliar\FADDASG.rel +reliar\FADDSUB.rel +reliar\FCMP.rel +reliar\FDEC.rel +reliar\FDECASG.rel +reliar\FDIV.rel +reliar\FDIVASG.rel +reliar\FENDASG2.rel +reliar\FINC.rel +reliar\FINCASG.rel +reliar\FMUL.rel +reliar\FMULASG.rel +reliar\FNEGASG.rel +reliar\FPACK.rel +reliar\FROUND.rel +reliar\FSUBASG.rel +reliar\FTOL.rel +reliar\FUNPACK.rel +reliar\LADDASG.rel +reliar\LAND.rel +reliar\LANDASG.rel +reliar\LDEC.rel +reliar\LDECASG.rel +reliar\LDIVMOD.rel +reliar\LEAVE32.rel +reliar\LEAVEDIRECT.rel +reliar\LENDASG.rel +reliar\LENDMULDIVASG.rel +reliar\LFINDSIGN.rel +reliar\LIBVERSION.rel +reliar\LINC.rel +reliar\LINCASG.rel +reliar\LLSH.rel +reliar\LLSHASG.rel +reliar\LMUL.rel +reliar\LMULASG.rel +reliar\LNEG.rel +reliar\LNEGASG.rel +reliar\LNOT.rel +reliar\LNOTASG.rel +reliar\LOR.rel +reliar\LORASG.rel +reliar\LSSWITCH.rel +reliar\LSUBASG.rel +reliar\LTOF.rel +reliar\LVSWITCH.rel +reliar\LXOR.rel +reliar\LXORASG.rel +reliar\MEMCMP.rel +reliar\MEMSET.rel +reliar\MONITORBANKLEAVE.rel +reliar\MONITORBANKLEAVE32.rel +reliar\MONITORBANKLEAVEIX.rel +reliar\MONITORBANKLEAVEPOP.rel +reliar\MONITORLEAVE.rel +reliar\MONITORLEAVE32.rel +reliar\MONITORLEAVEIX.rel +reliar\MONITORLEAVEIXPA.rel +reliar\MONITORLEAVEPA.rel +reliar\MONITORLEAVEPOP.rel +reliar\SCDIV.rel +reliar\SCMOD.rel +reliar\SCRSH.rel +reliar\SCRSHASG.rel +reliar\SDIVMOD.rel +reliar\SFINDSIGN.rel +reliar\SLCMP.rel +reliar\SLDIV.rel +reliar\SLDIVASG.rel +reliar\SLMOD.rel +reliar\SLMODASG.rel +reliar\SLRSH.rel +reliar\SLRSHASG.rel +reliar\SLSH.rel +reliar\SLSHASG.rel +reliar\SLSHASGBCprim.rel +reliar\SLSHASGDEprim.rel +reliar\SMUL.rel +reliar\SMULASG.rel +reliar\SMULASGBCprim.rel +reliar\SMULASGDEprim.rel +reliar\SMULASGIX.rel +reliar\SMULASGIY.rel +reliar\SSCMP.rel +reliar\SSDIV.rel +reliar\SSDIVASG.rel +reliar\SSDIVASGBCprim.rel +reliar\SSDIVASGDEprim.rel +reliar\SSDIVASGIX.rel +reliar\SSDIVASGIY.rel +reliar\SSMOD.rel +reliar\SSMODASG.rel +reliar\SSMODASGBCprim.rel +reliar\SSMODASGDEprim.rel +reliar\SSMODASGIX.rel +reliar\SSMODASGIY.rel +reliar\SSRSH.rel +reliar\SSRSHASG.rel +reliar\SSRSHASGBCprim.rel +reliar\SSRSHASGDEprim.rel +reliar\SSRSHASGIX.rel +reliar\SSRSHASGIY.rel +reliar\SSSWITCH.rel +reliar\SSWITCHEND.rel +reliar\STRCAT.rel +reliar\STRCHR.rel +reliar\STRCMP.rel +reliar\STRCPY.rel +reliar\STRLEN.rel +reliar\SVSWITCH.rel +reliar\UCDIV.rel +reliar\UCMOD.rel +reliar\UCRSH.rel +reliar\UCRSHASG.rel +reliar\ULDIV.rel +reliar\ULDIVASG.rel +reliar\ULMOD.rel +reliar\ULMODASG.rel +reliar\ULRSH.rel +reliar\ULRSHASG.rel +reliar\USDIV.rel +reliar\USDIVASG.rel +reliar\USDIVASGBCprim.rel +reliar\USDIVASGDEprim.rel +reliar\USDIVASGIX.rel +reliar\USDIVASGIY.rel +reliar\USMOD.rel +reliar\USMODASG.rel +reliar\USMODASGBCprim.rel +reliar\USMODASGDEprim.rel +reliar\USMODASGIX.rel +reliar\USMODASGIY.rel +reliar\USRSH.rel +reliar\USRSHASG.rel +reliar\USRSHASGBCprim.rel +reliar\USRSHASGDEprim.rel +reliar\USRSHASGIX.rel +reliar\USRSHASGIY.rel +reliar\VSWITCHEND.rel diff --git a/lib/libsysb.lib b/lib/libsysb.lib new file mode 100755 index 00000000..6c982515 --- /dev/null +++ b/lib/libsysb.lib @@ -0,0 +1,58 @@ +relsysb\access.rel +relsysb\alarm.rel +relsysb\brk.rel +relsysb\chdir.rel +relsysb\chmod.rel +relsysb\chown.rel +relsysb\chroot.rel +relsysb\close.rel +relsysb\creat.rel +relsysb\dup.rel +relsysb\dup2.rel +relsysb\execve.rel +relsysb\_exit.rel +relsysb\falign.rel +relsysb\fork.rel +relsysb\fstat.rel +relsysb\getegid.rel +relsysb\geteuid.rel +relsysb\getfsys.rel +relsysb\getgid.rel +relsysb\getpid.rel +relsysb\getppid.rel +relsysb\getprio.rel +relsysb\getuid.rel +relsysb\ioctl.rel +relsysb\kill.rel +relsysb\link.rel +relsysb\lseek.rel +relsysb\mkfifo.rel +relsysb\mknod.rel +relsysb\module.rel +relsysb\mount.rel +relsysb\open.rel +relsysb\pause.rel +relsysb\pipe.rel +relsysb\read.rel +relsysb\reboot.rel +relsysb\sbrk.rel +relsysb\seek.rel +relsysb\setgid.rel +relsysb\setprio.rel +relsysb\setuid.rel +relsysb\signal.rel +relsysb\stat.rel +relsysb\stime.rel +relsysb\symlink.rel +relsysb\sync.rel +relsysb\sys0b.rel +relsysb\sys1b.rel +relsysb\systrace.rel +relsysb\time.rel +relsysb\times.rel +relsysb\umask.rel +relsysb\umount.rel +relsysb\unlink.rel +relsysb\utime.rel +relsysb\waitpid.rel +relsysb\write.rel diff --git a/lib/libsysl.lib b/lib/libsysl.lib new file mode 100755 index 00000000..1cb0d327 --- /dev/null +++ b/lib/libsysl.lib @@ -0,0 +1,58 @@ +relsysl\access.rel +relsysl\alarm.rel +relsysl\brk.rel +relsysl\chdir.rel +relsysl\chmod.rel +relsysl\chown.rel +relsysl\chroot.rel +relsysl\close.rel +relsysl\creat.rel +relsysl\dup.rel +relsysl\dup2.rel +relsysl\execve.rel +relsysl\_exit.rel +relsysl\falign.rel +relsysl\fork.rel +relsysl\fstat.rel +relsysl\getegid.rel +relsysl\geteuid.rel +relsysl\getfsys.rel +relsysl\getgid.rel +relsysl\getpid.rel +relsysl\getppid.rel +relsysl\getprio.rel +relsysl\getuid.rel +relsysl\ioctl.rel +relsysl\kill.rel +relsysl\link.rel +relsysl\lseek.rel +relsysl\mkfifo.rel +relsysl\mknod.rel +relsysl\module.rel +relsysl\mount.rel +relsysl\open.rel +relsysl\pause.rel +relsysl\pipe.rel +relsysl\read.rel +relsysl\reboot.rel +relsysl\sbrk.rel +relsysl\seek.rel +relsysl\setgid.rel +relsysl\setprio.rel +relsysl\setuid.rel +relsysl\signal.rel +relsysl\stat.rel +relsysl\stime.rel +relsysl\symlink.rel +relsysl\sync.rel +relsysl\sys0l.rel +relsysl\sys1l.rel +relsysl\systrace.rel +relsysl\time.rel +relsysl\times.rel +relsysl\umask.rel +relsysl\umount.rel +relsysl\unlink.rel +relsysl\utime.rel +relsysl\waitpid.rel +relsysl\write.rel diff --git a/relnotes/20030306.txt b/relnotes/20030306.txt new file mode 100644 index 00000000..e5509831 --- /dev/null +++ b/relnotes/20030306.txt @@ -0,0 +1,234 @@ +HYTECH-INTERNATIONAL BV +CMX/UZI TESTRELEASE FOR SOFTWARE DEPARTMENT 030306SD + +MANIFEST + +-rw-r--r-- 1 nick users 10162351 Mar 6 22:08 uzi.zip + +INTRODUCTION + +Full release of the Hytech CMX/UZI kernel and associated utilities. The zipped +release is at "http://www.hytechscales.com/release/nld/test/030306SD". + +Note: This doesn't contain Joost's userlevel work at the moment. + +CHANGES IN THIS RELEASE + +1. New executable file format. Executables can now be 'large' or 'banked' + (see the IAR C compiler manuals for more information about memory models). + + The 'large' executables are similar to the older executables, but they now + have a header which tells the kernel which segments must be loaded where. + This cuts down the need for startup code to be compiled into every program. + The handling of "IDATA" and "CDATA" is more efficient because they are now + overlaid in logical memory, allowing full usage of the program's 32 kbyte + address space for code and read/write data. (In other words, read-only + data is loaded once, into the read/write space, and is not kept during the + execution of the program). Large executables can be up to 32k in size. + + The 'banked' executables are almost the same as the new 'large' format, + but the header of the file instructs the kernel's loaded not to load any + code beyond a certain point in the file. After the initialisation code + and data has been loaded, further code (banked code) is executed by using + the Z180's "BBR" (Bank Base Register) to bring the code into the logical + address space. The code really lies in the terminal's 768 kbyte protected + RAM-disk area, which is shared with the root filesystem. So quite some + contortions are needed to ensure that the remaining space, after software + has been loaded for banked execution, can still be used as a RAM drive. + There is no limit on the size of a banked executable, it can use all of + available RAM except for that used by the kernel. So approximately 512k. + + We also have a third executable type, 'kernel' which is very similar to a + 'banked' executable, but the header describes an extra code/data segment + which gets loaded at address 0. This provides the interrupt table and + some other routines which need to be loaded all the time. Previously this + initialisation had been done by the kernel itself, but the new arrangement + moves initialisation code out of the kernel and into the bootloader. This + is very desirable because the bootloader can be discarded after booting. + 'Kernel' executables are specially marked with a magic number, ensuring + they can't be executed at user level by accident. 'Kernel' and 'banked' + executables need to be aligned with the 'align' command before being run. + +2. Changes to the Hytech 'align' and 'ualign' utilities. We now have a mode + which prints which files are being aligned, and the programs can be told + to skip symlinks as well. This was necessary to get the bootup copying of + files to look pretty. It's also a good example of why we would want to + add new switches and modes of operation to the standard Unix utilities. + In general the standard Unix version 7 functionality is exactly what we + want, but in some cases we will take out features which we don't need, and + in some cases we will add specific functionality where there is a need. + +3. In the kernel, revised handling for block and character devices. We now + have an improved "devtab" (device table) which works more like 7th Edition + Unix - the previous "uzi" device table was more limited because it couldn't + handle "major" and "minor" device numbers - all devices had to be "major 0" + and all the corresponding minor numbers had to be listed explicitly in the + device table. Now, the "major" number correctly indicates the family of + devices, as it should, and each major number only takes one "devtab" entry. + In our system, most of the devices are versions of the "tty" device (ie. + serial ports and API BUS), so this was a substantial reduction in the size + of the device table (from 18 entries to 5). The changes to the device + handling introduced some incompatiblity with existing device drivers, so + they have also been modified for the new calling convention. Please test! + +4. Fixed a bug in the TTY handling so that the TTY mode is remembered for as + long as at least one handle remains open to the device. This covers the + situation of 'more' which opens its own TTY handle in order to save and + restore the mode. The default mode is binary since the last release. + Binary is suitable for the Cognitive printer and other devices such as the + touchscreen. However the user's TTY is only set to cooked mode at bootup, + so it should not be clobbered thereafter - hence the reference counting. + +5. Improvements to the 'signal' handling - not quite finished yet. The idea + is that you can catch various events, such as "control C" or "broken pipe" + by registering a signal handler with the kernel (this is standard Unix + functionality). Unfortunately there are some bank-switching complications + making it rather hard for the kernel to call out into the user program - + the kernel must at least find out whether the user program is 'large' or + 'banked' and use the appropriate calling conventions. This is mostly done + but needs to be tested for each memory model - for now, don't use signals! + +6. Now got a choice of shells - SASH, Minix or Bourne. At present the simple + SASH shell is suitable for all our needs, but looking to the future we will + probably want to run some shell scripts overnight, eg. to back up journal + files into a special directory of the flash card, etc. The shell scripts + can get very complicated (see /uzi/src/man/makewhatis.sh for example), so + we will probably want to use the features of the Minix or Bourne shell in + our scripts eventually. The Minix shell seems to be a little more reliable + but the Bourne shell is the original and so it would potentially be more + compatible with other people's shell scripts. Note: We need SED / AWK!! + +7. The unix 'man' command now works properly. The manual pages themselves + are copied from an early Unix version and are probably not legal, but good + enough to test the "manpage" infrastructure. The BSD utilities "catman" + and so on, have been ported in order to create the /usr/man/* directories. + +8. The unix 'more' command now works properly. Pipes now work properly, so + you can give a command such as "ls | more". Please test this feature, and + other shell redirection or piping features in general! Does it all work?? + +9. Improvements to the compile system - we now have our own assembler (as-z80) + and linker (link-z80). This was necessary to get the banked executables + to work, and also led to substantial reductions in the footprint of both + large and kernel executables. The output from the IAR 'C' compiler is + automatically run through the IAR assembler (there seems to be no way of + preventing this), but we ignore this and take the resulting 'S01' file, + which contains assembler source in a fairly generic Z80 language. + + Our assembler had to be modified to handle the IAR compiler output, this is + all working fine, except for a small problem handling symbol names which + happen to conflict with Z80 registers. So don't define global symbols of + the names: a b c d e h l n r bc de hl ix iy, as this will abort assembly! + + Coming soon - faster linking - we have some code which needs to be added + to the linker so that library searching will be faster. This wasn't + important enough to delay the release, so please put up with the compile + times for now. The new code for library indexing will reduce them a lot. + + Please note the new "rst" files (relocated listing) which are produced in + your build directory after building. This contains the real object code, + AFTER linking, alongside the assembler source. So you can easily check if + your symbols ended up where you intended them to be. Use the mapfile too! + The "rst" files are much easier to read than the Intel-Hex format used for + generating the binaries. So there's no need for a Z180 disassembler when + checking your output. In future the "rst" files could form the basis for + a source-level debugger if we decided to develop this feature. + + Note: The Hytech assembler and linker are based on an open-source package + called "asxxxx" which seems to be receiving regular updates. See /uzi/doc. + +10. In most of the build directories, temporary files are now gathered in a + subdirectory named 'build-b' (banked), 'build-l' (large) or 'build' (if + a choice is not available). This means the /uzi folder can be archived + with a command to exclude the build directories, which should reduce the + download time via Internet, and would also make it possible to build the + software using less disk space than before. All the intermediate files + can harmlessly be deleted after the build (eg. type "deltree build-l"). + +11. Improvements to the /uzi folder structure. Source code for programs is + placed one level deeper, for example "/uzi/src/hello" or several levels + deeper, for example "/uzi/src/kernel/cmx". Binaries are still kept under + "/uzi/bin" as usual, but Windows binaries are now kept in "/uzi/src/bin" + exclusively. The folder "/uzi/include" is unchanged, but the new folder + "/uzi/lib" contains all the pre-compiled library modules, including the + 'C' library, the 'system calls' library and the 'IAR internal' library. + These are "libc.lib", "libsys.lib" and "libiar" respectively. The source + is now under "/uzi/src/libc", "/uzi/src/libsys" and "/uzi/src/libiar" + respectively, rather than the old system of mixing binary and source files. + +12. Batch files to create 'n.bat' and 'xxxx.lnk' files for you. This should + make it easier to convert from the earlier compile system to the new. + + For a sample project you might create the folder "/uzi/src/sample" and + create a single file called "/uzi/src/sample/sample.c". To compile the + program you would first type "mknbat-l sample" which creates "n.bat" + containing the necessary commands to compile "sample.c" to an executable + called "sample". ('l' for large memory model, you could use 'b' instead). + + Before running this "n.bat" file, you must first create a corresponding + linker script, done by typing "mklink-l sample" which creates "sample.lnk" + having the commands to link "sample.rel" with the usual 'C' libraries to + create the final executable, "sample". + + Note that once you've created the compile and link scripts, you shouldn't + need to use "mk*.bat" any more. You just continue developing, and run + "n.bat" each time compilation is needed. The generated files "n.bat" and + "sample.lnk" can be edited if you need to add any further 'C' modules to + the project. If you do this, be careful not to run "mknbat-*.bat" or + "mklink-*.bat" since you would clobber your changes. + + Note: The generated files are geared for simplicity, so they don't support + the "build", "build-b" or "build-l" directories. For an example of how + you would create both "large" and "banked" versions of a program, see the + example folder "/uzi/src/hello". Your build system should ideally look + like this, although you might want to modify it to output your executables + directly into "/uzi/bin/large" or "/uzi/bin/banked" for inclusion in a + flash card image. After this, add the needed commands to "/uzi/bin/n.ucp". + +INSTALLATION PROCEDURE + +In the Windows "System Properties" dialog, click "Advanced -> Environment +Variables". Add the entry "c:\uzi\src\bin" into your path. This is necessary +for the new compile system to work. Note the distinction between "c:\uzi\bin", +which contains executables for the Hytech 1000 / 1500 terminal, and the folder +mentioned here, which contains Windows executables to use during building. + +Due to the system-wide changes (executable formats and device numbering), it's +not possible to upgrade to this release by means of "newkrnl.sh" (although we +would like to test the "newkrnl.sh" functionality whenever possible). Instead +you should use the CLR MEM switch of the terminal, although this will mean +having to reset the terminal's RTC manually to the current time and date. + +As with the previous release, it's necessary to have a DOS or Windows 98 PC, +loaded with the Hytech POS software, to load the software from the CLR MEM +state. Coming soon is a modification to the EPROM to avoid this inconvenience. +Once the kernel has been loaded, further initialisation proceeds via flash +card. So the flash card must have been initialised, with "hytdisk.dat" and +"uzidisk.dat" as usual, and inserted, before loading the kernel via POS. + +Normally, you would build the kernel before doing the above. This is because +only the kernel's build-script contains the commands to generate CHECKSUM for +the downloading via POS. If you want to save time building the kernel, you +could just copy the distribution files CHECKSUM, KERNEL.BIN and BOOT.BIN from +the "/uzi/bin" directory to "/nlddl" on the machine which is running POS. + +*** LATE BREAKING NOTE: + +When using the banked executables, you will have to copy the executable onto +the root filesystem (ie. the RAMdrive) before executing each time. Then the +file needs to be aligned with the "align" command. But this can lead to a +problem: If the file is modified after being aligned, the alignment is broken +and this can't easily be fixed at the moment. You would need to delete the +file and start again. So please use the following sequence to test your work: + + rm /bin/myprogram + cp /usr/myfolder/myprogram /bin + align /bin/myprogram + chmod 755 myprogram + myprogram + +In this case I selected a folder called "myfolder" on the flash card for use in +transporting the banked program code onto the RAMdrive. Note that the flash +card is mounted on /usr, so the folder "/usr/myfolder" is referred to as simply +"/myfolder" while constructing the flash card. Use the "ucp" program for this. + diff --git a/silly.bat b/silly.bat new file mode 100755 index 00000000..d9a46b49 --- /dev/null +++ b/silly.bat @@ -0,0 +1,2 @@ +pkzipc -add=update -path=relative -recurse -excl=build -excl=build-b -excl=build-l -excl=dev-nick silly * +xcopy silly.zip \\darkstar\public\uzi.backup.zip diff --git a/src/as-z80/as-z80.exe b/src/as-z80/as-z80.exe new file mode 100755 index 0000000000000000000000000000000000000000..632a28d56156ab272a7d3e22ecf13d12ee127930 GIT binary patch literal 110637 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 z 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 +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "asxxxx.h" + +/*)Module asdata.c + * + * The module asdata.c contains the global constants, + * structures, and variables used in the assembler. + */ + +int aserr; /* ASxxxx error counter + */ +jmp_buf jump_env; /* compiler dependent structure + * used by setjmp() and longjmp() + */ +int inpfil; /* count of assembler + * input files specified + */ +int incfil; /* current file handle index + * for include files + */ +int cfile; /* current file handle index + * of input assembly files + */ +int flevel; /* IF-ELSE-ENDIF flag will be non + * zero for false conditional case + */ +int tlevel; /* current conditional level + */ +int ifcnd[MAXIF+1]; /* array of IF statement condition + * values (0 = FALSE) indexed by tlevel + */ +int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel + * values indexed by tlevel + */ + +char afn[FILSPC]; /* current input file specification + */ +int afp; /* current input file path length + */ +char afntmp[FILSPC]; /* temporaryr input file specification + */ +int afptmp; /* temporary input file path length + */ +char srcfn[MAXFIL][FILSPC]; /* array of source file names + */ +int srcfp[MAXFIL]; /* array of source file path lengths + */ +int srcline[MAXFIL]; /* source line number + */ +char incfn[MAXINC][FILSPC]; /* array of include file names + */ +int incfp[MAXINC]; /* array of include file path lengths + */ +int incline[MAXINC]; /* include line number + */ + +int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +int line; /* current assembler source + * line number + */ +int page; /* current page number + */ +int lop; /* current line number on page + */ +int pass; /* assembler pass number + */ +int lflag; /* -l, generate listing flag + */ +int gflag; /* -g, make undefined symbols global flag + */ +int aflag; /* -a, make all symbols global flag + */ +int oflag; /* -o, generate relocatable output flag + */ +int sflag; /* -s, generate symbol table flag + */ +int pflag; /* -p, enable listing pagination + */ +int wflag; /* -w, enable wide listing format + */ +int zflag; /* -z, enable symbol case sensitivity + */ +int xflag; /* -x, listing radix flag + */ +int fflag; /* -f(f), relocations flagged flag + */ +int a_bytes; /* REL file T Line address length + */ +a_uint a_mask; /* Address Mask + */ +a_uint s_mask; /* Sign Mask + */ +a_uint v_mask; /* Value Mask + */ +a_uint laddr; /* address of current assembler line + * or value of .if argument + */ +a_uint fuzz; /* tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + */ +int lmode; /* listing mode + */ +char *ep; /* pointer into error list + * array eb[NERR] + */ +char eb[NERR]; /* array of generated error codes + */ +char *ip; /* pointer into the assembler-source + * text line in ib[] + */ +char ib[NINPUT]; /* assembler-source text line + */ +char *cp; /* pointer to assembler output + * array cb[] + */ +char cb[NCODE]; /* array of assembler output values + */ +int *cpt; /* pointer to assembler relocation type + * output array cbt[] + */ +int cbt[NCODE]; /* array of assembler relocation types + * describing the data in cb[] + */ +char tb[NTITL]; /* Title string buffer + */ +char stb[NSBTL]; /* Subtitle string buffer + */ +char erb[NINPUT+4]; /* Error string buffer + */ + +char symtbl[] = { "Symbol Table" }; +char aretbl[] = { "Area Table" }; + +char module[NCPS+2]; /* module name string + */ + +/* + * The mne structure is a linked list of the assembler + * mnemonics and directives. The list of mnemonics and + * directives contained in the device dependent file + * xxxpst.c are hashed and linked into NHASH lists in + * module assym.c by syminit(). The structure contains + * the mnemonic/directive name, a subtype which directs + * the evaluation of this mnemonic/directive, a flag which + * is used to detect the end of the mnemonic/directive + * list in xxxpst.c, and a value which is normally + * associated with the assembler mnemonic base instruction + * value. + * + * struct mne + * { + * struct mne *m_mp; Hash link + * char * m_id; Mnemonic (JLH) + * char m_type; Mnemonic subtype + * char m_flag; Mnemonic flags + * a_uint m_valu; Value + * }; + */ +struct mne *mnehash[NHASH]; + +/* + * The sym structure is a linked list of symbols defined + * in the assembler source files. The first symbol is "." + * defined here. The entry 'struct tsym *s_tsym' + * links any temporary symbols following this symbol and + * preceeding the next normal symbol. The structure also + * contains the symbol's name, type (USER or NEW), flag + * (global, assigned, and multiply defined), a pointer + * to the area structure defining where the symbol is + * located, a reference number assigned by outgsd() in + * asout.c, and the symbols address relative to the base + * address of the area where the symbol is located. + * + * struct sym + * { + * struct sym *s_sp; Hash link + * struct tsym *s_tsym; Temporary symbol link + * char *s_id; Symbol (JLH) + * char s_type; Symbol subtype + * char s_flag; Symbol flags + * struct area *s_area; Area line, 0 if absolute + * int s_ref; Ref. number + * a_uint s_addr; Address + * }; + */ +struct sym sym[] = { + { NULL, NULL, ".", S_USER, 0, NULL,0,0 }, +#if 1 /* Nick */ + { NULL, NULL, ".__.ABS.", S_USER, S_ASG|S_GBL|S_ENDPST,NULL,0,0 } +#else + { NULL, NULL, ".__.ABS.", S_USER, S_ASG|S_GBL|S_END, NULL,0,0 } +#endif +}; + +struct sym *symp; /* pointer to a symbol structure + */ +struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ + +/* + * The area structure contains the parameter values for a + * specific program or data section. The area structure + * is a linked list of areas. The initial default area + * is "_CODE" defined here, the next area structure + * will be linked to this structure through the structure + * element 'struct area *a_ep'. The structure contains the + * area name, area reference number ("_CODE" is 0) determined + * by the order of .area directives, area size determined + * from the total code and/or data in an area, area fuzz is + * an variable used to track pass to pass changes in the + * area size caused by variable length instruction formats, + * and area flags which specify the area's relocation type. + * + * struct area + * { + * struct area *a_ap; Area link + * char * a_id; Area Name + * int a_ref; Reference number + * a_uint a_size; Area size + * a_uint a_fuzz; Area fuzz + * int a_flag; Area flags + * }; + */ +struct area area[] = { +#if 1 /* Nick */ + { NULL, "_DEFAULT", 0, 0, 0, A_CON|A_REL } +#else + { NULL, "_CODE", 0, 0, 0, A_CON|A_REL } +#endif +}; + +struct area *areap; /* pointer to an area structure + */ + +FILE *lfp; /* list output file handle + */ +FILE *ofp; /* relocation output file handle + */ +FILE *tfp; /* symbol table output file handle + */ +FILE *sfp[MAXFIL]; /* array of assembler-source file handles + */ +FILE *ifp[MAXINC]; /* array of include-file file handles + */ + +/* + * array of character types, one per + * ASCII character + */ +char ctype[128] = { +/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, +/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, +/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, +/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, +/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, LETTER/*ETC*/, +/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*X*/ LETTER, LETTER, LETTER, ETC, ETC, ETC, BINOP, LETTER, +/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC +}; + +/* + * an array of characters which + * perform the case translation function + */ +char ccase[128] = { +/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', +/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', +/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', +/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', +/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', +/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', +/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', +/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', +/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', +/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' +}; diff --git a/src/as-z80/asexpr.c b/src/as-z80/asexpr.c new file mode 100755 index 00000000..74856e3d --- /dev/null +++ b/src/as-z80/asexpr.c @@ -0,0 +1,1218 @@ +/* asexpr.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With enhancements from + * + * Bill McKinnon (BM) + * w_mckinnon@conknet.com + */ + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "asxxxx.h" + +/*)Module asexpr.c + * + * The module asexpr.c contains the routines to evaluate + * arithmetic/numerical expressions. The functions in + * asexpr.c perform a recursive evaluation of the arithmetic + * expression read from the assembler-source text line. + * The expression may include binary/unary operators, brackets, + * symbols, labels, and constants in hexadecimal, decimal, octal + * and binary. Arithmetic operations are prioritized and + * evaluated by normal arithmetic conventions. + * + * asexpr.c contains the following functions: + * VOID abscheck() + * a_uint absexpr() + * VOID clrexpr() + * int digit() + * VOID expr() + * int oprio() + * VOID term() + * + * asexpr.c contains no local/static variables + */ + +/*)Function VOID expr(esp, n) + * + * expr * esp pointer to an expr structure + * int n a firewall priority; all top + * level calls (from the user) + * should be made with n set to 0. + * + * The function expr() evaluates an expression and + * stores its value and relocation information into + * the expr structure supplied by the user. + * + * Notes about the arithmetic: + * The coding emulates N-Bit unsigned + * arithmetic operations. This allows + * program compilation without regard to the + * intrinsic integer length of the host + * machine. + * + * local variables: + * a_uint ae value from expr esp + * a_uint ar value from expr re + * int c current assembler-source + * text character + * int p current operator priority + * area * ap pointer to an area structure + * exp re internal expr structure + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * + * functions called: + * VOID abscheck() asexpr.c + * VOID clrexpr() asexpr.c + * VOID expr() asexpr.c + * int get() aslex.c + * int getnb() aslex.c + * int oprio() asexpr.c + * VOID qerr() assubr.c + * VOID rerr() assubr.c + * VOID term() asexpr.c + * VOID unget() aslex.c + * + * + * side effects: + * An expression is evaluated modifying the user supplied + * expr structure, a sym structure maybe created for an + * undefined symbol, and the parse of the expression may + * terminate if a 'q' error occurs. + */ + +VOID +expr(esp, n) +register struct expr *esp; +int n; +{ +#if 1 /* Nick has added this to allow operators such as .low. etc */ + char *ip_save; +#endif + register a_uint ae, ar; + int c, p; + struct area *ap; + struct expr re; + + term(esp); +#if 1 /* Nick has modified this to allow operators such as .low. etc */ + ip_save = ip; + while ((c = getop())) { +#else + while (ctype[c = getnb()] & BINOP) { +#endif + /* + * Handle binary operators + - * / & | % ^ << >> + */ +#if 1 /* Nick has modified this to allow operators such as .low. etc */ + if ((p = oprio(c)) <= n) { + ip = ip_save; + break; + } +#else + if ((p = oprio(c)) <= n) + break; +#endif +#if 1 /* Nick has modified this to allow less-than / greater-than operators */ + if (c == '<' && c != get()) { + unget(c); + if (get() != '=') { + unget(c); + c = 'l'; /* less-than operator */ + } else { + c = 'L'; /* less-than-or-equal operator */ + } + } else + if (c == '>' && c != get()) { + unget(c); + if (get() != '=') { + unget(c); + c = 'g'; /* greather-than operator */ + } else { + c = 'G'; /* greater-than-or-equal operator */ + } + } +#else + if ((c == '>' || c == '<') && c != get()) + qerr(); +#endif + clrexpr(&re); + expr(&re, p); + esp->e_rlcf |= re.e_rlcf; + + /* + * 16-Bit Unsigned Arithmetic + */ + ae = esp->e_addr & a_mask; + ar = re.e_addr & a_mask; + + if (c == '+') { + /* + * esp + re, at least one must be absolute + */ + if (esp->e_base.e_ap == NULL) { + /* + * esp is absolute (constant), + * use area from re + */ + esp->e_base.e_ap = re.e_base.e_ap; + } else + if (re.e_base.e_ap) { + /* + * re should be absolute (constant) + */ + rerr(); + } + if (esp->e_flag && re.e_flag) + rerr(); + if (re.e_flag) + esp->e_flag = 1; + ae += ar; + } else +#if 1 /* Nick has modified this to allow less-than / greater-than operators */ + if (c == '-' || c == 'l' || c == 'L' || c == 'g' || c == 'G') { +#else + if (c == '-') { +#endif + /* + * esp - re + */ + if ((ap = re.e_base.e_ap) != NULL) { + if (esp->e_base.e_ap == ap) { + esp->e_base.e_ap = NULL; + } else { + rerr(); + } + } + if (re.e_flag) + rerr(); +#if 1 /* Nick has modified this to allow less-than / greater-than operators */ + switch (c) { + case 'l': + ae = (ae < ar); + break; + case 'L': + ae = (ae <= ar); + break; + case 'g': + ae = (ae > ar); + break; + case 'G': + ae = (ae >= ar); + break; + case '-': + ae -= ar; + break; + } +#else + esp->e_addr -= re.e_addr; + ae -= ar; +#endif + } else { + /* + * Both operands (esp and re) must be constants + */ + abscheck(esp); + abscheck(&re); + switch (c) { + /* + * The (int) /, %, and >> operations + * are truncated to 2-bytes. (Really? --Nick) + */ + +#if 1 /* Nick has modified this to allow operators such as .or. etc */ + case 'a': + ae = ae && ar; + break; + + case 'o': + ae = ae || ar; + break; +#endif + + case '*': + ae *= ar; + break; + + case '/': + if (ar == 0) { + ae = 0; + err('z'); + } else { + ae /= ar; + } + break; + + case '&': + ae &= ar; + break; + + case '|': + ae |= ar; + break; + + case '%': + if (ar == 0) { + ae = 0; + err('z'); + } else { + ae %= ar; + } + break; + + case '^': + ae ^= ar; + break; + + case '<': + ae <<= ar; + break; + + case '>': + ae >>= ar; + break; + + default: + qerr(); + break; + } + } + esp->e_addr = (ae & s_mask) ? ae | ~v_mask : ae & v_mask; +#if 1 /* Nick has modified this to allow operators such as .low. etc */ + ip_save = ip; +#endif + } +#if 0 /* Nick has modified this to allow operators such as .low. etc */ + unget(c); +#endif +} + +#if 1 /* Nick has added this function to allow operators such as .low. etc */ +int getop(void) +{ + register int c; + + if (ctype[c = getnb()] & BINOP) { + return c; /* it's a single-character operator */ + } + unget(c); /* it's not a single-character operator */ + return getop_binary(); /* it may be a textual operator string */ +} + +int getnop(void) +{ + char *ip_save; + register int c; + + ip_save = ip; + if (getop_binary()) { + ip = ip_save; + return 0; /* it's a valid character, but stop processing! */ + } + if (ctype[c = get()] & (LETTER|DIGIT)) { + return c; /* it's a valid symbol character */ + } + unget(c); /* it's not a valid symbol character */ + return 0; +} + +int getop_binary(void) +{ + if (getop_srch(".AND.")) { + return 'a'; /* encode the operator as a single character */ + } + + if (getop_srch(".BINAND.")) { + return '&'; /* encode the operator as a single character */ + } + + if (getop_srch(".OR.")) { + return 'o'; /* encode the operator as a single character */ + } + + if (getop_srch(".BINOR.")) { + return '|'; /* encode the operator as a single character */ + } + + if (getop_srch(".XOR.")) { + return '^'; /* encode the operator as a single character */ + } + + return 0; /* it's not a binary operator at all */ +} + +int getop_unary(void) +{ +#if 0 + if (getop_srch("LWRD")) { + unget(getnb()); /* skip this IAR keyword (what is it??) */ + } +#endif + + if (getop_srch(".NOT.")) { + return '!'; /* encode the operator as a single character */ + } + + if (getop_srch(".BINNOT.")) { + return '~'; /* encode the operator as a single character */ + } + + if (getop_srch(".LOW.")) { + return '<'; /* encode the operator as a single character */ + } + + if (getop_srch(".HIGH.")) { + return '>'; /* encode the operator as a single character */ + } + + if (getop_srch(".SFB.")) { + return '{'; /* encode the operator as a single character */ + } + + if (getop_srch(".SFE.")) { + return '}'; /* encode the operator as a single character */ + } + + return getnb(); /* it may be a single-character operator */ +} + +/* + * srch --- does string match ? + */ +int +getop_srch(str) +register char *str; +{ + register char *ptr; + ptr = ip; + +#if 0 /* CASE_SENSITIVE */ + while (*ptr && *str) { + if (*ptr != *str) + break; + ptr++; + str++; + } + if (*ptr == *str) { + ip = ptr; + return(1); + } +#else + while (*ptr && *str) { + if (ccase[(unsigned char)(*ptr)] != ccase[(unsigned char)(*str)]) + break; + ptr++; + str++; + } + if (ccase[(unsigned char)(*ptr)] == ccase[(unsigned char)(*str)]) { + ip = ptr; + return(1); + } +#endif + + if (!*str) + /*if (any(*ptr," \t\n,);+-"))*/ { /* if str is exhausted */ + ip = ptr; + return(1); + } + return(0); +} +#endif + +/*)Function a_uint absexpr() + * + * The function absexpr() evaluates an expression, verifies it + * is absolute (i.e. not position dependent or relocatable), and + * returns its value. + * + * local variables: + * expr e expr structure + * + * global variables: + * none + * + * functions called: + * VOID abscheck() asexpr.c + * VOID clrexpr() asexpr.c + * VOID expr() asexpr.c + * + * side effects: + * If the expression is not absolute then + * a 'r' error is reported. + */ + +a_uint +absexpr() +{ + struct expr e; + + clrexpr(&e); + expr(&e, 0); + abscheck(&e); + return (e.e_addr); +} + +/*)Function VOID term(esp) + * + * expr * esp pointer to an expr structure + * + * The function term() evaluates a single constant + * or symbol value prefaced by any unary operator + * ( +, -, ~, ', ", >, or < ). This routine is also + * responsible for setting the relocation type to symbol + * based (e.flag != 0) on global references. + * + * Notes about the arithmetic: + * The coding emulates N-Bit unsigned + * arithmetic operations. This allows + * program compilation without regard to the + * intrinsic integer length of the host + * machine. + * + * local variables: + * int c current character + * char id[] symbol name + * char * jp pointer to assembler-source text + * int n constant evaluation running sum + * int r current evaluation radix + * sym * sp pointer to a sym structure + * tsym * tp pointer to a tsym structure + * int v current digit evaluation + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * sym * symp pointer to a symbol structure + * + * functions called: + * VOID abscheck() asexpr.c + * int digit() asexpr.c + * VOID err() assubr.c + * VOID expr() asexpr.c + * int is_abs() asexpr.c + * int get() aslex.c + * VOID getid() aslex.c + * int getmap() aslex.c + * int getnb() aslex.c + * sym * lookup() assym.c + * VOID qerr() assubr.c + * VOID unget() aslex.c + * + * side effects: + * An arithmetic term is evaluated, a symbol structure + * may be created, term evaluation may be terminated + * by a 'q' error. + */ + +VOID +term(esp) +register struct expr *esp; +{ + register int c, n; + register char *jp; + char id[NCPS]; + struct sym *sp; + struct tsym *tp; + int r, v; + + r = radix; + c = getnb(); + /* + * Discard the unary '+' at this point and + * also any reference to numerical arguments + * associated with the '#' prefix. + */ + while (c == '+' || c == '#') { c = getnb(); } +#if 1 /* Nick has modified this to allow operators such as .low. etc */ + unget(c); /* so that c is included in the search for .low. etc */ + c = getop_unary(); /* encodes the operator as a single character */ +#endif + /* + * Evaluate all binary operators + * by recursively calling expr(). + */ + if (c == LFTERM) { + expr(esp, 0); + if (getnb() != RTTERM) + qerr(); + return; + } + if (c == '-') { + expr(esp, 100); + abscheck(esp); + esp->e_addr = ~esp->e_addr + 1; + return; + } + if (c == '~') { + expr(esp, 100); + abscheck(esp); + esp->e_addr = ~esp->e_addr; + return; + } +#if 1 /* Nick has added a new single-character operator, also used for .not. */ + if (c == '!') { + expr(esp, 100); + abscheck(esp); + esp->e_addr = !esp->e_addr; + return; + } +#endif + if (c == '\'') { + esp->e_mode = S_USER; + esp->e_addr = getmap(-1)&0377; +#if 1 /* Nick has added this to allow an optional closing quote for literals */ + c = get(); + if (c != '\'') { + unget(c); + } +#endif + return; + } + if (c == '\"') { + esp->e_mode = S_USER; + if (hilo) { + esp->e_addr = (getmap(-1)&0377)<<8; + esp->e_addr |= (getmap(-1)&0377); + } else { + esp->e_addr = (getmap(-1)&0377); + esp->e_addr |= (getmap(-1)&0377)<<8; + } + if (esp->e_addr & s_mask) { + esp->e_addr |= ~v_mask; + } else { + esp->e_addr &= v_mask; + } + return; + } + if (c == '>' || c == '<') { + expr(esp, 100); + if (is_abs (esp)) { + /* + * evaluate msb/lsb directly + */ + if (c == '>') + esp->e_addr >>= 8; + esp->e_addr &= 0377; + return; + } else { + /* + * let linker perform msb/lsb, lsb is default + */ + esp->e_rlcf |= R_BYTX; + if (c == '>') + esp->e_rlcf |= R_MSB; + return; + } + } +#if 1 /* Nick, for .SFB. and .SFE. operators */ + if (c == '{' || c == '}') + { + /* + * Evaluate symbols and labels + */ + n = getnb(); + if (ctype[n] & LETTER) + { + unget(n); /* skip white space */ + esp->e_mode = S_USER; + getid(id, '_'); + n = NCPS; + while (--n) + { + id[n] = id[n-1]; + } + id[n] = (c == '{') ? 's' : 'e'; + sp = lookup(id); + if (sp->s_type == S_NEW) + { +#if 1 + sp->s_flag |= S_GBL; +#else + if (sp->s_flag&S_GBL) + { +#endif + esp->e_flag = 1; + esp->e_base.e_sp = sp; + return; +#if 0 + } + err('u'); +#endif + } + else + { + esp->e_mode = sp->s_type; + esp->e_addr = sp->s_addr; + esp->e_base.e_ap = sp->s_area; + } + return; + } + /* + * Else not a term. + */ + qerr(); + } +#endif + /* + * Evaluate digit sequences as local symbols + * if followed by a '$' or as constants. + */ + if (ctype[c] & DIGIT) { + esp->e_mode = S_USER; + jp = ip; + while (ctype[*jp & 0x007F] & RAD10) { + jp++; + } + if (*jp == '$') { + n = 0; + while ((v = digit(c, 10)) >= 0) { + n = 10*n + v; + c = get(); + } + tp = symp->s_tsym; + while (tp) { + if (n == tp->t_num) { + esp->e_base.e_ap = tp->t_area; + esp->e_addr = tp->t_addr; + return; + } + tp = tp->t_lnk; + } + err('u'); + return; + } +#if 1 /* Nick has copied the code below, to process suffixes eg. 1234h */ + jp = ip; + while (ctype[(unsigned char)(*jp)] & RAD16) { + jp++; + } + if (ctype[(unsigned char)(*jp)] & LETTER) { + jp++; + } + if (ctype[(unsigned char)(*jp)] & (LETTER|DIGIT)) { + goto radix_prefix; + } + switch (*--jp) { + case 'b': + case 'B': + r = 2; + goto radix_suffix; + case 'o': + case 'O': + case 'q': + case 'Q': + r = 8; + goto radix_suffix; + case 'd': + case 'D': + r = 10; + goto radix_suffix; + case 'h': + case 'H': + case 'x': + case 'X': + r = 16; + goto radix_suffix; + default: + break; + } + radix_prefix: +#endif + if (c == '0') { + c = get(); + switch (c) { + case 'b': + case 'B': + r = 2; + c = get(); + break; + case 'o': + case 'O': + case 'q': + case 'Q': + r = 8; + c = get(); + break; + case 'd': + case 'D': + r = 10; + c = get(); + break; + case 'h': + case 'H': + case 'x': + case 'X': + r = 16; + c = get(); + break; + default: + break; + } + } + n = 0; + while ((v = digit(c, r)) >= 0) { + n = r*n + v; + c = get(); + } + unget(c); + esp->e_addr = (n & s_mask) ? n | ~v_mask : n & v_mask; + return; +#if 1 /* Nick has inserted the label below, to process suffixes eg. 1234h */ + radix_suffix: + n = 0; + while ((v = digit(c, r)) >= 0) { + n = r*n + v; + c = get(); + } + /*unget(c);*/ + esp->e_addr = (n & s_mask) ? n | ~v_mask : n & v_mask; + return; +#endif + } + /* + * Evaluate '$' sequences as a temporary radix + * if followed by a '%', '&', '#', or '$'. + */ + if (c == '$') { + c = get(); + if (c == '%' || c == '&' || c == '#' || c == '$') { + switch (c) { + case '%': + r = 2; + break; + case '&': + r = 8; + break; + case '#': + r = 10; + break; + case '$': + r = 16; + break; + default: + break; + } + c = get(); + n = 0; + while ((v = digit(c, r)) >= 0) { + n = r*n + v; + c = get(); + } + unget(c); + esp->e_mode = S_USER; + esp->e_addr = (n & s_mask) ? n | ~v_mask : n & v_mask; + return; + } + unget(c); + c = '$'; + } + /* + * Evaluate symbols and labels + */ + if (ctype[c] & LETTER) { + esp->e_mode = S_USER; + getid(id, c); +#if 1 /* Nick */ +/* printf("\"%s\"\n", id); */ + if (symeq(id, "LOW", 0)) + { + expr(esp, 100); + if (is_abs(esp)) + { + /* + * evaluate msb/lsb directly + */ + esp->e_addr &= 0xff; + return; + } + else + { + /* + * let linker perform msb/lsb, lsb is default + */ + esp->e_rlcf |= R_BYTX; + return; + } + } + else if (symeq(id, "HIGH", 0)) + { + expr(esp, 100); + if (is_abs(esp)) + { + /* + * evaluate msb/lsb directly + */ + esp->e_addr >>= 8; + esp->e_addr &= 0xff; + return; + } + else + { + /* + * let linker perform msb/lsb, lsb is default + */ + esp->e_rlcf |= R_BYTX; + esp->e_rlcf |= R_MSB; + return; + } + } + else if (symeq(id, "LWRD", 0)) + { + expr(esp, 100); + if (is_abs(esp)) + { + /* + * evaluate msb/lsb directly + */ + esp->e_addr &= 0xffff; + return; + } + else + { + /* + * let linker perform msb/lsb, lsb is default + */ +#if 0 + esp->e_rlcf |= R_BYTX; + esp->e_rlcf |= R_MSB; /* ???? */ +#endif + return; + } + } +#if 1 /*def R_BYTE3 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + else if (symeq(id, "BYTE3", 0)) + { + expr(esp, 100); + if (is_abs(esp)) + { + /* + * evaluate msb/lsb directly + */ + esp->e_addr >>= 16; + esp->e_addr &= 0xff; + return; + } + else + { + /* + * let linker perform msb/lsb, lsb is default + */ + esp->e_rlcf |= R_BYTX; +#ifdef R_BYTE3 + esp->e_rlcf |= R_BYTE3; +#endif + return; + } + } +#endif +#ifdef R_BYTE4 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + else if (symeq(id, "BYTE4", 0)) + { + expr(esp, 100); + if (is_abs(esp)) + { + /* + * evaluate msb/lsb directly + */ + esp->e_addr >>= 24; + esp->e_addr &= 0xff; + return; + } + else + { + /* + * let linker perform msb/lsb, lsb is default + */ + esp->e_rlcf |= R_BYTX; + esp->e_rlcf |= R_BYTE4; + return; + } + } +#endif +#endif + sp = lookup(id); + if (sp->s_type == S_NEW) { + if (sp->s_flag&S_GBL) { + esp->e_flag = 1; + esp->e_base.e_sp = sp; + return; + } + err('u'); + } else { + esp->e_mode = sp->s_type; + esp->e_addr = sp->s_addr; + esp->e_base.e_ap = sp->s_area; + } + return; + } + /* + * Else not a term. + */ + qerr(); +} + +/*)Function int digit(c, r) + * + * int c digit character + * int r current radix + * + * The function digit() returns the value of c + * in the current radix r. If the c value is not + * a number of the current radix then a -1 is returned. + * + * local variables: + * none + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * + * functions called: + * none + * + * side effects: + * none + */ + +int +digit(c, r) +register int c, r; +{ + if (r == 16) { + if (ctype[c] & RAD16) { + if (c >= 'A' && c <= 'F') + return (c - 'A' + 10); + if (c >= 'a' && c <= 'f') + return (c - 'a' + 10); + return (c - '0'); + } + } else + if (r == 10) { + if (ctype[c] & RAD10) + return (c - '0'); + } else + if (r == 8) { + if (ctype[c] & RAD8) + return (c - '0'); + } else + if (r == 2) { + if (ctype[c] & RAD2) + return (c - '0'); + } + return (-1); +} + +/*)Function VOID abscheck(esp) + * + * expr * esp pointer to an expr structure + * + * The function abscheck() tests the evaluation of an + * expression to verify it is absolute. If the evaluation + * is relocatable then an 'r' error is noted and the expression + * made absolute. + * + * Note: The area type (i.e. ABS) is not checked because + * the linker can be told to explicitly relocate an + * absolute area. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * VOID rerr() assubr.c + * + * side effects: + * The expression may be changed to absolute and the + * 'r' error invoked. + */ + +VOID +abscheck(esp) +register struct expr *esp; +{ + if (esp->e_flag || esp->e_base.e_ap) { + esp->e_flag = 0; + esp->e_base.e_ap = NULL; + rerr(); + } +} + +/*)Function int is_abs(esp) + * + * expr * esp pointer to an expr structure + * + * The function is_abs() tests the evaluation of an + * expression to verify it is absolute. If the evaluation + * is absolute then 1 is returned, else 0 is returned. + * + * Note: The area type (i.e. ABS) is not checked because + * the linker can be told to explicitly relocate an + * absolute area. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * none + * + * side effects: + * none + */ + +int +is_abs (esp) +register struct expr *esp; +{ + if (esp->e_flag || esp->e_base.e_ap) { + return(0); + } + return(1); +} + +/*)Function int oprio(c) + * + * int c operator character + * + * The function oprio() returns a relative priority + * for all valid unary and binary operators. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * none + * + * side effects: + * none + */ + +int +oprio(c) +register int c; +{ + if (c == '*' || c == '/' || c == '%') + return (10); + if (c == '+' || c == '-') + return (7); + if (c == '<' || c == '>') + return (5); + if (c == '^') + return (4); + if (c == '&') + return (3); + if (c == '|') + return (1); + return (0); +} + +/*)Function VOID clrexpr(esp) + * + * expr * esp pointer to expression structure + * + * The function clrexpr() clears the expression structure. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * none + * + * side effects: + * expression structure cleared. + */ + +VOID +clrexpr(esp) +register struct expr *esp; +{ + esp->e_mode = 0; + esp->e_flag = 0; + esp->e_addr = 0; + esp->e_base.e_ap = NULL; + esp->e_rlcf = 0; +} + +/*)Function VOID exprmasks(esp) + * + * int n T Line Bytes in Address + * + * The function exprmasks() configures the assembler + * for 16, 24, or 32-Bit Data/Addresses. + * + * local variables: + * none + * + * global variables: + * int a_bytes T Line Bytes in Address + * a_uint a_mask Address mask + * a_uint s_mask Sign mask + * a_uint v_mask Value mask + * + * functions called: + * none + * + * side effects: + * The arithmetic precision parameters are set. + */ + +VOID +exprmasks(n) +int n; +{ + a_bytes = n; + + switch(a_bytes) { + default: + a_bytes = 2; + case 2: + a_mask = 0x0000FFFF; + s_mask = 0x00008000; + v_mask = 0x00007FFF; + break; + + case 3: + a_mask = 0x00FFFFFF; + s_mask = 0x00800000; + v_mask = 0x007FFFFF; + break; + + case 4: + a_mask = 0xFFFFFFFF; + s_mask = 0x80000000; + v_mask = 0x7FFFFFFF; + break; + } +} + + diff --git a/src/as-z80/aslex.c b/src/as-z80/aslex.c new file mode 100755 index 00000000..499815f2 --- /dev/null +++ b/src/as-z80/aslex.c @@ -0,0 +1,529 @@ +/* aslex.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + */ + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "asxxxx.h" + +/*)Module aslex.c + * + * The module aslex.c includes the general lexical + * analysis routines for the assembler. + * + * aslex.c contains the following functions: + * char endline() + * int get() + * VOID getid() + * int getline() + * int getmap() + * int getnb() + * VOID getst() + * int more() + * VOID unget() + * + * aslex.c contains no local/static variables + */ + +/*)Function VOID getid(id,c) + * + * char * id a pointer to a string of + * maximum length NCPS-1 + * int c mode flag + * >=0 this is first character to + * copy to the string buffer + * <0 skip white space, first + * character must be a LETTER + * + * The function getid() scans the current assembler-source text line + * from the current position copying the next LETTER | DIGIT string + * into the external string buffer (id). The string ends when a non + * LETTER or DIGIT character is found. The maximum number of characters + * copied is NCPS-1. If the input string is larger than NCPS-1 + * characters then the string is truncated. The string is always + * NULL terminated. If the mode argument (c) is >=0 then (c) is + * the first character copied to the string buffer, if (c) is <0 + * then intervening white space (SPACES and TABS) are skipped and + * the first character found must be a LETTER else a 'q' error + * terminates the parse of this assembler-source text line. + * + * local variables: + * char * p pointer to external string buffer + * int c current character value + * + * global variables: + * char ctype[] a character array which defines the + * type of character being processed. + * This index is the character + * being processed. + * + * called functions: + * int get() aslex.c + * int getnb() aslex.c + * VOID unget() aslex.c + * + * side effects: + * use of getnb(), get(), and unget() updates the + * global pointer ip, the position in the current + * assembler-source text line. + */ + +VOID +getid(id, c) +register int c; +char *id; +{ + register char *p; +#if 1 /* Nick */ + char *ipsave; +#endif + + if (c < 0) { + c = getnb(); + if ((ctype[c] & LETTER) == 0) + qerr(); + } + p = id; + do { +#if 1 /* Nick, to terminate symbol processing when binary operator seen */ + if (c == '.') + { + ipsave = ip--; /* unget(c); */ + if (getop_binary()) + { + ip = ipsave; + break; + } + ip = ipsave; + } +#endif + if (p < &id[NCPS-1]) + *p++ = c; + } while (ctype[c=get()] & (LETTER|DIGIT)); + unget(c); + *p++ = 0; +} + +/*)Function VOID getst(id,c) + * + * char * id a pointer to a string of + * maximum length NCPS-1 + * int c mode flag + * >=0 this is first character to + * copy to the string buffer + * <0 skip white space, first + * character must be a LETTER + * + * The function getnbid() scans the current assembler-source text line + * from the current position copying the next character string into + * the external string buffer (id). The string ends when a SPACE or + * ILL character is found. The maximum number of characters copied is + * NCPS-1. If the input string is larger than NCPS-1 characters then + * the string is truncated. The string is always NULL terminated. + * If the mode argument (c) is >=0 then (c) is the first character + * copied to the string buffer, if (c) is <0 then intervening white + * space (SPACES and TABS) are skipped and the first character found + * must be a LETTER else a 'q' error terminates the parse of this + * assembler-source text line. + * + * local variables: + * char * p pointer to external string buffer + * int c current character value + * + * global variables: + * char ctype[] a character array which defines the + * type of character being processed. + * This index is the character + * being processed. + * + * called functions: + * int get() aslex.c + * int getnb() aslex.c + * VOID unget() aslex.c + * + * side effects: + * use of getnb(), get(), and unget() updates the + * global pointer ip, the position in the current + * assembler-source text line. + */ + +VOID +getst(id, c) +register int c; +char *id; +{ + register char *p; + + if (c < 0) { + c = getnb(); + if ((ctype[c] & LETTER) == 0) + qerr(); + } + p = id; + do { + if (p < &id[NCPS-1]) + *p++ = c; + } while (ctype[c=get()] & ~(SPACE|ILL) & 0xFF); + unget(c); + *p++ = 0; +} + +/*)Function int getnb() + * + * The function getnb() scans the current assembler-source + * text line returning the first character not a SPACE or TAB. + * + * local variables: + * int c current character from + * assembler-source text line + * + * global variables: + * none + * + * called functions: + * int get() aslex.c + * + * side effects: + * use of get() updates the global pointer ip, the position + * in the current assembler-source text line + */ + +int +getnb() +{ + register int c; + + while ((c=get()) == ' ' || c == '\t') + ; + return (c); +} + +/*)Function int get() + * + * The function get() returns the next character in the + * assembler-source text line, at the end of the line a + * NULL character is returned. + * + * local variables: + * int c current character from + * assembler-source text line + * + * global variables: + * char * ip pointer into the current + * assembler-source text line + * + * called functions: + * none + * + * side effects: + * updates ip to the next character position in the + * assembler-source text line. If ip is at the end of the + * line, ip is not updated. + */ + +int +get() +{ + register int c; + + if ((c = *ip) != 0) + ++ip; + return (c & 0x007F); +} + +/*)Function VOID unget(c) + * + * int c value of last character read from + * assembler-source text line + * + * If (c) is not a NULL character then the global pointer ip + * is updated to point to the preceeding character in the + * assembler-source text line. + * + * NOTE: This function does not push the character (c) + * back into the assembler-source text line, only + * the pointer ip is changed. + * + * local variables: + * int c last character read from + * assembler-source text line + * + * global variables: + * char * ip position into the current + * assembler-source text line + * + * called functions: + * none + * + * side effects: + * ip decremented by 1 character position + */ + +VOID +unget(c) +int c; +{ + if (c) + if (ip != ib) + --ip; +} + +/*)Function int getmap(d) + * + * int d value to compare with the + * assembler-source text line character + * + * The function getmap() converts the 'C' style characters \b, \f, + * \n, \r, and \t to their equivalent ascii values and also + * converts 'C' style octal constants '\123' to their equivalent + * numeric values. If the first character is equivalent to (d) then + * a (-1) is returned, if the end of the line is detected then + * a 'q' error terminates the parse for this line, or if the first + * character is not a \ then the character value is returned. + * + * local variables: + * int c value of character from the + * assembler-source text line + * int n looping counter + * int v current value of numeric conversion + * + * global variables: + * none + * + * called functions: + * int get() aslex.c + * + * side effects: + * use of get() updates the global pointer ip the position + * in the current assembler-source text line + */ + +int +getmap(d) +int d; +{ + register int c, n, v; + + if ((c=get()) == '\0') + qerr(); + if (c == d) + return (-1); + if (c == '\\') { + c = get(); + switch (c) { + + case 'b': + c = '\b'; + break; + + case 'f': + c = '\f'; + break; + + case 'n': + c = '\n'; + break; + + case 'r': + c = '\r'; + break; + + case 't': + c = '\t'; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + n = 0; + v = 0; + while (++n<=3 && c>='0' && c<='7') { + v = (v<<3) + c - '0'; + c = get(); + } + unget(c); + c = v; + break; + } + } + return (c); +} + +/*)Function int getline() + * + * The function getline() reads a line of assembler-source text + * from an assembly source text file or an include file. + * Lines of text are processed from assembler-source files until + * all files have been read. If an include file is opened then + * lines of text are read from the include file (or nested + * include file) until the end of the include file is found. + * The input text line is copied into the global string ib[] + * and converted to a NULL terminated string. The function + * getline() returns a (1) after succesfully reading a line + * or a (0) if all files have been read. + * + * local variables: + * int i string length + * + * global variables: + * char afn[] afile() constructed filespec + * int afp afile constructed path length + * char ib[] string buffer containing + * assembler-source text line + * char ifp[] array of file handles for + * include files + * int incfil index for ifp[] specifies + * active include file + * int incline[] array of include file + * line numbers + * char incfn[][] array of include file names + * int incfp[] array of include file path lengths + * char sfp[] array of file handles for + * assembler source files + * int cfile index for sfp[] specifies + * active source file + * int srcline[] array of source file + * line numbers + * char srcfn[][] array of source file names + * int srcfp[] array of source file path lengths + * int inpfil maximum input file index + * + * called functions: + * int fclose() c-library + * char * fgets() c-library + * int strlen() c-library + * + * side effects: + * include file will be closed at detection of end of file. + * the next sequential source file may be selected. + * the global file indexes incfil or cfile may be changed. + * The current file specification afn[] and the path + * length afp may be changed. + * The respective source line or include line counter + * will be updated. + */ + +int +getline() +{ +register int i; + +loop: if (incfil >= 0) { + if (fgets(ib, sizeof ib, ifp[incfil]) == NULL) { + fclose(ifp[incfil]); + ifp[incfil--] = NULL; + if (incfil >= 0) { + strcpy(afn, incfn[incfil]); + afp = incfp[incfil]; + } else { + strcpy(afn, srcfn[cfile]); + afp = srcfp[cfile]; + } + lop = NLPP; + goto loop; + } else { + ++incline[incfil]; + } + } else { + if (fgets(ib, sizeof ib, sfp[cfile]) == NULL) { + if (++cfile <= inpfil) { + strcpy(afn, srcfn[cfile]); + afp = srcfp[cfile]; + srcline[cfile] = 0; + goto loop; + } + return (0); + } else { + ++srcline[cfile]; + } + } + i = strlen(ib) - 1; + if (ib[i] == '\n') + ib[i] = 0; + return (1); +} + +/*)Function int more() + * + * The function more() scans the assembler-source text line + * skipping white space (SPACES and TABS) and returns a (0) + * if the end of the line or a comment delimeter (;) is found, + * or a (1) if their are additional characters in the line. + * + * local variables: + * int c next character from the + * assembler-source text line + * + * global variables: + * none + * + * called functions: + * int getnb() aslex.c + * VOID unget() aslex.c + * + * side effects: + * use of getnb() and unget() updates the global pointer ip + * the position in the current assembler-source text line + */ + +int +more() +{ + register int c; + + c = getnb(); + unget(c); + return( (c == '\0' || c == ';') ? 0 : 1 ); +} + +/*)Function char endline() + * + * The function endline() scans the assembler-source text line + * skipping white space (SPACES and TABS) and returns the next + * character or a (0) if the end of the line is found or a + * comment delimiter (;) is found. + * + * local variables: + * int c next character from the + * assembler-source text line + * + * global variables: + * none + * + * called functions: + * int getnb() aslex.c + * + * side effects: + * use of getnb() updates the global pointer ip the + * position in the current assembler-source text line + */ + +char +endline() +{ + register int c; + + c = getnb(); + return( (c == '\0' || c == ';') ? 0 : c ); +} diff --git a/src/as-z80/aslist.c b/src/as-z80/aslist.c new file mode 100755 index 00000000..2236336b --- /dev/null +++ b/src/as-z80/aslist.c @@ -0,0 +1,953 @@ +/* aslist.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With enhancements from + * + * John L. Hartman (JLH) + * jhartman@compuserve.com + * + */ + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "asxxxx.h" + +/*)Module aslist.c + * + * The module aslist.c contains all the functions used + * to generate the assembler list and symbol output files. + * + * aslist.c contains the following functions: + * VOID list() + * VOID list1() + * VOID list2() + * VOID slew() + * VOID lstsym() + * + * The module aslist.c contains no local/static variables + */ + +/*)Function VOID list() + * + * The function list() generates the listing output + * which includes the input source, line numbers, + * and generated code. Numerical output may be selected + * as hexadecimal, decimal, or octal. + * + * local variables: + * int * wp pointer to the assembled data bytes + * int * wpt pointer to the data byte mode + * int n number of bytes listed per line + * int nb computed number of assembled bytes + * int l_addr laddr (int) truncated to 2-bytes + * + * global variables: + * int cb[] array of assembler output values + * int cbt[] array of assembler relocation types + * describing the data in cb[] + * int * cp pointer to assembler output array cb[] + * int * cpt pointer to assembler relocation type + * output array cbt[] + * char eb[] array of generated error codes + * char * ep pointer into error list + * array eb[] + * char ib[] assembler-source text line + * a_uint laddr address of current assembler line, + * equate, or value of .if argument + * FILE * lfp list output file handle + * int line current assembler source line number + * int lmode listing mode + * int xflag -x, listing radix flag + * + * functions called: + * int fprintf() c_library + * VOID list1() aslist.c + * int putc() c_library + * VOID slew() asslist.c + * + * side effects: + * Listing or symbol output updated. + */ + +/* The Output Formats +| Tabs- | | | | | | + 11111111112222222222333333333344444----- +012345678901234567890123456789012345678901234----- + | | | | | +ee XXXX xx xx xx xx xx xx LLLLL ************* HEX(16) +ee 000000 ooo ooo ooo ooo LLLLL ************* OCTAL(16) +ee DDDDD ddd ddd ddd ddd LLLLL ************* DECIMAL(16) + XXXX + OOOOOO + DDDDD + +| Tabs- | | | | | | + 11111111112222222222333333333344444----- +012345678901234567890123456789012345678901234----- + | | | | | +ee XXXXXX xx xx xx xx xx xx xx LLLLL ********* HEX(24) +ee OO000000 ooo ooo ooo ooo ooo LLLLL ********* OCTAL(24) +ee DDDDDDDD ddd ddd ddd ddd ddd LLLLL ********* DECIMAL(24) + XXXXXX + OOOOOOOO + DDDDDDDD + +| Tabs- | | | | | | + 11111111112222222222333333333344444----- +012345678901234567890123456789012345678901234----- + | | | | | +ee XXXXXXXX xx xx xx xx xx xx xx LLLLL ********* HEX(32) +eeOOOOO000000 ooo ooo ooo ooo ooo LLLLL ********* OCTAL(32) +ee DDDDDDDDDD ddd ddd ddd ddd ddd LLLLL ********* DECIMAL(32) + XXXXXXXX + OOOOOOOOOOO + DDDDDDDDDD +*/ + +VOID +list() +{ + register char *frmt, *wp; + register int *wpt; + register int n, nb; + register int l_addr; + + if (lfp == NULL || lmode == NLIST) + return; + + /* + * Get Correct Line Number + */ + if (incfil >= 0) { + line = incline[incfil]; + if (line == 0) { + if (incfil > 0) { + line = incline[incfil-1]; + } else { + line = srcline[cfile]; + } + } + } else { + line = srcline[cfile]; + } + + /* + * Move to next line. + */ + slew(lfp, pflag); + + /* + * Output a maximum of NERR error codes with listing. + */ + while (ep < &eb[NERR]) + *ep++ = ' '; + fprintf(lfp, "%.2s", eb); + + /* + * Source listing only option. + */ + if (lmode == SLIST) { + switch(a_bytes) { + default: + case 2: frmt = "%24s%5u %s\n"; break; + case 3: + case 4: frmt = "%32s%5u %s\n"; break; + } + fprintf(lfp, frmt, "", line, ib); + return; + } + if (lmode == ALIST) { + outchk(HUGE,HUGE); + } + + /* + * Truncate (int) to N-Bytes + */ + l_addr = laddr & a_mask; + + /* + * HEX output Option. + */ + if (xflag == 0) { /* HEX */ + /* + * Equate only + */ + if (lmode == ELIST) { + switch(a_bytes) { + default: + case 2: frmt = "%19s%04X"; break; + case 3: frmt = "%25s%06X"; break; + case 4: frmt = "%23s%08X"; break; + } + fprintf(lfp, frmt, "", l_addr); + fprintf(lfp, " %5u %s\n", line, ib); + return; + } + + /* + * Address (with allocation) + */ + switch(a_bytes) { + default: + case 2: frmt = " %04X"; break; + case 3: frmt = " %06X"; break; + case 4: frmt = " %08X"; break; + } + fprintf(lfp, frmt, l_addr); + if (lmode == ALIST || lmode == BLIST) { + switch(a_bytes) { + default: + case 2: frmt = "%19s%5u %s\n"; break; + case 3: + case 4: frmt = "%22s%5u %s\n"; break; + } + fprintf(lfp, frmt, "", line, ib); + outdot(); + return; + } + wp = cb; + wpt = cbt; + nb = (int) (cp - cb); + + /* + * Bytes per Line and Spacing + */ + switch(a_bytes) { + default: + case 2: n = 6; frmt = "%7s"; break; + case 3: + case 4: n = 7; frmt = "%12s"; break; + } + + /* + * First line of output for this source line with data. + */ + list1(wp, wpt, nb, n, 1); + fprintf(lfp, " %5u %s\n", line, ib); + + /* + * Subsequent lines of output if more data. + */ + while ((nb - n) > 0) { + nb -= n; + wp += n; + wpt += n; + slew(lfp, 0); + fprintf(lfp, frmt, ""); + list1(wp, wpt, nb, n, 0); + putc('\n', lfp); + } + } else + /* + * OCTAL output Option. + */ + if (xflag == 1) { /* OCTAL */ + /* + * Equate only + */ + if (lmode == ELIST) { + switch(a_bytes) { + default: + case 2: frmt = "%17s%06o"; break; + case 3: frmt = "%23s%08o"; break; + case 4: frmt = "%20s%011o"; break; + } + fprintf(lfp, frmt, "", l_addr); + fprintf(lfp, " %5u %s\n", line, ib); + return; + } + + /* + * Address (with allocation) + */ + switch(a_bytes) { + default: + case 2: frmt = " %06o"; break; + case 3: frmt = " %08o"; break; + case 4: frmt = "%011o"; break; + } + fprintf(lfp, frmt, l_addr); + if (lmode == ALIST || lmode == BLIST) { + switch(a_bytes) { + default: + case 2: frmt = "%17s%5u %s\n"; break; + case 3: + case 4: frmt = "%21s%5u %s\n"; break; + } + fprintf(lfp, frmt, "", line, ib); + outdot(); + return; + } + wp = cb; + wpt = cbt; + nb = (int) (cp - cb); + + /* + * Bytes per Line and Spacing + */ + switch(a_bytes) { + default: + case 2: n = 4; frmt = "%9s"; break; + case 3: + case 4: n = 5; frmt = "%13s"; break; + } + + /* + * First line of output for this source line with data. + */ + list1(wp, wpt, nb, n, 1); + fprintf(lfp, " %5u %s\n", line, ib); + + /* + * Subsequent lines of output if more data. + */ + while ((nb - n) > 0) { + nb -= n; + wp += n; + wpt += n; + slew(lfp, 0); + fprintf(lfp, frmt, ""); + list1(wp, wpt, nb, n, 0); + putc('\n', lfp); + } + } else + /* + * DECIMAL output Option. + */ + if (xflag == 2) { /* DECIMAL */ + /* + * Equate only + */ + if (lmode == ELIST) { + switch(a_bytes) { + default: + case 2: frmt = "%18s%05u"; break; + case 3: frmt = "%23s%08u"; break; + case 4: frmt = "%21s%010u"; break; + } + fprintf(lfp, frmt, "", l_addr); + fprintf(lfp, " %5u %s\n", line, ib); + return; + } + + /* + * Address (with allocation) + */ + switch(a_bytes) { + default: + case 2: frmt = " %05u"; break; + case 3: frmt = " %08u"; break; + case 4: frmt = " %010u"; break; + } + fprintf(lfp, frmt, l_addr); + if (lmode == ALIST || lmode == BLIST) { + switch(a_bytes) { + default: + case 2: frmt = "%17s%5u %s\n"; break; + case 3: + case 4: frmt = "%21s%5u %s\n"; break; + } + fprintf(lfp, frmt, "", line, ib); + outdot(); + return; + } + wp = cb; + wpt = cbt; + nb = (int) (cp - cb); + + /* + * Bytes per Line and Spacing + */ + switch(a_bytes) { + default: + case 2: n = 4; frmt = "%9s"; break; + case 3: + case 4: n = 5; frmt = "%13s"; break; + } + + /* + * First line of output for this source line with data. + */ + list1(wp, wpt, nb, n, 1); + fprintf(lfp, " %5u %s\n", line, ib); + + /* + * Subsequent lines of output if more data. + */ + while ((nb - n) > 0) { + nb -= n; + wp += n; + wpt += n; + slew(lfp, 0); + fprintf(lfp, frmt, ""); + list1(wp, wpt, nb, n, 0); + putc('\n', lfp); + } + } +} + +/*)Function VOID list1(wp, wpt, nw, n, f) + * + * int f fill blank fields (1) + * int n number of bytes listed per line + * int nb number of data bytes + * int * wp pointer to data bytes + * int * wpt pointer to data byte mode + * + * local variables: + * int i loop counter + * + * global variables: + * int xflag -x, listing radix flag + * + * functions called: + * VOID list2() asslist.c + * int fprintf() c_library + * + * side effects: + * Data formatted and output to listing. + */ + +VOID +list1(wp, wpt, nb, n, f) +register char *wp; +register int *wpt, nb, n, f; +{ + register int i; + + /* + * HEX output Option. + */ + if (xflag == 0) { /* HEX */ + /* + * Bound number of words to HEX maximum per line. + */ + if (nb > n) + nb = n; + + /* + * Output bytes. + */ + for (i=0; i n) + nb = n; + + /* + * Output bytes. + */ + for (i=0; i n) + nb = n; + + /* + * Output bytes. + */ + for (i=0; i= 2) { + if (t & R_RELOC) { +#ifdef R_PAG0 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + if ((t & (R_PAG0|R_PAG)) && ((t & R_ECHEK) != R_EXTND)) { + c = '*'; + } else +#endif + if (t & R_USGN) { + c = 'u'; + } else if (t & R_PCR) { + c = 'p'; + } else { + c = 'r'; + } + if (t & R_HIGH || t & R_BYT4) c += 1; + if (t & R_BYT3 || t & R_BYT4) c &= ~0x20; + } + } + + /* + * Output the selected mode. + */ + putc(c, lfp); +} + +/*)Function VOID slew(fp, flag) + * + * FILE * fp file handle for listing + * int flag enable pagination + * + * The function slew() increments the page line count. + * If the page overflows and pagination is enabled: + * 1) put out a page skip, + * 2) a title, + * 3) a subtitle, + * 4) and reset the line count. + * + * local variables: + * none + * + * global variables: + * char cpu[] cpu type string + * int lop current line number on page + * int page current page number + * char stb[] Subtitle string buffer + * char tb[] Title string buffer + * + * functions called: + * int fprintf() c_library + * + * side effects: + * Increments page line counter, on overflow + * a new page header is output to the listing file. + */ + +VOID +slew(fp,flag) +FILE *fp; +int flag; +{ + register char *frmt; + + if ((lop++ >= NLPP) && flag) { + fprintf(fp, "\fASxxxx Assembler %s (%s), page %u.\n", + VERSION, cpu, ++page); + switch(xflag) { + default: +#if 1 /* Nick */ + case 0: frmt = "Hexadecimal [%d-Bits]\n"; break; +#else + case 0: frmt = "Hexidecimal [%d-Bits]\n"; break; +#endif + case 1: frmt = "Octal [%d-Bits]\n"; break; + case 2: frmt = "Decimal [%d-Bits]\n"; break; + } + fprintf(fp, frmt, 8 * a_bytes); + fprintf(fp, "%s\n", tb); + fprintf(fp, "%s\n\n", stb); + lop = 6; + } +} + +/*)Function VOID lstsym(fp) + * + * FILE * fp file handle for output + * + * The function lstsym() outputs alphabetically + * sorted symbol and area tables. + * + * local variables: + * int c temporary + * int i loop counter + * int j temporary + * int k temporary + * char * ptr pointer to an id string + * int nmsym number of symbols + * int narea number of areas + * sym * sp pointer to symbol structure + * sym ** p pointer to an array of + * pointers to symbol structures + * area * ap pointer to an area structure + * + * global variables: + * area * areap pointer to an area structure + * char aretbl[] string "Area Table" + * sym dot defined as sym[0] + * char stb[] Subtitle string buffer + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * char symtbl[] string "Symbol Table" + * FILE * tfp symbol table output file handle + * int wflag -w, wide listing flag + * int xflag -x, listing radix flag + * + * functions called: + * int fprintf() c_library + * int putc() c_library + * VOID slew() aslist.c + * int strcmp() c_library + * char * strcpy() c_library + * + * side effects: + * Symbol and area tables output. + */ + +VOID +lstsym(fp) +FILE *fp; +{ + register int c, i, j, k; + register char *frmt, *ptr; + int nmsym, narea; + struct sym *sp; + struct sym **p; + struct area *ap; + + /* + * Symbol Table Header + */ + strcpy(stb, &symtbl[0]); + lop = NLPP; + if (fp == tfp) + page = 0; + slew(fp, 1); + + /* + * Find number of symbols + */ + nmsym = 0; + for (i=0; is_sp; + } + } + if (nmsym == 0) + goto atable; + + /* + * Allocate space for an array of pointers to symbols + * and load array. + */ + if ((p = (struct sym **) malloc(sizeof((struct sym *) sp)*nmsym)) + == NULL) { + fprintf(fp, "Insufficient space to build Symbol Table.\n"); + return; + } + nmsym = 0; + for (i=0; is_sp; + } + } + + /* + * Bubble Sort on Symbol Table Array + */ + j = 1; + c = nmsym - 1; + while (j) { + j = 0; + for (i=0; is_id[0],&p[i+1]->s_id[0]) > 0) { + j = 1; + sp = p[i+1]; + p[i+1] = p[i]; + p[i] = sp; + } + } + } + + /* + * Symbol Table Output + */ + for (i=0; is_area) { + j = sp->s_area->a_ref; + switch(xflag) { + default: + case 0: frmt = " %2X "; break; + case 1: frmt = "%3o "; break; + case 2: frmt = "%3u "; break; + } + fprintf(fp, frmt, j); + } else { + fprintf(fp, " "); + } + + ptr = &sp->s_id[0]; + if (wflag) { + fprintf(fp, "%-55.55s", ptr ); /* JLH */ + } else { + fprintf(fp, "%-14.14s", ptr); + } + if (sp->s_flag & S_ASG) { + fprintf(fp, " = "); + } else { + fprintf(fp, " "); + } + if (sp->s_type == S_NEW) { + switch(a_bytes) { + default: + case 2: + switch(xflag) { + default: + case 0: frmt = " **** "; break; + case 1: frmt = "****** "; break; + case 2: frmt = " ***** "; break; + } + break; + + case 3: + switch(xflag) { + default: + case 0: frmt = " ****** "; break; + case 1: frmt = "******** "; break; + case 2: frmt = "******** "; break; + } + break; + + case 4: + switch(xflag) { + default: + case 0: frmt = " ******** "; break; + case 1: frmt = "*********** "; break; + case 2: frmt = " ********** "; break; + } + break; + + } + fprintf(fp, frmt); + } else { + j = sp->s_addr & 0xFFFF; + switch(a_bytes) { + default: + case 2: + switch(xflag) { + default: + case 0: frmt = " %04X "; break; + case 1: frmt = "%06o "; break; + case 2: frmt = " %05u "; break; + } + break; + + case 3: + switch(xflag) { + default: + case 0: frmt = " %06X "; break; + case 1: frmt = "%08o "; break; + case 2: frmt = "%08u "; break; + } + break; + + case 4: + switch(xflag) { + default: + case 0: frmt = " %08X "; break; + case 1: frmt = "%011o "; break; + case 2: frmt = " %010u "; break; + } + break; + } + fprintf(fp, frmt, j); + } + + j = 0; + if (sp->s_flag & S_GBL) { + putc('G', fp); + ++j; + } + if (sp->s_area != NULL) { + putc('R', fp); + ++j; + } + if (sp->s_type == S_NEW) { + putc('X', fp); + ++j; + } + if (wflag) { + putc('\n', fp); /* JLH */ + slew(fp, 0); + ++i; + } else { + if (++i % 2 == 0) { + putc('\n', fp); + slew(fp, pflag); + } else + if (i < nmsym) { + while (j++ < 4) + putc(' ', fp); + fprintf(fp, "| "); + } + } + } + putc('\n', fp); + + /* + * Area Table Header + */ + +atable: + strcpy(stb, &aretbl[0]); + lop = NLPP; + slew(fp, 1); + + /* + * Area Table Output + */ + narea = 0; + ap = areap; + while (ap) { + ++narea; + ap = ap->a_ap; + } + for (i=0; ia_ap; + j = ap->a_ref; + switch(xflag) { + default: + case 0: frmt = " %2X "; break; + case 1: frmt = " %3o "; break; + case 2: frmt = " %3u "; break; + } + fprintf(fp, frmt, j); + + ptr = &ap->a_id[0]; + if (wflag) { + fprintf(fp, "%-35.35s", ptr ); + } else { + fprintf(fp, "%-14.14s", ptr); + } + + j = ap->a_size & 0xFFFF; + k = ap->a_flag; + switch(a_bytes) { + default: + case 2: + switch(xflag) { + default: + case 0: frmt = " size %4X flags %3X\n"; break; + case 1: frmt = " size %6o flags %3o\n"; break; + case 2: frmt = " size %5u flags %3u\n"; break; + } + break; + + case 3: + switch(xflag) { + default: + case 0: frmt = " size %6X flags %3X\n"; break; + case 1: frmt = " size %8o flags %3o\n"; break; + case 2: frmt = " size %8u flags %3u\n"; break; + } + break; + + case 4: + switch(xflag) { + default: + case 0: frmt = " size %8X flags %3X\n"; break; + case 1: frmt = " size %11o flags %3o\n"; break; + case 2: frmt = " size %10u flags %3u\n"; break; + } + break; + } + fprintf(fp, frmt, j, k); + } +} diff --git a/src/as-z80/asmain.c b/src/as-z80/asmain.c new file mode 100755 index 00000000..3c3fefc3 --- /dev/null +++ b/src/as-z80/asmain.c @@ -0,0 +1,1524 @@ +/* asmain.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "asxxxx.h" + + +/*)Module asmain.c + * + * The module asmain.c includes the command argument parser, + * the three pass sequencer, and the machine independent + * assembler parsing code. + * + * asmain.c contains the following functions: + * int main(argc, argv) + * VOID asexit(n) + * VOID asmbl() + * FILE * afile(fn, ft, wf) + * int fndidx(str) + * VOID newdot(nap) + * VOID phase(ap, a) + * VOID usage() + * + * asmain.c contains the array char *usetxt[] which + * references the usage text strings printed by usage(). + */ + +/*)Function int main(argc, argv) + * + * int argc argument count + * char * argv array of pointers to argument strings + * + * The function main() is the entry point to the assembler. + * The purpose of main() is to (1) parse the command line + * arguments for options and source file specifications and + * (2) to process the source files through the 3 pass assembler. + * Before each assembler pass various variables are initialized + * and source files are rewound to their beginning. During each + * assembler pass each assembler-source text line is processed. + * After each assembler pass the assembler information is flushed + * to any opened output files and the if-else-endif processing + * is checked for proper termination. + * + * The function main() is also responsible for opening all + * output files (REL, LST, and SYM), sequencing the global (-g) + * and all-global (-a) variable definitions, and dumping the + * REL file header information. + * + * local variables: + * char * p pointer to argument string + * int c character from argument string + * int i argument loop counter + * area * ap pointer to area structure + * + * global variables: + * int aflag -a, make all symbols global flag + * char afn[] afile() constructed filespec + * int afp afile constructed path length + * area * areap pointer to an area structure + * int aserr assembler error counter + * int cb[] array of assembler output values + * int cbt[] array of assembler relocation types + * describing the data in cb[] + * int cfile current file handle index + * of input assembly files + * int * cp pointer to assembler output array cb[] + * int * cpt pointer to assembler relocation type + * output array cbt[] + * char eb[] array of generated error codes + * char * ep pointer into error list array eb[] + * int fflag -f(f), relocations flagged flag + * int flevel IF-ELSE-ENDIF flag will be non + * zero for false conditional case + * a_uint fuzz tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + * int gflag -g, make undefined symbols global flag + * char ib[] assembler-source text line + * int inpfil count of assembler + * input files specified + * int ifcnd[] array of IF statement condition + * values (0 = FALSE) indexed by tlevel + * int iflvl[] array of IF-ELSE-ENDIF flevel + * values indexed by tlevel + * int incfil current file handle index + * for include files + * char * ip pointer into the assembler-source + * text line in ib[] + * jmp_buf jump_env compiler dependent structure + * used by setjmp() and longjmp() + * int lflag -l, generate listing flag + * int line current assembler source + * line number + * int lop current line number on page + * int oflag -o, generate relocatable output flag + * int page current page number + * int pflag enable listing pagination + * int pass assembler pass number + * int radix current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + * int sflag -s, generate symbol table flag + * char srcfn[][] array of source file names + * int srcfp[] array of source file path lengths + * int srcline[] current source file line + * char stb[] Subtitle string buffer + * sym * symp pointer to a symbol structure + * int tlevel current conditional level + * int wflag -w, enable wide listing format + * int xflag -x, listing radix flag + * int zflag -z, enable symbol case sensitivity + * FILE * lfp list output file handle + * FILE * ofp relocation output file handle + * FILE * tfp symbol table output file handle + * FILE * sfp[] array of assembler-source file handles + * + * called functions: + * FILE * afile() asmain.c + * VOID allglob() assym.c + * VOID asexit() asmain.c + * VOID diag() assubr.c + * VOID err() assubr.c + * int fprintf() c-library + * int getline() aslex.c + * VOID list() aslist.c + * VOID lstsym() aslist.c + * VOID minit() ___mch.c + * VOID newdot() asmain.c + * VOID outbuf() asout.c + * VOID outchk() asout.c + * VOID outgsd() asout.c + * int rewind() c-library + * int setjmp() c-library + * VOID symglob() assym.c + * VOID syminit() assym.c + * VOID usage() asmain.c + * + * side effects: + * Completion of main() completes the assembly process. + * REL, LST, and/or SYM files may be generated. + */ + +int +main(argc, argv) +int argc; +char *argv[]; +{ + register char *p; + register int c, i; + struct area *ap; + + fprintf(stdout, "\n"); + inpfil = -1; +#if 1 /* Nick */ + pflag = 0; +#else + pflag = 1; +#endif + for (i=1; i= 0) + usage(ER_FATAL); + ++p; + while ((c = *p++) != 0) + switch(c) { + + case 'a': + case 'A': + ++aflag; + break; + + case 'g': + case 'G': + ++gflag; + break; + + case 'l': + case 'L': + ++lflag; + break; + + case 'o': + case 'O': + ++oflag; + break; + + case 's': + case 'S': + ++sflag; + break; + + case 'p': + case 'P': +#if 1 /* Nick */ + pflag = 1; + break; + + case 'n': + case 'N': +#endif + pflag = 0; + break; + + case 'w': + case 'W': + ++wflag; + break; + + case 'z': + case 'Z': + ++zflag; + break; + + case 'x': + case 'X': + xflag = 0; + break; + + case 'q': + case 'Q': + xflag = 1; + break; + + case 'd': + case 'D': + xflag = 2; + break; + + case 'f': + case 'F': + ++fflag; + break; + + default: + usage(ER_FATAL); + } + } else { + if (++inpfil == MAXFIL) { + fprintf(stderr, "too many input files\n"); + asexit(ER_FATAL); + } + sfp[inpfil] = afile(p, "", 0); + strcpy(srcfn[inpfil],afn); + srcfp[inpfil] = afp; + if (inpfil == 0) { + if (lflag) + lfp = afile(p, "lst", 1); + if (oflag) + ofp = afile(p, "rel", 1); + if (sflag) + tfp = afile(p, "sym", 1); + } + } + } + if (inpfil < 0) + usage(ER_WARNING); +#if 1 /* Nick */ + exprmasks(4); +#else + exprmasks(2); +#endif + syminit(); + for (pass=0; pass<3; ++pass) { + aserr = 0; + if (gflag && pass == 1) + symglob(); + if (aflag && pass == 1) + allglob(); + if (oflag && pass == 2) + outgsd(); + flevel = 0; + tlevel = 0; + ifcnd[0] = 0; + iflvl[0] = 0; + radix = 10; + srcline[0] = 0; + page = 0; + stb[0] = 0; + lop = NLPP; + cfile = 0; + strcpy(afn, srcfn[cfile]); + afp = srcfp[cfile]; + incfil = -1; + for (i = 0; i <= inpfil; i++) + rewind(sfp[i]); + ap = areap; + while (ap) { + ap->a_fuzz = 0; + ap->a_size = 0; + ap = ap->a_ap; + } + fuzz = 0; + dot.s_addr = 0; + dot.s_area = &dca; + outbuf("I"); + outchk(0,0); + symp = ˙ + minit(); + while (getline()) { + cp = cb; + cpt = cbt; + ep = eb; + ip = ib; + if (setjmp(jump_env) == 0) + asmbl(); + if (pass == 2) { + diag(); + list(); + } + } + newdot(dot.s_area); /* Flush area info */ + if (flevel || tlevel) + err('i'); + } + if (oflag) + outchk(HUGE, HUGE); /* Flush */ + if (sflag) { + lstsym(tfp); + } else + if (lflag) { + lstsym(lfp); + } + asexit(aserr ? ER_ERROR : ER_NONE); + return(0); +} + +/*)Function VOID asexit(i) + * + * int i exit code + * + * The function asexit() explicitly closes all open + * files and then terminates the program. + * + * local variables: + * int j loop counter + * + * global variables: + * FILE * ifp[] array of include-file file handles + * FILE * lfp list output file handle + * FILE * ofp relocation output file handle + * FILE * tfp symbol table output file handle + * FILE * sfp[] array of assembler-source file handles + * + * functions called: + * int fclose() c-library + * VOID exit() c-library + * + * side effects: + * All files closed. Program terminates. + */ + +VOID +asexit(i) +int i; +{ + int j; + + if (lfp != NULL) fclose(lfp); + if (ofp != NULL) fclose(ofp); + if (tfp != NULL) fclose(tfp); + + for (j=0; j= 0) { + n = 10*n + d; + c = get(); + } + if (c != '$' || get() != ':') + qerr(); + tp = symp->s_tsym; + if (pass == 0) { + while (tp) { + if (n == tp->t_num) { + tp->t_flg |= S_MDF; + break; + } + tp = tp->t_lnk; + } + if (tp == NULL) { + tp=(struct tsym *) new (sizeof(struct tsym)); + tp->t_lnk = symp->s_tsym; + tp->t_num = n; + tp->t_flg = 0; + tp->t_area = dot.s_area; + tp->t_addr = dot.s_addr; + symp->s_tsym = tp; + } + } else { + while (tp) { + if (n == tp->t_num) { + break; + } + tp = tp->t_lnk; + } + if (tp) { + if (pass == 1) { + fuzz = tp->t_addr - dot.s_addr; + tp->t_area = dot.s_area; + tp->t_addr = dot.s_addr; + } else { + phase(tp->t_area, tp->t_addr); + if (tp->t_flg & S_MDF) + err('m'); + } + } else { + err('u'); + } + } + lmode = ALIST; + goto loop; + } + /* + * If the first character is a letter then assume a lable, + * symbol, assembler directive, or assembler mnemonic is + * being processed. + */ + if ((ctype[c] & LETTER) == 0) { + if (flevel) { + return; + } else { + qerr(); + } + } + getid(id, c); + c = getnb(); + /* + * If the next character is a : then a label is being processed. + * A double :: defines a global label. If this is new label + * then create a symbol structure. + * pass 0: + * Flag multiply defined labels. + * pass 1: + * Load area, address, and fuzz values + * into structure symp. + * pass 2: + * Check for assembler phase error and + * multiply defined error. + */ + if (c == ':') { + if (flevel) + return; + if ((c = get()) != ':') { + unget(c); + c = 0; + } + symp = lookup(id); + if (symp == &dot) + err('.'); + if (pass == 0) + if ((symp->s_type != S_NEW) && + ((symp->s_flag & S_ASG) == 0)) + symp->s_flag |= S_MDF; + if (pass != 2) { + fuzz = symp->s_addr - dot.s_addr; + symp->s_type = S_USER; + symp->s_area = dot.s_area; + symp->s_addr = dot.s_addr; + } else { + if (symp->s_flag & S_MDF) + err('m'); + phase(symp->s_area, symp->s_addr); + } + if (c) { + symp->s_flag |= S_GBL; + } + lmode = ALIST; + goto loop; + } + /* + * If the next character is a = then an equate is being processed. + * A double == defines a global equate. If this is a new variable + * then create a symbol structure. + */ + if (c == '=') { + if (flevel) + return; + if ((c = get()) != '=') { + unget(c); + c = 0; + } + clrexpr(&e1); + expr(&e1, 0); + sp = lookup(id); + if (sp == &dot) { + outall(); + if (e1.e_flag || e1.e_base.e_ap != dot.s_area) + err('.'); + } else + if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) { + err('m'); + } + sp->s_type = S_USER; + sp->s_area = e1.e_base.e_ap; + sp->s_addr = laddr = e1.e_addr; + sp->s_flag |= S_ASG; + if (c) { + sp->s_flag |= S_GBL; + } + lmode = ELIST; + goto loop; + } + unget(c); + lmode = flevel ? SLIST : CLIST; + if ((mp = mlookup(id)) == NULL) { +#if 1 /* Nick has copied the above code in order to process '.equ' and 'equ' */ + p = ip; /* save the input position */ + + getid(opt, -1); + mp = mlookup(opt); + if (mp && mp->m_type == S_EQU) { + if (flevel) + return; + /*if ((c = get()) != '=') { + unget(c); + c = 0; + }*/ + clrexpr(&e1); + expr(&e1, 0); + sp = lookup(id); + if (sp == &dot) { + outall(); + if (e1.e_flag || e1.e_base.e_ap != dot.s_area) + err('.'); + } else + if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) { + err('m'); + } + sp->s_type = S_USER; + sp->s_area = e1.e_base.e_ap; + sp->s_addr = laddr = e1.e_addr; + sp->s_flag |= S_ASG; + /*if (c) { + sp->s_flag |= S_GBL; + }*/ + lmode = ELIST; + goto loop; + } + + ip = p; /* restore the input position */ +#endif + if (!flevel) + err('o'); + return; + } + /* + * If we have gotten this far then we have found an + * assembler directive or an assembler mnemonic. + * + * Check for .if, .else, .endif, and .page directives + * which are not controlled by the conditional flags + */ + switch (mp->m_type) { + + case S_IF: +#if 1 /* Nick, in case undefined symbols are encountered in nested .if */ + if (flevel) + { + n = 0; /* value doesn't really matter */ + } + else + { + n = absexpr(); + } +#else + n = absexpr(); +#endif + if (tlevel < MAXIF) { + ++tlevel; + ifcnd[tlevel] = n; + iflvl[tlevel] = flevel; + if (n == 0) { + ++flevel; + } + } else { + err('i'); + } + lmode = ELIST; + laddr = n; + return; + + case S_ELSE: + if (ifcnd[tlevel]) { + if (++flevel > (iflvl[tlevel]+1)) { + err('i'); + } + } else { + if (--flevel < iflvl[tlevel]) { + err('i'); + } + } + lmode = SLIST; + return; + + case S_ENDIF: + if (tlevel) { + flevel = iflvl[tlevel--]; + } else { + err('i'); + } + lmode = SLIST; + return; + + case S_PAGE: + lop = NLPP; + lmode = NLIST; + return; + + default: + break; + } + if (flevel) + return; + /* + * If we are not in a false state for .if/.else then + * process the assembler directives here. + */ + switch (mp->m_type) { + +#if 1 /* Nick */ + case S_END: + /* this really does nothing for the moment, so put at end! */ + break; +#endif + + case S_EVEN: + outall(); + laddr = dot.s_addr = (dot.s_addr + 1) & ~1; + lmode = ALIST; + break; + + case S_ODD: + outall(); + laddr = dot.s_addr |= 1; + lmode = ALIST; + break; + + case S_DATA: + if ((a_uint) a_bytes < mp->m_valu) { + err('o'); + } + do { +#if 1 /* Nick, to allow quoted strings within .db definitions */ + if ((d = getnb()) == '\'' || d == '"') + { +#if 1 /* for IAR compatibility, the only escape sequence is 'double quote' */ + while (c = get()) + { + if (c == d) + { + c = get(); + if (c != d) + { + unget(c); + break; + } + } + outab(c); + } +#else /* process all the usual c-style string escape sequences */ + while ((c = getmap(d)) >= 0) + { + outab(c); + } +#endif + } + else + { + unget(d); + clrexpr(&e1); + expr(&e1, 0); + switch(mp->m_valu) + { + default: + case 1: + outrb(&e1, R_NORM); + break; + case 2: + outrw(&e1, R_NORM); + break; + case 3: + outr3b(&e1, R_NORM); + break; + case 4: + outr4b(&e1, R_NORM); + break; + } + } +#else + clrexpr(&e1); + expr(&e1, 0); + switch(mp->m_valu) { + default: + case 1: outrb(&e1, R_NORM); break; + case 2: outrw(&e1, R_NORM); break; + case 3: outr3b(&e1, R_NORM); break; + case 4: outr4b(&e1, R_NORM); break; + } +#endif + } while ((c = getnb()) == ','); + unget(c); + break; + + case S_ERROR: + clrexpr(&e1); + if (more()) { + expr(&e1, 0); + } + if (e1.e_addr != 0) { + err('e'); + } + lmode = SLIST; + break; + + case S_ASCII: + case S_ASCIZ: + if ((d = getnb()) == '\0') + qerr(); + while ((c = getmap(d)) >= 0) + outab(c); + if (mp->m_type == S_ASCIZ) + outab(0); + break; + + case S_ASCIS: + if ((d = getnb()) == '\0') + qerr(); + c = getmap(d); + while (c >= 0) { + if ((n = getmap(d)) >= 0) { + outab(c); + } else { + outab(c | 0x80); + } + c = n; + } + break; + + case S_BLK: + if ((a_uint) a_bytes < mp->m_valu) { + err('o'); + } + clrexpr(&e1); + expr(&e1, 0); + outchk(HUGE,HUGE); + dot.s_addr += e1.e_addr*mp->m_valu; + lmode = BLIST; + break; + + case S_TITLE: + p = tb; + if ((c = getnb()) != 0) { + do { + if (p < &tb[NTITL-1]) + *p++ = c; + } while ((c = get()) != 0); + } + *p = 0; + unget(c); + lmode = SLIST; + break; + + case S_SBTL: + p = stb; + if ((c = getnb()) != 0) { + do { + if (p < &stb[NSBTL-1]) + *p++ = c; + } while ((c = get()) != 0); + } + *p = 0; + unget(c); + lmode = SLIST; + break; + + case S_MODUL: + getst(id, -1); + if (pass == 0) { + if (module[0]) { + err('m'); + } else { + strncpy(module, id, NCPS); + } + } +#if 1 /* Nick */ + if ((c = getnb()) == '(') + { + if (ctype[c = getnb()] & DIGIT) + { + while (ctype[c = get()] & DIGIT) + ; + if (c != ')') + { + qerr(); + } + } + else + { + qerr(); + } + } +#endif + lmode = SLIST; + break; + +#if 1 /* Nick */ + case S_ENDMOD: + if (pass == 0) { + if (module[0]) { + module[0] = 0; + } else { + err('m'); + } + } + lmode = SLIST; + break; +#endif + + case S_GLOBL: + do { + getid(id, -1); + sp = lookup(id); + sp->s_flag |= S_GBL; + } while ((c = getnb()) == ','); + unget(c); + lmode = SLIST; + break; + + case S_DAREA: + getid(id, -1); + uaf = 0; + uf = A_CON|A_REL; + if ((c = getnb()) == '(') { +#if 1 /* Nick */ + if (ctype[c = getnb()] & DIGIT) + { + while (ctype[c = get()] & DIGIT) + ; + goto numeric; + } + unget(c); +#endif + do { + getid(opt, -1); + mp = mlookup(opt); + if (mp && mp->m_type == S_ATYP) { + ++uaf; + uf |= mp->m_valu; + } else { + err('u'); + } + } while ((c = getnb()) == ','); +#if 1 /* Nick */ + numeric: +#endif + if (c != ')') + qerr(); + } else { + unget(c); + } + if ((ap = alookup(id)) != NULL) { + if (uaf && uf != ap->a_flag) + err('m'); + } else { + ap = (struct area *) new (sizeof(struct area)); + ap->a_ap = areap; + ap->a_id = strsto(id); + ap->a_ref = areap->a_ref + 1; + ap->a_size = 0; + ap->a_fuzz = 0; + ap->a_flag = uaf ? uf : (A_CON|A_REL); + areap = ap; + } + newdot(ap); + lmode = SLIST; + break; + + case S_ORG: + if (dot.s_area->a_flag & A_ABS) { + outall(); + laddr = dot.s_addr = absexpr(); + } else { +#if 1 /* Nick has modified this to allow org'ing to a relocatable address */ + clrexpr(&e1); + expr(&e1, 0); + if (e1.e_base.e_ap == dot.s_area) { + laddr = dot.s_addr = e1.e_addr; + } else { + rerr(); + } +#else + err('o'); +#endif + } + outall(); + lmode = ALIST; + break; + + case S_RADIX: + if (more()) { + switch (getnb()) { + case 'b': + case 'B': + radix = 2; + break; + case '@': + case 'o': + case 'O': + case 'q': + case 'Q': + radix = 8; + break; + case 'd': + case 'D': + radix = 10; + break; + case 'h': + case 'H': + case 'x': + case 'X': + radix = 16; + break; + default: + radix = 10; + qerr(); + break; + } + } else { + radix = 10; + } + lmode = SLIST; + break; + + case S_INCL: + lmode = SLIST; + if (++incfil == MAXINC) { + --incfil; + err('i'); + break; + } + /* + * Copy path of file opening the include file + */ + strncpy(fn,afn,afp); + p = fn + afp; + /* + * Concatenate the .include file specification + */ + d = getnb(); +#if 1 /* Nick, to allow unquoted filenames */ + if (d == 0x22 || d == 27) + { + while ((c = get()) != d) + { + if (p < &fn[FILSPC-1]) + { + *p++ = c; + } + else + { + break; + } + } + } + else + { + c = d; + do + { + if (p < &fn[FILSPC-1]) + { + *p++ = c; + } + else + { + break; + } + c = get(); + } while (ctype[c & 0x7f] & (char)~(SPACE|ILL)); + } +#else + while ((c = get()) != d) { + if (p < &fn[FILSPC+FILSPC-1]) { + *p++ = c; + } else { + break; + } + } +#endif + *p = 0; + /* + * If .include specifies a path + * use it + * else + * use path of file opening the include file + */ + if (fndidx(fn + afp) != 0) { + afilex(fn + afp, ""); + } else { + afilex(fn, ""); + } + /* + * Open File + */ + if ((ifp[incfil] = fopen(afntmp, "r")) == NULL) { + --incfil; + err('i'); + } else { + lop = NLPP; + incline[incfil] = 0; + strcpy(afn, afntmp); + afp = afptmp; + strcpy(incfn[incfil],afn); + incfp[incfil] = afp; + } + break; + + /* + * If not an assembler directive then go to + * the machine dependent function which handles + * all the assembler mnemonics. + */ + default: + machine(mp); + } + goto loop; +} + +/*)Function FILE * afile(fn, ft, wf) + * + * char * fn file specification string + * char * ft file type string + * int wf read(0)/write(1) flag + * + * The function afile() opens a file for reading or writing. + * + * afile() returns a file handle for the opened file or aborts + * the assembler on an open error. + * + * local variables: + * FILE * fp file handle for opened file + * + * global variables: + * char afn[] afile() constructed filespec + * int afp afile() constructed path length + * char afntmp[] afilex() constructed filespec + * int afptmp afilex() constructed path length + * + * functions called: + * VOID afilex() asmain.c + * int fndidx() asmain.c + * FILE * fopen() c_library + * int fprintf() c_library + * char * strcpy() c_library + * + * side effects: + * File is opened for read or write. + */ + +FILE * +afile(fn, ft, wf) +char *fn; +char *ft; +int wf; +{ + FILE *fp; + + afilex(fn, ft); + + if ((fp = fopen(afntmp, wf?"w":"r")) == NULL) { + fprintf(stderr, "%s: cannot %s.\n", afntmp, wf?"create":"open"); + asexit(ER_FATAL); + } + + strcpy(afn, afntmp); + afp = afptmp; + + return (fp); +} + +/*)Function VOID afilex(fn, ft) + * + * char * fn file specification string + * char * ft file type string + * + * The function afilex() processes the file specification string: + * (1) If the file type specification string ft + * is not NULL then a file specification is + * constructed with the file path\name in fn + * and the extension in ft. + * (2) If the file type specification string ft + * is NULL then the file specification is + * constructed from fn. If fn does not have + * a file type then the default source file + * type dsft is appended to the file specification. + * + * afilex() aborts the assembler on a file specification length error. + * + * local variables: + * int c character value + * char * p1 pointer into filespec string afntmp + * char * p2 pointer into filespec string fn + * char * p3 pointer to filetype string ft + * + * global variables: + * char afntmp[] afilex() constructed filespec + * int afptmp afilex() constructed path length + * char dsft[] default assembler file type string + * + * functions called: + * VOID asexit() asmain.c + * int fndidx() asmain.c + * int fprintf() c_library + * char * strcpy() c_library + * + * side effects: + * File specification string may be modified. + */ + +VOID +afilex(fn, ft) +char *fn; +char *ft; +{ + register char *p1, *p2, *p3; + register int c; +#if 1 /* Nick */ + int l; +#endif + + if (strlen(fn) > (FILSPC-5)) { + fprintf(stderr, "File Specification %s is too long.", fn); + asexit(ER_FATAL); + } + + /* + * Save the File Name Index + */ + strcpy(afntmp, fn); + afptmp = fndidx(afntmp); + p1 = &afntmp[afptmp]; + p2 = &fn[afptmp]; + + /* + * Skip to File Extension Seperator + */ +#if 1 /* Nick */ + l = strlen(p2); + for (c = l - 1; c >= 0; c--) + { + if (p2[c] == FSEPX) + { + l = c; + break; + } +#ifdef WIN32 + if (p2[c] == '\\') +#else + if (p2[c] == '/') +#endif + { + break; + } + } + p1 += l; + p2 += l; + + c = *p2++; +#else + while (((c = *p2++) != 0) && (c != FSEPX)) { + p1++; + } +#endif + *p1++ = FSEPX; + + /* + * Copy File Extension + */ + p3 = ft; + if (*p3 == 0) { + if (c == FSEPX) { + p3 = p2; + } else { + p3 = dsft; + } + } + while ((c = *p3++) != 0) { + if (p1 < &afntmp[FILSPC-1]) + *p1++ = c; + } + *p1++ = 0; +} + +/*)Function int fndidx(str) + * + * char * str file specification string + * + * The function fndidx() scans the file specification string + * to find the index to the file name. If the file + * specification contains a 'path' then the index will + * be non zero. + * + * fndidx() returns the index value. + * + * local variables: + * char * p1 temporary pointer + * char * p2 temporary pointer + * + * global variables: + * none + * + * functions called: + * char * strrchr() c_library + * + * side effects: + * none + */ + +int +fndidx(str) +char *str; +{ + register char *p1, *p2; + + /* + * Skip Path Delimiters + */ + p1 = str; + if ((p2 = strrchr(p1, ':')) != NULL) { p1 = p2 + 1; } + if ((p2 = strrchr(p1, '/')) != NULL) { p1 = p2 + 1; } + if ((p2 = strrchr(p1, '\\')) != NULL) { p1 = p2 + 1; } + + return(p1 - str); +} + +/*)Function VOID newdot(nap) + * + * area * nap pointer to the new area structure + * + * The function newdot(): + * (1) copies the current values of fuzz and the last + * address into the current area referenced by dot + * (2) loads dot with the pointer to the new area and + * loads the fuzz and last address parameters + * (3) outall() is called to flush any remaining + * bufferred code from the old area to the output + * + * local variables: + * area * oap pointer to old area + * + * global variables: + * sym dot defined as sym[0] + * a_uint fuzz tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + * + * functions called: + * none + * + * side effects: + * Current area saved, new area loaded, buffers flushed. + */ + +VOID +newdot(nap) +register struct area *nap; +{ + register struct area *oap; + + oap = dot.s_area; + oap->a_fuzz = fuzz; + oap->a_size = dot.s_addr; + fuzz = nap->a_fuzz; + dot.s_area = nap; + dot.s_addr = nap->a_size; + outall(); +} + +/*)Function VOID phase(ap, a) + * + * area * ap pointer to area + * a_uint a address in area + * + * Function phase() compares the area ap and address a + * with the current area dot.s_area and address dot.s_addr + * to determine if the position of the symbol has changed + * between assembler passes. + * + * local variables: + * none + * + * global varaibles: + * sym * dot defined as sym[0] + * + * functions called: + * none + * + * side effects: + * The p error is invoked if the area and/or address + * has changed. + */ + +VOID +phase(ap, a) +struct area *ap; +a_uint a; +{ + if (ap != dot.s_area || a != dot.s_addr) + err('p'); +} + +char *usetxt[] = { + "Usage: [-dqxgalospwzf] file1 [file2 file3 ...]", + " d decimal listing", + " q octal listing", + " x hex listing (default)", + " g undefined symbols made global", + " a all user symbols made global", + " l create list output file1[.lst]", + " o create object output file1[.rel]", + " s create symbol output file1[.sym]", +#if 1 /* Nick */ + " p paginate listing file", + " n no pagination of listing file (default)", +#else + " p disable listing pagination", +#endif + " w wide listing format for symbol table", + " z enable case sensitivity for symbols", + " f flag relocatable references by ` in listing file", + " ff flag relocatable references by mode in listing file", + "", + NULL +}; + +/*)Function VOID usage(n) + * + * int n exit code + * + * The function usage() outputs to the stderr device the + * assembler name and version and a list of valid assembler options. + * + * local variables: + * char ** dp pointer to an array of + * text string pointers. + * + * global variables: + * char cpu[] assembler type string + * char * usetxt[] array of string pointers + * + * functions called: + * VOID asexit() asmain.c + * int fprintf() c_library + * + * side effects: + * program is terminated + */ + +VOID +usage(n) +int n; +{ + register char **dp; + + fprintf(stderr, "\nASxxxx Assembler %s (%s)\n\n", VERSION, cpu); + for (dp = usetxt; *dp; dp++) + fprintf(stderr, "%s\n", *dp); + asexit(n); +} diff --git a/src/as-z80/asout.c b/src/as-z80/asout.c new file mode 100755 index 00000000..684b76f4 --- /dev/null +++ b/src/as-z80/asout.c @@ -0,0 +1,1440 @@ +/* asout.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With enhancements from + * + * John L. Hartman (JLH) + * jhartman@compuserve.com + * + * Bill McKinnon (BM) + * w_mckinnon@conknet.com + */ + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "asxxxx.h" + + +/*)Module asout.c + * + * The module asout.c contains all the functions used to + * generate the .REL assembler output file. + * + * + * The assemblers' output object file is an ascii file containing + * the information needed by the linker to bind multiple object + * modules into a complete loadable memory image. + * + * The object module contains the following designators: + * + * [XDQ][HL][234] + * X Hexadecimal radix + * D Decimal radix + * Q Octal radix + * + * H Most significant byte first + * L Least significant byte first + * + * 2 16-Bit Relocatable Addresses/Data + * 3 24-Bit Relocatable Addresses/Data + * 4 32-Bit Relocatable Addresses/Data + * + * H Header + * M Module + * A Area + * S Symbol + * T Object code + * R Relocation information + * P Paging information + * + * + * (1) Radix Line + * + * The first line of an object module contains the [XDQ][HL][234] + * format specifier (i.e. XH2 indicates a hexadecimal file with + * most significant byte first and 16-bit addresses) for the + * following designators. + * + * + * (2) Header Line + * + * H aa areas gg global symbols + * + * The header line specifies the number of areas(aa) and the + * number of global symbols(gg) defined or referenced in this ob- + * ject module segment. + * + * + * (3) Module Line + * + * M name + * + * The module line specifies the module name from which this + * header segment was assembled. The module line will not appear + * if the .module directive was not used in the source program. + * + * + * (4) Symbol Line + * + * S string Defnnnn + * + * or + * + * S string Refnnnn + * + * The symbol line defines (Def) or references (Ref) the symbol + * 'string' with the value nnnn. The defined value is relative to + * the current area base address. References to constants and ex- + * ternal global symbols will always appear before the first area + * definition. References to external symbols will have a value of + * zero. + * + * + * (5) Area Line + * + * A label size ss flags ff + * + * The area line defines the area label, the size (ss) of the + * area in bytes, and the area flags (ff). The area flags specify + * the ABS, REL, CON, OVR, and PAG parameters: + * + * OVR/CON (0x04/0x00 i.e. bit position 2) + * + * ABS/REL (0x08/0x00 i.e. bit position 3) + * + * PAG (0x10 i.e. bit position 4) + * + * + * (6) T Line + * + * T xx xx nn nn nn nn nn ... + * + * The T line contains the assembled code output by the assem- + * bler with xx xx being the offset address from the current area + * base address and nn being the assembled instructions and data in + * byte format. + * + * + * (7) R Line + * + * R 0 0 nn nn n1 n2 xx xx ... + * + * The R line provides the relocation information to the linker. + * The nn nn value is the current area index, i.e. which area the + * current values were assembled. Relocation information is en- + * coded in groups of 4 bytes: + * + * 1. n1 is the relocation mode and object format + * 1. bit 0 word(0x00)/byte(0x01) + * 2. bit 1 relocatable area(0x00)/symbol(0x02) + * 3. bit 2 normal(0x00)/PC relative(0x04) relocation + * 4. bit 3 1-byte(0x00)/n-byte(0x08) byte format + * 5. bit 4 signed(0x00)/unsigned(0x10) byte data + * 6. bit 5 normal(0x00)/page '0'(0x20) reference + * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference + * 8. bit 7 normal(0x00)/MSB of value + * + * 2. n2 is a byte index into the corresponding (i.e. pre- + * ceeding) T line data (i.e. a pointer to the data to be + * updated by the relocation). The T line data may be + * 1-byte or 2-byte byte data format or 2-byte word + * format. + * + * 3. xx xx is the area/symbol index for the area/symbol be- + * ing referenced. the corresponding area/symbol is found + * in the header area/symbol lists. + * + * + * The groups of 4 bytes are repeated for each item requiring relo- + * cation in the preceeding T line. + * + * + * (8) P Line + * + * P 0 0 nn nn n1 n2 xx xx + * + * The P line provides the paging information to the linker as + * specified by a .setdp directive. The format of the relocation + * information is identical to that of the R line. The correspond- + * ing T line has the following information: + * T xx xx aa aa bb bb + * + * Where aa aa is the area reference number which specifies the + * selected page area and bb bb is the base address of the page. + * bb bb will require relocation processing if the 'n1 n2 xx xx' is + * specified in the P line. The linker will verify that the base + * address is on a 256 byte boundary and that the page length of an + * area defined with the PAG type is not larger than 256 bytes. + * + * The linker defaults any direct page references to the first + * area defined in the input REL file. All ASxxxx assemblers will + * specify the _CODE area first, making this the default page area. + * + * + * asout.c contains the following functions: + * int lobyte(); + * int hibyte(); + * int thrdbyte(); + * int frthbyte(); + * VOID out(); + * VOID outarea(); + * VOID outdp(); + * VOID outall(); + * VOID outdot(); + * VOID outbuf(); + * VOID outchk(); + * VOID outgsd(); + * VOID outsym(); + * VOID outab(); + * VOID outaw(); + * VOID outa3b(); + * VOID outa4b(); + * VOID outaxb(); + * VOID outatxb(); + * VOID outrb(); + * VOID outrw(); + * VOID outr3b(); + * VOID outr4b(); + * VOID outrxb(); + * VOID outr11(); JLH + * VOID out_lb(); + * VOID out_lw(); + * VOID out_l3b(); + * VOID out_l4b(); + * VOID out_lxb(); + * VOID out_rw(); + * VOID out_txb(); + * + * The module asout.c contains the following local variables: + * int rel[] relocation data for code/data array + * int * relp pointer to rel array + * int txt[] assembled code/data array + * int * txtp pointer to txt array + */ + +#define NTXT 16 +#define NREL 16 + +char txt[NTXT]; +char rel[NREL]; + +char *txtp = &txt[0]; +char *relp = &rel[0]; + +/*)Function VOID outab(v) + *)Function VOID outaw(v) + *)Function VOID outa3b(v) + *)Function VOID outa4b(v) + * + * int v assembler data + * + * Dispatch to output routine of 1 to 4 absolute bytes. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * VOID outatxb() asout.c + * + * side effects: + * Absolute data is processed. + */ + +VOID +outab(v) +int v; +{ + outaxb(1, v); +} + +VOID +outaw(v) +int v; +{ + outaxb(2, v); +} + +VOID +outa3b(v) +int v; +{ + outaxb(3, v); +} + +VOID +outa4b(v) +int v; +{ + outaxb(4, v); +} + +/*)Function VOID outaxb(i, v) + * + * int i output byte count + * int v assembler data + * + * The function outaxb() processes 1 to 4 bytes of + * assembled data in absolute format. + * + * local variables: + * none + * + * global variables: + * sym dot defined as sym[0] + * int oflag -o, generate relocatable output flag + * int pass assembler pass number + * + * functions called: + * VOID outatxb() asout.c + * VOID outchk() asout.c + * VOID out_lxb() asout.c + * + * side effects: + * The current assembly address is incremented by i. + */ + +VOID +outaxb(i, v) +int i; +int v; +{ + if (pass == 2) { + out_lxb(i, v, 0); + if (oflag) { + outchk(i, 0); + outatxb(i, v); + } + } + dot.s_addr += i; +} + +/*)Function VOID outatxb(i, v) + * + * int i number of bytes to process + * int v assembler data + * + * The function outatxb() outputs i bytes + * + * local variables: + * none + * + * global variables: + * int hilo byte order + * char *txtp T line output pointer + * + * functions called: + * int lobyte() asout.c + * int hibyte() asout.c + * int thrdbyte() asout.c + * int frthbyte() asout.c + * + * side effects: + * i bytes are placed into the T Line Buffer. + */ + +VOID +outatxb(i, v) +int i; +int v; +{ + if (hilo) { + if (i >= 4) *txtp++ = frthbyte(v); + if (i >= 3) *txtp++ = thrdbyte(v); + if (i >= 2) *txtp++ = hibyte(v); + if (i >= 1) *txtp++ = lobyte(v); + } else { + if (i >= 1) *txtp++ = lobyte(v); + if (i >= 2) *txtp++ = hibyte(v); + if (i >= 3) *txtp++ = thrdbyte(v); + if (i >= 4) *txtp++ = frthbyte(v); + } +} + +/*)Function VOID outrb(esp, r) + *)Function VOID outrw(esp, r) + *)Function VOID outr3b(esp, r) + *)Function VOID outr4b(esp, r) + * + * expr * esp pointer to expr structure + * int r relocation mode + * + * Dispatch functions for processing relocatable data. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * int outrxb() asout.c + * + * side effects: + * relocatable data processed + */ + +VOID +outrb(esp, r) +register struct expr *esp; +int r; +{ + outrxb(1, esp, r); +} + +VOID +outrw(esp, r) +register struct expr *esp; +int r; +{ + outrxb(2, esp, r); +} + +VOID +outr3b(esp, r) +register struct expr *esp; +int r; +{ + outrxb(3, esp, r); +} + +VOID +outr4b(esp, r) +register struct expr *esp; +int r; +{ + outrxb(4, esp, r); +} + +/*)Function VOID outrxb(i, esp, r) + * + * int i output byte count + * expr * esp pointer to expr structure + * int r relocation mode + * + * The function outrxb() processes 1 to 4 bytes of generated code + * in either absolute or relocatable format dependent upon + * the data contained in the expr structure esp. If the + * .REL output is enabled then the appropriate information + * is loaded into the txt and rel buffers. + * + * local variables: + * int n symbol/area reference number + * + * global variables: + * int a_bytes T Line byte count + * sym dot defined as sym[0] + * int oflag -o, generate relocatable output flag + * int pass assembler pass number + * int * relp pointer to rel array + * + * functions called: + * int hibyte() asout.c + * int lobyte() asout.c + * VOID outatxb() asout.c + * VOID outchk() asout.c + * VOID out_lb() asout.c + * VOID out_lw() asout.c + * VOID out_lxb() asout.c + * VOID out_rw() asout.c + * VOID out_txb() asout.c + * + * side effects: + * R and T Lines updated. Listing updated. + * The current assembly address is incremented by i. + */ + +VOID +outrxb(i, esp, r) +int i; +register struct expr *esp; +int r; +{ + register int n; + + if (pass == 2) { + if (esp->e_flag==0 && esp->e_base.e_ap==NULL) { + out_lxb(i,esp->e_addr,0); + if (oflag) { + outchk(i,0); + outatxb(i,esp->e_addr); + } + } else { + if (i == 1) { + r |= R_BYTE | R_BYTX | esp->e_rlcf; +#ifdef R_BYTE4 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + if (r & R_BYTE4) + { + out_lb(frthbyte(esp->e_addr),r|R_RELOC|R_BYT3); + } + else +#endif +#ifdef R_ /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + if (r & R_BYTE3) + { + out_lb(thrdbyte(esp->e_addr),r|R_RELOC|R_BYT4); + } + else +#endif + if (r & R_MSB) { + out_lb(hibyte(esp->e_addr),r|R_RELOC|R_HIGH); + } else { + out_lb(lobyte(esp->e_addr),r|R_RELOC); + } + } else { + switch(i) { + default: + case 2: r |= R_WORD; break; + case 3: r |= R_3BYTE; break; + case 4: r |= R_4BYTE; break; + } + r |= esp->e_rlcf; + out_lxb(i,esp->e_addr,r|R_RELOC); + } + if (oflag) { + outchk(a_bytes,4); + out_txb(a_bytes,esp->e_addr); + if (esp->e_flag) { + n = esp->e_base.e_sp->s_ref; + r |= R_SYM; + } else { + n = esp->e_base.e_ap->a_ref; + } + *relp++ = r; + *relp++ = txtp - txt - a_bytes; + out_rw(n); + } + } + } + dot.s_addr += i; +} + +/*)Function VOID outdp(carea, esp) + * + * area * carea pointer to current area strcuture + * expr * esp pointer to expr structure + * + * The function outdp() flushes the output buffer and + * outputs paging information to the .REL file. + * + * local variables: + * int n symbol/area reference number + * int r relocation mode + * int * relp pointer to rel array + * int * txtp pointer to txt array + * + * global variables: + * int a_bytes T Line byte count + * int oflag -o, generate relocatable output flag + * int pass assembler pass number + * + * functions called: + * VOID outbuf() asout.c + * VOID outchk() asout.c + * VOID out_rw() asout.c + * VOID out_txb() asout.c + * + * side effects: + * Output buffer flushed to .REL fiel. + * Paging information dumped to .REL file. + */ + +VOID +outdp(carea, esp) +register struct area *carea; +register struct expr *esp; +{ + register int n, r; + + if (oflag && pass==2) { + outchk(HUGE,HUGE); + out_txb(a_bytes,carea->a_ref); + out_txb(a_bytes,esp->e_addr); + if (esp->e_flag || esp->e_base.e_ap!=NULL) { + r = R_WORD; + if (esp->e_flag) { + n = esp->e_base.e_sp->s_ref; + r |= R_SYM; + } else { + n = esp->e_base.e_ap->a_ref; + } + *relp++ = r; + *relp++ = txtp - txt - a_bytes; + out_rw(n); + } + outbuf("P"); + } +} + +/*)Function VOID outall() + * + * The function outall() will output any bufferred assembled + * data and relocation information (during pass 2 if the .REL + * output has been enabled). + * + * local variables: + * none + * + * global variables: + * int oflag -o, generate relocatable output flag + * int pass assembler pass number + * + * functions called: + * VOID outbuf() asout.c + * + * side effects: + * assembled data and relocation buffers will be cleared. + */ + +VOID +outall() +{ + if (oflag && pass==2) + outbuf("R"); +} + +/*)Function VOID outdot() + * + * The function outdot() outputs information about the + * current program counter value (during pass 2 if the .REL + * output has been enabled). + * + * local variables: + * none + * + * global variables: + * int oflag -o, generate relocatable output flag + * int pass assembler pass number + * + * functions called: + * int fprintf() c_library + * VOID out() asout.c + * + * side effects: + * assembled data and relocation buffers will be cleared. + */ + +VOID +outdot() +{ + if (oflag && pass==2) { + fprintf(ofp, "T"); + out(txt,(int) (txtp-txt)); + fprintf(ofp, "\n"); + fprintf(ofp, "R"); + out(rel,(int) (relp-rel)); + fprintf(ofp, "\n"); + txtp = txt; + relp = rel; + } +} + +/*)Function outchk(nt, nr) + * + * int nr number of additional relocation words + * int nt number of additional data words + * + * The function outchk() checks the data and relocation buffers + * for space to insert the nt data words and nr relocation words. + * If space is not available then output the current data and + * initialize the data buffers to receive the new data. + * + * local variables: + * area * ap pointer to an area structure + * int * relp pointer to rel array + * int * txtp pointer to txt array + * + * global variables: + * int a_bytes T Line byte count + * sym dot defined as sym[0] + * + * functions called: + * VOID outbuf() asout.c + * VOID out_rw() asout.c + * VOID out_txb() asout.c + * + * side effects: + * Data and relocation buffers may be emptied and initialized. + */ + +VOID +outchk(nt, nr) +int nt; +int nr; +{ + register struct area *ap; + + if (txtp+nt >= &txt[NTXT] || relp+nr >= &rel[NREL]) { + outbuf("R"); + } + if (txtp == txt) { + out_txb(a_bytes,dot.s_addr); + if ((ap = dot.s_area) != NULL) { + *relp++ = R_WORD|R_AREA; + *relp++ = 0; + out_rw(ap->a_ref); + } + } +} + +/*)Function VOID outbuf(s) + * + * char * s "R" or "P" or ("I" illegal) + * + * The function outbuf() will output any bufferred data + * and relocation information to the .REL file. The output + * buffer pointers and counters are initialized. + * + * local variables: + * int rel[] relocation data for code/data array + * int * relp pointer to rel array + * int txt[] assembled code/data array + * int * txtp pointer to txt array + * + * global variables: + * FILE * ofp relocation output file handle + * + * functions called: + * int fprintf() c_library + * VOID out() asout.c + * + * side effects: + * All bufferred data written to .REL file and + * buffer pointers and counters initialized. + */ + +VOID +outbuf(s) +char *s; +{ + if (txtp > &txt[a_bytes]) { + fprintf(ofp, "T"); + out(txt,(int) (txtp-txt)); + fprintf(ofp, "\n"); + fprintf(ofp, s); + out(rel,(int) (relp-rel)); + fprintf(ofp, "\n"); + } + txtp = txt; + relp = rel; +} + +/*)Function VOID outgsd() + * + * The function outgsd() performs the following: + * (1) outputs the .REL file radix + * (2) outputs the header specifying the number + * of areas and global symbols + * (3) outputs the module name + * (4) set the reference number and output a symbol line + * for all external global variables and absolutes + * (5) output an area name, set reference number and output + * a symbol line for all global relocatables in the area. + * Repeat this proceedure for all areas. + * + * local variables: + * area * ap pointer to an area structure + * sym * sp pointer to a sym structure + * int i loop counter + * int j loop counter + * int c string character value + * int narea number of code areas + * char * ptr string pointer + * int nglob number of global symbols + * int rn symbol reference number + * + * global variables: + * area * areap pointer to an area structure + * int hilo byte order + * char module[] module name string + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * int xflag -x, listing radix flag + * + * functions called: + * int fprintf() c_library + * VOID outarea() asout.c + * VOID outsym() asout.c + * + * side effects: + * All symbols are given reference numbers, all symbol + * and area information is output to the .REL file. + */ + +VOID +outgsd() +{ + register struct area *ap; + register struct sym *sp; + register int i, j; + char *ptr; + int narea, nglob, rn; + + /* + * Number of areas + */ + narea = areap->a_ref + 1; + + /* + * Number of global references/absolutes + */ + nglob = 0; + for (i = 0; i < NHASH; ++i) { + sp = symhash[i]; + while (sp) { + if (sp->s_flag&S_GBL) + ++nglob; + sp = sp->s_sp; + } + } + + /* + * Output Radix and number of areas and symbols + */ + if (xflag == 0) { + fprintf(ofp, "X%c%d\n", hilo ? 'H' : 'L', a_bytes); + fprintf(ofp, "H %X areas %X global symbols\n", narea, nglob); + } else + if (xflag == 1) { + fprintf(ofp, "Q%c%d\n", hilo ? 'H' : 'L', a_bytes); + fprintf(ofp, "H %o areas %o global symbols\n", narea, nglob); + } else + if (xflag == 2) { + fprintf(ofp, "D%c%d\n", hilo ? 'H' : 'L', a_bytes); + fprintf(ofp, "H %u areas %u global symbols\n", narea, nglob); + } + + /* + * Module name + */ + if (module[0]) { + fprintf(ofp, "M "); + ptr = &module[0]; + fprintf(ofp, "%s\n", ptr); + } + + /* + * Global references and absolutes. + */ + rn = 0; + for (i=0; is_area==NULL && sp->s_flag&S_GBL) { + sp->s_ref = rn++; + outsym(sp); + } + sp = sp->s_sp; + } + } + + /* + * Global relocatables. + */ + for (i=0; ia_ref != i) + ap = ap->a_ap; + outarea(ap); + for (j=0; js_area==ap && sp->s_flag&S_GBL) { + sp->s_ref = rn++; + outsym(sp); + } + sp = sp->s_sp; + } + } + } +} + +/*)Function VOID outarea(ap) + * + * area * ap pointer to an area structure + * + * The function outarea() outputs the A line to the .REL + * file. The A line contains the area's name, size, and + * attributes. + * + * local variables: + * char * ptr pointer to area id string + * + * global variables: + * FILE * ofp relocation output file handle + * int xflag -x, listing radix flag + * + * functions called: + * int fprintf() c_library + * + * side effects: + * The A line is sent to the .REL file. + */ + +VOID +outarea(ap) +register struct area *ap; +{ + register char *ptr; + + fprintf(ofp, "A "); + ptr = &ap->a_id[0]; + fprintf(ofp, "%s", ptr); + if (xflag == 0) { + fprintf(ofp, " size %X flags %X\n", ap->a_size, ap->a_flag); + } else + if (xflag == 1) { + fprintf(ofp, " size %o flags %o\n", ap->a_size, ap->a_flag); + } else + if (xflag == 2) { + fprintf(ofp, " size %u flags %u\n", ap->a_size, ap->a_flag); + } +} + +/*)Function VOID outsym(sp) + * + * sym * sp pointer to a sym structure + * + * The function outsym() outputs the S line to the .REL + * file. The S line contains the symbols name and whether the + * the symbol is defined or referenced. + * + * local variables: + * char * ptr pointer to symbol id string + * int s_addr (int) truncated to 2-bytes + * + * global variables: + * int a_bytes argument size in bytes + * FILE * ofp relocation output file handle + * int xflag -x, listing radix flag + * + * functions called: + * int fprintf() c_library + * + * side effects: + * The S line is sent to the .REL file. + */ + +VOID +outsym(sp) +register struct sym *sp; +{ + register char *frmt, *ptr; + register int s_addr; + + /* + * Truncate (int) to N-Bytes + */ + s_addr = sp->s_addr & a_mask; + + fprintf(ofp, "S "); + ptr = &sp->s_id[0]; /* JLH */ + fprintf(ofp, "%s", ptr); + fprintf(ofp, " %s", sp->s_type==S_NEW ? "Ref" : "Def"); + switch(xflag) { + default: + case 0: + switch(a_bytes) { + default: + case 2: frmt = "%04X\n"; break; + case 3: frmt = "%06X\n"; break; + case 4: frmt = "%08X\n"; break; + } + break; + + case 1: + switch(a_bytes) { + default: + case 2: frmt = "%06o\n"; break; + case 3: frmt = "%08o\n"; break; + case 4: frmt = "%011o\n"; break; + } + break; + + case 2: + switch(a_bytes) { + default: + case 2: frmt = "%05u\n"; break; + case 3: frmt = "%08u\n"; break; + case 4: frmt = "%010u\n"; break; + } + break; + } + fprintf(ofp, frmt, s_addr); +} + +/*)Function VOID out(p, n) + * + * int n number of words to output + * int * p pointer to data words + * + * The function out() outputs the data words to the .REL file + * int the specified radix. + * + * local variables: + * none + * + * global variables: + * FILE * ofp relocation output file handle + * int xflag -x, listing radix flag + * + * functions called: + * int fprintf() c_library + * + * side effects: + * Data is sent to the .REL file. + */ + +VOID +out(p, n) +register char *p; +register int n; +{ + while (n--) { + if (xflag == 0) { + fprintf(ofp, " %02X", (*p++)&0377); + } else + if (xflag == 1) { + fprintf(ofp, " %03o", (*p++)&0377); + } else + if (xflag == 2) { + fprintf(ofp, " %03u", (*p++)&0377); + } + } +} + +/*)Function VOID out_lb(v, t) + * + * int v assembled data + * int t relocation type + * + * The function out_lb() copies the assembled data and + * its relocation type to the list data buffers. + * + * local variables: + * none + * + * global variables: + * int * cp pointer to assembler output array cb[] + * int * cpt pointer to assembler relocation type + * output array cbt[] + * + * functions called: + * none + * + * side effects: + * Pointers to data and relocation buffers incremented by 1. + */ + +VOID +out_lb(v, t) +register int v, t; +{ + if (cp < &cb[NCODE]) { + *cp++ = v; + *cpt++ = t; + } +} + +/*)Function VOID out_lw(v, t) + *)Function VOID out_l3b(v, t) + *)Function VOID out_l4b(v, t) + * + * int v assembled data + * int t relocation type + * + * Dispatch functions for processing listing data. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * none + * + * side effects: + * Listing data processed. + */ + +VOID +out_lw(v, t) +register int v, t; +{ + out_lxb(2, v, t); +} + +VOID +out_l3b(v, t) +register int v, t; +{ + out_lxb(3, v, t); +} + +VOID +out_l4b(v, t) +register int v, t; +{ + out_lxb(4, v, t); +} + +/*)Function VOID out_lxb(i, v, t) + * + * int i output byte count + * int v assembled data + * int t relocation type + * + * Dispatch function for list processing. + * + * local variables: + * none + * + * global variables: + * int hilo byte order + * + * functions called: + * VOID out_lb() asout.c + * VOID out_lw() asout.c + * + * side effects: + * i list bytes are processed. + */ + +VOID +out_lxb(i, v, t) +register int i, v, t; +{ + if (hilo) { + if (i >= 4) out_lb(frthbyte(v),t&R_RELOC ? t|R_BYT4 : 0); + if (i >= 3) out_lb(thrdbyte(v),t&R_RELOC ? t|R_BYT3 : 0); + if (i >= 2) out_lb(hibyte(v),t&R_RELOC ? t|R_HIGH : 0); + if (i >= 1) out_lb(lobyte(v),t); + } else { + if (i >= 1) out_lb(lobyte(v),t); + if (i >= 2) out_lb(hibyte(v),t&R_RELOC ? t|R_HIGH : 0); + if (i >= 3) out_lb(thrdbyte(v),t&R_RELOC ? t|R_BYT3 : 0); + if (i >= 4) out_lb(frthbyte(v),t&R_RELOC ? t|R_BYT4 : 0); + } +} + +/*)Function VOID out_rw(v) + * + * int v assembled data + * + * The function out_rw() outputs the relocation (R) + * data word as two bytes ordered according to hilo. + * + * local variables: + * int * relp pointer to rel array + * + * global variables: + * int hilo byte order + * + * functions called: + * int lobyte() asout.c + * int hibyte() asout.c + * + * side effects: + * Pointer to relocation buffer incremented by 2. + */ + +VOID +out_rw(v) +register int v; +{ + if (hilo) { + *relp++ = hibyte(v); + *relp++ = lobyte(v); + } else { + *relp++ = lobyte(v); + *relp++ = hibyte(v); + } +} + +/*)Function VOID out_txb(i, v) + * + * int i T Line byte count + * int v data word + * + * The function out_txb() outputs the text (T) + * as a_bytes bytes ordered according to hilo. + * + * local variables: + * int * txtp pointer to txt array + * + * global variables: + * int hilo byte order + * + * functions called: + * int lobyte() asout.c + * int hibyte() asout.c + * int thrdbyte() asout.c + * int frthbyte() asout.c + * + * side effects: + * T Line buffer updated. + */ + +VOID +out_txb(i, v) +register int i, v; +{ + if (hilo) { + if (i >= 4) *txtp++ = frthbyte(v); + if (i >= 3) *txtp++ = thrdbyte(v); + if (i >= 2) *txtp++ = hibyte(v); + if (i >= 1) *txtp++ = lobyte(v); + } else { + if (i >= 1) *txtp++ = lobyte(v); + if (i >= 2) *txtp++ = hibyte(v); + if (i >= 3) *txtp++ = thrdbyte(v); + if (i >= 4) *txtp++ = frthbyte(v); + } +} + +/*)Function int lobyte(v) + *)Function int hibyte(v) + *)Function int thrdbyte(v) + *)Function int frthbyte(v) + * + * int v assembled data + * + * These functions return the 1st, 2nd, 3rd, or 4th byte + * of integer v. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * none + * + * side effects: + * none + */ + +int +lobyte(v) +int v; +{ + return (v&0377); +} + +int +hibyte(v) +int v; +{ + return ((v>>8)&0377); +} + +int +thrdbyte(v) +int v; +{ + return ((v>>16)&0377); +} + +int +frthbyte(v) +int v; +{ + return ((v>>24)&0377); +} + +/*)Function VOID outr11(esp, op) + * + * expr * esp pointer to expr structure + * int op opcode + * + * The function outr11() processes a word of generated code + * in either absolute or relocatable format dependent upon + * the data contained in the expr structure esp. If the + * .REL output is enabled then the appropriate information + * is loaded into the txt and rel buffers. The code is output + * in a special format to the linker to allow relocation and + * merging of the opcode and an 11 bit paged address as required + * by the 8051 architecture. + * + * This function based on code by + * + * John L. Hartman + * jhartman@compuserve.com + * + * local variables: + * int n symbol/area reference number + * int r relocation mode + * + * global variables: + * sym dot defined as sym[0] + * int oflag -o, generate relocatable output flag + * int pass assembler pass number + * int * relp pointer to rel array + * int * txtp pointer to txt array + * + * functions called: + * VOID outchk() asout.c + * VOID out_rw() asout.c + * VOID out_txb() asout.c + * + * side effects: + * The current assembly address is incremented by 2. + */ + +VOID +outr11(esp, op) +register struct expr *esp; +int op; +{ + register int n, r; + + if (pass == 2) { + if (esp->e_flag==0 && esp->e_base.e_ap==NULL) { + /* + * Absolute Destination + * + * Use the global symbol '.__.ABS.' + * of value zero and force the assembler + * to use this absolute constant as the + * base value for the relocation. + */ + esp->e_flag = 1; + esp->e_base.e_sp = &sym[1]; + } + /* + * Relocatable Destination. Build THREE + * byte output: relocatable word, followed + * by op-code. Linker will combine them. + */ + r = R_J11 | esp->e_rlcf; + n = ((esp->e_addr & 0x0700) >> 3) | (op & 0x1F); + n = (n << 8) | (esp->e_addr & 0xFF); + out_lxb(2,n,r|R_RELOC); + if (oflag) { + outchk(a_bytes+1, 4); + out_txb(a_bytes,esp->e_addr); + *txtp++ = op; + + if (esp->e_flag) { + n = esp->e_base.e_sp->s_ref; + r |= R_SYM; + } else { + n = esp->e_base.e_ap->a_ref; + } + *relp++ = r; + *relp++ = txtp - txt - (a_bytes + 1); + out_rw(n); + } + } + dot.s_addr += 2; +} + +/*)Function VOID outr19(esp, op) + * + * expr * esp pointer to expr structure + * int op opcode + * + * The function outr19() processes 3 bytes of generated code + * in either absolute or relocatable format dependent upon + * the data contained in the expr structure esp. If the + * .REL output is enabled then the appropriate information + * is loaded into the txt and rel buffers. The code is output + * in a special format to the linker to allow relocation and + * merging of the opcode and a 19 bit paged address as required + * by the DS80C390 architecture. + * + * This function based on code by + * + * Bill McKinnon (BM) + * w_mckinnon@conknet.com + * + * John L. Hartman + * jhartman@compuserve.com + * + * local variables: + * int n symbol/area reference number + * int r relocation mode + * + * global variables: + * sym dot defined as sym[0] + * int oflag -o, generate relocatable output flag + * int pass assembler pass number + * int * relp pointer to rel array + * int * txtp pointer to txt array + * + * functions called: + * VOID outchk() asout.c + * VOID out_rw() asout.c + * VOID out_txb() asout.c + * + * side effects: + * The current assembly address is incremented by 3. + */ + +VOID +outr19(esp, op) +register struct expr *esp; +int op; +{ + register int n, r; + + if (pass == 2) { + if (esp->e_flag==0 && esp->e_base.e_ap==NULL) { + /* + * Absolute Destination + * + * Use the global symbol '.__.ABS.' + * of value zero and force the assembler + * to use this absolute constant as the + * base value for the relocation. + */ + esp->e_flag = 1; + esp->e_base.e_sp = &sym[1]; + } + /* + * Relocatable Destination. Build THREE + * byte output: relocatable word, followed + * by op-code. Linker will combine them. + */ + r = R_J19 | esp->e_rlcf; + n = ((esp->e_addr & 0x070000) >> 11) | (op & 0x1F); + n = (n << 16) | (esp->e_addr & 0xFFFF); + out_lxb(3,n,r|R_RELOC); + if (oflag) { + outchk(a_bytes+1, 4); + out_txb(a_bytes,esp->e_addr); + *txtp++ = op; + + if (esp->e_flag) { + n = esp->e_base.e_sp->s_ref; + r |= R_SYM; + } else { + n = esp->e_base.e_ap->a_ref; + } + *relp++ = r; + *relp++ = txtp - txt - (a_bytes + 1); + out_rw(n); + } + } + dot.s_addr += 3; +} + diff --git a/src/as-z80/assubr.c b/src/as-z80/assubr.c new file mode 100755 index 00000000..f8ef428e --- /dev/null +++ b/src/as-z80/assubr.c @@ -0,0 +1,241 @@ +/* assubr.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "asxxxx.h" + +/*)Module assubr.c + * + * The module assubr.c contains the error + * processing routines. + * + * assubr.c contains the following functions: + * VOID aerr() + * VOID diag() + * VOID err() + * VOID qerr() + * VOID rerr() + * char * geterr() + * + * assubr.c contains the local array of *error[] + */ + +/*)Function VOID err(c) + * + * int c error type character + * + * The function err() logs the error code character + * suppressing duplicate errors. If the error code + * is 'q' then the parse of the current assembler-source + * text line is terminated. + * + * local variables: + * char * p pointer to the error array + * + * global variables: + * int aserr error counter + * char eb[] array of generated error codes + * + * functions called: + * VOID longjmp() c_library + * + * side effects: + * The error code may be inserted into the + * error code array eb[] or the parse terminated. + */ + +VOID +err(c) +register int c; +{ + register char *p; + + aserr++; + p = eb; + while (p < ep) + if (*p++ == c) + return; + if (p < &eb[NERR]) { + *p++ = c; + ep = p; + } + if (c == 'q') + longjmp(jump_env, -1); +} + +/*)Function VOID diag() + * + * The function diag() prints any error codes and + * the source line number to the stderr output device. + * + * local variables: + * char * p pointer to error code array eb[] + * + * global variables: + * int cfile current source file index + * char eb[] array of generated error codes + * char * ep pointer into error list + * int incfile current include file index + * char incfn[] array of include file names + * int incline[] array of include line numbers + * char srcfn[] array of source file names + * int srcline[] array of source line numbers + * FILE * stderr c_library + * + * functions called: + * int fprintf() c_library + * char * geterr() assubr.c + * + * side effects: + * none + */ + +VOID +diag() +{ + register char *p,*errstr; + + if (eb != ep) { + p = eb; + fprintf(stderr, "?ASxxxx-Error-<"); + while (p < ep) { + fprintf(stderr, "%c", *p++); + } + fprintf(stderr, "> in line "); + if (incfil >= 0) { + fprintf(stderr, "%d", incline[incfil]); + fprintf(stderr, " of %s\n", incfn[incfil]); + } else { + fprintf(stderr, "%d", srcline[cfile]); + fprintf(stderr, " of %s\n", srcfn[cfile]); + } + p = eb; + while (p < ep) { + if ((errstr = geterr(*p++)) != NULL) { + fprintf(stderr, " %s\n", errstr); + } + } + } +} + +/*)Functions: VOID aerr() + * VOID qerr() + * VOID rerr() + * + * The functions aerr(), qerr(), and rerr() report their + * respective error type. These are included only for + * convenience. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * VOID err() assubr.c + * + * side effects: + * The appropriate error code is inserted into the + * error array and the parse may be terminated. + */ + +/* + * Note an 'r' error. + */ +VOID +rerr() +{ + err('r'); +} + +/* + * Note an 'a' error. + */ +VOID +aerr() +{ + err('a'); +} + +/* + * Note a 'q' error. + */ +VOID +qerr() +{ + err('q'); +} + +/* + * ASxxxx assembler errors + */ +char *errors[] = { + "<.> use \". = . + \" not \". = \"", + " machine specific addressing or addressing mode error", + " direct page boundary error", + " direct page addressing error", + " .include file error or an .if/.endif mismatch", + " multiple definitions error", + " .org in REL area or directive / mnemonic error", + "

phase error: label location changing between passes 2 and 3", + " missing or improper operators, terminators, or delimiters", + " relocation error", + " undefined symbol encountered during assembly", + " divide by zero or mod of zero error", + NULL +}; + +/*)Function: char *geterr(c) + * + * int c the error code character + * + * The function geterr() scans the list of errors returning the + * error string corresponding to the input error character. + * + * local variables: + * int i error index counter + * + * global variables: + * char *errors[] array of pointers to the + * error strings + * + * functions called: + * none + * + * side effects: + * A pointer to the appropriate + * error code string is returned. + */ +char * +geterr(c) +int c; +{ + int i; + + for (i=0; errors[i]!=NULL; i++) { + if (c == errors[i][1]) { + return(errors[i]); + } + } + sprintf(erb, " %.*s", (int) (sizeof(erb)-5), ib); + return(erb); +} + diff --git a/src/as-z80/assym.c b/src/as-z80/assym.c new file mode 100755 index 00000000..3ebec5a6 --- /dev/null +++ b/src/as-z80/assym.c @@ -0,0 +1,610 @@ +/* assym.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With enhancements from + * + * John L. Hartman (JLH) + * jhartman@compuserve.com + */ + +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "asxxxx.h" + +/*)Module assym.c + * + * The module assym.c contains the functions that operate + * on the mnemonic/directive and symbol structures. + * + * assym.c contains the following functions: + * VOID allglob() + * area * alookup() + * int hash() + * sym * lookup() + * mne * mlookup() + * VOID * new() + * sym * slookup() + * char * strsto() + * int symeq() + * VOID syminit() + * VOID symglob() + * + * assym.c contains the static variables: + * char * pnext + * int bytes + * used by the string store function. + */ + +/*)Function VOID syminit() + * + * The function syminit() is called early in the game + * to set up the hashtables. First all buckets in a + * table are cleared. Then a pass is made through + * the respective symbol lists, linking them into + * their hash buckets. Finally the base area pointer + * is set to 'dca'. + * + * local variables: + * int h computed hash value + * mne * mp pointer to a mne structure + * mne ** mpp pointer to an array of + * mne structure pointers + * sym * sp pointer to a sym structure + * sym ** spp pointer to an array of + * sym structure pointers + * + * global variables: + * area area[] single elememt area array + * area dca defined as area[0] + * mne * mnehash[] array of pointers to NHASH + * linked mnemonic/directive lists + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * + * functions called: + * none + * + * side effects: + * (1) The symbol hash tables are initialized, + * the predefined symbols are '.' and '.__.ABS.'. + * (2) The mnemonic/directive hash tables are + * initialized with the assembler directives + * and mnemonics found in the machine dependent + * file ___pst.c. + * (3) The area pointer is initialized to dca (area[0]). + */ + +VOID +syminit() +{ + register struct mne *mp; + struct mne **mpp; + register struct sym *sp; + struct sym **spp; + register int h; + + mpp = &mnehash[0]; + while (mpp < &mnehash[NHASH]) + *mpp++ = NULL; + mp = &mne[0]; + for (;;) { + h = hash(mp->m_id, 0); + mp->m_mp = mnehash[h]; + mnehash[h] = mp; +#if 1 /* Nick */ + if (mp->m_flag&S_ENDPST) +#else + if (mp->m_flag&S_END) +#endif + break; + ++mp; + } + + spp = &symhash[0]; + while (spp < &symhash[NHASH]) + *spp++ = NULL; + sp = &sym[0]; + for (;;) { + h = hash(sp->s_id, zflag); + sp->s_sp = symhash[h]; + symhash[h] = sp; +#if 1 /* Nick */ + if (sp->s_flag&S_ENDPST) +#else + if (sp->s_flag&S_END) +#endif + break; + ++sp; + } + + areap = &dca; +} + +/*)Function area * alookup(id) + * + * char * id area name string + * + * The function alookup() searches the area list for a + * match with id. If the area is defined then a pointer + * to this area is returned else a NULL is returned. + * + * local variables: + * area * ap pointer to area structure + * + * global variables: + * area * areap pointer to an area structure + * + * functions called: + * int symeq() assym.c + * + * side effects: + * none + */ + +struct area * +alookup(id) +char *id; +{ + register struct area *ap; + + ap = areap; + while (ap) { + /* + * JLH: case insensitive lookup always + */ + if(symeq(id, ap->a_id, 0)) + return (ap); + ap = ap->a_ap; + } + return(NULL); +} + +/*)Function mne * mlookup(id) + * + * char * id mnemonic/directive name string + * + * The function mlookup() searches the mnemonic/directive + * hash tables for a match returning a pointer to the + * mne structure else it returns a NULL. + * + * local variables: + * mne * mp pointer to mne structure + * int h calculated hash value + * + * global variables: + * mne * mnehash[] array of pointers to NHASH + * linked mnemonic/directive lists + * + * functions called: + * none + * + * side effects: + * none + */ + +struct mne * +mlookup(id) +char *id; +{ + register struct mne *mp; + register int h; + + /* + * JLH: case insensitive lookup always + */ + h = hash(id, 0); + mp = mnehash[h]; + while (mp) { + if(symeq(id, mp->m_id, 0)) + return (mp); + mp = mp->m_mp; + } + return (NULL); +} + +/*)Function sym * slookup(id) + * + * char * id symbol name string + * + * The function lookup() searches the symbol hash tables for + * a symbol name match returning a pointer to the sym structure + * eles it returns a NULL. + * + * local variables: + * int h computed hash value + * sym * sp pointer to a sym structure + * + * global varaibles: + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * int zflag enable symbol case sensitivity + * + * functions called: + * int hash() assym.c + * int symeq() assym.c + * + * side effects: + * none + */ + +struct sym * +slookup(id) +char *id; +{ + register struct sym *sp; + register int h; + + h = hash(id, zflag); + sp = symhash[h]; + while (sp) { + if(symeq(id, sp->s_id, zflag)) + return (sp); + sp = sp->s_sp; + } + return (NULL); +} + +/*)Function sym * lookup(id) + * + * char * id symbol name string + * + * The function lookup() searches the symbol hash tables for + * a symbol name match returning a pointer to the sym structure. + * If the symbol is not found then a sym structure is created, + * initialized, and linked to the appropriate hash table. + * A pointer to this new sym structure is returned. + * + * local variables: + * int h computed hash value + * sym * sp pointer to a sym structure + * + * global varaibles: + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * int zflag enable symbol case sensitivity + * + * functions called: + * int hash() assym.c + * VOID * new() assym.c + * char * strsto() assym.c + * int symeq() assym.c + * + * side effects: + * If the function new() fails to allocate space + * for the new sym structure the assembly terminates. + */ + +struct sym * +lookup(id) +char *id; +{ + register struct sym *sp; + register int h; + +#if 1 /* Nick has modified this to make $ a synonym for . */ + if (!strcmp(id, "$")) { + return ˙ + } +#endif + h = hash(id, zflag); + sp = symhash[h]; + while (sp) { + if(symeq(id, sp->s_id, zflag)) + return (sp); + sp = sp->s_sp; + } + sp = (struct sym *) new (sizeof(struct sym)); + sp->s_sp = symhash[h]; + symhash[h] = sp; + sp->s_tsym = NULL; + sp->s_id = strsto(id); + sp->s_type = S_NEW; + sp->s_flag = 0; + sp->s_area = NULL; + sp->s_ref = 0; + sp->s_addr = 0; + return (sp); +} + +/*)Function VOID symglob() + * + * The function symglob() will mark all symbols of + * type S_NEW as global. Called at the beginning of pass 1 + * if the assembly option -g was specified. + * + * local variables: + * sym * sp pointer to a sym structure + * int i loop index + * + * global variables: + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * + * functions called: + * none + * + * side effects: + * Symbol types changed. + */ + +VOID +symglob() +{ + register struct sym *sp; + register int i; + + for (i=0; is_type == S_NEW) + sp->s_flag |= S_GBL; + sp = sp->s_sp; + } + } +} + +/*)Function VOID allglob() + * + * The function allglob() will mark all symbols of + * type S_USER as global. Called at the beginning of pass 1 + * if the assembly option -a was specified. + * + * local variables: + * sym * sp pointer to a sym structure + * int i loop index + * + * global variables: + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * + * functions called: + * none + * + * side effects: + * Symbol types changed. + */ + +VOID +allglob() +{ + register struct sym *sp; + register int i; + + for (i=0; is_type == S_USER) + sp->s_flag |= S_GBL; + sp = sp->s_sp; + } + } +} + +/*)Function int symeq(p1, p2, cflag) + * + * int cflag case sensitive flag + * char * p1 name string + * char * p2 name string + * + * The function symeq() compares the two name strings for a match. + * The return value is 1 for a match and 0 for no match. + * + * cflag == 0 case insensitve compare + * cflag != 0 case sensitive compare + * + * local variables: + * int n loop counter + * + * global variables: + * char ccase[] an array of characters which + * perform the case translation function + * + * functions called: + * none + * + * side effects: + * none + * + */ + +int +symeq(p1, p2, cflag) +register char *p1, *p2; +int cflag; +{ + register int n; + + n = strlen(p1) + 1; + if(cflag) { + /* + * Case Sensitive Compare + */ + do { + if (*p1++ != *p2++) + return (0); + } while (--n); + } else { + /* + * Case Insensitive Compare + */ + do { + if (ccase[*p1++ & 0x007F] != ccase[*p2++ & 0x007F]) + return (0); + } while (--n); + } + return (1); +} + +/*)Function int hash(p, cflag) + * + * char * p pointer to string to hash + * int cflag case sensitive flag + * + * The function hash() computes a hash code using the sum + * of all characters mod table size algorithm. + * + * cflag == 0 case insensitve hash + * cflag != 0 case sensitive hash + * + * local variables: + * int h accumulated character sum + * + * global variables: + * char ccase[] an array of characters which + * perform the case translation function + * + * functions called: + * none + * + * side effects: + * none + */ + +int +hash(p, cflag) +register char *p; +register int cflag; +{ + register int h; + + h = 0; + while (*p) { + if(cflag) { + /* + * Case Sensitive Hash + */ + h += *p++; + } else { + /* + * Case Insensitive Hash + */ + h += ccase[*p++ & 0x007F]; + } + } + return (h&HMASK); +} + +/*)Function char * strsto(str) + * + * char * str pointer to string to save + * + * Allocate space for "str", copy str into new space. + * Return a pointer to the allocated string. + * + * This function based on code by + * John L. Hartman + * jhartman@compuserve.com + * + * local variables: + * int l string length + 1 + * int bytes bytes remaining in buffer area + * char * p pointer to head of copied string + * char * pnext next location in buffer area + * + * global variables: + * none + * + * functions called: + * VOID * new() assym.c + * char * strncpy() c_library + * + * side effects: + * Space allocated for string, string copied + * to space. Out of Space terminates assembler. + */ + +/* + * To avoid wasting memory headers on small allocations, we + * allocate a big chunk and parcel it out as required. + * These static variables remember our hunk + */ + +#define STR_SPC 1024 +static char * pnext = NULL; +static int bytes = 0; + +char * +strsto(str) +char *str; +{ + int l; + char *p; + + /* + * What we need, including a null. + */ + l = strlen(str) + 1; + + if (l > bytes) { + /* + * No space. Allocate a new hunk. + * We lose the pointer to any old hunk. + * We don't care, as the names are never deleted. + */ + pnext = (char *) new (STR_SPC); + bytes = STR_SPC; + } + + /* + * Copy the name and terminating null. + */ + p = pnext; + strncpy(p, str, l); + + pnext += l; + bytes -= l; + + return(p); +} + +/*)Function char * new(n) + * + * unsigned int n allocation size in bytes + * + * The function new() allocates n bytes of space and returns + * a pointer to this memory. If no space is available the + * assembly is terminated. + * + * local variables: + * VOID * p a general pointer + * + * global variables: + * none + * + * functions called: + * VOID asexit() asmain.c + * int fprintf() c_library + * VOID * malloc() c_library + * + * side effects: + * Memory is allocated, if allocation fails + * the assembly is terminated. + */ + +char * +new(n) +unsigned int n; +{ + register VOID *p; + + if ((p = (VOID *) malloc(n)) == NULL) { + fprintf(stderr, "Out of space!\n"); + asexit(ER_FATAL); + } + return (p); +} diff --git a/src/as-z80/asxxxx.h b/src/as-z80/asxxxx.h new file mode 100755 index 00000000..bac1284d --- /dev/null +++ b/src/as-z80/asxxxx.h @@ -0,0 +1,850 @@ +/* asxxxx.h */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With enhancements from + * + * John L. Hartman (JLH) + * jhartman@compuserve.com + * + * Bill McKinnon (BM) + * w_mckinnon@conknet.com + */ + +#define VERSION "V03.11" + +/*)Module asxxxx.h + * + * The module asxxxx.h contains the definitions for constants, + * structures, global variables, and ASxxxx functions + * contained in the ASxxxx.c files. The two functions + * and three global variables from the machine dependent + * files are also defined. + */ + +/* + * compiler/operating system specific definitions + */ + +/* DECUS C void definition */ +/* File/extension seperator */ + +#ifdef decus +#define VOID char +#define FSEPX '.' +#endif + +/* PDOS C void definition */ +/* File/extension seperator */ + +#ifdef PDOS +#define VOID char +#define FSEPX ':' +#endif + +/* Default void definition */ +/* File/extension seperator */ + +#ifndef VOID +#define VOID void +#define FSEPX '.' +#define OTHERSYSTEM +#endif + +/* + * Error definitions + */ +#define ER_NONE 0 /* No error */ +#define ER_WARNING 1 /* Warning */ +#define ER_ERROR 2 /* Assembly error */ +#define ER_FATAL 3 /* Fatal error */ + +/* + * Assembler definitions. + */ +#define LFTERM '(' /* Left expression delimeter */ +#define RTTERM ')' /* Right expression delimeter */ + +#define NCPS 80 /* Characters per symbol */ +#define HUGE 1000 /* A huge number */ +#define NERR 3 /* Errors per line */ +#define NINPUT 128 /* Input buffer size */ +#define NCODE 128 /* Listing code buffer size */ +#define NTITL 80 /* Title buffer size */ +#define NSBTL 80 /* SubTitle buffer size */ +#define NHASH 64 /* Buckets in hash table */ +#define HMASK 077 /* Hash mask */ +#define NLPP 60 /* Lines per page */ +#define MAXFIL 6 /* Maximum command line input files */ +#define MAXINC 6 /* Maximum nesting of include files */ +#define MAXIF 10 /* Maximum nesting of if/else/endif */ +#define FILSPC 256 /* Nick 80 */ /* Chars. in filespec */ + +#define NLIST 0 /* No listing */ +#define SLIST 1 /* Source only */ +#define ALIST 2 /* Address only */ +#define BLIST 3 /* Address only with allocation */ +#define CLIST 4 /* Code */ +#define ELIST 5 /* Equate only */ + +#define dot sym[0] /* Dot, current loc */ +#define dca area[0] /* Dca, default code area */ + + +typedef unsigned int a_uint; + +/* + * The area structure contains the parameter values for a + * specific program or data section. The area structure + * is a linked list of areas. The initial default area + * is "_CODE" defined in asdata.c, the next area structure + * will be linked to this structure through the structure + * element 'struct area *a_ap'. The structure contains the + * area name, area reference number ("_CODE" is 0) determined + * by the order of .area directives, area size determined + * from the total code and/or data in an area, area fuzz is + * a variable used to track pass to pass changes in the + * area size caused by variable length instruction formats, + * and area flags which specify the area's relocation type. + */ +struct area +{ + struct area *a_ap; /* Area link */ + char * a_id; /* Area Name */ + int a_ref; /* Ref. number */ + a_uint a_size; /* Area size */ + a_uint a_fuzz; /* Area fuzz */ + int a_flag; /* Area flags */ +}; + +/* + * The "A_" area constants define values used in + * generating the assembler area output data. + * + * Area flags + * + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | | | | PAG | ABS | OVR | | | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + */ + +#define A_NUL 001 /* Nick, means segment only defines symbols */ +#define A_CON 000 /* Concatenating */ +#define A_OVR 004 /* Overlaying */ +#define A_REL 000 /* Relocatable */ +#define A_ABS 010 /* absolute */ +#define A_NOPAG 000 /* Non-Paged */ +#define A_PAG 020 /* Paged */ + +/* + * The "R_" relocation constants define values used in + * generating the assembler relocation output data for + * areas, symbols, and code. + * + * Relocation flags + * + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + */ + +#define R_WORD 0000 /* 16 bit */ +#define R_BYTE 0001 /* 8 bit */ + +#define R_AREA 0000 /* Base type */ +#define R_SYM 0002 + +#define R_NORM 0000 /* PC adjust */ +#define R_PCR 0004 + +#define R_BYT1 0000 /* Byte count for R_BYTE = 1 */ +#define R_BYTX 0010 /* Byte count for R_BYTE = X */ + +#define R_SGND 0000 /* Signed Byte */ +#define R_USGN 0020 /* Unsigned Byte */ + +#if 1 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ +#define R_BYTE3 0040 /* byte after 'high' byte */ +#define R_BYTE4 0100 /* byte after 'byte3' byte */ +#else +#define R_NOPAG 0000 /* Page Mode */ +#define R_PAG0 0040 /* Page '0' */ +#define R_PAG 0100 /* Page 'nnn' */ +#endif + +#define R_LSB 0000 /* low byte */ +#define R_MSB 0200 /* high byte */ + +/* + * Additional "R_" functionality is required to support + * some microprocesssor architectures. The 'illegal' + * "R_" mode of R_WORD | R_BYTX is used as a designator + * of the extended R_ modes. The extended modes replace + * the PAGING modes and are being added in an adhoc manner + * as follows: + * + * Extended Mode relocation flags + * + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | MSB | x | x | USGN| 1 | PCR | SYM | 0 | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + */ + +#define R_ECHEK 0011 /* Extended Mode Check Bits */ +#define R_EXTND 0010 /* Extended Mode Code */ +#define R_EMASK 0151 /* Extended Mode Mask */ + +/* #define R_AREA 0000 */ /* Base type */ +/* #define R_SYM 0002 */ + +/* #define R_NORM 0000 */ /* PC adjust */ +/* #define R_PCR 0004 */ + +/* #define R_SGND 0000 */ /* Signed value */ +/* #define R_USGN 0020 */ /* Unsigned value */ + +/* #define R_LSB 0000 */ /* output low byte */ +/* #define R_MSB 0200 */ /* output high byte */ + +#define R_J11 0010 /* JLH: 11 bit JMP and CALL (8051) */ +#define R_J19 0050 /* BM: 19 bit JMP and CALL (DS80C390) */ +#define R_3BYTE 0110 /* 3-Byte */ +#define R_4BYTE 0150 /* 4-Byte */ + +/* + * Listing Control Flags + */ + +#define R_HIGH 0010000 /* High Byte */ +#define R_BYT3 0020000 /* 3rd Byte */ +#define R_BYT4 0040000 /* 4th Byte */ +#define R_RELOC 0100000 /* Relocation */ + +#define R_DEF 00 /* Global def. */ +#define R_REF 01 /* Global ref. */ +#define R_REL 00 /* Relocatable */ +#define R_ABS 02 /* Absolute */ +#define R_GBL 00 /* Global */ +#define R_LCL 04 /* Local */ + +/* + * The mne structure is a linked list of the assembler + * mnemonics and directives. The list of mnemonics and + * directives contained in the device dependent file + * xxxpst.c are hashed and linked into NHASH lists in + * module assym.c by syminit(). The structure contains + * the mnemonic/directive name, a subtype which directs + * the evaluation of this mnemonic/directive, a flag which + * is used to detect the end of the mnemonic/directive + * list in xxxpst.c, and a value which is normally + * associated with the assembler mnemonic base instruction + * value. + */ +struct mne +{ + struct mne *m_mp; /* Hash link */ + char *m_id; /* Mnemonic (JLH) */ + char m_type; /* Mnemonic subtype */ + char m_flag; /* Mnemonic flags */ + a_uint m_valu; /* Value */ +}; + +/* + * The sym structure is a linked list of symbols defined + * in the assembler source files. The first symbol is "." + * defined in asdata.c. The entry 'struct tsym *s_tsym' + * links any temporary symbols following this symbol and + * preceeding the next normal symbol. The structure also + * contains the symbol's name, type (USER or NEW), flag + * (global, assigned, and multiply defined), a pointer + * to the area structure defining where the symbol is + * located, a reference number assigned by outgsd() in + * asout.c, and the symbols address relative to the base + * address of the area where the symbol is located. + */ +struct sym +{ + struct sym *s_sp; /* Hash link */ + struct tsym *s_tsym; /* Temporary symbol link */ + char *s_id; /* Symbol (JLH) */ + char s_type; /* Symbol subtype */ + char s_flag; /* Symbol flags */ + struct area *s_area; /* Area line, 0 if absolute */ + int s_ref; /* Ref. number */ + a_uint s_addr; /* Address */ +}; + +#define S_GBL 01 /* Global */ +#define S_ASG 02 /* Assigned */ +#define S_MDF 04 /* Mult. def */ +#if 1 /* Nick */ +#define S_ENDPST 010 /* End mark for ___pst files */ +#else +#define S_END 010 /* End mark for ___pst files */ +#endif + +#define S_NEW 0 /* New name */ +#define S_USER 1 /* User name */ + +#if 1 /* Nick */ +#define S_ENDMOD 2 /* Nick .endmod/endmod, formerly unused slot */ +#define S_END 3 /* Nick .end/end, formerly unused slot */ +#define S_EQU 4 /* Nick .equ/equ, formerly unused slot */ +#endif + +#define S_DATA 5 /* .byte, .word, .3byte, .4byte */ +#define S_ASCII 6 /* .ascii */ +#define S_ASCIZ 7 /* .asciz */ +#define S_BLK 8 /* .blkb or .blkw */ +#define S_INCL 9 /* .include */ +#define S_DAREA 10 /* .area */ +#define S_ATYP 11 /* .area type */ +#define S_AREA 12 /* .area name */ +#define S_GLOBL 13 /* .globl */ +#define S_PAGE 14 /* .page */ +#define S_TITLE 15 /* .title */ +#define S_SBTL 16 /* .sbttl */ +#define S_IF 17 /* .if */ +#define S_ELSE 18 /* .else */ +#define S_ENDIF 19 /* .endif */ +#define S_EVEN 20 /* .even */ +#define S_ODD 21 /* .odd */ +#define S_RADIX 22 /* .radix */ +#define S_ORG 23 /* .org */ +#define S_MODUL 24 /* .module */ +#define S_ASCIS 25 /* .ascis */ +#define S_ERROR 26 /* .assume or .error */ +#define S_BITS 27 /* .8bit, .16bit, .24bit, .32bit */ + + +/* + * The tsym structure is a linked list of temporary + * symbols defined in the assembler source files following + * a normal symbol. The structure contains the temporary + * symbols number, a flag (multiply defined), a pointer to the + * area structure defining where the temporary structure + * is located, and the temporary symbol's address relative + * to the base address of the area where the symbol + * is located. + */ +struct tsym +{ + struct tsym *t_lnk; /* Link to next */ + char t_num; /* 0-255$ */ + char t_flg; /* flags */ + struct area *t_area; /* Area */ + a_uint t_addr; /* Address */ +}; + +/* + * External Definitions for all Global Variables + */ + +extern int aserr; /* ASxxxx error counter + */ +extern jmp_buf jump_env; /* compiler dependent structure + * used by setjmp() and longjmp() + */ +extern int inpfil; /* count of assembler + * input files specified + */ +extern int incfil; /* current file handle index + * for include files + */ +extern int cfile; /* current file handle index + * of input assembly files + */ +extern int flevel; /* IF-ELSE-ENDIF flag will be non + * zero for false conditional case + */ +extern int tlevel; /* current conditional level + */ +extern int ifcnd[MAXIF+1]; /* array of IF statement condition + * values (0 = FALSE) indexed by tlevel + */ +extern int iflvl[MAXIF+1]; /* array of IF-ELSE-ENDIF flevel + * values indexed by tlevel + */ +extern char afn[FILSPC]; /* current input file specification + */ +extern int afp; /* current input file path length + */ +extern char afntmp[FILSPC]; /* temporary input file specification + */ +extern int afptmp; /* temporary input file path length + */ +extern char + srcfn[MAXFIL][FILSPC]; /* array of source file names + */ +extern int + srcfp[MAXFIL]; /* array of source file path lengths + */ +extern int + srcline[MAXFIL]; /* current source file line + */ +extern char + incfn[MAXINC][FILSPC]; /* array of include file names + */ +extern int + incfp[MAXINC]; /* array of include file path lengths + */ +extern int + incline[MAXINC]; /* current include file line + */ +extern int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +extern int line; /* current assembler source + * line number + */ +extern int page; /* current page number + */ +extern int lop; /* current line number on page + */ +extern int pass; /* assembler pass number + */ +extern int lflag; /* -l, generate listing flag + */ +extern int gflag; /* -g, make undefined symbols global flag + */ +extern int aflag; /* -a, make all symbols global flag + */ +extern int oflag; /* -o, generate relocatable output flag + */ +extern int sflag; /* -s, generate symbol table flag + */ +extern int pflag; /* -p, enable listing pagination + */ +extern int wflag; /* -w, enable wide format listing + */ +extern int zflag; /* -z, enable symbol case sensitivity + */ +extern int xflag; /* -x, listing radix flag + */ +extern int fflag; /* -f(f), relocations flagged flag + */ +extern int a_bytes; /* REL file T Line address length + */ +extern a_uint a_mask; /* Address Mask + */ +extern a_uint s_mask; /* Sign Mask + */ +extern a_uint v_mask; /* Value Mask + */ +extern a_uint laddr; /* address of current assembler line, + * equate, or value of .if argument + */ +extern a_uint fuzz; /* tracks pass to pass changes in the + * address of symbols caused by + * variable length instruction formats + */ +extern int lmode; /* listing mode + */ +extern struct area area[]; /* array of 1 area + */ +extern struct area *areap; /* pointer to an area structure + */ +extern struct sym sym[]; /* array of 1 symbol + */ +extern struct sym *symp; /* pointer to a symbol structure + */ +extern struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ +extern struct mne *mnehash[NHASH]; /* array of pointers to NHASH + * linked mnemonic/directive lists + */ +extern char *ep; /* pointer into error list + * array eb[NERR] + */ +extern char eb[NERR]; /* array of generated error codes + */ +extern char *ip; /* pointer into the assembler-source + * text line in ib[] + */ +extern char ib[NINPUT]; /* assembler-source text line + */ +extern char *cp; /* pointer to assembler output + * array cb[] + */ +extern char cb[NCODE]; /* array of assembler output values + */ +extern int *cpt; /* pointer to assembler relocation type + * output array cbt[] + */ +extern int cbt[NCODE]; /* array of assembler relocation types + * describing the data in cb[] + */ +extern char tb[NTITL]; /* Title string buffer + */ +extern char stb[NSBTL]; /* Subtitle string buffer + */ +extern char erb[NINPUT+4]; /* Error string buffer + */ +extern char symtbl[]; /* string "Symbol Table" + */ +extern char aretbl[]; /* string "Area Table" + */ +extern char module[NCPS+2]; /* module name string + */ +extern FILE *lfp; /* list output file handle + */ +extern FILE *ofp; /* relocation output file handle + */ +extern FILE *tfp; /* symbol table output file handle + */ +extern FILE *sfp[MAXFIL]; /* array of assembler-source file handles + */ +extern FILE *ifp[MAXINC]; /* array of include-file file handles + */ +extern char ctype[128]; /* array of character types, one per + * ASCII character + */ +extern char ccase[128]; /* an array of characters which + * perform the case translation function + */ +/* + * Definitions for Character Types + */ +#define SPACE '\000' +#define ETC '\000' +#define LETTER '\001' +#define DIGIT '\002' +#define BINOP '\004' +#define RAD2 '\010' +#define RAD8 '\020' +#define RAD10 '\040' +#define RAD16 '\100' +#define ILL '\200' + +#define DGT2 DIGIT|RAD16|RAD10|RAD8|RAD2 +#define DGT8 DIGIT|RAD16|RAD10|RAD8 +#define DGT10 DIGIT|RAD16|RAD10 +#define LTR16 LETTER|RAD16 + +/* + * The exp structure is used to return the evaluation + * of an expression. The structure supports three valid + * cases: + * (1) The expression evaluates to a constant, + * mode = S_USER, flag = 0, addr contains the + * constant, and base = NULL. + * (2) The expression evaluates to a defined symbol + * plus or minus a constant, mode = S_USER, + * flag = 0, addr contains the constant, and + * base = pointer to area symbol. + * (3) The expression evaluates to a external + * global symbol plus or minus a constant, + * mode = S_NEW, flag = 1, addr contains the + * constant, and base = pointer to symbol. + */ +struct expr +{ + char e_mode; /* Address mode */ + char e_flag; /* Symbol flag */ + a_uint e_addr; /* Address */ + union { + struct area *e_ap; + struct sym *e_sp; + } e_base; /* Rel. base */ + char e_rlcf; /* Rel. flags */ +}; + +/* C Library functions */ +/* for reference only +extern VOID exit(); +extern int fclose(); +extern char * fgets(); +extern FILE * fopen(); +extern int fprintf(); +extern VOID longjmp(); +extern VOID * malloc(); +extern int printf(); +extern char putc(); +extern int rewind(); +extern int setjmp(); +extern int strcmp(); +extern char * strcpy(); +extern int strlen(); +extern char * strncpy(); +extern char * strrchr(); +*/ + +/* Machine independent functions */ + +#ifdef OTHERSYSTEM + +/* asmain.c */ +extern FILE * afile(char *fn, char *ft, int wf); +extern VOID afilex(char *fn, char *ft); +extern VOID asexit(int i); +extern VOID asmbl(void); +extern int fndidx(char *str); +extern int main(int argc, char *argv[]); +extern VOID newdot(struct area *nap); +extern VOID phase(struct area *ap, a_uint a); +extern char * usetxt[]; +extern VOID usage(int n); + +/* aslex.c */ +extern char endline(void); +extern int get(void); +extern VOID getid(char *id, int c); +extern int getline(void); +extern int getmap(int d); +extern int getnb(void); +extern VOID getst(char *id, int c); +extern int more(void); +extern VOID unget(int c); + +/* assym.c */ +extern struct area * alookup(char *id); +extern struct mne * mlookup(char *id); +extern int hash(char *p, int cflag); +extern struct sym * lookup(char *id); +extern char * new(unsigned int n); +extern struct sym * slookup(char *id); +extern char * strsto(char *str); +extern int symeq(char *p1, char *p2, int cflag); +extern VOID syminit(void); +extern VOID symglob(void); +extern VOID allglob(void); + +/* assubr.c */ +extern VOID aerr(void); +extern VOID diag(void); +extern VOID err(int c); +extern char * errors[]; +extern char * geterr(int c); +extern VOID qerr(void); +extern VOID rerr(void); + +/* asexpr.c */ +extern VOID abscheck(struct expr *esp); +extern a_uint absexpr(void); +extern VOID clrexpr(struct expr *esp); +extern int digit(int c, int r); +extern VOID exprmasks(int n); +extern int is_abs(struct expr *esp); +extern VOID expr(struct expr *esp, int n); +extern int oprio(int c); +extern VOID term(struct expr *esp); + +/* aslist.c */ +extern VOID list(void); +extern VOID list1(char *wp, int *wpt, int nb, int n, int f); +extern VOID list2(int t); +extern VOID lstsym(FILE *fp); +extern VOID slew(FILE *fp, int flag); + +/* asout.c */ +extern int lobyte(int v); +extern int hibyte(int v); +extern int thrdbyte(int v); +extern int frthbyte(int v); +extern VOID out(char *p, int n); +extern VOID outarea(struct area *ap); +extern VOID outdp(struct area *carea, struct expr *esp); +extern VOID outall(void); +extern VOID outdot(void); +extern VOID outbuf(char *s); +extern VOID outchk(int nt, int nr); +extern VOID outgsd(void); +extern VOID outsym(struct sym *sp); +extern VOID outab(int v); +extern VOID outaw(int v); +extern VOID outa3b(int v); +extern VOID outa4b(int v); +extern VOID outaxb(int i, int v); +extern VOID outatxb(int i, int v); +extern VOID outrb(struct expr *esp, int r); +extern VOID outrw(struct expr *esp, int r); +extern VOID outr3b(struct expr *esp, int r); +extern VOID outr4b(struct expr *esp, int r); +extern VOID outrxb(int i, struct expr *esp, int r); +extern VOID outr11(struct expr *esp, int op); /* JLH */ +extern VOID outr19(struct expr *esp, int op); /* BM */ +extern VOID out_lb(int v, int t); +extern VOID out_lw(int v, int t); +extern VOID out_l3b(int v, int t); +extern VOID out_l4b(int v, int t); +extern VOID out_lxb(int i, int v, int t); +extern VOID out_rw(int n); +extern VOID out_txb(int i, int v); + +/* Machine dependent variables */ + +extern char * cpu; +extern char * dsft; +extern int hilo; +extern struct mne mne[]; + +/* Machine dependent functions */ + +extern VOID machine(struct mne *mp); +extern VOID minit(void); + +/* asxcnv.c */ + +/* Defined under asmain.c above +extern VOID asexit(int i); +extern int main(int argc, char *argv[]); +extern char * usetxt[]; +extern VOID usage(int n); +*/ +extern VOID linout(char *str, unsigned int n); + +/* asxscn.c */ + +/* Defined under asmain.c above +extern VOID asexit(int i); +extern int main(int argc, char *argv[]); +extern char * usetxt[]; +extern VOID usage(int n); +*/ +extern int dgt(int rdx, char *str, int n); + +#else + +/* asmain.c */ +extern FILE * afile(); +extern VOID afilex(); +extern VOID asexit(); +extern VOID asmbl(); +extern int fndidx(); +extern int main(); +extern VOID newdot(); +extern VOID phase(); +extern char * usetxt[]; +extern VOID usage(); + +/* aslex.c */ +extern char endline(); +extern int get(); +extern VOID getid(); +extern int getline(); +extern int getmap(); +extern int getnb(); +extern VOID getst(); +extern int more(); +extern VOID unget(); + +/* assym.c */ +extern struct area * alookup(); +extern struct mne * mlookup(); +extern int hash(); +extern struct sym * lookup(); +extern char * new(); +extern struct sym * slookup(); +extern char * strsto(); +extern int symeq(); +extern VOID syminit(); +extern VOID symglob(); +extern VOID allglob(); + +/* assubr.c */ +extern VOID aerr(); +extern VOID diag(); +extern VOID err(); +extern char * errors[]; +extern char * geterr(); +extern VOID qerr(); +extern VOID rerr(); + +/* asexpr.c */ +extern VOID abscheck(); +extern a_uint absexpr(); +extern VOID clrexpr(); +extern int digit(); +extern VOID exprmasks(); +extern int is_abs(); +extern VOID expr(); +extern int oprio(); +extern VOID term(); + +/* aslist.c */ +extern VOID list(); +extern VOID list1(); +extern VOID list2(); +extern VOID lstsym(); +extern VOID slew(); + +/* asout.c */ +extern int lobyte(); +extern int hibyte(); +extern int thrdbyte(); +extern int frthbyte(); +extern VOID out(); +extern VOID outarea(); +extern VOID outdp(); +extern VOID outall(); +extern VOID outdot(); +extern VOID outbuf(); +extern VOID outchk(); +extern VOID outgsd(); +extern VOID outsym(); +extern VOID outab(); +extern VOID outaw(); +extern VOID outa3b(); +extern VOID outa4b(); +extern VOID outaxb(); +extern VOID outatxb(); +extern VOID outrb(); +extern VOID outrw(); +extern VOID outr3b(); +extern VOID outr4b(); +extern VOID outrxb(); +extern VOID outr11(); /* JLH */ +extern VOID outr19(); /* BM */ +extern VOID out_lb(); +extern VOID out_lw(); +extern VOID out_l3b(); +extern VOID out_l4b(); +extern VOID out_lxb(); +extern VOID out_rw(); +extern VOID out_txb(); + +/* Machine dependent variables */ + +extern char * cpu; +extern char * dsft; +extern int hilo; +extern struct mne mne[]; + +/* Machine dependent functions */ + +extern VOID machine(); +extern VOID minit(); + +/* asxcnv.c */ + +/* Defined under asmain.c above +extern VOID asexit(); +extern int main(); +extern char * usetxt[]; +extern VOID usage(); +*/ +extern VOID linout(); + +/* asxscn.c */ + +/* Defined under asmain.c above +extern VOID asexit(); +extern int main(); +extern char * usetxt[]; +extern VOID usage(); +*/ +extern int dgt(); + +#endif + diff --git a/src/as-z80/n.bat b/src/as-z80/n.bat new file mode 100755 index 00000000..b8d45f52 --- /dev/null +++ b/src/as-z80/n.bat @@ -0,0 +1,34 @@ +cl -Zi -I. -DWIN32 -c asdata.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c asexpr.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c aslex.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c aslist.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c asmain.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c asout.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c assubr.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c assym.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c z80adr.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c z80ext.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c z80mch.c +@if errorlevel 1 goto failure +cl -Zi -I. -DWIN32 -c z80pst.c +@if errorlevel 1 goto failure +link @as-z80.lnk +@if errorlevel 1 goto failure +copy as-z80.exe ..\bin + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/as-z80/tz80.asm b/src/as-z80/tz80.asm new file mode 100755 index 00000000..9edd65cf --- /dev/null +++ b/src/as-z80/tz80.asm @@ -0,0 +1,1013 @@ + .title Test of Z80 / HD64180 assembler + + offset = 0x55 ;arbitrary constants + n = 0x20 + nn = 0x0584 + + ; notes: + ; Leading 'a' operand is optional. + ; If offset is ommitted 0 is assumed. + + ;*********************************************************** + ; add with carry to 'a' + adc a,(hl) ;8E + adc a,offset(ix) ;DD 8E 55 + adc a,offset(iy) ;FD 8E 55 + adc a,a ;8F + adc a,b ;88 + adc a,c ;89 + adc a,d ;8A + adc a,e ;8B + adc a,h ;8C + adc a,l ;8D + adc a,#n ;CE 20 + ;*********************************************************** + adc (hl) ;8E + adc offset(ix) ;DD 8E 55 + adc offset(iy) ;FD 8E 55 + adc a ;8F + adc b ;88 + adc c ;89 + adc d ;8A + adc e ;8B + adc h ;8C + adc l ;8D + adc #n ;CE 20 + ;*********************************************************** + ; add with carry register pair to 'hl' + adc hl,bc ;ED 4A + adc hl,de ;ED 5A + adc hl,hl ;ED 6A + adc hl,sp ;ED 7A + ;*********************************************************** + ; add operand to 'a' + add a,(hl) ;86 + add a,offset(ix) ;DD 86 55 + add a,offset(iy) ;FD 86 55 + add a,a ;87 + add a,b ;80 + add a,c ;81 + add a,d ;82 + add a,e ;83 + add a,h ;84 + add a,l ;85 + add a,#n ;C6 20 + ;*********************************************************** + ; add register pair to 'hl' + add hl,bc ;09 + add hl,de ;19 + add hl,hl ;29 + add hl,sp ;39 + ;*********************************************************** + ; add register pair to 'ix' + add ix,bc ;DD 09 + add ix,de ;DD 19 + add ix,ix ;DD 29 + add ix,sp ;DD 39 + ;*********************************************************** + ; add register pair to 'iy' + add iy,bc ;FD 09 + add iy,de ;FD 19 + add iy,iy ;FD 29 + add iy,sp ;FD 39 + ;*********************************************************** + ; logical 'and' operand with 'a' + and a,(hl) ;A6 + and a,offset(ix) ;DD A6 55 + and a,offset(iy) ;FD A6 55 + and a,a ;A7 + and a,b ;A0 + and a,c ;A1 + and a,d ;A2 + and a,e ;A3 + and a,h ;A4 + and a,l ;A5 + and a,#n ;E6 20 + ;*********************************************************** + ; test bit of location or register + bit 0,(hl) ;CB 46 + bit 0,offset(ix) ;DD CB 55 46 + bit 0,offset(iy) ;FD CB 55 46 + bit 0,a ;CB 47 + bit 0,b ;CB 40 + bit 0,c ;CB 41 + bit 0,d ;CB 42 + bit 0,e ;CB 43 + bit 0,h ;CB 44 + bit 0,l ;CB 45 + bit 1,(hl) ;CB 4E + bit 1,offset(ix) ;DD CB 55 4E + bit 1,offset(iy) ;FD CB 55 4E + bit 1,a ;CB 4F + bit 1,b ;CB 48 + bit 1,c ;CB 49 + bit 1,d ;CB 4A + bit 1,e ;CB 4B + bit 1,h ;CB 4C + bit 1,l ;CB 4D + bit 2,(hl) ;CB 56 + bit 2,offset(ix) ;DD CB 55 56 + bit 2,offset(iy) ;FD CB 55 56 + bit 2,a ;CB 57 + bit 2,b ;CB 50 + bit 2,c ;CB 51 + bit 2,d ;CB 52 + bit 2,e ;CB 53 + bit 2,h ;CB 54 + bit 2,l ;CB 55 + bit 3,(hl) ;CB 5E + bit 3,offset(ix) ;DD CB 55 5E + bit 3,offset(iy) ;FD CB 55 5E + bit 3,a ;CB 5F + bit 3,b ;CB 58 + bit 3,c ;CB 59 + bit 3,d ;CB 5A + bit 3,e ;CB 5B + bit 3,h ;CB 5C + bit 3,l ;CB 5D + bit 4,(hl) ;CB 66 + bit 4,offset(ix) ;DD CB 55 66 + bit 4,offset(iy) ;FD CB 55 66 + bit 4,a ;CB 67 + bit 4,b ;CB 60 + bit 4,c ;CB 61 + bit 4,d ;CB 62 + bit 4,e ;CB 63 + bit 4,h ;CB 64 + bit 4,l ;CB 65 + bit 5,(hl) ;CB 6E + bit 5,offset(ix) ;DD CB 55 6E + bit 5,offset(iy) ;FD CB 55 6E + bit 5,a ;CB 6F + bit 5,b ;CB 68 + bit 5,c ;CB 69 + bit 5,d ;CB 6A + bit 5,e ;CB 6B + bit 5,h ;CB 6C + bit 5,l ;CB 6D + bit 6,(hl) ;CB 76 + bit 6,offset(ix) ;DD CB 55 76 + bit 6,offset(iy) ;FD CB 55 76 + bit 6,a ;CB 77 + bit 6,b ;CB 70 + bit 6,c ;CB 71 + bit 6,d ;CB 72 + bit 6,e ;CB 73 + bit 6,h ;CB 74 + bit 6,l ;CB 75 + bit 7,(hl) ;CB 7E + bit 7,offset(ix) ;DD CB 55 7E + bit 7,offset(iy) ;FD CB 55 7E + bit 7,a ;CB 7F + bit 7,b ;CB 78 + bit 7,c ;CB 79 + bit 7,d ;CB 7A + bit 7,e ;CB 7B + bit 7,h ;CB 7C + bit 7,l ;CB 7D + ;*********************************************************** + ; call subroutine at nn if condition is true + call C,nn ;DC 84 05 + call M,nn ;FC 84 05 + call NC,nn ;D4 84 05 + call NZ,nn ;C4 84 05 + call P,nn ;F4 84 05 + call PE,nn ;EC 84 05 + call PO,nn ;E4 84 05 + call Z,nn ;CC 84 05 + ;*********************************************************** + ; unconditional call to subroutine at nn + call nn ;CD 84 05 + ;*********************************************************** + ; complement carry flag + ccf ;3F + ;*********************************************************** + ; compare operand with 'a' + cp a,(hl) ;BE + cp a,offset(ix) ;DD BE 55 + cp a,offset(iy) ;FD BE 55 + cp a,a ;BF + cp a,b ;B8 + cp a,c ;B9 + cp a,d ;BA + cp a,e ;BB + cp a,h ;BC + cp a,l ;BD + cp a,#n ;FE 20 + ;*********************************************************** + ; compare location (hl) and 'a' + ; decrement 'hl' and 'bc' + cpd ;ED A9 + ;*********************************************************** + ; compare location (hl) and 'a' + ; decrement 'hl' and 'bc' + ; repeat until 'bc' = 0 + cpdr ;ED B9 + ;*********************************************************** + ; compare location (hl) and 'a' + ; increment 'hl' and decrement 'bc' + cpi ;ED A1 + ;*********************************************************** + ; compare location (hl) and 'a' + ; increment 'hl' and decrement 'bc' + ; repeat until 'bc' = 0 + cpir ;ED B1 + ;*********************************************************** + ; 1's complement of 'a' + cpl ;2F + ;*********************************************************** + ; decimal adjust 'a' + daa ;27 + ;*********************************************************** + ; decrement operand + dec (hl) ;35 + dec offset(ix) ;DD 35 55 + dec offset(iy) ;FD 35 55 + dec a ;3D + dec b ;05 + dec bc ;0B + dec c ;0D + dec d ;15 + dec de ;1B + dec e ;1D + dec h ;25 + dec hl ;2B + dec ix ;DD 2B + dec iy ;FD 2B + dec l ;2D + dec sp ;3B + ;*********************************************************** + ; disable interrupts + di ;F3 + ;*********************************************************** + ; decrement b and jump relative if b # 0 + djnz .+0x12 ;10 10 + ;*********************************************************** + ; enable interrupts + ei ;FB + ;*********************************************************** + ; exchange location and (sp) + ex (sp),hl ;E3 + ex (sp),ix ;DD E3 + ex (sp),iy ;FD E3 + ;*********************************************************** + ; exchange af and af' + ex af,af' ;08 + ;*********************************************************** + ; exchange de and hl + ex de,hl ;EB + ;*********************************************************** + ; exchange: + ; bc <-> bc' + ; de <-> de' + ; hl <-> hl' + exx ;D9 + ;*********************************************************** + ; halt (wait for interrupt or reset) + halt ;76 + ;*********************************************************** + ; set interrupt mode + im 0 ;ED 46 + im 1 ;ED 56 + im 2 ;ED 5E + ;*********************************************************** + ; load 'a' with input from device n + in a,(n) ;DB 20 + ;*********************************************************** + ; load register with input from (c) + in a,(c) ;ED 78 + in b,(c) ;ED 40 + in c,(c) ;ED 48 + in d,(c) ;ED 50 + in e,(c) ;ED 58 + in h,(c) ;ED 60 + in l,(c) ;ED 68 + ;*********************************************************** + ; increment operand + inc (hl) ;34 + inc offset(ix) ;DD 34 55 + inc offset(iy) ;FD 34 55 + inc a ;3C + inc b ;04 + inc bc ;03 + inc c ;0C + inc d ;14 + inc de ;13 + inc e ;1C + inc h ;24 + inc hl ;23 + inc ix ;DD 23 + inc iy ;FD 23 + inc l ;2C + inc sp ;33 + ;*********************************************************** + ; load location (hl) with input + ; from port (c) + ; decrement 'hl' and 'b' + ind ;ED AA + ;*********************************************************** + ; load location (hl) with input + ; from port (c) + ; decrement 'hl' and 'b' + ; repeat until 'b' = 0 + indr ;ED BA + ;*********************************************************** + ; load location (hl) with input + ; from port (c) + ; increment 'hl' and decrement 'b' + ini ;ED A2 + ;*********************************************************** + ; load location (hl) with input + ; from port (c) + ; increment 'hl' and decrement 'b' + ; repeat until 'b' = 0 + inir ;ED B2 + ;*********************************************************** + ; unconditional jump to location nn + jp nn ;C3 84 05 + jp (hl) ;E9 + jp (ix) ;DD E9 + jp (iy) ;FD E9 + ;*********************************************************** + ; jump to location if condition is true + jp C,nn ;DA 84 05 + jp M,nn ;FA 84 05 + jp NC,nn ;D2 84 05 + jp NZ,nn ;C2 84 05 + jp P,nn ;F2 84 05 + jp PE,nn ;EA 84 05 + jp PO,nn ;E2 84 05 + jp Z,nn ;CA 84 05 + ;*********************************************************** + ; unconditional jump relative to PC+e + jr jr1+0x10 ;18 10 + ;*********************************************************** + ; jump relative to PC+e if condition is true +jr1: jr C,jr2+0x10 ;38 10 +jr2: jr NC,jr3+0x10 ;30 10 +jr3: jr NZ,jr4+0x10 ;20 10 +jr4: jr Z,jr5+0x10 ;28 10 +jr5: + ;*********************************************************** + ; load source to destination + ld a,(hl) ;7E + ld a,offset(ix) ;DD 7E 55 + ld a,offset(iy) ;FD 7E 55 + ld a,a ;7F + ld a,b ;78 + ld a,c ;79 + ld a,d ;7A + ld a,e ;7B + ld a,h ;7C + ld a,l ;7D + ld a,#n ;3E 20 + ld b,(hl) ;46 + ld b,offset(ix) ;DD 46 55 + ld b,offset(iy) ;FD 46 55 + ld b,a ;47 + ld b,b ;40 + ld b,c ;41 + ld b,d ;42 + ld b,e ;43 + ld b,h ;44 + ld b,l ;45 + ld b,#n ;06 20 + ld c,(hl) ;4E + ld c,offset(ix) ;DD 4E 55 + ld c,offset(iy) ;FD 4E 55 + ld c,a ;4F + ld c,b ;48 + ld c,c ;49 + ld c,d ;4A + ld c,e ;4B + ld c,h ;4C + ld c,l ;4D + ld c,#n ;0E 20 + ld d,(hl) ;56 + ld d,offset(ix) ;DD 56 55 + ld d,offset(iy) ;FD 56 55 + ld d,a ;57 + ld d,b ;50 + ld d,c ;51 + ld d,d ;52 + ld d,e ;53 + ld d,h ;54 + ld d,l ;55 + ld d,#n ;16 20 + ld e,(hl) ;5E + ld e,offset(ix) ;DD 5E 55 + ld e,offset(iy) ;FD 5E 55 + ld e,a ;5F + ld e,b ;58 + ld e,c ;59 + ld e,d ;5A + ld e,e ;5B + ld e,h ;5C + ld e,l ;5D + ld e,#n ;1E 20 + ld h,(hl) ;66 + ld h,offset(ix) ;DD 66 55 + ld h,offset(iy) ;FD 66 55 + ld h,a ;67 + ld h,b ;60 + ld h,c ;61 + ld h,d ;62 + ld h,e ;63 + ld h,h ;64 + ld h,l ;65 + ld h,#n ;26 20 + ld l,(hl) ;6E + ld l,offset(ix) ;DD 6E 55 + ld l,offset(iy) ;FD 6E 55 + ld l,a ;6F + ld l,b ;68 + ld l,c ;69 + ld l,d ;6A + ld l,e ;6B + ld l,h ;6C + ld l,l ;6D + ld l,#n ;2E 20 + ;*********************************************************** + ld i,a ;ED 47 + ld r,a ;ED 4F + ld a,i ;ED 57 + ld a,r ;ED 5F + ;*********************************************************** + ld (bc),a ;02 + ld (de),a ;12 + ld a,(bc) ;0A + ld a,(de) ;1A + ;*********************************************************** + ld (hl),a ;77 + ld (hl),b ;70 + ld (hl),c ;71 + ld (hl),d ;72 + ld (hl),e ;73 + ld (hl),h ;74 + ld (hl),l ;75 + ld (hl),#n ;36 20 + ;*********************************************************** + ld offset(ix),a ;DD 77 55 + ld offset(ix),b ;DD 70 55 + ld offset(ix),c ;DD 71 55 + ld offset(ix),d ;DD 72 55 + ld offset(ix),e ;DD 73 55 + ld offset(ix),h ;DD 74 55 + ld offset(ix),l ;DD 75 55 + ld offset(ix),#n ;DD 36 55 20 + ;*********************************************************** + ld offset(iy),a ;FD 77 55 + ld offset(iy),b ;FD 70 55 + ld offset(iy),c ;FD 71 55 + ld offset(iy),d ;FD 72 55 + ld offset(iy),e ;FD 73 55 + ld offset(iy),h ;FD 74 55 + ld offset(iy),l ;FD 75 55 + ld offset(iy),#n ;FD 36 55 20 + ;*********************************************************** + ld (nn),a ;32 84 05 + ld (nn),bc ;ED 43 84 05 + ld (nn),de ;ED 53 84 05 + ld (nn),hl ;22 84 05 + ld (nn),sp ;ED 73 84 05 + ld (nn),ix ;DD 22 84 05 + ld (nn),iy ;FD 22 84 05 + ;*********************************************************** + ld a,(nn) ;3A 84 05 + ld bc,(nn) ;ED 4B 84 05 + ld de,(nn) ;ED 5B 84 05 + ld hl,(nn) ;2A 84 05 + ld sp,(nn) ;ED 7B 84 05 + ld ix,(nn) ;DD 2A 84 05 + ld iy,(nn) ;FD 2A 84 05 + ;*********************************************************** + ld bc,#nn ;01 84 05 + ld de,#nn ;11 84 05 + ld hl,#nn ;21 84 05 + ld sp,#nn ;31 84 05 + ld ix,#nn ;DD 21 84 05 + ld iy,#nn ;FD 21 84 05 + ;*********************************************************** + ld sp,hl ;F9 + ld sp,ix ;DD F9 + ld sp,iy ;FD F9 + ;*********************************************************** + ; load location (hl) + ; with location (de) + ; decrement de, hl + ; decrement bc + ldd ;ED A8 + ;*********************************************************** + ; load location (hl) + ; with location (de) + ; decrement de, hl + ; decrement bc + ; repeat until bc = 0 + lddr ;ED B8 + ;*********************************************************** + ; load location (hl) + ; with location (de) + ; increment de, hl + ; decrement bc + ldi ;ED A0 + ;*********************************************************** + ; load location (hl) + ; with location (de) + ; increment de, hl + ; decrement bc + ; repeat until bc = 0 + ldir ;ED B0 + ;*********************************************************** + ; 2's complement of 'a' + neg ;ED 44 + ;*********************************************************** + ; no operation + nop ;00 + ;*********************************************************** + ; logical 'or' operand with 'a' + or a,(hl) ;B6 + or a,offset(ix) ;DD B6 55 + or a,offset(iy) ;FD B6 55 + or a,a ;B7 + or a,b ;B0 + or a,c ;B1 + or a,d ;B2 + or a,e ;B3 + or a,h ;B4 + or a,l ;B5 + or a,#n ;F6 20 + ;*********************************************************** + ; load output port (c) + ; with location (hl) + ; decrement hl and decrement b + ; repeat until b = 0 + otdr ;ED BB + ;*********************************************************** + ; load output port (c) + ; with location (hl) + ; increment hl and decrement b + ; repeat until b = 0 + otir ;ED B3 + ;*********************************************************** + ; load output port (c) with reg + out (c),a ;ED 79 + out (c),b ;ED 41 + out (c),c ;ED 49 + out (c),d ;ED 51 + out (c),e ;ED 59 + out (c),h ;ED 61 + out (c),l ;ED 69 + ;*********************************************************** + ; load output port (n) with 'a' + out (n),a ;D3 20 + ;*********************************************************** + ; load output port (c) + ; with location (hl) + ; decrement hl and decrement b + outd ;ED AB + ;*********************************************************** + ; load output port (c) + ; with location (hl) + ; increment hl and decrement b + outi ;ED A3 + ;*********************************************************** + ; load destination with top of stack + pop af ;F1 + pop bc ;C1 + pop de ;D1 + pop hl ;E1 + pop ix ;DD E1 + pop iy ;FD E1 + ;*********************************************************** + ; put source on stack + push af ;F5 + push bc ;C5 + push de ;D5 + push hl ;E5 + push ix ;DD E5 + push iy ;FD E5 + ;*********************************************************** + ; reset bit of location or register + res 0,(hl) ;CB 86 + res 0,offset(ix) ;DD CB 55 86 + res 0,offset(iy) ;FD CB 55 86 + res 0,a ;CB 87 + res 0,b ;CB 80 + res 0,c ;CB 81 + res 0,d ;CB 82 + res 0,e ;CB 83 + res 0,h ;CB 84 + res 0,l ;CB 85 + res 1,(hl) ;CB 8E + res 1,offset(ix) ;DD CB 55 8E + res 1,offset(iy) ;FD CB 55 8E + res 1,a ;CB 8F + res 1,b ;CB 88 + res 1,c ;CB 89 + res 1,d ;CB 8A + res 1,e ;CB 8B + res 1,h ;CB 8C + res 1,l ;CB 8D + res 2,(hl) ;CB 96 + res 2,offset(ix) ;DD CB 55 96 + res 2,offset(iy) ;FD CB 55 96 + res 2,a ;CB 97 + res 2,b ;CB 90 + res 2,c ;CB 91 + res 2,d ;CB 92 + res 2,e ;CB 93 + res 2,h ;CB 94 + res 2,l ;CB 95 + res 3,(hl) ;CB 9E + res 3,offset(ix) ;DD CB 55 9E + res 3,offset(iy) ;FD CB 55 9E + res 3,a ;CB 9F + res 3,b ;CB 98 + res 3,c ;CB 99 + res 3,d ;CB 9A + res 3,e ;CB 9B + res 3,h ;CB 9C + res 3,l ;CB 9D + res 4,(hl) ;CB A6 + res 4,offset(ix) ;DD CB 55 A6 + res 4,offset(iy) ;FD CB 55 A6 + res 4,a ;CB A7 + res 4,b ;CB A0 + res 4,c ;CB A1 + res 4,d ;CB A2 + res 4,e ;CB A3 + res 4,h ;CB A4 + res 4,l ;CB A5 + res 5,(hl) ;CB AE + res 5,offset(ix) ;DD CB 55 AE + res 5,offset(iy) ;FD CB 55 AE + res 5,a ;CB AF + res 5,b ;CB A8 + res 5,c ;CB A9 + res 5,d ;CB AA + res 5,e ;CB AB + res 5,h ;CB AC + res 5,l ;CB AD + res 6,(hl) ;CB B6 + res 6,offset(ix) ;DD CB 55 B6 + res 6,offset(iy) ;FD CB 55 B6 + res 6,a ;CB B7 + res 6,b ;CB B0 + res 6,c ;CB B1 + res 6,d ;CB B2 + res 6,e ;CB B3 + res 6,h ;CB B4 + res 6,l ;CB B5 + res 7,(hl) ;CB BE + res 7,offset(ix) ;DD CB 55 BE + res 7,offset(iy) ;FD CB 55 BE + res 7,a ;CB BF + res 7,b ;CB B8 + res 7,c ;CB B9 + res 7,d ;CB BA + res 7,e ;CB BB + res 7,h ;CB BC + res 7,l ;CB BD + ;*********************************************************** + ; return from subroutine + ret ;C9 + ;*********************************************************** + ; return from subroutine if condition is true + ret C ;D8 + ret M ;F8 + ret NC ;D0 + ret NZ ;C0 + ret P ;F0 + ret PE ;E8 + ret PO ;E0 + ret Z ;C8 + ;*********************************************************** + ; return from interrupt + reti ;ED 4D + ;*********************************************************** + ; return from non-maskable interrupt + retn ;ED 45 + ;*********************************************************** + ; rotate left through carry + rl a,(hl) ;CB 16 + rl a,offset(ix) ;DD CB 55 16 + rl a,offset(iy) ;FD CB 55 16 + rl a,a ;CB 17 + rl a,b ;CB 10 + rl a,c ;CB 11 + rl a,d ;CB 12 + rl a,e ;CB 13 + rl a,h ;CB 14 + rl a,l ;CB 15 + ;*********************************************************** + ; rotate left 'a' with carry + rla ;17 + ;*********************************************************** + ; rotate left circular + rlc a,(hl) ;CB 06 + rlc a,offset(ix) ;DD CB 55 06 + rlc a,offset(iy) ;FD CB 55 06 + rlc a,a ;CB 07 + rlc a,b ;CB 00 + rlc a,c ;CB 01 + rlc a,d ;CB 02 + rlc a,e ;CB 03 + rlc a,h ;CB 04 + rlc a,l ;CB 05 + ;*********************************************************** + ; rotate left 'a' circular + rlca ;07 + ;*********************************************************** + ; rotate digit left and right + ; between 'a' and location (hl) + rld ;ED 6F + ;*********************************************************** + ; rotate right through carry + rr a,(hl) ;CB 1E + rr a,offset(ix) ;DD CB 55 1E + rr a,offset(iy) ;FD CB 55 1E + rr a,a ;CB 1F + rr a,b ;CB 18 + rr a,c ;CB 19 + rr a,d ;CB 1A + rr a,e ;CB 1B + rr a,h ;CB 1C + rr a,l ;CB 1D + ;*********************************************************** + ; rotate 'a' right with carry + rra ;1F + ;*********************************************************** + ; rotate right circular + rrc a,(hl) ;CB 0E + rrc a,offset(ix) ;DD CB 55 0E + rrc a,offset(iy) ;FD CB 55 0E + rrc a,a ;CB 0F + rrc a,b ;CB 08 + rrc a,c ;CB 09 + rrc a,d ;CB 0A + rrc a,e ;CB 0B + rrc a,h ;CB 0C + rrc a,l ;CB 0D + ;*********************************************************** + ; rotate 'a' right circular + rrca ;0F + ;*********************************************************** + ; rotate digit right and left + ; between 'a' and location (hl) + rrd ;ED 67 + ;*********************************************************** + ; restart location + rst 0x00 ;C7 + rst 0x08 ;CF + rst 0x10 ;D7 + rst 0x18 ;DF + rst 0x20 ;E7 + rst 0x28 ;EF + rst 0x30 ;F7 + rst 0x38 ;FF + ;*********************************************************** + ; subtract with carry to 'a' + sbc a,(hl) ;9E + sbc a,offset(ix) ;DD 9E 55 + sbc a,offset(iy) ;FD 9E 55 + sbc a,a ;9F + sbc a,b ;98 + sbc a,c ;99 + sbc a,d ;9A + sbc a,e ;9B + sbc a,h ;9C + sbc a,l ;9D + sbc a,#n ;DE 20 + ;*********************************************************** + ; add with carry register pair to 'hl' + sbc hl,bc ;ED 42 + sbc hl,de ;ED 52 + sbc hl,hl ;ED 62 + sbc hl,sp ;ED 72 + ;*********************************************************** + ; set carry flag (C=1) + scf ;37 + ;*********************************************************** + ; set bit of location or register + set 0,(hl) ;CB C6 + set 0,offset(ix) ;DD CB 55 C6 + set 0,offset(iy) ;FD CB 55 C6 + set 0,a ;CB C7 + set 0,b ;CB C0 + set 0,c ;CB C1 + set 0,d ;CB C2 + set 0,e ;CB C3 + set 0,h ;CB C4 + set 0,l ;CB C5 + set 1,(hl) ;CB CE + set 1,offset(ix) ;DD CB 55 CE + set 1,offset(iy) ;FD CB 55 CE + set 1,a ;CB CF + set 1,b ;CB C8 + set 1,c ;CB C9 + set 1,d ;CB CA + set 1,e ;CB CB + set 1,h ;CB CC + set 1,l ;CB CD + set 2,(hl) ;CB D6 + set 2,offset(ix) ;DD CB 55 D6 + set 2,offset(iy) ;FD CB 55 D6 + set 2,a ;CB D7 + set 2,b ;CB D0 + set 2,c ;CB D1 + set 2,d ;CB D2 + set 2,e ;CB D3 + set 2,h ;CB D4 + set 2,l ;CB D5 + set 3,(hl) ;CB DE + set 3,offset(ix) ;DD CB 55 DE + set 3,offset(iy) ;FD CB 55 DE + set 3,a ;CB DF + set 3,b ;CB D8 + set 3,c ;CB D9 + set 3,d ;CB DA + set 3,e ;CB DB + set 3,h ;CB DC + set 3,l ;CB DD + set 4,(hl) ;CB E6 + set 4,offset(ix) ;DD CB 55 E6 + set 4,offset(iy) ;FD CB 55 E6 + set 4,a ;CB E7 + set 4,b ;CB E0 + set 4,c ;CB E1 + set 4,d ;CB E2 + set 4,e ;CB E3 + set 4,h ;CB E4 + set 4,l ;CB E5 + set 5,(hl) ;CB EE + set 5,offset(ix) ;DD CB 55 EE + set 5,offset(iy) ;FD CB 55 EE + set 5,a ;CB EF + set 5,b ;CB E8 + set 5,c ;CB E9 + set 5,d ;CB EA + set 5,e ;CB EB + set 5,h ;CB EC + set 5,l ;CB ED + set 6,(hl) ;CB F6 + set 6,offset(ix) ;DD CB 55 F6 + set 6,offset(iy) ;FD CB 55 F6 + set 6,a ;CB F7 + set 6,b ;CB F0 + set 6,c ;CB F1 + set 6,d ;CB F2 + set 6,e ;CB F3 + set 6,h ;CB F4 + set 6,l ;CB F5 + set 7,(hl) ;CB FE + set 7,offset(ix) ;DD CB 55 FE + set 7,offset(iy) ;FD CB 55 FE + set 7,a ;CB FF + set 7,b ;CB F8 + set 7,c ;CB F9 + set 7,d ;CB FA + set 7,e ;CB FB + set 7,h ;CB FC + set 7,l ;CB FD + ;*********************************************************** + ; shift operand left arithmetic + sla a,(hl) ;CB 26 + sla a,offset(ix) ;DD CB 55 26 + sla a,offset(iy) ;FD CB 55 26 + sla a,a ;CB 27 + sla a,b ;CB 20 + sla a,c ;CB 21 + sla a,d ;CB 22 + sla a,e ;CB 23 + sla a,h ;CB 24 + sla a,l ;CB 25 + ;*********************************************************** + ; shift operand right arithmetic + sra a,(hl) ;CB 2E + sra a,offset(ix) ;DD CB 55 2E + sra a,offset(iy) ;FD CB 55 2E + sra a,a ;CB 2F + sra a,b ;CB 28 + sra a,c ;CB 29 + sra a,d ;CB 2A + sra a,e ;CB 2B + sra a,h ;CB 2C + sra a,l ;CB 2D + ;*********************************************************** + ; shift operand right logical + srl a,(hl) ;CB 3E + srl a,offset(ix) ;DD CB 55 3E + srl a,offset(iy) ;FD CB 55 3E + srl a,a ;CB 3F + srl a,b ;CB 38 + srl a,c ;CB 39 + srl a,d ;CB 3A + srl a,e ;CB 3B + srl a,h ;CB 3C + srl a,l ;CB 3D + ;*********************************************************** + ; subtract operand from 'a' + sub a,(hl) ;96 + sub a,offset(ix) ;DD 96 55 + sub a,offset(iy) ;FD 96 55 + sub a,a ;97 + sub a,b ;90 + sub a,c ;91 + sub a,d ;92 + sub a,e ;93 + sub a,h ;94 + sub a,l ;95 + sub a,#n ;D6 20 + ;*********************************************************** + ; logical 'xor' operand with 'a' + xor a,(hl) ;AE + xor a,offset(ix) ;DD AE 55 + xor a,offset(iy) ;FD AE 55 + xor a,a ;AF + xor a,b ;A8 + xor a,c ;A9 + xor a,d ;AA + xor a,e ;AB + xor a,h ;AC + xor a,l ;AD + xor a,#n ;EE 20 + + .page + ;*********************************************************** + ; Hitachi HD64180 Codes + ;*********************************************************** + + .hd64 + + ;*********************************************************** + ; load register with input from port (n) + in0 a,(n) ;ED 38 20 + in0 b,(n) ;ED 00 20 + in0 c,(n) ;ED 08 20 + in0 d,(n) ;ED 10 20 + in0 e,(n) ;ED 18 20 + in0 h,(n) ;ED 20 20 + in0 l,(n) ;ED 28 20 + ;*********************************************************** + ; multiplication of each half + ; of the specified register pair + ; with the 16-bit result going to + ; the specified register pair + mlt bc ;ED 4C + mlt de ;ED 5C + mlt hl ;ED 6C + mlt sp ;ED 7C + ;*********************************************************** + ; load output port (c) with + ; location (hl), + ; decrement hl and b + ; decrement c + otdm ;ED 8B + ;*********************************************************** + ; load output port (c) with + ; location (hl), + ; decrement hl and c + ; decrement b + ; repeat until b = 0 + otdmr ;ED 9B + ;*********************************************************** + ; load output port (c) with + ; location (hl), + ; increment hl and b + ; decrement c + otim ;ED 83 + ;*********************************************************** + ; load output port (c) with + ; location (hl), + ; increment hl and c + ; decrement b + ; repeat until b = 0 + otimr ;ED 93 + ;*********************************************************** + ; load output port (n) from register + out0 (n),a ;ED 39 20 + out0 (n),b ;ED 01 20 + out0 (n),c ;ED 09 20 + out0 (n),d ;ED 11 20 + out0 (n),e ;ED 19 20 + out0 (n),h ;ED 21 20 + out0 (n),l ;ED 29 20 + ;*********************************************************** + ; enter sleep mode + slp ;ED 76 + ;*********************************************************** + ; non-destructive'and' with accumulator and specified operand + tst a ;ED 3C + tst b ;ED 04 + tst c ;ED 0C + tst d ;ED 14 + tst e ;ED 1C + tst h ;ED 24 + tst l ;ED 2C + tst #n ;ED 64 20 + tst (hl) ;ED 34 + ;*********************************************************** + ; non-destructive 'and' of n and the contents of port (c) + tstio #n ;ED 74 20 + ;*********************************************************** + diff --git a/src/as-z80/tz80l.asm b/src/as-z80/tz80l.asm new file mode 100755 index 00000000..92057542 --- /dev/null +++ b/src/as-z80/tz80l.asm @@ -0,0 +1,47 @@ + .sbttl Assembler Link Tests + + .module tz80l + + ; This file and TCONST.ASM should be assembled and linked. + ; + ; ASZ80 -XGOL TZ80L + ; ASZ80 -XGOL TCONST + ; + ; ASLINK -C + ; -XMS + ; TZ80L + ; TCONST + ; -E + ; + ; The following tests verify the correct processing of + ; external references for the branches. + ; + ; *L signifies an error will be reported at link time. + + ; branch test must be first + + .area TEST (ABS,OVR) + + .blkb 0x7E ;bra1: + jr C,bra1 ; 38 00 [38 80] + .blkb 0x7F ;bra2: + jr C,bra2 ;*L 38 00 [38 7F] + jr C,bra3 ; 38 00 [38 7F] + .blkb 0x7F + .blkb 0x00 ;bra3: + jr C,bra4 ;*L 38 00 [38 [80] + .blkb 0x80 + .blkb 0x00 ;bra4: + + .blkb 0x7E ;bra5: + jr C,bra5 ; 38 00 [38 80] + .blkb 0x7F ;bra6: + jr C,bra6 ;*L 38 00 [38 7F] + jr C,bra7 ; 38 00 [38 7F] + .blkb 0x7F + .blkb 0x00 ;bra7: + jr C,bra8 ;*L 38 00 [38 [80] + .blkb 0x80 + .blkb 0x00 ;bra8: + + diff --git a/src/as-z80/z80.h b/src/as-z80/z80.h new file mode 100755 index 00000000..96fb9668 --- /dev/null +++ b/src/as-z80/z80.h @@ -0,0 +1,185 @@ +/* z80.h */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +/*)BUILD + $(PROGRAM) = ASZ80 + $(INCLUDE) = { + ASXXXX.H + Z80.H + } + $(FILES) = { + Z80EXT.C + Z80MCH.C + Z80ADR.C + Z80PST.C + ASMAIN.C + ASLEX.C + ASSYM.C + ASSUBR.C + ASEXPR.C + ASDATA.C + ASLIST.C + ASOUT.C + } + $(STACK) = 3000 +*/ + +/* + * Indirect Addressing delimeters + */ +#define LFIND '(' +#define RTIND ')' + +/* + * Registers + */ +#define B 0 +#define C 1 +#define D 2 +#define E 3 +#define H 4 +#define L 5 +#define A 7 + +#define I 0107 +#define R 0117 + +#define BC 0 +#define DE 1 +#define HL 2 +#define SP 3 +#define AF 4 +#define IX 5 +#define IY 6 + +/* + * Conditional definitions + */ +#define NZ 0 +#define Z 1 +#define NC 2 +#define CS 3 +#define PO 4 +#define PE 5 +#define P 6 +#define M 7 + +/* + * Symbol types + */ +#define S_IMMED 30 +#define S_R8 31 +#define S_R8X 32 +#define S_R16 33 +#define S_R16X 34 +#define S_CND 35 +#define S_FLAG 36 + +/* + * Indexing modes + */ +#define S_INDB 40 +#define S_IDC 41 +#define S_INDR 50 +#define S_IDBC 50 +#define S_IDDE 51 +#define S_IDHL 52 +#define S_IDSP 53 +#define S_IDIX 55 +#define S_IDIY 56 +#define S_INDM 57 + +/* + * Instruction types + */ +#define S_LD 60 +#define S_CALL 61 +#define S_JP 62 +#define S_JR 63 +#define S_RET 64 +#define S_BIT 65 +#define S_INC 66 +#define S_DEC 67 +#define S_ADD 68 +#define S_ADC 69 +#define S_AND 70 +#define S_EX 71 +#define S_PUSH 72 +#define S_IN 73 +#define S_OUT 74 +#define S_RL 75 +#define S_RST 76 +#define S_IM 77 +#define S_INH1 78 +#define S_INH2 79 +#define S_DJNZ 80 +#define S_SUB 81 +#define S_SBC 82 + +/* + * HD64180 Instructions + */ +#define X_HD64 90 +#define X_INH2 91 +#define X_IN 92 +#define X_OUT 93 +#define X_MLT 94 +#define X_TST 95 +#define X_TSTIO 96 + +struct adsym +{ + char a_str[4]; /* addressing string */ + int a_val; /* addressing mode value */ +}; + +extern struct adsym R8[]; +extern struct adsym R8X[]; +extern struct adsym R16[]; +extern struct adsym R16X[]; +extern struct adsym CND[]; + + /* machine dependent functions */ + +#ifdef OTHERSYSTEM + + /* z80adr.c */ +extern int addr(struct expr *esp); +extern int admode(struct adsym *sp); +extern int any(int c, char *str); +extern int srch(char *str); + + /* z80mch.c */ +extern int comma(void); +extern int genop(int pop, int op, struct expr *esp, int f); +extern int gixiy(int v); +extern VOID machine(struct mne *mp); +extern int mchpcr(struct expr *esp); +extern VOID minit(void); + +#else + + /* z80adr.c */ +extern int addr(); +extern int admode(); +extern int any(); +extern int srch(); + + /* z80mch.c */ +extern int comma(); +extern int genop(); +extern int gixiy(); +extern VOID machine(); +extern int mchpcr(); +extern VOID minit(); + +#endif + diff --git a/src/as-z80/z80adr.c b/src/as-z80/z80adr.c new file mode 100755 index 00000000..b9e7b9b7 --- /dev/null +++ b/src/as-z80/z80adr.c @@ -0,0 +1,247 @@ +/* z80adr.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include +#include "asxxxx.h" +#include "z80.h" + +/* + * Read an address specifier. Pack the + * address information into the supplied + * `expr' structure. Return the mode of + * the address. + * + * This addr(esp) routine performs the following addressing decoding: + * + * address mode flag addr base + * #n S_IMMED 0 n NULL + * label s_type ---- s_addr s_area + * [REG] S_IND+icode 0 0 NULL + * [label] S_INDM ---- s_addr s_area + * offset[REG] S_IND+icode ---- offset ---- + */ +int +addr(esp) +register struct expr *esp; +{ + register int c, mode, indx; + + if ((c = getnb()) == '#') { + expr(esp, 0); + esp->e_mode = S_IMMED; + } else + if (c == LFIND) { + if ((indx = admode(R8)) != 0) { + mode = S_INDB; + } else + if ((indx = admode(R16)) != 0) { + mode = S_INDR; +#if 1 /* Nick has added this to process addressing modes eg. (ix+2) */ + if ((indx&0xff)==IX || (indx&0xff)==IY) { + if ((c = getnb()) != RTIND) { + unget(c); + expr(esp, 0); + /* the following is experimental */ + esp->e_mode = (mode + indx)&0xff; + goto silly_silly; + } else { + unget(c); + } + } +#endif + } else + if ((indx = admode(R8X)) != 0) { + mode = S_R8X; + aerr(); + } else + if ((indx = admode(R16X)) != 0) { + mode = S_R16X; + aerr(); + } else { + mode = S_INDM; + expr(esp, 0); + esp->e_mode = mode; + } + if (indx) { + esp->e_mode = mode + (indx&0xFF); + esp->e_base.e_ap = NULL; + } +#if 1 /* Nick's experiment to avoid setting esp->e_base.e_ap = NULL above */ + silly_silly: +#endif + if ((c = getnb()) != RTIND) + qerr(); + } else { + unget(c); + if ((indx = admode(R8)) != 0) { + mode = S_R8; + } else + if ((indx = admode(R16)) != 0) { + mode = S_R16; + } else + if ((indx = admode(R8X)) != 0) { + mode = S_R8X; + } else + if ((indx = admode(R16X)) != 0) { + mode = S_R16X; + } else { + mode = S_USER; + expr(esp, 0); + esp->e_mode = mode; + } + if (indx) { + esp->e_addr = indx&0xFF; + esp->e_mode = mode; + esp->e_base.e_ap = NULL; + } + if ((c = getnb()) == LFIND) { + if ((indx=admode(R16))!=0 + && ((indx&0xFF)==IX || (indx&0xFF)==IY)) { + esp->e_mode = S_INDR + (indx&0xFF); + } else { + aerr(); + } + if ((c = getnb()) != RTIND) + qerr(); + } else { + unget(c); + } + } + return (esp->e_mode); +} + +/* + * Enter admode() to search a specific addressing mode table + * for a match. Return the addressing value on a match or + * zero for no match. + */ +int +admode(sp) +register struct adsym *sp; +{ + register char *ptr; + register int i; + register char *ips; + + ips = ip; + unget(getnb()); + + i = 0; + while ( *(ptr = &sp[i].a_str[0]) ) { + if (srch(ptr)) { + return(sp[i].a_val); + } + i++; + } + ip = ips; + return(0); +} + +/* + * srch --- does string match ? + */ +int +srch(str) +register char *str; +{ + register char *ptr; + ptr = ip; + + while (*ptr && *str) { + if (ccase[*ptr & 0x007F] != ccase[*str & 0x007F]) + break; + ptr++; + str++; + } + if (ccase[*ptr & 0x007F] == ccase[*str & 0x007F]) { + ip = ptr; + return(1); + } + + if (!*str) +#if 1 /* Nick */ + if (any(*ptr," \t\n,);+-")) { +#else + if (any(*ptr," \t\n,);")) { +#endif + ip = ptr; + return(1); + } + return(0); +} + +/* + * any --- does str contain c? + */ +int +any(c,str) +int c; +char *str; +{ + while (*str) + if(*str++ == c) + return(1); + return(0); +} + +/* + * Registers + */ + +struct adsym R8[] = { + { "b", B|0400 }, + { "c", C|0400 }, + { "d", D|0400 }, + { "e", E|0400 }, + { "h", H|0400 }, + { "l", L|0400 }, + { "a", A|0400 }, + { "", 0000 } +}; + +struct adsym R8X[] = { + { "i", I|0400 }, + { "r", R|0400 }, + { "", 0000 } +}; + +struct adsym R16[] = { + { "bc", BC|0400 }, + { "de", DE|0400 }, + { "hl", HL|0400 }, + { "sp", SP|0400 }, + { "ix", IX|0400 }, + { "iy", IY|0400 }, + { "", 0000 } +}; + +struct adsym R16X[] = { + { "af", AF|0400 }, + { "af'", AF|0400 }, + { "", 0000 } +}; + +/* + * Conditional definitions + */ + +struct adsym CND[] = { + { "NZ", NZ|0400 }, + { "Z", Z |0400 }, + { "NC", NC|0400 }, + { "C", CS|0400 }, + { "PO", PO|0400 }, + { "PE", PE|0400 }, + { "P", P |0400 }, + { "M", M |0400 }, + { "", 0000 } +}; diff --git a/src/as-z80/z80ext.c b/src/as-z80/z80ext.c new file mode 100755 index 00000000..7694e794 --- /dev/null +++ b/src/as-z80/z80ext.c @@ -0,0 +1,19 @@ +/* z80ext.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include +#include "asxxxx.h" +#include "z80.h" + +char *cpu = "Zilog Z80 / Hitachi HD64180"; +int hilo = 0; +char *dsft = "asm"; diff --git a/src/as-z80/z80mch.c b/src/as-z80/z80mch.c new file mode 100755 index 00000000..b6009d09 --- /dev/null +++ b/src/as-z80/z80mch.c @@ -0,0 +1,761 @@ +/* z80mch.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include +#include "asxxxx.h" +#include "z80.h" + +char imtab[3] = { 0x46, 0x56, 0x5E }; +int hd64; + +/* + * Process a machine op. + */ +VOID +machine(mp) +struct mne *mp; +{ + register int op, t1, t2; + struct expr e1, e2; + int rf, v1, v2; +#if 1 /* Nick */ + int c; +#endif + + clrexpr(&e1); + clrexpr(&e2); + op = mp->m_valu; + rf = mp->m_type; + if (!hd64 && rf>X_HD64) + rf = 0; + switch (rf) { + + case S_INH1: + outab(op); + break; + + case S_INH2: + outab(0xED); + outab(op); + break; + + case S_RET: + if (more()) { + if ((v1 = admode(CND)) != 0) { + outab(op | v1<<3); + } else { + qerr(); + } + } else { + outab(0xC9); + } + break; + + case S_PUSH: + if (admode(R16X)) { + outab(op+0x30); + break; + } else + if ((v1 = admode(R16)) != 0 && (v1 &= 0xFF) != SP) { + if (v1 != gixiy(v1)) { + outab(op+0x20); + break; + } + outab(op | v1<<4); + break; + } + aerr(); + break; + + case S_RST: + v1 = absexpr(); + if (v1 & ~0x38) { + aerr(); + v1 = 0; + } + outab(op|v1); + break; + + case S_IM: + expr(&e1, 0); + abscheck(&e1); + if (e1.e_addr > 2) { + aerr(); + e1.e_addr = 0; + } + outab(op); + outab(imtab[e1.e_addr]); + break; + + case S_BIT: + expr(&e1, 0); + t1 = 0; + v1 = e1.e_addr; + if (v1 > 7) { + ++t1; + v1 &= 0x07; + } + op |= (v1<<3); + comma(); + addr(&e2); + abscheck(&e1); + if (genop(0xCB, op, &e2, 0) || t1) + aerr(); + break; + + case S_RL: + t1 = 0; + t2 = addr(&e2); + if (more()) { + if ((t2 != S_R8) || (e2.e_addr != A)) + ++t1; + comma(); + t2 = addr(&e2); + } + if (genop(0xCB, op, &e2, 0) || t1) + aerr(); + break; + + case S_AND: + case S_SUB: + t1 = 0; + t2 = addr(&e2); + if (more()) { + if ((t2 != S_R8) || (e2.e_addr != A)) + ++t1; + comma(); + t2 = addr(&e2); + } + if (genop(0, op, &e2, 1) || t1) + aerr(); + break; + + case S_ADD: + case S_ADC: + case S_SBC: + t1 = addr(&e1); + t2 = 0; + if (more()) { + comma(); + t2 = addr(&e2); + } + if (t2 == 0) { + if (genop(0, op, &e1, 1)) + aerr(); + break; + } + if ((t1 == S_R8) && (e1.e_addr == A)) { + if (genop(0, op, &e2, 1)) + aerr(); + break; + } + if ((t1 == S_R16) && (t2 == S_R16)) { + if (rf == S_ADD) + op = 0x09; + if (rf == S_ADC) + op = 0x4A; + if (rf == S_SBC) + op = 0x42; + v1 = e1.e_addr; + v2 = e2.e_addr; + if ((v1 == HL) && (v2 <= SP)) { + if (rf != S_ADD) + outab(0xED); + outab(op | (v2<<4)); + break; + } + if (rf != S_ADD) { + aerr(); + break; + } + if ((v1 == IX) && (v2 != HL) && (v2 != IY)) { + if (v2 == IX) + v2 = HL; + outab(0xDD); + outab(op | (v2<<4)); + break; + } + if ((v1 == IY) && (v2 != HL) && (v2 != IX)) { + if (v2 == IY) + v2 = HL; + outab(0xFD); + outab(op | (v2<<4)); + break; + } + } + aerr(); + break; + + case S_LD: + t1 = addr(&e1); + comma(); + t2 = addr(&e2); + if (t1 == S_R8) { + v1 = op | e1.e_addr<<3; + if (genop(0, v1, &e2, 0) == 0) + break; +#if 1 /* Nick, so that constants don't need # prefix */ + if (t2 == S_IMMED || t2 == S_USER) { +#else + if (t2 == S_IMMED) { +#endif + outab(e1.e_addr<<3 | 0x06); + outrb(&e2,0); + break; + } + } + v1 = e1.e_addr; + v2 = e2.e_addr; +#if 1 /* Nick, so that constants don't need # prefix */ + if ((t1 == S_R16) && (t2 == S_IMMED || t2 == S_USER)) { +#else + if ((t1 == S_R16) && (t2 == S_IMMED)) { +#endif + v1 = gixiy(v1); + outab(0x01|v1<<4); + outrw(&e2, 0); + break; + } + if ((t1 == S_R16) && (t2 == S_INDM)) { + if (gixiy(v1) == HL) { + outab(0x2A); + } else { + outab(0xED); + outab(0x4B | v1<<4); + } + outrw(&e2, 0); + break; + } + if ((t1 == S_INDM) && (t2 == S_R16)) { + if (gixiy(v2) == HL) { + outab(0x22); + } else { + outab(0xED); + outab(0x43 | v2<<4); + } + outrw(&e1, 0); + break; + } + if ((t1 == S_R8) && (v1 == A) && (t2 == S_INDM)) { + outab(0x3A); + outrw(&e2, 0); + break; + } + if ((t1 == S_INDM) && (t2 == S_R8) && (v2 == A)) { + outab(0x32); + outrw(&e1, 0); + break; + } + if ((t2 == S_R8) && (gixiy(t1) == S_IDHL)) { + outab(0x70|v2); + if (t1 != S_IDHL) + outrb(&e1, 0); + break; + } +#if 1 /* Nick, so that constants don't need # prefix */ + if ((t2 == S_IMMED || t2 == S_USER) && (gixiy(t1) == S_IDHL)) { +#else + if ((t2 == S_IMMED) && (gixiy(t1) == S_IDHL)) { +#endif + outab(0x36); + if (t1 != S_IDHL) + outrb(&e1, 0); + outrb(&e2, 0); + break; + } + if ((t1 == S_R8X) && (t2 == S_R8) && (v2 == A)) { + outab(0xED); + outab(v1); + break; + } + if ((t1 == S_R8) && (v1 == A) && (t2 == S_R8X)) { + outab(0xED); + outab(v2|0x10); + break; + } + if ((t1 == S_R16) && (v1 == SP)) { + if ((t2 == S_R16) && (gixiy(v2) == HL)) { + outab(0xF9); + break; + } + } + if ((t1 == S_R8) && (v1 == A)) { + if ((t2 == S_IDBC) || (t2 == S_IDDE)) { + outab(0x0A | (t2-S_INDR)<<4); + break; + } + } + if ((t2 == S_R8) && (v2 == A)) { + if ((t1 == S_IDBC) || (t1 == S_IDDE)) { + outab(0x02 | (t1-S_INDR)<<4); + break; + } + } + aerr(); + break; + + + case S_EX: + t1 = addr(&e1); + comma(); + t2 = addr(&e2); + if (t2 == S_R16) { + v1 = e1.e_addr; + v2 = e2.e_addr; + if ((t1 == S_IDSP) && (v1 == 0)) { + if (gixiy(v2) == HL) { + outab(op); + break; + } + } + if (t1 == S_R16) { + if ((v1 == DE) && (v2 == HL)) { + outab(0xEB); + break; + } + } + } + if ((t1 == S_R16X) && (t2 == S_R16X)) { + outab(0x08); + break; + } + aerr(); + break; + +#if 1 /* Nick */ + case S_IN: + t1 = addr(&e1); +#if 1 /* allow "in0 (nn)" which only affects the flags */ + c = getnb(); + if (c != ',') + { + if (t1 == S_IDC) + { + unget(c); /* to detect trailing garbage */ + outab(0xED); + outab(0x70); + break; + } + qerr(); /* see comma() function */ + } +#else + comma(); +#endif + t2 = addr(&e2); + if (t1 == S_R8) { + v1 = e1.e_addr; + if ((v1 == A) && (t2 == S_INDM)) { + v2 = e2.e_addr; + outab(op); + outab(v2); + break; + } + if (t2 == S_IDC) { + outab(0xED); + outab(0x40|(v1<<3)); + break; + } + } + aerr(); + break; + + case S_OUT: + t2 = addr(&e2); + comma(); + t1 = addr(&e1); + if (t1 == S_R8) { + v1 = e1.e_addr; + if ((v1 == A) && (t2 == S_INDM)) { + v2 = e2.e_addr; + outab(op); + outab(v2); + break; + } + if (t2 == S_IDC) { + outab(0xED); + outab(0x41|(v1<<3)); + break; + } + } + aerr(); + break; +#else + case S_IN: + case S_OUT: + if (rf == S_IN) { + t1 = addr(&e1); + comma(); + t2 = addr(&e2); + } else { + t2 = addr(&e2); + comma(); + t1 = addr(&e1); + } + v1 = e1.e_addr; + v2 = e2.e_addr; + if (t1 == S_R8) { + if ((v1 == A) && (t2 == S_INDM)) { + outab(op); + outab(v2); + break; + } + if (t2 == S_IDC) { + outab(0xED); + outab(((rf == S_IN) ? 0x40 : 0x41) + (v1<<3)); + break; + } + } + aerr(); + break; +#endif + + case S_DEC: + case S_INC: + t1 = addr(&e1); + v1 = e1.e_addr; + if (t1 == S_R8) { + outab(op|(v1<<3)); + break; + } + if (t1 == S_IDHL) { + outab(op|0x30); + break; + } + if (t1 != gixiy(t1)) { + outab(op|0x30); + outrb(&e1,0); + break; + } + if (t1 == S_R16) { + v1 = gixiy(v1); + if (rf == S_INC) { + outab(0x03|(v1<<4)); + break; + } + if (rf == S_DEC) { + outab(0x0B|(v1<<4)); + break; + } + } + aerr(); + break; + + case S_DJNZ: + case S_JR: + if ((v1 = admode(CND)) != 0 && rf != S_DJNZ) { + if ((v1 &= 0xFF) <= 0x18) { + op += (v1+1)<<3; + } else { + aerr(); + } + comma(); + } + expr(&e2, 0); + outab(op); + if (mchpcr(&e2)) { + v2 = e2.e_addr - dot.s_addr - 1; + if ((v2 < -128) || (v2 > 127)) + aerr(); + outab(v2); + } else { + outrb(&e2, R_PCR); + } + if (e2.e_mode != S_USER) + rerr(); + break; + + case S_CALL: + if ((v1 = admode(CND)) != 0) { + op |= (v1&0xFF)<<3; + comma(); + } else { + op = 0xCD; + } + expr(&e1, 0); + outab(op); + outrw(&e1, 0); + break; + + case S_JP: + if ((v1 = admode(CND)) != 0) { + op |= (v1&0xFF)<<3; + comma(); + expr(&e1, 0); + outab(op); + outrw(&e1, 0); + break; + } + t1 = addr(&e1); + if (t1 == S_USER) { + outab(0xC3); + outrw(&e1, 0); + break; + } + if ((e1.e_addr == 0) && (gixiy(t1) == S_IDHL)) { + outab(0xE9); + break; + } + aerr(); + break; + + case X_HD64: + ++hd64; + break; + + case X_INH2: + outab(0xED); + outab(op); + break; + +#if 1 /* Nick */ + case X_IN: + t1 = addr(&e1); +#if 1 /* allow "in0 (nn)" which only affects the flags */ + c = getnb(); + if (c != ',') + { + if (t1 == S_INDM) + { + unget(c); /* to detect trailing garbage */ + outab(0xED); + outab(op|(0x06<<3)); + outrb(&e1, 0); + break; + } + qerr(); /* see comma() function */ + } +#else + comma(); +#endif + t2 = addr(&e2); + if ((t1 == S_R8) && (t2 == S_INDM)) + { + v1 = e1.e_addr; + outab(0xED); + outab(op|(v1<<3)); + outrb(&e2, 0); + break; + } + aerr(); + break; + + case X_OUT: + t2 = addr(&e2); + comma(); + t1 = addr(&e1); + if ((t1 == S_R8) && (t2 == S_INDM)) { + v1 = e1.e_addr; + outab(0xED); + outab(op|(v1<<3)); + outrb(&e2, 0); + break; + } + aerr(); + break; +#else + case X_IN: + case X_OUT: + if (rf == X_IN) { + t1 = addr(&e1); + comma(); + t2 = addr(&e2); + } else { + t2 = addr(&e2); + comma(); + t1 = addr(&e1); + } + if ((t1 == S_R8) && (t2 == S_INDM)) { + outab(0xED); + outab(op | e1.e_addr<<3); + outrb(&e2, 0); + break; + } + aerr(); + break; +#endif + + case X_MLT: + t1 = addr(&e1); + if ((t1 == S_R16) && ((v1 = e1.e_addr) <= SP)) { + outab(0xED); + outab(op | v1<<4); + break; + } + aerr(); + break; + + case X_TST: + t1 = addr(&e1); + if (t1 == S_R8) { + outab(0xED); + outab(op | e1.e_addr<<3); + break; + } + if (t1 == S_IDHL) { + outab(0xED); + outab(0x34); + break; + } +#if 1 /* Nick, so that constants don't need # prefix */ + if (t1 == S_IMMED || t1 == S_USER) { +#else + if (t1 == S_IMMED) { +#endif + outab(0xED); + outab(0x64); + outrb(&e1, 0); + break; + } + aerr(); + break; + + case X_TSTIO: + t1 = addr(&e1); +#if 1 /* Nick, so that constants don't need # prefix */ + if (t1 == S_IMMED || t1 == S_USER) { +#else + if (t1 == S_IMMED) { +#endif + outab(0xED); + outab(op); + outrb(&e1, 0); + break; + } + aerr(); + break; + + default: + err('o'); + } +} + +/* + * general addressing evaluation + * return(0) if general addressing mode output, else + * return(esp->e_mode) + */ +int +genop(pop, op, esp, f) +register int pop, op; +register struct expr *esp; +int f; +{ + register int t1; + if ((t1 = esp->e_mode) == S_R8) { + if (pop) + outab(pop); + outab(op|esp->e_addr); + return(0); + } + if (t1 == S_IDHL) { + if (pop) + outab(pop); + outab(op|0x06); + return(0); + } + if (gixiy(t1) == S_IDHL) { + if (pop) { + outab(pop); + outrb(esp,0); + outab(op|0x06); + } else { + outab(op|0x06); + outrb(esp,0); + } + return(0); + } +#if 1 /* Nick, so that constants don't need # prefix */ + if ((t1 == S_IMMED || t1 == S_USER) && (f)) { +#else + if ((t1 == S_IMMED) && (f)) { +#endif + if (pop) + outab(pop); + outab(op|0x46); + outrb(esp,0); + return(0); + } + return(t1); +} + +/* + * IX and IY prebyte check + */ +int +gixiy(v) +int v; +{ + if (v == IX) { + v = HL; + outab(0xDD); + } else if (v == IY) { + v = HL; + outab(0xFD); + } else if (v == S_IDIX) { + v = S_IDHL; + outab(0xDD); + } else if (v == S_IDIY) { + v = S_IDHL; + outab(0xFD); + } + return(v); +} + +/* + * Branch/Jump PCR Mode Check + */ +int +mchpcr(esp) +register struct expr *esp; +{ + if (esp->e_base.e_ap == dot.s_area) { + return(1); + } + if (esp->e_flag==0 && esp->e_base.e_ap==NULL) { + /* + * Absolute Destination + * + * Use the global symbol '.__.ABS.' + * of value zero and force the assembler + * to use this absolute constant as the + * base value for the relocation. + */ + esp->e_flag = 1; + esp->e_base.e_sp = &sym[1]; + } + return(0); +} + +/* + * The next character must be a + * comma. + */ +int +comma() +{ + if (getnb() != ',') + qerr(); + return(1); +} + +/* + * Machine dependent initialization + */ +VOID +minit() +{ +#if 1 /* Nick, for IAR compatibility */ + hd64 = 1; +#else + hd64 = 0; +#endif +} diff --git a/src/as-z80/z80pst.c b/src/as-z80/z80pst.c new file mode 100755 index 00000000..80a82971 --- /dev/null +++ b/src/as-z80/z80pst.c @@ -0,0 +1,260 @@ +/* z80pst.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +/* + * Extensions: P. Felber + */ + +#include +#include +#include "asxxxx.h" +#include "z80.h" + +struct mne mne[] = { + + /* machine */ + + /* system */ + + { NULL, "CON", S_ATYP, 0, A_CON }, + { NULL, "OVR", S_ATYP, 0, A_OVR }, + { NULL, "NUL", S_ATYP, 0, A_NUL }, /* Nick */ + { NULL, "REL", S_ATYP, 0, A_REL }, + { NULL, "ABS", S_ATYP, 0, A_ABS|A_OVR }, + { NULL, "NOPAG", S_ATYP, 0, A_NOPAG }, + { NULL, "PAG", S_ATYP, 0, A_PAG }, + + { NULL, ".assume", S_ERROR, 0, 0 }, + { NULL, "assume", S_ERROR, 0, 0 }, /* Nick */ + { NULL, ".error", S_ERROR, 0, 1 }, + { NULL, "error", S_ERROR, 0, 1 }, /* Nick */ + + { NULL, ".end", S_END, 0, 0 }, /* Nick */ + { NULL, "end", S_END, 0, 0 }, /* Nick */ + + { NULL, ".equ", S_EQU, 0, 0 }, /* Nick */ + { NULL, "equ", S_EQU, 0, 0 }, /* Nick */ + { NULL, "defl", S_EQU, 0, 0 }, /* Nick */ + + { NULL, ".byte", S_DATA, 0, 1 }, + { NULL, ".db", S_DATA, 0, 1 }, + { NULL, "db", S_DATA, 0, 1 }, /* Nick */ + { NULL, "defb", S_DATA, 0, 1 }, /* Nick */ + { NULL, "defm", S_DATA, 0, 1 }, /* Nick */ + + { NULL, ".word", S_DATA, 0, 2 }, + { NULL, ".dw", S_DATA, 0, 2 }, + { NULL, "dw", S_DATA, 0, 2 }, /* Nick */ + { NULL, "defw", S_DATA, 0, 2 }, /* Nick */ + + { NULL, ".3byte", S_DATA, 0, 3 }, /* Nick */ + { NULL, ".da", S_DATA, 0, 3 }, /* Nick */ + { NULL, "da", S_DATA, 0, 3 }, /* Nick */ + { NULL, "defa", S_DATA, 0, 3 }, /* Nick */ + + { NULL, ".4byte", S_DATA, 0, 4 }, /* Nick */ + { NULL, ".dd", S_DATA, 0, 4 }, /* Nick */ + { NULL, "dd", S_DATA, 0, 4 }, /* Nick */ + { NULL, "defd", S_DATA, 0, 4 }, /* Nick */ + +#if 0 /* Nick */ + { NULL, ".df", S_FLOAT, 0, 0 }, + { NULL, "df", S_FLOAT, 0, 0 }, /* Nick */ +#endif + + { NULL, ".ascii", S_ASCII, 0, 0 }, + { NULL, ".asciz", S_ASCIZ, 0, 0 }, + { NULL, ".ascis", S_ASCIS, 0, 0 }, + + { NULL, ".blkb", S_BLK, 0, 1 }, + { NULL, ".ds", S_BLK, 0, 1 }, + { NULL, "ds", S_BLK, 0, 1 }, /* Nick */ + { NULL, "defs", S_BLK, 0, 1 }, /* Nick */ + + { NULL, ".blkw", S_BLK, 0, 2 }, + + { NULL, ".page", S_PAGE, 0, 0 }, + { NULL, "page", S_PAGE, 0, 0 }, /* Nick */ + + { NULL, ".title", S_TITLE, 0, 0 }, + { NULL, "title", S_TITLE, 0, 0 }, /* Nick */ + + { NULL, ".sbttl", S_SBTL, 0, 0 }, + { NULL, "sbttl", S_SBTL, 0, 0 }, /* Nick */ + + { NULL, ".globl", S_GLOBL, 0, 0 }, + { NULL, "extern", S_GLOBL, 0, 0 }, /* Nick */ + { NULL, "public", S_GLOBL, 0, 0 }, /* Nick */ + + { NULL, ".area", S_DAREA, 0, 0 }, + { NULL, "rseg", S_DAREA, 0, 0 }, /* Nick */ + { NULL, "common", S_DAREA, 0, 0 }, /* Nick */ + + { NULL, ".even", S_EVEN, 0, 0 }, + { NULL, "even", S_EVEN, 0, 0 }, /* Nick */ + + { NULL, ".odd", S_ODD, 0, 0 }, + { NULL, "odd", S_ODD, 0, 0 }, /* Nick */ + + { NULL, ".if", S_IF, 0, 0 }, + { NULL, "if", S_IF, 0, 0 }, /* Nick */ + + { NULL, ".else", S_ELSE, 0, 0 }, + { NULL, "else", S_ELSE, 0, 0 }, /* Nick */ + + { NULL, ".endif", S_ENDIF, 0, 0 }, + { NULL, "endif", S_ENDIF, 0, 0 }, /* Nick */ + + { NULL, ".include", S_INCL, 0, 0 }, + { NULL, "include", S_INCL, 0, 0 }, /* Nick */ + { NULL, "$", S_INCL, 0, 0 }, /* Nick */ + + { NULL, ".radix", S_RADIX, 0, 0 }, + { NULL, "radix", S_RADIX, 0, 0 }, /* Nick */ + + { NULL, ".org", S_ORG, 0, 0 }, + { NULL, "org", S_ORG, 0, 0 }, /* Nick */ + + { NULL, ".module", S_MODUL, 0, 0 }, + { NULL, "module", S_MODUL, 0, 0 }, /* Nick */ + { NULL, "name", S_MODUL, 0, 0 }, /* Nick */ + + { NULL, ".endmod", S_ENDMOD, 0, 0 }, /* Nick */ + { NULL, "endmod", S_ENDMOD, 0, 0 }, /* Nick */ + + /* z80 / hd64180 */ + + { NULL, "ld", S_LD, 0, 0x40 }, + + { NULL, "call", S_CALL, 0, 0xC4 }, + { NULL, "jp", S_JP, 0, 0xC2 }, + { NULL, "jr", S_JR, 0, 0x18 }, +#ifndef GAMEBOY + { NULL, "djnz", S_DJNZ, 0, 0x10 }, +#endif /* GAMEBOY */ + { NULL, "ret", S_RET, 0, 0xC0 }, + + { NULL, "bit", S_BIT, 0, 0x40 }, + { NULL, "res", S_BIT, 0, 0x80 }, + { NULL, "set", S_BIT, 0, 0xC0 }, + + { NULL, "inc", S_INC, 0, 0x04 }, + { NULL, "dec", S_DEC, 0, 0x05 }, + + { NULL, "add", S_ADD, 0, 0x80 }, + { NULL, "adc", S_ADC, 0, 0x88 }, + { NULL, "sub", S_SUB, 0, 0x90 }, + { NULL, "sbc", S_SBC, 0, 0x98 }, + + { NULL, "and", S_AND, 0, 0xA0 }, + { NULL, "cp", S_AND, 0, 0xB8 }, + { NULL, "or", S_AND, 0, 0xB0 }, + { NULL, "xor", S_AND, 0, 0xA8 }, + +#ifndef GAMEBOY + { NULL, "ex", S_EX, 0, 0xE3 }, +#endif /* GAMEBOY */ + + { NULL, "push", S_PUSH, 0, 0xC5 }, + { NULL, "pop", S_PUSH, 0, 0xC1 }, + +#ifndef GAMEBOY + { NULL, "in", S_IN, 0, 0xDB }, + { NULL, "out", S_OUT, 0, 0xD3 }, +#endif /* GAMEBOY */ + + { NULL, "rl", S_RL, 0, 0x10 }, + { NULL, "rlc", S_RL, 0, 0x00 }, + { NULL, "rr", S_RL, 0, 0x18 }, + { NULL, "rrc", S_RL, 0, 0x08 }, + { NULL, "sla", S_RL, 0, 0x20 }, + { NULL, "sra", S_RL, 0, 0x28 }, + { NULL, "srl", S_RL, 0, 0x38 }, + + { NULL, "rst", S_RST, 0, 0xC7 }, + +#ifndef GAMEBOY + { NULL, "im", S_IM, 0, 0xED }, +#endif /* GAMEBOY */ + + { NULL, "ccf", S_INH1, 0, 0x3F }, + { NULL, "cpl", S_INH1, 0, 0x2F }, + { NULL, "daa", S_INH1, 0, 0x27 }, + { NULL, "di", S_INH1, 0, 0xF3 }, + { NULL, "ei", S_INH1, 0, 0xFB }, +#ifndef GAMEBOY + { NULL, "exx", S_INH1, 0, 0xD9 }, +#endif /* GAMEBOY */ + { NULL, "nop", S_INH1, 0, 0x00 }, + { NULL, "halt", S_INH1, 0, 0x76 }, + { NULL, "rla", S_INH1, 0, 0x17 }, + { NULL, "rlca", S_INH1, 0, 0x07 }, + { NULL, "rra", S_INH1, 0, 0x1F }, + { NULL, "rrca", S_INH1, 0, 0x0F }, + { NULL, "scf", S_INH1, 0, 0x37 }, + +#ifndef GAMEBOY + { NULL, "cpd", S_INH2, 0, 0xA9 }, + { NULL, "cpdr", S_INH2, 0, 0xB9 }, + { NULL, "cpi", S_INH2, 0, 0xA1 }, + { NULL, "cpir", S_INH2, 0, 0xB1 }, + { NULL, "ind", S_INH2, 0, 0xAA }, + { NULL, "indr", S_INH2, 0, 0xBA }, + { NULL, "ini", S_INH2, 0, 0xA2 }, + { NULL, "inir", S_INH2, 0, 0xB2 }, + { NULL, "ldd", S_INH2, 0, 0xA8 }, + { NULL, "lddr", S_INH2, 0, 0xB8 }, + { NULL, "ldi", S_INH2, 0, 0xA0 }, + { NULL, "ldir", S_INH2, 0, 0xB0 }, + { NULL, "neg", S_INH2, 0, 0x44 }, + { NULL, "otdr", S_INH2, 0, 0xBB }, + { NULL, "otir", S_INH2, 0, 0xB3 }, + { NULL, "outd", S_INH2, 0, 0xAB }, + { NULL, "outi", S_INH2, 0, 0xA3 }, + { NULL, "reti", S_INH2, 0, 0x4D }, + { NULL, "retn", S_INH2, 0, 0x45 }, + { NULL, "rld", S_INH2, 0, 0x6F }, + { NULL, "rrd", S_INH2, 0, 0x67 }, + + /* 64180 */ + + { NULL, ".hd64", X_HD64, 0, 0 }, + + { NULL, "otdm", X_INH2, 0, 0x8B }, + { NULL, "otdmr", X_INH2, 0, 0x9B }, + { NULL, "otim", X_INH2, 0, 0x83 }, + { NULL, "otimr", X_INH2, 0, 0x93 }, + { NULL, "slp", X_INH2, 0, 0x76 }, + + { NULL, "in0", X_IN, 0, 0x00 }, + { NULL, "out0", X_OUT, 0, 0x01 }, + + { NULL, "mlt", X_MLT, 0, 0x4C }, + + { NULL, "tst", X_TST, 0, 0x04 }, +#if 1 /* Nick */ + { NULL, "tstio", X_TSTIO, S_ENDPST, 0x7 } +#else + { NULL, "tstio", X_TSTIO, S_END, 0x7 } +#endif +#else /* GAMEBOY */ + { NULL, "stop", S_STOP, 0, 0x10 }, + { NULL, "swap", S_RL, 0, 0x30 }, + { NULL, "reti", S_INH1, 0, 0xD9 }, + { NULL, "ldh", S_LDH, 0, 0xE0 }, + { NULL, "lda", S_LDA, 0, 0xE8 }, +#if 1 /* Nick */ + { NULL, "ldhl", S_LDHL, S_ENDPST, 0xF } +#else + { NULL, "ldhl", S_LDHL, S_END, 0xF } +#endif +#endif /* GAMEBOY */ +}; diff --git a/src/as-z80/z80pst.c$ b/src/as-z80/z80pst.c$ new file mode 100755 index 00000000..5eae04fe --- /dev/null +++ b/src/as-z80/z80pst.c$ @@ -0,0 +1,157 @@ +/* z80pst.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include +#include "asxxxx.h" +#include "z80.h" + +struct mne mne[] = { + + /* machine */ + + /* system */ + + { NULL, "CON", S_ATYP, 0, A_CON }, + { NULL, "OVR", S_ATYP, 0, A_OVR }, + { NULL, "REL", S_ATYP, 0, A_REL }, + { NULL, "ABS", S_ATYP, 0, A_ABS|A_OVR }, + { NULL, "NOPAG", S_ATYP, 0, A_NOPAG }, + { NULL, "PAG", S_ATYP, 0, A_PAG }, + + { NULL, ".byte", S_DATA, 0, 1 }, + { NULL, ".db", S_DATA, 0, 1 }, + { NULL, ".word", S_DATA, 0, 2 }, + { NULL, ".dw", S_DATA, 0, 2 }, + { NULL, ".ascii", S_ASCII, 0, 0 }, + { NULL, ".asciz", S_ASCIZ, 0, 0 }, + { NULL, ".blkb", S_BLK, 0, 1 }, + { NULL, ".ds", S_BLK, 0, 1 }, + { NULL, ".blkw", S_BLK, 0, 2 }, + { NULL, ".page", S_PAGE, 0, 0 }, + { NULL, ".title", S_TITLE, 0, 0 }, + { NULL, ".sbttl", S_SBTL, 0, 0 }, + { NULL, ".globl", S_GLOBL, 0, 0 }, + { NULL, ".area", S_DAREA, 0, 0 }, + { NULL, ".even", S_EVEN, 0, 0 }, + { NULL, ".odd", S_ODD, 0, 0 }, + { NULL, ".if", S_IF, 0, 0 }, + { NULL, ".else", S_ELSE, 0, 0 }, + { NULL, ".endif", S_ENDIF, 0, 0 }, + { NULL, ".include", S_INCL, 0, 0 }, + { NULL, ".radix", S_RADIX, 0, 0 }, + { NULL, ".org", S_ORG, 0, 0 }, + { NULL, ".module", S_MODUL, 0, 0 }, + { NULL, ".ascis", S_ASCIS, 0, 0 }, + { NULL, ".assume", S_ERROR, 0, 0 }, + { NULL, ".error", S_ERROR, 0, 1 }, + + /* z80 / hd64180 */ + + { NULL, "ld", S_LD, 0, 0x40 }, + + { NULL, "call", S_CALL, 0, 0xC4 }, + { NULL, "jp", S_JP, 0, 0xC2 }, + { NULL, "jr", S_JR, 0, 0x18 }, + { NULL, "djnz", S_DJNZ, 0, 0x10 }, + { NULL, "ret", S_RET, 0, 0xC0 }, + + { NULL, "bit", S_BIT, 0, 0x40 }, + { NULL, "res", S_BIT, 0, 0x80 }, + { NULL, "set", S_BIT, 0, 0xC0 }, + + { NULL, "inc", S_INC, 0, 0x04 }, + { NULL, "dec", S_DEC, 0, 0x05 }, + + { NULL, "add", S_ADD, 0, 0x80 }, + { NULL, "adc", S_ADC, 0, 0x88 }, + { NULL, "sub", S_SUB, 0, 0x90 }, + { NULL, "sbc", S_SBC, 0, 0x98 }, + + { NULL, "and", S_AND, 0, 0xA0 }, + { NULL, "cp", S_AND, 0, 0xB8 }, + { NULL, "or", S_AND, 0, 0xB0 }, + { NULL, "xor", S_AND, 0, 0xA8 }, + + { NULL, "ex", S_EX, 0, 0xE3 }, + + { NULL, "push", S_PUSH, 0, 0xC5 }, + { NULL, "pop", S_PUSH, 0, 0xC1 }, + + { NULL, "in", S_IN, 0, 0xDB }, + { NULL, "out", S_OUT, 0, 0xD3 }, + + { NULL, "rl", S_RL, 0, 0x10 }, + { NULL, "rlc", S_RL, 0, 0x00 }, + { NULL, "rr", S_RL, 0, 0x18 }, + { NULL, "rrc", S_RL, 0, 0x08 }, + { NULL, "sla", S_RL, 0, 0x20 }, + { NULL, "sra", S_RL, 0, 0x28 }, + { NULL, "srl", S_RL, 0, 0x38 }, + + { NULL, "rst", S_RST, 0, 0xC7 }, + + { NULL, "im", S_IM, 0, 0xED }, + + { NULL, "ccf", S_INH1, 0, 0x3F }, + { NULL, "cpl", S_INH1, 0, 0x2F }, + { NULL, "daa", S_INH1, 0, 0x27 }, + { NULL, "di", S_INH1, 0, 0xF3 }, + { NULL, "ei", S_INH1, 0, 0xFB }, + { NULL, "exx", S_INH1, 0, 0xD9 }, + { NULL, "nop", S_INH1, 0, 0x00 }, + { NULL, "halt", S_INH1, 0, 0x76 }, + { NULL, "rla", S_INH1, 0, 0x17 }, + { NULL, "rlca", S_INH1, 0, 0x07 }, + { NULL, "rra", S_INH1, 0, 0x1F }, + { NULL, "rrca", S_INH1, 0, 0x0F }, + { NULL, "scf", S_INH1, 0, 0x37 }, + + { NULL, "cpd", S_INH2, 0, 0xA9 }, + { NULL, "cpdr", S_INH2, 0, 0xB9 }, + { NULL, "cpi", S_INH2, 0, 0xA1 }, + { NULL, "cpir", S_INH2, 0, 0xB1 }, + { NULL, "ind", S_INH2, 0, 0xAA }, + { NULL, "indr", S_INH2, 0, 0xBA }, + { NULL, "ini", S_INH2, 0, 0xA2 }, + { NULL, "inir", S_INH2, 0, 0xB2 }, + { NULL, "ldd", S_INH2, 0, 0xA8 }, + { NULL, "lddr", S_INH2, 0, 0xB8 }, + { NULL, "ldi", S_INH2, 0, 0xA0 }, + { NULL, "ldir", S_INH2, 0, 0xB0 }, + { NULL, "neg", S_INH2, 0, 0x44 }, + { NULL, "otdr", S_INH2, 0, 0xBB }, + { NULL, "otir", S_INH2, 0, 0xB3 }, + { NULL, "outd", S_INH2, 0, 0xAB }, + { NULL, "outi", S_INH2, 0, 0xA3 }, + { NULL, "reti", S_INH2, 0, 0x4D }, + { NULL, "retn", S_INH2, 0, 0x45 }, + { NULL, "rld", S_INH2, 0, 0x6F }, + { NULL, "rrd", S_INH2, 0, 0x67 }, + + /* 64180 */ + + { NULL, ".hd64", X_HD64, 0, 0 }, + + { NULL, "otdm", X_INH2, 0, 0x8B }, + { NULL, "otdmr", X_INH2, 0, 0x9B }, + { NULL, "otim", X_INH2, 0, 0x83 }, + { NULL, "otimr", X_INH2, 0, 0x93 }, + { NULL, "slp", X_INH2, 0, 0x76 }, + + { NULL, "in0", X_IN, 0, 0x00 }, + { NULL, "out0", X_OUT, 0, 0x01 }, + + { NULL, "mlt", X_MLT, 0, 0x4C }, + + { NULL, "tst", X_TST, 0, 0x04 }, + { NULL, "tstio", X_TSTIO, S_END, 0x74 } +}; diff --git a/src/bin/4dos.com b/src/bin/4dos.com new file mode 100755 index 0000000000000000000000000000000000000000..ef6c91e9efeebc3f5b47e8c7ce73a9a79fc15550 GIT binary patch literal 153314 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 z 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 G?tcU9sN22( literal 0 HcmV?d00001 diff --git a/src/bin/bin2c.exe b/src/bin/bin2c.exe new file mode 100755 index 0000000000000000000000000000000000000000..8ed8ca852b139432fd9c575ff33e31d23c48d933 GIT binary patch literal 57388 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 literal 0 HcmV?d00001 diff --git a/src/bin/crcd.com b/src/bin/crcd.com new file mode 100755 index 0000000000000000000000000000000000000000..ee5da3b7050dc8249ccea5bd9c0d706a3088f838 GIT binary patch literal 1045 zcmcgq|7#m%7=P|^mox|G#wLRX9Pde?tlest%7pf;i|wkYOS7rl>bgNRXB%h}x!hTt zh?((+_U@Pc;%{1&L50v_3W23@Byl&|^@p2RL8w1%c2l2`;kRwfEv4ss9oqlE_ks6) zp67i&pNHp5W4)4v*#VhVpTP-M3!hz&gv#%8>fVbGz!|puD_0EJQto!dT*p1^)PVyG zHbVsfUt;y!C3wY_$_-yJXiFuA>gL_tB5VFuo#F5vgFiDlMD?DGNY)edehU;1`F@3g#KBzm^qJIbPF8Swtu3KWCrN6e6X~vHj zQRs`OQfZB(-%(QJ?c|sOw?yXrPTt(TlP|$>TbkMxVW%E@lf^v@HlXLqr&VaycE#GS zv_Cjr2<3kI@W`F~&>J^=_%#gO2%h~Ng64NP$$X}*;C;Ylh*cr@<(v=y1|)ztVWL$*+xS37xtga))R%NHfq_rka-|?>VDy-&K5}Cu(btos7gGs1-ZJ( z+_l{GeF>hYMa7KE$iRu1gO9{BTDEcLS|2~ynzv5R3N@|CaEh!g)$h2!3>v&VtZ{O; ze(wcqHZRolhxCz&)+7h1Th#v=T;w5|{lM+kn~qh!;P6NHv^6WoRlj^@f^E4*b)q$B z@cpPPS``Rpdw1}lZTD6Ha*JH<7Iy?c*%&Ih?l%w!a|6bzaXB0?z5-_L&+~IWi+T;q zaM;@C;Y)@Su1%j|3%(5dG;93ftgftWiEwE$FnIx(4NJdj(M>wq*Wb}Mc$j$Sn4*&X z9i5$`APTQ%;v)(n`v~zu$jMmbwHHrCBZm)>lUw>J(&33HM8?L*cwBpH^xuwV$Y}gs z#l!9;iMXbacq&1((b8UVv> L9c?fS|L^$+UZ{5- literal 0 HcmV?d00001 diff --git a/src/bin/fsck.exe b/src/bin/fsck.exe new file mode 100755 index 0000000000000000000000000000000000000000..dc57f4bca510cdce7c258ba5adb301bca3cee7ea GIT binary patch literal 73770 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

-V2EECuA|>QoFoEp%U(sMSdI^z+ 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 literal 0 HcmV?d00001 diff --git a/src/bin/ihex2bin.exe b/src/bin/ihex2bin.exe new file mode 100755 index 0000000000000000000000000000000000000000..bcfb99dfcad7c0d3a09181019de53fad7267801e GIT binary patch literal 57391 zcmeIb4O~>mxj%lEUGM;lyDCIXFj*7K8;M<5Kz0{!QC2Y#T}42mXox_75~OgBFRhp* z2YNXiH`*rYO?z|G7}M4!xovLqW>aH845)eYt%*(iC79agkhLkP7BCXe|NG2Yl)UxR z|L=GIpWprb?=H@nIWy19JoC)VGtWHF%(3u}?VOS0I1`+vaoleB^z*RiKYsKhdEzxM zP2`@7eq+XN!=g84EU&3;wly}bySu649^2ZAhK6;5?XD_Ylh|OZZLsApDYD(OuCi)Y zTwF|YsOUX^S!f^Gdc)ew?)tUI@&1zs($`*qFKtg@zV(4y)}F`v_qN}(_8ffc1Gld2 zg1@YGZ4Kr9CQN-^j$34i6))2*Ue#A8DvB$50Z-v`V?;bsjccKgZ z#(a)5=xK-}y0I6^N12&_$)iY)>*u%|S>PKUgTN1{P`ydt0P=Ow$)`AO^y?BrakGS~ zjRL~ry?78_{*VuE>}TV+J7+ajRtOaw*Bgmg;Bc7+V^EA5o>@8=XLlg}F*sYuhd1`~ za9r1{S{<;G+SCt6b$7vy`*{eisj7Y*dhHhzkT3{GaEIZ>{X85ucid|@7^Xm&0$~b- zDG;VWm;zx6geefFK$rqy3WO=}e?WoP={Il%N*K5WJ6rZT{!y%)k>W`GdAaahFj^@-C+#!H#pe|7Ik(qr+4erlQVP#m_Wr>0l80NSo{!-;X}_t% zJ1FH8{My4Aw#3(&EPK6!KDB}+@v`?!@CwV`!a*e=`#(IKqpMmm-6r*$5HGcy;RK`= z4@w`~mBNu@A1dC_*nP5hH2CeY;-=R4Q6=SHs#?ZMRD+3>YX>XvV6|fQwVom{xlol_ z)JtWSezDA{HR(@!IQ8LZhH{;z{u|FifRYAGa^c88oTh0&LHSd84@lE`CK*JlSw)%F z>X{TTFSnn&sA+xeqj(~j3tE%_g{5wT%mT_o^y+?yz$}4(1xU@qC_-U5ltQx--?~iw zO&nFtw|5Cw*F5r-)Cb2>MRQ+d<8F|ZD!Q%av9CbZjX|QEC%%%pXe^b=5yr}i2u2PR zP)iv`Zq}Zbc)b-$u~{*7TK4kN`CG-?Yj&YX^=_V#spdGn+!1==p2ACE=p~(AJfW9H zdU5D4bp|yPIslB2nx_%1lLiA#F>jXxCqW?PA$l&;QIWa~GQ&x|*UZQxw+|v!dYPV_ zcr_7kscBiwGgQM7RxXbkjzb$kHISM?{m)qTvU4L^E9KCW6Q|Z3ryM`kF+q;U$K|Mj zUX0s8fIc;eWi~4Ts!&;KmOiw$9~B}89svCnhKrAZ*U;csx3S@9ZtoH!2fhOc%icJO zm(II{h~V$)___(Ie-!BN=cN&o=&3W;MXT%dh@JHeJ?auph*uKW>xY)^4=2hj9E{sR zQQiGk202iN?qUUgYplRXRJwdDcA6fG(G)rG5t>sMfkvA2NV#1_W9p*njOyPmFl>yG zRJPpSPmK)F(;a7j(!({Im51m}PM|l1r5jmpx%~`-rKdZt61mp{mfqw9dh289s2HKs zh>b=F^Mb{)P92v$K#x;C6W&F4{i2H1H6VquMg{A{!Na zpq*ZQ>IeF8k=sXDRqXi?J*AHgG7GdH6kG~Rw(Q*+Nx7u+tHg-lOob&|_O>Ok$dOs1 zRS8hm-nKZ3;ervt|EL+opd73FhkD(?q%W|EF;qz3hGBGhispBY`T_weYN>iRsLfaj z#<}TfjLR3H&cuAc5O@hnOqv-_V06|PB<@mm{Cr9<>ur->Ce*l=t3%b*q*E#1VWrUg z67*6O*6}H9sK{|Opstidyos~44S=Rn4n^@zr3&jbBkKl7SLa-lG_q05Q{t#AjV!n0 zXy?*M>9Z0sh0Qx-B=wTxU}r&;bUt0Y;>!h0kVYm8Q)^ZbR`2P!0IT;SSlbkaN$V+^ z#p5$}+-BNA2z9IcOqMpT{*JszC4nV=Y;FDU()`!)=Sh2qG?OCe# z_cB$^VPw_Egin0~D=)~e7q?Vl6j?S#cStYGJW-CP)Sj4qs5e9-$ zr(AwTgi6*70xzvIta0Y-$0QIZAseqH+;R%5oR)ASJZW>XnJZFOCCAG-T>$BrzJ~y_ zcigCBc&!qbj8IA7JEQKwrYTC4j4ll%*yob)rGd^4&nE33KXmx#D= z7b2#yi1znZidL#xW@u;$n^E(co)QI7ZnUg9?ozqErr=*z_Y{@v-TrG2S6ZUxfaNJ8 zf&An|9|}k;QHKywQmUL#pFu#{pQ!Y#S-q0Pw51Tr0tJTF^CTs0Fe`B+6xeo7Wonb|wFs6=Cbg3`k z9rc092~at1*+uBfC`oDM{!kvz-RC#eHQ z?yzjzL4hvYz>nc8<@_szVV%MK!RnTo&I}Tlx5Sndsaas-Wo5w_CeC)6R$SMM`bGeF%L|30-Ti!QH^_J}#CuAW&B=VQF7QM$5atw3S(I!l z9qu;bMX+=l^4hutxBe=Asu*66e_r&?=}(-YCGXYdbAm`Ab+G zIbk9^jN^#l8-Yz)FfOp^VvrAP`aEb1Y#K!c=1}?5Iw$3|9Th4&rY;Co@kuaJo+|a3 zSUrj%RFg94QeCG2pWZek+%UY4)ijxWR#l%o6`jPd>8aKOy$d2R?m{nXdOAX>)V@&l z@p|(-W6dLr8TXIdn1(hc>usEJxs7>@YAM}4fxL@UJ_~(*DMU@CI5r1LrMEO?zIm5N zh?EX!LDw!xNH0-;JqaUS8Bz1#YwNA*_hCK5d~WY*i3EIbvN9h7Qi%1bxs*_y#FZ(1 zQni^|vzkVv)I#&RoG(=_+-q`l1v9lmbBS=Xf{D1;v@u4RXnDbqCr=DcC{Yt9W7bL| zns7zOgaz3#LL@-NKlpFpl%CaVR+jg;TX^wP$9uuSFoZqKoUa8rybo+C8^>xJu$NoUc-zNxpQ(3Qiyp%;ps+HjYLrudbt6V$LOM#@ zX#(F@>u=z=od=LZO+b}uDOiO%^Sq|*cmi=dcj4jFG9H1aWjst!_x+U-PxhYnsW$^o z@t#q5C0Z`*_bpW)0Dg6nIMCsAYd@O-n`ATE=# z+mGXwD=H1>q2H15TC^3ZrJrjW#+5uloD!HHUl$?I=jEss^87@3z9|@|%#l|o%3F9j zS6*$ZZe47Sn1r&|tX$pW=vvK&Ggl&9i-pfTG(XNN+*G0-h=bj}I_?vxI+2sE$3*72 zvemS}K}&A`=tck)4r+4o>vHi4xwv00J}noI%Ec!KHUa_#Nvch7OR7=0RZ@B3nt}ph zGTtohWk{9^NBIGt9xx3o&;y2nTm<}uqyB*mJtkt{7K*uWvv^&=YxSvr#~YE?+iwX> z)#S}4r&U#Jmm{tNZOWdDT?miEUezVLH?;9ptZQR~3{dcZc&PDyhz#d!a{ zhIDb_f(3x{gYEjDReV|k%xC_fKN^t6EYj87AJ5Xz_C3#iU(z&;ir&-jFD zs$jo)U?zMb>B!xdZAs{5X{5>$_z_L!krkG0K?E#q8!29$XKDK>UP0|fxOz!7TiOS} ziK>Uaqjp|2Q3DilP`apzk$b_j?q!sD1mzQil`m5cK+9!my9mzHeo%~7;_5L85Y^{B zNz6#;R^DFRe$>)-9B$SR8mOLtOk38$vi5n;5vX1cRFwlCfi|q6&jJV|NN^|xCTz`b8S;M43sWtxa7R?M z5jBOHIq*DDv+5+Z9H|34@w%giDB&IP4cw2yMYI3H-QonaimFn)R!w|e>Vhg0fkCBU zL@wN|ct&OK9_ryxivr%=Bw9b~;S_OH+8^KgXFu`^@lwkmCr%6jfsq2Bj7p!3<>_+t zEi9Um^;R(s9cc)>{96zT6fRYZhan&ii~<))t+lifktH?K()K6UM$mXK{kj6Z|x#dte*OHVDNE z<%TAN8}g3&L3=PmPAKp69`E&jY&R|K^PUFvAU_9#1tAE^Be>Coh+qcmm#ff&NVAm* z(bY=fnQEC2M#7i*P_GYMNBx0eh2mpaO`rP(OcgMNzaXV7m`AyV8F+fwP%^6rDBki) z*N=lU)jcfyVps5QmjHP67c67H`cv{9M=3?Ps{QD_Q#YI1yP78rpOB7n%HZ(3L}}%- zph+22KErtNi$>`qj=HQRI@J3?6PCeYr8l-uMCdez+KZ$h_YP`>gY8}SMp263hJO6V z%Y3CJvbRev-me}5y)|*aazg5{YhoAnGfNR8U2sx8Ta3o?(tZv!Qp!h%dOX7QLwyDz3SDt)Fn*{< z52gg8hk7D}Sj5`UJ?Kb`$o>@Zbc%RxsK+c$4l$vUI-5EbsStK3CgA-TEK3uyOsDCw zLp_*2Lp`Q(Iqd46P#khdEhjl4Pii^GZK1X+RK2FnYO0thknk?VmfiNToX zVx+`teISBDCKIx1O{;LA0d0wX43rl$@~L7d+Z@W)b2|plhqQ$y30UGx3I~=Fdf_1<<&7vy$KH`x zO{qJ$V`ybve0$ewal&p6V>=k-?roW%^zNjTI+IWRBeiDdGZ1t^eQ`#esYK48H1*II z68O3+)gKIjtvC+uZUpO75-5vonuP5tB-Wfk2-BNCb{ze!pAz>ef9oEJl>U5;Vruv7 zMTBXPwhc5ujZ!pBAGW!z=lcP<`8WjY+rj7kIiybDppSkF^^yn!p>@|c39X5`(7K}^ zc^vP#d&JxT#6`&NB{feVPl=Y0e~KC;n3Ue&bV@6!d5jW@v;+@Jv9!I(k=}d7PAWqh zi4c<&ZxTw1+(Fx5O^nyD0TRtL67@U-w3JFC221;c2sq0VMScf|U5M;WEGp806|Zgh z#8q8VKkxBrVxpFijk+L_xO;@Pa`|W=o5RMd%a}Z>&O;+1bt@3bPL>vxsK@@sgx+8* zWI&Q`9q&1Yz~MCaS>Yx~x+Qw~(B_PliXwqtybmeR(@<+kL<>~C4uP&xjsu3+-eI4v z6LR-A5i&_9q(gJ&oJO<7`K3?-tt?_x+)LVrl2R?fr_+*`rxQ%@+S1Y@otj8n6r$#} zfbENDfruO`7Xzpejb%wR5_D21gR*$SJuIXRdE-oi$Jvr(Y5NT-c8f{(UadFn z%URmHEbZF>LOpcgOFaZ@Dkuc8GgHU;#t_aYwezYWTnfz4&8q?D#oFFyU8Hbma1MX1mG2ALbjwCpytpb#4G9| z)LDqGGbpM$6M-`Kt7Sq`sXC3qn4YWHAQWS?gca026;t6arD`h(sTj-rm39-?{ud#- zSRK6<@WBM^=i;TAevC#8+0F2xffn>BYgU)9)LTe87D<@Cix;M8>v=T_M5=DBHV&4Q+&45A(Fi?#KMpft7i zTChg678C}W^|WlOA(DU6|q;%>UCHrMsUIN)~1tVYa|Hi|0 zE-|g~pSsU~{ys6v|E5hYF}H3>B$gz`D~r)!UN8^6YJ#LbKasZS%ESWHqbs;p_vnnp zDs@?-=bMS5tPe?lwZlw|K8~I}EUZ6)poKIJ+F|N)7|>RrbMdc^Bh6C{)nIwB3j?&0 z4bYvWP7)GS(*0p2w2bMO?nEl`QT8Iod(P>P0IXQKm8Q^^{2hC*K3z0?~&&&>+j{N|d~S_TzzIdy!+81g$v6UHQooDn0( ztv51cc2ew$o*ECh)1|CT7uMdjlgfi8Oq%&H0-Q9HP{#b+`5^qhNI#w=_pj*LK?wn~ zpS2=j?r?WE$CFYl#b<8)j2h82LF$SRs;Chwm2@Va&Jz^!m>zjnq9F)MeBO8Z7j zyFalgZz|s%tvzT$XWmXceybrLn91emWT-IA7^((r&%}GX&ztJzELQ=`UvGS_gliZA<5$egL~;X>|a7b z{$n3A+>Xvzei{2o4Es>>81_eJJop9dmzr3Syt2?F-=>F6%0gbgjaQ0C=zNVB?IabE zj9Rcz1zy`+cXXBlqIw7AE9F&FMm65jj$y;? zpkaqawe15!Gj2QH^a;{^%3>@q|Bhw_n4^^NV!d3& zW4%}~PX{Ql`Zvu3O{6z75nG=6B20)zv-S>)(i*Lo=Lbz%Ht3ZEnj-;|9|xqA z0}L?bKw#0NGfM*n@k@Pb>vg~!_MiP`EsiFMJCfS8-YBW@N*raC<7hGkjR4w7Npc1? zb4;kiR2f%IQ3)!70`fip)7&VSDxDg{yueUfh#}uHQF>E5_K8$DqCpE7go?Qztj#fW zOeLkDcVq|Eq(G{W%lYPM%Izk_eO=+mbr)mb5@V&Fcz5|I5}H1OFK$xabwk?Xn-jhO z774K6pWP?KG5|GClD@}tB9Ayg2LD3&t{=-6$I=-5CxD-*W?@1rC)(cws1RSIzKho~ z<#wxVQ07^sEKQu?=o+vfQl8GRoM%<6(q~XLj$#?ux}CaB*}Oe}4By#`9@UtCUGd0u z;yF@D2MY3I-&VwP;#B1aZGhLjqe#TAMY(vLGxi-}K*78`sKW|cEQow&c1@Gy;Xj&{?oU;WJe>F*1abQoONm79c z(vos%4uA;+HfNcJkICg{u3OcSFT-85h#2b7$DWxH8%!NPFBoiKD;uH1$7W2sXhAkH zHUxaT2}1<=FoC~ol3GSM;!2p=-{rxOEN!$`Axt-aY6_S?mA{Kw|CK3R*|{jnBwfT5 zj%~T=Vz<8~mg_)_7|W)j^5(I>M!PQsfqV4kj{M-a#sS6!7LQHa=fDDG*2N4P+h7-7VS!`LYjF4mJgvM6hb=Hk?MxOLw18A?b?~ zTfjoO39e>;9@Z}&vq;YnNN?5cKJGqwzE!xn4yVOzp>-F#o_baqi81jISuRyVlOMw6 zRB173LY=AmBa3kpWB{zLZ0Qf-0%?NBj2?IZ)W!+IMr=kt+mIbt zV3i6+G^yhZY`R*YV-#MWXLJxANZ2t7LyKHs>hr6JpvXunHc&9=KD53Mry2uG%#kA) z!#EWHFgcG8+-8;wcsb7`RX&=}$$K89$=5l5Ugv>}-ECc9JspeZiN@%SCdOu!*N%NW zd~}A7XNGsS6P3=;;tsWmZkSNs2{cYkS!%{w4})9x#}?(#SEk^S(S>eIE~~Q2iFx1z zBO0~bzXn)Adu3@~f`IW4?z5I{UW70-bcQzvvvGY?-JCM`${Le<4VF(@`LDUO){L;_ z^Vp14+b=Et)7bL)6^KU|KN(y6%S_4=9!1I&Fe&%aBvT5lDQ_CE(zlFqmix(;ue4yD zH`7WUSd=e9~_R+v92PUaiE;kdSLj-so2|25wenVHZQ@h2{5EEnxppbhB zFD?LUX}(%#es3NN281YZK1TV8;*BIxO$*KdrwCC#0M3KtuaLdmOqAbXlE1?!zk!#( z1KWkwD2~da^$WFL=62sB!cte=4ubP|x^HI`4skmsutb@fL17YD#<4g)+IgA6ZxV$8 z06L6uITC3$nF1jSFCIr>uT?h6`H6HoMCVXrl1dNJhp{pynCOBEo5M@B1d{Fl>&28s zQVy{n!BL`2 z!9=*oxITn&uD26P^Niix#c(%*n#isjPQgqk8kZIeuHD+ za*Har9G1oXR6?BxnjE?1G{hck&Yj*fftUB=bmG~kEL-0NmW;xrF1}QLDwXd&=Xfu$ zofx9@l6er@+rV$E@GR}jwBSPEN&=gRU4?R9n7j~&g-nmvb7p0LC*s&?2NLs{}8EC)d&}0wcxnBG9RXeK`yX`SKfB_!t82kd!EJ@ z_7H`G?pR?9mV9@&<-S@fwwv=~J?OSbE2+W*)vc$vL8;pu_yOVMK4fW|jd=F~Ay%0t z{qdslHTNO$Q;N0`I3MDuB-NC;VgG7pVol-e&H~8dkpR)WgUVsWV*(cLUQ7E%(iOlS zBHVx_o@7tUZeZp=rbc^DMthGl;qy|=>1eO&Y%*Ee4-oc+qY(7n;3dScoKr3Bq%nY< zLxO%El8r|hwrq`HgxRl@A5gp}-ShpHc2d14-qUW-iPTH2-gDI6R__T~N{>{X(Y%MH zUgSS)!-%nLJp_Z7;yvy*ifa_F>Yis3OChIf-hNn&F*@CB#kOp%0GOkTP2swW!OXhR zU|QX0!C7@9!JF&O2d}TY5WKc-ICyp4--B1yoeN%3cQ!b=ZYVgh?$cmQ-QR*yb%Vi( zy1%Xn?!~Tl=~8TGGi)zG8X;>u1lWX%*mua{jI@>Nnv&zl-@K1 z`QJt(N_rCqv+w9!U|8Vlv9$dW&2t~Kw7m!4vbRebS$=PmaHpiE2wq8@CS*$LL?Nlb z(*88komeN^cOno{FG>e(!53L1*()zaT7!=db$i4X>7Xb0Ftj~lvvlgB^yg9OU_|Si zen1BA+fAdg{eV~&dtji6I#<0*fHirRq{fmFKT7lrz1k(Z{cm^%ijeFq9}#Eud1<0> zt$)^D(X@f=Q1sNX=r=hJ47D>6jjX~1$I*dl2>ajg4@`p3P9H;a%#1BR$H71-$o5;^ zueH!Yj4KsyynX;fZZyj)Omd>Uf|pk$$pu!{SxN#KFQ9jH`~|wNF8A+Cx0EZ>ncnMy zVsXDABn;)5B_YOxb7Jm&o6iL2DCtr#SsAIbb$=A0?tBj>4keD@Ws^nMmt{|Ie=Z~{ z!|uPMy^F1y++dO$%yI)S&ypLGNUVbn1^ofm(~UQdsITyL+2WPOJF$fO+BS zfH^?1&?q5Ffbm0Dp4rg-I9nO1o}UidX3)VSht?V8>JcVq=Lm)cCF<-G=wnDBhM*cS zy$rUFiyTk=0bF6Q%zakQcmg?aq$yf`oQ;JXDk19{!C73Ye*O-i)H1JsPL6PGvAQ0a z+&xeTGw@~tFV!;DkKRTAET_!)dDb=J!E%iup?0f?mZwv3^3`ir_eENPDFyjl zeAHqSqESn<|FdZE^|qs;u^`B!4wJuH!%~^Z!E9k^>qpBvtppoMaCB6G#nWmt9(koW zUW@4S^3)rS_xxF_M3V@&of5MNpnVHnwHxHjN3;H>SwAXJMyv2&c9O0+z< zPcBY85>$@ej^m0G=Mf^kQLE-_hTFxnomSv^o79rXi7|xA9H1h&q!ykNW&v>8xF$yF z^wDW!8Am`PsHPb_11rEDSt~&>%`h;PUNyle;RL2P9{i8&&`X!@NW@xG1P$_53>oZ; zVN1l`xJPtozlXeWRseS(2x@KcMlGQOP|Aq=f~Dk2GN80~u!Wt77pwZ?KhZo{1yed4GLRRv3m0Nq3Mjndqct4Vw|U#bR` zpA1zsL=km|o)xAqzV0gZQOtO7F)}iM!C_Ufq3MC|6Qp~v`AR<-2_|a2^CM$+5RBBz zM^akwLmWi6Lh=6y>Z*pNWG+VItH=s7TR!P6e@kI|pvJVDS$T^ zNGjJK0v)XS?&d`Qov5DIdOeXbiUmpnhi^T z=!_t@8`Q!^35T>}H6v`syy$oJIkaS_Wdd(1}^3*pwB#(rCu9IbjxV zB_sj zdT-riqKa_o3(AmXW+&ABkqoz*k@2?en6q%G|{ll*OS*~)z;T+uC=mu6ov z&u(Y-6If14q0Gc)*~<@mSR*a%v~;s0NLFke!2jiWqYCcseUGOWR0PcHrOn$+oZu}f z4t(3HE#GD;UyTxCy9CF^Y(N#Mzr@}~+HXQCZXdkQUU+1KJvM(EuU3EyDW+}mJTvn0 z$bcjzeOqt`iTPYGiM1q{K!w+7Me3t^{&E&Q)+xnwN?N%|$xHGnd5J!CQwRtx+(GAi zaVS8D1B%BlP{SeH1XW)y|1iFoWt0yBdpnq897D3-WanZ8q{jg?Z&Ky<=hY{m3`g)Mt28MQk-mvgR{=i!LKOq2^8{D6~sugw$No5$UWvdgHJ!* zkU?j0v;dBP&KD7As5(|4s}Af2mF>gvYagr5it5aO#hdBAV%F!D{QS`z&o|K>)JH)7ju%2H^^_ZSS(` z8%bp`pL|iC2wgVdnbEt-%q9QT95H67zg9m6FYuuw@Ucbe^%%uilSEtzspB!#=qx;M zC>1J0M;CCrN}i}JPF&co$%{=}tff9odkEU#d$QLYbVwI)g+%F5Ui}f&&+&mS5vMo^-Kad4EIP7p{9aG{kPW**%@z3W+OHA3jYpvaDSbQ%bOx8Fv*# z!O;xyS}BLFpm4&p5_RwceTj|_{uYM8QZ?!gVwYz9Tm<&4BPFGEMu)aKbPOYZ+%b%A z4SBE|jq|C~Uq>D~ePMvQG=B3`2BW1vqjsLeRSDXUmPyIaaAT)0_E6zHuP@DEDtqwG zrufzY3g60h>joCzd?w|9vcKJ+oWk)ykI5IBzH%HLecA1K7W|MGY~Y7;b9OyP{7^bS zrD?i!K6yi;K5=Mq>QPL;&j;vEIw;fAdVUY$nkKiNKLlTg!U*8j)BX&$HG1 z)!;n+5Skhb@{knd2uVQ!vwrY{6)GFt`lVlcl;kJ%Cdf&4N7u@4I#9$&UgC};Nv5>97$>Jc4V`_;zI66!g0Yv8WHzjwILjVd;I46W zr5q5f3k80mIK@Xb`>1B$<(eh49V)7CuK5z{ZBF_U-yH(qH3UrEf>GgchJ%Jfs4qh& zp_mYr_TG@!%$Ep89OB1OHxB}@`4Q!(08aPeIGirgiIeq%S3dRMpfxL_t^EoT?jrrK zd9d?`Y=;cI`X|!74IdI*M!!Tq5LBlUNe2_D3yez>uI(k5Vk82BC#LCaq>=Tv_59X zwYl|7Ja`I(tRlV3N=hx#CXyg7_uIHLYn?c=whLOEQb5oS(Tc4RQ{3 zP4J2o@8CC$ZCx_~Ya*?4e5spl6fDxK)Kk5f(-=9J&!OXmp%G;4?ev+3_MyAzKq_g| zv3r+VteoT015v#=sIoNN3rbZ;y=8i3_5Va*_!9 zj6SwpdPD0X%V2>{xJ)*k(+=cPg(LT{aY6b)pW6HxC^2w7;R_SoIYTk*k#-XsPZ%8| zpaS#=(f&CxqRDIuMkHV8FwjR(=u(Q+c);BayQW2Y4PdaPc5>OEA*sr<#VD~0I`UH^gEzTb%wnv+MT-$5dnd#M6LBS4qwcPTc>&8Hr9d5m zdVxPsvfQ@-@@dct>I!Ic)GiMi8PO4y(gK^$2*%<+=yhH5%go>E$g9LD=yGWnY|}!V zw9w4=<*{RZ!AW>A1@hvNfGFAyz}7BR;Ebf<3tvrus8q^CB^a2Y&goW;7<=6p*YoZX z%Y7TsJHvfOBp_Fa9>Fm$6*dV{!~#m$dMO3@zXc?c;Ns!Ta3;7>;BXG^44jgG|7kgY+iCbJ zd=>r~_-Eh`!XJcx4*og#Bk)Jy!%DmjTEhUE%^3%cBV&}%sKGwCRd9`Pkik~3IoPwE zT01_hw>%UB9KS#fkYWrrAizcjYk!FT$(QLL_xahMjiTPeD^ZI!{0C6kk08n#>yPt# zf22@AmHsP!aM?YxX$^;>yC6RFfK;HONeqWj4PJ#3Z-A}qfa8FzcT7?9S6C6 z92~Gm>q33?iBbA1^{C~(J22MAgiRY1*(F2W{!-i}G9yhcSA}StSnBm^ z)?lo^N`v+34CWTMoAZOu9S|oCz3LHpXJqrLqqZY>aI6bK=f zO2VZ)omPi|nV8eK{e_6Gpj8ieg1CQ2F@CT-X~ZgAFOArQL}|n>#7H9^@prN~7)-z= zEn){j^Vn@Iqg+1t5{C`zhCIQuNIn>|%PK^%uvHD5gV1mSH~rlo ze4SjCTZj8FA_RleK3qm*H>V&AJ%^QxE&>RXp<)e*aaSR@3i0}ChR@NQB@Wv+@HX(! zm34)hCm2lv9d#2AWzf%2cNx}%GUcrDn%SU>)E(Z~@lv(FDz*SCg-P6qqw4|$$OxeU zdpoFt@*#R*g}}ZCS8c_Kt!(9&P@7N~oa3*Wg1d9Luz{W4#1Xcm!g_QC4!c}QGRI(% z`cq`5dst<{WYYE(spqg2(aRIfMe4nz#voyI8l7mvFoQG;BliS9mRef?vfKEBNpz!# z7Of6ilVJ$T@c+)k$+(i+R)-keF*<8$E1}TQ-Mg_@a@vI^smqRy)AO`(3V2oA#7Wo< z;<4*1$$+f$;5@=BHW)zgi8+JJ3OxJNlk)UrXg)08|0|m5Z~26?wEYgDK;d6IC$-@w zEv@607xFYH|K0m6|MCDqbua^nC-}+bBF{b*NM8mka`&H2PX-=60F3-@PI*nZrE{r4 zH@@J)+Gp;*4LDFe+WEt00KjjjVm$7?^?%RH^E)~5IAlwyhsUucQ&Ts1L0_bKk8Tz4 z?WESLy@c2cdyw}P4kUWZWE?&&+f_WX~F>N z**%HErFEV%pi2FRUJD`3=(3Yq!6<L*WV{H5X zxF>S<$+>eo=W1=Z4Y_6|KH$=R2BM^vLH(jvO|m~KDWR{?yl?>BLonER>8T}`l1ubV z>U#%6F!=i0mtks%?}gx=1)Q{h6>cyEsLE<(5`<~t3cc&CoexG*B^}#spiM9d^0Z*p zlWdfPvV(v0KSqh1Coc~KcqO;2*FB`^O4HQG217+(CUpc8BXCiT=G{6}F9|Ll z&J1UQ8wC#M;LgB7ZuqZ||4^!;QGw?oyNWQ6 zfE{j3Zu_eIrppWYfdA&RC^m&g$Ppc z)g0F&YP!hZc?%-7w|Cm%?VvEU6IW=5=^B7AaRD&Nr>DeTd1^2b-xS2kiO@uZP!&Qjv#>H9 zT?>U6N0&SSHr<8d2oM(A$8f~8$cwwd+t~6}q-(@VN}HR%Ub#605zHWz;Kp}QS2eR! zLJ&Mj{}o(9G=^b?E}m-%uTyt2jqDfIX3;)%_W)`P+8{>ZUghVy81;=ic3K?S`7w1F zve8$jN*qJ(>7)&{NOUafD@K5!`~xQFXwCztIs*jE8CaFZL_`QROR(nxl?36vszIBwEF;Z>y8AdHW&d0HS}vxp5?b&J&Re@vy2>Hjd% zaB%qjtA>W($Gs43Off`-=n^*5s!?v3Se?j?+HsmJ7_wT0)RJR@P)K*(e8-n`xq;=~ zrp`s(CNk*fc6RTjw$6m(oY?yG4M)pi*Pd|IMv1bQ+Ze`Ey?D-&jKFpqvu;*j!`2>6J zV$Y}9^BMMhjy-p?=N|U#V$c2Td4N4%XV1fUj(yK8?1w23ra+hiVG4vP5T-zw0$~b- zDG;VWm;zx6geefFK$rqy3WO;Tra+hiVG4vP5T-zw0$~b-DG;VWm;zx6geefFK$rqy z3WO;Tra+hiU!VZaUj29a?Qd9_OZd?BmT!$A)~^R}=uUgk=E2QY58ZExq65`d&KSi- zMOaN5Z6Jlvn*DEy;aJ={;=n#2a7 z_MR$RRa4WtCL71a#ck zUG-HqVV$kEp;oA^sIUEQm93_#qLCHD5!`HoYgi}Psv6dbch}gO8!OgU*{V@@{kjdc z<1$tVwd)!#=ga)Ye9c1TKggFs`5MKhD%<+nCPA#Iw^fS`YpHD8+KT#mRsrFa{*C3Y zS=Ugtu~zt2g+QK7peA0zE7eK)F1LGKV-*Ts*U-EUbf~OaU%Pf3Y=}lx8yloT@CA+?g0TB zo7UakRB?|@sA{^Ww&9C(wzKwpZU0m?fP(89?x|`JP#$o#v-W%~Y(>-EA^|p!(bt|v zbgHgjhw2*cwl%J+Z4lTnKul#-rB2Vn+OZ*AuDYj*y0lKL6uBM8n zO*EEcFet~Oy)*GX6=G1VNpf1kcT0# zzRI_*QEX&!`g>_@L*=>+TwzsnbH&|NbJuOm~m-d*dONGCokhO4cq+L(4%ZNn|L zyEfTwt7wLeVzJoJV9Ty+Zdm7mX1W3StD0stR0*>x#N1nKOV$duG`rmnefX`=Pv5!- zt`=?~K4d@|Y?p1UNZZO=>&x+|El1^4v2Eo#QJ_G149rfq*4u1V_uK`WM157m-9nA6 zLLh4cvklnN31vV7X9inqL)zW7FrR#@v1U^<1#I_JG&YiApA0z*^OnH`a!(@)ZzA&% z7plp|RPnXV%swJCiOdF4-L&qWF_dbnnMt4-rjOd{+N#Q1kh?;sm{3FcDw<(jssSNU zG%KuXqfph*OvW5auBm9a8%==uX%?s$!!@C9W*=}NYr_qKjag?d6W?~j%;pVogq{;Q$wg!YEKAWFNhG-iE|09W?O9~j2}c8*8Z{b*NOF&tc7b~ z&Or^VAHIk~i2RN9u!_~Jt4D9!)>qVvRkn52gix9zJtK2=7Au5}CRYADR$L`(j%{62 z?cL}v`^K3YZOvqVqYwil)c>#k=KqI>BL_q0SN?8BY*twt!er<$R6JA;X2^B z9yt2JH;f0ym)yVnBYXUKkgrQ8nD8%5fq#|)G|Wbf^gsV{U9q7|(-Fo85ZUiX{uKCT_=)h3|G>jhp-;oV621WcD)`y( z>AU0c@HfIY!6!rfIn2-R!aogv6n;N^`Z(8N_`kaQ>mAKc`j!&mOODz{KGBnKpijWk z_n&ZfhP8p(Zib_Fkx%U+pXfnp)F)$UR4(Nu-vUSFTHz>;+C4esD1HVU#nXRWMDKZ_ z_j#drAAHKQEEHc9@=M`U`DJiacRd`Ha}S&it`UxC)dWYlQacFV4@Wq+hWz{BQ@R94 z>1}XS&JW;jf_pUdz5_nt_XHf(_X{|Jdl8QCdlQb*-+`m_L=c7OGxjq?&=)(AAB4X1 zzD@Vd2qpad13j?gXS(0|(|+ng&a=hO{9Skk~!j-_? z1t-AW2lp`ClW=?Bj>3Hi_cyqUa1)U)3GQaNEV%h_C2*B+0-OynKZoB1_b%Mu;LN8v z?rOMMaM^H+;qHK|hFcHU3HKwoC*YoedkL-=?gX3)_Zi%O{T0xkD^{-97g}v%ILbp(>BV|9Ds> zlvFj5q8qzyLm}M>m(PiY@a5|+ zmBGDYSTwJ&qEXL_d|l(;k?W@nxA{#~RUCIEl}YF4nM#|3c3@upy5_0^pjuzW{X2uq zuWA;W)@|bcjlJo*X^wj(qC~%c!3z4_*qh#D?r{dYtV(~~ZCKbmx1zGNsaB}+2~FI8 zL=-nbw~s0+y&Kn7HPY>k`L*@9zkvBi7!|Io6zi)HRkawW{n3Wsa8!-=@{I+(b6}hyddtKAMS@!A`KSu+w-nBs2X#g&)xN}ANa0)x)8NaitZbrz%Iz~O!cC0OB@0ln zjxeC&d~{WVC|yA@-iFF0)q0(`dzUTtE(+g`_^;%g;j+RM2vZ3 z{@YQ&iaj%sT4isrZ?nH_@3&i1y{R3kKTmx%^>FGZsc~s}X^YcVrq!g0XdPK&f8J}j%&RmjN zoVhZyBC{cLLuN~6AoGFD$1`_j?#|qs`9|iSGC$26&eSsFW>1-&H2db+_Sw$a1+y2= zE}30Ed+qFw+1qA6GW&(n(Dg2b*n4gmFp^Xt#MVl8eO7Gas9yc zoNLGx>8^7ByZhJfeeR3yCv*RjYn^k&oOkDZFlTfQ8fe2#5MGo$-hPe!2K#OHCH6A= zJ@zL1Ci}hi=j})A@7jma_N3GsQZrLMsgu)Yq|Hvd+c6_OC8H_hfs7|JuF3o;E131y ztg~6eSr@XjETi*?Gw3|;oZy=5y54n*%jKHqTJE~Xwb`}J^`Pq+SC8wE>!jm2Y( zblcrN_s`wC-6!1t%RTCj&b}hsmVI+}TDB*9b@unNAIN?-J2q!V&hnf+Ij3^+b8pMN zBlkPGFXndVp2i1IvsSl<; zlG>B{R_Y&8Po)l|{xx+NeV3GWZQ4y~X=zUM;)1kgX?LXkGX2H$m($-#Kbam(|1{l@ zVa~WZBQ+yCV{XQRjKYjNGB#wiWOQWQpYbqy?^hYmWsGDznyF;{DC^Oz|IB(Z>y51A zS?^|@&iWX1_TvnZz`XJgKm94Y6AIS=RT%6T^D)tnNn=1$MOH8&@BUT$%2dG6-ilewG+Hg>ehl)5r?SK9ux6KTA|>R9i%&+#C} z)_*wmI$m?U@A%YVN}r0+m6N_8eOY>Sx{%(Q{x9i)^dG1HI=v_TXu2sQKBF{aZN@zr ztr^=g9?95|@r#Uz%;?OenLoyCoB|5KmW;>TU z?{mt|N1d-b-*yf=&90kVKG$mW-9xUOu05{9u1W6ix*x=NdMNve>=&|6W)EZ!XGi2D zeA4tu&Qy*|A;{h{=y(_cwHp8h`TO>@S~ zjCV4unbR_pGqchD&6(fFZ2Jl3+TqN1GVQZnvlq->I@^#HndBS3SYic?V;tI z&YU^R=B%1iHRoUF{A|vPb56{8e~w0T^iF)M1N4f<9GzyLVRzaW+n3w#wBLTRjNO?@Txe}PvS(ymBLPn(;zByCNaAKdCuQ1T^= ztJl&_rrqf9I2JgTIF>tBI97q4PdQ$7yzV&cIPN&%IO*tjoOY;=G;px&bWeJI`jhF; zrypjsq(A*MW=Tp$c}8VMO-6l2V}_8iF=KOvKjTow;f&)MCo)cE+??sibY^-pZ_8W` zPPaC*HnTBP1nnQs+&lZ&>`!O&SqWM0thrftXKl%v?7Ygk$a$x;&biLnfzkJC=Q$?_ z4wC4)+Li3O*=2WSg5Gmo1+K;5CU>~*bXB|RT}`fyt}U)MSEp;c>qo9fT#vhUxqbzn z_mZp2)$4lQb<}mj^*(y#W7i<~;HWFY&ATVMR)e7Kh!D?#OavJCG&(3sWFWfiMNa6bMrwOo1>3!W8&#PJzX9Q?aw; nIQj-4j-+yHU8}_J)~;%9TD$6=Z;L{0{i?AmSF;)`@8bR+0^@w} literal 0 HcmV?d00001 diff --git a/src/bin/link-z80.exe b/src/bin/link-z80.exe new file mode 100755 index 0000000000000000000000000000000000000000..f6760bf1dfa41e57c23be60e0fe451bc106ab6ab GIT binary patch literal 106545 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 LF}k{V9``>0Qgqci literal 0 HcmV?d00001 diff --git a/src/bin/make.exe b/src/bin/make.exe new file mode 100755 index 0000000000000000000000000000000000000000..74890153475137ebe354ced57a2b5172719495ed GIT binary patch literal 188416 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 Oi+v5(*E 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 literal 0 HcmV?d00001 diff --git a/src/bin/mkfs.exe b/src/bin/mkfs.exe new file mode 100755 index 0000000000000000000000000000000000000000..4fd4a4e9b8f2314cfb920eb0b0080d5dd29002d2 GIT binary patch literal 65578 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.lnk +@echo -l libcb.lib>>%1.lnk +@echo -l libsysb.lib>>%1.lnk +@echo -l libiar.lib>>%1.lnk +@echo -m>>%1.lnk +@echo -u>>%1.lnk +@echo -i>>%1.lnk +@echo -o %1>>%1.lnk +@echo -bl RCODE=0x8100>>%1.lnk +@echo -bl CODE=0x4000,0x10000>>%1.lnk +@echo -bc CODE=0x4000>>%1.lnk +@echo %2..\..\lib\c0b.rel>>%1.lnk +@echo %1>>%1.lnk + +@echo SUCCESS +@goto done + +:failure +@echo usage: %0 filename +@echo. +@echo Writes link-z80 definition file "filename.lnk" for banked memory model, +@echo containing the needed commands to link "filename.rel" to "filename.i86". +@echo The generated file can then be manually edited to link further modules. +@echo Please note, any previously existing "filename.lnk" will be overwritten! +@echo. + +:done + diff --git a/src/bin/mklink-l.bat b/src/bin/mklink-l.bat new file mode 100755 index 00000000..5ed40087 --- /dev/null +++ b/src/bin/mklink-l.bat @@ -0,0 +1,28 @@ +@if .%1==. goto failure + +@echo -k %2..\..\lib>%1.lnk +@echo -l libcl.lib>>%1.lnk +@echo -l libsysl.lib>>%1.lnk +@echo -l libiar.lib>>%1.lnk +@echo -m>>%1.lnk +@echo -u>>%1.lnk +@echo -i>>%1.lnk +@echo -o %1>>%1.lnk +@echo -bl RCODE=0x8100>>%1.lnk +@echo %2..\..\lib\c0l.rel>>%1.lnk +@echo %1>>%1.lnk + +@echo SUCCESS +@goto done + +:failure +@echo usage: %0 filename +@echo. +@echo Writes link-z80 definition file "filename.lnk" for large memory model, +@echo containing the needed commands to link "filename.rel" to "filename.i86". +@echo The generated file can then be manually edited to link further modules. +@echo Please note, any previously existing "filename.lnk" will be overwritten! +@echo. + +:done + diff --git a/src/bin/mknbat-b.bat b/src/bin/mknbat-b.bat new file mode 100755 index 00000000..d0c375be --- /dev/null +++ b/src/bin/mknbat-b.bat @@ -0,0 +1,34 @@ +@if .%1==. goto failure + +@echo iccz80 -S -w -mb -v1 -z -A -I..\..\include\ %1>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo del %1.r01>>n.bat +@echo as-z80 -l -o %1.s01>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo.>>n.bat +@echo link-z80 -f %1>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo ihex2bin -l %1.i86 %1>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo.>>n.bat +@echo @echo SUCCESS>>n.bat +@echo @goto done>>n.bat +@echo :failure>>n.bat +@echo @echo FAILURE>>n.bat +@echo :done>>n.bat +@echo.>>n.bat + +@echo SUCCESS +@goto done + +:failure +@echo usage: %0 filename +@echo. +@echo Writes Windows NT/2000/XP batch file "n.bat" for banked memory model, +@echo containing the needed commands to compile "filename.c" to "filename". +@echo The generated file can then be manually edited to add further commands. +@echo Please note, any previously existing "n.bat" will be overwritten! +@echo. + +:done + diff --git a/src/bin/mknbat-l.bat b/src/bin/mknbat-l.bat new file mode 100755 index 00000000..921a0bd6 --- /dev/null +++ b/src/bin/mknbat-l.bat @@ -0,0 +1,34 @@ +@if .%1==. goto failure + +@echo iccz80 -S -w -ml -v1 -z -A -I..\..\include\ %1>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo del %1.r01>>n.bat +@echo as-z80 -l -o %1.s01>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo.>>n.bat +@echo link-z80 -f %1>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo ihex2bin -l %1.i86 %1>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo.>>n.bat +@echo @echo SUCCESS>>n.bat +@echo @goto done>>n.bat +@echo :failure>>n.bat +@echo @echo FAILURE>>n.bat +@echo :done>>n.bat +@echo.>>n.bat + +@echo SUCCESS +@goto done + +:failure +@echo usage: %0 filename +@echo. +@echo Writes Windows NT/2000/XP batch file "n.bat" for large memory model, +@echo containing the needed commands to compile "filename.c" to "filename". +@echo The generated file can then be manually edited to add further commands. +@echo Please note, any previously existing "n.bat" will be overwritten! +@echo. + +:done + diff --git a/src/bin/nroff.exe b/src/bin/nroff.exe new file mode 100755 index 0000000000000000000000000000000000000000..60199e7624f65ea3fa82bb219ff1fdf87178fd3d GIT binary patch literal 143403 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∈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Μt+(E_KCnKw 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 TVju7)C5`lvvR!K8Sn59jVOtVX literal 0 HcmV?d00001 diff --git a/src/bin/roff.exe b/src/bin/roff.exe new file mode 100755 index 0000000000000000000000000000000000000000..4cd088371b388413b944e8c159290a2012a02c1f GIT binary patch literal 77866 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 S$7B9LbU59ek`wlhA^!#b0WR(U literal 0 HcmV?d00001 diff --git a/src/bin/touch.exe b/src/bin/touch.exe new file mode 100755 index 0000000000000000000000000000000000000000..7fd6378ca129ec9e725042ccf385b2af1c2b95cb GIT binary patch literal 61484 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 literal 0 HcmV?d00001 diff --git a/src/bin/ucp.exe b/src/bin/ucp.exe new file mode 100755 index 0000000000000000000000000000000000000000..49f121100b9587fee71bb961074b14c37a2c38c5 GIT binary patch literal 143402 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\wv`Jk zKuIyW!Hj>%vmh@8K^U?DI5f%eN7#hPGAIv->49uiF+d_C0TL373JOrYalc`<^Hp0H zkg5G>(!e%tIpW4l`u8Jd-Xlng>vFx=@iXzCi0A2riJDXfRZOfn;1w!@MWStuI2 z8a5UP(_qdO46&(0KPoJX?&D3J)B9QR#Z`y(fRNlu#P); zw=>}G`jQ}EH`?F{u?w;w!a-Zk0M{kwwr(<}5%m)ZC$$}t=iFg zJ8EK4%JnJKGajW7jzKqz9YPxR3mqyLKaIYs0?%@->;^lF`OGCa&Wly;SX-2t%QlG- zOo~-9chUfNF0**lt%i8r=hj*U<`iXKL;*o1y1GdMW3upHtagE5T?^E(rquv48$-=d zTPRmW$t@b_*$=NWkoX88vRd7$CJZ<<*Oa_`6|~Yw=3!)+KYbCG=Rj38i3KGgkeCWQ zFjd>a8~Eu?4tPXI=4JWey#W}=|LQN0>#)pV4`4ZPK&H&147aXiLKpK6luaB8hBvh1 z0rLhK0RyO|%AITMT8J|d8*%HT121?+v*5n`^7v7#>2q6LJNC`b6B(U3H=`}*3bdB! zu7=&%SwAQtQG=OVM@L67j}FmCgqZsw_6{rlfAQ-29o$jt+3FM4`kkW8z&l)w8nsEl zPAC|Wr@B?(qu-hCoYxe7rqPht;92H47I*EAXl#g+V|f5+gYii_P)J!!>KDAEVmcGZ zHsuL-XoXU@LZ~Y@iD(SvQKUO0(k-5W4$3ezgh=-Qo*~^hl8f>6Fn>Y1@hFAHNcUUP z3Z)ya4BWOMj8<<7R&yhZ|J;p;6p17U#fvjs)OhWIK{&z)5=tZ`Y_eUCS}E0)Ls15o=MYyJ9I&V^FK)&JhFORP z8shl;5%Wu}LIsWq@FDr7k_CSOU}N2+Jo=0Zj@x(;jr*Oy*N(yw$zjKi2AlnP2vvqU@PM?sZHsX zkbwaCMOH1u7c#6UTLC4?#ooNdFC|oC_UlEQ59-RKn8=U; ziZ9I^ETwV&C@YFM>+C!RzCzBN&#V$AK9BL|Eo+wgR^lZO384u+Bm~iA^mC5PImr%h zcmSDsuC{oL%E6P+Z$4tB1-O-pSy)ORUc82(Sb!^c9-r1JH}YrY#vP6#4m@0sZT;76 zIvSlE)NtO^Qbh2k&|A4ZRZ;2Q^fk$EcQ*z$PfguWppa^35+%SdQ@3pb#`HrsQC6wZ9<4 zOG{*RoXAXrvBc#aI{+I8=z%@fp@C}}QE>H4WV3@Zb{G0!5^&u&BKM&Yo(h?5GL~D{64^G`RXAxN^sjWSO~*~7sHRGsVv#*P1L;b zFac7n`JHb&Hys7(i;j-;bPAPeFi8cFSxtRvTO;kumQg}Y#KgQ7ifjonieaBv%0;BFh5K=B z?oFkYP^7Ye;Es}~SF;n*8~A(bM|v`JarL}8Ve$(}D81T|$#QFk^KOW)Ouwa7%0qh-^Xz`0hutqh_A~Im6o*$7dE3CZX*eGXy zG79wEEc$Trvu5V9cuh%uR;5)3ZiF(F`ARrq#Vo|S<*rZIq2M~A7;q?dELzraop(5> z05&eIBd|rb`D>t-#K@**@hZTTh$}lJBhT4HmyWE5z$Djon{~bmP{bz=hg-JoO%Na3 zOrWnA6I>j@-RAtO&XBT!@f)@T6NAPcig8lG89}yB(}#=HZ@OKIA15LWGaeTWQRW{= zOJ}j34d`U_oV>u~ql2v|!uhSyIx4HyaGOe&|ns6Ik6HV=0M7dc55+! zxnUrXG8=7@&D;(ZZ0ETe@5JeO9YHFH3gSI8xQrCmnwqM( zAP4oL<^kLd2on((JH#h$p>x3bP-i(W6zXUkUf(+05Dy}KU;GRQVH;U2;CP`9u1a9# z2J_$-ZRIQ~iDCN#wmsgHHH1}qX|1uvzpWdSP1E29mmB4e!=^1T z&)q+&hs}j1ZV)}J=%!R@Qz2a?P03QOv2f)}YMH;Ou!g<}L|VcHC7w3_(k+t_EsG=d zLHcOg-rT|y-&zS1;t_!{wxq8Qxzvhaj$PB<<2bY~Dt7pyOM5keiR%fWUy zP_?=}To}K%i-!z1UyIJ*4jZOr=@2}O$?}!>(O1M={_A2M4y-Vb|57E)=QS4i(;x@A zaHt^~8~Hs}0zbHw9Kg9n$s83>@Lk2u`~xz-ESVY^%MCwV48EN2uUtP#X)J5tt zinM7npJG?B#LZeW|5K=-R@7Xf%{3RBKgHQ_p!p{Aut3vRVk=quR9m~Y4BkGywg9w= zm?>WE?`dtpplb^{9+4QtvBAqYDD)L%X_psnTFSWQi$D;>H6x3{&>&%HV{4_#pJq<% z3Xm^$JJI=UjHu2vTx%Ncotb8!EN#1sr`Xdhc&8K$*wxdT54)=+tVHZm3H{N1pSfH~ ziu+-Tmn+-*;y9S##Hqz@Gb$;7i5c5ONn^UwkEbL2S9lwIG_|^*SzM}0o znO1?37JCS?wVOcNd};0et7c+$seE^7)R*dfd3zKas(0!Kxz427H@x&cC-H2)@hd z_g;UIPBOSHrLF=L`T)qK5e4!nnP8y2PS&02DN-scUQvwQu!}HeTvat6qan;N;=*+} zkO$RNfiF79H(Y!D^mF%BSAZKnr`OecT^rChz}U>cZA+O_=dH$_YV@D$8TD;n=arLu$`_2ThMz|cw1#UdFQt7N$IN!fH^K>nTgTd z8J*ctE<*#`EVwIh!5z<*tQ*i0(| z?e{LL#3y8rHJ%rO>=Mhib{57u;s+7Bq=8G=zx3X8NGOxjleeE>r=+8BnGq4-heQZW za0U>-x2|gy1P7lHLdwu-d06Ue_4(F;lYCnMtl>tqa>I~%%ro35kSPuha2(KOG%+?5 zcqX|@D#3gFRcCkeMQAT-289SP^+u$zWDR_bBfSMUt?h1?My>r=;L95xEvH!n0(-dJ zYP}jHm-`sW7Su)XxelDza)^uhh5mrdzgLDr4|dYzG5o`FzCjE~%N=Nk&s0(|{FP3X zbn%g*%)f0*nM&U-0e6}65nNVuPO6;GoIG$vk-Xkk3EIBTIqyok%JW;@TwegZP zZkqf8*EZ~r-P-3hrqj3&0TmN93oKUW_09a$;CF-hi%Utw z24H>&I{mKUWeH;^jBr9W9ywEls$_C%X#q1Vz?NGc}l)*fsUf{39wj~X*YcbBvBQ8Riu+ERfR`T6?_g&Wc0IDQ~6(NFVU})fCTh64|oRGQ!SJXPA=jVboVKmA9Pm$~qlbrwMCGt3c zaS9xh0$4Aox;|9}PllSQy&Icjk08RqyWOg^i-Uv*I&?6#*n3)dXn<#sc)&wWB%RKq z3k(gyp4_Jafop##4@8)8If=zm`zpQ+ITg)81pY&9VKH^LzSF7a~Z}eFylby z3Kv*7cL`?Pf5d>E32g*R11COT)%R$bu{8o@wF2?NRW}jch&ffzwMUGh90k){7}t8c zLpvsnYZKN7yalOm83S#gd7uLStZ<<37_SC>_XIX>*T5Qwt_x7*bLmA_63Wwz<}S9g z*HylQGcB_QRkdkgR8rKOYCXSu#SrJ>%pm}hfMb4X7ODtGHwO7=mg5@Nj@knVAeI=X zrPxhJT%73vc5lbazvTgf8iR#59|zdx5t5w2iGZyoq*K(a24IPp*1h-J zv~{o!m5MUg0ZbQ_=)6&Eho?%0@%Z*Db9&bATECgEbM}SmT5u1|ph>xRb1$5f+R8V_ z3Qti+Zd+~~(qJLPoV0C|a6rZ^8?ZH5M{#H{jl%Ch2R5m@H&N`l+Jmj61jL=@v@;b* zVt)VxJKdJ!(d{t>PsuBY3kKXc3(9EbUZlsWhY$)+e)FUFm!l5iop82=oZ5-AF4p0c zcXZkf`=>iLGhHgED+)1Rd7tL3aOXb@znsMnAb~(dOyM0ea^29j#h{MZL~@W}UM>{R zTr33{mTcinARM@bAyEgEMxC`o9rsI!BoC$G-e4SS^HqwZ@p4{(#_^qGDc1_aeW>Vm z5glkd=tGJSU9#mg5gO+Jx zV%EAaB$f^LATl0pzV=FGdMc`99z~L99pHe{&(`2bG2L zsUtmVo^B?dAk1KceERZU*!rj#HD?K$JObl)Ez#+QC#CUD_#u}j>M)1d1u4*@Z3w!8;>Ou|+zifhag4T; z2WOwUh#=fq9wTelPU*ov=$Q3Cc?csF1}x+S6M+&@=>TQOxlJZF_8c=<3t~s;AA{_= zy`9-fqM47jGk2 zlG_Rmv9(;;th9}&1gsX=h}ky41$019K!*cSbBBrxdxbX?plkFE)u~bj7dOcY5Eor# zXW))2>`qXF+Y!-e74=Edo_leC9zwe+v6Ll!@iVYEpo4SJ z*_6Lf{CJSDWPyW2!(5Q$zp@%u=IkqhBkR-zHWOpiNfo#>&r@5Iu&&ITXl0@Np(DFg z4LT#l5Q_hEBDn!oM>I&BT__$k%al-hnMS^;^$pk0biLLDl+E-&d8Uzh300wX7Ix8L z6*1@8awRO4v`$cF;j3;<#FmFT3!#KngZ*04JpOu>`-e)wTCyaRiYbHMcL*) z%G-j8ZV)ZOBc`2#0+JQhN36=E4kG&+%ze^FFCx$ni;5(9`xe2C%QID($a3E`97Jh! zp#z)PB^*HSEMagdZ@CtiY^o->nK`KvgET3b`R4SYo2@vgmc=C`_TB(ddmmKv-|n9y za)>!S?=U9{5>-)vagiz*OFRe#Y?2cGicSiRHWMYBmb2n0(#Vc^+Odcnu-l4q2n&`n zu48g>Q=8E5obAe~4X=&Qbva4*aK!vx(H+ZG#Mqaqy$kc`EN}tyT&M}+K&~Zub+@$` zG$tBCHMxhSk~JZ$8hF4!j+8Sr83E{}ct1_n15tCEG$-yJvqqctSlLWVj_NAnnu$HKE6tVGQmK;iuPBhMil(v;`<|D@}%Td_tqaB zoje1Ku_xokqGEgeGqep|C@h%aN>$=u*;=c{CRsK1VdBBzWv9J)>yd$4VKtKRIcf#u zqHC8Not+ZsFEf^#m76#{AODeA>g@OY0->}VFtii-FQqN6282VL)m-D(tYm*EQj!HL z9k&Ll@h38Ir{w1@Oo&=Kyd>{E&fBSny~lU8$>OWEfK|`#%*;@BXSqn#$CUtTTjft( z^JJ0fn$9Q-U4b*$cdA?iQ+FovgaqGR$x;itiYRYN$y^BKoHz4+@_HFsy!n9F3l(Kf zK)xsO(_0qmP$K6V%#ChgJ*t0Wr5$h%()S#{0@UzorB4#U%v9qwI1NqVH1n<9*61Wg6-jJ zzT<#^oGd^~^R)z&DHycK<=~)a$xV;nXst$mn?_GU=UX@U9yJ#Z3|DV!9j4cG4RpDD z7N!R6uEU8I#T|-HPfbco`R=oOVkOFpP|ejsL3*O}AcjsSoHX8%Q(|`Uvn=-s;O5chQS*}z z3X82mudp^dR-rhUB(C`EwN@-;9UI=z1{^Uds7lJYp=BW&VefgOX@iT5E)#M>SPfIy z@=g2)XGjgK8mEb=1}1y7NJ zSTW&XCHfe9l(`#ZwG8YE++0Z26)4|VQ&#D=#|0I4Ke2SW97`;tODw)I_Kg~Z0CSsA zTNjcT)Pqi?^ks?m-5UZCGh5%}&3sF&D*`h)8o&`c>`P!JiaTF%x*EO%x!i-dRJwL8 z9h{lp!3zd<<~c?1#p*VEv3jM?ci+40LwLgr-~xX@^urr?7chUIgYkFsp_*?$MR02Y zj&IiU4HEhB5Xv?4?It|jnYkKea4RtPUuQsBFqn>7^abS~Zi|B}0W8Ps=-dYL9q)Cj zcF$&6q{|gHqu4Hzi(v}$E{4fe2yE$bQRWYD1=(xnjW)<*Tp{@wL{&{0uR0?<{>%It zWi343&=sn>yzCxaau&ihFbkv^J;tcsfy~RO;$G=wyK;ki5O9+XYJJ}~7e^rL$}Xrk z_gv0jjxJw|1iDT;YE(6CpahjVq%9;dD9I0dC^nG9N#-9TGh( zzBNDAwAeN?-L~K_kPG)%gLE8nq5$>aXi`XpyZ@Eua>`Pvhdan{S~9$0E#{n5`94sk z=g_2N<36F)yiqV5@IwGKWJ$aVrxu|dVCLJ~$*|%0=B9}8yJMpN)Y$GV{t0V`~n?a+>JN^f($>>&11;& z5o{p!{QImTbg%1p5{04v4*)6X?@-&)Jrt((KHnNR>UhK9fkNmF{b-5l*4p@B$q`v! z(JUNfrjO(r`31yrkrh8};oOW#P}1N&!1L^ zvXoX1kUj#a5RL?Sz?ZKJc{S01@V~G&yO|;Z_u~ST;P|lXI4G97MC-n3tHU`#k)n1` zVDSSeyBsV(vTyHA*1|PF;Vf+21(`@j%J4I4t`p1xnUDU39*O}SV#>VuLd?JJ>I~Ok z=LYY(=>#Q`nv9kK8daz>Q^yo-IV+6_A>bJ2c=L=hy{6}@LITfDoQQL&4~V4Ln{>ik z#U#)3`s+!F5TTc$ZO}phVKkD4^P5>PSLupA) z3_mcL+4V!CbJPFyTs6%kC>Q)0;Ze%WU*vgszP_RXm3dQN(V}B1L}FxquCKTdw|nZD z?fMF^YFbRc$l@BYkpoA@qm z-%W|V!*|yrF3WtxD;K&1?;dBlTl5{)DGclG83=4HLtbA|1=32zh|yTUn>aXUsf=*j zfy=Tbkg#OQRp=y4ReTl?51w z;__fsT`)e$dfN1R5p#5|r;Xz98cm4<9&w)0*W4HL7SK4XaAXza@h{&d{cwc5!W|G_vzBZFpGx}4iYgdrC)Gwjq$7_lVM}p z=>W_*%a-WkZYu{^#9?t}SwLRW=9{k#+Iy5FKmaZiTu@a1PMZG8H$gnvRFJK5M&>lHFd%# z=Owcez)%9mrh?%g+M921N=kx!xjvLn5;T}WWvo3n^P2vWm|f-KzbbzvVmHRveX~>F zG~2@&xN|J3MgQ;~VYnrf4HD;RHdjk61|js60iu?%!4$IRV&DN7(dc7D661IQoz)0P z#x9)m19wvv{*pTFn|7hMpdj`X*E(-qCOx)tDTG6G!*=b6k~^T}mON@sE`41|nWhhu zs3s{XrT5tF4XQ%tUfoG9Xql(s?IPc9guCnvOzszSc|65A%?(Fp&X@|=54NP2{ce%T zRA6He^n^}S>DHZ`WLcVTQ?)(~O2`SQyQy7nx1SQ((pHOf!F_hr5NVE@v+PJTw~I)5 zOM1Wadj5vd=Y^tn^~Pz%lD-r}NeM3lCt1Uw5li8}u1C&-qh3b)!8=-xgPVqXGl@gD zv=oCUduoMK$`c#(Y6V@ji7wA4hacdrvbsF~;;w3V-$Wp40+~*{ccmk>4E_<8b9e1C zx8s+)t5j->1*;_D5N8ggm<(~OSM9c^guiBZZFuHng66)z+_BVU_;jLx*X^Y_Dtzt? zR+M=gq;AI9iz3;xHoHXlgV^eXn+4-@uod6a%MQBu;O1|9zI3;|1ao+$gIz#DX1_oB~zpFW1S49xQXwSR%r`C(7;E61je~0Cj1xhmjTDi<(an5= zc@Q_#9yVdvO%vaX)xIhCe=`1`iT}6a{~G*14}6=0|7YNTD}KlDw;ligmTfbhKTd(a zMFA+P#9%dyQ@g3d&l%u@0*h-zz0e=1S7UVyV6ecq$eo<~_v0D&_}P&AMfe3hnRy#N zFYM_Zwuie37N#wDhAsFK3m!EX-4ibO9ZkI9(`WwvrOW6hv8P)E9)rjlCNEB>Z;8AD=ulWwG#hWAH z6MsXH!rmaZ9qRkXY!}Q>HO^je>x13QoCIfR4yQeM-_JW8wE?z;2GG|119*h7oT}fU zAh~(cZ=3w!GU8YP3#|k@4S-v}EAwMa;3%>k{jNkq+cW$)@Zn^s-DeG?eW<2zQ;oZ{ zJ5?`))8~PrpiAvuOS0`+W|XMA;y2)ZmL1tRdbyW`*aiRi9+G7{f9dCL z0J*`mUCg>O!I1%cSw~P<%8eyJ`A2S$9s45X0ZZUcfgl$t7iDfk9UwKVha2%%sf>e; zpmGRiQf4zqZO2m`zu*Rf>>xq#tp-@7U@#UlD1CH-=&1;@oK!%cD0C2Gezi?V($DQA zkmP$pk_r*D#(w31_a&cRthrozW5bX)bXr;TSt78w_egT<#`p(O%4l^?1Pk@1U<54`=d$+qiT1 zuo4d^@Sze93is0%?$1F$=4?XFDSTLuhvWEAjfWCG08F_3dB~?5N!S>~_l_9<&<&LF zrDATt2?VU&lC|Bb`feI%SiHYk!2OoQ{@*9I;f~tIeX>$Gav&rQP7is>Dqk znnw6Tc<00Jr&T0~dTBwhwq9_X8%5Zj$4$Fnj$NQb-f*fQ45>TU1Bgw0UTupJZd-s} zF%n-lAsVaX^(kxTLdtnzslEE0AB+4Eng`4FQVe#X?jF=aAU?nU#BVQoW6^~z9}cG+ z;d&HdFR|JVq0JYW_^PoW@oPI97zRY%>sVx9%f5C`#C-8WzT);}ET_bw+2lNN{l2_j>MT*! z-+G}oyC2laSI-zUQ0yL2L_twWVDdZlA~sUte1+COwwLX(sr7G!*Z*V_x~*~fa4iX!V!IPEsJNd_e(H2%KENgS@Yp zDh}K|UYNr;wsR@lwLUb{2K+oAeK-=gX zgy!@}pF5 zM+aof0KF7k4r??XhLc29K)hC<7Lr;mW27XTfzj39&dE|Kb-j{HtN z)V&HA4mDZ77n?^2078rmY^MV<7vngX$=o4|6F6kaEI6RIE*^u3iqId3jLQLH!DF+V(55JhLNaFHWvK><2?Jqx7y12xlc$7wyV>#_%Gh^kuCqQ9`tj z*|s;}@wpvQrbtJ03e0I9^xPdaRy?^V`5L=i=}Nfn20#qCDEZjC1Wj@dQt7G*)uL1a z7?DesRsC!&znOiETvyHuhpK+ox(HI|Vld)XP%x1NFM&qGO@*&OzOe>?zo(pOQ&A;7 z&chi{b(9(=H{i~OZiDv2G|khf)}nK@*pV88yBs>a#QHu`V?bBT^k(yXCHFYh#j+Eq zF3Lp7O%8B))y^l!X>N+@z=xL_MXsqaaEidvdhu>mZ{dyGU>qYX3p+=N)|u`%5W2Zy zqT-PI&(W0w6ef*C#_IRAv#osVNgtK(2T_M0!W)_)B#GA2f|g?ZE(m|(1Nhxny9XTQ z%}n)siWB`M3m_~j{!O6DvO>9Z66$5X`4_YW;SFzK9NIC!*w4(- zZF8%znycx(9yX{YLr*T|gzi`!DD1_&UGB;fFcL4=1bm)ry6R)vkuv0Xnp%w=2p5f= zUO&IWi(3Nftvw$#8y1ot?rIxaRX$EK+?2duv}(QSZ6iM@m8@#tGr|+H`4O!Q*_^-z zX>H*$2AsqiBf(c5Rw^)7B~{{z|AMtRARMY(r^H(W;_+weG~JA;54}1dAKn?@1ylo2 zYNNQOfq%e$XpZ^=df=X#${HP2{o(X{;cA(374pe5`6$x1jUll(I0;j*!R%5I1I^`2 zaB7zKWG7KgVf=jROe-#WIz{oLyyn2k$2XyM3%5aqp%x6wdLvF2W7koLqc+x_w6VKb zN5wEj_PmL3Qf{sFyk0T+l_ciO#=$v_1DMn=%2lye+k&2S*^dqT3`+>pEta(A-~wTu zNB^auf7Uq;zg9lP{3M7?BY^wsQehH@CGPWxNW0$Yb}4)xIfIKUSW-f=Ax(ul z#5Xci!DBdUb`hC1kGzVQN*QHbVq*1Q#`tYC23~Y9=DRc){sdz?Wp~ANKtL@KfX1L@ z1Wg&+F*~!t{rBLfrPeX}#d(1)Pe^;}442x{39fcXTU!xP=2Xc%%_-%^_BhQp7;y~u z&tL1}QXMPW#ZvipPHE;8aM9kURr>0F==u&=ru^(I!um%#gT)ME9_c7{reQnEyxotU zcTSxR&)!H!sYSj2bQg75S?5m9h#R3)!g~vfgqCnnx}R!Fygt!hl|_fu?hc0I9z!tl zN1!Vh;WURYriZ^i0xy>#CS0XhA3g$01$B>_Is#h>*c;Gx1ZMwJBQVGKG}g})7hIr# zS#Mx*4>s+F=4?Z(34>rj%Rx@mJ;FI}fm)&Rx!?u$sfM_owKn6C>)FJ?iLECCD(q(q zKor`m19SQjf549v?|{MxH5KBsP54rk@Du?GwydSS@c3NZG6ojYn#H_WFyCdT>fO6> zqY%X_YJPXx*qrx4Bts6A9|DF7u%(~*9Yzw#3@AT1tSrC&4aHx7AafQ9dE|9@zMvo9 z6@~I)P(#Sm6{Wcq%wf6$3%Vg!SLjO6)fMoY0$W==CuB5YiJBVxIUPJj@bn}=Bp4Qn z1&$^}n<)1o`{AvK+)?+^oPG^!w~$Go-cwxy2^{EO>xpt#|K7UQ!_ZZJ`5n?>;CAR| zNAFNaswZjgJS7%>Y>x5c&MK_Vvc|$0;yQfpH3qQ{b;t0Pzo; zIWf;?;F#k*+EZa6W0w?Gqkf&<`L)DVVM@iiMoRIJ?sSyutPRnm#g!JQ8gzbjv~u`L zY6ze@gB`_qlKGy$E$H1EMh6V4YJ;sopaEmlnE==@3t(f|86CmHEU@nA1^#*m|3!MdjYzxr|!kyrUp|kb8go^;(D#4Y9i4z>8BY z`SJ<9rlj1>&Xu=Zj;?#&@sIMpbS&3x^z?6L2|$4mA%u5M68xJB=u{U7QFF02bJ(5f z*RuG_T71ks>AW(1Gp`KNo7AIbiejY~WS<1Okw9w9FlG|ebT1s|=XY_fZCUGVv6AFW zp!=C#dt2NM3e0)g{1k0lFp#0mj18p7NK{^*#Lf}2S&L#;7PXN1Bv2UhMsH{@pwEr~ z7=dIkjW3VjvOXUxZ)VQn4IPD^r@HWu zAeBcC?b38}*WutaqtdK6Ji~OHK>GX*#WtQjh5}vPAFA=KXfA8-zOH5B7W!|T301wV z6H~pLnbRDImfexfYP=bvu-L#URJHW&qcUGYa zVI~QUm3Gr9YGila*>T62mCN|9^Koa~9S50FF->CU|4`EvUG>DW6Bhu!&uI3&Qx-Q-PYFicfXVIYODZ$PR792D34Oz& z#2VM!-w<=Q@Y4CRQ~H2U5sUcnpp@a$$ZB_>G3L`|!hxnUL5IfJU~RTb6pT#{?SCTE zq255_wVkoD&c>LR(%Q>T`ITC`(j%X-g%8Uv& z2Celwsh1V*1#Dd9kZl-@%3`V9Tm+Vh;L$*XGtlaQIBl^$m3%GIq`_#4nB&nVC4!`s ztaz=HW!C%~mQaa_DN6Sml!`v~`3;HJy1`Uc22{7hV@P)L2*HdB-b&o3mBR_C7)sHA z>g|05gXZ^XPf?P%T2qwoF~p*LpH`1}KEKkdr6&@^sEFib^efFpydG443IQf0G?ZmU zoPQ{ajR=&p4r_H=r|2|4rSppQ_r~aGtL>;fV3h5{-1?ctYTYJkO7#e$&1^d>PW>6G z2b1Y|Sq#u_-cYv~dbYY{ROi(#mvx)EWdsG-6Zv1$F`>HcxVW}`%92D8pX#ZRDRMW* z%2BL|l9UN!Wt~C%xov~uH-`4Hk|xrd71bS?qSO@eYhvq7N7s@R%h<=7SbHLLXA@gb zVv2FJDStmqy72peM38Vn6Bos&r4yfj!Y3H?F~U^PiFU1wdDzLr$~>-5dN9s}hDk-U z3e$zGHfiAEu}^={x~8J)B$kgf0m*nHujx_PfHU&e;)OA%Wwg2|H&S&JQQD``I+H4Q zt~G0TJ?`s*%cnj%;vCp8NlC*@L#^dcIp;izvhkC~rlM|Cx!`qFnPhnbfu@@ez~jaq zcz~M*kMODcu_{q?gjK`HJBpIm#Mo+cqGcPi$MWss^iLYu@;>MAHO+kic{D(hAy765 zlp6FC=MgF2*~M&L{jJZVU50H-EW&F$11`P6*#+KkDU!glcSITyi(r<=x5DGos=#MK zPhu@d?vEvAtGc!bh-3#w-K+FQ`*`KvB7SHeo4S)aG8dJe-I-T!AymC!r9bhiYLP30h%SOlZj|*)VQ26sMA*|Ee zDo!Q{_`E}CJB4p$IbSpy$pMT+dj%)(_R%d8=Psn*hgZoi&o9EYDvWHX_TpR)^o?)o#gQYbF9pY?(Za z4MT}3hiI!hliaFQu18PZ6W6LOgD$R6%nqgmEne-T8(2Ez+)>ZB^Lj2Bv*OoKmZxE# zgYj?e6)pBPFs};`uY(<6Dt_v`y%6<>OkpEBB?%7+{w2Uut_l8JN$`hWMR)v{Fz_}E zdXWhOCtZPo)eNeZL}P08DCN&wm&aTL63GwaLRzWl9Eiwaa36zxTH3sYm$+*E9;L^p z%%e|Sxi0KJHdy1ch8o43(7I7F@7eCY98A$OLhCNW>L(<@R;l%%gA@E(fjI=5xK?c+ z>!<>3^eG2o!b|SVnQr@mn6`EnGY4pm(RM+gg8j8WVcZx9bivC`f9)9UTmW)o)7EFs zSIkpP;6>=1#B_z65Tb7NXvfVlHNblu*bH)MU#QT6?ZDkfHhQJYh7kxTT~{sd!{`gU zKYT!FBk2*^n|wpvw4%M(jnbE3ZB>}x*p1S!+Ksx$cB3V<8%@VZOg2X%lZ}M*=G}U> z{8@_5%b(d`+VL|ESVQhm7iA7}`R_#gQ>5j3LC54;Y%yinl9q}y6QQ~pTB;lZav^3T z3W5+3%_o00J~G(#OiDr0VPEu zV>#4`ij+%B*=`kir8XbpYr4JLol922bQ?B_MA%JAEzn7Ern5)6v>`=_`;FVZS{pW~ zSuOmmR?fNrHL|^@w2bI?IqP#bzz$!oMTv?TWygo4TqRnv&*P=Kdy;h*Zzlxuj#+Nr z)~f@dd5cHg3Awtl-G*u`HfVdwrK`z=@Fq+=oH>Ev9Ef4LJ9Lf~z0zHFyu{59Np}6u zw93Y{6IXS$jG&>oj_W;mtW(R2GT5k5tCv{a zd`Yjfd&2_iuUP;OxO)snlFPrq;$fXI$3WF<^Y20zggduVJyAPL_>>U#T-_JgXhu*< zcL^)hu7BiRiQ#T8%9X251EyMA1z~r35Ug2om=>l^pC$n6;Hu?52$+brCHiq;_Z>^* z(b>wUn0TWl5=Y-TVw5(4nGc(BAN#Lr3dqnP|`H-!0KT=oM9;F2OoATw^N=!-_ z>IL?Ce+=-2(;h~B1F;o}YQg^3)z$hFHTl1*Rs`_ts*06;lFWxy?T2P2U#i+HwHA^; zPb&k#%$3NY$g6y=O@eSNfKk4!XVT}&JIbf5+6+;rif0Y=DsRchVG#;l`WCez5Hqqx z?0=glWSvfn#BhAQn1TifK|c7d}|V147$77_^}9qp-W0n_yFKc>vT-yV7e_DK-`EA5*EA_Xa_wDuun9^S}w5&Y7L)$ zb(C6wxUFx?ozsowx!BXYYYQGm8@p>AS!kqAJJz;yhv6iVe4osVnk@pB(;M9J+ z-kJI_A>U4XX!y|RV-7w(#K(v9F#{j(k-oDRFWs$%A*5#@(}xMU z$J)JCj;BZy*UK$OEMgXkIEks)n01UWvn=fMt5V-@_dc^55 zNRQ9y0kPB!8ZJ<{_ZI-5q(rO?Ap~vK1;n{&?Sg8{+MQ^o#j`e2OmEl|1FVaz(~P`k z)CxNNCnI@3ML|lBDHRgQeimQRGra9!B>Ne1YK~n$#2Xv*we#4NkoaJM_OHk+Ag>#- zXfMKLE4YKY&x33Dpk9Ebp`gN2pZ0wO%T;lt!jVDCxdR0goLB%y6NzCM zc>@4kh<_zg|LuuL*C0|L5sS_|G5K5#L6#=MthBA=Y$<@=zz46@en^WjGLOh1-Kmvm zR3S3Qy>E!=9N0KDL`ZLr(N&w8xs&3^U3@Bq>F?u|jgxuacI3Yv$2r(oZhIX`v2E9o zRK)MdU8**5d+0hA=YU!;r#VF#sF+7(wA}L=hs@0Se1_T*rK4On%a5e1?X39d#{AF& zD4sXET&bCg06TBnqO9<Pd z%f?{Zg4Ra4OOQVtC^O*u*iFu9g?hE+v23rlz=^Sl2f~I_;tTS|ymR-!>Pg-XR&{t@ zFIQQ>G{EgeK5a>2Fmmh&_&RPy?XJxy%umUwLpdhJuQA4EMIUZ2c4Q<@i#T4zupn^hCe8YdRZ5R?GRtn?r81b>XZTN(eZ)agL-*NFpt~@We-`gc?2vR0oWrl6t$d-mwu^ zr;HeoHp>WI%9PR#_du5=+ttpylpgh;DQ3w*oa|8F=EI=Sv9u*|*hdfI;KaWC9>r$N zEj999aP!i#E8W9- zt3QMYW-ns@)w|XDi~bb`=s}<*UMU1wUqp)_im(6smB`N!At9GW1SWcHgXlOH?r?G2 zL*-M2wl_w}oGlFniP1)?XlV4wCGG(|S1zWHs|Si<HBb1@nubQrxY0^oBUhU=ESU!<-X_8u-8%&AN8dw#W90WXG4)L}uG$B44Qj_FIjxC+XxZ_KmFI-*r{NzOE^M9@8s5A$N7x(d2;Gc*TkaERk_&s=x|ZQH8t3GA zI%Ls>zyDVxFp9z_^AHIJJ)wpkS=kFSt&x>y!H!={7lUt&6}{R`j-)sKYw=b1h!{Wp`(@J-T8B0On-!54-J^e91{ zXhz}4rfXk6hcDni!rntF7gB4gkLvv}LfZcc=p&T;I+lEQGWmd@o{~nfTsW>Mz+$0u;h94FuhK3&#!q1X_{bj!YUs&1^NB{RtM`3@Mf)?H`<%YIe z=Sn$CmLOgT{oemD0!Ue#5lzrJ!tU5$O|>;7UZdioD$Hke6pY*>R>yQe$0bNJK43i+ zu;1Qaj5l>@{9D441sG*HzD`hofO#&*R|!w*a0qRi$zNM6wEY`C(c6#U|FEptg>XOU z3G0X4Bc;5=Q3DidKpur2{9fP~TUpOMgZwFmgAXVW=Zy<(qX0d)hBiaV<_Nv7kHZ`S zyaKqA*2;SC%|nBIf+Psw1^O(+$REmxZ?d3^Jd*TTgt{j zTGdy7hmJxI`?X#jaG-w#b&<7)gf{AASxXh#egX%&sf}LZ3R-||myxCpe*eMZU_~B4 zDk#!`{9@57OQOf({V&4D9DUYiT-0O^yU2&iEuzh(pD&5_Kgp5}0F9*7>39vgM?gBi z2w-Rt8#>%4yWAg_au8-Xi{1kbP}l1cF({4bL=#frJNRP*W*`j>?x5%&rAMQBHPr)n|$%c2RqEtdn zrEElU;k(OPiXa(A?uGD0^pVmqG8l7-Hw<=L#WW1XY&~}{W;#psjKNrnm<8WL3=akp zGqSHlI$I)L9E{nei3uR&3l?fq5DKa*`Ka!Xi5w*1m~@-zI~c?A8H{n`Qj}_cMs`TS zj+fPRi&!hQU1^A`o1yq&Ta0{qJd3seSb%=VVr;#Qw4abM^VfRK)Jpf=XxmXeFHsdk zx@bsojfD4+HwKFn$Jg@FM5-3Mx$|Mq3s1Vlj&f|PzsFH+xlyRLEXMyy{JZc!g1-&^ zKfoUwC}b0irQGHmWkQFWZ%;9-Ad%=KU{$F8UFKk+ z{+O0RcpiOL5vr6Tgh|;Zcni=kZTUiTJcMvA{F?T^fRpiOSR3q!BD5Lk;U*3t+FPI} zf@l*SH1(srFWcY?#6$ZbMih+(I!Z^)E+hyozy|Ru96s%K^r6~ZY6LpcD_2W7!PP#E zry1ak2lSN6TOh2}i4uKU4wQWY0iTwJ_>6<3jeKYrws>HhL8S*aJ_=u-_7T)o%trcX zgqqm+=bKHGmM5AgI;j|m6*CYJbAq?{v~MN8q*-dKHMrWZ`4Y9DV82$E_>wZc$atjx z8z{!7-8lgz-;V{k2CMjvz;D>&b)4Z(}` zRzPxkwNkW&%&}`bZcOxSKx}C`hnD*_4o&j?!ZUpD} zw3C(QD2cP_9GFEtf<}Y3_6&N!>=4F^dzN(wjt24m$KmvAyZ=ljr+T!>RB|uauz^U! zhtL|K2Lo{WzYcLJ5H&Pi~ zRwou2o5u)Z!UhHCO+-XjzXTOdivMf8N#=lvaacs0k@qZ4DwKSJd35k-eHGM8IGur! zIBgKT*%WcIc~;0qRl8H^cmTx1qMrg6RjyiwLmTF^GLOhbesLW}^4f}dui!%rXs@~m zgOEICD8{E2YuXV$B`)x4UhtR#N}RE;Z}Dg~_;hv$Hce5|LY3uJlHm7xv;|0y?#1yj z71RU$gp#J#lv@eeriG3k*>-L}1~s%!rz%J!L(-9kfokiFG#nP%&fuV_fP$Zj#}yJc z=;ED3Cah$M2zi(hKe%pwk5-HgG!XD;X?P2}Ypt~&A}uB=1vwe! z^B#Nx`lq1<#X|TUY}cW6hw#_%@5ldh{Lkb6F^;UEb;FiO!`VnfU!>t;m-~V>(g1pT zqqR0ki%56UIzL;MF#qg zWRHpbsQbL0gS4aWVLffM{=#VeaH!=xz|-AW;h~n#EfEPD9{@aXHf9ab!SJ_}tfei( zAT@NPReHtD%Ee+@sD9YcVQ+BQikU6!E|ZTG%A?+H*+Q6XFm<{6 zt^MDH1D@({D{)Xpkd)K@V{)p$t-@1Jm4{2DDVS77J%(b$uN^@?fD)00bKs-3@az)Z zjBPC!8!$Or!O~%led>7CeH6a7&PhM1Lu_zz@w$ZYiMDk5dL@S&Te(Hwf||j zXkuND86ZJTt`8Rqce&47^$Cg9(1gs*Stbvc3Sl>DkqB9ChJY-AE){PH4X+Y!l1Dcu zuvL){{#|4L)6+EZ2r;5W(d2%iX15UyjD4=?1O&XZ>&+xcKidiCiNLUf6;PDyY0CC zqOiNCKZ+G&2m4aipV~7oosIsULCWk~s+zJ3p=2 zsgxMV0Kkjbs`Lb{DC9n2Z-aK?eWeH5aKheY+0T?63Lg_6py8D63AKD|5v$GJqTStt zUBskLWV0!K2#2yjyZeAKkGP(Mw5#rY9&Ofq9N-oAK6KamNLp>JZo|rmNGF-4Cjer) zFUp`wd$e7YL!d%BDzx1Qr#XkV(x|x)qm=-08}LE3fb9Vs{p3PR{{!TM_bR+;J24@d zgn83%HP_!?olR4zI5ymJ%TaWufSJHxeE0*Jh@+dOyOWDkXbQp0t6lpiwm!2HeBo8a zP4+}^^E}%UGtji1aevojq7E~+&8NJEu7)W~a^w+KR20(TxPaZCB@h0-K z1+;6BpDsWaCex5k8&a=U4ot+%9{@pJeDrCnyLSSa(7;ebK=qrdkhdyKLjdM8qUnq8M;cE^7r2D(FBD33lO&cCV=nP1z8 zP1FeNqvb6RM?bRZ3)RZkj(wz;CsQVS^Nmwq+neGY-snf1R)gU%I}UB6mZ{Ctk6zun zRbx@iS(Iqq{qQzhC#DR&Cy&;e=WG*}A3aviF$<)d!hfJP5wFBY+xeujFiHz4dzt98ZzEeI7@nM9%z6uW#D^CiSYyqsER z4@Fvl&Syp?9l(^NdLl+|wth#dQ3g8F+B$`>4?Gtg$9ozitYIBPNnoC+UV=;1Q4{6lJ{KYFV0XuHhWlD}cfQH)-pPGlZ7DnDj7bYrFq**@ z^fg_i6R(l?g2`IplrDW5h54EWD8Osv{gQl(cRlEY^l)BRn4q@`} zMF%AGAf@U5H=0Rts}Oz)j*5nSiQid(s1bL**J~06U;@VEjPWiUz4DE`=aCMybQ~7G ziSve9i9H-A)uIt?1Vavfy#i*!X}{N}Et^WS)UIcNdqI40h@cOGHfK05h_k>WHxF!3 z#~RBOSvpWj51rJ_*3x-LU3VC)h_w+qgMrU#o(ESz5K5U>gsPI*SJ|mZLmZXC{`;Uf zwQ_?fRDuwHJ)ptwNH0l;ku&*-Rp)<~0WbMTO3->=#}ez3`7xo5Aind2DK9GQ?Udv9 zZrvb0AZsO}Th^|D{Fas@7SsvhU$Xug5yAxUp?8IhEb@Uu{iTWqcoLpC=IPM?$6(YY zwa5ot`VS#GFKv|1jLIL5$Olrk9SI?({`el6Zs8s&kk!+_0V_t<{ze2HevYhV5&I)e zat*%TDLF%Lxca>au4sr$bD#o8g>L)Mcn$VnVU3Y_Pf2kc>gtU zhu#SFPr$qBr$~zdWn`+S!4<|F-S2Q7Y9S>ET*8-YE`!J;_Q)zOk{?;cM^+U?>P%@g zC69DBAc9c#2^0xBop1SD8Ew5qaA)egaAIaj7TFT)tkkn=BS?{bF``3@KPjy>`nJ~Air9Z1YD(JIDw!_m3O zr=11o4dBE_Ty@(uaD$lzSdid_zlbRbs#!uP%vnY3R6%|My#|kAM$It zAW;z}Bv#6X6(?;YMVcH;(JtSJWn@(}jV_xDIA0Hl1%6EQ2f|~lg^X=3PJ5mguK^QWOT%!j-?rX9G+YKA zRvPgJYdOZclh4`dtk3(MO!7dGU&o*VQ~z)}ng|G*;1?&G0tpFn%qE`-As5}!}n%j}0H+H3GFF_{yMzbx5tGbP#HOa0{G$=8e*hrTU zB^t;sV;t9slRDf6`ezEVQL>h_*W8+_&vLfdrL0hkktwBirDwu6hc!qDmNo^1WB@!0 z5jiRs^+%P2$CqG8bq9J^M4Qu|ccGCf?P(<~cJO3CIG=N{+`Rb396DJXXzN<3W*kG{N1D{|oqc)Y@hqYhPkpj*Rc7p4&YxTdG$g z{K^=8ngVHY*2m*w?id#jwMXj`WA!N{%4tM}$M3^D9hU-mbEu3R|6KeF@GrvuX8h;k zzXX5ua{>Cf0PlRf^YPBbI~Q*U-VVI&c-!&j@#gX7@aC=_7qfpJKz>d5Z^nN+<((Xt zS{qtFZXDP*T03qG&^E*|{jM6faSI4IC=cY$k=28z9XxB`q(f)+IV|3xGfFRo4y`T9 zwVAFnwiEXwNUrJxDh16D4YVPPkxE~toG+wv4;f80{{dvph|K2UADPw*azSKT51!he zAaDV4zVk0acn~R@9Ef1bS2}@pOa%V8lf0DdwRnEJvvPgKY#&^}Om;Cr**wY-Vk_sr zJy>b$Vt$D7bMm})=N`PAuZt5)qLDljqDA^$B=@S@BeUr{GMm0g#7~*m35e}k8C>{U zA<8u7y@CL5Q!X;_8}kU&Gu{TxZ9>JvMGh%zCxwO{SZL9C(^<$eq2$KAPL{Ii>Xbs; zLO>o$ZSsqDQY^}${}%W&whjUPov)ZRo&de7w{FE&fRlmHW=9BWgdlAK1dDyz{5K54 z1=&hQs<%5|-$h|U+gWrVP6c*I90zSavklt!ODS8FMi6O#Zs-9UikmHQL2Ke?ja0N^Pz)m8O@3E1GDsnKztQRMBJ++DJ@Tcqw}~K31%+sCu3} zU&?-wKJos~#QOz$OVi-r(HA9yQCcd6`zeB7 z|C8VEhe(^>3$B3ItL;GagikOP1QC|U_gEgQl)S^}jh(0QP?i_KQu}qV;<}v--#L4P zCtsrX!Pe`XJuOoera}q}i-XRCTR(U9wDJ`5pAiFsh?oPA38!b;L!BBnOx%|&lpS!U z9;Lqiaa4)wQTpto&u60gXV{X-x*?c+4xbQ?pfW(EBMlCDox`RKNLkSjQ0ew+R++&0{Sr|{&z;K@{)l)106 zVUrv*oM||sv|4MmwIs6;Q|~e!>ZFMjy_BN79g*TtPiPph?SlJP zpipMzf!vU?BK#xV!$KeU7(RJx@w6TD!BTvlI(KQwF?H^52T%bLZ|t()DGfo$Vcx@t zQ-!lPyAqH-WMrT}QUy>k=CzHy8me$U81rf)uRE*$X`EM>yzZz1vN#s&aq=pvdUBi> zohbDQRsTp{xUQW_q|q{1MIf4e0;2fj8EAy69-6)aKEPXcQ5%UgmqFa=y#3gbG53ki zrerrEdPSawmihM3Q>50St>l(F?ar=^T!lmWi)vrmsM=NXbwjrC<9QQYu=&9a>l=UcXYaA(1nNLn(`1K+&Ngr)}(n16=BW z?Q;2a=|F?QDxp;kz&kRHvWr}|rm;Jf80MG=7RJ8@1?Q^TPe$$c4xpo$@CXsLdeBch zNl_y*Z$I)-M$7YIWdKsgaWEK0uqF7ldgO)!6l9lGuHB=3lNflAO2~I!Kn;2AyGKxi zWPFGrtK1VF$e(~7fm9?}R~KRW9cvnQk%EUgt6}UOE63}TXF%A=LFA=wR%;Ao*bw>1 z9RL!{vrq;)vjC)c`|`z_|ykFXC8 zEV^3Cpw^`?Wlu9-m2SM?M&TD5X%$Kq(oaFEXUVZO0{BoerZDA{Sb3 z;BcRBfyABA)`ymLI4Eu^#j`;IkNMNW8ee&3Wv-FZ4eccOmz@fgua-F1Vtt6JbTfp% zq+${=&lj^nrM_PESS3!`r-ReP6Riyb!TG{dFx;JgOjl0ag>!q(VyZ}2+Ui=vdY5#e z!-0Cy6YD%{Bg@Xii_*SnHbm5UI|_ycGSIYczq z@;;$;0_hNv5CNI@0jge1_YwhjnRA#xMzY3YW%+ca8IZPRLnX)6$_6tCcJZP!Fd52NGp8)gXm)SOUAc>$(PDZp3kjGb&R(Mle6;3VKd3dlN z8ZZaQj1>{>hpI`u+q`K5rgQ1EcW;p+lClSgoQ15Qz{}wYjy7#a25Swdh*>NNWix~n zV((HOu|winoCEU`MdFR>+)ax8H<4wqKv8Fxn;{b{O>DAa5-Bym;WZah8~6T(*JEp+ zL~mi@?6;#b=-aglBUNwP!cjqzLs?;0?y*;_;HA_(GzDYc6)%eb`+8==fgLt-7av*7 zMZRqh+`o^*ZH&Ifx0SA1Tw2QT1fH5c0ud5`pdlA)q!6aZ_DQYu$^pD`e~{ zH_b9bJleP6McOhHE^E%9%@%JeKn{NG*bJI44mJD$y1B{1a-EG_O%L$;O2#_?#`@M&@Y>q_KulEu?+pqy`Bqu&62bo7$Z1)RR)W5~9*EzhhWBL^vQ8AT2G@VgzTf@3HIQ z#c2ibBF5ijf-qp{kl(Kpe(xeRqj@{$G3_?!l|KN;MbQf&K1aB_sRZX60|iXct&s?! zSj~2-D|VbErtK8Ja!LMz+c10R9kOn~mmC8zc&YRSgc$mGTa;c7ybgjI3R0JtcHtLD z3L@WyfWvokblOE5&mg{U7LBNKO@RqhHe{@2yjNh1dRkTz@(?4|f zN&!ULI6?j%PZ##ZKs(~~Pbl3D$#mH)jK%*H@pH6tENG=S43;-9=6bb1;xnM!<%n37 z#SXdLU^GJko{?#+mWv&VL;eB^cq34p-M)i{O=;dyldSI@is|)8&CHeYnbJj4lvnF& zvffstixBkuhc?8AL<<68$V?fXS&{Vzu^$Fnm4ju530#tZ1;)#lA>SiXcA}VIAqrU& zKG2+c?938<2*&4?doOWHW(nZWdBC3ND7Rc5UD%3+-{>3?+K5PySR@Z(fwYv2tpPgU zHJ5WkCm?e(b9H-71piS1X1N+bLpV1hOTTsex?pkD?QDh)otSaWsDNZrRwD9U9Ht1; zVF7=alUw2zf=XD~-{k?2gf^0cpqe(H=T!Uo$ak^ozp{kab}UQdnwtS`Z#9jlR z2(K>U*g`OuKsN0+I3^ij-j=F05f7FeEFI7y0#m?LFCW0Vbasmm%I4<8Hn2o$ir2Ki z8v7TIRb(bm=Wa7q(w*IrT8DU3kZZCOCQbo3ft+Kxk;$!G=+TZ9LW>{#@hS3h-hj4i zD`%wA(pG96(48S60NUhMu>H-iJnDeJP1&h%C+1Th4y#HmxbUG)+TQL{+e+Eq2K{Ci zA8~QO2Jb}o3x7oc>^EI&v<7WH2&kKl~<#bcG~5{FzDH{|wn z0w%rMK7v=bYh(Z~bYc4l4pa~m>ket~AkS3FR;?Rw9^BMT)P=k4sd3CAeq{;XJ+jn^#f7tE1!GD=Dn|JJ8q^BM zdLeu_9JY6y7lbF>aA9hg0B<2yVUtkJth)YWBJq>e~~od6v?0P6_JX@pW5hJq-LQ146tK^A}>a^B5D0%5dp<8>zR zJ90t?;V#+pIk<}q7}YiU3_yxR&#Qnu7?`hgJ5Gz}`Nz1(qpas2<0FqkO4wnOMk12q zs#32&yYErQ(oo%n4(IW7-o<)20qq#VlE!UB4->*N4#e>p6<2!r2=y=`pdXS@j!>E{ zoSNw2<>Pu7dK9)uO+MLuGa*zGQ;AXkFi^%26BAKkYj}l`N0f&D`)JBCxr)G#wRQ3T z9*Qyy!K5+#BmsWS18XJb27{hh$R>)DfVW28MKlG+3Zbfo1h&>qMaRk+WoukOeB^ujNM?SDiqSr3yE|n0woIL0CjSlZTG8;wlEc{nlJg1 zL)iW{Vh% zM6Qr}0fj5lgz!HilmwnsRto4NFnA`f8?dM_d;hkx3&se9w%^kH!Wp7|z?lUp`1*^u zD(dlvDBGwdg#92Y$Rtjz^sL{8yMN`VUHu2D6S#$KcfjA-BW5Yr$RCW_4uMH{p1g4s zw5WuRKVqP@}?Oz#MufS|v%8;-}q+ zrJ)Cxi92gULYO3_a1E0a{Y3nXZMbGQM6X`jN{_8OM>F8CLHYVe{yIe0;z7#!4dg6H+j;OBZ;a6nH9ezr>Aiv)f}o047aHPOp>K&jUp$u}0&tb7IN?-wOnFiQH9)sRy1x^XvNJy_5=8gt2ea z@x3fzp-8oxW@A{U5i7EV^uQHEMKC_i+uqi-=trr_d!{L65DPe;Dd6kh2y>QSC%i0I z-fBp9Ei#J?C}!e<(X z@o!uSfv==pn94D`FzL+7i&eY>m_Ib&5_GibWt}BGqGPGZFO?>FsALb7?7331Y%j%d z{q>U3;Dptif-gxk4?>#Rs&Y}$rdUAFAbG#5O{NgU^WJu9&~4{^q77yq2HmiJZ3`U= z!7D@#2>C+3*EH%RO*BObaSJjgBWYjitBCNO8am_x6AgBkkbu|zOtWwRq0Rwm(p9Ar zu~08Yju3ALNP$((KK-Jmk#1>#sXi=vI!hPiZB^& z>I2|+Kr>Sspeahy*Fer;vcSF`*H2m=s|Z@#`Be=uwVs#Pflo;1VN#v}V+#V&o+eXP zhl%Ip5qklP02e5Nfs$>OaTCfwXI!!UN@7kR0>N~4R;QGYMnVFs$N>|L=b2=a9q$u* zHD)esHWO7Gq4s0_$4(vl_*ie&0qNq<1(+~cTa=F&H83suq3zg)94F#E#&1Y>BJL*Z za@h1l4?-p?DN^O7sEOiOhO9Wy)lk?zSdj6s;v9@@2j4Fh*F(Zq|A2=hQI;KL<)AEn z6JLV5Uwdy+F5W!e_MtyQL*LgS4jpY#$5@Wj(gs_gO!tO)D z?(>6BL{|_i?z)cqtc%)Ci4%q07ho(d>qrI6xI19kSkDS~>NfgHQT8E*^tvgLa1O{y zsKP1Ps&&{^z-8f4vA$yh$vaw0vG7_m{cNKT_Gt^oG6Xa@x zTA}7+;IgDGuX7GbFj2P~6j$7Tb{wtrX#4+@?ue~Ky@Z3p!e*nOV+G<#8012GFg*K9FDLVyD z{!ArK`jJ)QRKKQ5jRM zpT-tL(!URH$SCgoH$r+~I|Ie6K;yJ$e@e_UI|)%xn+YJ#M7%95o&%ERu&d$GzH7#^ z4Roay_WuRD5&DYw^H}b5@q|(;E}#l}Sbc3VWN_ngm{uD`&bA>s;8TZR3-1|}Z#p{O zqup?&Wc@v`!lBTa>x4xYCPHun_6_P+?HD8->11)H|GL7~k$l&>d zh6fh}7$?Bx{!Co3Qv3MN%!C2sa^K?juk>IF-_By7LD!LPSgv*sSAP&54mlB6JCOEJ zHOclYt%Sc2&S07`0J}b~qQN0LNQ4E#rqUz;M&}_h9l)`3 zeFRq*tkTaU74Z_vsr5T)M+H16DrVqe28jF|0;;CO7FJ)Xj=;) zBe#O%fJ+W8cM+gWbJp@;+O%Tx&2>f625apuae|SfqybP1@W2{{Xajk)=OZJdmcum) zbcKQvW5!bTGpN*xDn<_l&woSiwtjNYrbpPy{5PH}=~4EFt;!i#Byw>cGQwgHy6`lu z_H*c985frT63FKYfGI=J#5WiX`Ju{Ba5~bUi5Vc|10QkdS%kL0azA>H&QYq&W3ihys}s zaVp*rX%RD=2gRKJ1!jB_HlaEaX$2dweQyZwa5t_I%zg@O8ag(!J{SGQnCY;wpSkS_ z!qFdt*1`P{8_XJdz7Q8)kSDKaKJO6InA@Q}4tfqw(r+5h_rC6kwIB!;R0+~|X8{5S z7@~ti9KV4O9iVd)L6J(F=&ps65Siq`E&^M~FxKDyHi|TD>ed@B9oVG}yI8%!L;U1N zBq|6^tAKJrIb^q*s=@8xEXF+#v#!3QVTJqw-O#`yAoLbU(qYeF*Cv>nMdCzCDztT=WeHuQ zPtEHc9!9`j(ih3=91@o}{QAGV#Np<)LGikweSnfsGod%I16<;uCoaH-D+gCE!y7Ij z$SlvYP8ioI>x>X)vQ&zr!csU{M<$;ER)6vy8(eXpGT$oA$?OzwnExO|3Nz1&(_o@| zeszj;4Lm2zf6yj@v&sP@&pay~S3r-5?YOq{7&N7!E47bix0u_JvIv>sI`S~-b zVf_R0tTCA18R0fWfircp6EbRU@$4eZPwS$J?VgLYuRV+J=bj7fqPjn)uS5o041l9L zfEVCVW(|2)6^;Fd^FD1m-e%-0nd)hgX>?#M>twn8;upWrvn!_ENRT&2`#utAWI6%_ zCK48BtAo%VxtL<0S4SmBcPhE5f<|#J>*~u_dpelsh$JwD^efTX20Z(xfS}^_vc|!5 zla?*o>qHX5*~0;b#`a8PPYyVJY|jL8`-3iE#ccdAYKcm-e%VE>U_F60tTBo8xqz^+ zCWxDyOr-hBRG5tVmUS|+VtZTaIUx8hXV->{9q!M&!t_;$b$bWQ{jR(q?1u4#PG|J7 zX%J#~g+;C2Q-~j1uor&8?qj*|^F@m~78z}@U%2M}paq7MzrYwUtlTWx121IjqdRc+ zzDCy7-~mdQ8R{DghE5bi<@2&IRVmKMSK~C%=97r`Nha;JtD#%3QjzPG3D6T3C!0g> z=y)oX3TfZbiN4VbpehX72Aj8q6okC>4?@pUpv6^PjShHCUz+F@IbOZt8aaO7W4Xz^ zdP32{_I8%jbUFUuhDmb#yN~50v+D`<7wUb<%#hVy$fNC~F(FdL%v74Xz_duj9rUx{ zWvu|En17wBFHnKki)G0SiZlGIw9QY4l z&;OQw?y83%-2OHCxsNoVUPWpXf=NI396oo1@c1SENAdq(($A&L)&EvMmtuXrer_WD z-H1?$|6KfU#=i*v0{nCFx8o1J&a=?#{6EysWj$d~gCD`a8UG!WcTx}Z|2O^IfgnmT z^>d$v6aAGOkMa7sanuFlK#_Owc-)A;2mhpA?N{`3DJJqthW{7(xh&6d@&0@L+(h0# zMG?Qm|3&;?!GAyghw(p&|3~;^T>dZU=Tc#cVfi*T9{lt1zZw6rarr;d&xN&xlh0sH zL%@^P4;0(WI^_e#=fA2RdgpH3ihcR>Uo9z57s*ToE&v*Vo;ISvjLPO0|B4xvQf&UP zLPEMFrYN+Ph31;R!ifMs_oMSuf* z`dsIQR>Q7IoHZnu0k?8qIH_ z&cI=8xLAX1!H^~#MnTyhai1oeFW~qkjle`2m=F3CV^h&^T4*E0h{&1JY04X@TcI+K zvSzBuTgVU%b+K9I+tl-Y=&A=vZjZa&EN)w(INWd0%Zi&gRvfO=K>09Rj16Hn;e{+O z7@bMfpP)T?Q}HH0!JHzbE}^b_@k^#>z|4RSJINsX)H@9*$iU7u?^4b$h4k_Td^Ad_ zB?yiw`)Hn$l^Rgb=%Ry_!74&YCxGNiDCtlD=RDC>A@QPy}+5%e{dP<$^^ zZl;kYA*d!1#4_0*DKCNYXcZNJu0+rC+EJS8WU)8UyjWgn5f@+!yv>;Vl3Mwa_IJOh zV-P&ElqFm(I|AqfN*5CygZb8e;8~>AEmrFD02m_NOZsi$Q_^?CgDojT@2VVGx5OgT zqKSAyn+vlERJ@4&1$pfYoP|}GsH9>oRppi^Y1+a5E$HTEmBcylhrQnpcyt9yaI=%m z9S;>+Ttla>JvDSm+1A7Ho7mL0$aEPzdGV(1xl2`6SM z4&oPtk4uBzl`wLE){^S_!J~;*D4#ObxikNQ3M%Q!dl5IappHV$_gUrt2siZAQywPkF1kqZoGq09HGa;b6T0mJ~9=*Ro3pHHs zgkhn(iEhSNf-Cv%wSzxK|R4F&7i`FaFyIM zcD(pk_KbqWo&lj77ofLP3ktXOelN4TWeO2MZg4K!8nACnqd5BYP)s-NZy~Idg$ZqB za;iI(!fD&6XvwAhftf2N8$1D6T+H1`p|n3tGeOaKt6XMA{qIu6$tc$emdUs+f;dc+ z9Tc+18RbeqGO}oR7Lb6McxKS?S`#{c6VT!+U<_)AX^{(;0+_(K;cP|AX>mP3Er1}E z0E+ZD2w9KDj)RZX6$FQSLHM~1?0pW9tffF`qeCAyuC3RZP5W{ZVh}xvCPN>4v_`EAM{%tmi0Tno9SjWvSiwOMD-A`hX zvUsEpC!`dm%LC2V&tAe}S*Z=dVg{CE7y?)!?a&?s1vAO&BQ%g@YQ{=>{gpMG_E zlG-094on$H(~`GM<@&UD&}x8uAv_J;$IOh8t-qvMEAXnWgBkS*;J8OSa0s12+d~#W z%HlSBz#6W}Ka5lpj6Mls#4W)!bw&nEVKm^~k1Pmw)0 zvu87VhS;->J&D+96mMtG9qjoOd;X9;Nwvx-ewICd%AO3NDgGsMzrda^vL~aI7Qe#W zG%t1<0rot}p1tgOnmzm2^DKL6?0Jqo2iWr>d&b#wgguF)Y!nl7+9)Q< ztx-%=E~A)eEhZVpD5ev$QA}rOqnPkjqnHq8qnLJ9qnKc_QB2^@D5j;BCAXTE$$3PU*(sNY)C6V{a8xMhvjj&dg1CS-!I_;-&6WxQVKLS zR1UqPmxJenej4kesj%as-GSaSJ83pt=%he-FQt4(&oEP_485a7S%=X&gd&g0-s&u5 z*lR*?37exd4LBW$JHqy#Q%3RogeP~BqqC6NZU$Py_#Hv3^S#EF;tD3q)S3k>Xpn$j+XcRF^?R#}4Bmsg6i6kttchViw(CKb_Awf|A(Lr%R+)x<>2NfMu zP*mJTKy=)76gLL95fl}7R8-XWKh@nK5uN9}Z{GL)-uJ4);a1)K{_nZxoV!$Y9hl8dE;r|~Gxeq7XaVBPi zyYxtgxcjAzABdY~p0@C@1(Ocku%pLC>B)>eNcPz;wTX~M4+)YjD3RhGLk z>D|4Y9%W2l5We!)on9aA#q8Ie>7LuGTV-YC{&dM4Q%AAcL0a9o19~tj$BnJSX9ii8 zKB&O-nA$QG7sJG2?YMd%20lXAqX(QG_@hT=5EEfiOc;MBQxaxSBoz+hb|UWU${L1~ zpIbq4snX;&`jf7UhPW<8&RkUQlTRvRia_WN5Il z#vd<>#cTYtMx-JmQsJ`HwEAGIwkbI>IER9E7h^ zHB{Hu*Qb5xk*Tj5IjqwoQ&C$}RyA_3&nSfxw1e`C*i^*d7!I<@C>x4|k|BRMbY_rk z3HoDhHVnm6DPAO+WP_1tYFZ1Mi20j>Y%|IZN83W368e*&Xk>3Xcv^vxn_s3@u-{ylUv)+}&w*&I?>(Y%fz`{&%aWP|MTN&|#yHk-Fk!V{4 z(qdRJS?y0G%fJFNgLTnZD(3p7pT~wGfoL036HFxh(}F{y?f4u;A{ZBi;y^e|CF7N5 zT*a+ri~yqhKf+y}xqm2*5B!11Kbk0G5+LvL5bzN25bzN25bzN25bzN25bzN25bzN2 z5cqc?u=|@*re&Hp*ZgE-i3AAvu9Tlzo05nc;C1Uv-(EeO*^N-Q-WQ*@W;5q*`Mg&+LRm(jQMYhG(!7f{_4Rx4{z>XrwVbWQoaYgaK=NEzSOQf2bu=GE>*&hnij#1d(7^G!? z>|;%fbgFFQtYk2OhGC1Ma{yBpM{2fmWJBdBcVDs~kh{T-rG?*i=&to!S;kHnjjM zbXRaD{>S!8D2~0aN%?u%Fe5)NuPDZ1kIs*+7S`X40h4Y#1@H(6L?b69!IjjP1S9#+ z>hLEnr#%{X3vu-Ls&VN5#Ekqr6i8Wf#ld7H(?gXx-6moagmTJEP>WxcWANlCEr>846|8&iV3Mwizi7P1(CJvbUA*r6&& zpkq7!F|JHNR3;-97zg(mUSu-7=*kL;LkM(br)(87EQNBY+;qH9WF|TYk|K`XF1Dbl zn3_kjgUG-RC^e#~g@z64PSpvyDAL1pgAOc6&>veM1lUppr`){QBA@G0zC{pNl=rXYOMXZkO1L7(Pm&UYF&dwR z9^D(?-NJS`xFDL5F$UX+?Pt;#Zr@LF1y5HwP#{L#FiPXfvrHO{&kp|rG=j*LU%$vR z^79$DQ+N`z-G9+ z|DG)?pJ{gU&q%Yo$~z6I78gS0|fzg5Z7MNesa1`IH{e!%FY$Evv3%4*x7J# zI%GCtP^45O9E!}?mq)Yy;HS=P#7xNsbOOlLG5cnb);%suQZIDLrc+odLh_SNT~K|9 zx3Rt7Dcn7P&>Bk;7h_EA4Qq0xTe?2%z~X^jI+F6~Qm>A9T_a}VWSZ5b+nI`tR7Dd~ zB?T$AkuXk>kPMVG$AiJbj6aMk^z~kUs;H|se+83_e|nf^MZ4?is-A4R&ciq!oR$jv zp#j0qE(Trl-aDMLY16p4k<#)et-JTFOxC|sVG(FV*gQDAk|`}4C!Oiu!n*q7fQ)M@ zWfUWIly@;lWiZHrI|@8bk7G%^z#U#eqB?7dl5PN(wNs3)7oB~(;;>RCuXm~IzSOIf zxgB&mo+)1n%aU?AD9l*jxJ5dDG8x1`B~!zdaz%}P9B4W-7>_olV2b{y;X_i*Y)dGaC}|BP5+%*y zL`!DmVesW6usLCn-IwQ%!@PAKvFNSAeL8<%7Z4wAMU6@{hfYp$~*_AAcur&LL>HncJ=7bBFcV8_dcu}+_Qnx@1ftym34+NS(=}TGz2bN z3jYjs@h^jahPwC!LtXqU;Gdx`{+000P#6E9@Xt^e|6%aYP-p+&YVYsy z@3RGSbC3m^2#SH$4;aD}z`h|v#g(@i8v!D?!ymjskM47Gf{iv4cftpg;P?!PG=GAU zQ#ed^L~zeB(j*y)Fs*X4O_xAt)Cy9FN7+$Wa{_K#e2N=~+7Oz8EZ`=iQDh%+&#i@~ z1cKxnfsGWJLK*`03r$Qz^h~nzmo7VqW;1khG&BXL6{AfI=Ej*j{F(xUDovJ+bUR|5 zXO>ilz2Vt;fIBkWO4EFa;uNOQ>S!PNHM>)ZtUhpMI>8lT3t}#IP0@Hf6{8c3X{6!( zZ@=ga-HyNG{N0%$f}j}382{~Mcp0Vm3A{bn8sb1XA&4eto zhk%#aWD?v>vH4<-85;~^y6Bz(9*$*_rWO{XWF~BNI&td`tZ>keStKk0*H-DYFygSt z1No6<3dU`m#U^0K;EZVj=D{fUU%5JLToN{}eVo>BWK)uDN;nW6W9w==vJFIO z<cN zdl&IRg`iSU11Jod4_X3R1zHc<3fc+k@elltET|CF0BQ#<1+4{b27M0d@m?9j5uv_3 zTN?|;(-Ri5y7AB&f=)+QFakR=%3{%?B|VkFnqr4N&xjpinVvv=iLHvDKQeLz-3`;g zJ&}ztnXM|RO`F<`(vdbZ^+V4702Fj0!KiFmd>R`LCCH?R;&?PVTVpHRgH0seS}~n= zCn1c^4naqyr+e+3(8iH;bk^G?aEX=9>fX{mWqvr&v%9N5OBRgl<*j2cT%kKGXpe>qbYEik&KQ=AbLwgJO0jdr>@ zjF4%M+es*mEGa>A>+YWZ4+o)6As*7rLzvE1g~P#V7@dh=a0VlCESbke(MWh!I^#6I z5C$UpD_b|hh5Aqw*dg)g44lM|g=pnd6xkYovW3kyl#Ql)G!Sh?FH_&rI{}C%rQ@MH zaO$2V7LNyGc*03`nt!_G$*4=Fw*sh?JFRYurocwgrlypuQ$;0>qr2wZ!I{Wkr8Z;D zB^pm3=0~T@#9DJl-WoeJ`*H#m9%_wYIUj|CWkj8=$S&8oH6u$JydrUX+n<=#+87Oo znlK~)1m3V{qD51f9N;(!JdiwzxFFFI3y8{yOI{kJ zi)ayM9ey@_C1@LHD`+$5SrD67bP(;i5_P`j#M1fEZ-dv>H*^mAm+$K;{?F1|AHs$O z(dD+MQw@Ikygx+pftm1QaNjL+e|4w(OK?x`TGDlCr~At~-7o5Ne|e|-#hvc2=ybmy z^1_>*?s^yfP%NndcK<7mfYaq7Ilt;2*vW9`z@_!{2Dmi2;owrbZg6|U-F$Z$b12-^ za1Vn!A8voR)o>}}6W|^RcjuZicWrPj+@tY)FP~I$38MCpOMc{1dnkSfWn}h+-~mBSb>h8I&apz0fEHh=x^ew`^@n3%Zt#`h|TRSO}KZ&Lcg9)_!rZ`>`%qr5`V2c98AcT zjGY|2qsk1m~+gI-*A-=f9NKAP9DkioX#ZTD~x6Xc|uffh!iap43-FdHiq#q}@G z9=`f$Ea`(ZEyqdCMRpogVm1FWoj;_h8sjaBY8(Cd7^3=RR z@H;tgROQh6yo#z(4X2})$RLmYrC04aC7OLAZ-m#;f=^z3Ls`S<`n<7aRSkJ{RTX)4 zbq%BP%Bsso)#TMxj;ugC@~Vc7tQ}QZkvC*iW!b6uo%2l>kS+to&_5R*g3h}<1Uv*h z1Uv*h1Uv*h1Uv*h1Uv*h1Uv*h1Uv-(A0jX)ws%EsKS{VJ6CH_GMBj}p36K4 zdLFa`v>VhTk;@zj8U!*xBS7Oo(?K&q7l5t<-2!?T^gL)A=o?TEVhtmCGCo8VKS*rJy=cGiWyGQqWS+O3>Y)zkpr@y#x9Z)D3Ms z7E}!KfhK~Ip#QGR!|lI@?Ac5u4)@Ti6rE7HA-5s(k-cEni}{wmL06uN$FZ@W^^E1f zuK|m2NP99&UwWqVCJpqOSY0|4Z{ww6RFN{~+MMC|f@7I` z`tV2!rSIoqIgri|-p&jSrxGocn$F*%P=O?uZIRI+na(h`YI&iyEQt2N~(zlQsE$F zF%qXVQU2Wwl~lR+ONjMoR%99)b z^+Ek!E;!Jw4Oq7v2VS#m$vmGs)*ng^jmGQI%5bo@aXMZYVk($)Z8Fh-ifGLl*#{BVM8e#Yh z?CJxY8mSGPkR9WXhv+O#8RJif1Ztbp{r_lAb$N|H){)ox&d}!&vGNT0 zdigc^Bl%nTVC7JypK_$~k^Y0e()i3c+pd(gMh_muBDU#`=`>E#S|M8|N(Ia8fxC+aM47CF~A_c#wb8=YsIZD`*v zY9GfiPr~WT9m}1-6>>wlT5b$Ck6X<>$L--x;gkGA{(gQV|0I8yaH3!f=L^>fcL`4j zjCi~l7Td(L#e2o|;uGT6VvaOOx=VUc+9Vw>7t4}-hrCYSDCuX6D%4u_boB~# zhx(QJqxyo@OHb$*>Pz&ajKRjK#+$|=rfLo`hnp9g51F5vqIIejvi@v6XT5H{WqoY* zv=6tBu}yoZU2XUB4fUmbxB6c7F^=g>cdm6Fqjr?yP#>J2yi|Tw-XgyvcT)}mhKDQ1 zD90;<6M*rI^{a<#Q?#&_)Mjhv zYg@GUv;w_YSM*EtNAyqi0;AZ_jFH9|V~TOHafQK{eaxBW+2*6>Vb(Bfv^Ck9X=S&oZg1`JO>-`GRyuc4{V`jjLwsM0 zJ*9rq(GoAIQk67DYL(igdD0cq4bm!Uo%ERWlC)LYDRq~7$w$fq<-x$&lFQ|7@@Mjo za)DB&Oj6EJ&QkuMEK@e1Wp5}SDg#tQouE!v6Y4eUP3mg(b@fB_OLe!JqxIK{G)t?{ z8nifCdx3U^wnqCv`&{d-Yx*#Zu2%HXLj5v*g}z3AP5(^)NuzhC^{utPeZ0-vwe}hI zx%PeFVZ}Ge_q>mDPIH*4IQIw$KHxv)#|o2##eyg{iPwoM#XH3f;(OwU;uh&`=_&be z^xZ;bt#X&TNqt@oYA#}yUUpxM`x<+a z-E2Q)@AQ4?W1SMma)vn7j^CMw(N2d8t5NoWTp#X8j^$3qIM=yyZXCCZuNF=h&KCY5 z93_^C=ZbmCABI zR3B7kDfp^CSIv!r^qR)Ca&e6B1>7avQtl@1R_+<@Mec1*8GBe>T0Q41C9=Wqi3rN)hpF&)mzmE)XnPq z>i23-tw1|Ple99eTAQrR)D~-ZKyN$-z44m1L;F_C)${be`Z4+deUQ#!TpRijeWX5K zZ_;D>JdE-y^=tLp^tI3`f7M^mU)SFO-+!a$7zaSZ9AO*}X;osFMyXM2jDrja8*Rqj z#?!{D#y3X3dANBzq*#^N+v;!CSz{r=F0d9u^W1DbYQ1djvU2Q$A;k*qo1Lefmz}K+ zvkYPjeWP;|xd8g*eDFvqKMedahrgI#%wNy<5_E7#oiGNPWTtSVut9iE_)z#p=q(Nq zi^WQDrnpqRS^NYVWvsMO`Vw+susmL#F3*wkl!1x^c{fTK3x1uY%u_B>K3Dpxsyad) z4=J#pb|}XGaTxzYwJ2~p7t-z`?OI5HEsz190x7&srW5cLR4b_d543_Z8QhXZfjoj9<&Y3ml7} zyDEU-8sTl>0C9vkUc5)#E*>B)lom<1Nq0)k^0CSZN|7Qex>Bb!DG}vt2`hErrEl~=5E;g<* z9xy&IJ~zHIel{kVGl0hB<_h5Pl=-^(rn%Gn0y=$vtB-YrHOMNmEUUsAVNC=+Gp%#2 zORU?VMb=pNLXSLRZLl755cEb<_$qgz$iU zHE%TkVxC|XTDmpF8V*iru*O?ct?5?Wnr&T(k+ck&WTmyrT5YYh)>#i*>#a@Dv9(S+ z?6sF1=0&{c4t`j|ZIo6)9_&#IwfD7I`j>it<5uH&<70C=w9p&AAAN}QPWn9e{#;TZ zCh7xRkAQqWg%|jtd^O()t8OlT75``c8A!tq_#a@^u|lyR36?MdBXYDb9%C{hEEAp; zUJ?E-d?D;7=865pK_V}fi`C*}F$SqVPh22gFRl>p0Jl9Mz99Y`n(S+ET`x#cS@KDB zumWdDN$G6qGHD5P{2JI#>!p_=KR<=^%#)9h3!vXCVHr-9Ly(*EKbrevY(5UV_#_|iJI*P_=*n@=r=Kq_6Q2^_6pw~I5`dI{4&3&x z^pR8|m&sG)t6^;=m2;E}m8+FMDXW!7lugRZ3Zv%3mZ}DSCDgg<#gNeVs}HMBs9V&x zA)|My12vyEObciWwaa1EZ_>Wj_JFq>y-J_1pQ|s`AJhM)=NdhXevq|O!9V917a5Nj zn~WW>>T}Hb=B4Jx=1;J=j>_zrN_T%hi`PBK=Z9#xQTg?1^dm`m*I>^to;-)PJrUiQ65Wnh4AgYzYKDEQ`U zzDOt&z7)EPh2V-j=_ct>NtB1n&GOmuMe=I-e)&nc7vzqjn2^)cVY{6N>*jil+eekx zly8+9b&5I<*7C;~eI>f8&(|-~uY)!AEi_W0A)<$`#9U{W@sn|&+1GsBe8H^2m|2N& z@mK2wYcs6pt+2UHu`6LW*VzrgXrevU4!|D0+g@isY_GRB*@Jzuug*8tH_!rhD6(njuO?k(;!?rY2``tpU)aZUUz{yhE;eluoGd-!gc zFP(%L6OFCOLL25x3xy>ZTeo7aaX+-))51%_TfzszZXs997Y`MW#B8calrhdmi^GldnQI8tPDWoGaz$LCW8x-m5;T{$2ePcJhH*KW(t4X_eZk+G*M($j3iuS8GpV zCVG^9lFsXudOc)fP@kbcp+BehgSw=XU22%+$UjzA8l+!n+tl`-?qA zN30Uhf>d20J|b>}Jbf3o&zF#=he?BBi;^YUCe4n>=VE!KxvN9YYJPPfO})9mxn-h1rF?6=%D+89UIIBT81U_O(>SQsOV!S~x? z`S<3J#%e(`e;t3jxJmq*_?GyE_=DI@QltvZ^4g#QZje?=_h62OJa%>PGPN3($<)!PUco#x&S|Nof1o+RfTC+ICnppKH6&w|k&L zy6HXiQTjN2B6vHXKaEwE&mnjAKoWL?1$Zj7`g~&nY@9`qK}(FK(C{C@(%EI~hK4`e zoChRVxt8Bk=4SIB=HZrrnc#Wg{7G1U*ga3^Gj^9r>P&fi>EDb_fxLDXGd@mG_ZuN+pO-hg>jLjX%6}>EmVd$uLB7%pt1L&uRvx4jE0SU; zrOHsH8dfu58-PTPDKmlbJY|7$DeS@Pfb}h|Rkcp}3v}Jnm}9@HY=w=u1L*HkzK8BR zR=r(auXcldU4_+yqx2%ZRG$rAdsY8PKhWrJoCwK{Hm=TLSU45jaL7c4pDoRi7DyLM zSHcchhItgTJ_q}+uu;TbBCBv%b+BMlRv5#LYFJebn0-uyZVVVLu&`oA5?XS$G3OUO z!n~Nn?4mr>UaI!G;4IgATUwO|1bhnB8`^)ODIiuqKF8dhU!5_ZHKSh@?K zxfiJ`wN=_`jQ(}n!`gc2>L;~lF^?iXNpnbl{b4p`oo>;@`Sk*PvJHh6Y;6giTJUQiOq>rG8CSOpP(p?1sa+E0E?45 Apa1{> literal 0 HcmV?d00001 diff --git a/src/chset/CHSET00.WIN b/src/chset/CHSET00.WIN new file mode 100755 index 0000000000000000000000000000000000000000..fdc89ad27198bc152a2adfcb915802283a611373 GIT binary patch literal 1792 zcmbVLU1%It6uxtRr)8m&ijam_?iP){sFM)lf?%i8N)^!&K_B#CR~o1YWoQH!6un|7 zgJ4-&kbMwY1aT0Q;7j9!F!U+Kw;)oi%2I265?7Ei(st{2?rdr)l!#|$@18mT=R4;v zEgm`)FU&s@FD%S2F3z`B)c5+lJ|KV4KkA?LP+!z5YP)9#Us0FzWxbov^1b|iKF^o< zetwug$6w+d{u+Oszr|1R5BMqmA^(_v#@G1Q{4D>Lf5(5~m-!$3Z_Y(S+%4`AbK+sq z5(mUn;(771SQf{`8{%E@zBnyD5}%4M#TikGb7E6m5SPU7;)=K-LOCU8F4efB?~eWwin zPk!vSj&&FW&oX9A)3gqblF`9d5Ki07g32IdQP(-wjd;`G-!bN7Qw#=!z@%w~Ck>44 z4zdSEHZbKzWRw1MVA{PwQuL0BrYIBG8=Js2vEXo8dA}cKY+saxcI%FzzC#b;l zvV1A&-i}adY*R!0}FWP6J+5Sn2?D4^WLBw^bi_i5d8D=MFDGa+bH_P zpc@d3DL0I232?6^-W>&HJ|I9Q@>y#y@153?q9{^Qr8ccofFolMo~tmpA(i2V7z+Us zl7!;fVIbh6X>fsv0i0nh3%k@G8b*#0N&F5`dtFGNf=yl#gwr&AWC~#eO$d>5Ya6g4 zSeQ?$nqkBuP_Iq%a2^^At;ASC6m5hC3Szu#9iN~<*czOh2||ubzg8kJS#^O93iLZ@ zr%8g$eE{eg0*4q64j4j*0#OfCDOQB`5JklawkC<|QBu{Al@^O*OKv*+NS}-eTYxki z3;}FSW5Nwb<0vNT!(v!hbZ08_pZ^|SXxjsOD^(LqTAB#CPy|-x7GW5ZDg+WF1cGrK zr)k=wy8fEOwN>Yz!Y+QOd`%dO(O-T~%UMJL2n1C`}? zY%Vrt*c{t;^V!Qdo_*{WcXj70ja_Vyi&@OZ_-&ng+%6_|bYwXD*gMy6hs$)P;=`+} dQc7GxXQM-dI%QDJ}5*isu z5WNTrf-K@i*i#lgspw%53RWfuTLgvK0S8HTy(nQFf6$=4-F~lTCOe6T$ohJwr|W(7 zzW2RX)ityAnVE2AdOn<)nVy@QeqdeQ;T`cNyqb5Hcegj`-RrHZgD#J+t10h3?`B@% zck)R-&FA@1evF^s&+zB?3q0X#{0;s#Kg-|a=lBQw6aG1G@vnJ@Z}Fe_Z#?HpjEg{2 z#XVw1JSZL&kBg_ov*MI^QM@8v6K{&M;(c*md?YT2FT_{klGqeKieE)0O0p~iS(8(8 zPCg_blgH%~a!JPWw0uc6s9@ZKCeI1-|C6vm1>Z zSHn?ZViG?I;bN^c2v4@~RBzN*y6K8r6H#PJH5En(jzT=)9%AIxN~}@O>kX&G!Y~U% z*Nthe(6N)bGUmnr@dHeCRFZbH?KDBEGd)CSCzlbKy*56E=pEDSs&~4Iz$aVScbH(wyx&w zR*T}cvo2u?fKnNB)i?#vv zkCp+gP(7=qhm}E30-rp@81}rH9IrQ8C5Kk8Ca~6yVl45SDY}FPARSr(PimXv14s!X zPiD}H3heiyZmSnW1VgA+F97aq|b_|kcZ-}K8g>CyVY(t8y2Ge5D`rwq1Y&BP)0?Bn_*b# zuP14C6pi5p0bl9Trl&ULmltj=ip64s!G0-V8~El-6~&bzqcN}^W91QSaRf63W2?X! zMIa8hK^&OMJyBeb6BfgbY@=6946&>qe1-hP#ENoJ3^;*dP;6Q^#g%)-Fb?@9;IeV} z-NR|IoKenyaROT$P?FyLoQuU)ZsRPrSLY&9?$rsk#hNOh6P#PSIt_H91dCZMBb}{eX>fVzjlpw%4)#`k_EET=)Iha8KYh z?3;9Bi4AXZIw_@$@v_mg|1xb^+L3;m{GsDRwDU*JI{OExeTVEV8_c9rCkSvbM_?Ou z`gMYQyaY5;>maDtlO_BEiZ! p_iHRZv~cp`MIlO*E?^8dr^>6MDyv!bS~ag0RloXs_4fa5{{WuI9IyZY literal 0 HcmV?d00001 diff --git a/src/chset/CHSET02.WIN b/src/chset/CHSET02.WIN new file mode 100755 index 0000000000000000000000000000000000000000..32f3758bd6c51ed79c5bf9970a42164c76b10365 GIT binary patch literal 3584 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 literal 0 HcmV?d00001 diff --git a/src/chset/CHSET04.WIN b/src/chset/CHSET04.WIN new file mode 100755 index 0000000000000000000000000000000000000000..02dc4652cadeb81b41b240d26e2b34721bb7b543 GIT binary patch literal 3712 zcmeH~zm6P55XNh7?mTz4VGt6Dg*_n7n9UB`i6yiXAm>En79>Qxz_2@x2>m2TL_)}94AN+u-&ehJJ9pkYbNq|gz52RmySwVE>gwvbj~_jLd~*N8N65p6ClBr) z?fqNdn|md?-{1Rb@4f8D?92VP4!%2haxKrl$&GV`bT?T_~^IS zHTD}L`ZhOGdolj-+Qno4kGvcKvpWy=ub)`+`rGfkdF!)-7>DWK@!^w$UZ4HBts0xf z*7Dd}5eF;d+RCuDitoZotF358=`9ccl#Dvn%8u;GuI!74_=uPI9oU_p=P;>luwgc2 zLp~HkHN<*d4|P`ujr@hLoDUf3EW=oi(ZZcyi3+5OW@!b=a~GrCNuQ3KmoCqwnItEyFu-t6Z1zVI@IWrb%;Ti_8Dq&T^%KQ9g zD@5!yS2U;Io!w^QLIf0zvZ>>tQsJ^uGpbX2HuCBDYNu!Pf9m^KjFjnPfz&Bj zdWL!|!>(A4zY*&oy_$c?>0#&oP8r66thm5FP)L3kNnK+7>t^WkcyG5>Skbz){HA zJj+`LN>SD>fzDwd`Fn>s{^SulB?XDfv?hBfWm$a6UJq=3LAJJ7$UF3Af?0>kS&vHV z(PlvazY);mwL5JbesI^E1HYCvkD5J#v?Qgdx84D3)?<9uLnG^R?yNqGw(3Mug)}x0 zU*jf)irc_U{y3LHPF4DObc)!`VuKExYBx@`?v(rEu#jmn;X*-=gLp0-WMi=lwo`nC zgKKepTlH>D!EBv@b8%MkCoxT&oxS|P9~mTo0A@DZhVso;Vj)X=jG4SGfqLPbjAl+MqBO;S96Vc2(w^tLBM_qZRK zcaP_|+MgG9k11Da&+E|hRo0Jlcj>uz7n*QpOt&Cu1n9;l**KU2UVMN`P&zc~orBX+ zpSR?ZwWBIm+Uc_K;8ko4SH1o26}86Af*#7RU;Y!C>&aPd3)pb z=l5(`G_&}u$>Xp7>Qd^J<@?xF7P+KX&C;qSy)MZMUFUq*t&dELTtYj{sLoB3f_}X1wy@f!#X&`~mIAZ)gAj literal 0 HcmV?d00001 diff --git a/src/chset/CHSET05.WIN b/src/chset/CHSET05.WIN new file mode 100755 index 0000000000000000000000000000000000000000..2537856fd22e84fc6d9d9296a14b2b40ae9f3caa GIT binary patch literal 3456 zcmd^BeM}Q)7=P{#xk9@ZqGrd&I96RG&W~0yR|RPqWMFi| zybkgc&p)>gAO}z!^rczUNLU&yqELHPQmYw%hUP*5W(iu^+1&u9DmVI$qfaak1F#?i zWPl5O(2bRt?Z6hYei>ZLGk}$gSeawCGct>*GJhXL1*>Cy7gPae9s>rJl!FykgFge~ zTt(S3d)!tH%LQvU95;9gAu#}LER_u8h-4g0Ik5CI@=5P8zuylly8JCr(Sxs-di>4c z>mfek>w0089jI6oP4NlEr6F?y<-352wjcl!fCrd}3LKFw#03_jI*AM-344hGP7)zR z1+R04kT5h7P0f&LLL!hV%Ya9K+saavlTiECx)_<_q&R66U9^%q(Aq2ryma`wq=k9ujC8T2m6mlk zYFwIGN$&BiWBsLB8`oS;A)dr$>x(hYoMM~`4~mX(N1#CmVVrhj5-`&$_SV6S4B*8d z6)rB}o++A*M@N8gzM23$2{Dsm3Pi+P+IB%M9xw8zsM-=?2=qm9Rk%+hewp|8ry@3GJnf6wI08jG~$eA)&McP6DM!}`o@1;ioLHLdeUueBeI0-bq zAu2KyVCTf(O~B9-|NF)W^{2U--Yn|b8aC~@lw7F#ZP-P^6 z;KVM;#<1!zjs;hNM6k^ta9#!#!36}DdUjVXY0d$%TViJ{fyp`fNs? zC@~E<+#^44mS%h~b^FW%m!*C0y{*47HfgZu)03gnj_ZSE#jf*{6O9ckJvTzl`>%92 zK4`l!+BWe+bW3N4lK16zSuL3_icS5?M}@t8HV}#fHR2j*E_&-7w`ev6^1{WFAG&@g z*F2WsRLga1e5UBGEWu_EX%c^dzgo;zBd3~yK3*lE={p9*U>N2c4mHbA!%7lsbSkPe z|8Xi=&l&|sL&T8~Jqm9wiBl|ia8-Orm^I?EN(`QB{IZb)t&&q=jo@ZfUM)}?R4Taa zG(n~DngO`qY4NmbKHiTKGWuv}9a7!~8Zc zLcN^mT`!A}Yc-PCLeHMHIcZl<@;b-Ufs)1~T*-G{#~gU5i;H`?Xv`9f5oNrcGE7_? zK``9L#p|y|iE|P`4SrL|gi0r6Gt?gess0KRavX@5!5+{U;;4_AVbf8Nyhk?0H9-BC z6DtkpYZr?oS)vM7GlNt6v>65aXh4#Vd%_FZEMVl4G^5PNnspI5(BXJu2_f{j}m7 zEjE4b;KAyYU`)8|g~_O7-T%1H(MHHe2S)sB-Xi@{#s6c2 z6|i98!bLMF=YBknlgcdZ9mC^4Mm&~QB|Vpmc*U!o{n1z?E{5iFM@Kp?KJCl9ToZDP zrl$dC3U+0Ra41mYv(-J!wYL^<(M34lMUn4Zkkk6LZVF((+w*JUI76MGXrLi3UYyV2 a{CpiFHv$fv-+XQ!o(s9TV4l4o_tZbiE<6+f literal 0 HcmV?d00001 diff --git a/src/chset/CHSET06.WIN b/src/chset/CHSET06.WIN new file mode 100755 index 0000000000000000000000000000000000000000..a9138c1fdfbefeee2992698d3ad0e0c731844bca GIT binary patch literal 2560 zcmcgtZHQD=7(QS3Yn*kD8a94F$7vOnKJFUjQsmsNU0R`N^hZCk;I1nqi@_yKmz?DI zfn6hHupez?u?WFLAR<9RME6I?7Fr8|_#^0Q2GI{2$Y_djr{~<6)$t?nSLfV&?t9+n z{dnH@oShwBKRoRF{eFLc|A62BX#cpk)7#~(6%*bYUd7w%X>a_l=6>&>=duNC5nIOk z*c!HuJ;8?9b8Iu)!nUy;Y!`cz?PrJB5%wONVxO>6>|d(8EcbuYsD{H73%}*l=Y2u={C&RHm#-hfW6rs_jcgDoB6i=(H$*M*@=D5 z{@MP=p6@Jn?k3W>_qa3CW%)vvJm@MT|-Tl*D>^bjy%GA&gw zS)fi>oeFBz?UaWqpbnHlpd@v$NNlK0R4uA0^HmL{ggt5uxjjl7mOaYC5Qqyyq>SRp z+H@QtNvJR&M6rPy)M-d1T?0wKTy03iZ|J(4Y5YKgGoXgC4ZtD7Hq&68aHYu*hIpux zeLFO@p=lA)Aczmycy}_QYy>%7JFPPgaomVw>L81G45YO-8PjSU$JNx3(P*0CnF%_x zIgRYpfd#zb9+{dm z#wT+JpUBNRkfl&r(zcgzj>~OLtyU`=sI1B+at0_sS>H_d2;B>U2<LZ$V|X;|T)NeC#S zt|UG(nWku+bp`hdNY*dhNl>quBpo*s+cae^B&Y&Qvi2Azkqb)MbyEcc!FY0eM=;GW znyeWROgBs**ks&rA=+2Y4+0$oz6qoVUNDllB-wRR5=Q6~?q*=(sYvTcxhp(bIX_cb ze7+*{#rcfbq&F=nAJ;j-3?UU%Z)y`p0J|hlX2}7vPwPa7n8`kU0Gd2;Nl!6XN>pHG z8ik>sEYZD)1~o#GCE8EIFpb&Cp~~G6*9M>CuJ62kUg8ZB_eYH8Qi zt}&~Zy3NjzMP~x62EThv4pxKmo+D61sAlDnRpq{C`<~kQ5)^~5c>00Cb%Vvh;-2Hi zB0nOAE)U-`e08IUuE?T0tcUc_vC7e*qeI7rXNY7tsX~E}7Mfb1Je^7x-k$?ks7fsz z5}jlZ1Z<%MlrQ4$+oY8qRPEU<^%R{}J@HS@9F~WqmaTfO=t-PbOUIaV>+Cgl(KY{2 f&2XJjI*T9K_MnO>p_=NNnpG{8S69{2|8M*YJt>$P literal 0 HcmV?d00001 diff --git a/src/chset/CHSET07.WIN b/src/chset/CHSET07.WIN new file mode 100755 index 0000000000000000000000000000000000000000..0381d680c2ca4053fe89094dde19d6da2eed63fe GIT binary patch literal 3200 zcmeHJJ&znk5PiLUo;l-XXC;y`tUQa592qnxY#2+6=Kx`g56KDA5e~9tLN>f$@%G7q zGn^8T@dx+^v}H?9j6_HTeKOc4Vu=`w^);`$XICe{$T`$%->a(rnC`0To;iQ|wRg&` zt*Sh;Rh`*-^$h-(|6Bx)^*-A8J^AqHch3ON9@FX~One`z16=sI%Uu$4WH!zOvtmguwZXgkM|CGff(AU#M;*=S@wT{NXK zg$LNp2{$izTa(Mdn?^Xt+n65!16;wJW`fJYxQ3}rm1?JN!sXGzb$m41AcbK_@V3Um~+Qi^1vMi7(xhXS}9|X2I zHxk=o!fZg@GGYR<@xb0hMcXDQ%1$DiByfBlpA;;hw-J>jHY4jA(vC?-)y^;Pg8N?CpTQqWZ&`T*KyZUnW2TC_MVC8HM>mu1!j4Q@j@o`adX4c&4-pXeE~B}%+>e;}nc z#>q*7+M5Qa`19Ub9*l|dkGaGlPNcrA<;WbQwUos$^Mjx~*WOyzjvf|8TU#n3Pooqr zbY+39l~{1}EW4(RM=40Q3PP53od)Sj!EWp`2q&5PiB-Nv|E6@w9pQ;eVY^C5+ricF z47E(V6&2|X6I|)7G%9c^H~`o2T8Xz1y_yjWk}wyYA~~fb8@*1U<2ZI6zE9KS(Puku zs%SUeG~;LfX8ZsPXw%-27*VZ-wxuFrLB|H3BP zyo#L+f5Y(kGK;JOSYC+s_ZLm5#}B@Ze16Y{_Dg#@#Dr8EytDRb|}DMzFo+& z^1PYwuEu6Qt}@Ga#Bf|`2W$+>N>aR04X3j0;J(l(JHJv+V{R#XRuTM{$vqWie6IP2KUH!OPhBnZ;$q zV}}9_!B|eFEK<3cwWVjBI?+Wcftf(amR!q9U|-;oKqkQJ=`e&YaYVS#!vr~2Qc|f8 z(BqZU4$|MeUlx|?Os+=Ta4NG)uy^N#2Xl*$zhXmO5{hB%a6BhuEuml47K1(^7uXc& zryQHg3iLGs?)+i-;=4(x_XsoPfL(zp0x-B!iD7_JV%h>7+{hHDDI yF9(ANsEvNWBFa4XQ51ZU4hH8K(^&q@4imzElM^hjRxMjhkPGc^&965CRLG7J zR9Rf;32`b(PR17y2atLoE5R8!)Z#`q%7IG&Qwd>#lgIyN?Ld_%M?mUGyWjjX@4b05 zZ+4$A&(D^gEzj^N&(4-+fbq=z3?ACHFmm$NpBepZ>?DiX?2Yl0=Kt?=V_C;}6=ve; zr!E2o&2~;-wx^x6XJt{PeO=PtDxd7?G~kS~H!-me7W7qceUDOQ7c_9E{H694??aLc3aV!em;dI?ha< zTSqG!iAW!?xm%hSN*nit(ieUy@J^0_jE)Bb1&0(7J_T^8J9tL1v z)q~J64jzk0N4tpRM@6W?65=OCAU_C~_2sTG2~Vzzuo4Hq=#gN5n<0UlTXX{+)BJ$E z8Ukn45O_%r6xXah5^L|o7N<;P-4G_UxTtjjUWadpyD3h?qhML>pQDiCh4a&P8`2*j zQ5#HcTe)`}`Y}dNeZRF7BU@uNW8n0c9V&eMrm9TslloHX*FVmE7}G8wd!|}h31x44 zI|?IkcP4udFzg%W6+N(YBKnlF~*cRPX372b>r(EglO zJj>2yunhQGwJTUqO@>w;a# zrt^8<`eTYz|B7eq`g8nTR4+TR)eXm>vqvJjee~X#AZXSCb?ceg}Ldz46>K5N-8+ zFr7;9v!{f=8}yalPVb|xGKn#5$=5&VCstxe`-ySLeyGfQKyN43XvjM$b3yVHC0YP{n{kUL*3>^RoC@6bzbkG)o7&iWU6cY p{fKNlSD@FC#t28+5hD&9G2+0(W;b6vJi_5|43FU7(vSZq?JxLAE(`zw literal 0 HcmV?d00001 diff --git a/src/chset/CHSET09.WIN b/src/chset/CHSET09.WIN new file mode 100755 index 0000000000000000000000000000000000000000..e1ecb9138436fe36ee8a21aa2b22a10c1b71ea81 GIT binary patch literal 2816 zcmc&#&5ImG6n{Ovo7%+e*5sqjs?D^?>cQJaP3(nc+jtf9U)T&NUWAq$EOD{x=0yU6 zNRW`fBLtMn#oRo25?rLlIRr1J!X7NJo$^=J(>pVpY{2ATz509~zk07;b@e+Jue`DO z`bFO^U%IsU7Cl8d(QA#~?0qzy5#2bLb$~zj_P`tUR^zSsgZS(C`}mJIS-P_H@lvNT z8@~f@FYu2qx7>HbD5fi-JIf8`+s9@$-R#>b?+(V_jvZ&08PR*}bM!>tg#I@AU&E}k zdG>LCiudx$vt#{V2w%bXQ|EfU_lcg1`olAkWeq<$ppq$A`e|nE+{w5nq+z@w^IaxBb8*341L#U(|E0|T}rMt1(<_h|- zg6-)Gi3>%;qN6sjZso^T=gdZ;V|i3{PPX+Z1@QY95`D1E(KFY0I=7KTK028>RWiLB z8C)FPG($pDK3~BBA5!Q*6Z)`%EgU}ZDpK?m^~oV4qC?d%SuxtpsGLv+=M4>BNi?U* zHU`_2%0C;aLX1^Wja6#)rEdfMsmydu+&5K*#?&@3IS6f;5BrcC zXN}N#WHVda8rNUvT0F$7RNL~#a(~!|t*NaLxbmq#RM+@pH~5^PVYq_MS-w{`bt87Y zPDiG&yZG1|zNb@@1KVVZ&u8y}!n0?s2wVDX57F}Z1TPB_x`na;qJ_32GuHRj1LSzZ_++q_G7z4ll-eh=ou`BpkDYty^cSzanp9PjieEnY>2f2keVOg$72`L3mv-Hn zpG~{kU^e@o)%?d7CRcBKxV|~->g>LqTLwYB4wc`Fv(A<7o;QE!zsh@P6JpMdky{kV z@b&XKSvektucakKtpldxhW=OSU4Tn z-i{l8Mt+7i$1SHX*;~BbbntQ^@cR9l|W#XcFwa?IAx)Y`N$symgW}_zBF> zfu9O~B7`6dzRY1Na+#c$&13rKDad@pKK40GGE-SNYc}uaAJ_El*orHwM2L^@-hZ+7K_;=vIe+Gt5hQmOO{|^AQ@j?Lr DIsYZF literal 0 HcmV?d00001 diff --git a/src/chset/TRI08.CHR b/src/chset/TRI08.CHR new file mode 100755 index 0000000000000000000000000000000000000000..77eea29ad9c4e2c58ea35770f34619ee376a3af0 GIT binary patch literal 12344 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 PmgLf~=9KRj|LXq%<~V`w literal 0 HcmV?d00001 diff --git a/src/chset/TRI10.CHR b/src/chset/TRI10.CHR new file mode 100755 index 0000000000000000000000000000000000000000..b8b90682b05f7b1d9defc08294d4c36ea8a1efb6 GIT binary patch literal 13924 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 JrNLr5{~ye&1aSZW literal 0 HcmV?d00001 diff --git a/src/chset/TRI16.CHR b/src/chset/TRI16.CHR new file mode 100755 index 0000000000000000000000000000000000000000..559be150f35978cf0c0f6e9d964f9fcdf1c2e1de GIT binary patch literal 18831 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 literal 0 HcmV?d00001 diff --git a/src/chset/chset2 b/src/chset/chset2 new file mode 100755 index 0000000000000000000000000000000000000000..807fe8778b4968bcc6ce47bd1908070eafada25c GIT binary patch literal 3618 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 Rm-*Z5nEmFqdGJ57e*jXP&b0sl literal 0 HcmV?d00001 diff --git a/src/chset/chset4 b/src/chset/chset4 new file mode 100755 index 0000000000000000000000000000000000000000..a027682141f2a6684d556dd9b201d582ba5ecabd GIT binary patch literal 3746 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 literal 0 HcmV?d00001 diff --git a/src/chset/chset8 b/src/chset/chset8 new file mode 100755 index 0000000000000000000000000000000000000000..412b45def809f38900f8842eea60ee96f648d661 GIT binary patch literal 2722 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 BBqaa< literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned02-3 b/src/chset/demos/ned02-3 new file mode 100755 index 00000000..3aeaec77 --- /dev/null +++ b/src/chset/demos/ned02-3 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1S<R(D0S=R& E1X1 \ No newline at end of file diff --git a/src/chset/demos/ned02-4 b/src/chset/demos/ned02-4 new file mode 100755 index 00000000..f9202a9a --- /dev/null +++ b/src/chset/demos/ned02-4 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1S(RPD0S)RNE1X1 \ No newline at end of file diff --git a/src/chset/demos/ned02-5 b/src/chset/demos/ned02-5 new file mode 100755 index 00000000..7f16771a --- /dev/null +++ b/src/chset/demos/ned02-5 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1SRx-D0S Rv+E1X1 \ No newline at end of file diff --git a/src/chset/demos/ned02-6 b/src/chset/demos/ned02-6 new file mode 100755 index 0000000000000000000000000000000000000000..95e15ad9d2559001cf13e4eef3fcf975bf5cd266 GIT binary patch literal 100 zcmW-WyAD7w6oyIIJb>gk9GgwgDi-2|MqScY!pn(ARkrVfQ(;gT89PH1>YxmlM6gf$ r9hb(icY_eyY!YL(^5eYllUO0`h)H`{{#faiuI;eYcWxG6LKr8%4e=F- literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned03-1 b/src/chset/demos/ned03-1 new file mode 100755 index 0000000000000000000000000000000000000000..adb744a304acf355bb265ef15b1ec87083572dec GIT binary patch literal 237 zcmYL?!3u&v6h#dTT!jlM@NVV<4Brrg5D`fZ5|)ai;79ZUeNEWjMeX{$#!+&07U$jb z&=L|t%29GiLP*Gva0n>N?hM=!Yy=tf_G`FOZwuAQ9SZ8RKy_RVi{78)dX}5Nq)7&| z+#0EKUoP`B%&(?x>vnfA?WJx%_t0M)N7eDIWJOb}OCp(Us-l#}cx8Ofm>~9G6hs2L PclUg@ivmHA94-F=(+@S9 literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned03-2 b/src/chset/demos/ned03-2 new file mode 100755 index 00000000..12914e58 --- /dev/null +++ b/src/chset/demos/ned03-2 @@ -0,0 +1 @@ +X0D0G1P1E0/00S OVERNIGHT PREPAID EXPRESS0S,PACK 5 x 17,501Sl, 87,50E1X1 \ No newline at end of file diff --git a/src/chset/demos/ned04-1 b/src/chset/demos/ned04-1 new file mode 100755 index 0000000000000000000000000000000000000000..43d3a6e6ec37ee7ebdf41413537d9519f737cab3 GIT binary patch literal 245 zcmYL>u?oU46h$l4O{9~G&mrA9C`|+x5wV&_4b@nZ2=(Wr?j3aV^GwoWhsT9`?mJLX z;1qHOB?F|8QYe5k*nkeg+DFs|X@mM`!k1g=cL3@TIfMQTK<&rwqnUSb(!=Q=(he?r zxbo2Iz6@oa%8Pf0)?M$sduZLyE!aggDup~{iW4C|?$T8Ceni!Bl#eSEaICB61 literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned04-2 b/src/chset/demos/ned04-2 new file mode 100755 index 0000000000000000000000000000000000000000..e2ea2b621a57d2af316358d814239c30419d75d9 GIT binary patch literal 107 zcmb1+FpzdJkajne4ltB{}*gXURD16dp#&Y{5}{=Tk3 z3L*X>jy}>rg*hBjhDN431_odS3XY*69{xd|!JdBZ3IUFhzOH^DdU|@&u7=VPh5)y= B7j*yt literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned04-3 b/src/chset/demos/ned04-3 new file mode 100755 index 00000000..df8f32bd --- /dev/null +++ b/src/chset/demos/ned04-3 @@ -0,0 +1 @@ +X0D0G1P1E0/00S,DEACTIVATING RF SECURITY...E1X1 \ No newline at end of file diff --git a/src/chset/demos/ned05-1 b/src/chset/demos/ned05-1 new file mode 100755 index 0000000000000000000000000000000000000000..4028b840d4ba8d0f6fb4708b91293a951607d094 GIT binary patch literal 82 zcmb1+FpzdJkajne4ltB{}*gXURD0|j+>LOdM(ycHt- cLlr@M8HHe1R}fFZ(cRJ0Pf^;{P&&d80JIYkYXATM literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned05-2 b/src/chset/demos/ned05-2 new file mode 100755 index 0000000000000000000000000000000000000000..3c4ca4a662a49ea9bfbf2b8973040caaa37e11cc GIT binary patch literal 178 zcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}u&)7U7T%s?Y_S REy^h!RHiNMYA79H2mscPD0%<@ literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned05-3 b/src/chset/demos/ned05-3 new file mode 100755 index 0000000000000000000000000000000000000000..43a377c4b87f9d22a1322dddfcd5995f5cbb30d4 GIT binary patch literal 178 zcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}u&)*5H>83XlVv RttlWKHTYA79H2msWBC_(@L literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned05-4 b/src/chset/demos/ned05-4 new file mode 100755 index 0000000000000000000000000000000000000000..791fe8c1c24078bdee2725160ec8977a8166081f GIT binary patch literal 178 zcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}u&)wgGC_;0K#+ P3)HU0EA4719bpIn(sw8d literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned05-5 b/src/chset/demos/ned05-5 new file mode 100755 index 0000000000000000000000000000000000000000..ed0a33866fab3cb51c1bb06c4221e2eda77ba24f GIT binary patch literal 156 zcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}s(_8cIhP0sxFy BBqaa< literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned06-1 b/src/chset/demos/ned06-1 new file mode 100755 index 0000000000000000000000000000000000000000..61b723e6358b60075d79eda205bf1aecf255b54e GIT binary patch literal 40 tcmb1+FpzdJkajne4ltBWlmdh@08?vN7J^g-Z(xuP zau5KS5WJC5I>?R>q+^W~R8kBfDGrx3fJ*8hBz3`(K;w28y85~6`}s(_8cIhP0sxFy BBqaa< literal 0 HcmV?d00001 diff --git a/src/chset/demos/ned06-3 b/src/chset/demos/ned06-3 new file mode 100755 index 00000000..3aeaec77 --- /dev/null +++ b/src/chset/demos/ned06-3 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1S<R(D0S=R& E1X1 \ No newline at end of file diff --git a/src/chset/demos/ned06-4 b/src/chset/demos/ned06-4 new file mode 100755 index 00000000..f9202a9a --- /dev/null +++ b/src/chset/demos/ned06-4 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1S(RPD0S)RNE1X1 \ No newline at end of file diff --git a/src/chset/demos/ned06-5 b/src/chset/demos/ned06-5 new file mode 100755 index 00000000..7f16771a --- /dev/null +++ b/src/chset/demos/ned06-5 @@ -0,0 +1 @@ +X0D0G1P1E0/0D1SRx-D0S Rv+E1X1 \ No newline at end of file diff --git a/src/chset/demos/ned06-6 b/src/chset/demos/ned06-6 new file mode 100755 index 0000000000000000000000000000000000000000..2caa83db537d094b3cd1d2091ec87202355232fb GIT binary patch literal 109 zcmW;Bu?oUK5Jgc11^?kS&(1=~PAfKR9Ad(nU3MlAe=hi`iFWsLFb6yXIzbU=K(npD z4m;HE{U>(Zqb@gWb-H-wL%V*wa+u6nQf!ru-$>uS!cYQOD^q11wn3QLzV3rjC CyBKBw literal 0 HcmV?d00001 diff --git a/src/chset/headers.bat b/src/chset/headers.bat new file mode 100755 index 00000000..f1d30bb8 --- /dev/null +++ b/src/chset/headers.bat @@ -0,0 +1,14 @@ +debug < clrscrn.dbg +debug < headers.dbg +copy/b header0+chset00.win chset0 +copy/b header1+chset01.win chset1 +copy/b header2+chset02.win chset2 +copy/b header3+chset03.win chset3 +copy/b header4+chset04.win chset4 +copy/b header5+chset05.win chset5 +copy/b header6+chset06.win chset6 +copy/b header7+chset07.win chset7 +copy/b header8+chset08.win chset8 +copy/b header9+chset09.win chset9 +copy/b clrscrn.bin+chset0+chset1+chset2+chset3+chset4+chset5+chset6+chset7 ..\..\bin\chset\std-chs +copy/b clrscrn.bin+chset0+chset1+chset2+chset9+chset4+chset8 ..\..\bin\chset\ned-chs diff --git a/src/chset/headers.dbg b/src/chset/headers.dbg new file mode 100755 index 00000000..c3eb35f3 --- /dev/null +++ b/src/chset/headers.dbg @@ -0,0 +1,75 @@ +rbx +0 +rcx +22 +a100 +db 'Downloading character set 0',0d,0a +db 1b,'.0' +dw 0700 + +nheader0 +w +a100 +db 'Downloading character set 1',0d,0a +db 1b,'.1' +dw 0980 + +nheader1 +w +a100 +db 'Downloading character set 2',0d,0a +db 1b,'.2' +dw 0e00 + +nheader2 +w +a100 +db 'Downloading character set 3',0d,0a +db 1b,'.3' +dw 0680 + +nheader3 +w +a100 +db 'Downloading character set 4',0d,0a +db 1b,'.4' +dw 0e80 + +nheader4 +w +a100 +db 'Downloading character set 5',0d,0a +db 1b,'.5' +dw 0d80 + +nheader5 +w +a100 +db 'Downloading character set 6',0d,0a +db 1b,'.6' +dw 0a00 + +nheader6 +w +a100 +db 'Downloading character set 7',0d,0a +db 1b,'.7' +dw 0c80 + +nheader7 +w +a100 +db 'Downloading character set 5',0d,0a +db 1b,'.5' +dw 0a80 + +nheader8 +w +a100 +db 'Downloading character set 3',0d,0a +db 1b,'.3' +dw 0b00 + +nheader9 +w +q diff --git a/src/chset/hylab.tmp b/src/chset/hylab.tmp new file mode 100755 index 0000000000000000000000000000000000000000..a7dc9b72ad57bc9741484fe4f510265d14780c67 GIT binary patch literal 45298 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 W00NL=na>2B+7&Sy@uB{0`u_t4TL@eL literal 0 HcmV?d00001 diff --git a/src/chset/hylab0.tmp b/src/chset/hylab0.tmp new file mode 100755 index 00000000..8cff0b01 --- /dev/null +++ b/src/chset/hylab0.tmp @@ -0,0 +1,14 @@ +! 0 0 0 0 +GRAPHIC STORE PCX 3 HYPCX0 +!S% 3 E400 HYFMT0 +GRAPHIC RECALL HYPCX0 620 50 +JUSTIFY CENTRE +TEXT 2 712 5 DEMOLAND +% +JUSTIFY CENTRE +TEXT 3 712 260 % +TEXT 1 712 320 % +TEXT 2 712 345 % +VARIABLE DARKNESS 20 +NOINDEX +END diff --git a/src/chset/hylab1.tmp b/src/chset/hylab1.tmp new file mode 100755 index 00000000..a497aece --- /dev/null +++ b/src/chset/hylab1.tmp @@ -0,0 +1,15 @@ +! 0 0 0 0 +GRAPHIC STORE PCX 3 HYPCX1 +!S% 3 E270 HYFMT1 +GRAPHIC RECALL HYPCX1 299 0 +JUSTIFY CENTRE +TEXT 2 725 5 NEDERLAND +TEXT 2 725 180 CENT +% +JUSTIFY CENTRE +TEXT 3 725 105 % +TEXT 1 725 230 % +TEXT 2 450 155 % +VARIABLE DARKNESS -20 +NOINDEX +END diff --git a/src/chset/hylab2.tmp b/src/chset/hylab2.tmp new file mode 100755 index 00000000..78142bb2 --- /dev/null +++ b/src/chset/hylab2.tmp @@ -0,0 +1,19 @@ +!S% 3 E150 HYFMT2 +TEXT 3 (-21,180,1,1) 649 90 N +TEXT 3 (-21,180,1,1) 619 90 e +TEXT 3 (-21,180,1,1) 594 90 d +TEXT 3 (-21,180,1,1) 571 90 e +TEXT 3 (-21,180,1,1) 548 90 r +TEXT 3 (-21,180,1,1) 533 90 l +TEXT 3 (-21,180,1,1) 524 90 a +TEXT 3 (-21,180,1,1) 500 90 n +TEXT 3 (-21,180,1,1) 476 90 d +% +JUSTIFY RIGHT +TEXT 3 (0,180,1,1) 453 30 % +JUSTIFY LEFT +TEXT 1 (0,180,1,1) 827 32 % +TEXT 1 (0,180,1,1) 827 3 % +VARIABLE DARKNESS 20 +NOINDEX +END diff --git a/src/chset/n.bat b/src/chset/n.bat new file mode 100755 index 00000000..a6ed79fb --- /dev/null +++ b/src/chset/n.bat @@ -0,0 +1,37 @@ +copy chset.sh ..\..\bin +copy demos\demos.sh ..\..\bin + +call cognitiv.bat +copy demos\cog-lab ..\..\bin\demos + +call headers.bat +copy demos\ned01-1 ..\..\bin\demos +copy demos\ned01-2 ..\..\bin\demos +copy demos\ned01-3 ..\..\bin\demos +copy demos\ned01-4 ..\..\bin\demos +copy demos\ned02-1 ..\..\bin\demos +copy demos\ned02-2 ..\..\bin\demos +copy demos\ned02-3 ..\..\bin\demos +copy demos\ned02-4 ..\..\bin\demos +copy demos\ned02-5 ..\..\bin\demos +copy demos\ned02-6 ..\..\bin\demos +copy demos\ned03-1 ..\..\bin\demos +copy demos\ned03-2 ..\..\bin\demos +copy demos\ned04-1 ..\..\bin\demos +copy demos\ned04-2 ..\..\bin\demos +copy demos\ned04-3 ..\..\bin\demos +copy demos\ned05-1 ..\..\bin\demos +copy demos\ned05-2 ..\..\bin\demos +copy demos\ned05-3 ..\..\bin\demos +copy demos\ned05-4 ..\..\bin\demos +copy demos\ned05-5 ..\..\bin\demos +copy demos\ned06-1 ..\..\bin\demos +copy demos\ned06-2 ..\..\bin\demos +copy demos\ned06-3 ..\..\bin\demos +copy demos\ned06-4 ..\..\bin\demos +copy demos\ned06-5 ..\..\bin\demos +copy demos\ned06-6 ..\..\bin\demos + +call printer.bat +copy demos\lpr-rec ..\..\bin\demos + diff --git a/src/chset/printer.bat b/src/chset/printer.bat new file mode 100755 index 00000000..0bf97249 --- /dev/null +++ b/src/chset/printer.bat @@ -0,0 +1,3 @@ +debug < printer.dbg +debug < cutpull.dbg +copy/b printer.bin+cutpull.bin ..\..\bin\chset\lpr-chs diff --git a/src/chset/printer.dbg b/src/chset/printer.dbg new file mode 100755 index 00000000..14391ccb --- /dev/null +++ b/src/chset/printer.dbg @@ -0,0 +1,21 @@ +rbx +0 +rcx +6c +a100 +db 'Downloading character set',0d +db 1b,'.0' +dw d114 +dw 0043 +db 06 +db '0',00,7e,c3,c3,c3,c3,c3,7e,00,00 +db 'x',00,00,00,c3,66,3c,66,c3,00,00 +db '|',00,3e,63,f8,60,f8,63,3e,00,00 +db 9f,00,0f,18,7e,18,18,18,f0,00,00 +db 90,c3,00,ff,c0,fe,c0,c0,ff,00,00 +db 89,00,c3,00,7e,c3,ff,c0,7e,00,00 +db 0d,0d,0d,0d,0d,0d,0d,0d + +nprinter.bin +w +q diff --git a/src/fsutil/bd.c b/src/fsutil/bd.c new file mode 100755 index 00000000..31035c25 --- /dev/null +++ b/src/fsutil/bd.c @@ -0,0 +1,198 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + UZIX utilities: + + Block dump: to examine disk. + Usage: bd d: blkstart [blkend] +**********************************************************/ + +/* The device is given as drive letter. + * Major device is always 0 (FDD), minor device is 0..7 (drives A..H) + */ + +#define __MAIN__COMPILATION +#define NEED__DEVIO +#define SKIP_TIME_T /* Nick */ + +#include "utildos.h" + +#if 1 /* Nick */ +#include +#include +#include +#ifdef NATIVE /* Nick */ +#include +#ifdef VAX +#include +#else +#include +#endif +#include "utils.h" +#endif +#else +#ifdef SEPH +#include "sys\ioctl.h" +#endif +#ifdef _MSX_DOS +#include "..\include\stdio.h" +#include "..\include\stdlib.h" +#include "..\include\ctype.h" +#else +#include +#include +#include +#endif +#endif + +#ifdef NATIVE /* Nick */ +int device_handle; +uchar device_name[0x200]; /* 16]; */ +#endif + +char buf[BUFSIZE]; + +void dread(int dev, uint blk, char *addr); + +void dread(int dev, uint blk, char *addr) +{ +#ifdef NATIVE /* Nick */ +/* printf("seeking to %ld\n", ((long)blk) << BUFSIZELOG); */ +/* fflush(stdout); */ + if (lseek(device_handle, ((long)blk) << BUFSIZELOG, SEEK_SET) < 0) + { + printf("can't seek: "); + fflush(stdout); + perror(device_name); + exit(1); + } + + if (read(device_handle, addr, BUFSIZE) != BUFSIZE) + { + printf("can't read: ", dev); + fflush(stdout); + perror(device_name); + exit(1); + } +#else + char *buf = bread(dev, blk, 0); + if (buf == NULL) { + printf("bd: disk is not MSXDOS compatible, device or drive error\n"); + xexit(1); + } + bcopy(buf, addr, BUFSIZE); + bfree((bufptr)buf, 0); +#endif +} + +void main(int argc, char *argv[]) +{ + int i, j, k, dev; + unsigned blkno, blkend; + long addr; + +#ifdef _MSX_DOS + initenv(); +#endif +#ifdef NATIVE /* Nick */ + dev = 0; + if (argc < 3) + { + fprintf(stderr, "usage: bd device blkstart [blkend|-blkno]\n"); + exit(1); + } + strcpy(device_name, argv[1]); + device_handle = open(device_name, O_RDWR | O_BINARY); + if (device_handle < 0) + { + printf("can't open: "); + fflush(stdout); + perror(device_name); + exit(1); + } +#else + if (argc < 3 || !isalpha(argv[1][0]) || (argv[1][1] != ':')) { + fprintf(stderr, "usage: bd d: blkstart [blkend|-blkno]\n"); + xexit(1); + } + dev = ((argv[1][0] & 223) - 65); +#endif + blkno = (unsigned)atol(argv[2]); + if (argc < 4) + blkend = blkno; + else { + if (argv[3][0] == '-') + blkend = blkno + (unsigned)atol(argv[3]+1) - 1; + else blkend = (unsigned)atol(argv[3]); + } +#ifdef _MSX_DOS + printf("Insert disk and press RETURN: "); + while (getchar() != '\n') + ; + cursor(0); +#endif +#ifdef NATIVE /* Nick */ + printf("%s, blocks %u..%u (0x%X..0x%X)\n\n", + device_name,blkno,blkend,blkno,blkend); +#else + bufinit(); + d_init(); + d_open(dev); + printf("Device %x, blocks %u..%u (0x%X..0x%X)\n\n", + dev,blkno,blkend,blkno,blkend); +#endif + addr = (long)blkno * BUFSIZE; /* starting address */ + while (blkno <= blkend) { + printf("Block %u (0x%X)\n", blkno, blkno); + dread(dev, blkno++, buf); + for (i = 0; i < BUFSIZE / 16; ++i, addr += 16) { + printf("%02x%04x\t", (uint)(addr >> 16), + (uint)(addr & 0xffff)); + for (j = 0; j < 16; ++j) { + k = buf[(i<<4)+j] & 0xFF; + printf("%02X ", k); + } + printf(" |"); + for (j = 0; j < 16; ++j) { + k = buf[(i<<4)+j] & 0xFF; +#if 1 /* Nick temporary */ + if (k < 0x20 || k >= 0x7f) +#else + if (k < ' ' || k == 0177 || k == 0377) +#endif + k = '.'; + printf("%c", k); + } + printf("|\n"); + } + printf("\n"); + fflush(stdout); + } +#ifdef _MSX_DOS + cursor(255); +#endif +#ifdef NATIVE /* Nick */ + close(device_handle); +#else + /* bufsync(); */ + d_close(dev); +#endif + exit(0); +} + diff --git a/src/fsutil/bd.exe b/src/fsutil/bd.exe new file mode 100755 index 0000000000000000000000000000000000000000..23c67f4d3eed8fde8b9eb847bac2b6d332663d27 GIT binary patch literal 57384 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 G?tcU9sN22( literal 0 HcmV?d00001 diff --git a/src/fsutil/bd.lnk b/src/fsutil/bd.lnk new file mode 100755 index 00000000..8658b71e --- /dev/null +++ b/src/fsutil/bd.lnk @@ -0,0 +1,11 @@ +-k ..\..\lib +-l libcl.lib +-l libsysl.lib +-l libiar.lib +-m +-u +-i +-o bd +-bl RCODE=0x8100 +..\..\lib\c0l.rel +bd diff --git a/src/fsutil/bd.w32 b/src/fsutil/bd.w32 new file mode 100755 index 00000000..b92273dc --- /dev/null +++ b/src/fsutil/bd.w32 @@ -0,0 +1,6 @@ +/debug +/subsystem:console +"/libpath:c:\Program Files\Microsoft Visual Studio\VC98\lib" +/map:bd.map +bd.obj +utils.obj diff --git a/src/fsutil/boot.c b/src/fsutil/boot.c new file mode 100755 index 00000000..ca22ad13 --- /dev/null +++ b/src/fsutil/boot.c @@ -0,0 +1,243 @@ +/* ..\fsutil\boot.c generated from ..\..\bin\boot.bin, do not edit! */ + +0x45,0x42,0x42,0x37,0x30,0x33,0x30,0x33, +0x30,0x35,0x30,0x31,0x31,0x33,0x33,0x38, +0x31,0x00,0x80,0xcd,0xa3,0x06,0xcd,0xab, +0x05,0xcd,0xfd,0x04,0x18,0x22,0x00,0x00, +0x00,0x42,0x4f,0x4f,0x54,0x20,0x20,0x20, +0x20,0x42,0x49,0x4e,0x00,0x00,0x00,0x0f, +0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xcd,0xd2,0x01,0x6c,0x6f,0x61,0x64,0x69, +0x6e,0x67,0x20,0x2f,0x62,0x6f,0x6f,0x74, +0x2f,0x6b,0x65,0x72,0x6e,0x65,0x6c,0x2e, +0x62,0x69,0x6e,0x0d,0x0a,0x00,0xcd,0x2c, +0x02,0x11,0x04,0x00,0x21,0x7a,0x07,0xcd, +0xab,0x04,0x2a,0x7a,0x07,0x11,0xc6,0x31, +0xb7,0xed,0x52,0xc2,0x79,0x01,0x2a,0x7c, +0x07,0x22,0x28,0x07,0x2a,0x7e,0x07,0x22, +0x2a,0x07,0x2a,0x80,0x07,0x22,0x2c,0x07, +0x11,0x01,0x00,0x21,0x06,0x07,0xcd,0x70, +0x02,0x20,0x7b,0x21,0x0b,0x07,0xcd,0x70, +0x02,0x20,0x73,0xcd,0x99,0x03,0x21,0x94, +0x0d,0x01,0x14,0x00,0xcd,0x22,0x03,0x38, +0x7b,0xcd,0x40,0x01,0xcd,0x5d,0x01,0x3e, +0xf8,0xed,0x39,0x38,0xcd,0x51,0x02,0x21, +0x00,0x80,0xcd,0x22,0x03,0x3e,0xfc,0xed, +0x39,0x38,0xcd,0x59,0x02,0xeb,0xcd,0x22, +0x03,0xcd,0x62,0x02,0xd4,0x3f,0x02,0xcd, +0x99,0x02,0xcd,0x0c,0x02,0x01,0x80,0x80, +0x21,0xaa,0x0d,0x18,0x06,0x19,0xcd,0xda, +0x04,0x02,0x03,0xed,0x5b,0xa8,0x0d,0xb7, +0xed,0x52,0x38,0xf1,0x31,0xcd,0xff,0x21, +0xd3,0x06,0x11,0xcd,0xff,0x01,0x33,0x00, +0xed,0xb0,0x21,0x3a,0x01,0xed,0x5b,0xa4, +0x0d,0xd5,0x0e,0x06,0xed,0xb0,0x2a,0xa0, +0x0d,0xed,0x5b,0xa6,0x0d,0xc9,0xcd,0xd2, +0x01,0x66,0x69,0x6c,0x65,0x20,0x6e,0x6f, +0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x0d, +0x0a,0x00,0x18,0x6b,0xcd,0xd2,0x01,0x66, +0x69,0x6c,0x65,0x20,0x74,0x6f,0x6f,0x20, +0x73,0x68,0x6f,0x72,0x74,0x0d,0x0a,0x00, +0x18,0x55,0x3e,0x84,0xed,0x39,0x3a,0xe9, +0x2a,0x94,0x0d,0x11,0xc9,0xa6,0xb7,0xed, +0x52,0xc8,0xcd,0xd2,0x01,0x62,0x61,0x64, +0x20,0x65,0x5f,0x6d,0x61,0x67,0x69,0x63, +0x3a,0x20,0x00,0x18,0x2b,0x2a,0x96,0x0d, +0x11,0x03,0x00,0xb7,0xed,0x52,0xc8,0xcd, +0xd2,0x01,0x62,0x61,0x64,0x20,0x65,0x5f, +0x66,0x6f,0x72,0x6d,0x61,0x74,0x3a,0x20, +0x00,0xcd,0xd2,0x01,0x62,0x61,0x64,0x20, +0x6d,0x61,0x67,0x69,0x63,0x3a,0x20,0x00, +0x19,0xcd,0xb4,0x05,0xcd,0xab,0x05,0xcd, +0xd2,0x01,0x64,0x6f,0x69,0x6e,0x67,0x20, +0x61,0x20,0x63,0x6c,0x65,0x61,0x6e,0x20, +0x62,0x6f,0x6f,0x74,0x0d,0x0a,0x00,0x21, +0x7a,0x07,0x11,0x7b,0x07,0x01,0xff,0x01, +0x36,0xaa,0xed,0xb0,0x11,0x00,0x00,0x06, +0x04,0xc5,0xd5,0x21,0x7a,0x07,0xcd,0xb9, +0x04,0xd1,0xc1,0x13,0x10,0xf3,0x3e,0xaa, +0xed,0x39,0x0b,0x3e,0x13,0xed,0x39,0x0a, +0x18,0xfe,0xcd,0xcc,0x05,0x67,0x62,0x6f, +0x6f,0x74,0x3a,0x20,0x00,0xc3,0xcc,0x05, +0x11,0x02,0x00,0xcd,0x00,0x02,0x3e,0x81, +0xed,0x39,0x0b,0x3e,0x13,0xed,0x39,0x0a, +0x97,0x3d,0x20,0xfd,0x3d,0x20,0xfd,0x3d, +0x20,0xfd,0x3d,0x20,0xfd,0x11,0x00,0x02, +0x21,0x81,0xfc,0xe5,0xfd,0xe1,0x01,0x05, +0x00,0xc3,0xdb,0x05,0xcd,0xd2,0x01,0x73, +0x74,0x61,0x72,0x74,0x69,0x6e,0x67,0x20, +0x6f,0x70,0x65,0x72,0x61,0x74,0x69,0x6e, +0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d, +0x0d,0x0a,0x00,0xc9,0xcd,0xe0,0x01,0x3e, +0x80,0xed,0x39,0x3a,0x3e,0xfc,0xed,0x39, +0x38,0x11,0x01,0x80,0x01,0xff,0x00,0x6b, +0x62,0x2b,0x36,0x00,0x79,0xb0,0xc8,0xed, +0xb0,0xc9,0xb7,0xed,0x52,0xd0,0x19,0xeb, +0xc9,0x2a,0x9c,0x0d,0x11,0x14,0x00,0x18, +0x11,0x2a,0xa2,0x0d,0xed,0x5b,0x9e,0x0d, +0x18,0x08,0x2a,0xa6,0x0d,0xed,0x5b,0xa2, +0x0d,0x13,0xb7,0xed,0x52,0x4d,0x44,0xc9, +0x22,0x2e,0x07,0xcd,0x99,0x03,0x01,0x10, +0x00,0x21,0x7a,0x0d,0xcd,0x22,0x03,0xd8, +0x23,0xed,0x5b,0x2e,0x07,0x06,0x0e,0x23, +0x1a,0xbe,0x20,0xea,0xb7,0x28,0x05,0x13, +0x10,0xf5,0x1a,0xb7,0xed,0x5b,0x7a,0x0d, +0xc9,0x21,0xaa,0x0d,0x22,0xa8,0x0d,0xcd, +0xa5,0x03,0xcd,0xc4,0x03,0x7d,0xb4,0x28, +0x3e,0xcd,0xec,0x03,0x7b,0xb2,0x28,0x49, +0x7b,0xe6,0x07,0x20,0x59,0x2a,0xa8,0x0d, +0x73,0x23,0x72,0x23,0x22,0xa8,0x0d,0x06, +0x1f,0xc5,0xd5,0xcd,0xc4,0x03,0x7d,0xb4, +0x28,0x1a,0xcd,0xec,0x03,0x7b,0xb2,0x28, +0x28,0xeb,0xd1,0x13,0xb7,0xed,0x52,0x20, +0x35,0xc1,0x10,0xe5,0xcd,0xc4,0x03,0x7d, +0xb4,0x20,0xc6,0xc9,0xe1,0xe1,0xc9,0xcd, +0xd2,0x01,0x6e,0x75,0x6c,0x6c,0x20,0x66, +0x69,0x6c,0x65,0x0d,0x0a,0x00,0xc3,0x8f, +0x01,0xcd,0xd2,0x01,0x68,0x6f,0x6c,0x65, +0x20,0x69,0x6e,0x20,0x66,0x69,0x6c,0x65, +0x0d,0x0a,0x00,0xc3,0x8f,0x01,0xcd,0xd2, +0x01,0x6e,0x6f,0x74,0x20,0x61,0x6c,0x69, +0x67,0x6e,0x65,0x64,0x0d,0x0a,0x00,0xc3, +0x8f,0x01,0xe5,0xc5,0xed,0x43,0x8e,0x0d, +0x22,0x90,0x0d,0x21,0x00,0x00,0x22,0x92, +0x0d,0x2a,0x8a,0x0d,0x7d,0xb4,0x20,0x1a, +0xcd,0xc4,0x03,0x7d,0xb4,0x28,0x4f,0x22, +0x8a,0x0d,0xcd,0xec,0x03,0x7b,0xb2,0x28, +0xb0,0x21,0x7a,0x07,0x22,0x8c,0x0d,0xcd, +0xab,0x04,0x2a,0x8a,0x0d,0xed,0x5b,0x8e, +0x0d,0xcd,0x4a,0x02,0x2a,0x8a,0x0d,0xb7, +0xed,0x52,0x22,0x8a,0x0d,0x2a,0x8e,0x0d, +0xb7,0xed,0x52,0x22,0x8e,0x0d,0x2a,0x92, +0x0d,0x19,0x22,0x92,0x0d,0x4b,0x42,0xed, +0x5b,0x90,0x0d,0x2a,0x8c,0x0d,0xed,0xb0, +0x22,0x8c,0x0d,0xed,0x53,0x90,0x0d,0x2a, +0x8e,0x0d,0x7d,0xb4,0x20,0xaa,0x2a,0x92, +0x0d,0x4d,0x44,0xd1,0xb7,0xed,0x52,0xe1, +0xc9,0x21,0x3a,0x07,0xcd,0x5f,0x04,0x21, +0x00,0x00,0x22,0x8a,0x0d,0x2a,0x42,0x07, +0x22,0x30,0x07,0x2a,0x44,0x07,0x22,0x32, +0x07,0x21,0x52,0x07,0x22,0x34,0x07,0x21, +0x7a,0x0b,0x22,0x36,0x07,0x21,0x7a,0x0d, +0x22,0x38,0x07,0xc9,0x2a,0x30,0x07,0xed, +0x5b,0x32,0x07,0x01,0x00,0x02,0xb7,0xed, +0x42,0xeb,0x06,0x00,0xed,0x42,0xeb,0x38, +0x0b,0x22,0x30,0x07,0xed,0x53,0x32,0x07, +0x21,0x00,0x02,0xc9,0x2a,0x30,0x07,0xed, +0x43,0x30,0x07,0xc9,0x2a,0x34,0x07,0x11, +0x76,0x07,0xb7,0xed,0x52,0x30,0x0b,0x2a, +0x34,0x07,0x5e,0x23,0x56,0x23,0x22,0x34, +0x07,0xc9,0x2a,0x36,0x07,0x11,0x7a,0x0b, +0xb7,0xed,0x52,0x38,0x13,0x2a,0x34,0x07, +0x5e,0x23,0x56,0x23,0x22,0x34,0x07,0x21, +0x7a,0x09,0x22,0x36,0x07,0xcd,0xab,0x04, +0x2a,0x34,0x07,0x11,0x79,0x07,0xb7,0xed, +0x52,0x30,0x0b,0x2a,0x36,0x07,0x5e,0x23, +0x56,0x23,0x22,0x36,0x07,0xc9,0x2a,0x38, +0x07,0x11,0x7a,0x0d,0xb7,0xed,0x52,0x38, +0x13,0x2a,0x36,0x07,0x5e,0x23,0x56,0x23, +0x22,0x36,0x07,0x21,0x7a,0x0b,0x22,0x38, +0x07,0xcd,0xab,0x04,0x2a,0x38,0x07,0x5e, +0x23,0x56,0x23,0x22,0x38,0x07,0xc9,0xe5, +0x7b,0xe6,0x07,0x06,0x03,0xcb,0x3a,0xcb, +0x1b,0x10,0xfa,0x2a,0x2a,0x07,0x37,0xed, +0x52,0x38,0x1a,0x2a,0x28,0x07,0x19,0xeb, +0x21,0x7a,0x07,0xf5,0xe5,0xcd,0xab,0x04, +0xe1,0xd1,0x01,0x40,0x00,0x59,0xed,0x5c, +0x19,0xd1,0xed,0xb0,0xc9,0xcd,0xd2,0x01, +0x62,0x61,0x64,0x20,0x69,0x6e,0x6f,0x64, +0x65,0x3a,0x20,0x00,0xc6,0x30,0xcd,0x9e, +0x05,0xcd,0xcc,0x05,0x2c,0x20,0x00,0xeb, +0xc3,0x89,0x01,0xe5,0xcd,0xc5,0x04,0xe5, +0xfd,0xe1,0x57,0xe1,0x1e,0x03,0xc3,0xdb, +0x05,0xe5,0xcd,0xc5,0x04,0xfd,0xe1,0x16, +0x03,0x5f,0xc3,0xdb,0x05,0x21,0x00,0x06, +0x37,0xed,0x52,0x38,0x1d,0x01,0x00,0x02, +0x21,0x00,0x02,0x19,0x7c,0x65,0x69,0x29, +0x8f,0xc9,0x7e,0x23,0x56,0x23,0xcb,0x3a, +0x1f,0xcb,0x3a,0x1f,0xcb,0x3a,0x1f,0xc6, +0x3c,0xc9,0xcd,0xd2,0x01,0x62,0x61,0x64, +0x20,0x62,0x6c,0x6f,0x63,0x6b,0x3a,0x20, +0x00,0xeb,0xc3,0x89,0x01,0x21,0x16,0x07, +0xcd,0x37,0xf0,0xc8,0xcd,0xd2,0x01,0x6c, +0x6f,0x61,0x64,0x69,0x6e,0x67,0x20,0x41, +0x3a,0x4b,0x45,0x52,0x4e,0x45,0x4c,0x2e, +0x42,0x49,0x4e,0x0d,0x0a,0x00,0x3e,0x31, +0x32,0xf7,0x06,0xed,0x5b,0x26,0x07,0xb7, +0xed,0x52,0x20,0x23,0x19,0x22,0x24,0x07, +0x7d,0xb4,0x20,0x04,0x21,0x23,0x07,0x34, +0x21,0x00,0x40,0x19,0x22,0x26,0x07,0x21, +0x22,0x07,0x34,0x21,0x16,0x07,0xcd,0x37, +0xf0,0x20,0xd8,0x21,0x22,0x07,0x35,0xcd, +0x2c,0x02,0xfd,0x21,0x00,0x00,0x21,0x94, +0x0d,0x11,0x03,0x0c,0x01,0x14,0x00,0xcd, +0xdb,0x05,0xcd,0x40,0x01,0xcd,0x5d,0x01, +0xcd,0x51,0x02,0xd5,0xfd,0xe1,0x11,0x00, +0x0c,0x6b,0x63,0xcd,0xdb,0x05,0xd5,0xcd, +0x59,0x02,0x21,0x00,0xc0,0x19,0xd1,0xcd, +0xdb,0x05,0xcd,0x62,0x02,0xd4,0x3f,0x02, +0xcd,0x0c,0x02,0x3a,0x22,0x07,0x3c,0x47, +0x21,0x80,0x80,0x3e,0xbc,0x77,0x23,0xc6, +0x04,0x10,0xfa,0xc3,0xec,0x00,0xf5,0xed, +0x38,0x05,0xe6,0x02,0x28,0xf9,0xf1,0xed, +0x39,0x07,0xc9,0x3e,0x0d,0xcd,0x9e,0x05, +0x3e,0x0a,0x18,0xea,0x7c,0xcd,0xb9,0x05, +0x7d,0xf5,0x0f,0x0f,0x0f,0x0f,0xcd,0xc2, +0x05,0xf1,0xe6,0x0f,0xc6,0x90,0x27,0xce, +0x40,0x27,0x18,0xd2,0xe3,0xf5,0x7e,0x23, +0xb7,0x28,0x05,0xcd,0x9e,0x05,0x18,0xf6, +0xf1,0xe3,0xc9,0x7b,0xfe,0x04,0xd2,0x59, +0x06,0x79,0xe6,0x1f,0xc5,0x4f,0x06,0x00, +0xcd,0x2b,0x06,0x0c,0x0d,0x28,0x11,0xed, +0x38,0x30,0xee,0x50,0xed,0x39,0x30,0xfd, +0x09,0xdc,0x55,0x06,0x09,0xdc,0x57,0x06, +0xc1,0x3e,0x05,0xcb,0x38,0xcb,0x19,0x3d, +0x20,0xf9,0x18,0x1a,0xc5,0x01,0x20,0x00, +0xed,0x09,0x26,0xed,0x38,0x30,0xee,0x50, +0xed,0x39,0x30,0xfd,0x09,0xdc,0x55,0x06, +0x09,0xdc,0x57,0x06,0xc1,0x0b,0x78,0xb1, +0x20,0xe2,0xc9,0xed,0x09,0x26,0xed,0x01, +0x27,0x18,0x05,0x3e,0x01,0xed,0x39,0x26, +0xe5,0xfd,0xe5,0xed,0x29,0x23,0xed,0x21, +0x24,0xed,0x19,0x25,0xe1,0xed,0x29,0x20, +0xed,0x21,0x21,0xed,0x11,0x22,0xe1,0x3e, +0x02,0xed,0x39,0x31,0xc9,0x14,0xc9,0x1c, +0xc9,0xc5,0xaf,0xed,0x39,0x26,0xed,0x39, +0x27,0x3e,0x04,0xcb,0x38,0xcb,0x19,0x3d, +0x20,0xf9,0x78,0xb1,0x28,0x0d,0xc5,0x01, +0x10,0x00,0xcd,0x83,0x06,0xc1,0x0b,0x78, +0xb1,0x20,0xf3,0xc1,0x47,0x79,0xe6,0x0f, +0x28,0x20,0x4f,0xed,0x30,0x26,0xcc,0x33, +0x06,0xfd,0x09,0xdc,0x55,0x06,0x09,0xdc, +0x57,0x06,0x41,0x0e,0x01,0xed,0x38,0x30, +0xee,0x50,0xed,0x39,0x30,0xed,0x09,0x26, +0x10,0xf8,0xc9,0x3e,0x74,0xed,0x39,0x00, +0xed,0x39,0x01,0x3e,0x22,0xed,0x39,0x02, +0xed,0x39,0x03,0x97,0xed,0x39,0x04,0xed, +0x39,0x05,0xed,0x30,0x08,0xed,0x30,0x09, +0xed,0x39,0x27,0xed,0x39,0x2f,0xed,0x39, +0x29,0xed,0x39,0x2a,0xed,0x39,0x2b,0xed, +0x39,0x2c,0xc9,0x02,0x00,0xd3,0xff,0xf3, +0xff,0xd9,0xff,0xea,0xff,0x00,0x00,0x2f, +0x62,0x6f,0x6f,0x74,0x2f,0x6b,0x65,0x72, +0x6e,0x65,0x6c,0x2e,0x62,0x69,0x6e,0x00, +0x72,0x6f,0x6f,0x74,0x3d,0x68,0x64,0x30, +0x00,0xf7,0xff,0x00,0x00,0x53,0x4e,0x3d, +0x30,0x30,0x30,0x30,0x30,0x00,0x62,0x6f, +0x6f,0x74,0x00,0x6b,0x65,0x72,0x6e,0x65, +0x6c,0x2e,0x62,0x69,0x6e,0x00,0x01,0x4b, +0x45,0x52,0x4e,0x45,0x4c,0x20,0x20,0x42, +0x49,0x4e,0x00,0x0c,0x00,0x00,0x00,0x40, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, +0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a + diff --git a/src/fsutil/f.bat b/src/fsutil/f.bat new file mode 100755 index 00000000..eb08e560 --- /dev/null +++ b/src/fsutil/f.bat @@ -0,0 +1,13 @@ +cl -Zi -I. -I..\kernel -DVAX -DUTIL -DDEBUG=1 -c utils.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel -DVAX -DUTIL -DNATIVE -DDEBUG=1 -c fsck.c +@if errorlevel 1 goto failure +link @fsck.lnk +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/fsutil/fsck.c b/src/fsutil/fsck.c new file mode 100755 index 00000000..01a8f2e1 --- /dev/null +++ b/src/fsutil/fsck.c @@ -0,0 +1,1262 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + UZIX utilities: + + Filesystem Check: to check an UZIX disk. + Usage: fsck [-y] d: +**********************************************************/ + +/* The device is given as drive letter. + * Major device is always 0 (FDD), minor device is 0..7 (drives A..H) + */ + +#define __MAIN__COMPILATION +#define NEED__DEVIO +#define SKIP_TIME_T /* Nick */ + +#include "utildos.h" + +#if 1 /* Nick */ +#include +#include +#include +#include +#ifdef NATIVE /* Nick */ +#include +#ifdef VAX +#include +#else +#include +#endif +#include "utils.h" +#endif +#else +#ifdef SEPH +#include "sys\ioctl.h" +#include "sys\stat.h" +#endif +#ifdef _MSX_DOS +#include ".\include\stdio.h" +#include ".\include\stdlib.h" +#include ".\include\ctype.h" +#include ".\include\string.h" +#else +#include +#include +#include +#include +#define xexit(n) (exit(n)) /* Nick */ +#endif +#endif + +#ifdef NATIVE /* Nick */ +int device_handle; +uchar device_name[0x200]; /* 16]; */ + +char zeroed[BUFSIZE]; /* actually a misnomer */ +#endif + +#define MAXDEPTH 33 /* Maximum depth of directory tree to search */ +uint depth; + +int _yes = 0; + +dev_t dev; +filesys_t filsys; +uint ninodes; +blkno_t finode; + +#if 1 /* Nick free bitmap */ +off_t bitmap_inode; +off_t bitmap_block; +off_t bitmap_immov; + +char *inode_bitmap; +#endif +char *block_bitmap; +uchar *link_count; + +void ckdir(uint inum, uint pnum, char *name); +void mkentry(uint inum); +blkno_t getblkno(dinode_t *ino, blkno_t num); +void setblkno(dinode_t *ino, blkno_t num, blkno_t dnum); +blkno_t _blk_alloc(filesys_t *filsys); +char *daread(uint blk); +void dwrite(uint blk, void *addr); +void iread(uint ino, dinode_t *buf); +void iwrite(uint ino, dinode_t *buf); +void dirread(dinode_t *ino, uint j, direct_t *dentry); +void dirwrite(dinode_t *ino, uint j, direct_t *dentry); +int da_read(dev_t,uint,void *); +int da_write(dev_t,uint,void *); +int yes(void); +#if 1 /* Nick free bitmap */ +void bitmap_dump(char *bitmap, off_t start, off_t final); +blkno_t bitmap_find(blkno_t start, blkno_t final); +#endif +#ifdef NATIVE /* Nick */ +void mypanic(char *message); +#endif + +int da_read(dev, blk, addr) + dev_t dev; + uint blk; + void *addr; +{ +#ifdef NATIVE /* Nick */ + if (lseek(device_handle, ((long)blk) << BUFSIZELOG, SEEK_SET) < 0) + { + printf("can't seek: "); + fflush(stdout); + perror(device_name); + exit(1); + } + + if (read(device_handle, addr, BUFSIZE) != BUFSIZE) + { + printf("can't read: "); + fflush(stdout); + perror(device_name); + exit(1); + } +#else + bufptr buf = bread(dev, blk, 0); + + if (buf == NULL) + return 0; + bcopy(buf, addr, BUFSIZE); + bfree(buf, 0); +#endif + return BUFSIZE; +} + +int da_write(dev, blk, addr) + dev_t dev; + uint blk; + void *addr; +{ +#ifdef NATIVE /* Nick */ + if (lseek(device_handle, ((long)blk) << BUFSIZELOG, SEEK_SET) < 0) + { + printf("can't seek: "); + fflush(stdout); + perror(device_name); + exit(1); + } + + if (write(device_handle, addr, BUFSIZE) != BUFSIZE) + { + printf("can't write: "); + fflush(stdout); + perror(device_name); + exit(1); + } +#else + bufptr buf = bread(dev, blk, 1); + + if (buf == NULL) + return 0; + bcopy(addr, buf, BUFSIZE); + bfree(buf, 1); +#endif + return BUFSIZE; +} + +/* Pass 1 checks each inode independently for validity, zaps bad block + * numbers in the inodes, and builds the block allocation map. + */ +void pass1(void) { + uint n, mode, icount = 0; + blkno_t b, bn, bno, *buf; + dinode_t ino; + + n = ROOTINODE; + while (n < ninodes) { + iread(n, &ino); + link_count[n] = -1; + if (ino.i_mode == 0) + goto Cont; + mode = ino.i_mode & S_IFMT; + /* Check mode */ + if (mode != S_IFALIGN && /* Nick */ + mode != S_IFREG && + mode != S_IFDIR && + mode != S_IFLNK && + mode != S_IFBLK && + mode != S_IFCHR) { + PF("Inode %d with mode 0%o is not of correct type. Zap? ", + n, ino.i_mode); + if (yes()) { + ino.i_mode = 0; + ino.i_nlink = 0; + iwrite(n, &ino); + goto Cont; + } + } + link_count[n] = 0; + ++icount; + /* Check blocks and build free block map */ + if (mode == S_IFALIGN || /* Nick */ + mode == S_IFREG || mode == S_IFDIR || mode == S_IFLNK) { + /* Check singly indirect blocks */ + b = DIRECTBLOCKS; + while (b <= DIRECTBLOCKS+INDIRECTBLOCKS) { + bno = ino.i_addr[b]; + if (bno != 0 && + (bno < finode || + bno >= filsys.s_fsize)) { + PF("Inode %d singly indirect " + "block %d is out of range " + "with value of %u. Zap? ", + n, b, bno); + if (yes()) { + ino.i_addr[b] = 0; + iwrite(n, &ino); + } + } + if (bno != 0 && + (uint)(ino.i_size >> BUFSIZELOG) < DIRECTBLOCKS) { + PF("Inode %d singly indirect block " + "%d is past end of file with " + "value of %u. Zap? ", + n, b, bno); + if (yes()) { + ino.i_addr[b] = 0; + iwrite(n, &ino); + } + } + if (bno != 0) + block_bitmap[bno >> 3] |= 1 << (bno & 7); + ++b; + } + /* Check the double indirect blocks */ + if (ino.i_addr[DIRECTBLOCKS+INDIRECTBLOCKS] != 0) { + buf = (blkno_t *) daread(ino.i_addr[19]); + b = 0; + while (b < BUFSIZE/sizeof(blkno_t)) { + bno = buf[n]; + if (bno != 0 && + (bno < finode || + bno >= filsys.s_fsize)) { + PF("Inode %d doubly indirect " + "block %d is out of range " + "with value of %u. Zap? ", + n, b, bno); + if (yes()) { + buf[b] = 0; + dwrite(b, (char *) buf); + } + } + if (bno != 0) + block_bitmap[bno >> 3] |= 1 << (bno & 7); + ++b; + } + } + /* Check the rest */ + b = 0; + bn = (uint)(ino.i_size >> BUFSIZELOG); + while (b <= bn) { + bno = getblkno(&ino, b); + if (bno != 0 && + (bno < finode || bno >= filsys.s_fsize)) { + PF("Inode %d block %d is out of " + "range with value of %u. Zap? ", + n, b, bno); + if (yes()) { + setblkno(&ino, b, 0); + iwrite(n, &ino); + } + } + if (bno != 0) + block_bitmap[bno >> 3] |= 1 << (bno & 7); + ++b; + } + } +Cont: ++n; + } + /* Fix free inode count in super block */ + b = ninodes - ROOTINODE - icount; + if (filsys.s_tinode != b) { + PF("Free inode count in super block is %u should be %u. Fix? ", + filsys.s_tinode, b); + if (yes()) { + filsys.s_tinode = b; + dwrite((blkno_t)1, (char *) &filsys); + } + } +} + +/* Clear inode free list, rebuild block free list using bit map. */ +void pass2(void) { +#if 1 /* Nick free bitmap */ + char *buf; + blkno_t j, lm, oldtfree, oldtinode; + blkno_t bitmap_inode, bitmap_block, bitmap_immov; + + oldtfree = filsys.s_tfree; + oldtinode = filsys.s_tinode; + + if (filsys.s_bitmap_inode) + { + printf(" Rebuild free bitmaps? "); + } + else + { + printf(" Rebuild free list? "); + } +#else + blkno_t j, oldtfree = filsys.s_tfree; + + PF(" Rebuild free list? "); +#endif + if (!yes()) + return; + /* Initialize the super-block */ + filsys.s_ninode = 0; +#if 1 /* Nick free bitmap */ + if (filsys.s_bitmap_inode) + { + /* grab fields of superblock, for clarity and extra speed */ + bitmap_inode = filsys.s_bitmap_inode; + bitmap_block = filsys.s_bitmap_block; + bitmap_immov = filsys.s_bitmap_immov; + + /* mark all system reserved blocks as used in the bitmap */ + for (j = 0; j < finode+filsys.s_isize; j++) + { + block_bitmap[j >> 3] |= 1 << (j & 7); + } + + /* mark all out-of-range blocks as used in the bitmap */ + lm = (bitmap_immov - bitmap_block) << 3; /* may wrap to 0 */ + for (j = filsys.s_fsize; j != lm; j++) + { + block_bitmap[j >> 3] |= 1 << (j & 7); + } + + /* count free blocks in the already constructed bitmap */ + filsys.s_tfree = 0; + for (j = finode+filsys.s_isize; j < filsys.s_fsize; j++) + { + if ((block_bitmap[j >> 3] & (1 << (j & 7))) == 0) + { + ++filsys.s_tfree; + } + } + + /* dump bitmap, preserving unused bytes of reserved blocks */ + bitmap_dump(block_bitmap, bitmap_block, bitmap_immov); + + /* mark all system reserved inodes as used in the bitmap */ + inode_bitmap[0] |= 1; + inode_bitmap[ROOTINODE >> 3] |= 1 << (ROOTINODE & 7); + + /* mark inodes as used in the bitmap, using link_count[] */ + for (j = ROOTINODE + 1; j < ninodes; j++) + { + if (link_count[j] != (uchar)-1) + { + inode_bitmap[j >> 3] |= 1 << (j & 7); + } + } + + /* mark all out-of-range inodes as used in the bitmap */ + lm = (bitmap_block - bitmap_inode) << 3; /* may wrap to 0 */ + for (j = DINODESPERBLOCK * filsys.s_isize; j != lm; j++) + { + inode_bitmap[j >> 3] |= 1 << (j & 7); + } + + /* dump bitmap, preserving unused bytes of reserved blocks */ + bitmap_dump(inode_bitmap, bitmap_inode, bitmap_block); + } + else + { + filsys.s_nfree = 1; + filsys.s_free[0] = 0; + filsys.s_tfree = 0; + + /* Free each block, building the free list */ + j = filsys.s_fsize - 1; + while (j >= finode+filsys.s_isize) + { + if ((block_bitmap[j >> 3] & (1 << (j & 7))) == 0) + { + if (filsys.s_nfree == FSFREEBLOCKS) + { + dwrite(j, (char *) &filsys.s_nfree); + filsys.s_nfree = 0; + } + filsys.s_free[filsys.s_nfree] = j; + ++filsys.s_nfree; + ++filsys.s_tfree; + } + --j; + } + } +#else + filsys.s_nfree = 1; + filsys.s_free[0] = 0; + filsys.s_tfree = 0; + + /* Free each block, building the free list */ + j = filsys.s_fsize - 1; + while (j >= finode+filsys.s_isize) { + if ((block_bitmap[j >> 3] & (1 << (j & 7))) == 0) { + if (filsys.s_nfree == FSFREEBLOCKS) { + dwrite(j, (char *) &filsys.s_nfree); + filsys.s_nfree = 0; + } + filsys.s_free[filsys.s_nfree] = j; + ++filsys.s_nfree; + ++filsys.s_tfree; + } + --j; + } +#endif +#if 1 /* Nick free bitmap */ + buf = daread(SUPERBLOCK); + bcopy((char *)&filsys, buf, sizeof(filsys)); + dwrite(SUPERBLOCK, buf); +#else + dwrite(SUPERBLOCK, (char *) &filsys); +#endif + if (oldtfree != filsys.s_tfree) { + PF("During free list regeneration s_tfree " + "was changed to %d from %d.\n", + filsys.s_tfree, oldtfree); + FF; + } +} + +/* Pass 3 finds and fixes multiply allocated blocks. */ +void pass3(void) { + uint n, mode; + dinode_t ino; + blkno_t b, bn, bno,newno; + + b = finode; + while (b < filsys.s_fsize) { + block_bitmap[b >> 3] &= ~(1 << (b & 7)); + b++; + } + n = ROOTINODE; + while (n < ninodes) { + iread(n, &ino); + mode = ino.i_mode & S_IFMT; + if (mode != S_IFALIGN && /* Nick */ + mode != S_IFREG && mode != S_IFDIR && mode != S_IFLNK) + goto Cont; + /* Check singly indirect blocks */ + b = DIRECTBLOCKS; + while (b <= DIRECTBLOCKS+INDIRECTBLOCKS) { + bno = ino.i_addr[b]; + if (bno != 0) { + if ((block_bitmap[bno >> 3] & (1 << (bno & 7))) != 0) { + PF("Indirect block %d in inode %u " + "value %u multiply allocated. " + "Fix? ", b, n, bno); + if (yes()) { + newno = _blk_alloc(&filsys); + if (newno == 0) { + PF("Sorry... " + "No more free blocks.\n"); + FF; + } + else { + dwrite(newno,daread(bno)); + ino.i_addr[b] = newno; + iwrite(n, &ino); + } + } + } + else block_bitmap[bno >> 3] |= 1 << (bno & 7); + } + ++b; + } + /* Check the rest */ + b = 0; + bn = (uint)(ino.i_size >> BUFSIZELOG); + while (b <= bn) { + bno = getblkno(&ino, b); + if (bno == 0) + goto Cont1; + if ((block_bitmap[bno >> 3] & (1 << (bno & 7))) != 0) { + PF("Block %d in inode %u value %u " + "multiply allocated. Fix? ", + b, n, bno); + if (yes()) { + newno = _blk_alloc(&filsys); + if (newno == 0) { + PF("Sorry... " + "No more free blocks.\n"); + FF; + } + else { + dwrite(newno, daread(bno)); + setblkno(&ino, b, newno); + iwrite(n, &ino); + } + } + } + else block_bitmap[bno >> 3] |= 1 << (bno & 7); +Cont1: ++b; + } +Cont: ++n; + } +} + +/* This recursively checks the directories */ +void ckdir(inum, pnum, name) + uint inum; + uint pnum; + char *name; +{ + dinode_t ino; + direct_t dentry; + uint j, i, nentries; + char ename[150]; + + iread(inum, &ino); + if ((ino.i_mode & S_IFMT) != S_IFDIR) + return; + ++depth; + i = (uint)(ino.i_size) % sizeof(direct_t); + if (i != 0) { + PF("Directory inode %d has improper length (%d extra). Fix? ", + inum, i); + if (yes()) { + ino.i_size &= ~(sizeof(direct_t) - 1); + iwrite(inum, &ino); + } + } + nentries = (uint)(ino.i_size / sizeof(direct_t)); + j = 0; + while (j < nentries) { + dirread(&ino, j, &dentry); + if (dentry.d_ino == 0) + goto Cont; + if (dentry.d_ino < ROOTINODE || + dentry.d_ino >= 8 * filsys.s_isize) { + PF("Directory entry %s%-1.14s has out-of-range " + "inode %u. Zap? ", + name, dentry.d_name, dentry.d_ino); + if (yes()) { + dentry.d_ino = 0; + dentry.d_name[0] = '\0'; + dirwrite(&ino, j, &dentry); + goto Cont; + } + } + if (dentry.d_ino && link_count[dentry.d_ino] == (uchar)-1) { + PF("Directory entry %s%-1.14s points to " + "bogus inode %u. Zap? ", + name, dentry.d_name, dentry.d_ino); + if (yes()) { + dentry.d_ino = 0; + dentry.d_name[0] = '\0'; + dirwrite(&ino, j, &dentry); + goto Cont; + } + } + if (link_count[dentry.d_ino]++ == 254) { + fprintf(stderr, "More than 254 links to inode %u.\n" + "Not enough memory. FSCK aborted.\n", + dentry.d_ino); +#ifdef NATIVE /* Nick */ + exit(1); +#else + xexit(1); +#endif + } + i = 0; + while (i < DIRNAMELEN && dentry.d_name[i]) { + if (dentry.d_name[i] == '/') { + PF("Directory entry %s%-1.14s " + "contains slash. Fix? ", + name, dentry.d_name); + if (yes()) { + dentry.d_name[i] = '~'; + dirwrite(&ino, j, &dentry); + } + } + ++i; + } + if (strcmp((char *)dentry.d_name, ".") == 0 && + dentry.d_ino != inum) { + PF("'.' entry %s%-1.*s points to wrong place. Fix? ", + name, DIRNAMELEN, dentry.d_name); + if (yes()) { + dentry.d_ino = inum; + dirwrite(&ino, j, &dentry); + } + } + if (strcmp((char *)dentry.d_name, "..") == 0 && + dentry.d_ino != pnum) { + PF("'..' entry %s%-1.*s points to wrong place. Fix? ", + name, DIRNAMELEN, dentry.d_name); + if (yes()) { + dentry.d_ino = pnum; + dirwrite(&ino, j, &dentry); + } + } + if (dentry.d_ino != pnum && + dentry.d_ino != inum && + depth < MAXDEPTH) { + strcpy(ename, name); + strcat(ename, (char *)dentry.d_name); + strcat(ename, "/"); + ckdir(dentry.d_ino, inum, ename); + } +Cont: ++j; + } + --depth; +} + +/* Pass 4 traverses the directory tree, fixing bad directory entries + * and finding the actual number of references to each inode. + */ +void pass4(void) { + depth = 0; + link_count[ROOTINODE] = 1; + ckdir(ROOTINODE, ROOTINODE, "/"); + if (depth != 0) +#ifdef NATIVE /* Nick */ + mypanic("Inconsistent depth"); +#else + panic("Inconsistent depth"); +#endif +} + +/* This makes an entry in "lost+found" for inode n */ +void mkentry(inum) + uint inum; +{ + dinode_t rootino; + direct_t dentry; + uint d, ne; + + iread(ROOTINODE, &rootino); + d = 0; + ne = (uint)(rootino.i_size / sizeof(direct_t)); + while (d < ne) { + dirread(&rootino, d, &dentry); + if (dentry.d_ino == 0 && dentry.d_name[0] == '\0') { + dentry.d_ino = inum; + sprintf(dentry.d_name, "l_f%d", inum); + dirwrite(&rootino, d, &dentry); + return; + } + ++d; + } + PF("Sorry... No empty slots in root directory.\n"); FF; +} + +/* Pass 5 compares the link counts found in pass 4 with the inodes. */ +void pass5(void) { +#if 1 /* Nick free bitmap */ + char *buf; +#endif + uint n; + dinode_t ino; + + n = ROOTINODE; + while (n < ninodes) { + iread(n, &ino); + if (ino.i_mode == 0) { + if (link_count[n] != (uchar)-1) +#ifdef NATIVE /* Nick */ + mypanic("Inconsistent link count"); +#else + panic("Inconsistent link count"); +#endif + goto Cont; + } + if (link_count[n] == (uchar)-1 && ino.i_mode != 0) +#ifdef NATIVE /* Nick */ + mypanic("Inconsistent link count"); +#else + panic("Inconsistent link count"); +#endif + if (link_count[n] != (uchar)-1 && ino.i_nlink != link_count[n]) { + PF("Inode %d has link count %d should be %d. Fix? ", + n, ino.i_nlink, link_count[n]); + if (yes()) { + ino.i_nlink = link_count[n]; + iwrite(n, &ino); + } + } + if (link_count[n] == 0) { + if (S_ISBLK(ino.i_mode) || + S_ISCHR(ino.i_mode) || + ino.i_size == 0) { + PF("Useless inode %d with mode 0%o has " + "become detached. Link count is %d. Zap? ", + n, ino.i_mode, ino.i_nlink); + if (yes()) { + ino.i_nlink = 0; + ino.i_mode = 0; + iwrite(n, &ino); + ++filsys.s_tinode; +#if 1 /* Nick free bitmap */ + buf = daread(SUPERBLOCK); + bcopy((char *)&filsys, + buf, sizeof(filsys)); + dwrite(SUPERBLOCK, buf); +#else + dwrite(SUPERBLOCK, (char *) &filsys); +#endif + } + } + else { + PF("Inode %d has become detached. " + "Link count is %d. Fix? ", + n, ino.i_nlink); + if (yes()) { + ino.i_nlink = 1; + iwrite(n, &ino); + mkentry(n); + } + } + } +Cont: ++n; + } +} + +/* Getblkno gets a pointer index, and a number of a block in the file. + * It returns the number of the block on the disk. A value of zero + * means an unallocated block. + */ +blkno_t getblkno(ino, num) + dinode_t *ino; + blkno_t num; +{ + blkno_t indb; + blkno_t dindb; + blkno_t *buf; + + if (num < DIRECTBLOCKS) /* Direct block */ + return (ino->i_addr[num]); + if (num < DIRECTBLOCKS + BUFSIZE/sizeof(blkno_t)) { /* Single indirect */ + indb = ino->i_addr[DIRECTBLOCKS]; + if (indb == 0) + return (0); + buf = (blkno_t *) daread(indb); + return (buf[num - DIRECTBLOCKS]); + } + /* Double indirect */ + indb = ino->i_addr[DIRECTBLOCKS+INDIRECTBLOCKS]; + if (indb == 0) + return (0); + buf = (blkno_t *) daread(indb); + indb = (num - DIRECTPERBLOCK + BUFSIZE/sizeof(blkno_t)); + dindb = buf[indb >> 8]; + buf = (blkno_t *) daread(dindb); + return (buf[indb & 0xFF]); +} + +/* Setblkno sets the given block number of the given file to the given + * disk block number, possibly creating or modifiying the indirect blocks. + * A return of zero means there were no blocks available to create an + * indirect block. This should never happen in fsck. + */ +void setblkno(ino, num, dnum) + dinode_t *ino; + blkno_t num; + blkno_t dnum; +{ + blkno_t indb; + blkno_t dindb; + blkno_t *buf; + + if (num < DIRECTBLOCKS) /* Direct block */ + ino->i_addr[num] = dnum; + else if (num < DIRECTBLOCKS + BUFSIZE/sizeof(blkno_t)) { /* Single indirect */ + indb = ino->i_addr[DIRECTBLOCKS]; + if (indb == 0) +#ifdef NATIVE /* Nick */ + mypanic("Missing indirect block"); +#else + panic("Missing indirect block"); +#endif + buf = (blkno_t *) daread(indb); + buf[num - DIRECTBLOCKS] = dnum; + dwrite(indb, (char *) buf); + } + else { /* Double indirect */ + indb = ino->i_addr[DIRECTBLOCKS+INDIRECTBLOCKS]; + if (indb == 0) +#ifdef NATIVE /* Nick */ + mypanic("Missing indirect block"); +#else + panic("Missing indirect block"); +#endif + buf = (blkno_t *) daread(indb); + num -= DIRECTBLOCKS + BUFSIZE/sizeof(blkno_t); + dindb = buf[num >> 8]; + if (dindb == 0) +#ifdef NATIVE /* Nick */ + mypanic("Missing indirect block"); +#else + panic("Missing indirect block"); +#endif + buf = (blkno_t *) daread(dindb); + buf[num & 0xFF] = num; + dwrite(indb, buf); + } +} + +/* Blk_alloc allocates an unused block. + * A returned block number of zero means no more blocks. + */ +blkno_t _blk_alloc(filsys) + filesys_t *filsys; +{ + uint j; + char *buf; /* blkno_t *buf; */ + blkno_t newno; +#if 1 /* Nick free bitmap */ + blkno_t bitmap_block, bitmap_immov; + + if (filsys->s_bitmap_inode) + { + /* grab fields of superblock, for clarity and extra speed */ + bitmap_block = filsys->s_bitmap_block; + bitmap_immov = filsys->s_bitmap_immov; + + /* read bitmap, skipping unused bytes of reserved blocks */ + newno = bitmap_find(bitmap_block, bitmap_immov); + if (newno == (blkno_t)-1) + { + /* no '0' bit found within the bitmap limits */ + return 0; /* return an ENOSPC error (really full) */ + } + + goto found_block; /* crude way to skip free list processing */ + } +#endif + newno = filsys->s_free[--filsys->s_nfree]; + if (newno == 0) { + ++filsys->s_nfree; + return (0); + } + /* See if we must refill the s_free array */ + if (filsys->s_nfree == 0) { + buf = daread(newno); + filsys->s_nfree = ((blkno_t *)buf)[0]; + j = 0; + while (j < FSFREEBLOCKS) { + filsys->s_free[j] = ((blkno_t *)buf)[j + 1]; + ++j; + } + } +#if 1 /* Nick free bitmap */ +found_block: +#endif + --filsys->s_tfree; + if (newno < finode || newno >= filsys->s_fsize) { + PF("Free list is corrupt. Did you rebuild it?\n"); + return (0); + } +#if 1 /* Nick free bitmap */ + buf = daread(SUPERBLOCK); + bcopy((char *)&filsys, buf, sizeof(filsys)); + dwrite(SUPERBLOCK, buf); +#else + dwrite(SUPERBLOCK, filsys); +#endif + return (newno); +} + +char *daread(blk) + uint blk; +{ + static char buf[BUFSIZE]; + + if (da_read(dev, blk, buf) != BUFSIZE) { + PF("Read of block %d failed.\n", blk); + abort(); + } + return (buf); +} + +void dwrite(blk, addr) + uint blk; + void *addr; +{ + if (da_write(dev, blk, addr) != BUFSIZE) { + PF("Write of block %d failed.\n", blk); + abort(); + } +} + +void iread(ino, buf) + uint ino; + dinode_t *buf; +{ + dinode_t *addr = (dinode_t *)daread((ino>>DINODESPERBLOCKLOG)+finode); + + bcopy((char *)&addr[ino & (DINODESPERBLOCK-1)], (char *)buf, + sizeof(dinode_t)); /* Nick added casts */ +} + +void iwrite(ino, buf) + uint ino; + dinode_t *buf; +{ + dinode_t *addr = (dinode_t *)daread((ino>>DINODESPERBLOCKLOG)+finode); + + bcopy((char *)buf, (char *)&addr[ino & (DINODESPERBLOCK-1)], + sizeof(dinode_t)); /* Nick added casts */ + dwrite((ino >> DINODESPERBLOCKLOG) + finode, addr); +} + +void dirread(ino, j, dentry) + dinode_t *ino; + uint j; + direct_t *dentry; +{ + direct_t *buf; + blkno_t blkno = getblkno(ino, (blkno_t) j / DIRECTPERBLOCK); + + if (blkno == 0) +#ifdef NATIVE /* Nick */ + mypanic("Missing block in directory"); +#else + panic("Missing block in directory"); +#endif + buf = (direct_t *)daread(blkno); + bcopy((char *)(buf+j % DIRECTPERBLOCK), (char *)dentry, + sizeof(direct_t)); /* Nick added casts */ +} + +void dirwrite(ino, j, dentry) + dinode_t *ino; + uint j; + direct_t *dentry; +{ + direct_t *buf; + blkno_t blkno = getblkno(ino, (blkno_t) j / DIRECTPERBLOCK); + + if (blkno == 0) +#ifdef NATIVE /* Nick */ + mypanic("Missing block in directory"); +#else + panic("Missing block in directory"); +#endif + buf = (direct_t *)daread(blkno); + bcopy((char *)dentry, (char *)(buf+j % DIRECTPERBLOCK), + sizeof(direct_t)); /* Nick added casts */ + dwrite(blkno, buf); +} + +int yes(void) { + char line[20]; + + FF; + if (_yes) + PF("Y\n"); + else if (!fgets(line, sizeof(line), stdin) || + (*line != 'y' && *line != 'Y')) + return (0); + return (1); +} + +void main(argc, argv) + int argc; + char *argv[]; +{ + char *buf, *p; + int ap = 1, ac = argc; + +#ifdef _MSX_DOS + initenv(); +#endif + if (--ac > 0 && *(p = argv[ap]) == '-') { + if (p[1] != 'y' && p[1] != 'Y') { + fprintf(stderr, "Illegal switch %s\n", p); +#ifdef NATIVE /* Nick */ + exit(1); +#else + xexit(-1); +#endif + } + ++_yes; + ++ap; /* p = argv[2]; */ + --ac; + } +#ifdef NATIVE /* Nick */ + if (ac != 1) + { + fprintf(stderr,"usage: fsck [-y] device\n"); + exit(1); + } + strcpy(device_name, argv[ap]); + device_handle = open(device_name, O_RDWR | O_BINARY); + if (device_handle < 0) + { + printf("can't open: "); + fflush(stdout); + perror(device_name); + exit(1); + } +#else + if ((ac != 1) || ((p = argv[ap])[1] != ':') || !isalpha(*p)) { + fprintf(stderr,"usage: fsck [-y] d:\n"); + xexit(-1); + } + dev = ((*p & 223) - 65); + if (dev >= 8) { + fprintf(stderr,"Invalid drive %c.\n",dev+65); + xexit(-1); + } +#endif +#ifdef _MSX_DOS + if (!_yes) { + PF("Insert disk and press RETURN: "); FF; + getchar(); + } +#endif +#ifndef NATIVE /* Nick */ + bufinit(); + if (d_init() || d_open(dev)) { + fprintf(stderr,"Can't open device number %x\n", dev); + xexit(-1); + } +#endif + /* Read in the super block. */ + buf = daread(SUPERBLOCK); + bcopy(buf, (char *)&filsys, sizeof(filesys_t)); /* Nick added cast */ + /* Verify the fsize and isize parameters */ + if (filsys.s_mounted != SMOUNTED) { + PF("Device %x has invalid magic number %d. Fix? ", + dev, filsys.s_mounted); + if (!yes()) +#ifdef NATIVE /* Nick */ + exit(1); +#else + xexit(-1); +#endif + filsys.s_mounted = SMOUNTED; +#if 1 /* Nick free bitmap */ + /* buf = daread(SUPERBLOCK); */ + bcopy((char *)&filsys, buf, sizeof(filsys)); + dwrite(SUPERBLOCK, buf); +#else + dwrite(SUPERBLOCK, &filsys); +#endif + } +#ifdef NATIVE /* Nick */ + PF("\nChecking %s with fsize %u, isize %u, rsize %u. Confirm? ", + device_name, filsys.s_fsize, filsys.s_isize, + filsys.s_reserv-1-SUPERBLOCK); +#else + PF("Checking drive %c with fsize %u, isize %u, rsize %u. Confirm? ", + dev+65, filsys.s_fsize, filsys.s_isize, + filsys.s_reserv-1-SUPERBLOCK); +#endif + if (!yes()) +#ifdef NATIVE /* Nick */ + exit(1); +#else + xexit(-1); +#endif + +#if 1 /* Nick free bitmap */ + if (filsys.s_bitmap_inode) + { + inode_bitmap = malloc(filsys.s_bitmap_block - + filsys.s_bitmap_inode); + if (inode_bitmap == NULL) + { + p = "inode bitmap"; + goto nomem; + } + bfill(inode_bitmap, 0, filsys.s_bitmap_block - + filsys.s_bitmap_inode); + + block_bitmap = malloc(filsys.s_bitmap_immov - + filsys.s_bitmap_block); + if (block_bitmap == NULL) + { + p = "block bitmap"; + goto nomem; + } + bfill(block_bitmap, 0, filsys.s_bitmap_immov - + filsys.s_bitmap_block); + } + else + { + block_bitmap = malloc(((filsys.s_fsize - 1) >> 3) + 1); + if (block_bitmap == NULL) + { + p = "block bitmap"; + goto nomem; + } + bfill(block_bitmap, 0, ((filsys.s_fsize - 1) >> 3) + 1); + } +#else + block_bitmap = malloc(((filsys.s_fsize - 1) >> 3) + 1); + if (block_bitmap == NULL) { + p="block bitmap"; + goto nomem; + } + bfill(block_bitmap, 0, ((filsys.s_fsize - 1) >> 3) + 1); +#endif + + ninodes = DINODESPERBLOCK * filsys.s_isize; + finode = filsys.s_reserv; + + link_count = (uchar *) malloc(ninodes); + if (!link_count) { + p="link counts"; +nomem: fprintf(stderr,"Not enough memory for %s.\n", p); +#ifdef NATIVE /* Nick */ + exit(1); +#else + xexit(-1); +#endif + } + bfill(link_count, 0, ninodes); /* * sizeof(char)); */ + + PF("\nPass 1: Checking inodes.\n"); FF; pass1(); +#if 1 /* Nick free bitmap */ + if (filsys.s_bitmap_inode) + { + printf("Pass 2: Rebuilding free bitmaps.\n"); + fflush(stdout); + pass2(); + } + else + { + printf("Pass 2: Rebuilding free list.\n"); + fflush(stdout); + pass2(); + } +#else + PF("Pass 2: Rebuilding free list.\n"); FF; pass2(); +#endif + PF("Pass 3: Checking block allocation.\n"); FF; pass3(); + PF("Pass 4: Checking directory entries.\n"); FF; pass4(); + PF("Pass 5: Checking link counts.\n"); FF; pass5(); +#ifdef NATIVE /* Nick */ + close(device_handle); + PF("Done.\n\n"); +#else + bufsync(); + d_close(dev); + PF("Done.\n"); +#endif + exit(0); +} + +#if 1 /* Nick free bitmap */ +void bitmap_dump(char *bitmap, off_t start, off_t final) + { + char *buf; + blkno_t j, lm; + + j = start; + while (j < final) + { + /* calculate ending position after writing block */ + lm = int_min((j + BUFSIZE) & ~(BUFSIZE - 1), final); + + /* optimisation if we are writing the entire block */ + if ((lm - j) < BUFSIZE) + { + buf = daread(j >> BUFSIZELOG); + } + else + { + buf = zeroed; /* no need to read the block */ + } + + /* ready to copy data into the block and write it */ + bcopy(bitmap + (j - start), buf + (j & (BUFSIZE - 1)), lm - j); + dwrite(j >> BUFSIZELOG, buf); + + /* bump counter to continue after data just written */ + j = lm; + } + } + +blkno_t bitmap_find(blkno_t start, blkno_t final) + { + char *buf, *p; + blkno_t i, j, lm, newno; + + j = start; + while (j < final) + { + /* calculate ending position for bits in this block */ + lm = int_min((j + BUFSIZE) & ~(BUFSIZE - 1), final); + + /* read block and calculate starting relevant byte */ + buf = daread(j >> BUFSIZELOG); + p = buf + (j & (BUFSIZE - 1)); + + /* ready to scan each byte looking for a bit of '0' */ + for (i = j; i < lm; i++) + { + if (*p != (char)0xff) + { + /* at least one of the 8 blocks is available */ + + /* calculate which disk block it refers to */ + newno = (i - start) << 3; + for (i = 0; i < 7; i++) /* don't check bit 7 */ + { + if ((*p & (1 << i)) == 0) + { + break; + } + } + newno += i; + + /* ready to turn on this bit and write back */ + *p |= 1 << i; + dwrite(j >> BUFSIZELOG, buf); + + return newno; + } + p++; + } + + /* nothing found this time, release block and loop */ + + /* bump counter to continue after data just read */ + j = lm; + } + + /* no '0' bit found within the bitmap limits */ + return (blkno_t)-1; + } +#endif + +#ifdef NATIVE /* Nick */ +void mypanic(char *message) + { + printf("PANIC: %s", message); + fflush(stdout); + exit(1); + } +#endif + diff --git a/src/fsutil/fsck.exe b/src/fsutil/fsck.exe new file mode 100755 index 0000000000000000000000000000000000000000..dc57f4bca510cdce7c258ba5adb301bca3cee7ea GIT binary patch literal 73770 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

-V2EECuA|>QoFoEp%U(sMSdI^z+ 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 literal 0 HcmV?d00001 diff --git a/src/fsutil/fsck.lnk b/src/fsutil/fsck.lnk new file mode 100755 index 00000000..aeeac6d4 --- /dev/null +++ b/src/fsutil/fsck.lnk @@ -0,0 +1,12 @@ +-k ..\..\lib +-l libcl.lib +-l libsysl.lib +-l libiar.lib +-m +-u +-i +-o fsck +-bl RCODE=0x8100 +..\..\lib\c0l.rel +fsck +utils diff --git a/src/fsutil/fsck.w32 b/src/fsutil/fsck.w32 new file mode 100755 index 00000000..142eeb9f --- /dev/null +++ b/src/fsutil/fsck.w32 @@ -0,0 +1,6 @@ +/debug +/subsystem:console +"/libpath:c:\Program Files\Microsoft Visual Studio\VC98\lib" +/map:fsck.map +fsck.obj +utils.obj diff --git a/src/fsutil/hdasm.c b/src/fsutil/hdasm.c new file mode 100755 index 00000000..e87df069 --- /dev/null +++ b/src/fsutil/hdasm.c @@ -0,0 +1,68 @@ +/* hdasm.c for uzi180 utils by Nick - implements a simple disk emulator */ + +#include +#include +#include + +extern char cmdblk[8]; /* for scsiop(), defined in devhd.c */ +extern long hd_offset; +extern long hd_sector; +extern char *dptr; +extern int dlen; +extern char *cptr; +extern int busid; + +int scsiop(void); + +int scsiop(void) + { + int count; + long position; + static int drive_handle = -1; + static char *drive_name = "uzidisk.dat"; + +#if DEBUG > 1 + printf(" %s sector %08x count %02x\n", + cmdblk[1] == 'W' ? "Writing" : "Reading", + hd_sector, cmdblk[7]); +#endif + + if (drive_handle < 0) + { + drive_handle = open(drive_name, O_RDWR | O_BINARY); + if (drive_handle < 0) + { + return 1; /* says we failed the operation */ + } + } + + count = cmdblk[7] * 0x200; + position = hd_sector * 0x200; + + if (lseek(drive_handle, position, 0) != position) + { + return 2; /* says we failed the operation */ + } + + switch (cmdblk[1]) + { + + case 'R': + if (read(drive_handle, dptr, count) != count) + { + return 3; /* says we failed the operation */ + } + break; + + case 'W': + if (write(drive_handle, dptr, count) != count) + { + return 4; /* says we failed the operation */ + } + break; + + } + + return 0; /* says the operation was successful */ + } + diff --git a/src/fsutil/kernel.bin b/src/fsutil/kernel.bin new file mode 100755 index 0000000000000000000000000000000000000000..0f3bdc437089747a3bb6fe82498e89c6f66ea445 GIT binary patch literal 88832 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 literal 0 HcmV?d00001 diff --git a/src/fsutil/m.bat b/src/fsutil/m.bat new file mode 100755 index 00000000..e476e5ba --- /dev/null +++ b/src/fsutil/m.bat @@ -0,0 +1,13 @@ +cl -Zi -I. -I..\kernel -DVAX -DUTIL -DDEBUG=1 -c utils.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel -DVAX -DUTIL -DNATIVE -DDEBUG=1 -c mkfs.c +@if errorlevel 1 goto failure +link @mkfs.lnk +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/fsutil/main.c b/src/fsutil/main.c new file mode 100755 index 00000000..191c4123 --- /dev/null +++ b/src/fsutil/main.c @@ -0,0 +1,39 @@ +/* main.c for uzi utils by Nick - a few scrappy publics missed elsewhere */ + +#include +#include + +#define SKIP_TIME_T +#include + +char UZIX[14]="UZI180"; /* Nick "UZIX"; should be 13 chars or fewer */ +char HOST[14]="sn00000"; /* Nick kdata.k_host should be 13 chars or fewer */ + +char recv_bufs[13][256]; /* getting a bit pernickety here */ + +/* the following variables are the wrong size and would crash if accessed: */ +int osBank, disp_tab, ncalls; + +void abort(int exitcode) + { + fflush(stdout); + exit(exitcode); + } + +void rdtime(uzitime_t *tloc) + { + time_t now; + struct tm *tmbuf; + + time(&now); + tmbuf = localtime(&now); /* gmtime(&now); */ + + tloc->t_time = (tmbuf->tm_sec >> 1) | + (tmbuf->tm_min << 5) | + (tmbuf->tm_hour << 11); + + tloc->t_date = tmbuf->tm_mday | + ((tmbuf->tm_mon + 1) << 5) | + ((tmbuf->tm_year - 80) << 9); + } + diff --git a/src/fsutil/mkboot.c b/src/fsutil/mkboot.c new file mode 100755 index 00000000..ff47f7fd --- /dev/null +++ b/src/fsutil/mkboot.c @@ -0,0 +1,252 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + UZIX utilities: + + Make Boot: to make an UZIX disk bootable. + Usage: mkboot [-y] d: primary secondary image +**********************************************************/ + +/* The device is given as drive letter. + * Major device is always 0 (FDD), minor device is 0..7 (drives A..H) + */ + +#define __MAIN__COMPILATION +#define NEED__DEVIO + +#include "utildos.h" +#ifdef SEPH +#include "sys\ioctl.h" +#endif +#ifdef _MSX_DOS +#include ".\include\stdio.h" +#include ".\include\stdlib.h" +#include ".\include\ctype.h" +#else +#include +#include +#include +#endif + +#define IMAGE (0x7000/512) + +int _yes = 0; + +dev_t dev; +filesys_t filsys; + +char *daread __P((uint blk)); +void dwrite __P((uint blk, void *addr)); +int da_read __P((dev_t,uint,void *)); +int da_write __P((dev_t,uint,void *)); + +int da_read(dev, blk, addr) + dev_t dev; + uint blk; + void *addr; +{ + bufptr buf = bread(dev, blk, 0); + + if (buf == NULL) + return 0; + bcopy(buf, addr, BUFSIZE); + bfree(buf, 0); + return BUFSIZE; +} + +int da_write(dev, blk, addr) + dev_t dev; + uint blk; + void *addr; +{ + bufptr buf = bread(dev, blk, 1); + + if (buf == NULL) + return 0; + bcopy(addr, buf, BUFSIZE); + bfree(buf, 1); + return BUFSIZE; +} + +char *daread(blk) + uint blk; +{ + static char buf[BUFSIZE]; + + if (da_read(dev, blk, buf) != BUFSIZE) { + PF("Read of block %d failed.\n", blk); + abort(); + } + return (buf); +} + +void dwrite(blk, addr) + uint blk; + void *addr; +{ + if (da_write(dev, blk, addr) != BUFSIZE) { + PF("Write of block %d failed.\n", blk); + abort(); + } +} + +void _pass(char *fn, char *descr, uint from, uint to) { + FILE *fd = fopen(fn, "rb"); + bufptr buf; + uint i; + + if (fd == NULL) { + fprintf(stderr, "Can't find %s %s\n", descr, fn); + xexit(1); + } + i = from; + while (i <= to) { + if ((buf = bread(dev, i, 2)) == NULL) { + fprintf(stderr, "Get block %d error.\n", i); + xexit(1); + } + if (fread(buf, 1, 512, fd) == 0) { + bfree(buf, 0); + break; + } + bfree(buf, 2); + if (feof(fd)) + break; + ++i; + } + fclose(fd); + if (i == from) { + fprintf(stderr, "Can't read %s %s\n", descr, fn); + xexit(1); + } +} + +/* 1 - write primary bootstrap */ +void pass1(char *fn) { + FILE *fd = fopen(fn, "rb"); + char diskpar[30]; + static char bootdata[256]; + bufptr buf; + + if (fd == NULL) { + fprintf(stderr, "Can't find primary bootstrap %s\n", fn); + xexit(1); + } + if ((buf = bread(dev, 0, 0)) == NULL) { + fprintf(stderr, "Get block 0 error.\n"); + xexit(1); + } + bcopy(buf, diskpar, 30); + bcopy(&(buf->bf_data[256]), bootdata, 256); + bfree(buf, 0); + if ((buf = bread(dev, 0, 2)) == NULL) { + fprintf(stderr, "Get block 0 error.\n"); + xexit(1); + } + if (fread(buf, 1, 512, fd) == 0) { + bfree(buf, 0); + fprintf(stderr, "Can't read primary bootstrap %s\n", fn); + xexit(1); + } + bcopy(buf, diskpar, 11); + bcopy(diskpar, buf, 30); + bcopy(bootdata, &(buf->bf_data[256]), 256); + bfree(buf, 2); + fclose(fd); +} + +/* 2 - write secondary bootstrap */ +void pass2(char *fn) { + _pass(fn, "secondary bootstrap", SUPERBLOCK+1, SUPERBLOCK+1+4-1); +} + +/* 3 - write image */ +void pass3(char *fn) { + _pass(fn, "image", SUPERBLOCK+1+5-1, SUPERBLOCK+1+5+55-1); +} + +void main(argc, argv) + int argc; + char *argv[]; +{ + char *p = argv[1]; + int ix = 1; + bufptr buf; + +#ifdef _MSX_DOS + initenv(); +#endif + if (--argc > 0 && *p == '-') { + if (p[1] != 'y' && p[1] != 'Y') { + fprintf(stderr, "Illegal switch %s\n", p); + xexit(-1); + } + ++_yes; + ++ix; + --argc; + } + if ((argc != 4) || (argv[ix][1] != ':') || !isalpha(argv[ix][0])) { + fprintf(stderr,"usage: mkboot [-y] d: primary secondary image\n"); + xexit(0); + } + dev = ((argv[ix][0] & 223) - 65); + if (dev >= 8) { + fprintf(stderr,"Invalid drive %c.\n",dev+65); + xexit(1); + } +#ifdef _MSX_DOS + if (!_yes) { + PF("Insert disk and press RETURN: "); FF; + while (getchar() != '\n') + ; + cursor(0); + } +#endif + bufinit(); + if (d_init() || d_open(dev)) { + fprintf(stderr,"Can't open device number %x\n", dev); + xexit(1); + } + /* Read in the super block. */ + if ((buf = bread(dev,SUPERBLOCK,0)) == NULL) { + fprintf(stderr,"Can't read device %x superblock\n", dev); + xexit(1); + } + bcopy(buf, &filsys, sizeof(filesys_t)); + bfree(buf, 0); + if (filsys.s_mounted != SMOUNTED) { + fprintf(stderr, "Drive %c has invalid magic number %d\n", + dev+65, filsys.s_mounted); + xexit(1); + } + if (filsys.s_reserv-(SUPERBLOCK+1) != IMAGE+4) { + fprintf(stderr, "Drive %c has invalid number of reserved blocks (%d)\n", + dev+65, filsys.s_reserv - (SUPERBLOCK+1)); + xexit(1); + } + PF("Installing boot to disk in drive %c: ", dev+65); FF; + pass1(argv[++ix]); PF("primary, "); FF; + pass2(argv[++ix]); PF("secondary, "); FF; + pass3(argv[++ix]); PF("image.\n"); FF; + bufsync(); + d_close(dev); + PF("Done.\n"); + exit(0); +} + diff --git a/src/fsutil/mkfs.c b/src/fsutil/mkfs.c new file mode 100755 index 00000000..4ade213f --- /dev/null +++ b/src/fsutil/mkfs.c @@ -0,0 +1,829 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + UZIX utilities: + + Make Filesystem: to make an UZIX disk. + Usage: mkfs [-yfqv] d: fsize isize [rsize] +**********************************************************/ + +/* The device is given as drive letter. + * Major device is always 0 (FDD), minor device is 0..7 (drives A..H) + */ + +#define __MAIN__COMPILATION +#define NEED__DEVIO +#define SKIP_TIME_T /* Nick */ + +#include "utildos.h" + +#if 1 /* Nick */ +#include +#include +#include +#ifdef NATIVE /* Nick */ +#include +#ifdef VAX +#include +#else +#include +#endif +#include "utils.h" +#endif +#else +#ifdef SEPH +#include "sys\ioctl.h" +#include "sys\stat.h" +#endif +#ifdef _MSX_DOS +#include ".\include\stdio.h" +#include ".\include\stdlib.h" +#include ".\include\ctype.h" +#else +#include +#include +#include +#endif +#endif + +#ifdef NATIVE /* Nick */ +int device_handle; +uchar device_name[0x200]; /* 16]; */ + +char zeroed[BUFSIZE]; +#endif + +char bootblock[] = { +#if 1 +#include "boot.c" /* see ..\gboot\gboot.asm and ..\..\bin\boot.bin */ +#else + 0xEB, 0xFE, 0x90, 'U', 'Z', 'I', 'X', 'd', + 'i', 's', 'k', 0x00, 0x02, 0x02, 0x01, 0x00, + 0x00, 0x00, 0x00, 0xA0, 0x05, 0xF9, 0x00, 0x00, + 0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0xD0, 0x36, + 0x56, 0x23, 0x36, 0xC0, 0x31, 0x1F, 0xF5, 0x11, + 0x4A, 0xC0, 0x0E, 0x09, 0xCD, 0x7D, 0xF3, 0x0E, + 0x08, 0xCD, 0x7D, 0xF3, 0xFE, 0x1B, 0xCA, 0x22, + 0x40, 0xF3, 0xDB, 0xA8, 0xE6, 0xFC, 0xD3, 0xA8, + 0x3A, 0xFF, 0xFF, 0x2F, 0xE6, 0xFC, 0x32, 0xFF, + 0xFF, 0xC7, 0x57, 0x41, 0x52, 0x4E, 0x49, 0x4E, + 0x47, 0x21, 0x07, 0x0D, 0x0A, 0x0A, 0x54, 0x68, + 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x6E, + 0x20, 0x55, 0x5A, 0x49, 0x58, 0x20, 0x64, 0x69, + 0x73, 0x6B, 0x2C, 0x20, 0x6E, 0x6F, 0x6E, 0x20, + 0x62, 0x6F, 0x6F, 0x74, 0x61, 0x62, 0x6C, 0x65, + 0x2E, 0x0D, 0x0A, 0x55, 0x73, 0x69, 0x6E, 0x67, + 0x20, 0x69, 0x74, 0x20, 0x75, 0x6E, 0x64, 0x65, + 0x72, 0x20, 0x4D, 0x53, 0x58, 0x44, 0x4F, 0x53, + 0x20, 0x63, 0x61, 0x6E, 0x20, 0x64, 0x61, 0x6D, + 0x61, 0x67, 0x65, 0x20, 0x69, 0x74, 0x2E, 0x0D, + 0x0A, 0x0A, 0x48, 0x69, 0x74, 0x20, 0x45, 0x53, + 0x43, 0x20, 0x66, 0x6F, 0x72, 0x20, 0x42, 0x41, + 0x53, 0x49, 0x43, 0x20, 0x6F, 0x72, 0x20, 0x61, + 0x6E, 0x79, 0x20, 0x6B, 0x65, 0x79, 0x20, 0x74, + 0x6F, 0x20, 0x72, 0x65, 0x62, 0x6F, 0x6F, 0x74, + 0x2E, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +#endif +}; + +/* This makes a filesystem */ +dev_t dev; +direct_t dirbuf[DIRECTPERBLOCK] = { + { ROOTINODE, "." }, + { ROOTINODE, ".."} +}; +dinode_t inode[DINODESPERBLOCK]; + +#if 1 /* Nick free bitmap */ +off_t bitmap_inode; +off_t bitmap_block; +off_t bitmap_immov; +off_t bitmap_final; + +char *inode_bitmap; +char *block_bitmap; +char *immov_bitmap; +#endif + +uchar _fmt = 0; /* do low level formatting */ +uchar _yes = 0; /* yes to all questions */ +uchar _quick = 0; /* quick initialization */ +uchar _verb = 0; /* be verbose */ +#if 1 /* Nick free bitmap */ +uchar _bitmap = 0; /* use a free bitmap rather than a free list */ +uchar _immov = 0; /* create a locking bitmap as well as free bitmaps */ +#endif + +#if 1 /* Nick fsck compatible */ +char *daread(uint blk); +void dwrite(uint blk, void *addr); +int da_read(dev_t,uint,void *); +int da_write(dev_t,uint,void *); +#else +void dwrite(uint, void *); +#endif +int yes(char *); +void mkfs(uint, uint, uint); +void doformatting(uint fsize); +#if 1 /* Nick free bitmap */ +void bitmap_dump(char *bitmap, off_t start, off_t final); +#endif + +#if 1 /* Nick fsck compatible */ +char *daread(blk) + uint blk; +{ + static char buf[BUFSIZE]; + + if (da_read(dev, blk, buf) != BUFSIZE) { + PF("Read of block %d failed.\n", blk); + abort(); + } + return (buf); +} + +void dwrite(blk, addr) + uint blk; + void *addr; +{ + if (da_write(dev, blk, addr) != BUFSIZE) { + PF("Write of block %d failed.\n", blk); + abort(); + } +} + +int da_read(dev, blk, addr) + dev_t dev; + uint blk; + void *addr; +{ +#ifdef NATIVE /* Nick */ + if (lseek(device_handle, ((long)blk) << BUFSIZELOG, SEEK_SET) < 0) + { + printf("can't seek: "); + fflush(stdout); + perror(device_name); + exit(1); + } + + if (read(device_handle, addr, BUFSIZE) != BUFSIZE) + { + printf("can't read: "); + fflush(stdout); + perror(device_name); + exit(1); + } +#else + bufptr buf = bread(dev, blk, 0); + + if (buf == NULL) + return 0; + bcopy(buf, addr, BUFSIZE); + bfree(buf, 0); +#endif + return BUFSIZE; +} + +int da_write(dev, blk, addr) + dev_t dev; + uint blk; + void *addr; +{ +#ifdef NATIVE /* Nick */ + if (lseek(device_handle, ((long)blk) << BUFSIZELOG, SEEK_SET) < 0) + { + printf("can't seek: "); + fflush(stdout); + perror(device_name); + exit(1); + } + + if (write(device_handle, addr, BUFSIZE) != BUFSIZE) + { + printf("can't write: "); + fflush(stdout); + perror(device_name); + exit(1); + } +#else + bufptr buf = bread(dev, blk, 1); + + if (buf == NULL) + return 0; + bcopy(addr, buf, BUFSIZE); + bfree(buf, 1); +#endif + return BUFSIZE; +} +#else +void dwrite(blk, addr) + uint blk; + void *addr; +{ +#ifdef NATIVE /* Nick */ + if (lseek(device_handle, ((long)blk) << BUFSIZELOG, SEEK_SET) < 0) + { + printf("can't seek: "); + fflush(stdout); + perror(device_name); + exit(1); + } + + if (write(device_handle, addr, BUFSIZE) != BUFSIZE) + { + printf("can't write: "); + fflush(stdout); + perror(device_name); + exit(1); + } +#else + char *buf = bread(dev, blk, 2); + + if (buf == NULL) { + printf("mkfs: disk is not MS(X)DOS compatible, device or drive error\n"); + xexit(1); + } + bcopy(addr, buf, BUFSIZE); + bfree((bufptr)buf, 2); +#endif +} +#endif + +int yes(p) + char *p; +{ + char line[20]; + + fputs(p,stdout); + FF; + if (_yes) + fputs("Y\n", stdout); + else if (fgets(line, sizeof(line), stdin) == NULL || + (*line != 'y' && *line != 'Y')) + return (0); + return (1); +} + +void mkfs(fsize, isize, rsize) + uint fsize, isize, rsize; +{ + uint j, lm; + filesys_t fs; +#ifdef NATIVE /* Nick */ +#if 1 /* Nick fsck compatible */ + char *buf; + + if (_verb) + { + PF("Creating boot block...\n"); FF; + } +#if 1 /* Nick generic boot routine */ + for (j = 0; j < sizeof(bootblock); j += BUFSIZE) + { + /* writing a complete block, or the last partial block? */ + lm = int_min(sizeof(bootblock) - j, BUFSIZE); + + if (lm < BUFSIZE) + { + buf = daread(j >> BUFSIZELOG); + } + else + { + buf = zeroed; + } + + bcopy(&bootblock[j], buf, lm); + dwrite(j >> BUFSIZELOG, buf); + } +#else + buf = daread(0); + /* Preserve disk data (number of sectors, format type, etc) */ + for (j = 11; j < 30; j++) bootblock[j] = buf[j]; + /* Preserve other relevant data (we just use first 256 bytes) */ + for (j = 256; j < 512; j++) bootblock[j] = buf[j]; + /* Write new boot block */ + bootblock[0x10] = rsize; + dwrite(0, bootblock); +#endif +#else + char buf[BUFSIZE]; + + if (_verb) + { + PF("Creating boot block...\n"); FF; + } + + if (lseek(device_handle, 0L, SEEK_SET) < 0) + { + printf("can't seek: "); + fflush(stdout); + perror(device_name); + exit(1); + } + + if (read(device_handle, buf, BUFSIZE) != BUFSIZE) + { + printf("can't read: "); + fflush(stdout); + perror(device_name); + exit(1); + } + + /* Preserve disk data (number of sectors, format type, etc) */ + for (j = 11; j < 30; j++) bootblock[j] = buf[j]; + /* Preserve other relevant data (we just use first 256 bytes) */ + for (j = 256; j < 512; j++) bootblock[j] = buf[j]; + /* Write new boot block */ + bootblock[0x10] = rsize; + dwrite(0, bootblock); +#endif +#else + char zeroed[BUFSIZE]; + char *buf = bread(dev, 0, 0); + + if (buf == NULL) { + printf("mkfs: disk is not MS(X)DOS compatible, device or drive error\n"); + xexit(1); + } + if (_verb) { + PF("Creating boot block...\n"); FF; + } + /* Preserve disk data (number of sectors, format type, etc) */ + for (j = 11; j < 30; j++) bootblock[j] = buf[j]; + /* Preserve other relevant data (we just use first 256 bytes) */ + for (j = 256; j < 512; j++) bootblock[j] = buf[j]; + /* Write new boot block */ + bfree((bufptr)buf, 0); + bootblock[0x10] = rsize; + dwrite(0, bootblock); +#endif + + /* Zero out the blocks */ + bzero(zeroed, BUFSIZE); + if (_verb) { + PF("Initializing inodes, be patient...\n"); FF; + } + if (_quick) { +#if 0 /* Nick, don't write last block, done by my doformatting() routine */ + dwrite(fsize-1,zeroed); /* Last block */ +#endif + lm = SUPERBLOCK+1+rsize+isize; /* Super+Reserv+Inodes */ + } + else lm = fsize; /* All blocks of filesys */ +#if 1 /* Nick, don't write reserved area, done by my doformatting() routine */ + j = SUPERBLOCK+1+rsize; +#else + j = 1; +#endif + while (j < lm) { + if (_verb && j % 9 == 0) { + PF("Blk #%d\r", j); FF; + } + dwrite(j++, zeroed); + } + if (_verb) { + PF("Blk #%d\n",--j); FF; + } + /* Initialize the super-block */ + if (_verb) { +#ifdef NATIVE + PF("Creating super block...\n"); FF; +#else + PF("Creating super-block...\n"); FF; +#endif + } + bzero((char *)&fs,sizeof(fs)); /* Nick added cast */ + fs.s_mounted = SMOUNTED; /* Magic number */ + fs.s_reserv = SUPERBLOCK+1+rsize; + fs.s_isize = isize; + fs.s_fsize = fsize; + fs.s_tinode = DINODESPERBLOCK * isize - 2; +#if 1 /* Nick free bitmap */ + fs.s_tfree = fsize - (SUPERBLOCK+1+rsize+isize+1); /* +1 block */ + fs.s_bitmap_inode = bitmap_inode; + fs.s_bitmap_block = bitmap_block; + fs.s_bitmap_immov = bitmap_immov; + fs.s_bitmap_final = bitmap_final; + + if (_bitmap) + { + /* mark all system reserved blocks as used in the bitmap */ + for (j = 0; j < SUPERBLOCK+1+rsize+isize+1; j++) /* +1 block */ + { + block_bitmap[j >> 3] |= 1 << (j & 7); + } + + /* mark all out-of-range blocks as used in the bitmap */ + lm = (bitmap_immov - bitmap_block) << 3; /* may wrap to 0 */ + for (j = fsize; j != lm; j++) + { + block_bitmap[j >> 3] |= 1 << (j & 7); + } + + /* dump bitmap, preserving unused bytes of reserved blocks */ + bitmap_dump(block_bitmap, bitmap_block, bitmap_immov); + } + else + { + /* Free each block, building the free list */ + j = fsize - 1; + while (j >= SUPERBLOCK+1+rsize+isize+1) /* +1 block root dir */ + { + if (fs.s_nfree == FSFREEBLOCKS) + { + dwrite(j, (char *) &fs.s_nfree); + fs.s_nfree = 0; + bzero((char *)fs.s_free,sizeof(fs.s_free)); /* Nick */ + } + fs.s_free[fs.s_nfree++] = j--; + } + } + + if (_immov) + { + /* mark all system reserved blocks as used in the bitmap */ + for (j = 0; j < SUPERBLOCK+1+rsize+isize+1; j++) /* +1 block */ + { + immov_bitmap[j >> 3] |= 1 << (j & 7); + } + + /* mark all out-of-range blocks as used in the bitmap */ + lm = (bitmap_final - bitmap_immov) << 3; /* may wrap to 0 */ + for (j = fsize; j != lm; j++) + { + immov_bitmap[j >> 3] |= 1 << (j & 7); + } + + /* dump bitmap, preserving unused bytes of reserved blocks */ + bitmap_dump(immov_bitmap, bitmap_immov, bitmap_final); + } +#else + /* Free each block, building the free list */ + j = fsize - 1; + while (j > SUPERBLOCK+1+rsize+isize) { /* +1 block root dir */ + if (fs.s_nfree == FSFREEBLOCKS) { + dwrite(j, (char *) &fs.s_nfree); + fs.s_nfree = 0; + bzero((char *)fs.s_free,sizeof(fs.s_free)); /* Nick */ + } + /* fs.s_tfree++; */ + fs.s_free[fs.s_nfree++] = j--; + } +#endif + /* The inodes are already zeroed out */ + /* create the root dir */ + inode[ROOTINODE].i_mode = S_IFDIR | 0755; + inode[ROOTINODE].i_nlink = 3; + inode[ROOTINODE].i_size = sizeof(direct_t)*2; + inode[ROOTINODE].i_addr[0] = SUPERBLOCK+1+rsize+isize; + /* Reserve reserved inode */ + inode[0].i_nlink = 1; + inode[0].i_mode = ~0; +#if 1 /* Nick free bitmap */ + if (_bitmap) + { + /* mark all system reserved inodes as used in the bitmap */ + inode_bitmap[0] |= 1; + inode_bitmap[ROOTINODE >> 3] |= 1 << (ROOTINODE & 7); + + /* mark all out-of-range inodess as used in the bitmap */ + lm = (bitmap_block - bitmap_inode) << 3; /* may wrap to 0 */ + for (j = DINODESPERBLOCK * isize; j != lm; j++) + { + inode_bitmap[j >> 3] |= 1 << (j & 7); + } + + /* dump bitmap, preserving unused bytes of reserved blocks */ + bitmap_dump(inode_bitmap, bitmap_inode, bitmap_block); + } + else + { + /* Free inodes in first inode block */ + j = ROOTINODE+1; + while (j < DINODESPERBLOCK) + { + if (fs.s_ninode == FSFREEINODES) + { + break; + } + fs.s_inode[fs.s_ninode++] = j++; + } + } +#else + /* Free inodes in first inode block */ + j = ROOTINODE+1; + while (j < DINODESPERBLOCK) { + if (fs.s_ninode == FSFREEINODES) + break; + fs.s_inode[fs.s_ninode++] = j++; + } +#endif + dwrite(SUPERBLOCK+1+rsize, inode); + dwrite(SUPERBLOCK+1+rsize+isize, dirbuf); + /* Write out super block */ +#if 1 /* Nick fsck compatible */ + buf = daread(SUPERBLOCK); + bcopy((char *)&fs, buf, sizeof(fs)); + dwrite(SUPERBLOCK, buf); +#else + dwrite(SUPERBLOCK, &fs); +#endif +} + +void doformatting(uint fsize) +{ +#ifdef _MSX_DOS + if (_verb) { + PF("Low level formatting:\n"); FF; + } + asm(" push ix"); + asm(" push iy"); + asm(" ld ix,0147h"); /* FORMAT function (it asks user) */ + asm(" ld iy,(0fcc0h)"); /* ROM BIOS slot */ + asm(" call 001Ch"); + asm(" pop iy"); + asm(" pop ix"); +#else +#ifdef __ONFILE + uint j; + char zeroed[BUFSIZE]; + + /* apply minimum size, in case never formatted before */ + fdinfo[MINOR(dev)].size = min(fsize, fdinfo[MINOR(dev)].size); + + /* write the entire disk, growing the file if necessary */ + bfill(zeroed, 0xaa, BUFSIZE); + for (j = 0; j < fsize; j++) + { + dwrite(j, zeroed); + } +#else +#if 1 /* Nick */ + uint j; + char zeroed[BUFSIZE]; + + if (_verb) { + PF("Low level formatting...\n"); FF; + } + + /* write the entire disk, growing the file if necessary */ + bfill(zeroed, 0xaa, BUFSIZE); + for (j = 0; j < fsize; j++) + { + dwrite(j, zeroed); + } +#else + fprintf(stderr, "Use FORMAT for low level formatting!\n"); +#endif +#endif +#endif +} + +void main(argc, argv) + int argc; + char *argv[]; +{ + uint fsize, isize, rsize = 0; + int ap = 1, ac = argc; + uchar *p; + +#ifdef _MSX_DOS + initenv(); +#endif + while (ap < argc && *(p = (uchar *)argv[ap]) == '-') { + ++p; + ++ap; + --ac; + while (*p) { + switch (*p++) { + case 'y': case 'Y': _yes = 1; break; + case 'f': case 'F': _fmt = 1; break; + case 'q': case 'Q': _quick = 1; break; + case 'v': case 'V': _verb = 1; break; +#if 1 /* Nick free bitmap */ + case 'l': case 'L': _immov = 1; /* fallthru */ + case 'b': case 'B': _bitmap = 1; break; +#endif + default: + fprintf(stderr, "Illegal switch %s\n", p); +#ifdef NATIVE /* Nick */ + exit(1); +#else + xexit(-1); +#endif + } + } + } +#ifdef NATIVE /* Nick */ + if (ac < 4) { + /* parameters order agree with FSCK */ +#if 1 /* Nick free bitmap */ + fprintf(stderr, "usage: mkfs [-yfqvb] device fsize isize [rsize]\n"); +#else + fprintf(stderr, "usage: mkfs [-yfqv] device fsize isize [rsize]\n"); +#endif + exit(1); +#else + if ((ac < 4) || (argv[ap+0][1] != ':') || !isalpha(argv[ap+0][0])) { + /* parameters order agree with FSCK */ + fprintf(stderr, "usage: mkfs [-yfqv] d: fsize isize [rsize]\n"); + xexit(-1); +#endif + } +#ifdef NATIVE /* Nick */ + strcpy(device_name, argv[ap]); + device_handle = open(device_name, O_RDWR | O_BINARY); + if (device_handle < 0) + { + printf("can't open: "); + fflush(stdout); + perror(device_name); + exit(1); + } +#else + dev = ((argv[ap+0][0] & 223) - 65); +#endif + fsize = (uint) atoi(argv[ap+1]); + isize = (uint) atoi(argv[ap+2]); + if (ac > 4) + rsize = (uint) atoi(argv[ap+3]); +#ifndef NATIVE + if (dev >= 8) { + fprintf(stderr,"Invalid drive %c:.\n",dev+65); + xexit(-1); + } +#endif + if (fsize < 100 || isize >= fsize/30 || rsize > 100) { + fprintf(stderr,"Bad parameter values\n"); +#ifdef NATIVE /* Nick */ + exit(1); +#else + xexit(-1); +#endif + } +#if 1 /* Nick free bitmap */ + if (_bitmap) + { + bitmap_inode = SUPERBLOCK * BUFSIZE + sizeof(filesys_t); + bitmap_inode = (bitmap_inode + 3) & ~3; + + bitmap_block = bitmap_inode + + ((DINODESPERBLOCK * isize - 1) >> 3) + 1; + bitmap_block = (bitmap_block + 3) & ~3; + + bitmap_immov = bitmap_block + ((fsize - 1) >> 3) + 1; + bitmap_immov = (bitmap_immov + 3) & ~3; + + bitmap_final = bitmap_immov; + rsize = ((bitmap_final + (BUFSIZE - 1)) >> BUFSIZELOG) - + (SUPERBLOCK + 1); + } + + if (_immov) + { + bitmap_final = bitmap_immov + ((fsize - 1) >> 3) + 1; + bitmap_final = (bitmap_final + 3) & ~3; + + rsize = ((bitmap_final + (BUFSIZE - 1)) >> BUFSIZELOG) - + (SUPERBLOCK + 1); + } +#endif +#ifdef NATIVE /* Nick */ + PF("\nMaking filesystem on %s, fsize %u, isize %u, rsize %u. ", + device_name, fsize, isize, rsize); FF; +#else + PF("\nMaking filesystem on drive %c, fsize %u, isize %u, rsize %u. ", + dev+65, fsize, isize, rsize); FF; +#endif + if (!yes("Confirm? ")) +#ifdef NATIVE /* Nick */ + exit(1); +#else + xexit(-1); +#endif +#ifdef _MSX_DOS + if (!_yes) { + PF("Insert disk and press RETURN: "); FF; + getchar(); + } +#endif + PF("\n"); + if (_fmt) + doformatting(fsize); +#if 1 /* Nick free bitmap */ + if (_bitmap) + { + inode_bitmap = malloc(bitmap_block - bitmap_inode); + if (inode_bitmap == NULL) + { + p = "inode bitmap"; + goto nomem; + } + bfill(inode_bitmap, 0, bitmap_block - bitmap_inode); + + block_bitmap = malloc(bitmap_final - bitmap_block); + if (block_bitmap == NULL) + { + p = "block bitmap"; + goto nomem; + } + bfill(block_bitmap, 0, bitmap_final - bitmap_block); + } + + if (_immov) + { + immov_bitmap = malloc(bitmap_final - bitmap_immov); + if (immov_bitmap == NULL) + { + p = "lock bitmap"; +nomem: fprintf(stderr,"Not enough memory for %s.\n", p); + exit(1); + } + bfill(immov_bitmap, 0, bitmap_final - bitmap_immov); + } +#endif +#ifndef NATIVE /* Nick */ + bufinit(); + if (d_init() || d_open(dev)) { + fprintf(stderr, "Can't open device %x",dev); + xexit(-1); + } +#endif + mkfs(fsize, isize, rsize); +#ifdef NATIVE /* Nick */ + close(device_handle); +#else + d_close(dev); + bufsync(); +#endif + if (_verb) +#ifdef NATIVE /* Nick */ + PF("Filesystem on %s successfully initialized!\n\n", + device_name); +#else + PF("Filesystem on drive %c successfully initialized!\n", + dev+65); +#endif + exit(0); +} + +#if 1 /* Nick free bitmap */ +void bitmap_dump(char *bitmap, off_t start, off_t final) + { + char *buf; + blkno_t j, lm; + + /* dump bitmap, preserving unused bytes of reserved blocks */ + j = start; + while (j < final) + { + /* calculate ending position after writing block */ + lm = int_min((j + BUFSIZE) & ~(BUFSIZE - 1), final); + + /* optimisation if we are writing the entire block */ + if ((lm - j) < BUFSIZE) + { + buf = daread(j >> BUFSIZELOG); + } + else + { + buf = zeroed; /* no need to read the block */ + } + + /* ready to copy data into the block and write it */ + bcopy(bitmap + (j - start), buf + (j & (BUFSIZE - 1)), lm - j); + dwrite(j >> BUFSIZELOG, buf); + + /* bump counter to continue after data just written */ + j = lm; + } + } +#endif + diff --git a/src/fsutil/mkfs.exe b/src/fsutil/mkfs.exe new file mode 100755 index 0000000000000000000000000000000000000000..4fd4a4e9b8f2314cfb920eb0b0080d5dd29002d2 GIT binary patch literal 65578 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 +#include +#include +#include +/* #include */ +#include +#ifdef NATIVE /* Nick native mode */ +#include +#include +/* void bzero(char *ptr, int count); */ +#endif +#else +#include "fcntl.h" +#ifdef SEPH +#include "sys\ioctl.h" +#include "sys\stat.h" +#endif +#ifdef _MSX_DOS +#include ".\include\stdio.h" +#include ".\include\stdlib.h" +#include ".\include\string.h" +#include ".\include\unixio.h" +#include ".\include\ctype.h" +#else +#include +#include +#include +#include +#include +#include +#endif +#endif + +FILE *in = stdin; +int rdev = -1; +uchar *syserror = (uchar *)&udata.u_error; +uchar cwd[128+1]; +uchar line[128+1]; +uchar f_pause = 0; + +int xls(char *option, char *path); +int xchmod(char *path, char *modes); +int xumask(char *masks); +int xmknod(char *path, char *modes, char *devs, char *devs1); +int xmkdir(char *path); +int xget(char *arg, char *unixn, int binflag); +int xput(char *arg, char *dosn, int binflag); +int xtype(char *arg); +int xdump(char *arg, char *start, char *end); +int xunlink(char *path); +int xrmdir(char *path); +int xdf(void); +#if 1 /* Nick free bitmap */ +int xalign(char *path, char *size); +int xualign(char *path); +#endif +extern int ldir(char *s1); +#ifdef _MSX_DOS +extern int memicmp(char *s1, char *s2, int t); +extern int chdir(char *s1); +#endif + +void pse(void); +void dohelp(void); +int eq(char *, char *); +int execute(char *cmd, char *a1, char *a2, char *a3, char *a4); + +char *help[] = { +#ifndef _MSX_DOS + "!", +#endif + "exit|quit", + "root d:", + "df", + "pwd", + "ls [-l] [dirname[/filename]]", + "cd dirname", + "lcd dosdirname", + "ldir [filemask]", + "umask mask", + "mkdir name", + "mknod name mode major minor", + "chmod mode name", + "[b]get dosfilename [uzixfilename]", + "[b]put uzixfilename [dosfilename]", + "type|cat filename", + "dump filename [startblk [endblk]]", + "[s]ln srcname dstname", + "rm [dirname/]filename", + "rmdir dirname", + "mount devicename dirname", + "umount devicename", + "success|failure label", +#if 1 /* Nick free bitmap */ + "align filename [bytes]", + "ualign filename", +#endif + NULL +}; + +void pse(VOID) { + if (f_pause) { + fprintf(stderr,"Press ENTER>"); + fflush(stderr); + fgets(line,128,stdin); + } +} + +void dohelp(VOID) { + int i = 0; + + while (help[i] != NULL) + PF("%s\n",help[i++]); +} + +int eq(s1,s2) + char *s1; + char *s2; +{ + return (stricmp(s1,s2) == 0); +} + +int execute(cmd, a1, a2, a3, a4) + char *cmd, *a1, *a2, *a3, *a4; +{ + if (rdev < 0) { + PF("error: root device not mounted\n"); + pse(); + } + else if (eq(cmd, "ls")) + xls (a1, a2); + else if (eq(cmd, "umask")) + xumask(*a1 ? a1 : "0"); + else if (eq(cmd, "cd")) { + if (*a1) { + if (UZIXchdir(a1)) { + PF("cd: error %s\n", stringerr[*syserror]); + pse(); + } + else strcpy(cwd, a1); + } + } + else if (eq(cmd, "pwd")) { + PF("%s\n",cwd); + } + else if (eq(cmd, "mkdir")) { + if (*a1) + xmkdir(a1); + } + else if (eq(cmd, "mknod")) { + if (*a1 && *a2 && *a3 && *a4) + xmknod(a1, a2, a3, a4); + } + else if (eq(cmd, "chmod")) { + if (*a1 && *a2) + xchmod(a1, a2); + } + else if (eq(cmd, "ln")) { + if (*a1 && *a2) + UZIXlink(a1, a2); + } + else if (eq(cmd, "sln")) { + if (*a1 && *a2) + UZIXsymlink(a1, a2); + } + else if (eq(cmd, "get")) { + if (*a1) + xget(a1, a2, 0); + } + else if (eq(cmd, "bget")) { + if (*a1) + xget(a1, a2, 1); + } + else if (eq(cmd, "put")) { + if (*a1) + xput(a1, a2, 0); + } + else if (eq(cmd, "bput")) { + if (*a1) + xput(a1, a2, 1); + } + else if (eq(cmd, "type") || eq(cmd, "cat")) { + if (*a1) + xtype(a1); + } + else if (eq(cmd, "dump")) { + if (*a1) + xdump(a1, a2, a3); + } + else if (eq(cmd, "rm")) { + if (*a1) + xunlink(a1); + } + else if (eq(cmd, "df")) + xdf(); + else if (eq(cmd, "rmdir")) { + if (*a1) + xrmdir(a1); + } + else if (eq(cmd, "mount")) { + if (*a1 && *a2 && UZIXmount(a1, a2, 0) != 0) { + PF("mount: error %s\n", stringerr[*syserror]); + pse(); + } + } + else if (eq(cmd, "umount")) { + if (*a1 && UZIXumount(a1) != 0) { + PF("umount: error %s\n", stringerr[*syserror]); + pse(); + } + } +#if 1 /* Nick free bitmap */ + else if (eq(cmd, "align")) { + if (*a1) + xalign(a1, a2); + } + else if (eq(cmd, "ualign")) { + if (*a1) + xualign(a1); + } +#endif + else return 1; + return 0; +} + +void usage(void) { + fprintf(stderr, + "usage: ucp [switches] [dev] [indirect]\n" + "\tswitches:\n" + "\t\t-p - pause after error\n" + "\t\t-1 - don't mount root\n" + "\t\t-y - don't ask user for UZIX disk\n" + "\tdev:\n" + "\t\t0..7\n" + "\t\tA:..Z:\n" + "\tindirect:\n" + "\t\t@filename\n" + "\t\t@ filename\n" + ); + xexit(1); +} + +int main(argc, argv) + int argc; + char *argv[]; +{ + int count, lasterr, quiet, skip = 0, _rdev; + uchar waitdisk = 1; + char *s, cmd[30], a1[30], a2[30], a3[30], a4[30]; + +#ifdef _MSX_DOS + initenv(); + cursor(0); +#endif + for (++argv; --argc > 0; ) { + s = *argv++; + if (*s == '-') { + switch (*++s) { + case 'p': case 'P': + f_pause = 1; + break; + case '1': + rdev = -1; + break; + case 'y': case 'Y': + waitdisk = 0; + break; + default: + usage(); + } + } + else if (*s == '@') { + if (in != stdin) { + fprintf(stderr,"Input file already redirected\n"); + xexit(1); + } + if (*++s == '\0') { + if (--argc <= 0) + usage(); + s = *argv++; + } + if (NULL == (in = fopen(s,"rt"))) { + fprintf(stderr,"Can't redirect input to file %s\n",s); + xexit(1); + } + } + else if (isdigit(*s) && s[1] == '\0') { + rdev = *s - '0'; + } + else if (isalpha(*s) && s[1] == ':') { + rdev = ((*s & 0xDF) - 'A'); + } + else usage(); + } + xfs_init(rdev, waitdisk); + strcpy(cwd, "/"); + quiet = !isatty(fileno(in)); + if (!quiet) + PF("UCP ready!\n"); + lasterr = 0; + for (;;) { + if (!quiet) { + PF("\ruzix: "); + skip = 0; + } + if (fgets(line,128,in) == NULL) + break; + if (quiet) { + if (skip && memicmp(line,a1,strlen(a1))) { + putchar('#'); + fputs(line,stdout); + goto Cont; + } + if (skip && (memicmp(line,a1,strlen(a1))==0)) --skip; + fputs(line,stdout); + } + cmd[0] = a1[0] = a2[0] = a3[0] = '\0'; + count = sscanf(line, "%s %s %s %s %s", cmd, a1, a2, a3, a4); + if (count == 0 || cmd[0] == '#' || cmd[0] == ':') + goto Cont; + if (*cmd == 0) + UZIXsync(); + else if (eq(cmd, "exit") || eq(cmd, "quit")) + break; +#ifndef _MSX_DOS + else if (cmd[0] == '!') { + s = strchr(line, '\n'); + if (s != NULL) *s='\0'; + for (s = line; *s++ != '!'; ) + ; + while (*s == ' ' || *s == '\t') + ++s; + system(s); + } +#endif + else if (eq(cmd, "?")) + dohelp(); + else if (eq(cmd, "success")) { + if (!lasterr) + ++skip; + } + else if (eq(cmd, "failure")) { + if (lasterr) + ++skip; + } + else if (eq(cmd, "root")) { + if (rdev >= 0) { + PF("root: root device already mounted!\n"); + pse(); + } + else { + if (isdigit(*a1)) + _rdev = *a1 - '0'; + else _rdev = (*a1 & 0xDF) - 'A'; + if ((unsigned)_rdev <= 8) { + rdev = _rdev; + xfs_init(rdev, waitdisk); + strcpy(cwd, "/"); + } + else { + PF("root: invalid drive %c.\n",*a1); + pse(); + } + } + } + else if (eq(cmd, "lcd")) { + if (*a1 && chdir(a1)) { + PF("lcd: can't chdir to %s\n", a1); + pse(); + } + } + else if (eq(cmd, "ldir")) { + ldir(*a1 ? a1 : "*.*"); + } + else if (execute(cmd, a1, a2, a3, a4)) { + PF("Unknown command - use ?\n"); + pse(); + } +Cont: lasterr = *syserror; + *syserror = 0; + } + xfs_end(); +#ifdef _MSX_DOS + cursor(255); +#endif + return 0; +} + diff --git a/src/fsutil/ucp.exe b/src/fsutil/ucp.exe new file mode 100755 index 0000000000000000000000000000000000000000..49f121100b9587fee71bb961074b14c37a2c38c5 GIT binary patch literal 143402 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\wv`Jk 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 Apa1{> literal 0 HcmV?d00001 diff --git a/src/fsutil/ucp.ltc b/src/fsutil/ucp.ltc new file mode 100755 index 00000000..2f4218fa --- /dev/null +++ b/src/fsutil/ucp.ltc @@ -0,0 +1,16 @@ +/subsystem:console +"/libpath:c:\Program Files\Microsoft Visual Studio\VC98\lib" +/map:ucp.map +ucp.obj +xdata.obj +xmachdep.obj +devhd.obj +hdasm.obj +devio.obj +xdevmisc.obj +xdevtty.obj +xfs1.obj +xfs1a.obj +xfs1b.obj +xfs2.obj +utils.obj diff --git a/src/fsutil/ucp.w32 b/src/fsutil/ucp.w32 new file mode 100755 index 00000000..82b617a0 --- /dev/null +++ b/src/fsutil/ucp.w32 @@ -0,0 +1,20 @@ +/debug +/subsystem:console +"/libpath:c:\Program Files\Microsoft Visual Studio\VC98\lib" +/map:ucp.map +ucp.obj +ucpsub.obj +devhd.obj +devio.obj +devmisc.obj +devtty.obj +filesys.obj +hdasm.obj +machdep.obj +main.obj +process.obj +scall1.obj +scall2.obj +xip.obj +utils.obj +xfs.obj diff --git a/src/fsutil/ucpsub.c b/src/fsutil/ucpsub.c new file mode 100755 index 00000000..c3b90ddc --- /dev/null +++ b/src/fsutil/ucpsub.c @@ -0,0 +1,649 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + Subroutines for UCP +**********************************************************/ + +#define SKIP_TIME_T /* Nick */ + +#include "utildos.h" +#include "xfs.h" + +#if 1 /* Nick */ +#include +#include +#include +#include +/* #include */ +#include +#ifdef NATIVE /* Nick native mode */ +#include +#include +/* void bzero(char *ptr, int count); */ +#endif +#else +#include "fcntl.h" +#ifdef SEPH +#include "types.h" +#include "signal.h" +#include "sys\ioctl.h" +#include "sys\stat.h" +#endif +#ifdef _MSX_DOS +#include "..\include\stdio.h" +#include "..\include\stdlib.h" +#include "..\include\string.h" +#include "..\include\unixio.h" +#else +#include +#include +#include +#include +#include +#endif +#endif + +#define PF printf + +extern uchar *syserror; + +int xls(char *option, char *path); +int xchmod(char *path, char *modes); +int xumask(char *masks); +int xmknod(char *path, char *modes, char *devs, char *devs1); +int xmkdir(char *path); +int xget(char *arg, char *unixn, int binflag); +int xput(char *arg, char *dosn, int binflag); +int xtype(char *arg); +int xdump(char *arg, char *start, char *end); +int xunlink(char *path); +int xrmdir(char *path); +int xdf(void); +#ifdef VAX /* Nick PC_HOSTED */ +int ldir(char *s1); +#endif +#ifdef _MSX_DOS +extern int memicmp(char *s1, char *s2, int t); +extern unsigned char tolower(unsigned char c); +extern int chdir(char *s1); +#endif + +extern int eq(char *, char *); +extern void pse(void); + +int devdir(int stat); +char *prot(int stat); +void dols(int d, char *path, int wide); + +#ifdef _MSX_DOS +#include "ucp.msx" +#endif + +#ifdef VAX /* Nick PC_HOSTED */ +int ldir(char *s1) { + char s[130]; + + printf("DOS files:\n"); + sprintf(s, "dir %s", s1); + return system(s); +} +#endif + +int devdir(stat) + int stat; +{ + stat &= S_IFMT; + + switch (stat) { + case S_IFDIR: return 'd'; + case S_IFPIPE: return 'p'; + case S_IFBLK: return 'b'; + case S_IFCHR: return 'c'; + case S_IFLNK: return 'l'; + } + return '-'; +} + +char *prot(stat) + int stat; +{ + static char _prots[8][4] = { + "---", "--x", "-w-", "-wx", + "r--", "r-x", "rw-", "rwx" + }; + return _prots[stat & 7]; +} + +void dols(d, path, wide) + int d; + char *path; + int wide; +{ + int i, fd; + direct_t buf; + char dname[512]; + struct stat statbuf; + + while (UZIXread(d, (char *) &buf, sizeof(direct_t)) == sizeof(direct_t)) { + if (buf.d_name[0] == '\0') + continue; + dname[0] = '\0'; + if (!eq(path,".")) { + strcpy(dname, path); + strcat(dname, "/"); + } + strncat(dname, buf.d_name, DIRNAMELEN); + fd = UZIXopen(dname, O_SYMLINK); + i = (fd >= 0) ? UZIXfstat(fd, &statbuf) : + UZIXstat(dname, &statbuf); + if (i) { + PF("ls: can't stat %s\n", dname); + if (fd >= 0) + UZIXclose(fd); + continue; + } + if ((statbuf.st_mode & S_IFMT) == S_IFDIR) + strcat(dname, "/"); + if (!wide) { + if (S_ISDEV(statbuf.st_mode)) + PF("%3d,%-5d", + MAJOR(statbuf.st_rdev), + MINOR(statbuf.st_rdev)); + else PF("%-9ld", statbuf.st_size); + PF(" %c%s%s%s %2d @%-5u %s", + devdir(statbuf.st_mode), + prot(statbuf.st_mode >> 6), + prot(statbuf.st_mode >> 3), + prot(statbuf.st_mode >> 0), + statbuf.st_nlink, + statbuf.st_ino, + dname); + if ((statbuf.st_mode & S_IFMT) == S_IFLNK) { + dname[0] = 0; + i = UZIXread(fd, dname, sizeof(dname)-1); + dname[i] = 0; + PF(" -> %s", dname); + UZIXclose(fd); + } + } else { + printf("%s", dname); + i = strlen(dname) + 1; + if ((statbuf.st_mode & S_IFMT) == S_IFLNK) putchar('@'); + else if (((statbuf.st_mode & S_IFMT) != S_IFDIR) && + ((statbuf.st_mode & S_IEXEC) + + (statbuf.st_mode & S_IGEXEC) + + (statbuf.st_mode & S_IOEXEC) != 0)) putchar('*'); + else i--; + if (i < 16) putchar('\t'); + if (i < 8) putchar('\t'); + } + if (!wide) putchar('\n'); + } + if (wide) putchar('\n'); +} + +int xls(option, thepath) + char *thepath, *option; + +{ + int d, wide = 1; + char *path = option; + struct stat statbuf; + + if (eq(option, "-l")) { + wide = 0; + path = thepath; + } + if (!*path) path = "."; + if (UZIXstat(path, &statbuf) != 0) { + PF("ls: can't stat %s\n", path); + pse(); + } + else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { + PF("ls: %s is not a directory\n", path); + pse(); + } + else if ((d = UZIXopen(path, 0)) < 0) { + PF("ls: can't open %s\n", path); + pse(); + } + else { + dols(d, path, wide); + UZIXclose(d); + } + return 0; +} + +/* just to make syntax equal to Solaris, Linux, etc */ +int xchmod(modes, path) + char *path, *modes; +{ + int mode = -1; + + sscanf(modes, "%o", &mode); + if (mode == -1) { + PF("chmod: bad mode\n"); + pse(); + return (-1); + } + if (UZIXchmod(path, mode)) { + PF("_chmod: error %s\n", stringerr[*syserror]); + pse(); + return (-1); + } + return 0; +} + +int xumask(masks) + char *masks; +{ + int mask = -1; + + if (masks == NULL) { + mask = UZIXumask(0); + UZIXumask(mask); + PF("%3o\n", mask); + } + else { + sscanf(masks, "%o", &mask); + if (mask == -1) { + PF("umask: bad mask\n"); + pse(); + return (-1); + } + UZIXumask(mask); + } + return 0; +} + +int xmknod(path, modes, devs, devs1) + char *path, *modes, *devs, *devs1; +{ + int dev, major = -1, minor = -1, mode = -1; + + sscanf(modes, "%o", &mode); + sscanf(devs, "%d", &major); + sscanf(devs1, "%d", &minor); + if (mode == -1) { + PF("mknod: bad mode\n"); + pse(); + return (-1); + } + if ((mode & S_IFMT) != S_IFBLK && (mode & S_IFMT) != S_IFCHR) { + PF("mknod: mode is not device\n"); + pse(); + return (-1); + } + if (major == -1 || minor == -1) { + PF("mknod: bad device numbers\n"); + pse(); + return (-1); + } + dev = MKDEV(major, minor); + if (UZIXmknod(path, mode, dev) != 0) { + PF("_mknod: error %s\n", stringerr[*syserror]); + pse(); + return (-1); + } + return (0); +} + +int xmkdir(path) + char *path; +{ + if (UZIXmknod(path, S_IFDIR | 0777, 0) != 0) { + PF("mkdir: mknod error %s\n", stringerr[*syserror]); + pse(); + return (-1); + } + return 0; +} + +int xget(arg, unixn, binflag) + char *arg; + char *unixn; + int binflag; +{ + int d, nread; + FILE *fp = fopen(arg, binflag ? "rb" : "r"); + char cbuf[BUFSIZE]; + + if (fp == NULL) { + PF("Source file not found\n"); + pse(); + return (-1); + } + if (*unixn == 0) { + unixn = arg+strlen(arg); + while (--unixn > arg) { + if (*unixn == '\\' || *unixn == ':') { + ++unixn; + break; + } + } + } + d = UZIXcreat(unixn, 0666); + if (d < 0) { + PF("Cant open uzix file %s, error %s\n", + unixn, stringerr[*syserror]); + pse(); + return (-1); + } + for (;;) { + nread = fread(cbuf, 1, BUFSIZE, fp); + if (nread == 0) + break; + if (UZIXwrite(d, cbuf, nread) != nread) { + PF("_write: error %s\n", stringerr[*syserror]); + fclose(fp); + UZIXclose(d); + pse(); + return (-1); + } + } + fclose(fp); + UZIXclose(d); + return (0); +} + +int xput(arg, dosn, binflag) + char *arg; + char *dosn; + int binflag; +{ + int d, nread; + FILE *fp; + char cbuf[BUFSIZE]; + + d = UZIXopen(arg, 0); + if (d < 0) { + PF("Can't open uzix file %s, error %s\n", + arg, stringerr[*syserror]); + pse(); + return (-1); + } + if (*dosn == 0) { + dosn = arg+strlen(arg); + while (--dosn > arg) { + if (*dosn == '\\' || *dosn == ':') { + ++dosn; + break; + } + } + } + fp = fopen(dosn, binflag ? "wb" : "w"); + if (fp == NULL) { + PF("Can't open destination file %s\n",dosn); + pse(); + return (-1); + } + for (;;) { + if ((nread = UZIXread(d, cbuf, BUFSIZE)) == 0) + break; + if (fwrite(cbuf, 1, nread, fp) != nread) { + PF("fwrite error\n"); + fclose(fp); + UZIXclose(d); + pse(); + return (-1); + } + } + fclose(fp); + UZIXclose(d); + return (0); +} + +int xtype(arg) + char *arg; +{ + int nread; + int d = UZIXopen(arg, 0); + char cbuf[BUFSIZE]; + + if (d < 0) { + PF("Can't open uzix file %s, error %s\n", + arg, stringerr[*syserror]); + pse(); + return (-1); + } + for (;;) { + if ((nread = UZIXread(d, cbuf, BUFSIZE)) <= 0) + break; + fwrite(cbuf, 1, nread, stdout); + } + UZIXclose(d); + return (0); +} + +int xdump(arg, start, end) + char *arg, *start, *end; +{ + int nread; + char buf[BUFSIZE]; + uint i, j, k, d, blk, blkstart, blkend; + + d = UZIXopen(arg, 0); + if (d < 0) { + PF("Can't open uzix file %s, error %s\n", + arg, stringerr[*syserror]); + pse(); + return (-1); + } + if (*start) + blkstart = atoi(start); + else blkstart = 0; + if (*end) + blkend = atoi(end); + else blkend = 0xFFFF; + if (blkend < blkstart) + blkend = blkstart; + blk = blkstart; + while (blk <= blkend && (nread = UZIXread(d, buf, BUFSIZE)) > 0) { + PF("Block %d (0x%x)\n",blk,blk); + i = 0; + while (i < ((nread + 15) >> 4)) { + PF("%04x\t", blk*BUFSIZE + (i<<4)); + for (j = 0; j < 16; ++j) { + k = buf[(i<<4)+j] & 0xFF; + if (k < 0x10) + PF("0%x ", k); + else PF("%x ", k); + } + PF(" |"); + for (j = 0; j < 16; ++j) { + k = buf[(i<<4)+j] & 0xFF; + if (k < ' ' || k == 0177 || k == 0377) + k = '.'; + PF("%c", k); + } + PF("|\n"); + ++i; + } + PF("\n"); + ++blk; + } + UZIXclose(d); + return nread; +} + +int xunlink(path) + char *path; +{ + int i, fd = UZIXopen(path, O_SYMLINK); + struct stat statbuf; + + if (fd >= 0) { + i = UZIXfstat(fd, &statbuf); + UZIXclose(fd); + } + else i = UZIXstat(path, &statbuf); + if (i) { + PF("unlink: can't stat %s\n", path); + pse(); + return (-1); + } + if ((statbuf.st_mode & S_IFMT) == S_IFDIR) { + PF("unlink: %s directory\n", path); + pse(); + return (-1); + } + if (UZIXunlink(path) != 0) { + PF("_unlink: error %s\n", stringerr[*syserror]); + pse(); + return (-1); + } + return (0); +} + +int xrmdir(path) + char *path; +{ + int fd; + struct stat statbuf; + char newpath[100]; + direct_t dir; + + if (UZIXstat(path, &statbuf) != 0) { + PF("rmdir: can't stat %s\n", path); + pse(); + return (-1); + } + if ((statbuf.st_mode & S_IFDIR) == 0) { + PF("rmdir: %s not directory\n", path); + pse(); + return (-1); + } + if ((fd = UZIXopen(path, 0)) < 0) { + PF("rmdir: %s unreadable\n", path); + pse(); + return (-1); + } + while (UZIXread(fd, (char *) &dir, sizeof(dir)) == sizeof(dir)) { + if (dir.d_ino == 0 || + eq(dir.d_name, ".") || + eq(dir.d_name, "..")) + continue; + PF("rmdir: %s not empty\n", path); + UZIXclose(fd); + pse(); + return (-1); + } + UZIXclose(fd); + strcpy(newpath, path); + strcat(newpath, "/."); + if (UZIXunlink(newpath) != 0) + PF("rmdir: can't unlink \".\", error %s\n", stringerr[*syserror]); + strcat(newpath, "."); + if (UZIXunlink(newpath) != 0) + PF("rmdir: can't unlink \"..\", error %s\n", stringerr[*syserror]); + if (UZIXunlink(path) != 0) { + PF("rmdir: _unlink error %s\n", stringerr[*syserror]); + pse(); + return (-1); + } + return (0); +} + +int xdf() { + uint j; + fsptr fsys; + info_t info; + + for (j = 0; j < 8; ++j) { + if (!UZIXgetfsys(j, &info) && + (fsys = (fsptr)info.ptr)->s_mounted) { + PF("Drive %c: %u/%u blocks used/free, " + "%u/%u inodes used/free\n", + j + 65, + (fsys->s_fsize - fsys->s_isize) - fsys->s_tfree - fsys->s_reserv, + fsys->s_tfree, + (DINODESPERBLOCK * fsys->s_isize - fsys->s_tinode), + fsys->s_tinode); + } + } + return 0; +} + +#if 1 /* Nick free bitmap */ +int xalign(char *path, char *size) + { + int d; + struct stat statbuf; + + if (UZIXstat(path, &statbuf) != 0) + { + PF("align: can't stat %s\n", path); + pse(); + } + else if ((statbuf.st_mode & S_IFMT) == S_IFALIGN) + { + PF("align: %s is already aligned\n", path); + pse(); + } + else if ((statbuf.st_mode & S_IFMT) != S_IFREG) + { + PF("align: %s is not a regular file\n", path); + pse(); + } + else if ((d = UZIXopen(path, 0)) < 0) + { + PF("align: can't open %s\n", path); + pse(); + } + else + { + if (UZIXfalign(d, XIP_ALIGN) < 0) + { + PF("align: can't align %s\n", path); + } + UZIXclose(d); + } + } + +int xualign(char *path) + { + int d; + struct stat statbuf; + + if (UZIXstat(path, &statbuf) != 0) + { + PF("ualign: can't stat %s\n", path); + pse(); + } + else if ((statbuf.st_mode & S_IFMT) != S_IFALIGN) + { + PF("ualign: %s is not an aligned file\n", path); + pse(); + } + else if ((d = UZIXopen(path, 0)) < 0) + { + PF("ualign: can't open %s\n", path); + pse(); + } + else + { + if (UZIXfalign(d, XIP_UALIGN) < 0) + { + PF("ualign: can't unalign %s\n", path); + } + UZIXclose(d); + } + } +#endif + diff --git a/src/fsutil/utildos.c b/src/fsutil/utildos.c new file mode 100755 index 00000000..27ba0072 --- /dev/null +++ b/src/fsutil/utildos.c @@ -0,0 +1,88 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + MSX machine dependent routines for UZIX utilities +**********************************************************/ + +#include "utildos.h" + +#ifdef _MSX_DOS /* MSXDOS initialization procedures */ +#ifdef Z80MU +#define BDOSADDR 0FEFEh +#else +#define BDOSADDR 00005h +#endif + +/* CALROM and BDOS routines for DOS utils */ +#asm + psect text +_calromd: + ld iy,(0FCC1h) + jp 1Ch +_calbdos: + ld iy,(MAINDRV-1) + jp 1Ch +#endasm + +uchar xxbdos(uint de,uchar c) { +#asm + push bc + call BDOSADDR + ld l,a + pop bc + ret +#endasm +} + +/* Set UZIX CALROM and BDOS calls to DOS routines */ +void initenv(void) { +#asm + ld a,0C3h ; JP + ld (CALROM),a + ld (BDOS),a + ld hl,_calromd + ld (CALROM+1),hl + ld hl,_calbdos + ld (BDOS+1),hl +#endasm +} + +extern void exit(int); + +/* Quit program and also batch file if called under one */ +void xexit(int errcode) { + uint i; + + if (DOSVER == 0) { /* DOS1: */ + i = *(uint *)0x6; + i += 19; + *(uchar *)i = 0; /* clear BATFLG (abort batchfile) */ + exit(errcode); + } + i = 0; /* a C statement must be put here or the "else" statement + of the above if will not jump to the ASM code below */ + /* DOS2: */ +#asm + ld bc,08062h ; exit with error code 0x80 (abort batchfile) + jp BDOSADDR +#endasm +} + +#endif + diff --git a/src/fsutil/utildos.h b/src/fsutil/utildos.h new file mode 100755 index 00000000..419ea055 --- /dev/null +++ b/src/fsutil/utildos.h @@ -0,0 +1,52 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + MSX machine dependent routines for UZIX utilities +**********************************************************/ + +#if 1 /* Nick */ +#include +#include +#include +#include +#else +#include "uzix.h" +#ifdef SEPH +#include "types.h" +#include "signal.h" +#include "errno.h" +#endif +#include "unix.h" +#include "extern.h" /* need for CALLROM/BDOS*/ +#endif + +#define PF printf +#define FF fflush(stdout) + +#ifdef _MSX_DOS +#define GETDEVNUM(p) (dev_t)atol(p); +extern void initenv __P((void)); +extern uchar xxbdos __P((uint, uchar)); +extern void xexit __P((int)); +#define DOSVER (*(char *)0xf313) /* MSX: 0=DOS1 */ +#else +#define GETDEVNUM(p) (dev_t)strtol(p,NULL,0); +#define xexit(s) (exit(s)) /* Nick */ +#endif + \ No newline at end of file diff --git a/src/fsutil/utils.c b/src/fsutil/utils.c new file mode 100755 index 00000000..018e4030 --- /dev/null +++ b/src/fsutil/utils.c @@ -0,0 +1,75 @@ +/* utils.c for uzi180 utils by Nick - subroutines based on utils.asz source */ + +#include "utils.h" + +#define TRUE 1 +#define FALSE 0 + +#if 0 +/* convert an integer to a string in any base (2-36) */ +char *itob (int n, char *s, int base) + { + register unsigned int u; + register char *p, *q; + register negative, c; + if ((n < 0) && (base == -10)) { + negative = TRUE; + u = -n; + } + else { + negative = FALSE; + u = n; + } + if (base == -10) /* Signals signed conversion */ + base = 10; + p = q = s; + do { /* Generate digits in reverse order */ + if ((*p = u % base + '0') > '9') + *p += ('A' - ('9' + 1)); + ++p; + u = u / base; + } while (u > 0); + if (negative) + *p++ = '-'; + *p = '\0'; /* Terminate the string */ + while (q < --p) { /* Reverse the digits */ + c = *q; + *q++ = *p; + *p = c; + } + return s; + } +#endif + +void bzero(char *ptr, int count) + { + while (count--) + { + *ptr++ = 0; + } + } + +void bfill(char *ptr, char val, int count) + { + while (count--) + *ptr++ = val; + } + +void bcopy(char *src, char *dest, int count) + { + while (count--) + { + *dest++ = *src++; + } + } + +int int_min(int a, int b) + { + return (b < a ? b : a); + } + +int int_max(int a, int b) + { + return (b > a ? b : a); + } + diff --git a/src/fsutil/utils.h b/src/fsutil/utils.h new file mode 100755 index 00000000..094a5abe --- /dev/null +++ b/src/fsutil/utils.h @@ -0,0 +1,14 @@ +/* utils.h for uzi180 utils by Nick - subroutines based on utils.asz source */ + +#ifndef __UTILS_H +#define __UTILS_H + +/* char *itob(int n, char *s, int base); */ +void bzero(char *ptr, int count); +void bfill(char *ptr, char val, int count); +void bcopy(char *src, char *dest, int count); +int int_min(int a, int b); +int int_max(int a, int b); + +#endif /* __UTILS_H */ + diff --git a/src/fsutil/uzidisk.dat b/src/fsutil/uzidisk.dat new file mode 100755 index 0000000000000000000000000000000000000000..0eed8eb19e5c9a18cb4f2cf5ff3f330a262abd59 GIT binary patch literal 1572352 zcmeI#@o!aE9RTqA`rZZ0qoYlA>0?UodrxTTWW3UKw2eFgvrMBIW)i1iQGs^YQQL%p z9RU_h{9Rp4_CM?wnOQ;>jgcUYFYrt-n)t(#xIp_PmpL6bMI=XxNcx9xrt+IXisnI95ZL6=#9Xc>KcXT3&>fg-vCDHCZd-f)w z?EdnzQ55B)Ot{`rLjRe${gczPhmx(Waa#{h9hse)=~@%@;6@iHfV^`cE^-WO42C?-%NErg|eCA1g+SJ({>K zCUbhRcp~4os!*?FJF@A%`Fxmf>{{`7J~V77riHQdmliktC@oB+{tsFuY2k{*P?^{cPXO(Ej4|%v3TvcQko%?%3>PNVM-}n5HzJFK&lyLpH53qwS`US~D!is_eyyi;s1GI5ZG%4^h?+ZHx<7 zgV6P5qRW|`(YMkU3YXI}Er8ZGn4X=RoC@3EYHJ&;%Y8117Ao~ddq*_uk7b)njprL1 zvgbGCT6as0N3-7v^c_G*RVf9z%e;Zv- z$8uLX25($T$5+*=UE#H>Yx@3rvi`5^sq5=PsmHl%SJo~3WZ?HZ2m1c--t||@VOND- zeIHzVuh!fYy%fxrnvHO+CZTy#bU0KS&6WGGRF<|=a+!d~gzRDUhEwrj8_ z9jm%WkRGHGTYtqfdxE%(tL-S5`I)4sTxNyj%emzwG3 za$5XsTG-e~Hz#SanD&$!)sA$0xc14~r)w8}9(twY1J(HA*u}z*?wR9P`UjIeX=T%;*K@Zs+4V?fC3eWS`=7Pe(G|6it|-%9r}mMzHk@@k z*FU)OhC<+D6j&Hu9UY8r<$spH)D-SZFKeHQh8&FQZ8iJIKg;iY@--4Y-`fB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZ;9h}D^u%3F;r{N1yPmrFe-n5^AwYlt0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly sK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyaEHLZ0lf(|;Q#;t literal 0 HcmV?d00001 diff --git a/src/fsutil/xfs.c b/src/fsutil/xfs.c new file mode 100755 index 00000000..b5bc88a6 --- /dev/null +++ b/src/fsutil/xfs.c @@ -0,0 +1,397 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + UZIX system calls wrappers, used by UZIX utilities +**********************************************************/ + +#define NEED__SCALL +#define NEED__DEVIO +#define NEED__DEVFLOP +#define NEED__FILESYS + +#if 1 /* Nick */ +#define MAIN /* creates the public data structures */ +#include "xfs.h" /* this will include unix.h and extern.h */ +#else +#include "uzix.h" +#ifdef _MSX_DOS +#include "..\include\stdio.h" +#include "..\include\stdlib.h" +#include "signal.h" +#include "fcntl.h" +#else +#include +#include +#endif +#include "xfs.h" +#endif + +char *stringerr[] = { + "0", + "1 Operation not permitted", + "2 No such file or directory", + "3 No such process", + "4 Interrupted system call", + "5 I/O error", + "6 No such device or address", + "7 Arg list too long", + "8 Exec format error", + "9 Bad file number", + "10 No child processes", + "11 Try again", + "12 Out of memory", + "13 Permission denied", + "14 Bad address", + "15 Block device required", + "16 Device or resource busy", + "17 File exists", + "18 Cross-device link", + "19 No such device", + "20 Not a directory", + "21 Is a directory", + "22 Invalid argument", + "23 File table overflow", + "24 Too many open files", + "25 Not a typewriter", + "26 Text file busy", + "27 File too large", + "28 No space left on device", + "29 Illegal seek", + "30 Read-only file system", + "31 Too many links", + "32 Broken pipe", + "33 Math argument out of domain of func", + "34 Math result not representable", + "35 Resource deadlock would occur", + "36 File name too long", + "37 No record locks available", + "38 Function not implemented", + "39 Directory not empty", + "40 Too many symbolic links encountered", + "41 It's a shell script" +}; + +#if 1 /* Nick */ +ptptr ptab_alloc(void); +void newproc(ptptr *p); +#endif + +void xfs_init(bootdev, waitfordisk) + dev_t bootdev; + uchar waitfordisk; +{ +#if 1 /* Nick */ + char *j; + ptptr initproc; + + inint = 0; + udata.u_euid = 0; + udata.u_insys = 1; + udata.u_mask = 022; + + newproc (udata.u_ptab = initproc = ptab_alloc()); + initproc->p_status = P_RUNNING; + initproc->p_fork_inf = udata.u_page; /* set for use in execve */ + + /* User's file table + */ + for (j=udata.u_files; j < (udata.u_files+UFTSIZE); ++j) + *j = -1; +#else + arch_init(); +#endif + bufinit(); + d_init(); + /* User's file table */ + bfill(udata.u_files, -1, sizeof(udata.u_files)); + /* Open the console tty device */ + if (d_open(TTYDEV) != 0) + panic("no tty"); + if ((root_dev = bootdev) != (NULLDEV)) { +#ifdef _MSX_DOS + if (waitfordisk) { + printf("Insert disk and press RETURN: "); + while (getchar() != '\n') + ; + } +#endif + /* Mount the root device */ + if (fmount(root_dev, NULL, 0)) + panic("no filesys"); + if ((root_ino = i_open(root_dev, ROOTINODE)) == 0) + panic("no root"); + udata.u_cwd = root_ino; + udata.u_root = root_ino; + i_ref(root_ino); + } + rdtime(&udata.u_time); +} + +void xfs_end(void) +{ + register int j; + + for (j = 0; j < UFTSIZE; ++j) { + if ((udata.u_files[j] & 0x80) == 0) + doclose(j); + } + UZIXsync(); /* Not necessary, but a good idea. */ +} + +int UZIXopen(name, flag) + char *name; + int flag; +{ + udata.u_argn0 = (uint)name; + udata.u_argn1 = (uint)flag; + udata.u_argn2 = (uint)0; + return sys_open(); +} + +int UZIXclose(uindex) + int uindex; +{ + udata.u_argn0 = uindex; + return sys_close(); +} + +int UZIXcreat(name, mode) + char *name; + mode_t mode; +{ + udata.u_argn0 = (uint)name; + udata.u_argn1 = O_CREAT|O_WRONLY|O_TRUNC; + udata.u_argn2 = (uint)mode; + return sys_open(); +} + +int UZIXlink(name1, name2) + char *name1; + char *name2; +{ + udata.u_argn0 = (uint)name1; + udata.u_argn1 = (uint)name2; + return sys_link(); +} + +int UZIXsymlink(name1, name2) + char *name1; + char *name2; +{ + udata.u_argn0 = (uint)name1; + udata.u_argn1 = (uint)name2; + return sys_symlink(); +} + +int UZIXunlink(path) + char *path; +{ + udata.u_argn0 = (uint)path; + return sys_unlink(); +} + +int UZIXread(d, buf, nbytes) + int d; + char *buf; + uint nbytes; +{ + udata.u_argn0 = (uint)d; + udata.u_argn1 = (uint)buf; + udata.u_argn2 = (uint)nbytes; + udata.u_callno = 23; + return sys_readwrite(); +} + +int UZIXwrite(d, buf, nbytes) + int d; + char *buf; + uint nbytes; +{ + udata.u_argn0 = (uint)d; + udata.u_argn1 = (uint)buf; + udata.u_argn2 = (uint)nbytes; + udata.u_callno = 36; + return sys_readwrite(); +} + +off_t UZIXlseek(file, offset, flag) + int file; + off_t offset; + int flag; +{ + udata.u_argn0 = (uint)file; + udata.u_argn1 = (uint)offset; + udata.u_argn2 = (uint)(offset >> 16); + udata.u_argn3 = (uint)flag; + return sys_lseek(); +} + +int UZIXchdir(dir) + char *dir; +{ + udata.u_argn0 = (uint)dir; + return sys_chdir(); +} + +int UZIXmknod(name, mode, dev) + char *name; + mode_t mode; + int dev; +{ + udata.u_argn0 = (uint)name; + udata.u_argn1 = (uint)mode; + udata.u_argn2 = (uint)dev; + return sys_mknod(); +} + +void UZIXsync() +{ + sys_sync(); +} + +int UZIXaccess(path, mode) + char *path; + int mode; +{ + udata.u_argn0 = (uint)path; + udata.u_argn1 = (uint)mode; + return sys_access(); +} + +int UZIXchmod(path, mode) + char *path; + mode_t mode; +{ + udata.u_argn0 = (uint)path; + udata.u_argn1 = (uint)mode; + return sys_chmod(); +} + +int UZIXchown(path, owner, group) + char *path; + int owner; + int group; +{ + udata.u_argn0 = (uint)path; + udata.u_argn1 = (uint)owner; + udata.u_argn2 = (uint)group; + return sys_chown(); +} + +int UZIXstat(path, buf) + char *path; + void *buf; +{ + udata.u_argn0 = (uint)path; + udata.u_argn1 = (uint)buf; + udata.u_callno = 27; + return sys_statfstat(); +} + +int UZIXfstat(fd, buf) + int fd; + void *buf; +{ + udata.u_argn0 = (uint)fd; + udata.u_argn1 = (uint)buf; + udata.u_callno = 13; + return sys_statfstat(); +} + +#if 1 /* Nick free bitmap */ +int UZIXfalign(fd, parm) + int fd; + int parm; +{ + udata.u_argn0 = (uint)fd; + udata.u_argn1 = (uint)parm; + return sys_falign(); +} +#endif + +int UZIXdup(oldd) + int oldd; +{ + udata.u_argn0 = (uint)oldd; + return sys_dup(); +} + +int UZIXdup2(oldd, newd) + int oldd; + int newd; +{ + udata.u_argn0 = (uint)oldd; + udata.u_argn1 = (uint)newd; + return sys_dup2(); +} + +int UZIXumask(mask) + int mask; +{ + udata.u_argn0 = (uint)SET_UMASK; + udata.u_argn1 = (uint)mask; + return sys_getset(); +} + +int UZIXgetfsys(dev, buf) + dev_t dev; + void *buf; +{ + udata.u_argn0 = (uint)dev; + udata.u_argn1 = (uint)buf; + return sys_getfsys(); +} + +int UZIXioctl(fd, request, data) + int fd; + int request; + void *data; +{ + udata.u_argn0 = (uint)fd; + udata.u_argn1 = (uint)request; + udata.u_argn2 = (uint)data; + return sys_ioctl(); +} + +int UZIXmount(spec, dir, rwflag) + char *spec; + char *dir; + int rwflag; +{ + udata.u_argn0 = (uint)spec; + udata.u_argn1 = (uint)dir; + udata.u_argn2 = (uint)rwflag; + udata.u_callno = 19; + return sys_mountumount(); +} + +int UZIXumount(spec) + char *spec; +{ + udata.u_argn0 = (uint)spec; + udata.u_callno = 32; + return sys_mountumount(); +} + +int UZIXtime(tvec) + void *tvec; +{ + udata.u_argn0 = (uint)tvec; + return sys_time(); +} diff --git a/src/fsutil/xfs.h b/src/fsutil/xfs.h new file mode 100755 index 00000000..ccf25be8 --- /dev/null +++ b/src/fsutil/xfs.h @@ -0,0 +1,71 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + UZIX system calls wrappers, used by UZIX utilities +**********************************************************/ + +#ifndef _XFS_H +#define _XFS_H + +#if 1 /* Nick */ +#include +#include +#include +#include +#else +#include "uzix.h" +#include "unix.h" +#include "extern.h" +#endif + +extern char *stringerr[]; + +extern void xfs_init(dev_t bootdev, uchar waitfordisk); +extern void xfs_end(void); +extern int UZIXopen(char *name, int flag/*, ...*/); +extern int UZIXclose(int uindex); +extern int UZIXcreat(char *name, mode_t mode); +extern int UZIXlink(char *name1, char *name2); +extern int UZIXsymlink(char *name1, char *name2); +extern int UZIXunlink(char *path); +extern int UZIXread(int d, char *buf, uint nbytes); +extern int UZIXwrite(int d, char *buf, uint nbytes); +extern int UZIXseek(int file, uint offset, int flag); +extern int UZIXchdir(char *dir); +extern int UZIXmknod(char *name, mode_t mode, int dev); +extern void UZIXsync(void); +extern int UZIXaccess(char *path, int mode); +extern int UZIXchmod(char *path, mode_t mode); +extern int UZIXchown(char *path, int owner, int group); +extern int UZIXstat(char *path, void *buf); +extern int UZIXfstat(int fd, void *buf); +#if 1 /* Nick free bitmap */ +extern int UZIXfalign(int fd, int parm); +#endif +extern int UZIXdup(int oldd); +extern int UZIXdup2(int oldd, int newd); +extern int UZIXumask(int mask); +extern int UZIXioctl(int fd, int request, void *data); +extern int UZIXmount(char *spec, char *dir, int rwflag); +extern int UZIXumount(char *spec); +extern int UZIXtime(void *tvec); + +extern int UZIXgetfsys(dev_t dev, void *buf); +#endif + \ No newline at end of file diff --git a/src/gboot/checksum.dat b/src/gboot/checksum.dat new file mode 100755 index 00000000..172cee84 --- /dev/null +++ b/src/gboot/checksum.dat @@ -0,0 +1,2 @@ +C A:KERNEL.BIN +C A:BOOT.BIN diff --git a/src/gboot/clears.inc b/src/gboot/clears.inc new file mode 100755 index 00000000..ff7f0386 --- /dev/null +++ b/src/gboot/clears.inc @@ -0,0 +1,50 @@ +; clears.s01 +; Hard and fast system initialisation for built in Z180 devices +; Now modified for use as an include file when compiling the boot routines + +; ----------------------------------------------------------------------------- + +;$io64180.s01 + +; .area _CODE + rseg RCODE + +; ----------------------------------------------------------------------------- + + public clears + +clears:: + ; initialise z180 serial ports + ld a,01110100b ; enables, rts off, d8 pn s1, tend0 + out0 (CNTLA0),a ; rts0 = 1 keeps us alive, new v5 + out0 (CNTLA1),a ; cka1d = 1 enables tend0 + .if 1 + ld a,22h ; 22h = 9600, 20h = 38400 + out0 (CNTLB0),a ; ps = 1 enables /30 mode + out0 (CNTLB1),a ; ps = 1 enables /30 mode + sub a + out0 (STAT0),a + out0 (STAT1),a ; cts1e = 0 enables rxs + .else + sub a + out0 (STAT0),a + out0 (STAT1),a ; cts1e = 0 enables rxs + out0 (CNTLB0),a ; 115200, ps = 0 disables /30 mode + out0 (CNTLB1),a ; 115200, ps = 0 disables /30 mode + .endif + in0 (RDR0) ; clear asci0 rx & irq + in0 (RDR1) ; clear asci1 rx & irq + + ; initialise dma controller + out0 (BCR0H),a + out0 (BCR1H),a + out0 (MAR1H),a + out0 (MAR1B),a + out0 (IAR1L),a + out0 (IAR1H),a + + ret + +; ----------------------------------------------------------------------------- + +; END diff --git a/src/gboot/copyr.inc b/src/gboot/copyr.inc new file mode 100755 index 00000000..a89d7c77 --- /dev/null +++ b/src/gboot/copyr.inc @@ -0,0 +1,312 @@ +; copyr.s01 +; Reentrant DMA copy routine for Hytech CMX, doesn't disable ints for too long +; Now modified for use as an include file when compiling the boot routines + +; ----------------------------------------------------------------------------- + +; $io64180.s01 + +BITE equ 32 +BITELOG equ 5 + +PBITE equ 16 +PBITELOG equ 4 + +; extern abyte, ahexw, ahexn, acrlf + +; copy routine +; ------------ + +; copy bc bytes from d:iy --> e:hl + +; 10 bits @ 38400 == 260 usec +; 1 dma cycle (read+write) == 6 t-states == .977 usec +; so 266 dma cycles burst per character 6*266 = 1596 +; we will use a max of 256 characters burst mode 6*256 = 1536 + + rseg RCODE + +; public _copyr +; +;_copyr: push iy +; +; push de +; pop iy +; ld d,c ; d:iy = entry c:de -> source data +; +; ld hl,9 +; add hl,sp +; ld b,(hl) +; dec hl +; ld c,(hl) ; bc = entry (sp+6) = byte count +; +; dec hl +; dec hl +; ld e,(hl) +; dec hl +; ld a,(hl) +; dec hl +; ld l,(hl) +; ld h,a ; e:hl = entry (sp+2) -> destination +; call copyr +; +; pop iy +; ret +; +; public copyb +; +;copyb: ld bc,1 + + public copyr + +copyr: + .if 0 ; diagnostic + push hl + + ld a,d + call ahexn + ld a,':' + call abyte + + push iy + pop hl + call ahexw + + ld a,' ' + call abyte + + ld a,e + call ahexn + ld a,':' + call abyte + + pop hl + push hl + call ahexw + + ld a,' ' + call abyte + + ld l,c + ld h,b + call ahexw + + call acrlf + + pop hl + .endif + ld a,e + cp 4 + .if 1 + jp nc,copyrp + .else + jr nc,copyrp + .endif + + .if 1 + LD A,C + AND BITE-1 ;00011111B +; JR Z,CPYL0 + PUSH BC + LD C,A + LD B,0 + .if 1 +;;; di +; out0 (BCR0L),c + call cpyst0 + inc c + dec c + jr z,cpyl0 + in0 a,(DSTAT) + xor 01010000b + out0 (DSTAT),a + add iy,bc + call c,inc_d + add hl,bc + call c,inc_e +cpyl0: + .else + CALL CPYBC + .endif + .if 0 +; POP BC +; .if 0 +; LD A,C +; AND .binnot.(BITE-1) ;11100000B +; LD C,A +; .endif +;CPYL0: +; POP AF ; HIGH ORDER CNT +; PUSH HL +; LD L,C +; LD H,B + ex (sp),hl + sub a ; high order count + LD B,8-BITELOG ;3 +CPYL1: ADD HL,HL + ADC A,A + DJNZ CPYL1 ; A:H = A:HL/BITE ;32 + LD C,H + LD B,A + POP HL + .else + pop bc + ld a,BITELOG ;5 +cpyl30: srl b + rr c + dec a + jr nz,cpyl30 ; bc = bc/BITE ;32 + .endif + JR CPYL3 +CPYL2: PUSH BC + LD BC,BITE ;32 + .if 1 +;;; ei +; out0 (BCR0L+1),b + out0 (BCR0L),c +;;; di +; in0 (BCR0L+1) ;f,(BCR0L+1) +; call z,cpyst0 +;;; in0 (BCR0L) +;;; call z,cpyst0 + in0 a,(DSTAT) + xor 01010000b + out0 (DSTAT),a + add iy,bc + call c,inc_d + add hl,bc + call c,inc_e + .else + CALL CPYBCI + .endif + POP BC + DEC BC +CPYL3: LD A,B + OR C + JR NZ,CPYL2 + .else + push bc + ld b,0 +;;; di +; out0 (BCR0L),c + call cpyst0 + inc c + dec c + jr z,cpyl0 + in0 a,(DSTAT) + xor 01010000b + out0 (DSTAT),a + add iy,bc + call c,inc_d + add hl,bc + call c,inc_e +cpyl0: pop bc + inc b + jr cpyl1 +cpyl2: push bc + ld bc,100h +;;; ei + out0 (BCR0L+1),b +;;; di + in0 (BCR0L+1) ;f,(BCR0L+1) + call z,cpyst0 + in0 a,(DSTAT) + xor 01010000b + out0 (DSTAT),a + add iy,bc + call c,inc_d + add hl,bc + call c,inc_e + pop bc +cpyl1: djnz cpyl2 + .endif +;;; ei + ret + +cpyst0: + out0 (BCR0L),c + out0 (BCR0L+1),b + jr cpyst2 +cpyst1: ld a,1 + out0 (BCR0L),a +cpyst2: push hl + push iy + out0 (DAR0L),l + out0 (DAR0L+1),h + out0 (DAR0L+2),e + pop hl + out0 (SAR0L),l + out0 (SAR0L+1),h + out0 (SAR0L+2),d + pop hl + ld a,2 ; memory+ --> memory+, burst mode + out0 (DMODE),a + ret + +inc_d: inc d + ret +inc_e: inc e + ret + +copyrp: push bc + xor a +;;; di + out0 (BCR0L),a + out0 (BCR0L+1),a + .if 0 + push hl + ld l,c + ld h,b + sub a ; high order count + LD B,8-PBITELOG +CPYL1X: ADD HL,HL + ADC A,A + DJNZ CPYL1X ; A:H = A:HL/PBITE ;32 + LD C,H + LD B,A + pop hl + .else + ld a,PBITELOG ;5 +cpyl31: srl b + rr c + dec a + jr nz,cpyl31 ; bc = bc/PBITE ;32 + .endif + ld a,b + or c + jr z,cpyc0 +cpyl4: push bc ; 1464 t-states for this loop + ld bc,PBITE + call cpybc0 + pop bc + dec bc +;;; di + ld a,b + or c + jr nz,cpyl4 +cpyc0: pop bc + ld b,a ; 0 + ld a,c + and PBITE-1 ;00011111b + jr z,cpyl5 + ld c,a +cpybc0: in0 (BCR0L) ;f,(BCR0L) + call z,cpyst1 + add iy,bc ; 1396 t-states for this subroutine + call c,inc_d ; 32 bytes, no boundary + add hl,bc ; no interrupt, no dma1 cycle steal + call c,inc_e + ld b,c + ld c,1 + in0 a,(DSTAT) + xor 01010000b +cpybc1: out0 (DSTAT),a + out0 (BCR0L),c + djnz cpybc1 +cpyl5: +;;; ei + ret + +; ----------------------------------------------------------------------------- + +; END diff --git a/src/gboot/diag.inc b/src/gboot/diag.inc new file mode 100755 index 00000000..747720ee --- /dev/null +++ b/src/gboot/diag.inc @@ -0,0 +1,132 @@ +; diag.s01 +; Polled mode serial output for built in Z180 port SERIAL 0 (Hytech CMX) +; Now modified for use as an include file when compiling the boot routines + +; ----------------------------------------------------------------------------- + +;$io64180.s01 + +; .area _CODE + rseg RCODE + +; ----------------------------------------------------------------------------- + +; public _abyte +; +;_abyte:: +; .if 0 ; SDCC +; ld hl,2 +; add hl,sp +; ld a,(hl) +; .else ; IAR +; ld a,e +; .endif + + public abyte + +abyte:: + .if 0 ; 0=enable abytes, 1=disable abytes (doesn't affect the code size) + ret + .else + push af + .endif + + .if 0 ; checking to see when memory corruption occurs + extern _osBank + ld a,(_osBank) + cp 0 + jr z,ok + pop af + ld a,'_' + push af +ok: + .endif + +L1$: in0 a,(STAT1) ;(STAT0) + and 10b + jr z,L1$ + + pop af + out0 (TDR1),a ;(TDR0),a + + .if 0 + di + .endif + .if 0 + ei + .endif + ret + +; public _acrlf +; +;_acrlf:: + + public acrlf + +acrlf:: + ld a,0dh + call abyte + ld a,0ah + jr abyte + +; public _ahexw +; +;_ahexw:: +; .if 0 ; SDCC +; ld hl,2 +; add hl,sp +; ld e,(hl) +; inc hl +; ld d,(hl) +; .endif +; ex de,hl + + public ahexw + +ahexw:: + ld a,h + call ahexb + ld a,l + + public ahexb + +ahexb:: + push af + rrca + rrca + rrca + rrca + call ahexn + pop af + + public ahexn + +ahexn:: + and 0fh + add a,90h + daa + adc a,40h + daa + jr abyte + + public amess + +amess:: + ex (sp),hl + push af + +L01$: ld a,(hl) + inc hl + or a + jr z,L02$ + + call abyte + jr L01$ + +L02$: pop af + ex (sp),hl + ret + +; ----------------------------------------------------------------------------- + +; END diff --git a/src/gboot/gboot.asm b/src/gboot/gboot.asm new file mode 100755 index 00000000..a49b6d8d --- /dev/null +++ b/src/gboot/gboot.asm @@ -0,0 +1,1175 @@ +; gboot.asm +; Generic Hytech boot loader program to occupy 4 sectors at start of each disk + +$ io64180.inc + +LDFILE equ 0f037h ; BOOTLDR.BIN entry point + +SUPERBLOCK equ 4 ; starting position of filesystem +SMOUNTED equ 12742 ; random number to specify mounted fs +ROOTINODE equ 1 ; inode number of / for all mounted fs + +BUFSIZE equ 200h ; how many bytes per disk block +BUFSIZELOG equ 9 ; shift count representing the above + +SIZEOF_DINODE_T equ 64 ; how many bytes per disk inode +DINODESPERBLOCK equ 8 ; how many disk inodes per disk block +DINODESPERBLOCKLOG equ 3 ; shift count representing the above + +DIRECTBLOCKS equ 18 +INDIRECTBLOCKS equ 1 ; MUST BE 1! +DINDIRECTBLOCKS equ 1 ; MUST BE 1! + +SIZEOF_DIRECT_T equ 16 ; how many bytes per directory entry +DIRNAMELEN equ 14 ; how many bytes of these are dir name + +REGION_LOG equ 14 +REGION_BYTES equ (1<> 14) & 1 + defb ((800h-(final-start)) >> 14) & 2 + defb ((0c00h-(final-start)) >> 14) & 3 + defb 0,0,0,0,0,0,0,0,0,0,0,0 + +; ----------------------------------------------------------------------------- + +entry: + call gmess + defb 'loading /boot/kernel.bin',0dh,0ah,0 + + .if 1 ; new kernel format + call virtual_init ; modifies CBR (can't call EPROM now) + .endif + + ld de,SUPERBLOCK + ld hl,block + call block_read + + ld hl,(block) + ld de,SMOUNTED + or a + sbc hl,de + jp nz,black_magic + + ld hl,(block+2) + ld (reserv),hl + ld hl,(block+4) + ld (isize),hl + ld hl,(block+6) + ld (fsize),hl + + ld de,ROOTINODE + ld hl,name_boot + call dir_search ; returns de = the found inode + jr nz,bad_file + + ld hl,name_kernel_bin + call dir_search ; returns de = the found inode + jr nz,bad_file + + .if 1 ; new kernel format + call file_setup ; read inode and prepare to walk file + + ld hl,exe_header_buf + ld bc,exe_header_size + call file_read ; read first block, copy header to buf + jr c,bad_length + + call check_e_magic ; ensure e_magic = E_MAGIC + call check_e_format ; ensure e_format = E_FORMAT_KERNEL + + ld a,0-8 ; so that logical 8000 = phys 0:0000 + out0 (CBR),a + + call get_ca0_size ; returns bc = size, de = start of copy + ld hl,8000h ; destination = start of CA0 region + call file_read ; read CA0 data to common data segment + + ld a,4-8 ; so that logical 8000 = phys 0:4000 + out0 (CBR),a + + call get_ca1_size ; returns bc = size, de = start of copy + ex de,hl ; destination specified by file header + call file_read ; read CA1 data to kernel data segment + + call get_udata_size_m1 ; returns bc = size-1, de = start+1 + call nc,clear_bc_p1_at_de_m1 ; if bc => 0, clear bc+1 bytes at de-1 + .endif + + call file_scan ; scan file and construct block list + + .if 1 ; new kernel format + call say_starting ; tell the user we have liftoff + .else + call virtual_init ; modifies CBR (can't call EPROM now) + .endif + + ld bc,8080h ; initial spot in virt memory table + .if 1 ; new kernel format + ld hl,region_list ; -> block no. of 1st found region + .else + ld hl,region_list+2 ; -> block no. of 2nd found region + .endif + jr translate_loope + +translate_loop: + add hl,de ; restore hl value from comparison + + call block_to_bbr ; calculates a from word at hl (bumped) + ld (bc),a ; a = required bbr value to access page + inc bc + +translate_loope: + ld de,(region_ptr) ; indicates end of region list + or a + sbc hl,de ; see if we've gone past the end + jr c,translate_loop + + .if 0 ; new kernel format + ld hl,region_list ; there is at least one entry + call block_to_bbr ; a = required bbr value for init code + .endif + +kazumi: + .if 0 + ; please preserve a for entering kernel at label runsys! + .endif + ld sp,parameters-parameters_end ; stack just under copied params + + ld hl,parameters ; pre-initialised parameter block + ld de,parameters-parameters_end ; to fit neatly at top of memory + ld bc,parameters_end-parameters ; size in bytes to copy + ldir ; copy parameter block for kernel init + ; careful! b will be used again below!! + + .if 1 ; so as not to corrupt CBR when jumping to the loaded program + ld hl,runsys ; start of small stub program below + .if 1 ; new kernel format + ld de,(e_stack) ; load into base of stack region + .else + ld de,8100h ; -> just after virtual memory table + .endif + push de + ld c,runsys_end-runsys ; size of small stub program (b=0) + ldir ; copy stub program + .if 1 ; new kernel format + ld hl,(e_entry) ; information for the runsys stub + ld de,(e_break) ; information for the client program + .endif + ret ; enter stub program (jp 8100h) + .else + ld e,30h-8 + out0 (CBR),e ; window onto runsys (CBAR = 80h) + jp runsys+8000h ; run the remaining startup from window + .endif + +bad_file: + call gmess + defb 'file not found',0dh,0ah,0 + jr reboot_plain + + .if 1 ; new kernel format +bad_length: + call gmess + defb 'file too short',0dh,0ah,0 + jr reboot_plain + .endif + +runsys: + .if 1 ; new kernel format + ld a,84h + out0 (CBAR),a ; CA0 = 16k, bank area = 16k, CA1 = 32k + jp (hl) ; jump to entry address from exe header + .else + ld e,84h + out0 (CBAR),e ; CA0 = 16k, bank area = 16k, CA1 = 32k + + out0 (BBR),a ; bank area = logical 4000 = abs c:0000 + jp 4000h ; execute file from the 1st loaded page + .endif + .if 1 ; so as not to corrupt CBR when jumping to the loaded program +runsys_end: + .endif + +; ----------------------------------------------------------------------------- +; had some kind of fatal error, the entry points are to save code space + + .if 1 ; new kernel format +check_e_magic: + ld hl,(e_magic) + ld de,E_MAGIC_FIXME + or a + sbc hl,de + ret z + + call gmess + defb 'bad e_magic: ',0 + jr reboot_magic + +check_e_format: + ld hl,(e_format) + ld de,E_FORMAT_KERNEL + or a + sbc hl,de + ret z + + call gmess + defb 'bad e_format: ',0 + ; fall into reboot_magic + + .endif + +black_magic: + call gmess + defb 'bad magic: ',0 + +reboot_magic: + add hl,de + +reboot_ahexw: + call ahexw + +reboot_acrlf: + call acrlf + +reboot_plain: + ; try not to surprise the user unnecessarily + call gmess + defb 'doing a clean boot',0dh,0ah,0 + + ; before rebooting, prepare to clobber CP/M drive A: directory + ld hl,block + ld de,block+1 + ld bc,BUFSIZE-1 + ld (hl),0aah ; clobbering pattern + ldir ; initialise temporary buffer + + ; perform the clobbering (this ensures a clean boot from EPROM) + .if 1 + ld de,0 + ld b,4 +clobber_loop: + push bc + push de + + ld hl,block + call block_write + + pop de + pop bc + inc de + djnz clobber_loop + .else + ld de,304h + ld l,c + ld h,b ; ld hl,0 ; e:hl -> destination 4:0000 + + ld b,4 ; clobber until just before 4:0800 +clobber_loop: + push bc + + ld iy,block ; copy from d:iy -> destination + ld bc,BUFSIZE ; bytes to copy + call copyr ; copy them, one byte at a time + + pop bc + djnz clobber_loop + .endif + + ; ready to reboot, by instructing the WPO chip on motherboard + ld a,0aah + out0 (TRDR),A ; command byte to reboot the system + ld a,13h + out0 (CNTR),A ; TE=1, divisor = 3, start transmission + + ; wait for the reboot to occur, or else we're rather stuck + jr $ + +; ----------------------------------------------------------------------------- + +gmess: call amess + defb 'gboot: ',0 + jp amess + +rsel1: + .if 1 ; temporary only + ld de,2 ; save eprom serial no to 2:fc81 + call copy_serial_no + .endif + ld a,81h + out0 (TRDR),A ; command byte to set RSEL=1 + ld a,13h + out0 (CNTR),A ; TE=1, divisor = 3, start transmission + + sub a + dec a + jr nz,$-1 + dec a + jr nz,$-1 + dec a + jr nz,$-1 + dec a + jr nz,$-1 ; delay for command to be processed + .if 1 ; temporary only + ld de,200h ; restore eprom serial no from 2:fc81 +copy_serial_no: + ld hl,0fc81h + push hl + pop iy + ld bc,5 + jp copyr + .else + ret + .endif + + .if 1 ; new kernel format +say_starting: + call gmess + defb 'starting operating system',0dh,0ah,0 + ret +.endif + +virtual_init: + .if 0 ; new kernel format + call gmess + defb 'starting operating system',0dh,0ah,0 + .endif + + call rsel1 + + ld a,80h + out0 (CBAR),a ; CA0 = 0k, bank area = 32k, CA1 = 32k + + ld a,4-8 ;0 also works, see bstartup.s01 at label init + out0 (CBR),a ; window onto 0:8000, virt memory table + + .if 1 ; new kernel format + ld de,08001h ; address of virtual memory table+1 + ld bc,0ffh ; size of virtual memory table-1 + ; fall into clear_bc_p1_at_de_m1 + +clear_bc_p1_at_de_m1: + ld l,e + ld h,d + dec hl + ld (hl),0 + + ld a,c + or b + ret z + + ldir + ret + +de_min_hl_de: + ; enter with values in hl and de, returns de = min(hl, de) + or a + sbc hl,de + ret nc ; de is lesser + add hl,de ; hl was lesser, restore its value + ex de,hl ; and return the original hl in de + ret + +get_ca0_size: + ld hl,(e_hsize) ; variable size of header + ld de,exe_header_size ; subtract fixed size of header + jr calculate_size + +get_ca1_size: + ld hl,(e_udata) ; ending logical addr in CA1 region + ld de,(e_idata) ; starting logical addr in CA1 region + jr calculate_size + +get_udata_size_m1: + ld hl,(e_break) ; ending logical addr to be cleared + ld de,(e_udata) ; starting logical addr to be cleared + inc de ; special algorithm for correct cf + ; fall into calculate_size + +calculate_size: ; enter with hl = start addr, de = end + or a + sbc hl,de ; find the difference + ld c,l + ld b,h ; bc = bytes to load for region + ret + .else + ld hl,08000h + ld de,08001h + ld bc,0ffh + ld (hl),l ; 0 + ldir ; zero out the virtual memory table + ret + .endif + +; ----------------------------------------------------------------------------- + +dir_search: + ld (dir_name),hl + + .if 1 ; new kernel format + call file_setup ; read inode and prepare to walk file + +dir_search_loop: + ld bc,SIZEOF_DIRECT_T + ld hl,directory_buf + call file_read ; returns hl = preserved, cf set up + ret c ; also implies nz ; directory search failed (not found) + + inc hl + + ld de,(dir_name) + ld b,DIRNAMELEN + +dir_search_compare_loop: + inc hl + + ld a,(de) + cp (hl) + jr nz,dir_search_loop ; didn't match, go and read another + or a + jr z,dir_search_compare_good ; matched, and sentinel was reached + + inc de + djnz dir_search_compare_loop + + ; matched, and directory filename was of maximal length + ld a,(de) + or a + ; if user's filename is exactly maximum, return zf=1 (found) + ; if user's filename is longer than maximum, return zf=0 (not found) + +dir_search_compare_good: + ld de,(directory_buf) ; de = return value, inode number + ret ; with zf=1 from the comparisons above + .else + ld hl,inode + call inode_read ; read inode of the dir to be searched + + call bmap_setup ; prepare counters to walk the file + jr dir_search_loope + +dir_search_loop: + push hl ; h = count of entries in current block + call bmap_block ; get de = block no. of current block + ; and increment the block position + ld a,e + or d + jr z,bad_dir_block ; hole in directory + + ld hl,block + push hl + call block_read + pop hl + pop bc ; b = count of entries in current block + +dir_search_entry_loop: + push hl + inc hl + + ld de,(dir_name) + ld c,DIRNAMELEN + +dir_search_compare_loop: + inc hl + + ld a,(de) + cp (hl) + jr nz,dir_search_compare_bad + or a + jr z,dir_search_compare_good + + inc de + dec c + jr nz,dir_search_compare_loop + +dir_search_compare_good: + pop hl + ld e,(hl) + inc hl + ld d,(hl) + ret + +dir_search_compare_bad: + pop hl + ld de,SIZEOF_DIRECT_T + add hl,de + djnz dir_search_entry_loop + +dir_search_loope: + call bmap_remain ; get hl = valid bytes in current block + ; and decrement the file size remaining + add hl,hl + add hl,hl + add hl,hl + add hl,hl ; assumes SIZEOF_DIRECT_T = 16!! + + ld a,h ; a = valid bytes / SIZEOF_DIRECT_T + or a + jr nz,dir_search_loop + + ret + +bad_dir_block: + call gmess + defb 'hole in directory',0dh,0ah,0 + jp reboot_plain + .endif + +; ----------------------------------------------------------------------------- + +file_scan: + ld hl,region_list + ld (region_ptr),hl + + .if 0 ; new kernel format + ld hl,inode + call inode_read ; read inode of the target file + .endif + + call bmap_setup ; prepare counters to walk the file + call bmap_remain ; get hl = valid bytes in first block + ; and decrement the file size remaining + ld a,l + or h ; any bytes in file? + jr z,bad_file_size ; no, abort proceedings + +file_scan_loop: + call bmap_block ; get de = block no. of current block + ; and increment the block position + ld a,e + or d + jr z,bad_file_block +; ld l,e +; ld h,d +; call ahexw + + ld a,e + and PAGE_BLOCKS-1 ; check it starts on a page boundary + jr nz,bad_alignment + + ld hl,(region_ptr) + ld (hl),e + inc hl + ld (hl),d ; stash away the starting block no. + inc hl + ld (region_ptr),hl ; for the current region (bumped) + + ld b,REGION_BLOCKS-1 + +file_region_loop: + push bc + push de + + call bmap_remain ; get hl = valid bytes in current block + ; and decrement the file size remaining + ld a,l + or h + jr z,file_region_final + + call bmap_block ; get de = block no. of current block + ; and increment the block position + ld a,e + or d + jr z,bad_file_block +; ld a,' ' +; call abyte +; ld l,e +; ld h,d +; call ahexw + + ex de,hl ; hl = the actual block no. from file + pop de + inc de ; de = expected, contiguous block no. + + or a + sbc hl,de + jr nz,bad_alignment + + pop bc + djnz file_region_loop +; call acrlf + + call bmap_remain ; get hl = valid bytes in current block + ; and decrement the file size remaining + ld a,l + or h ; anything left to read? + jr nz,file_scan_loop ; yes (scan is limited by file size) + ret ; last region is = REGION_BLOCKS blocks + +file_region_final: +; call acrlf + pop hl ; last region is < REGION_BLOCKS blocks + pop hl ; clean up saved variables, and done + ret + +bad_file_size: + call gmess + defb 'null file',0dh,0ah,0 + jp reboot_plain + +bad_file_block: + call gmess + defb 'hole in file',0dh,0ah,0 + jp reboot_plain + +bad_alignment: + call gmess + defb 'not aligned',0dh,0ah,0 + jp reboot_plain + +; ----------------------------------------------------------------------------- + + .if 1 ; new kernel format +file_read: + ; enter with hl -> user buffer, bc = bytes to read (must be nonzero!!) + + push hl ; this will be preserved for caller + push bc ; this will be used to set cf on return + + ld (read_user),bc + ld (read_user_ptr),hl + + ld hl,0 + ld (read_done),hl + + ld hl,(read_remain) + ld a,l + or h ; got any leftover data in buffer? + jr nz,file_read_entry ; yes, use it first + +file_read_loop: + ; read a new block into the buffer, recording no. of valid bytes read + call bmap_remain ; get hl = valid bytes in current block + ; and decrement the file size remaining + ld a,l + or h + jr z,file_read_done ; reached end of file + + ld (read_remain),hl + + call bmap_block ; get de = block no. of current block + ; and increment the block position + ld a,e + or d + jr z,bad_file_block ; hole in file + + ld hl,block + ld (read_remain_ptr),hl + call block_read + +file_read_entry: + ; satisfy as much as possible of user's request from current buffer + ld hl,(read_remain) ; bytes available + ld de,(read_user) ; bytes wanted + call de_min_hl_de ; de = amount to be processed this time + + ld hl,(read_remain) + or a + sbc hl,de + ld (read_remain),hl ; reduce bytes available by amount + + ld hl,(read_user) + or a + sbc hl,de + ld (read_user),hl ; reduce bytes wanted by amount + + ld hl,(read_done) + add hl,de + ld (read_done),hl ; increase bytes copied by amount + + ld c,e + ld b,d + ld de,(read_user_ptr) + ld hl,(read_remain_ptr) + ldir + ld (read_remain_ptr),hl + ld (read_user_ptr),de + + ; see if the user's entire request has now been processed + ld hl,(read_user) + ld a,l + or h + jr nz,file_read_loop ; no, get another block + +file_read_done: + ld hl,(read_done) ; indicates how much was really read + ld c,l + ld b,h ; bc = return value, how much was read + + pop de ; de = size of user's original request + or a + sbc hl,de ; set cf=1 if less than amount wanted + + pop hl ; hl preserved for convenience of user + ret + .endif + +; ----------------------------------------------------------------------------- + + .if 1 ; new kernel format +file_setup: + ; enter with de = inode number for file to be read + + ld hl,inode + call inode_read ; read inode of the dir to be searched + + ld hl,0 + ld (read_remain),hl ; forces a new data block to be loaded + ; fall into bmap_setup + .endif + +bmap_setup: + ld hl,(inode+8) + ld (size_remain),hl + ld hl,(inode+10) + ld (size_remain+2),hl + + ld hl,inode+24 + ld (direct_ptr),hl + ld hl,indirect_block+BUFSIZE + ld (indirect_ptr),hl + ld hl,dindirect_block+BUFSIZE + ld (dindirect_ptr),hl + ret + +bmap_remain: + ld hl,(size_remain) + ld de,(size_remain+2) + + ld bc,BUFSIZE + or a + sbc hl,bc + ex de,hl + ld b,0 ; ld bc,0 + sbc hl,bc + ex de,hl + jr c,bmap_remain_final + + ld (size_remain),hl + ld (size_remain+2),de + + ld hl,BUFSIZE + ret ; return a complete block of size hl + +bmap_remain_final: + ld hl,(size_remain) + ld (size_remain),bc ; 0 + ;ld (size_remain+2),bc ; 0 + ret ; return a partial block of size hl + +bmap_block: + ld hl,(direct_ptr) + ld de,inode+24+DIRECTBLOCKS*2 + or a + sbc hl,de + jr nc,bmap_indirect + + ld hl,(direct_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (direct_ptr),hl + ret + +bmap_indirect: + ld hl,(indirect_ptr) + ld de,indirect_block+BUFSIZE + or a + sbc hl,de + jr c,bmap_indirect_already + + ld hl,(direct_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (direct_ptr),hl + + ld hl,indirect_block + ld (indirect_ptr),hl + call block_read + +bmap_indirect_already: + ld hl,(direct_ptr) + ld de,inode+24+DIRECTBLOCKS*2+INDIRECTBLOCKS*2+1 ; fudge! + or a + sbc hl,de + jr nc,bmap_dindirect + + ld hl,(indirect_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (indirect_ptr),hl + ret + +bmap_dindirect: + ld hl,(dindirect_ptr) + ld de,dindirect_block+BUFSIZE + or a + sbc hl,de + jr c,bmap_dindirect_already + + ld hl,(indirect_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (indirect_ptr),hl + + ld hl,dindirect_block + ld (dindirect_ptr),hl + call block_read + +bmap_dindirect_already: + ld hl,(dindirect_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (dindirect_ptr),hl + ret + +; ----------------------------------------------------------------------------- +; enter with hl -> buffer, de = inode number + +inode_read: + push hl + + ld a,e + and DINODESPERBLOCK-1 ; find inode position within disk block + + ld b,DINODESPERBLOCKLOG ; shift count to find which disk block +inode_shift: + srl d + rr e + djnz inode_shift ; leaves de = block (relative to itab) + + ld hl,(isize) + scf + sbc hl,de ; check if block is beyond end of table + jr c,bad_inode + + ld hl,(reserv) + add hl,de + ex de,hl ; adjust block for start of inode table + + ld hl,block + push af + push hl + call block_read + pop hl + pop de ; d = inode position within block + + ld bc,SIZEOF_DINODE_T + ld e,c + mlt de + add hl,de + pop de ; de -> user's buffer for disk inode + ldir ; copy it, freeing up block buffer + ret + +bad_inode: + call gmess + defb 'bad inode: ',0 + add a,'0' + call abyte + call amess + defb ', ',0 + ex de,hl + jp reboot_ahexw + +; ----------------------------------------------------------------------------- +; enter with hl -> buffer, de = block number + +block_read: + push hl + call block_xlate ; a:hl -> data in ramdrive + + push hl + pop iy + ld d,a ; d:iy -> data in ramdrive + + pop hl + ld e,3 ; e:hl -> user's buffer in seg 3: + jp copyr ; copy BUFSIZE bytes from d:iy to e:hl + +block_write: + push hl + call block_xlate ; a:hl -> data in ramdrive + + pop iy + ld d,3 ; d:iy -> user's buffer in seg 3: + + ld e,a ; e:hl -> data in ramdrive + jp copyr ; copy BUFSIZE bytes from d:iy to e:hl + +block_xlate: + ld hl,HD0_SIZE + scf + sbc hl,de ; check whether block no is in range + jr c,bad_block + + ld bc,BUFSIZE ; bytes to be copied for 1 block + + ld hl,HD0_START + add hl,de ; hl = block index (from start of ram) + + ld a,h + ld h,l + ld l,c ;0 ; a:hl = block index * 100h + + add hl,hl + adc a,a ; a:hl = block index * BUFSIZE (200h!!) + ret + +block_to_bbr: + ld a,(hl) + inc hl + ld d,(hl) ; d:a = block no. from start of disk + inc hl + + srl d + rra + srl d + rra + srl d + rra ; a = block / 8 (PAGE_BLOCKS = 8!!) + + add a,HD0_START/PAGE_BLOCKS-4 + ret + +bad_block: + call gmess + defb 'bad block: ',0 + ex de,hl + jp reboot_ahexw + +; ----------------------------------------------------------------------------- + +initial_boot: + ld hl,UZINAM + call LDFILE ; copy entire KERNEL.BIN data to c:0000 + ret z ; halt if the file could not be found + + call gmess + defb 'loading A:KERNEL.BIN',0dh,0ah,0 + + ld a,'1' + ld (argument_1+7),a ; so kernel will use /dev/hd1 as root + +loop: ld de,(LDMAX) + or a + sbc hl,de ; did we load an entire extent? + jr nz,done ; no, assume the file is fully loaded + + add hl,de ; restore hl = LDMAX + ld (LDPTR),hl ; load from where we finished last time + + ld a,l + or h ; did we wrap around to a new segment? + jr nz,cont + + ld hl,LDSEG + inc (hl) ; yes, need to advance segment counter + +cont: ld hl,4000h + add hl,de + ld (LDMAX),hl ; advance LDMAX to load 4000h bytes + + ld hl,LDEXT + inc (hl) ; advance extent counter to next extent + + ld hl,UZINAM + call LDFILE ; copy more CMX.BIN data to LDSEG:LDPTR + jr nz,loop + + .if 1 ; virtual memory + ld hl,LDEXT + dec (hl) ; account for extent that wasn't found + .endif + +done: + .if 1 ; virtual memory + call virtual_init ; modifies CBR (can't call EPROM now) + + .if 1 ; new kernel format + ld iy,0 + ld hl,exe_header_buf + ld de,0c03h ; copy from c: to 3: + ld bc,exe_header_size + call copyr ; read the executable's header + + call check_e_magic ; ensure e_magic = E_MAGIC + call check_e_format ; ensure e_format = E_FORMAT_KERNEL + + call get_ca0_size ; returns bc = size, de = start of copy + push de + pop iy + + ld de,0c00h ; copy from c: to 0: + ld l,e + ld h,e ; destination = 0 (start of CA0 region) + call copyr ; returns iy advanced, d & e preserved + push de + + call get_ca1_size ; returns bc = size, de = start of copy + ld hl,4000h-8000h + add hl,de ; correct for the intended CBR = 4-8 + + pop de ; copy from c: to 0: + call copyr + + call get_udata_size_m1 ; returns bc = size-1, de = start+1 + call nc,clear_bc_p1_at_de_m1 ; if bc => 0, clear bc+1 bytes at de-1 + + call say_starting ; tell the user we have liftoff + .endif + + ld a,(LDEXT) + .if 1 ; new kernel format + inc a ; do all pages, including the first + .endif + ld b,a ; how many extents were loaded ? (-1) + + ld hl,8080h ; initial spot in virt memory table + .if 1 ; new kernel format + ld a,0c0h-4 ; bbr value to access 1st loaded page + .else + ld a,0c0h ; bbr value to access 2nd loaded page + .endif + +virtual_loop: + ld (hl),a ; map 16kbytes into virt memory space + inc hl + add a,4 + djnz virtual_loop + .else + call rsel1 ; select RAM for segments 0: and 1: + + ld a,80h + out0 (CBAR),a ; CA0 = 0k, bank area = 32k, CA1 = 32k + .endif + + .if 0 ; new kernel format + ld a,0c0h-4 ; bbr value to access 1st loaded page + .endif + jp kazumi + +; ----------------------------------------------------------------------------- + +$ diag.inc +$ copyr.inc +$ clears.inc + +; ----------------------------------------------------------------------------- + +parameters: defw 2 ; argc + defw arguments-parameters_end ; argv + defw environment-parameters_end ; envp +arguments: defw argument_0-parameters_end + defw argument_1-parameters_end + defw 0 ; terminates the argument list +argument_0: defb '/boot/kernel.bin',0 +argument_1: defb 'root=hd0',0 +environment: defw environment_0-parameters_end + defw 0 ; termninates the environment list +environment_0: defb 'SN=00000',0 +parameters_end: ; this will equal address 0 after parameters are copied + +name_boot: defb 'boot',0 +name_kernel_bin: defb 'kernel.bin',0 + + ; note: defb 1 is very important here, because if UZINAM ends + ; up on a 32 byte boundary, the KERNEL.BIN filename (extent 0) + ; may be seen by the initial_boot routine, preventing the + ; proper loading of /boot/kernel after formatting the ramdrive +UZINAM: defb 1,'KERNEL BIN' ; LDNAM +LDEXT: defb 0 ; LDEXT +LDSEG: defb 0ch ; LDSEG +LDPTR: defw 0 ; LDPTR +LDMAX: defw 4000h ; LDMAX + +; ----------------------------------------------------------------------------- + +final: ; initialised code and data ends here + +reserv: +isize equ reserv+2 +fsize equ isize+2 + +dir_name equ fsize+2 +size_remain equ dir_name+2 + +direct_ptr equ size_remain+4 +indirect_ptr equ direct_ptr+2 +dindirect_ptr equ indirect_ptr+2 + +inode equ dindirect_ptr+2 +block equ inode+SIZEOF_DINODE_T + +indirect_block equ block+BUFSIZE +dindirect_block equ indirect_block+BUFSIZE + + .if 1 ; new kernel format +directory_buf equ dindirect_block+BUFSIZE + +read_remain equ directory_buf+SIZEOF_DIRECT_T +read_remain_ptr equ read_remain+2 +read_user equ read_remain_ptr+2 +read_user_ptr equ read_user+2 +read_done equ read_user_ptr+2 + +exe_header_buf equ read_done+2 +e_magic equ exe_header_buf +e_format equ e_magic+2 +e_size equ e_format+2 +e_hsize equ e_size+4 +e_idata equ e_hsize+2 +e_entry equ e_idata+2 +e_udata equ e_entry+2 +e_stack equ e_udata+2 +e_break equ e_stack+2 +exe_header_size equ e_break+2-exe_header_buf + +region_ptr equ exe_header_buf+exe_header_size + .else +region_ptr equ dindirect_block+BUFSIZE + .endif +region_list equ region_ptr+2 + +; ----------------------------------------------------------------------------- + + END diff --git a/src/gboot/gboot.asm$ b/src/gboot/gboot.asm$ new file mode 100755 index 00000000..29c12958 --- /dev/null +++ b/src/gboot/gboot.asm$ @@ -0,0 +1,793 @@ +; gboot.asm +; Generic Hytech boot loader program to occupy 4 sectors at start of each disk + +$ io64180.inc + +LDFILE equ 0f037h ; BOOTLDR.BIN entry point + +SUPERBLOCK equ 4 ; starting position of filesystem +SMOUNTED equ 12742 ; random number to specify mounted fs +ROOTINODE equ 1 ; inode number of / for all mounted fs + +BUFSIZE equ 200h ; how many bytes per disk block +BUFSIZELOG equ 9 ; shift count representing the above + +SIZEOF_DINODE_T equ 64 ; how many bytes per disk inode +DINODESPERBLOCK equ 8 ; how many disk inodes per disk block +DINODESPERBLOCKLOG equ 3 ; shift count representing the above + +DIRECTBLOCKS equ 18 +INDIRECTBLOCKS equ 1 ; MUST BE 1! +DINDIRECTBLOCKS equ 1 ; MUST BE 1! + +SIZEOF_DIRECT_T equ 16 ; how many bytes per directory entry +DIRNAMELEN equ 14 ; how many bytes of these are dir name + +REGION_LOG equ 14 +REGION_BYTES equ (1<> 14) & 1 + defb ((800h-(final-start)) >> 14) & 2 + defb ((0c00h-(final-start)) >> 14) & 3 + defb 0,0,0,0,0,0,0,0,0,0,0,0 + +entry: + call gmess + defb 'loading /boot/kernel.bin',0dh,0ah,0 + + ld de,SUPERBLOCK + ld hl,block + call block_read + + ld hl,(block) + ld de,SMOUNTED + or a + sbc hl,de + jr nz,black_magic + + ld hl,(block+2) + ld (reserv),hl + ld hl,(block+4) + ld (isize),hl + ld hl,(block+6) + ld (fsize),hl + + ld de,ROOTINODE + ld hl,name_boot + call dir_search ; returns de = the found inode + jr nz,bad_file + + ld hl,name_kernel_bin + call dir_search ; returns de = the found inode + jr nz,bad_file + + call file_scan + + call virtual_init ; modifies CBR (can't call EPROM now) + + ld bc,8080h ; initial spot in virt memory table + ld hl,region_list+2 ; -> block no. of 2nd found region + jr translate_loope + +translate_loop: + add hl,de ; restore hl value from comparison + + call block_to_bbr ; calculates a from word at hl (bumped) + ld (bc),a ; a = required bbr value to access page + inc bc + +translate_loope: + ld de,(region_ptr) ; indicates end of region list + or a + sbc hl,de ; see if we've gone past the end + jr c,translate_loop + + ld hl,region_list ; there is at least one entry + call block_to_bbr ; a = required bbr value for init code + +kazumi: ; please preserve a for entering kernel at label runsys! + ld sp,parameters-parameters_end ; stack just under copied params + + ld hl,parameters ; pre-initialised parameter block + ld de,parameters-parameters_end ; to fit neatly at top of memory + ld bc,parameters_end-parameters ; size in bytes to copy + ldir ; copy parameter block for kernel init + + .if 1 ; so as not to corrupt CBR when jumping to the loaded program + ld hl,runsys ; start of small stub program below + ld de,8100h ; -> just after virtual memory table + push de + ld c,runsys_end-runsys ; size of small stub program (b=0) + ldir ; copy stub program + ret ; enter stub program (jp 8100h) + .else + ld e,30h-8 + out0 (CBR),e ; window onto runsys (CBAR = 80h) + jp runsys+8000h ; run the remaining startup from window + .endif + +runsys: ld e,84h + out0 (CBAR),e ; CA0 = 16k, bank area = 16k, CA1 = 32k + + out0 (BBR),a ; bank area = logical 4000 = abs c:0000 + jp 4000h ; execute file from the 1st loaded page + .if 1 ; so as not to corrupt CBR when jumping to the loaded program +runsys_end: + .endif + +black_magic: + call gmess + defb 'bad magic: ',0 + add hl,de + jr reboot_ahexw + +bad_file: + call gmess + defb 'file not found',0dh,0ah,0 + jr reboot_plain + +; ----------------------------------------------------------------------------- +; had some kind of fatal error, the entry points are to save code space + +reboot_ahexw: + call ahexw + +reboot_acrlf: + call acrlf + +reboot_plain: + ; try not to surprise the user unnecessarily + call gmess + defb 'doing a clean boot',0dh,0ah,0 + + ; before rebooting, prepare to clobber CP/M drive A: directory + ld hl,block + ld de,block+1 + ld bc,BUFSIZE-1 + ld (hl),0aah ; clobbering pattern + ldir ; initialise temporary buffer + + ; perform the clobbering (this ensures a clean boot from EPROM) + ld de,304h + ld l,c + ld h,b ; ld hl,0 ; e:hl -> destination 4:0000 + + ld b,4 ; clobber until just before 4:0800 +clobber_loop: + push bc + + ld iy,block ; copy from d:iy -> destination + ld bc,BUFSIZE ; bytes to copy + call copyr ; copy them, one byte at a time + + pop bc + djnz clobber_loop + + ; ready to reboot, by instructing the WPO chip on motherboard + ld a,0aah + out0 (TRDR),A ; command byte to reboot the system + ld a,13h + out0 (CNTR),A ; TE=1, divisor = 3, start transmission + + ; wait for the reboot to occur, or else we're rather stuck + jr $ + +; ----------------------------------------------------------------------------- + +gmess: call amess + defb 'gboot: ',0 + jp amess + +rsel1: + .if 1 ; temporary only + ld de,2 ; save eprom serial no to 2:fc81 + call copy_serial_no + .endif + ld a,81h + out0 (TRDR),A ; command byte to set RSEL=1 + ld a,13h + out0 (CNTR),A ; TE=1, divisor = 3, start transmission + + sub a + dec a + jr nz,$-1 + dec a + jr nz,$-1 + dec a + jr nz,$-1 + dec a + jr nz,$-1 ; delay for command to be processed + .if 1 ; temporary only + ld de,200h ; restore eprom serial no from 2:fc81 +copy_serial_no: + ld hl,0fc81h + push hl + pop iy + ld bc,5 + jp copyr + .else + ret + .endif + +virtual_init: + call gmess + defb 'starting operating system',0dh,0ah,0 + + call rsel1 + + ld a,80h + out0 (CBAR),a ; CA0 = 0k, bank area = 32k, CA1 = 32k + + ld a,4-8 ;0 also works, see bstartup.s01 at label init + out0 (CBR),a ; window onto 0:8000, virt memory table + + ld hl,08000h + ld de,08001h + ld bc,0ffh + ld (hl),l ; 0 + ldir ; zero out the virtual memory table + ret + +; ----------------------------------------------------------------------------- + +file_scan: + ld hl,region_list + ld (region_ptr),hl + + ld hl,inode + call inode_read ; read inode of the target file + + call bmap_setup ; prepare counters to walk the file + call bmap_remain ; get hl = valid bytes in first block + ; and decrement the file size remaining + ld a,l + or h ; any bytes in file? + jr z,bad_file_size ; no, abort proceedings + +file_scan_loop: + call bmap_block ; get de = block no. of current block + ; and increment the block position + ld a,e + or d + jr z,bad_file_block +; ld l,e +; ld h,d +; call ahexw + + ld a,e + and PAGE_BLOCKS-1 ; check it starts on a page boundary + jr nz,bad_alignment + + ld hl,(region_ptr) + ld (hl),e + inc hl + ld (hl),d ; stash away the starting block no. + inc hl + ld (region_ptr),hl ; for the current region (bumped) + + ld b,REGION_BLOCKS-1 + +file_region_loop: + push bc + push de + + call bmap_remain ; get hl = valid bytes in current block + ; and decrement the file size remaining + ld a,l + or h + jr z,file_region_final + + call bmap_block ; get de = block no. of current block + ; and increment the block position + ld a,e + or d + jr z,bad_file_block +; ld a,' ' +; call abyte +; ld l,e +; ld h,d +; call ahexw + + ex de,hl ; hl = the actual block no. from file + pop de + inc de ; de = expected, contiguous block no. + + or a + sbc hl,de + jr nz,bad_alignment + + pop bc + djnz file_region_loop +; call acrlf + + call bmap_remain ; get hl = valid bytes in current block + ; and decrement the file size remaining + ld a,l + or h ; anything left to read? + jr nz,file_scan_loop ; yes (scan is limited by file size) + ret ; last region is = REGION_BLOCKS blocks + +file_region_final: +; call acrlf + pop hl ; last region is < REGION_BLOCKS blocks + pop hl ; clean up saved variables, and done + ret + +bad_file_size: + call gmess + defb 'null file',0dh,0ah,0 + jp reboot_plain + +bad_file_block: + call gmess + defb 'hole in file',0dh,0ah,0 + jp reboot_plain + +bad_alignment: + call gmess + defb 'not aligned',0dh,0ah,0 + jp reboot_plain + +; ----------------------------------------------------------------------------- + +dir_search: + ld (dir_name),hl + + ld hl,inode + call inode_read ; read inode of the dir to be searched + + call bmap_setup ; prepare counters to walk the file + jr dir_search_loope + +dir_search_loop: + push hl ; h = count of entries in current block + call bmap_block ; get de = block no. of current block + ; and increment the block position + ld a,e + or d + jr z,bad_dir_block + + ld hl,block + push hl + call block_read + pop hl + pop bc ; b = count of entries in current block + +dir_search_entry_loop: + push hl + inc hl + inc hl + + ld de,(dir_name) + ld c,DIRNAMELEN + +dir_search_compare_loop: + ld a,(de) + cp (hl) + jr nz,dir_search_compare_bad + or a + jr z,dir_search_compare_good + + inc hl + inc de + dec c + jr nz,dir_search_compare_loop + +dir_search_compare_good: + pop hl + ld e,(hl) + inc hl + ld d,(hl) + ret + +dir_search_compare_bad: + pop hl + ld de,SIZEOF_DIRECT_T + add hl,de + djnz dir_search_entry_loop + +dir_search_loope: + call bmap_remain ; get hl = valid bytes in current block + ; and decrement the file size remaining + add hl,hl + add hl,hl + add hl,hl + add hl,hl ; assumes SIZEOF_DIRECT_T = 16!! + + ld a,h ; a = valid bytes / SIZEOF_DIRECT_T + or a + jr nz,dir_search_loop + + ret + +bad_dir_block: + call gmess + defb 'hole in directory',0dh,0ah,0 + jp reboot_plain + +; ----------------------------------------------------------------------------- + +bmap_setup: + ld hl,(inode+8) + ld (size_remain),hl + ld hl,(inode+10) + ld (size_remain+2),hl + + ld hl,inode+24 + ld (direct_ptr),hl + ld hl,indirect_block+BUFSIZE + ld (indirect_ptr),hl + ld hl,dindirect_block+BUFSIZE + ld (dindirect_ptr),hl + ret + +bmap_remain: + ld hl,(size_remain) + ld de,(size_remain+2) + + ld bc,BUFSIZE + or a + sbc hl,bc + ex de,hl + ld b,0 ; ld bc,0 + sbc hl,bc + ex de,hl + jr c,bmap_remain_final + + ld (size_remain),hl + ld (size_remain+2),de + + ld hl,BUFSIZE + ret ; return a complete block of size hl + +bmap_remain_final: + ld hl,(size_remain) + ld (size_remain),bc ; 0 + ;ld (size_remain+2),bc ; 0 + ret ; return a partial block of size hl + +bmap_block: + ld hl,(direct_ptr) + ld de,inode+24+DIRECTBLOCKS*2 + or a + sbc hl,de + jr nc,bmap_indirect + + ld hl,(direct_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (direct_ptr),hl + ret + +bmap_indirect: + ld hl,(indirect_ptr) + ld de,indirect_block+BUFSIZE + or a + sbc hl,de + jr c,bmap_indirect_already + + ld hl,(direct_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (direct_ptr),hl + + ld hl,indirect_block + ld (indirect_ptr),hl + call block_read + +bmap_indirect_already: + ld hl,(direct_ptr) + ld de,inode+24+DIRECTBLOCKS*2+INDIRECTBLOCKS*2+1 ; fudge! + or a + sbc hl,de + jr nc,bmap_dindirect + + ld hl,(indirect_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (indirect_ptr),hl + ret + +bmap_dindirect: + ld hl,(dindirect_ptr) + ld de,dindirect_block+BUFSIZE + or a + sbc hl,de + jr c,bmap_dindirect_already + + ld hl,(indirect_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (indirect_ptr),hl + + ld hl,dindirect_block + ld (dindirect_ptr),hl + call block_read + +bmap_dindirect_already: + ld hl,(dindirect_ptr) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld (dindirect_ptr),hl + ret + +; ----------------------------------------------------------------------------- +; enter with hl -> buffer, de = inode number + +inode_read: + push hl + + ld a,e + and DINODESPERBLOCK-1 ; find inode position within disk block + + ld b,DINODESPERBLOCKLOG ; shift count to find which disk block +inode_shift: + srl d + rr e + djnz inode_shift ; leaves de = block (relative to itab) + + ld hl,(isize) + scf + sbc hl,de ; check if block is beyond end of table + jr c,bad_inode + + ld hl,(reserv) + add hl,de + ex de,hl ; adjust block for start of inode table + + ld hl,block + push af + push hl + call block_read + pop hl + pop de ; d = inode position within block + + ld bc,SIZEOF_DINODE_T + ld e,c + mlt de + add hl,de + pop de ; de -> user's buffer for disk inode + ldir ; copy it, freeing up block buffer + ret + +bad_inode: + call gmess + defb 'bad inode: ',0 + add a,'0' + call abyte + call amess + defb ', ',0 + ex de,hl + jp reboot_ahexw + +; ----------------------------------------------------------------------------- +; enter with hl -> buffer, de = block number + +block_read: + push hl + call block_xlate ; a:hl -> data in ramdrive + + push hl + pop iy + ld d,a ; d:iy -> data in ramdrive + + pop hl + ld e,3 ; e:hl -> user's buffer in seg 3: + jp copyr ; copy BUFSIZE bytes from d:iy to e:hl + +block_write: + push hl + call block_xlate ; a:hl -> data in ramdrive + + pop iy + ld d,3 ; d:iy -> user's buffer in seg 3: + + ld e,a ; e:hl -> data in ramdrive + jp copyr ; copy BUFSIZE bytes from d:iy to e:hl + +block_xlate: + ld hl,HD0_SIZE + scf + sbc hl,de ; check whether block no is in range + jr c,bad_block + + ld bc,BUFSIZE ; bytes to be copied for 1 block + + ld hl,HD0_START + add hl,de ; hl = block index (from start of ram) + + ld a,h + ld h,l + ld l,c ;0 ; a:hl = block index * 100h + + add hl,hl + adc a,a ; a:hl = block index * BUFSIZE (200h!!) + ret + +block_to_bbr: + ld a,(hl) + inc hl + ld d,(hl) ; d:a = block no. from start of disk + inc hl + + srl d + rra + srl d + rra + srl d + rra ; a = block / 8 (PAGE_BLOCKS = 8!!) + + add a,HD0_START/PAGE_BLOCKS-4 + ret + +bad_block: + call gmess + defb 'bad block: ',0 + ex de,hl + jp reboot_ahexw + +; ----------------------------------------------------------------------------- + +initial_boot: + ld hl,UZINAM + call LDFILE ; copy entire KERNEL.BIN data to c:0000 + ret z ; halt if the file could not be found + + call gmess + defb 'loading A:KERNEL.BIN',0dh,0ah,0 + + ld a,'1' + ld (argument_1+7),a ; so kernel will use /dev/hd1 as root + +loop: ld de,(LDMAX) + or a + sbc hl,de ; did we load an entire extent? + jr nz,done ; no, assume the file is fully loaded + + add hl,de ; restore hl = LDMAX + ld (LDPTR),hl ; load from where we finished last time + + ld a,l + or h ; did we wrap around to a new segment? + jr nz,cont + + ld hl,LDSEG + inc (hl) ; yes, need to advance segment counter + +cont: ld hl,4000h + add hl,de + ld (LDMAX),hl ; advance LDMAX to load 4000h bytes + + ld hl,LDEXT + inc (hl) ; advance extent counter to next extent + + ld hl,UZINAM + call LDFILE ; copy more CMX.BIN data to LDSEG:LDPTR + jr nz,loop + + .if 1 ; virtual memory + ld hl,LDEXT + dec (hl) ; account for extent that wasn't found + .endif + +done: + .if 1 ; virtual memory + call virtual_init ; modifies CBR (can't call EPROM now) + + ld a,(LDEXT) + ld b,a ; how many extents were loaded ? (-1) + + ld hl,8080h ; initial spot in virt memory table + ld a,0c0h ; bbr value to access 2nd loaded page + +virtual_loop: + ld (hl),a ; map 16kbytes into virt memory space + inc hl + add a,4 + djnz virtual_loop + .else + call rsel1 ; select RAM for segments 0: and 1: + + ld a,80h + out0 (CBAR),a ; CA0 = 0k, bank area = 32k, CA1 = 32k + .endif + + ld a,0c0h-4 ; bbr value to access 1st loaded page + jp kazumi + +; ----------------------------------------------------------------------------- + +$ diag.inc +$ copyr.inc +$ clears.inc + +; ----------------------------------------------------------------------------- + +parameters: defw 2 ; argc + defw arguments-parameters_end ; argv + defw environment-parameters_end ; envp +arguments: defw argument_0-parameters_end + defw argument_1-parameters_end + defw 0 ; terminates the argument list +argument_0: defb '/boot/kernel.bin',0 +argument_1: defb 'root=hd0',0 +environment: defw environment_0-parameters_end + defw 0 ; termninates the environment list +environment_0: defb 'SN=00000',0 +parameters_end: ; this will equal address 0 after parameters are copied + +name_boot: defb 'boot',0 +name_kernel_bin: defb 'kernel.bin',0 + + ; note: defb 1 is very important here, because if UZINAM ends + ; up on a 32 byte boundary, the KERNEL.BIN filename (extent 0) + ; may be seen by the initial_boot routine, preventing the + ; proper loading of /boot/kernel after formatting the ramdrive +UZINAM: defb 1,'KERNEL BIN' ; LDNAM +LDEXT: defb 0 ; LDEXT +LDSEG: defb 0ch ; LDSEG +LDPTR: defw 0 ; LDPTR +LDMAX: defw 4000h ; LDMAX + +; ----------------------------------------------------------------------------- + +final: ; initialised code and data ends here + +reserv: +isize equ reserv+2 +fsize equ isize+2 + +dir_name equ fsize+2 +size_remain equ dir_name+2 + +direct_ptr equ size_remain+4 +indirect_ptr equ direct_ptr+2 +dindirect_ptr equ indirect_ptr+2 + +inode equ dindirect_ptr+2 +block equ inode+SIZEOF_DINODE_T + +indirect_block equ block+BUFSIZE +dindirect_block equ indirect_block+BUFSIZE + +region_ptr equ dindirect_block+BUFSIZE +region_list equ region_ptr+2 + +; ----------------------------------------------------------------------------- + + END diff --git a/src/gboot/gboot.lnk b/src/gboot/gboot.lnk new file mode 100755 index 00000000..87fdf744 --- /dev/null +++ b/src/gboot/gboot.lnk @@ -0,0 +1,6 @@ +-m +-u +-i +-o gboot +-b _DEFAULT=0 +gboot diff --git a/src/gboot/io64180.inc b/src/gboot/io64180.inc new file mode 100755 index 00000000..01380ae1 --- /dev/null +++ b/src/gboot/io64180.inc @@ -0,0 +1,155 @@ +; /* - 64180.inc - +; +; This files defines the internal register addresses +; for HD64180 +; +; File version: $Revision: 1.4 $ +; +; */ +; +; /* ================================== */ +; /* */ +; /* ASCI Channel Control Registers */ +; /* */ +; /* ================================== */ + +CNTLA0 = 0x00; /* ASCI Ctrl Reg A, Ch 0 */ +CNTLA1 = 0x01; /* ASCI Ctrl Reg A, Ch 1 */ +CNTLB0 = 0x02; /* ASCI Ctrl Reg B, Ch 0 */ +CNTLB1 = 0x03; /* ASCI Ctrl Reg B, Ch 1 */ +; ----------------------------------------------------------------------------- +STAT0 = 0x04; /* ASCI Status Reg, Ch 0 */ +STAT1 = 0x05; /* ASCI Status Reg, Ch 1 */ +; ----------------------------------------------------------------------------- +TDR0 = 0x06; /* ASCI Transmit Data Reg, Ch 0 */ +TDR1 = 0x07; /* ASCI Transmit Data Reg, Ch 1 */ +RDR0 = 0x08; /* ASCI Receive Data Reg, Ch 0 */ +RDR1 = 0x09; /* ASCI Receive Data Reg, Ch 1 */ + +; /* ================================== */ +; /* */ +; /* CSI/O Registers */ +; /* */ +; /* ================================== */ + +CNTR = 0x0A; /* CSI/O Ctrl Reg */ +TRDR = 0x0B; /* CSI/O Trans/Rec Data Reg */ + +; /* ================================== */ +; /* */ +; /* Timer Registers */ +; /* */ +; /* ================================== */ + +TMDR0L = 0x0C; /* Timer 0 Data Reg L */ +TMDR0H = 0x0D; /* Timer 0 Data Reg H */ +TMDR1L = 0x14; /* Timer 1 Data Reg L */ +TMDR1H = 0x15; /* Timer 1 Data Reg H */ +; ----------------------------------------------------------------------------- +RLDR0L = 0x0E; /* Timer 0 Reload Reg L */ +RLDR0H = 0x0F; /* Timer 0 Reload Reg H */ +RLDR1L = 0x16; /* Timer 1 Reload Reg L */ +RLDR1H = 0x17; /* Timer 1 Reload Reg H */ +; ----------------------------------------------------------------------------- +TCR = 0x10; /* Timer Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* Free Running Counter */ +; /* */ +; /* ================================== */ + +FRC = 0x18; /* Free Running Counter */ + +; /* ================================== */ +; /* */ +; /* DMA Registers */ +; /* */ +; /* ================================== */ + +SAR0L = 0x20; /* DMA 0 Source Addr Reg */ +SAR0H = 0x21; /* DMA 0 Source Addr Reg */ +SAR0B = 0x22; /* DMA 0 Source Addr Reg */ +; ----------------------------------------------------------------------------- +DAR0L = 0x23; /* DMA 0 Destination Addr Reg */ +DAR0H = 0x24; /* DMA 0 Destination Addr Reg */ +DAR0B = 0x25; /* DMA 0 Destination Addr Reg */ +; ----------------------------------------------------------------------------- +BCR0L = 0x26; /* DMA 0 Counter Reg */ +BCR0H = 0x27; /* DMA 0 Counter Reg */ +; ----------------------------------------------------------------------------- +MAR1L = 0x28; /* DMA 1 Memory Addr Reg */ +MAR1H = 0x29; /* DMA 1 Memory Addr Reg */ +MAR1B = 0x2A; /* DMA 1 Memory Addr Reg */ +; ----------------------------------------------------------------------------- +IAR1L = 0x2B; /* DMA I/O Addr Reg */ +IAR1H = 0x2C; /* DMA I/O Addr Reg */ +; ----------------------------------------------------------------------------- +BCR1L = 0x2E; /* DMA 1 Byte Count Reg */ +BCR1H = 0x2F; /* DMA 1 Byte Count Reg */ +; ----------------------------------------------------------------------------- +DSTAT = 0x30; /* DMA Status Reg */ +DMODE = 0x31; /* DMA Mode Reg */ +DCNTL = 0x32; /* DMA/WAIT Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* MMU Registers */ +; /* */ +; /* ================================== */ + +CBR = 0x38; /* MMU Common Base Reg */ +BBR = 0x39; /* MMU Bank Base Reg */ +CBAR = 0x3A; /* MMU Bank/Common Area Reg */ +; CBR_location = 0x38; /* MMU Common Base Reg */ +; BBR_location = 0x39; /* MMU Bank Base Reg */ +; CBAR_location = 0x3A; /* MMU Bank/Common Area Reg */ +; #define CBR CBR_location +; #define BBR BBR_location +; #define CBAR CBAR_location + +; /* ================================== */ +; /* */ +; /* Interrupt Registers */ +; /* */ +; /* ================================== */ + +IL = 0x33; /* Int Vect Low Reg */ +ITC = 0x34; /* Int/Trap Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* Refresh Registers */ +; /* */ +; /* ================================== */ + +RCR = 0x36; /* Refresh Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* I/O Registers */ +; /* */ +; /* ================================== */ + +ICR = 0x3F; /* I/O Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* Bit Definitions */ +; /* */ +; /* ================================== */ + +INT0SW = 0x01; /* interrupt enable bits in ITC */ +INT1SW = 0x02; /* interrupt enable bits in ITC */ +INT2SW = 0x04; /* interrupt enable bits in ITC */ + +; ----------------------------------------------------------------------------- +; Hytech specific hardware: (For the WPO30-V5, Hytech 1000, Hytech 1500) + +BC8530 = 0x214; /* channel B control in 8530 */ +AC8530 = 0x215; /* channel A control in 8530 */ +BD8530 = 0x216; /* channel B data in 8530 */ +AD8530 = 0x217; /* channel A data in 8530 */ + +; ----------------------------------------------------------------------------- + diff --git a/src/gboot/n.bat b/src/gboot/n.bat new file mode 100755 index 00000000..2a922e15 --- /dev/null +++ b/src/gboot/n.bat @@ -0,0 +1,25 @@ +as-z80 -l -o gboot +@if errorlevel 1 goto failure +link-z80 -f gboot +@if errorlevel 1 goto failure + +ihex2bin gboot.i86 ..\..\bin\boot.bin +4dos /c crcd ..\..\bin\boot.bin +bin2c ..\..\bin\boot.bin ..\fsutil\boot.c + +copy checksum.dat \nlddl +copy checksum.dat \nlddl\crc.dat +copy ..\..\bin\boot.bin \nlddl +set country=NLD +crc +copy \nlddl\checksum ..\..\bin + +copy \nlddl\checksum \\darkstar\public\dos622\nlddl +copy \nlddl\boot.bin \\darkstar\public\dos622\nlddl + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/hello/build-b.ban b/src/hello/build-b.ban new file mode 100755 index 00000000..64534d41 --- /dev/null +++ b/src/hello/build-b.ban @@ -0,0 +1,17 @@ +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ ..\hello +@if errorlevel 1 goto failure +del hello.r01 +as-z80 -l -o hello.s01 +@if errorlevel 1 goto failure + +link-z80 -f hello +@if errorlevel 1 goto failure +ihex2bin -l hello.i86 ..\hello-b +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/hello/build-l.ban b/src/hello/build-l.ban new file mode 100755 index 00000000..c9c1b757 --- /dev/null +++ b/src/hello/build-l.ban @@ -0,0 +1,17 @@ +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ ..\hello +@if errorlevel 1 goto failure +del hello.r01 +as-z80 -l -o hello.s01 +@if errorlevel 1 goto failure + +link-z80 -f hello +@if errorlevel 1 goto failure +ihex2bin hello.i86 ..\hello-l +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/hello/hello-b b/src/hello/hello-b new file mode 100755 index 0000000000000000000000000000000000000000..3a1898672dae1b999c48300723f245ea9c04f9bc GIT binary patch literal 4833 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 P|28D-q%>z9(}w&Tc-dz& literal 0 HcmV?d00001 diff --git a/src/hello/hello-l.lnk b/src/hello/hello-l.lnk new file mode 100755 index 00000000..388430b6 --- /dev/null +++ b/src/hello/hello-l.lnk @@ -0,0 +1,11 @@ +-k ..\..\..\lib +-l libcl.lib +-l libsysl.lib +-l libiar.lib +-m +-u +-i +-o hello +-bl RCODE=0x8100 +..\..\..\lib\c0l.rel +hello diff --git a/src/hello/hello.c b/src/hello/hello.c new file mode 100755 index 00000000..f0a87841 --- /dev/null +++ b/src/hello/hello.c @@ -0,0 +1,7 @@ +#include + +void main(void) + { + printf("hello, world\n"); + } + diff --git a/src/hello/n.bat b/src/hello/n.bat new file mode 100755 index 00000000..9231c09e --- /dev/null +++ b/src/hello/n.bat @@ -0,0 +1,14 @@ +md build-l +cd build-l +copy ..\hello-l.lnk hello.lnk +copy ..\build-l.ban n.bat +call n +cd.. + +md build-b +cd build-b +copy ..\hello-b.lnk hello.lnk +copy ..\build-b.ban n.bat +call n +cd .. + diff --git a/src/init/build-b.ban b/src/init/build-b.ban new file mode 100755 index 00000000..d8a034e9 --- /dev/null +++ b/src/init/build-b.ban @@ -0,0 +1,28 @@ +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\init +@if errorlevel 1 goto failure +del init.r01 +as-z80 -l -o init.s01 +@if errorlevel 1 goto failure + +link-z80 -f init +@if errorlevel 1 goto failure +ihex2bin -l init.i86 ..\..\..\bin\banked\init +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\login +@if errorlevel 1 goto failure +del login.r01 +as-z80 -l -o login.s01 +@if errorlevel 1 goto failure + +link-z80 -f login +@if errorlevel 1 goto failure +ihex2bin -l login.i86 ..\..\..\bin\banked\login +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/init/build-l.ban b/src/init/build-l.ban new file mode 100755 index 00000000..8a45a7f4 --- /dev/null +++ b/src/init/build-l.ban @@ -0,0 +1,28 @@ +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\init +@if errorlevel 1 goto failure +del init.r01 +as-z80 -l -o init.s01 +@if errorlevel 1 goto failure + +link-z80 -f init +@if errorlevel 1 goto failure +ihex2bin -l init.i86 ..\..\..\bin\large\init +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\login +@if errorlevel 1 goto failure +del login.r01 +as-z80 -l -o login.s01 +@if errorlevel 1 goto failure + +link-z80 -f login +@if errorlevel 1 goto failure +ihex2bin -l login.i86 ..\..\..\bin\large\login +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/init/init.c b/src/init/init.c new file mode 100755 index 00000000..90016bb2 --- /dev/null +++ b/src/init/init.c @@ -0,0 +1,460 @@ +/* init.c + */ + +/* the use of 'firsttime' var for erasing /etc/mtab isn't the best solution. + * if init can't spawn the first tty, but can respawn it or spawn the second, + * /etc/mtab will not be erased and initialized. + */ + +/* #define NO_RTC + * causes init to ask and set system clock when executed at first time + */ +#define NO_RTC /* modified by Nick to skip prompt when year >= 2003 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Nick */ +#include +#include + +static firsttime = 1; + +struct exec_struct +{ + char *tty_name; + char *sh_name; + int pid; +}; + +#define NUM_TTYS 1 + +struct exec_struct tty_list[NUM_TTYS] = +{ + { _PATH_CONSOLE, _PATH_LOGIN } +}; + +void process_inittab(void) +{ + FILE *fdm; + char cmd[128], *p; /* [64], *p; */ + static char *_argv[3]; /* [2] = { 0, 0 }; */ + int pid; + + if ((fdm = fopen("/etc/inittab", "r")) != NULL) { + while (!feof(fdm)) { + if (fgets(cmd, sizeof(cmd)-1, fdm)==NULL) break; + if (cmd[0] != '#') { + if (NULL != (p = strchr(cmd, '\n'))) *p=0; + if (cmd[0] > ' ') { + printf("init: executing %s\n", cmd); + pid = fork(); + if (pid==-1) { + printf("init: can't execute %s\n", cmd); + continue; + } + if (pid==0) { + _argv[0] = cmd; + _argv[1] = NULL; + execve(_argv[0], _argv, environ); + if (errno == ESHELL) + { + _argv[0] = _PATH_BSHELL; + _argv[1] = cmd; + _argv[2] = NULL; + execve(_argv[0], _argv, environ); + } + printf("init: can't execute %s\n", cmd); + exit(1); + } + wait(&pid); + } + } + } + fclose(fdm); + } +} + +int determine_tty(int pid) +{ + int i; + + for (i = 0; i < NUM_TTYS; i++) { + if (pid == tty_list[i].pid) + return i; + } + return -1; +} + +void generate_mtab(void) +{ +#if 1 /* Nick, new getfsys() convention */ + filesys_t fsys; +#else + info_t info; + fsptr fsys; +#endif + int j; +#if 1 /* Nick */ + char mtabline[] = "/dev/hdX\t/\trw\n"; +#else + char mtabline[] = "/dev/fdX\t/\trw\n"; +#endif + char *s = "failed"; + FILE *fdm; + +#if 1 /* Nick */ + printf("init: creating /etc/mtab: "); +#else + printf("Updating /etc/mtab: "); +#endif + for (j = 0; j < 8; ++j) + { +#if 1 /* Nick, new getfsys() convention */ + if (getfsys(j, &fsys) == 0 && + fsys.s_mounted == SMOUNTED && + fsys.s_mntpt == NULL) + { + j = MINOR(fsys.s_dev); +#else + if (0 == getfsys(j, &info) && (fsys = (fsptr)info.ptr) != NULL + && fsys->s_mounted && fsys->s_mntpt == NULL) + { + j = MINOR(fsys->s_dev); +#endif + unlink("/etc/mtab"); + mtabline[7] = j + '0'; + if ((fdm = fopen("/etc/mtab", "w")) != NULL) + { + if (fputs(mtabline, fdm) != EOF) + s = "ok"; + fclose(fdm); + } + break; + } + } + printf("%s\n", s); +} + +#if 1 /* Nick, we want mtab preserved over bootup */ +#define PLENGTH 40 + +void process_mtab(void) + { + int r; + FILE *mtb; + char line[PLENGTH]; + char mf1[PLENGTH], mf2[PLENGTH], mf3[PLENGTH]; + + if ((mtb = fopen("/etc/mtab", "r")) == NULL) + { +#if 1 + generate_mtab(); +#else + printf("init: can't open /etc/mtab\n"); +#endif + return; + } + while (!feof(mtb)) + { + if (fgets(line, PLENGTH, mtb)) + { + mf1[0] = mf2[0] = mf3[0] = '\0'; + r = sscanf(line, "%s%s%s", mf1, mf2, mf3); + if (r > 1 && strcmp(mf2, "/")) + { + if (r > 2) + { + r = !strcmp(mf3, "ro"); + } + else + { + r = 0; /* default to read/write */ + } + r = mount(mf1, mf2, r); + if (r < 0) + { + fprintf(stderr, + "init: failed to mount %s on %s\n", + mf1, mf2); + } + } + } + } + fclose(mtb); + } +#endif + +int spawn_tty(unsigned num, char **argv) +{ + char *s; + int pid, fd; +#if 1 /* Nick */ + struct sgttyb state; +#endif + + struct exec_struct *p = &tty_list[num]; + + if (num >= NUM_TTYS) + exit(-1); + if ((pid = fork()) != 0) { /* error/parent */ + firsttime = 0; + p->pid = pid; + return pid; + } + /* child - must open own tty */ + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + if ((fd = open(p->tty_name, O_RDWR)) < 0) + exit(-2); +#if 1 /* Nick */ + if (isatty(fd)) + { + gtty(fd, &state); + state.sg_flags = XTABS | CRMOD | ECHO | COOKED; + stty(fd, &state); + } +#endif + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + if (firsttime) { +#if 1 /* Nick, we want mtab preserved over bootup */ + process_mtab(); +#else + generate_mtab(); +#endif + process_inittab(); + printf("Spawning tty #%d (%s): ok\n", num, p->tty_name); + } + setenv("TTY", p->tty_name, 1); + setenv("TERM", +#ifdef MSX_UZIX_TARGET + "vt52" +#endif +#ifdef PC_UZIX_TARGET + "ansi" +#endif + , 1); + for (s = p->sh_name; s[1] != 0; ++s) + ; + while (s > p->sh_name && s[-1] != '/') + --s; + argv[0] = s; + printf("Starting login...\n\n"); + execve(p->sh_name, argv, environ); + printf("init: can't execute %s\n", p->sh_name); + exit(-3); +} + +#ifdef NO_RTC +/* get an integer value from *p and return the first char after in p1 */ +int getint(char *p, char **p1) +{ + int v = 0; + + while (*p >= '0' && *p <= '9') { + v *= 10; + v += *p - '0'; + ++p; + } + *p1 = p; + return v; +} + +/* convert a given time in t1 and date in t2 into struct tm */ +int conv_time(char *t1, char *t2, struct tm *tt) +{ + int h, m, s, d, mm, y; + char *t; + + /* hh:mm[:ss] */ + t = t1; + h = getint(t, &t); + if ((h < 0) || (h > 23) || (*t++ != ':')) return 0; + m = getint(t, &t); + if ((m < 0) || (m > 59)) return 0; + if (*t) { + if (*t++ != ':') return 0; + s = getint(t, &t); + if ((s < 0) || (s > 59) || (*t != 0)) return 0; + } + else s = 0; + + /* dd/mm/yy[yy] */ + t = t2; + d = getint(t, &t); + if ((d < 1) || (d > 31) || (*t++ != '/')) return 0; + mm = getint(t, &t); + if ((mm < 1) || (mm > 12) || (*t++ != '/')) return 0; + y = getint(t, &t); + if (y < 100) { + if (y < 80) + y += 100; + } + else y -= 1900; + if ((y < 0) || (*t != 0)) return 0; + tt->tm_hour = h; + tt->tm_min = m; + tt->tm_sec = s; + tt->tm_year = y; + tt->tm_mon = mm - 1; + tt->tm_mday = d; + return 1; +} +#endif + +#if 1 /* Nick */ +void reopen_console(void) + { + int fd; + struct sgttyb state; + + /* reopen init's tty */ + close(STDIN_FILENO); + + fd = open(_PATH_CONSOLE, O_RDWR); + if (isatty(fd)) + { + gtty(fd, &state); + state.sg_flags = XTABS | CRMOD | ECHO | COOKED; + stty(fd, &state); + } + + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + } +#endif + +VOID main(int argc, char *argv[]) +{ + int i, pid, rv; +#if 0 /* Nick */ + int fd; + struct sgttyb state; +#endif +#ifdef NO_RTC + char buf[40], *p; + struct tm tt; + time_t mytimet; +#if 1 /* Nick */ + struct tm *tmbuf; +#endif +#endif + +/* (void)argc; */ + signal(SIGINT, SIG_IGN); +/* signal(SIGKILL, SIG_IGN); /* can't caught KILL!!! */ + signal(SIGABRT, SIG_IGN); +#if 1 /* Nick */ + reopen_console(); +#endif + setenv("PATH", _PATH_DEFPATH, 0); + setenv("HOME", "/", 0); +#ifdef NO_RTC +#if 1 /* Nick */ + /* reopen_console(); */ + + printf("Date/time: "); + fflush(stdout); + + time(&mytimet); + while (mytimet.t_time == 0 && mytimet.t_date == 0) + { + time(&mytimet); + } + tmbuf = localtime(&mytimet); + + printf("%s", asctime(tmbuf)); /* has embedded newline */ + fflush(stdout); + + if (tmbuf->tm_year < 103) /* 2003 */ +#else + for (;;) +#endif + { + printf("Enter date/time (hh:mm[:ss] dd/mm/yyyy): "); + fflush(stdout); + read(0, buf, 39); + p=strchr(buf, '\n'); + *p=0; + p=strchr(buf, ' '); + *p=0; + if (!conv_time(buf, p+1, &tt)) + { + printf("Bad date/time format\n"); +#if 1 /* Nick */ + } + else + { + mytimet = mktime(&tt); + if (stime(&mytimet) < 0) + { + printf("Error setting clock\n"); + } + else + { + printf("New date/time: %s", ctime(&mytimet)); + /* has embedded newline */ + } + } + } + + printf("\n"); + fflush(stdout); +#else + continue; + } + mytimet = mktime(&tt); + if (stime(&mytimet) < 0) + { + printf("Error setting clock\n"); + } + break; + } +#endif +#endif + for (i = 0; i < NUM_TTYS; i++) + spawn_tty(i, argv); +#if 1 /* Nick */ + reopen_console(); +#else + /* reopen init's tty */ + close(STDIN_FILENO); + fd = open(_PATH_CONSOLE, O_RDWR); +#if 1 /* Nick */ + if (isatty(fd)) + { + gtty(fd, &state); + state.sg_flags = XTABS | CRMOD | ECHO | COOKED; + stty(fd, &state); + } +#endif + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); +#endif +#if DEBUG > 0 + printf("INIT's PID is %d\n",getpid()); fflush(stdout); +#endif + while (1) { + pid = wait(&rv); +#if DEBUG > 0 + printf("process #%d returns %d,%d\n", + pid, (unsigned char)(rv >> 8), (unsigned char)rv); +#endif + fflush(stdout); + if ((i = determine_tty(pid)) >= 0) { + printf("\nRespawning tty #%d (%s): ok\n", + i, tty_list[i].tty_name); + fflush(stdout); + tty_list[i].pid = 0; + spawn_tty(i, argv); + } + } +} + diff --git a/src/init/login.c b/src/init/login.c new file mode 100755 index 00000000..d7cc7f8b --- /dev/null +++ b/src/init/login.c @@ -0,0 +1,101 @@ +/* login.c + * descripton: login into a user account + * author: Alistair Riddoch + * modification: David Murn + * Added password entry + * modification: Shane Kerr + * More work on password entry + */ + +/* todo: add a timeout for serial and network logins */ +/* ??? need a signal mechanism (i.e. alarm() and SIGALRM) */ +/* real getpass() ! */ + +#include +#include +#include +#include +#include + +void login(pwd, argv) + struct passwd *pwd; + char **argv; +{ + char pname[64]; + char *bname; + +#if 1 /* addition by Nick, purely for cosmetic purposes */ + fputs("\n", stdout); + fflush(stdout); +#endif + +#if 1 /* addition by Nick, please see linux manpage passwd.5 */ + if (!*pwd->pw_shell) + { + pwd->pw_shell = "/bin/sh"; + } +#endif + +/* chown("/dev/tty",pwd->pw_uid,pwd->pw_gid); */ + pname[0] = '-'; + if ((bname = strrchr(pwd->pw_shell, '/')) != NULL) + bname++; + else bname = pwd->pw_shell; + strcpy(pname+1, bname); + argv[0] = pname; + argv[1] = NULL; + /* we must set first GID, because we're still root + if UID is set first and we aren't logging as root, + we won't have permission to change our GID */ + setgid(pwd->pw_gid); + setuid(pwd->pw_uid); + chdir(pwd->pw_dir); + setenv("HOME", pwd->pw_dir, 1); + setenv("USER", pwd->pw_name, 1); + execv(pwd->pw_shell, argv); + perror(pwd->pw_shell); + exit(1); +} + +void main(argc, argv) + int argc; + char **argv; +{ + char lbuf[20], *pbuf, salt[3], *s; + struct passwd *pwd; + int n; + + argv[0] = "login"; + for (;;) { + if (argc > 1) { + strcpy(lbuf, argv[1]); + argc = 0; + } + else { + fputs("login: ", stdout); + fflush(stdout); + if (fgets(lbuf, sizeof(lbuf), stdin) == NULL) + exit(1); + n = strlen(lbuf) - 1; + if (lbuf[n] == '\n') + lbuf[n] = 0; + if (lbuf[0] == 0) + continue; + } + pwd = getpwnam(lbuf); + if ((pwd != NULL) && (pwd->pw_passwd[0] == 0)) + login(pwd, argv); + pbuf = getpass("password: "); + putchar('\n'); + if (pwd != NULL) { + salt[0] = pwd->pw_passwd[0]; + salt[1] = pwd->pw_passwd[1]; + salt[2] = 0; + s = crypt(pbuf, salt); + if (!strcmp(s, pwd->pw_passwd)) + login(pwd, argv); + } + fputs("Login incorrect\n\n", stdout); + } +} + diff --git a/src/init/n.bat b/src/init/n.bat new file mode 100755 index 00000000..6567cb06 --- /dev/null +++ b/src/init/n.bat @@ -0,0 +1,16 @@ +md build-l +cd build-l +call mklink-l init ..\ +call mklink-l login ..\ +copy ..\build-l.ban n.bat +call n +cd .. + +md build-b +cd build-b +call mklink-b init ..\ +call mklink-b login ..\ +copy ..\build-b.ban n.bat +call n +cd .. + diff --git a/src/kernel/build.ban b/src/kernel/build.ban new file mode 100755 index 00000000..a1368824 --- /dev/null +++ b/src/kernel/build.ban @@ -0,0 +1,280 @@ +rem build cmx + +copy ..\cmx\io64180.inc + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ ..\cmx\cmx_init +@if errorlevel 1 goto failure +del cmx_init.r01 +as-z80 -l -o cmx_init.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ ..\cmx\cxver5 +@if errorlevel 1 goto failure +del cxver5.r01 +as-z80 -l -o cxver5.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ ..\cmx\cmxio3 +@if errorlevel 1 goto failure +del cmxio3.r01 +as-z80 -l -o cmxio3.s01 +@if errorlevel 1 goto failure + +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ ..\cmx\cmxbug +rem @if errorlevel 1 goto failure +rem del cmxbug.r01 +rem as-z80 -l -o cmxbug.s01 +rem @if errorlevel 1 goto failure + +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ ..\cmx\cmxtrack +rem @if errorlevel 1 goto failure +rem del cmxtrack.r01 +rem as-z80 -l -o cmxtrack.s01 +rem @if errorlevel 1 goto failure + +rem copy ..\cmx\bstartup.asm bstartup.s01 +rem as-z80 -l -o bstartup.s01 +rem @if errorlevel 1 goto failure + +copy ..\cmx\cxskv5b.asm cxskv5b.s01 +as-z80 -l -o cxskv5b.s01 +@if errorlevel 1 goto failure + +copy ..\cmx\cmxintb.asm cmxintb.s01 +as-z80 -l -o cmxintb.s01 +@if errorlevel 1 goto failure + +copy ..\cmx\asci.asm asci.s01 +as-z80 -l -o asci.s01 +@if errorlevel 1 goto failure + +copy ..\cmx\escc.asm escc.s01 +as-z80 -l -o escc.s01 +@if errorlevel 1 goto failure + +copy ..\cmx\apibus.asm apibus.s01 +as-z80 -l -o apibus.s01 +@if errorlevel 1 goto failure + +copy ..\cmx\copyr.asm copyr.s01 +as-z80 -l -o copyr.s01 +@if errorlevel 1 goto failure + +copy ..\cmx\diag.asm diag.s01 +as-z80 -l -o diag.s01 +@if errorlevel 1 goto failure + +rem build uzi + +copy ..\uzi\asmdef.inc +copy ..\uzi\z180.inc + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\main +@if errorlevel 1 goto failure +del main.r01 +as-z80 -l -o main.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\data +@if errorlevel 1 goto failure +del data.r01 +as-z80 -l -o data.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devflop +@if errorlevel 1 goto failure +del devflop.r01 +as-z80 -l -o devflop.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devhd +@if errorlevel 1 goto failure +del devhd.r01 +as-z80 -l -o devhd.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devio +@if errorlevel 1 goto failure +del devio.r01 +as-z80 -l -o devio.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devmisc +@if errorlevel 1 goto failure +del devmisc.r01 +as-z80 -l -o devmisc.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\devtty +@if errorlevel 1 goto failure +del devtty.r01 +as-z80 -l -o devtty.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\filesys +@if errorlevel 1 goto failure +del filesys.r01 +as-z80 -l -o filesys.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\machdep +@if errorlevel 1 goto failure +del machdep.r01 +as-z80 -l -o machdep.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\process +@if errorlevel 1 goto failure +del process.r01 +as-z80 -l -o process.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\scall1 +@if errorlevel 1 goto failure +del scall1.r01 +as-z80 -l -o scall1.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\scall2 +@if errorlevel 1 goto failure +del scall2.r01 +as-z80 -l -o scall2.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\scall3 +@if errorlevel 1 goto failure +del scall3.r01 +as-z80 -l -o scall3.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\systrace +@if errorlevel 1 goto failure +del systrace.r01 +as-z80 -l -o systrace.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -I..\uzi\ -I..\libc\ -DDEBUG=1 ..\uzi\xip +@if errorlevel 1 goto failure +del xip.r01 +as-z80 -l -o xip.s01 +@if errorlevel 1 goto failure + +copy ..\uzi\flopasm.asm flopasm.s01 +as-z80 -l -o flopasm.s01 +@if errorlevel 1 goto failure + +copy ..\uzi\machasm.asm machasm.s01 +as-z80 -l -o machasm.s01 +@if errorlevel 1 goto failure + +copy ..\uzi\procasm.asm procasm.s01 +as-z80 -l -o procasm.s01 +@if errorlevel 1 goto failure + +copy ..\uzi\utils.asm utils.s01 +as-z80 -l -o utils.s01 +@if errorlevel 1 goto failure + +rem build libc + +copy ..\libc\c0k.asm c0k.s01 +as-z80 -l -o c0k.s01 +@if errorlevel 1 goto failure + +copy ..\libc\_exit.asm _exit.s01 +as-z80 -l -o _exit.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\kprintf +@if errorlevel 1 goto failure +del kprintf.r01 +as-z80 -l -o kprintf.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\vfprintf +@if errorlevel 1 goto failure +del vfprintf.r01 +as-z80 -l -o vfprintf.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\itoa +@if errorlevel 1 goto failure +del itoa.r01 +as-z80 -l -o itoa.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\ltoa +@if errorlevel 1 goto failure +del ltoa.r01 +as-z80 -l -o ltoa.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\ultoa +@if errorlevel 1 goto failure +del ultoa.r01 +as-z80 -l -o ultoa.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\strlen +@if errorlevel 1 goto failure +del strlen.r01 +as-z80 -l -o strlen.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\strcat +@if errorlevel 1 goto failure +del strcat.r01 +as-z80 -l -o strcat.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\strcpy +@if errorlevel 1 goto failure +del strcpy.r01 +as-z80 -l -o strcpy.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\strncmp +@if errorlevel 1 goto failure +del strncmp.r01 +as-z80 -l -o strncmp.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\memcpy +@if errorlevel 1 goto failure +del memcpy.r01 +as-z80 -l -o memcpy.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\abort +@if errorlevel 1 goto failure +del abort.r01 +as-z80 -l -o abort.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\cmx\ -DDEBUG=1 ..\libc\exit +@if errorlevel 1 goto failure +del exit.r01 +as-z80 -l -o exit.s01 +@if errorlevel 1 goto failure + +rem link everything + +link-z80 -f kernel +@if errorlevel 1 goto failure +ihex2bin -l kernel.i86 ..\..\..\bin\kernel.bin +@if errorlevel 1 goto failure + +copy ..\..\..\bin\kernel.bin \nlddl +set country=NLD +crc +copy \nlddl\checksum ..\..\..\bin + +copy \nlddl\checksum \\darkstar\public\dos622\nlddl +copy \nlddl\kernel.bin \\darkstar\public\dos622\nlddl + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/kernel/cmx/apibus.asm b/src/kernel/cmx/apibus.asm new file mode 100755 index 00000000..0583ec08 --- /dev/null +++ b/src/kernel/cmx/apibus.asm @@ -0,0 +1,557 @@ +; apibus.asm +; Interrupt driven driver for communications with/via the WPO controller + +; ----------------------------------------------------------------------------- + +$ io64180.inc + + extern _sdevs + extern _K_OS_Intrp_Entry + extern _K_OS_Intrp_Exit + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern abyte + +ADIV equ 1;3 ; clocked serial i/o rate (power of 2, higher = slower) +ADVMAX equ 9 ; number of api bus devices (controls round robin alg.) + +XMIT_SIZE equ 256 ; must match cxfuncs.h, size of transmitter buffer +RECV_SIZE equ 256 ; must match cxfuncs.h, size of reciever buffer + +; must match cxfuncs.h, fields in SDEV structure: ** ASSUMES 3 BYTE CODE PTRS! +axmit equ 0 ; offset of embedded CMX XMIT structure +atxcnt equ axmit+4 ; CMX name is 'word16 bytes_in' +arecv equ 13 ; offset of embedded CMX RECV structure +arxcnt equ arecv+4 ; CMX name is 'word16 bytes_out' +aport equ 13+13 +atxvec equ 13+13+1 ; called by interrupt, returns l=chr +arxvec equ 13+13+4 ; called by interrupt, passed c=chr +;smsvec equ 13+13+7 ; called by interrupt, passed c=bits +;sesvec equ 13+13+10 ; called by interrupt, passed c=bits +;stevec equ 13+13+13 ; vector to start asci/escc transmitter +;stdvec equ 13+13+16 ; vector to stop asci/escc transmitter +;sstat equ 13+13+19 ; address to read status (8530 02xxh) +;stxdr equ 13+13+20 ; address to write tx data (8530 02xxh) +;srxdr equ 13+13+21 ; address to read rx data (8530 02xxh) +;swr1 equ 13+13+22 ; wr1 contents (interrupt enable bits) +;swr5 equ 13+13+23 ; wr5 contents (modem control outputs) +;swr15 equ 13+13+24 ; wr15 contents (modem control int ena) +;sinint equ 13+13+25 ; says whether wr1 really reflects wr1! +sdvlen equ 13+13+26 ; byte size of block per serial port + +; ----------------------------------------------------------------------------- + + rseg CODE + + public _apibus_setup + +_apibus_setup:: + push bc + push de + + ld a,1 + di + ld (arobin),a + ld (arxovr),a + + in0 a,(ITC) + or INT1SW + out0 (ITC),a + ei + + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + rseg RCODE + + public _int1_vector + +_int1_vector:: + .if 1 + call _K_OS_Intrp_Entry + .else + push af + push bc + push de + push hl + push iy + .endif + + .if 1 + ld hl,LWRD aint1 + ld a,BYTE3 aint1 + call ?BANK_CALL_DIRECT_L08 + .else + call aint1 + .endif + + .if 1 + call _K_OS_Intrp_Exit + .else + pop iy + pop hl + pop de + pop bc + pop af + ei + ret + .endif + + public _csio_vector + +_csio_vector:: + .if 1 + call _K_OS_Intrp_Entry + .else + push af + push bc + push de + push hl + push iy + .endif + + .if 1 + ld hl,LWRD acsint + ld a,BYTE3 acsint + call ?BANK_CALL_DIRECT_L08 + .else + call acsint + .endif + + .if 1 + call _K_OS_Intrp_Exit + .else + pop iy + pop hl + pop de + pop bc + pop af + ei + ret + .endif + +; ----------------------------------------------------------------------------- + + rseg CODE + +public aint1 + +aint1: sub a + ld (astate),a + +public acsint + +acsint: + .if 1 + in0 a,(ITC) + and .binnot.INT1SW + out0 (ITC),a ; disable further INT1 interrupts + + in0 a,(CNTR) + and 10111111b + out0 (CNTR),a ; disable further CSI/O interrupts + + ei + .endif + + .if 0 + push iy + .endif + + ld hl,astate + ld a,(hl) + dec a + jp z,LWRD astat1 + dec a + jr z,astat2 + dec a + jr z,astat3 + dec a + jp z,LWRD astat4 + dec a + jp z,LWRD astat5 + dec a + jp z,LWRD astat6 + dec a + jp z,LWRD astat7 + +astat0: ; start sending address command + .if 1 ; this should be reinstated when we desire reboot control + ld a,(_abflag) + or a + jp nz,LWRD acstx ; jr nz,acmdtx ; reboot command + .endif + + ld hl,astate + ld (hl),1 ; set astate = 1 + + ld a,(adirn) + rrca + jr c,aadrrx + +aadrtx: + ;ld a,2 + ;ld (arobin),a + ld a,(arobin) ; address select +; call abyte + jp LWRD acstx ; send address command + +aadrrx: sub a ; address enquiry +; call abyte + jp LWRD acstx ; send address command + + .if 0 ; this should be reinstated when we desire reboot control +acmdtx: + ; it's not working for some reason... but the abyte does come out! + call abyte + out (TRDR),a ; send command byte provided by client + + ld a,10h+ADIV ; csi/o master, divisor, te=1, eie=0 + jp LWRD acstmr ; jr acstmr + .endif + +;astat1: ; start receiving address response +; inc (hl) ; set astate = 2 +; jr acsrx + +astat2: ; received address response, inspect + inc (hl) ; set astate = 3 + + in0 a,(TRDR) +; ld e,a +; or 80h +; call abyte +; ld a,e + or a ; selected some device? + jp z,LWRD acsnul ; no device available, go and flip dir + + ld (adevok),a + +astat3: ; start sending data size command + inc (hl) ; set astate = 4 + + ld a,(adevok) + call LWRD aindex ; iy -> _sdevs+(a+3)*sdvlen + + ld a,(adirn) + rrca + jr c,adirrx + +adirtx: ; ask to transmit anything waiting + ld l,(iy+atxcnt) + ld h,(iy+atxcnt+1) ; hl = bytes waiting to be sent + + ld a,l ; a = bytes waiting to be sent + ld de,80h + or a + sbc hl,de + jr c,$+4 + ld a,7fh ; a = maximum possible transfer count + + ld (acount),a ; save data size for transfer +; call abyte + jp LWRD acstx ; send data size command + +adirrx: ; ask to receive anything waiting + ld e,(iy+arxcnt) + ld d,(iy+arxcnt+1) + .if 1 + ld hl,RECV_SIZE + .else + ld l,(iy+arxsiz) + ld h,(iy+arxsiz+1) + .endif + or a + sbc hl,de ; hl = available rx buffer bytes + + ld a,l ; a = available rx buffer bytes + ld de,80h + or a + sbc hl,de + jr c,$+4 + ld a,7fh ; a = maximum possible transfer count + + or e ; say we want to receive + ld (acount),a ; save data size for transfer +; call abyte + jp LWRD acstx ; send data size command + +astat1: ; start receiving address response +astat4: ; start receiving data size response + inc (hl) ; set astate = 5 + + .if 1 ; 01oct02 ensures ef gets reset to 0 (we don't really need to access + ; trdr when changing from sending to receiving, except to reset ef!!) + in0 a,(TRDR) + .endif + jr acsrx + +astat5: ; received data size response, start transfer + inc (hl) ; set astate = 6 + + in0 a,(TRDR) +; call abyte +;;; or a +;;; ld e,90h+1 ; because wpov1.asm, etc, have only $10 bytes receive buffer +;;; jp m,bumx +;;; ld e,40h+1 ; because wpov1.asm, etc, have only $40 bytes transmit buffer +;;;bumx: +;;; cp e +;;; jr c,bumxx ; our crude heuristic says it's a valid data size response +;;; ld e,a +;;; ld a,'$' +;;; call abyte +;;; ld a,e +;;;bumxx: + ld hl,acount + xor (hl) ; test for wrong direction of response + jp m,LWRD areset + xor (hl) ; restore original data size response +; ld e,a +; ld a,(adevok) +; cp 7 +; ld a,e +; call z,abyte + cp (hl) + jr nc,$+3 + ld (hl),a ; acount = lower of our max / slave max + + ld a,(hl) +; call abyte + and 7fh ; test for null transfer + jr z,acsnul ; yes, go and flip direction + xor (hl) ; test transfer direction + jp m,LWRD acstst ; we need to receive, start + + ld hl,astate + inc (hl) + jp LWRD astat7 ; jr astat7 ; we need to transmit, start + +astat6: ; received data byte + .if 1 + ld a,(adevok) ;2 + call LWRD aindex ; iy -> _sdevs+(a+3)*sdvlen + + in0 c,(TRDR) ; c = 2nd parameter (byte) + push iy + pop de ; de = 1st parameter (word16) + + ld l,(iy+arxvec) + ld h,(iy+arxvec+1) + ld a,(iy+arxvec+2) + call LWRD ?BANK_CALL_DIRECT_L08 + .else + wcalld ainput ; process received data byte + .endif + +acstst: ld hl,acount + dec (hl) ; say we received 1 byte + jp p,LWRD acsrdn ; if there is no more to receive + +acsrx: ; 01oct02 please ensure that ef has been reset to 0 before entering + .if 0 ; try this 21mar01 + ld a,ADIV + out0 (CNTR),a ; csi/o master, ef=0, eie=0 + + in0 a,(ITC) + and .binnot.INT1SW ; maskoff INT1SW + out0 (ITC),a ; disable int1, in case it is still on + + ei + ld b,40h + djnz $ ; delay for 4433 to load 1 data byte + di + .endif + .if 1 ; 16oct02 now back in again, tests indicate we need it. (latest wpo) + ; 16oct02 trying this out... fingers crossed... please test old wpo!! + ld b,40h ;10h + djnz $ ; delay for 4433 to load 1 data byte + .endif + + ld a,60h+ADIV ; csi/o master, divisor, re=1, eie=1 + jp LWRD acstmr ; jr acstmr + +acsrdn: ld hl,astate + ld (hl),3 ; start new data size command + jp LWRD astat3 ; immediately + +acsnul: sub a + ld (adirn),a ; assume we will transmit + + ld a,(arobin) + ld c,a + ld b,ADVMAX ; 20mar02 ;8;ADVMAX + ; this will need to be revisited, and done based on rom version + +ascan: inc c + ld a,c + cp ADVMAX+1 ; 20mar02 ;8+1;ADVMAX+1 ; gone past maximum device? + jr c,$+4 + ld c,1 ; wrap output device + + ld a,c + call LWRD aindex ; iy -> _sdevs+(a+3)*sdvlen + + ld a,(iy+atxcnt) + or (iy+atxcnt+1) ; more data to transmit? + jr nz,akick ; we will transmit, start immediately + + ;inc c + ;ld a,c + ;cp ADVMAX+1 ; gone past maximum device? + ;jr c,$+4 + ;ld c,1 ; wrap output device + + djnz ascan +; ld a,80h +; call abyte + jr acsflp ; nothing to output, go and receive + +akick: ld a,c + ld (arobin),a ; set the found output device +; or 80h +; call abyte + + .if 0 + ld l,16 + ld de,500 ; delay ?? + call timer0 ; request a kick up the bum + .endif + + ld hl,arxovr + dec (hl) + jr nz,areset ; forced receive every so often + +acsflp: ld hl,arxovr + ld (hl),10h ; set time to next rx override + + ld hl,adirn + inc (hl) ; no data to send, we will receive + +areset: ld a,00h+ADIV ; csi/o master, divisor + .if 1 + di + .endif + out0 (CNTR),a ; no more csi/o needed for now + + sub a + ld (astate),a ; start with address command + + in0 a,(ITC) + or INT1SW + out0 (ITC),a ; enable int1 to start next poll + jr acsret + +astat7: ; start sending data byte + ld a,(adevok) + call LWRD aindex ; iy -> _sdevs+(a+3)*sdvlen + .if 1 + push iy + pop de ; de = 1st parameter (word16) + + ld l,(iy+atxvec) + ld h,(iy+atxvec+1) + ld a,(iy+atxvec+2) + call LWRD ?BANK_CALL_DIRECT_L08 + + ld a,l ; if h = 0ffh, should ignore, but don't + .else + call atxget ; read a = 1 byte from tx queue + .endif +; call abyte + +; ld e,a +;; sub a +;; out (cntlb0),a ; 115200 +; ld a,(adevok) +; cp 7 ;2 +; ld a,e +; call z,abyte + + ld hl,acount + dec (hl) ; say we transmitted 1 byte + jr nz,acstx ; if there is more to send + + ld hl,astate + ld (hl),3 ; say we will send new data size cmd + +acstx: ; 01oct02 no special ef precautions, as this trdr access clears ef: +; ld e,a +; sub a +; out (cntlb0),a ; 115200 +; ld a,e +; call abyte ; to see all transmissions, including data size response, etc + out0 (TRDR),a + + ld a,50h+ADIV ; csi/o master, divisor, te=1, eie=1 +acstmr: + .if 0 ; 16oct02 trying this out... probably safe, no need to test old wpo!! + ld b,0 ; 03oct02 ;40h ;10h + djnz $ ; delay for 4433 to load 1 data byte + .endif + .if 1 + di + .endif + out0 (CNTR),a + + .if 0 ; not necessary now that it's done at ACSINT + in0 a,(ITC) + and .binnot.INT1SW ; maskoff INT1SW + out0 (ITC),a ; disable int1, poll in progress + .endif + +acsret: + .if 0 + pop iy + .endif + .if 0 ; try this 01aug01 + ld bc,ac8530 + ld a,3 ; select rr3 + out0 (c),a + nop + in0 a,(c) + ret z ; 8530 not interrupting + push af + push bc + jp int2e + .else + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + .endif + +; ----------------------------------------------------------------------------- + +public aindex + +aindex: ld e,a + ld d,sdvlen + mlt de + + ld iy,_sdevs+3*sdvlen + add iy,de ; iy -> _sdevs+(a+3)*sdvlen + ret + +; ----------------------------------------------------------------------------- + + rseg UDATA0 + +acount: defs 1 +astate: defs 1 +adirn: defs 1 +arobin: defs 1 +arxovr: defs 1 +adevok: defs 1 + + public _abflag + +_abflag: defs 1 ; client must set this = 0aah to reboot + +; ----------------------------------------------------------------------------- + + END diff --git a/src/kernel/cmx/asci.asm b/src/kernel/cmx/asci.asm new file mode 100755 index 00000000..efa48c37 --- /dev/null +++ b/src/kernel/cmx/asci.asm @@ -0,0 +1,473 @@ +; asci.asm +; Interrupt driven serial driver for built in Z180 ports (Hytech CMX) + +; ----------------------------------------------------------------------------- + +$ io64180.inc + + extern _sdevs + extern _K_OS_Intrp_Entry + extern _K_OS_Intrp_Exit + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern abyte + +XMIT_SIZE equ 256 ; must match cxfuncs.h, size of transmitter buffer +RECV_SIZE equ 256 ; must match cxfuncs.h, size of reciever buffer + +; must match cxfuncs.h, fields in SDEV structure: ** ASSUMES 3 BYTE CODE PTRS! +sxmit equ 0 ; offset of embedded CMX XMIT structure +srecv equ 13 ; offset of embedded CMX RECV structure +sport equ 13+13 +stxvec equ 13+13+1 ; called by interrupt, returns l=chr +srxvec equ 13+13+4 ; called by interrupt, passed c=chr +smsvec equ 13+13+7 ; called by interrupt, passed c=bits +sesvec equ 13+13+10 ; called by interrupt, passed c=bits +stevec equ 13+13+13 ; vector to start asci/escc transmitter +stdvec equ 13+13+16 ; vector to stop asci/escc transmitter +sstat equ 13+13+19 ; address to read status (8530 02xxh) +stxdr equ 13+13+20 ; address to write tx data (8530 02xxh) +srxdr equ 13+13+21 ; address to read rx data (8530 02xxh) +swr1 equ 13+13+22 ; wr1 contents (interrupt enable bits) +swr5 equ 13+13+23 ; wr5 contents (modem control outputs) +swr15 equ 13+13+24 ; wr15 contents (modem control int ena) +sinint equ 13+13+25 ; says whether wr1 really reflects wr1! +sdvlen equ 13+13+26 ; byte size of block per serial port + +; ----------------------------------------------------------------------------- + + rseg CODE + + public _asci0_setup + +_asci0_setup:: +; push bc +; push de + + ld iy,_sdevs+0*sdvlen + ld (iy+sstat),STAT0 + ld (iy+stxdr),TDR0 + ld (iy+srxdr),RDR0 + ld (iy+stevec),.low._asci_tx_enable + ld (iy+stevec+1),.high._asci_tx_enable + ld (iy+stevec+2),BYTE3 _asci_tx_enable + + .if 0 ; now done by gboot.s01 + ld a,01110100b + out0 (CNTLA0),a ; enables, rts off, d8 pn s1, tend0 + ;sub a ; 115200 bps @ 18.432 MHz (ps = 0) + ;ld a,20h ; 38400 bps @ 18.432 MHz (ps = 1) + ld a,22h ; 9600 bps @ 18.432 MHz (ps = 1) + out0 (CNTLB0),a + .endif + + ld a,1000b + out (STAT0),a ; rx int enabled, tx int disabled + ld (iy+swr1),a ; set up shadow for ssrte, ssrtd + +; pop de +; pop bc + jp ?BANK_FAST_LEAVE_L08 + + public _asci1_setup + +_asci1_setup:: +; push bc +; push de + + ld iy,_sdevs+1*sdvlen + ld (iy+sstat),STAT1 + ld (iy+stxdr),TDR1 + ld (iy+srxdr),RDR1 + ld (iy+stevec),.low._asci_tx_enable + ld (iy+stevec+1),.high._asci_tx_enable + ld (iy+stevec+2),BYTE3 _asci_tx_enable + + .if 0 ; now done by gboot.s01 + ld a,01110100b + out0 (CNTLA1),a ; enables, rts off, d8 pn s1, tend0 + ;sub a ; 115200 bps @ 18.432 MHz (ps = 0) + ;ld a,20h ; 38400 bps @ 18.432 MHz (ps = 1) + ld a,22h ; 9600 bps @ 18.432 MHz (ps = 1) + out0 (CNTLB1),a + .endif + + ld a,1000b + out (STAT1),a ; transmit interrupts disabled + ld (iy+swr1),a ; set up shadow for ssrte, ssrtd + +; pop de +; pop bc +; ret + jp ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + public _asci_tx_enable + +_asci_tx_enable:: + push bc + push de + +; ld iy,_sdevs+0*sdvlen + push de + pop iy + di + .if 1 + ld hl,LWRD ssrte + ld a,BYTE3 ssrte + call ?BANK_CALL_DIRECT_L08 + .else + call ssrte + .endif + ei + + pop de + pop bc +; ret + jp ?BANK_FAST_LEAVE_L08 + + public _asci_tx_disable + +_asci_tx_disable:: + push bc + push de + +; ld iy,_sdevs+0*sdvlen + push de + pop iy + di + .if 1 + ld hl,LWRD ssrtd + ld a,BYTE3 ssrtd + call ?BANK_CALL_DIRECT_L08 + .else + call ssrtd + .endif + ei + + pop de + pop bc +; ret + jp ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + rseg RCODE + + public _asci0_vector + +_asci0_vector:: + .if 1 + call _K_OS_Intrp_Entry + .else + push af + push bc + push de + push hl + push iy + .endif + + ld iy,_sdevs+0*sdvlen + + .if 1 + inc (iy+sinint) + ld a,(_sdevs+0*sdvlen+swr1) ;(iy+swr1) + and 11110110b ; disable both tx and rx ints + out0 (STAT0),a + ei ; allow other interrupts to occur + .endif + + .if 1 + ld hl,LWRD si01 + ld a,BYTE3 si01 + call ?BANK_CALL_DIRECT_L08 + .else + call si01 + .endif + + .if 1 + di ; prevent ints occurring immediately + dec (iy+sinint) + ld a,(_sdevs+0*sdvlen+swr1) ;(iy+swr1) + out0 (STAT0),a ; re-enable tx and rx ints if needed + .endif + + .if 1 + call _K_OS_Intrp_Exit + .else + pop iy + pop hl + pop de + pop bc + pop af + ei + ret + .endif + + public _asci1_vector + +_asci1_vector:: + .if 1 + call _K_OS_Intrp_Entry + .else + push af + push bc + push de + push hl + push iy + .endif + + ld iy,_sdevs+1*sdvlen + + .if 1 + inc (iy+sinint) + ld a,(_sdevs+1*sdvlen+swr1) ;(iy+swr1) + and 11110110b ; disable both tx and rx ints + out0 (STAT1),a + ei ; allow other interrupts to occur + .endif + + .if 1 + ld hl,LWRD si01 + ld a,BYTE3 si01 + call ?BANK_CALL_DIRECT_L08 + .else + call si01 + .endif + + .if 1 + di ; prevent ints occurring immediately + dec (iy+sinint) + ld a,(_sdevs+1*sdvlen+swr1) ;(iy+swr1) + out0 (STAT1),a ; re-enable tx and rx ints if needed + .endif + + .if 1 + call _K_OS_Intrp_Exit + .else + pop iy + pop hl + pop de + pop bc + pop af + ei + ret + .endif + +; ----------------------------------------------------------------------------- + + rseg CODE + +si01: ; initial status read + ld c,(iy+sstat) + ld b,0 ;(iy+sbase) + in a,(c) + + ; test for receiver error + tst 01110000b ; ovrn, pe, fe + jr z,si01l0 + + ; receiver error, reset it + res 2,c + in a,(c) + and 11110111b ; reset efr + out (c),a + + set 2,c + in a,(c) ; repeat status read + +si01l0: ; test for receiver ready + tst 10000000b + jr z,si01l2 + +si01l1: ; receiver is ready, process 1 char + ld c,(iy+srxdr) + .if 1 + .if 0 ; SDCC + in a,(c) + + push af + inc sp + push iy + call _K_Update_Recv + inc sp + inc sp + inc sp + .else ; IAR + in c,(c) ; c = 2nd parameter (byte) + push iy + pop de ; de = 1st parameter (word16) + +; call _K_Update_Recv +; ld a,BYTE3 _K_Update_Recv +; ld hl,LWRD _K_Update_Recv + ld l,(iy+srxvec) + ld h,(iy+srxvec+1) + ld a,(iy+srxvec+2) + call LWRD ?BANK_CALL_DIRECT_L08 + .endif + .else + in e,(c) + + .if 0 + ld c,(iy+srxvec) + ld b,(iy+srxvec+1) + call 0eb53h ; winved + .else + call srxdft ; ignore the cf return for now + .endif + .endif + + ld c,(iy+sstat) + ld b,0 ;(iy+sbase) + in a,(c) ; repeat status read + tst 10000000b ; receiver ready again? + jr nz,si01l1 ; go and receive a second char + +si01l2: ; test for transmitter ready + and 00000010b + .if 1 + jp z,?BANK_FAST_LEAVE_L08 ; transmitter not ready + .else + ret z ; transmitter not ready + .endif + + bit 0,(iy+swr1) ; transmit interrupt enabled? + .if 1 + jp z,?BANK_FAST_LEAVE_L08 ; transmitter not ready + .else + ret z ; no, ignore transmitter ready status + .endif + +si01l3: ; transmitter is ready, process 1 char + .if 1 + .if 0 ; SDCC + push iy + call _K_Update_Xmit + inc sp + inc sp + jr c,ssrtd ; serial status register tx disable + .else ; IAR + push iy + pop de ; de = 1st parameter (word16) + +; call _K_Update_Xmit +; ld a,BYTE3 _K_Update_Xmit +; ld hl,LWRD _K_Update_Xmit + ld l,(iy+stxvec) + ld h,(iy+stxvec+1) + ld a,(iy+stxvec+2) + call LWRD ?BANK_CALL_DIRECT_L08 + + inc h ; sets zf if hl was 0ffffh + jr z,ssrtd ; serial status register tx disable + .endif + + ld c,(iy+stxdr) + ld b,0 ;(iy+sbase) + out (c),l ; client has provided char for tx + .else + .if 0 + ld c,(iy+stxvec) + ld b,(iy+stxvec+1) + call 0eb53h ; winved + .else + call stxdft + .endif + jr c,ssrtd ; serial status register tx disable + + ld c,(iy+stxdr) + ld b,0 ;(iy+sbase) + out (c),e ; client has provided char for tx + .endif + + ld c,(iy+sstat) + in a,(c) ; repeat status read + and 00000010b ; transmitter ready again? + .if 1 + jp z,?BANK_FAST_LEAVE_L08 ; transmitter not ready + .else + ret z ; transmitter not ready + .endif + + jr si01l3 ; go and transmit a second char + +; ----------------------------------------------------------------------------- +; utility subroutines for use by our clients - z180 ports (serial 0/1) + +ssrte: ; serial status register transmit enable - enter with di +;if nick0 ; new addition 17sep02 to implement inter-byte delay on s0dev @ 2400 % +; bit 2,(iy+sadlc) ; inter-byte delay enabled? (s0dev) +; jr nz,ssrtd ; yes, ensure tx int is always disabled +;endif ; % + ; new addition 07mar02 trying to fix double chars / corruption s0dev % + bit 0,(iy+swr1) + .if 1 + jp nz,?BANK_FAST_LEAVE_L08 ; transmit interrupt already enabled + .else + ret nz ; transmit interrupt already enabled + .endif + ; % + ;ld a,(iy+sdev) + ;cp s1dev + ;ld a,'e' + ;call z,abyte + ld e,1 +ssrsb: ; serial status register set bits - enter with di + ld c,(iy+sstat) + ld b,0 ;(iy+sbase) + ld a,e + or (iy+swr1) + .if 1 + ld e,a + ld a,(iy+sinint) + or a + jr nz,ssrsb0 + out (c),e +ssrsb0: ld (iy+swr1),e + .else + out (c),a + ld (iy+swr1),a + .endif + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +ssrtd: ; serial status register transmit disable - enter with di +; ; new addition 07mar02 trying to fix double chars / corruption s0dev % +; bit 0,(iy+swr1) +; ret z ; transmit interrupt already disabled +; ; % + ;ld a,(iy+sdev) + ;cp s1dev + ;ld a,'d' + ;call z,abyte + ld e,0feh +ssrrb: ; serial status register reset bits - enter with di + ld c,(iy+sstat) + ld b,0 ;(iy+sbase) + ld a,e + and (iy+swr1) + .if 1 + ld e,a + ld a,(iy+sinint) + or a + jr nz,ssrrb0 + out (c),e +ssrrb0: ld (iy+swr1),e + .else + out (c),a + ld (iy+swr1),a + .endif + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +; ----------------------------------------------------------------------------- + + END diff --git a/src/kernel/cmx/bstartup.asm b/src/kernel/cmx/bstartup.asm new file mode 100755 index 00000000..7f036a88 --- /dev/null +++ b/src/kernel/cmx/bstartup.asm @@ -0,0 +1,442 @@ +; bstartup.asm + +; +; $Id: Cstartup.s01 1.24 2001/01/04 12:19:06 IPEO Exp $ +; + +;----------------------------------------------------------; +; ; +; CSTARTUP.S01 ; +; ; +; This file contains the Z80/HD64180 C startup routine ; +; and must usually be tailored to suit customer's hardware.; +; ; +; Version: 4.00 [ 28/Apr/94 IJAR] ; +;----------------------------------------------------------; + +;#define banking 1 + +; Nick #define proc64180 ((__TID__&0x010)==0x010) + +$ io64180.inc + + NAME CSTARTUP + + extern _main + extern _int1_vector + extern _int2_vector + extern _timer0_vector + extern _csio_vector + extern _asci0_vector + extern _asci1_vector + extern abyte + extern copyr + +; EXTERN main ; where to begin execution + EXTERN ?C_EXIT ; where to go when program is done + +;#ifdef banking +;#if 0 ; Nick proc64180 +; +;CBAR_addr EQU 3AH ; define I/O ports to MMU registers +;CBR_addr EQU 38H ; (See also defines in debug.s01 and l08.s01) +; +; EXTERN CBAR_value +; EXTERN CBR_value +;#endif + + EXTERN ?BANK_CALL_DIRECT_L08 +;#endif + +;---------------------------------------------------------------; +; Forward declarations of segment used during initialization ; +;---------------------------------------------------------------; + + COMMON INTVEC + RSEG RCODE + RSEG CONST + RSEG CSTR + RSEG CDATA0 + RSEG CCSTR + RSEG DATA0 + RSEG IDATA0 + RSEG UDATA0 + RSEG ECSTR + RSEG TEMP + RSEG WCSTR + +;---------------------------------------------------------------; +; CSTACK - The C stack segment ; +; ; +; Please, see in the link file lnk*.xcl how to increment ; +; the stack size without having to reassemble cstartup.s01 ! ; +;---------------------------------------------------------------; + + RSEG CSTACK + DEFS 0 ; a bare minimum ! + +; ----------------------------------------------------------------------------- + +; ASEG +; ORG 0 +; +;init_A +; JP init_C + +;---------------------------------------------------------------; +; RCODE - where the execution actually begins ; +;---------------------------------------------------------------; + RSEG RCODE +;init_C +init:: + .if 1 + di ; for boot.bin this is redundant + .endif + + .if 1 + ld a,'A' + call abyte+4000h + .endif + + .if 0 ; now done by boot.bin before entering + ld a,4-8 ;0 also works, see gboot.s01 at label virtual_init + out0 (CBR),a ; CA1 = logical 8000 = abs 0:4000 + + ;; Stack at the top of logical memory. + ld sp,0 ; abs 1:0000 is just beyond stack top + .endif + + ld de,0 ; destination address + ld hl,.SFB.CDATA0+4000h ; ending source address + ld bc,4000h ; starting source address + call copy_mem+4000h ; copy RCODE, etc from bank area to CA0 + + jp silly +silly: ; and start executing in the new spot + + ld a,.low.vector_table + out0 (IL),a ; set interrupt vectors low byte + ld a,.high.vector_table + ld i,a ; set interrupt vectors high byte + + in0 a,(CBR) + ld (_os_bank),a ; for the CMX scheduler, and others + + .if 1 + ei ; now got a stack and interrupt vectors + .endif + +; LD SP,(.SFE.CSTACK)-1 ; from high to low address + +;---------------------------------------------------------------; +; If hardware must be initiated from assembly or if interrupts ; +; should be on when reaching main, this is the place to insert ; +; such code. ; +;---------------------------------------------------------------; + +;#ifdef banking +;#if 0 ; Nick proc64180 +; +;;---------------------------------------------------------------; +;; Setting of MMU registers - see chapter "Linking" of manual. ; +;;---------------------------------------------------------------; +; +; LD A,CBAR_value ; set CBAR value +; OUT0 (CBAR_addr),A +; +; LD A,CBR_value ; set CBR value +; OUT0 (CBR_addr),A +; +;#endif +;#endif + +;---------------------------------------------------------------; +; If it is not a requirement that static/global data is set ; +; to zero or to some explicit value at startup, the following ; +; line refering to seg_init can be deleted, or commented. ; +;---------------------------------------------------------------; + + CALL seg_init + + .if 1 + ld e,.high._rom_serial_no + ld d,0 + + ld a,(_os_bank) ; CBR value for kernel data segment + ld l,a + ld h,d ;0 + + add hl,hl + add hl,hl + add hl,hl + add hl,hl ; convert to absolute base address + add hl,de ; adjust for dest, carry into segment + + ld e,h ; e = segment no. for copy destination + ld h,l + ld l,.low._rom_serial_no ; e:hl -> copy dest (in kernel data) + + ld iy,0fc81h + ;ld d,0 ; d:iy -> copy source (in EPROM) + + ld bc,5 + call copyr + +; not necessary as this will have been zeroed by seg_init (it's in UDATA0): +; sub a +; ld (_rom_sn+5),a + .endif + + .if 1 + ld a,'B' + call abyte + .endif + + .if 1 +; now there are the next stack structure: +; +4 envp +; +2 argv +; sp-> +0 argc + ld ix, 0 + add ix, sp + ld l, (ix+4) + ld h, (ix+5) + ld (_environ),hl + ld c, (ix+2) + ld b, (ix+3) +; ld (__argv),bc ; 1st argument to main + ld e, (ix+0) + ld d, (ix+1) +; ld (__argc),de ; 2nd argument to main + .endif + +;#ifdef banking + LD HL,LWRD(_main) ; banked call to _main() + LD A,BYTE3(_main) + CALL ?BANK_CALL_DIRECT_L08 +;#else +; CALL _main ; non-banked call to _main() +;#endif + +;---------------------------------------------------------------; +; Now when we are ready with our C program we must perform a ; +; system-dependent action. In this case we just stop. ; +;---------------------------------------------------------------; +; DO NOT CHANGE THE NEXT LINE OF CSTARTUP IF YOU WANT TO RUN ; +; YOUR SOFTWARE WITH THE HELP OF THE C-SPY HLL DEBUGGER. ; +;---------------------------------------------------------------; + + JP ?C_EXIT + +;---------------------------------------------------------------; +; Copy initialized PROMmed code to shadow RAM and clear ; +; uninitialized variables. ; +;---------------------------------------------------------------; + +seg_init: + +;---------------------------------------; +; Zero out UDATA0 ; +;---------------------------------------; + LD HL,.SFE.UDATA0 + LD DE,.SFB.UDATA0 + CALL zero_mem + +;---------------------------------------; +; Copy CDATA0 into IDATA0 ; +;---------------------------------------; + LD DE,.SFB.IDATA0 ; destination address + LD HL,.SFE.CDATA0+4000h ; really 8:0000 + .SFE.(CDATA0) + LD BC,.SFB.CDATA0+4000h ; really 8:0000 + .SFB.(CDATA0) + CALL copy_mem + +;---------------------------------------; +; Copy CCSTR into ECSTR ; +;---------------------------------------; + LD DE,.SFB.ECSTR ; destination address + LD HL,.SFE.CCSTR+4000h ; really 8:0000 + .SFE.(CCSTR) + LD BC,.SFB.CCSTR+4000h ; really 8:0000 + .SFB.(CCSTR) + + ; Just fall in to the copy_mem function + +;---------------------------------------; +; Copy memory ; +;---------------------------------------; +copy_mem: + XOR A + SBC HL,BC + PUSH BC + LD C,L + LD B,H ; BC - that many bytes + POP HL ; source address + RET Z ; If block size = 0 return now + LDIR + RET + +;---------------------------------------; +; Clear memory ; +;---------------------------------------; +zero_mem: + XOR A +again: + PUSH HL + SBC HL,DE + POP HL + RET Z + LD (DE),A + INC DE + JR again + +; Nick has added read/write data here (must be in RCODE) + + public _os_bank + +_os_bank: defb 0 ; the CBR value for CMX/UZI data seg + +; Nick has added read/write data here (doesn't need to be in RCODE) + + rseg UDATA0 + + public _rom_serial_no + +_rom_serial_no: defs 6 ; for c:\uzi\kernel\main.c (hostname) + +;---------------------------------------------------------------; +; Interrupt vectors must be inserted here by the user. ; +;---------------------------------------------------------------; + + COMMON INTVEC + +common_start:: + jp init+4000h ; +4000h because we're not loaded yet + + org common_start+0x08 + ei + ret + org common_start+0x10 + ei + ret + org common_start+0x18 + ei + ret + org common_start+0x20 + ei + ret + org common_start+0x28 + ei + ret + org common_start+0x30 + ei + ret + org common_start+0x38 + ei + ret + + org common_start+0x40 + + public vector_table + +vector_table:: + defw _int1_vector + defw _int2_vector + defw _timer0_vector + defw _timer1_vector + defw _dma0_vector + defw _dma1_vector + defw _csio_vector + defw _asci0_vector + defw _asci1_vector + + public _timer1_vector + +_timer1_vector:: + + public _dma0_vector + +_dma0_vector:: + + public _dma1_vector + +_dma1_vector:: + ei + ret + +; ----------------------------------------------------------------------------- + +; variables added by Nick (see above in this file, and ..\libc\cstartup.s01) + + public _environ + ;public __argc, __argv, _environ, _errno, ___cleanup + + rseg UDATA0 +;__argc: defs 2 +;__argv: defs 2 +_environ: defs 2 +;errno: defs 2 +;___cleanup: defs 2 + + ENDMOD ;common_start ;init_A + +;---------------------------------------------------------------; +; Function/module: exit (int code) ; +; ; +; When C-SPY is used this code will automatically be replaced ; +; by a 'debug' version of exit(). ; +;---------------------------------------------------------------; + MODULE exit + + extern abyte, ahexw, amess, acrlf + + PUBLIC abort + PUBLIC ?C_ABORT + + PUBLIC exit + PUBLIC ?C_EXIT + + RSEG RCODE + +?C_ABORT: +abort EQU ?C_ABORT + +; ld de,1 ; abort() is equivalent to exit(1); + +?C_EXIT: +exit EQU ?C_EXIT + +;--------------------------------------------------------------; +; The next line can be replaced by user defined code. ; +;--------------------------------------------------------------; + .if 1 ; new interface to apibus.mac for reboot control + extern _abflag + + call amess + defb 'kernel: rebooting: exitcode ',0 + ex de,hl + call ahexw + call acrlf + + ld hl,0 + ; wait for last character to be sent @ 9600 +reboot_delay: + dec hl + ld a,l + or h + jr nz,reboot_delay + + ld a,0aah + ld (_abflag),a + + ei + .else + .if 1 ; diagnostic indication that program was exited + ld a,'X' + call abyte + .else + NOP + .endif + .endif + JR $ ; loop forever + +; ----------------------------------------------------------------------------- + + END diff --git a/src/kernel/cmx/cmx_init.c b/src/kernel/cmx/cmx_init.c new file mode 100755 index 00000000..c252162a --- /dev/null +++ b/src/kernel/cmx/cmx_init.c @@ -0,0 +1,658 @@ +/********************************************************* + +Copyright (c) CMX Company. 1999. All rights reserved + +*********************************************************/ +/* version 5.30, adds the following: +1. counting semaphores +2. priority inversion on resources +3. highest priority task waiting on resource, is the one + that will get resource when it is released. +4. new int_pipe routine +*/ + +#define CMX_INIT_MODULE +#define CMXMODULE + +#include /* get 64180 io configuration file */ +#include /* get cmx include header file */ +#include "cxconfig.h" /* get user configuration file */ + +#define TDRE 0x02 /* transmitter can be loaded with next char. */ +#define RDRF 0x80 /* data available at receive buffer. */ + + +#if CMXTRACKER_ENABLE > 0 +#include /* get cmx include header file */ +#endif + +#if C_PIPE_SIZE < 1 || C_PIPE_SIZE > 255 +#error: C_PIPE_SIZE must be between 1 and 255 +#endif + +#if C_MAX_MESSAGES > 0 +#define CMX_MAX_MESSAGES (C_MAX_MESSAGES + 2) +#endif + + +#if CMXBUG_ENABLE > 0 || CMXTRACKER_ENABLE > 0 +#define CC_TASK_STK_SIZE (C_TASK_STK_SIZE + 256) +#else +#define CC_TASK_STK_SIZE C_TASK_STK_SIZE +#endif + +#if CMXBUG_ENABLE > 0 && CMXTRACKER_ENABLE > 0 /* Nick */ +#define CC_MAX_TASKS (C_MAX_TASKS + 2) /* Nick */ +#else /* Nick */ +#if CMXBUG_ENABLE > 0 || CMXTRACKER_ENABLE > 0 +#define CC_MAX_TASKS (C_MAX_TASKS + 1) +#else +#define CC_MAX_TASKS C_MAX_TASKS +#endif +#endif /* Nick */ + +/*********************************************************** + WARNING: these are assumed to be initailized by the "C" compiler + start up code. Also all non-initialized CMX variables are assumed + to be zeroed out by the "C" compiler startup code. This is normally + done. If NOT, then the user must set the CMX_RAM_INIT define to 1. + See cxconfig.h (or equivalent file). +***********************************************************/ + +byte MAX_TASKS = CC_MAX_TASKS; +byte MAX_RESOURCES = C_MAX_RESOURCES; +byte MAX_CYCLIC_TIMERS = C_MAX_CYCLIC_TIMERS; +byte MAX_MAILBOXES = C_MAX_MAILBOXES; +byte MAX_QUEUES = C_MAX_QUEUES; +byte RTC_SCALE = C_RTC_SCALE; +byte MAX_SEMAPHORES = C_MAX_SEMAPHORES; +byte TSLICE_SCALE = C_TSLICE_SCALE; + +/******************************************************* + The following sets up the necessary memory needed by CMX +*******************************************************/ + +/****************************************************** + The cxvendor.h header file will actually add additional + CMX variables to ONLY this file. See that header file. +********************************************************/ + +struct _tcb cmx_tcb[CC_MAX_TASKS+1]; + +#if C_MAX_CYCLIC_TIMERS > 0 + +CYCLIC_TIMERS tcproc[C_MAX_CYCLIC_TIMERS]; + +#else + +byte tcproc[1]; + +#endif + + +#if C_MAX_RESOURCES > 0 + +RESHDR res_que[C_MAX_RESOURCES]; + +#else + +byte res_que[1]; + +#endif + +#if C_MAX_MAILBOXES > 0 + +MAILBOX mail_box[C_MAX_MAILBOXES]; + +#else + +byte mail_box[1]; + +#endif + +#if C_MAX_MESSAGES > 0 + +MSG message_box[CMX_MAX_MESSAGES]; + +#else + +byte message_box[1]; + +#endif + + +#if C_MAX_QUEUES > 0 + +QUEHDR queue[C_MAX_QUEUES]; + +#else + +byte queue[1]; + +#endif + +#if C_MAX_SEMAPHORES > 0 + +SEM sem_array[C_MAX_SEMAPHORES]; + +#else + +byte sem_array[1]; + +#endif + +struct { + word16 stack_space[CC_TASK_STK_SIZE / 2]; + word16 dummy; + } stack_storage; +word16 *stack_blk; + +struct { + word16 interrupt_bytes[C_INTERRUPT_SIZE / 2]; + word16 dummy; + } int_storage; +word16 *interrupt_stack; +word16 *stack_holder; + +CYCLIC_LNK cyclic_buf; +CYCLIC_LNK *cyclic_lnk; +TSK_TIMER_LNK *tsk_timer_lnk; +TSK_TIMER_LNK tsk_timer_buf; +MSG *message_ptr; +word16 message_free; + +byte tslice_count; +byte SLICE_ON; + +tcbpointer activetcb; +byte active_priority; +tcbpointer timertask; +byte rtc_count; + +PIPE_STRUC *out_ptr; + +PIPE_STRUC pipe[C_PIPE_SIZE]; + + +#if CMX_RAM_INIT > 0 +static void clear_ram(void *,word16); +static void init_cmx_variables(void); +#endif + +#if CMXTRACKER_ENABLE > 0 +byte CMXTRACKER_ACTIVE; +byte CMXTRACKER_ON; +struct _tcb *previoustcb; +extern byte cmxtracker_slot; +extern void cmxtracker(void); +extern void cmxtracker_mode(byte,word16); +extern word16 cmxtracker_ctr; +extern byte *cmxtracker_in_ptr; +extern word16 num_records; +void init_cmxtracker(void); +byte cmxtracker_array[CMXTRACKER_SIZE]; +#define LOG_DISPLAY_LEN 18 +word16 rec_cnt[((sizeof (cmxtracker_array) / 4) / LOG_DISPLAY_LEN) + 2]; +byte K_Track_Getchr(byte *ptr); /* Nick */ +void K_Track_Putchr(char); /* Nick */ +#endif + +#if CMXBUG_ENABLE > 0 +extern byte cmxbug_slot; +extern void cmxbug(void); +byte CMXBUG_ACTIVE; +byte K_Bug_Getchr(byte *ptr); /* Nick */ +void K_Bug_Putchr(char); /* Nick */ +#endif + +#if CMXBUG_ENABLE > 0 || CMXTRACKER_ENABLE > 0 +long stat_array[CC_MAX_TASKS+1]; +char *task_name[CC_MAX_TASKS + 1]; +byte BUG_WAIT_TICKS; +void setup_bug(void); +/* Nick byte K_Bug_Getchr(byte *ptr); */ +/* Nick void K_Bug_Putchr(char); */ +#else +char *task_name[1]; +#endif + +word32 cmx_tick_count; /* total number of CMX system ticks accumulated */ + +void K_OS_Init(void) +{ + MSG *link; /* scratch pointer */ + + /* abyte('I'); */ + + locked_out = 1; /* set lock so it will never goto K_I_Scheduler */ + cmx_tick_count = 0; /* reset CMX long counter */ + +#if CMX_RAM_INIT > 0 /* Should we initialize CMX variables */ + init_cmx_variables(); +#endif + +#if C_MAX_MESSAGES > 0 + link = message_box; /* address of 1st block */ + message_free = CMX_MAX_MESSAGES; /* use pipe_max to hold count */ + while (message_free--) + { + message_ptr = link; /* point head at 1st block */ + link++; /* compute addr of next block */ + message_ptr->env_link = link; /* create link to it */ + } + message_ptr->env_link = message_box; /* last link in chain is null */ + message_ptr = message_box; /* point head at 1st block */ + message_free = CMX_MAX_MESSAGES-2; +#endif + /* abyte('J'); */ + + in_ctr = out_ctr = cmx_flag1 = 0; + /* set up interrupt pipe. */ + pipe_slots_avail = C_PIPE_SIZE; + + cyclic_lnk = &cyclic_buf; /* set up cyclic timers time link. */ + cyclic_lnk->ftlink = cyclic_lnk->btlink = (struct _tcproc *)cyclic_lnk; + tsk_timer_lnk = &tsk_timer_buf; /* set up task timer link. */ + tsk_timer_lnk->ftlink = tsk_timer_lnk->btlink = (tcbpointer)tsk_timer_lnk; + + /* now set up stack block to release memory to task's stacks as + they are created. Also interrupt stack if used. */ + stack_blk = &stack_storage.dummy; + interrupt_stack = &int_storage.dummy; + activetcb = timertask = cmx_tcb; /* dummy tcb */ + timertask->nxttcb = cmx_tcb; /* set up link. */ + /* abyte('K'); */ + +#if CMXBUG_ENABLE > 0 || CMXTRACKER_ENABLE > 0 + setup_bug(); + BUG_WAIT_TICKS = 10; /* Number of system ticks to wait, before checking + to see if the + (plus key) has been received + by UART. */ +#endif + /* abyte('L'); */ + + RTC_SCALE = C_RTC_SCALE; /* number of timer ticks, before running + CMX task timer if needed. */ + rtc_count = C_RTC_SCALE; /* number of timer ticks, before running + CMX task timer if needed. */ + TSLICE_SCALE = C_TSLICE_SCALE; + /* abyte('M'); */ +} /* K_OS_Init */ + +#if CMX_RAM_INIT > 0 +static void init_cmx_variables(void) +{ + MAX_TASKS = CC_MAX_TASKS; + MAX_RESOURCES = C_MAX_RESOURCES; + MAX_CYCLIC_TIMERS = C_MAX_CYCLIC_TIMERS; + MAX_MAILBOXES = C_MAX_MAILBOXES; + MAX_QUEUES = C_MAX_QUEUES; + MAX_SEMAPHORES = C_MAX_SEMAPHORES; + clear_ram(cmx_tcb,sizeof cmx_tcb); + clear_ram(&stack_storage.stack_space[0],sizeof stack_storage); + +#if C_MAX_CYCLIC_TIMERS > 0 + clear_ram(tcproc,sizeof tcproc); +#endif + +#if C_MAX_RESOURCES > 0 + clear_ram(res_que,sizeof res_que); +#endif + +#if C_MAX_MAILBOXES > 0 + clear_ram(mail_box,sizeof mail_box); +#endif + +#if C_MAX_MESSAGES > 0 + clear_ram(message_box,sizeof message_box); +#endif + +#if C_MAX_QUEUES > 0 + clear_ram(queue,sizeof queue); +#endif + +#if C_MAX_SEMAPHORES > 0 + clear_ram(sem_array,sizeof sem_array); +#endif + +} + +static void clear_ram(void *addr_ptr,word16 size) +{ + byte *crap_ptr; + crap_ptr = addr_ptr; + while(size--) + { + *crap_ptr++ = 0; + } +} +#endif + +#if CMXBUG_ENABLE > 0 || CMXTRACKER_ENABLE > 0 + +void setup_bug(void) +{ + /* Do NOT change the "cmxbug_slot" or "cmxbug", for + CMXBug expects these names. You could change the priority + or stack size if need be, but we highly suggest you do not. */ + +#if CMXBUG_ENABLE > 0 + K_Task_Create(1,&cmxbug_slot,cmxbug,256); /* create CMXBug task */ + K_Task_Name(cmxbug_slot,"CMXBug"); /* Name for task */ + K_Task_Start(cmxbug_slot); /* start CMXBug task */ +#endif /* Nick #else */ +#if CMXTRACKER_ENABLE > 0 /* Nick */ + K_Task_Create(1,&cmxtracker_slot,cmxtracker,256); /* create CMXTracker task */ + K_Task_Name(cmxtracker_slot,"CMXTracker"); /* Name for task */ + K_Task_Start(cmxtracker_slot); /* start CMXBug task */ + init_cmxtracker(); + /* now done by gboot.s01 CNTLA1 = 0x74; /* Nick */ + /* now done by gboot.s01 CNTLB1 = 0x00; /* Nick */ +#endif + /* now done by gboot.s01 CNTLA0 = 0x74; /* RTS0=1 KEEPS US ALIVE 0x64; /* 8 bits, no parity, enable transmitter and receiver */ + /* now done by gboot.s01 CNTLB0 = 0x00; /* 115200 0x02; /* 9600 baud Xtal = 12.288 MHz */ + /* this must be a mistake as TDRE is not writeable STAT0 |= 0x02; */ +} + +#if CMXTRACKER_ENABLE > 0 +void init_cmxtracker(void) +{ + num_records = 0; + cmxtracker_in_ptr = cmxtracker_array; + cmxtracker_ctr = sizeof (cmxtracker_array); +} +#endif + +#if CMXBUG_ENABLE > 0 /* Nick */ +byte K_Bug_Getchr(byte *ptr) +{ + return 0; /* Nick temporary (don't clobber the cognitive printer) */ + if ( STAT0 & RDRF ) + { + *ptr = RDR0 & 0x7F; + return(1); + } + else + return(0); +} + +void K_Bug_Putchr(byte c) +{ + return; /* Nick temporary (don't clobber the cognitive printer) */ + while (!(STAT0 & TDRE)) + ; + TDR0 = c; +} +#endif /* Nick */ + +#if CMXTRACKER_ENABLE > 0 /* Nick */ +byte K_Track_Getchr(byte *ptr) +{ + return 0; /* Nick temporary (don't clobber the cognitive printer) */ + if ( STAT1 & RDRF ) + { + *ptr = RDR1 & 0x7F; + return(1); + } + else + return(0); +} + +void K_Track_Putchr(byte c) +{ + return; /* Nick temporary (don't clobber the cognitive printer) */ + while (!(STAT1 & TDRE)) + ; + TDR1 = c; +} +#endif /* Nick */ + +#endif + +byte K_I_Intrp_Pipe_In(byte a, byte b, byte c, word16 d, void *mesg) +{ + PIPE_STRUC *in_ptr; + +#if CMXTRACKER_ENABLE > 0 + if ((!(TEST_CMX_ACTIVE)) || (CMXTRACKER_ACTIVE)) + return(K_ERROR); +#else + if (!(TEST_CMX_ACTIVE)) + return(K_ERROR); +#endif + PROC_SAVE_INT; /* disable interrupts */ + if (pipe_slots_avail) + { + in_ptr = &pipe[in_ctr]; + --pipe_slots_avail; + if (++in_ctr == C_PIPE_SIZE) + in_ctr = 0; + PROC_RESTORE_INT; /* enable interrupts */ + DO_INT_PIPE; /* Set the do interrupt pipe flag. */ + in_ptr->identifier = a; + in_ptr->p1 = b; + switch(a) { + case 5: + case 6: + in_ptr->pipe_u.p3 = d; + break; + case 7: + in_ptr->pipe_u.p4 = mesg; + break; + case 8: + in_ptr->p2 = c; + in_ptr->pipe_u.p3 = d; + break; + } + return(K_OK); + } + else + { + PROC_RESTORE_INT; /* enable interrupts */ + return(K_ERROR); + } +} + +/********************************************************************* + The following function executes the functions that the interrupts + place into the interrupt pipe. called only by CMX K_I_Scheduler. +*********************************************************************/ +void K_I_Intrp_Pipe_Out(void) +{ + byte parm1; + byte parm2; + + while(1) + { +#if CMXTRACKER_ENABLE + if (!CMXTRACKER_ACTIVE) + { + cmxtracker_in1(INT_ACTION); + } +#endif + out_ptr = &pipe[out_ctr]; + switch (out_ptr->identifier) { + case 0: + K_Task_Wake(out_ptr->p1); + break; + case 1: + K_Task_Wake_Force(out_ptr->p1); + break; + case 2: + K_Task_Start(out_ptr->p1); + break; + case 3: + K_Timer_Stop(out_ptr->p1); + break; + case 4: + K_Timer_Restart(out_ptr->p1); + break; + case 5: + parm1 = out_ptr->p1; + K_Timer_Initial(parm1,out_ptr->pipe_u.p3); + break; + case 6: + parm1 = out_ptr->p1; + K_Timer_Cyclic(parm1,out_ptr->pipe_u.p3); + break; + case 7: + parm1 = out_ptr->p1; + K_Mesg_Send(parm1,out_ptr->pipe_u.p4); + break; + case 8: + parm1 = out_ptr->p1; + parm2 = out_ptr->p2; + K_Event_Signal(parm1,parm2,out_ptr->pipe_u.p3); + break; + case 9: + K_Semaphore_Post(out_ptr->p1); + break; + default: + /* What should we do here, possibly reset pipe ? to be beginning */ + break; + } + PROC_DISABLE_INT; /* disable interrupts */ + pipe_slots_avail++; + if (++out_ctr == C_PIPE_SIZE) + out_ctr = 0; + if (out_ctr == in_ctr) + { + CLR_DO_INT_PIPE; /* no, reset do interrupt pipe flag. */ + break; /* exit. */ + } + PROC_ENABLE_INT; /* re-enable interrupts and process more. */ + } + PROC_ENABLE_INT; /* re-enable interrupts and exit. */ +} + +/****************************************************************** + K_OS_Tick_Update: Called from timer interrupt routine to signal that + the CMX task timer should execute if need be. + THIS CODE EXECUTES ONLY AT INTERRUPT LEVEL. +**********************************************************************/ +void K_OS_Tick_Update(void) +{ + /* abyte('D'); */ + + if (TEST_CMX_ACTIVE) /* see if CMX OS has been entered. */ + { + /* abyte('E'); */ + +#if CMXBUG_ENABLE > 0 + if (!CMXBUG_ACTIVE) + { + if (activetcb->tcbstate & RUNNING) + stat_array[(struct _tcb *)activetcb - cmx_tcb] += 1; + else + stat_array[0] += 1; + } +#endif + + cmx_tick_count++; /* increment long counter */ + +#if CMXTRACKER_ENABLE + if (!CMXTRACKER_ACTIVE) + { +#endif + /* abyte(' '); */ + /* ahexw(rtc_count | (word16)RTC_SCALE<<8); */ + /* abyte(' '); */ + + if (!(--rtc_count)) /* converts hardware tics to CMX delay tics */ + { + /* abyte('F'); */ + +#if CMXTRACKER_ENABLE + { + cmxtracker_in1(CMX_TIC_CALL); + } +#endif + + rtc_count = RTC_SCALE; /* reset counter with rtc prescaler */ + /* the following will see if a task timer needs servicing or + a cyclic timer needs servicing. */ + if ((tsk_timer_lnk->ftlink != (tcbpointer)tsk_timer_lnk) || + (cyclic_lnk->ftlink != (struct _tcproc *)cyclic_lnk)) + { + DO_TIMER_TSK; /* yes, set flag to indicate that CMX timer + task should execute. */ + } + } +#if CMXTRACKER_ENABLE + } +#endif + + if (TEST_SLICE_ENABLE) /* see if time slicing active. */ + { + /* abyte('G'); */ + + if (!(--tslice_count)) /* if so, decrement and test time slice + counter. */ + { + /* abyte('H'); */ + + DO_TIME_SLICE; /* set flag indicating time count expired. */ + SLICE_DISABLE; /* disable time slicing. */ + } + } + } + + /* abyte(' '); */ + /* ahexw(rtc_count | (word16)RTC_SCALE<<8); */ + /* abyte(' '); */ + /* abyte('I'); */ + +} /* K_OS_Tick_Update */ + +byte K_Task_Name(byte task_slot,char *name) +{ + tcbpointer tcbptr; + + if(K_I_Get_Ptr(task_slot,&tcbptr)) /* send address of pointer */ + return(K_ERROR); +#if CMXBUG_ENABLE > 0 || CMXTRACKER_ENABLE > 0 + task_name[task_slot] = name; +#else + task_name[0] = name; +#endif + return(K_OK); +} + +byte K_OS_Task_Slot_Get(void) +{ + return ((struct _tcb *)activetcb - cmx_tcb); +} + +word32 K_OS_Tick_Get_Ctr(void) +{ + return(cmx_tick_count); +} + +void K_I_Func_Return(void) +{ + /* this function will decrement the task block (lock) counter. + Also see if the interrupt count is 0 and if so, will + test to see any of the CMX 5 flags are set, which will then call + the K_I_Scheduler to invoke possibly a task switch */ + /* abyte('{'); */ + K_I_Enable_Sched(); + /* abyte('}'); */ +} + +/***************************************************************** + The following is the CPU reduced power function. The user + MUST write their own and they must ensure that the proceesor + returns to the caller, without modifying the stack. + + NOTE: the CMX K_I_Scheduler calls this function which is in the assembly + module supplied. The user may find it necessary to modify the + assembly file, so every thing is correct when the CPU + comes out of the reduced power state. ALSO the CPU must let + the interrupts wake it up, out of the reduced power state + so as the task's timers and cyclic timers may have their + time counters decremented if need be. +*****************************************************************/ +void K_OS_Low_Power_Func(void) +{ +} + diff --git a/src/kernel/cmx/cmxbug.c b/src/kernel/cmx/cmxbug.c new file mode 100755 index 00000000..02f4e258 --- /dev/null +++ b/src/kernel/cmx/cmxbug.c @@ -0,0 +1,1865 @@ +#define CMXMODULE 1 + +#include /* get cmx include header file */ +#include /* get cmx include header file */ +#include /* get string include header file */ + +#define LARGE 0 /* Nick */ + +#define MAX_MEM_DECIMAL 0x05 /* max decimal size */ +#define MAX_MEM_HEX 0x04 /* max hex size */ +static byte *from_ptr; +static byte *thru_ptr; +#define mem_size_ptr byte * + +#define MAX_FIELD_LENGTH 12 /* the maximum field length of any field */ +#define SCROLL_SIZE 18 + +#define WHAT_FUNCTION 0 +#define DUMP_TASK 1 +#define DUMP_RESOURCES 2 +#define DUMP_TIMERS 3 +#define DUMP_QUEUES 4 +#define DUMP_MAILBOXES 5 +#define DUMP_RAM 6 +#define DUMP_STACKS 7 +#define CHANGE_RTC_SCALE 8 +#define CHANGE_TSLICE_SCALE 9 +#define ENABLE_TIME_SLICING 10 +#define DELAY_TICK 11 +#define QUICK_TICK 12 +#define STATS 13 +#define STATS_RESET 14 +#define TASK_CTRL 15 +#define EXIT_BUG 99 + +#define WHAT_FUNCTION_PROMPT 00 /* 1 */ +#define DUMP_TASK_PROMPT WHAT_FUNCTION_PROMPT + 1 /* 1 */ +#define DUMP_RESOURCE_PROMPT DUMP_TASK_PROMPT + 1 /* 1 */ +#define DUMP_CYCLIC_PROMPT DUMP_RESOURCE_PROMPT + 1 /* 1 */ +#define DUMP_QUEUES_PROMPT DUMP_CYCLIC_PROMPT + 1 /* 1 */ +#define DUMP_MAILBOX_PROMPT DUMP_QUEUES_PROMPT + 1 /* 1 */ +#define DUMP_RAM_PROMPT DUMP_MAILBOX_PROMPT + 1 /* 2 */ +#define DUMP_STACK_PROMPT DUMP_RAM_PROMPT + 2 /* 1 */ +#define RTC_SCALE_PROMPT DUMP_STACK_PROMPT + 1 /* 2 */ +#define TSLICE_SCALE_PROMPT RTC_SCALE_PROMPT + 2 /* 2 */ +#define ENABLE_SLICE_PROMPT TSLICE_SCALE_PROMPT + 2 /* 2 */ +#define DELAY_TICK_PROMPT ENABLE_SLICE_PROMPT + 2 /* 1 */ +#define STATS_RESET_PROMPT DELAY_TICK_PROMPT + 1 /* 1 */ +#define TASK_CTRL_PROMPT STATS_RESET_PROMPT + 1 /* 6 */ +struct prompt { + char *word; + byte in_length; + /* we could possibly do the following + struct prompt *next_prompt; point to next message + struct prompt *pevious_prompt; point to next message + */ + }; + +/* prompt char., length of field */ +static /* Nick */ const struct prompt prpt_array [] = { + /* what function prompt */ + { " Enter Function? \n",0x02}, + /* task dump entry */ + { "\r\nTASK dump",0x03}, + { "\r\nRESOURCE dump",0x03}, + { "\r\nCYCLIC TIMERS dump",0x03}, + { "\r\nQUEUE dump",0x03}, + { "\r\nMAILBOX dump",0x03}, + { "\r\nRAM dump\r\nEnter beginning ADDRESS of memory or to exit? ",MAX_MEM_DECIMAL}, + { "\r\n\r\nEnter ending ADDRESS of memory? ",MAX_MEM_DECIMAL}, + { "\r\nSTACK dump",0x03}, + { "\r\nCurrent SYSTEM TICK SCALE = ",0x00}, + { "\r\nEnter new SYSTEM TICK SCALE or to leave as is ",0x03}, + { "\r\nCurrent TIME SLICE SCALE = ",0x00}, + { "\r\nEnter new TIME SLICE SCALE or to leave as is ",0x03}, + { "\r\nCurrent TIME SLICING = ",0x00}, + { "\r\nEnter Y/y or N/n to enable/disable TIME SLICING or to leave as is ",0x01}, + { "\r\nEnter the number of ticks to wait or to leave? ",0x05}, + { "\r\nEnter Y/y to reset TIME ANALYSIS array or to leave as is ",0x03}, + { "\r\n*** ADDITIONAL TASK functions ***",0x01}, + { "\r\nEnter 1 to START TASK",0x01}, + { "\r\nEnter 2 to STOP TASK",0x01}, + { "\r\nEnter 3 to WAKE TASK",0x01}, + { "\r\nEnter 9 to EXIT",0x01}, + { "\r\nYour choice? ",0x01}, + { "\r\nTASK START",0x03}, + { "\r\nTASK STOP",0x03}, + { "\r\nTASK WAKE",0x03} + }; + +/* keyboard flags */ +struct bug_keyflag { /* bit structure */ + bit_word16 buff_wait:1; + bit_word16 f_key:1; + bit_word16 e_key:1; + bit_word16 max_in_needed:1; + bit_word16 non_zero:1; + bit_word16 cont:1; + bit_word16 e_jmp:1; + bit_word16 input_func:1; + bit_word16 allow_hex:1; + bit_word16 echo_off:1; + bit_word16 loop:1; + bit_word16 scroll:1; + bit_word16 string:1; + bit_word16 string_allowed:1; + }; + +static struct bug_keyflag keyflags; +static byte key_pressed; /* byte for scan code of keypad 0x00 thru 0x0f */ +static byte num_chars_in; +static byte *in_char_ptr; +static byte max_chars_in; +static byte current_func; +static byte keys_in_buff[MAX_FIELD_LENGTH]; +static byte prompt_index; +static byte hex_byte; +static word32 hex_long; +static byte func_offset; +static byte input_index; +static const struct prompt *prpt_ptr; +static word32 total_ticks; +static byte prompt_out(void); +static void dump_task(void); +static void dump_resource(void); +static void dump_cyclic(void); +static void dump_queue(void); +static void dump_mailbox(void); +static void dump_memory_ram(void); +static void dump_stack(void); +static void change_rtc_scale(void); +static void change_tslice_scale(void); +static void enable_tslice(void); +static void delay_tick(void); +static void quick_tick(void); +static void stat_display(void); +static void stat_reset(void); +static void task_ctrl_func(void); +static void display_char(char); +static void zerofill(byte *); +static void clear_chars_in(void); +static void conv_hex(void); +static void putbyte(byte); /* output a number (decimal) */ +static void putpercent(byte,byte); /* output a number (decimal) */ +static void putword(word16); /* output a number (decimal) */ +static void putlong(word32); +static void common_prompt(void); +static void com1_prompt(void); +static void putstg(char *); +static void putname(char *s); +static void putspaces(byte); +static void putcrlf(void); +static void puthexbyte(byte); +static void puthexword(word16); +static void puthexlong(word32); +static void showstate(word16); +static const char nibs[] = "0123456789ABCDEF"; + +static RESHDR res_dummy[1]; + +/* non-statics */ +byte cmxbug_slot; +extern long stat_array[]; +extern byte CMXBUG_ACTIVE; +extern byte BUG_WAIT_TICKS; +extern char *task_name[]; +extern byte K_Bug_Getchr(byte *ptr); +extern void K_Bug_Putchr(byte); +void cmxbug(void); + + +void cmxbug(void) +{ + byte status; + + /* process */ + CMXBUG_ACTIVE = 0; + while(1) + { + if (!keyflags.cont) { + while(1) + { + status = K_Bug_Getchr(&key_pressed); + if (status) + break; + if (!CMXBUG_ACTIVE) + K_Task_Wait(BUG_WAIT_TICKS); + } + + if (!keyflags.string) + { + switch (key_pressed) { + case '+': + locked_out = 1; + CMXBUG_ACTIVE = 1; + keyflags.f_key = TRUE; + break; + + case '"': + if (!keyflags.non_zero && keyflags.string_allowed) + { + display_char(key_pressed); + max_chars_in = 12; + keyflags.string = TRUE; + } + break; + + case 'p': + case 'P': + if (keyflags.echo_off) + keyflags.echo_off = FALSE; + else + keyflags.echo_off = TRUE; + break; + + case '\r': + if (keyflags.scroll) + { + func_offset |= 0x80; + keyflags.e_key = TRUE; + keyflags.e_jmp = TRUE; + break; + } + if ((current_func == TASK_CTRL) && !keyflags.non_zero) + { + func_offset = 0x00; + keyflags.e_key = TRUE; + keyflags.e_jmp = TRUE; + break; + } + if (!keyflags.non_zero) + { + keyflags.f_key = TRUE; + break; + } + + if (!keyflags.max_in_needed) + { + if (num_chars_in > 0 || keyflags.input_func) + { + keyflags.e_key = TRUE; + } + } + else + { + if (num_chars_in == max_chars_in) + { + keyflags.e_key = TRUE; + keyflags.max_in_needed = FALSE; + } + } + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (num_chars_in < max_chars_in && !keyflags.input_func) + { + keyflags.non_zero = TRUE; + display_char(key_pressed); + *in_char_ptr++ = key_pressed & 0x0f; + num_chars_in++; + } + break; + case '*': + if (num_chars_in < max_chars_in &&!keyflags.input_func) + { + keyflags.non_zero = TRUE; + display_char(key_pressed); + hex_byte = key_pressed; + keyflags.e_jmp = TRUE; + func_offset |= 0x80; /* set done entry flag */ + num_chars_in++; + } + break; + + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + if (!keyflags.allow_hex) + break; + if (num_chars_in < max_chars_in &&!keyflags.input_func) + { + keyflags.non_zero = TRUE; + display_char(key_pressed); + *in_char_ptr++ = ((key_pressed & 0x0f) + 0x09); + num_chars_in++; + } + break; + + case 'X': + case 'x': + if (!keyflags.non_zero) + { + display_char('x'); + keyflags.allow_hex = TRUE; + if (max_chars_in == MAX_MEM_DECIMAL) + max_chars_in = MAX_MEM_HEX; + } + break; + + case 'Y': + case 'y': + hex_byte = 1; + keyflags.e_jmp = TRUE; + keyflags.e_key = TRUE; + K_Bug_Putchr('Y'); + func_offset |= 0x80; /* set done entry flag */ + break; + + case 'N': + case 'n': + hex_byte = 0; + keyflags.e_jmp = TRUE; + keyflags.e_key = TRUE; + K_Bug_Putchr('N'); + func_offset |= 0x80; /* set done entry flag */ + break; + + default: + break; + } /* end of switch */ + } + else + { + if (key_pressed != '\r') + { + if (num_chars_in < max_chars_in) + { + keyflags.non_zero = TRUE; + display_char(key_pressed); + *in_char_ptr++ = key_pressed; + num_chars_in++; + } + } + else + { + func_offset |= 0x80; + keyflags.e_key = TRUE; + keyflags.e_jmp = TRUE; + } + } + } /* END OF KEYBOARD.CONT IF */ + + if (keyflags.cont) + { + keyflags.cont = FALSE; + keyflags.e_key = TRUE; + keyflags.e_jmp = TRUE; + func_offset = 0; + } + if (keyflags.f_key) + { + keyflags.f_key = FALSE; + keyflags.e_key = FALSE; + keyflags.e_jmp = FALSE; + keyflags.string = FALSE; + keyflags.string_allowed = FALSE; + keyflags.allow_hex = FALSE; + keyflags.scroll = FALSE; + keyflags.cont = FALSE; + keyflags.loop = FALSE; + keyflags.input_func = FALSE; + func_offset = 0; + current_func = WHAT_FUNCTION; + prompt_index = WHAT_FUNCTION_PROMPT; + keyflags.max_in_needed = FALSE; /* must have 2 characters in */ + /* clear all normal flags, etc. */ + clear_chars_in(); + max_chars_in = 2; + putstg("\r\nEnter 1 TASKS\r\n"); + putstg("Enter 2 RESOURCES\r\n"); + putstg("Enter 3 CYCLIC_TIMERS\r\n"); + putstg("Enter 4 QUEUES\r\n"); + putstg("Enter 5 MAILBOXES\r\n"); + putstg("Enter 6 RAM display\r\n"); + putstg("Enter 7 STACK information\r\n"); + putstg("Enter 8 SYSTEM TICK SCALE\r\n"); + putstg("Enter 9 TIME SLICE SCALE\r\n"); + putstg("Enter 10 TIME SLICING select\r\n"); + putstg("Enter 11 GO and RESUME CMXBug\r\n"); + putstg("Enter 12 Quick GO and RESUME CMXBug\r\n"); + putstg("Enter 13 TIME ANALYSIS\r\n"); + putstg("Enter 14 TIME ANALYSIS reset\r\n"); + putstg("Enter 15 ADDITIONAL TASK functions\r\n"); + putstg("Enter 99 EXIT CMXBug\r\n"); + putstg("Enter P/p to toggle ECHO mode, currently "); + if (!keyflags.echo_off) + { + putstg("ON"); + } + else + { + putstg("OFF"); + } + putstg("\r\nYour choice? "); + } + if (keyflags.e_key && CMXBUG_ACTIVE) + { + keyflags.e_key = FALSE; + if (!keyflags.e_jmp) + { + zerofill(&keys_in_buff[max_chars_in]); /* go zero fill, for proper entry */ + conv_hex(); /* go put characters into hex form, just 2 lsd */ + func_offset |= 0x80; /* set done entry flag */ + } + else + keyflags.e_jmp = FALSE; + if (current_func == WHAT_FUNCTION) + { + func_offset = 0; + current_func = hex_byte; + switch(current_func) { + case WHAT_FUNCTION: + break; + case DUMP_TASK: + break; + case DUMP_RESOURCES: + break; + case DUMP_TIMERS: + break; + case DUMP_QUEUES: + break; + case DUMP_MAILBOXES: + break; + case DUMP_RAM: + break; + case DUMP_STACKS: + break; + case CHANGE_RTC_SCALE: + break; + case CHANGE_TSLICE_SCALE: + break; + case ENABLE_TIME_SLICING: + break; + case QUICK_TICK: + break; + case DELAY_TICK: + break; + case STATS: + break; + case STATS_RESET: + break; + case TASK_CTRL: + break; + case EXIT_BUG: + break; + default: + current_func = WHAT_FUNCTION; + keyflags.f_key = TRUE; + putstg("\r\n\r\nInvalid entry, press any key to continue\r\n"); + break; + } + } + switch(current_func) { + case DUMP_TASK: + dump_task(); + break; + case DUMP_RESOURCES: + dump_resource(); + break; + case DUMP_TIMERS: + dump_cyclic(); + break; + case DUMP_QUEUES: + dump_queue(); + break; + case DUMP_MAILBOXES: + dump_mailbox(); + break; + case DUMP_RAM: + dump_memory_ram(); + break; + case DUMP_STACKS: + dump_stack(); + break; + case CHANGE_RTC_SCALE: + change_rtc_scale(); + break; + case CHANGE_TSLICE_SCALE: + change_tslice_scale(); + break; + case ENABLE_TIME_SLICING: + enable_tslice(); + break; + case QUICK_TICK: + quick_tick(); + break; + case DELAY_TICK: + delay_tick(); + break; + case STATS: + stat_display(); + break; + case STATS_RESET: + stat_reset(); + break; + case TASK_CTRL: + task_ctrl_func(); + break; + case EXIT_BUG: + locked_out = 0; + CMXBUG_ACTIVE = 0; + putstg("\r\n\r\n You have exited CMXBug(TM), press <+> (plus key) to enter CMXBug again!\r\n"); + break; + default: + break; + } /* end of switch */ + } /* end of e key brace */ + } /* end of endless while loop */ +} + +static void common_prompt(void) +{ + putstg(", enter number, '*' for all, to exit. Choice? "); +} + +static void com1_prompt(void) +{ + putstg(", enter SLOT #, \"TASK name, to exit. Choice? "); +} + + +static byte prompt_out(void) +{ + + prpt_ptr = &prpt_array[prompt_index + func_offset]; + /* chars_in(); */ + keyflags.non_zero = FALSE; + max_chars_in = prpt_ptr->in_length; + clear_chars_in(); + putstg(prpt_ptr->word); +} + +/* bit 7 of count will dictate whether we should increment/decrement + the source pointer */ + +static void zerofill(byte *mov_char_ptr) +{ + byte count; + byte *copy_in_char_ptr; + + if (num_chars_in != max_chars_in) + { + copy_in_char_ptr = in_char_ptr; + for (count = 0; count < num_chars_in; count++) + { + *(--mov_char_ptr) = *(--in_char_ptr); + } + for (count = num_chars_in; count < max_chars_in; count++) + { + *(--mov_char_ptr) = 0x00; + } + in_char_ptr = copy_in_char_ptr; + } +} + +static void conv_hex(void) +{ + + byte *hex_char_ptr; + word32 multiplier; + + multiplier = 1; + hex_long = 0; + if (max_chars_in == 1) + { + hex_char_ptr = keys_in_buff; + hex_byte = *hex_char_ptr; + hex_long = (word32)hex_byte; + } + else + { + hex_char_ptr = &keys_in_buff[max_chars_in-2]; + if (keyflags.allow_hex) + { + hex_byte = *hex_char_ptr * 16; + hex_char_ptr++; + hex_byte += *hex_char_ptr; + } + else + { + hex_byte = *hex_char_ptr * 10; + hex_char_ptr++; + hex_byte += *hex_char_ptr; + } + for (hex_char_ptr = &keys_in_buff[max_chars_in - 1]; + hex_char_ptr >= keys_in_buff; --hex_char_ptr) + { + hex_long += *hex_char_ptr * multiplier; + if (keyflags.allow_hex) + multiplier *= 16; + else + multiplier *= 10; + } + } + +} + +static void display_char(char x) +{ + if (!keyflags.echo_off) + K_Bug_Putchr(x); +} + +static void clear_chars_in(void) +{ + in_char_ptr = keys_in_buff; + do { + *in_char_ptr++ = 0; + } while (in_char_ptr != &keys_in_buff[sizeof keys_in_buff]); + in_char_ptr = keys_in_buff; + num_chars_in = 0; +} + +static void putword(word16 num) /* output a number (decimal) */ +{ + + byte digit,suppress; + word16 divisor; + divisor = 10000; + suppress = 1; + while( !( divisor == 1 )){ + digit = num / divisor; + num = num - (digit * divisor); + divisor = divisor / 10; + if( suppress && digit ) + suppress = 0; + if( !suppress ) + digit |= '0'; + else + digit = ' '; + K_Bug_Putchr(digit); + } + K_Bug_Putchr(num+'0'); +} + +static void putbyte(byte num) /* output a number (decimal) */ +{ + + byte digit,suppress; + byte divisor; + divisor = 100; + suppress = 1; + while( !( divisor == 1 )){ + digit = num / divisor; + num = num - (digit * divisor); + divisor = divisor / 10; + if( suppress && digit ) + suppress = 0; + if( !suppress ) + digit |= '0'; + else + digit = ' '; + K_Bug_Putchr(digit); + } + K_Bug_Putchr(num+'0'); +} + +static void putpercent(byte num,byte fill) /* output a number (decimal) */ +{ + + byte digit,suppress; + byte divisor; + divisor = 100; + suppress = 1; + while( !( divisor == 1 )){ + digit = num / divisor; + num = num - (digit * divisor); + if (divisor == 10 && fill) + suppress = 0; + divisor = divisor / 10; + if( suppress && digit ) + suppress = 0; + if( !suppress ) + digit |= '0'; + else + continue; + K_Bug_Putchr(digit); + } + K_Bug_Putchr(num+'0'); +} + +static void putlong(word32 num) /* output a number (decimal) */ +{ + word16 digit,suppress; + word32 divisor; + divisor = 1000000; + suppress = 1; + while( !( divisor == 1 )){ + digit = num / divisor; + num = num - (digit * divisor); + divisor = divisor / 10; + if( suppress && digit ) + suppress = 0; + if( !suppress ) + digit |= '0'; + else + digit = ' '; + K_Bug_Putchr(digit); + } + K_Bug_Putchr((char)('0'+num)); +} + +static void putstg(char *s) /* display null-terminated ASCII string thru serial port */ +{ + while (*s) + K_Bug_Putchr(*s++); +} + +static void putname(char *s) /* display null-terminated ASCII string thru serial port */ +{ + byte ctr; + + ctr = 0; + do { + if (*s) + K_Bug_Putchr(*s++); + else + K_Bug_Putchr(' '); + } while (++ctr < 13 ); +} + +static void putspaces(byte num) +{ + while (num--) + K_Bug_Putchr(' '); +} + + +static void putcrlf(void) +{ + K_Bug_Putchr(0x0d); + K_Bug_Putchr(0x0a); +} /* putcrlf */ + +static void puthexlong(word32 w) /* puts out long word in hex */ +{ + puthexbyte((byte)(w>>24)); + puthexbyte((byte)(w>>16)); + K_Bug_Putchr(':'); + puthexbyte((byte)(w>>8)); + puthexbyte((byte)(w & 0xff)); + putspaces(1); +} /* puthexlong */ + +static void puthexbyte(byte b) /* puts out byte in ASCII hex, to serial port */ +{ + K_Bug_Putchr(nibs[ b >> 4 ]); + K_Bug_Putchr(nibs[ b & 0x0F ]); +} /* puthexbyte */ + +static void puthexword(word16 w) +/* Put out word in hex, high byte first. */ +{ + puthexbyte((byte)(w>>8)); + puthexbyte((byte)(w & 0xff)); + putspaces(1); +} /* puthexword */ + + +static void showstate(word16 ts) +{ + + if (ts & RESOURCE) + putstg("resource "); + else if (ts & WAIT) + putstg("wait "); + else if (ts & SEND_MESG) + putstg("mesg_send"); + else if (ts & WAIT_MESG) + putstg("mesg_wait"); + else if (ts & FLAGS) + putstg("events "); + else if (ts & IDLE) + putstg("idle "); + else if (ts & READY) + putstg("ready "); + else if (ts & RESUME) + putstg("ready++ "); + else if (ts & RUNNING) + putstg("running "); + else + putstg("no create"); +} /* showstate */ + +static void dump_task(void) +{ + tcbpointer tcbptr; + + prompt_index = DUMP_TASK_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + common_prompt(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + /* if good */ + /* if all, set hex_byte to 2, because of bug task */ + if (!keyflags.scroll) + { + if (hex_byte == '*') + { + keyflags.loop = TRUE; + hex_byte = 1; + } + else + { + keyflags.loop = FALSE; + } + } + putcrlf(); + putstg("SLOT, NAME , State (time), Trig, Pri, TSK Addr, E-Flags, E-Match\r\n"); + while (1) + { + if (hex_byte <= MAX_TASKS) + { + /* abyte('('); */ + /* ahexw(keyflags.loop); */ + /* abyte(' '); */ + /* MUST change to relect slot number and name */ + tcbptr = &cmx_tcb[hex_byte]; + /* maybe change to decimal, later */ + putspaces(1); + putbyte(hex_byte); /* output task number */ + putspaces(1); + if (task_name[hex_byte]) + putname(task_name[hex_byte]); + else + putspaces(12); + putspaces(1); + showstate(tcbptr->tcbstate); + if (tcbptr->tcbstate & TIME) + { + putstg("("); + putword(tcbptr->tcbtimer); + putstg(")"); + } + else if ((tcbptr->tcbstate & TIME_EXPIRED) && ((activetcb - cmx_tcb) != hex_byte)) + { + putstg("( TIME)"); + } + else + putspaces(7); + putspaces(1); + putbyte(tcbptr->trig); + putspaces(3); + putbyte(tcbptr->priority); + putstg(" 0x"); +#if LARGE /* Nick ((sizeof(void (*)())) == 3) */ + puthexlong((word32)(tcbptr->task_addr)); /* TCB address */ +#else + puthexword((word16)(tcbptr->task_addr)); /* TCB address */ +#endif + putstg(" 0x"); + puthexword(tcbptr->e_flags); + putstg(" 0x"); + puthexword(tcbptr->e_match); + putcrlf(); + /* abyte(' '); */ + /* ahexw(keyflags.loop); */ + /* abyte(')'); */ + } + else + { + putstg("TASK Number out of range\r\n"); + keyflags.loop = FALSE; + } + /* abyte('\\'); */ + if (keyflags.loop) + { + /* abyte('_'); */ + /* ahexw(hex_byte | (word16)MAX_TASKS << 8); */ + /* abyte(' '); */ + if (++hex_byte > MAX_TASKS) + { + keyflags.scroll = FALSE; + break; + } +#if 0 + abyte('['); + ahexw(hex_byte % SCROLL_SIZE); + abyte(']'); +#else + else + { + if (hex_byte % SCROLL_SIZE == 0) + { + /* abyte('|'); */ + +#if 1 + keyflags.scroll = TRUE; + putstg("Enter to continue"); + return; +#endif + } + } +#endif + } + else + { + break; + } + } + keyflags.cont = TRUE; + break; + } +} + +static void dump_stack(void) +{ + tcbpointer tcbptr; + + prompt_index = DUMP_STACK_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + common_prompt(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + /* if good */ + /* if all, set hex_byte to 2, because of bug task */ + if (!keyflags.scroll) + { + if (hex_byte == '*') + { + keyflags.loop = TRUE; + hex_byte = 1; + } + else + { + keyflags.loop = FALSE; + } + } + putcrlf(); + putstg("SLOT, NAME , STACK Addr, MAX. bytes used SO FAR \r\n"); + while (1) + { + if (hex_byte <= MAX_TASKS) + { + /* MUST change to relect slot number and name */ + tcbptr = &cmx_tcb[hex_byte]; + /* maybe change to decimal, later */ + putspaces(1); + putbyte(hex_byte); /* output task number */ + putspaces(1); + if (task_name[hex_byte]) + putname(task_name[hex_byte]); + else + putspaces(12); + putspaces(1); + putstg(" 0x"); + if ((sizeof(char *)) == 4) + puthexlong((word32)(tcbptr->stk_start)); /* TCB address */ + else + puthexword((word16)(tcbptr->stk_start)); /* TCB address */ + putspaces(5); + putstg("Not Implemented"); +/* putword(stack_usage[hex_byte]); */ + putcrlf(); + } + else + { + putstg("TASK Number out of range\r\n"); + keyflags.loop = FALSE; + } + if (keyflags.loop) + { + if (++hex_byte > MAX_TASKS) + { + keyflags.scroll = FALSE; + break; + } + else + { + if (hex_byte % SCROLL_SIZE == 0) + { + keyflags.scroll = TRUE; + putstg("Enter to continue"); + return; + } + } + } + else + { + break; + } + } + keyflags.cont = TRUE; + break; + } +} + + +static void dump_resource(void) +{ + RESHDR *res_ptr; + RESHDR *link; /* forward wait link. */ + word16 ctr; + + prompt_index = DUMP_RESOURCE_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + common_prompt(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + if (hex_byte == '*') + { + keyflags.loop = TRUE; + hex_byte = 0; + } + else + { + keyflags.loop = FALSE; + } + putcrlf(); + putstg("RES #, Owner , Task(s) Waiting, MAX. 3 shown\r\n"); + while (1) + { + if (hex_byte < MAX_RESOURCES) + { + res_ptr = &res_que[hex_byte]; /* get address of resource */ + link = res_dummy; /* get address of dummy resource */ + /* now copy over, so we do NOT trash true resources que items. */ + link->fwlink = res_ptr->fwlink; + link->bwlink = res_ptr->bwlink; + link->owner = res_ptr->owner; + /* maybe change to decimal, later */ + putspaces(1); + putbyte(hex_byte); /* output task number */ + putspaces(1); + if (res_ptr->owner) + { + if (task_name[res_ptr->owner - cmx_tcb]) + putname(task_name[res_ptr->owner - cmx_tcb]); + else + putspaces(12); + putspaces(1); + ctr = 0; + while(1) + { + if (link->fwlink == (tcbpointer)res_ptr) + { + break; + } + if (ctr == 3) + { + putstg(", More..."); + break; + } + if (ctr) + putstg(", "); + if (task_name[link->fwlink - cmx_tcb]) + putname(task_name[link->fwlink - cmx_tcb]); + else + putspaces(12); + link->fwlink = link->fwlink->fwlink; + ctr++; + } + if (!ctr) + { + putstg("NONE"); + } + } + else + { + putstg("NONE NONE"); + } + putcrlf(); + } + else + { + putstg("RESOURCE Number out of range\r\n"); + keyflags.loop = FALSE; + } + if (keyflags.loop) + { + if (++hex_byte >= MAX_RESOURCES) + { + break; + } + } + else + { + break; + } + } + keyflags.cont = TRUE; + break; + } +} + +static void dump_cyclic(void) +{ + struct _tcproc *tpptr; + + prompt_index = DUMP_CYCLIC_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + common_prompt(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + if (hex_byte == '*') + { + keyflags.loop = TRUE; + hex_byte = 0; + } + else + { + keyflags.loop = FALSE; + } + putcrlf(); + putstg("TIMER #, Started?, Time left, CYCLIC Time, Mode , task/pri. , EVENT \r\n"); + while (1) + { + if (hex_byte < MAX_CYCLIC_TIMERS) + { + tpptr = &tcproc[hex_byte]; + /* maybe change to decimal, later */ + putspaces(3); + putbyte(hex_byte); /* output task number */ + putspaces(4); + if (tpptr->tproc_start) + putstg("YES "); + else + putstg("NO "); + putstg(" 0x"); + puthexword(tpptr->tproc_timer); + putstg(" 0x"); + puthexword(tpptr->reload_time); + putspaces(2); + switch(tpptr->mode) { + case 0: + putstg("Task number "); + if (task_name[tpptr->tskid_pri]) + putname(task_name[tpptr->tskid_pri]); + else + putspaces(12); + break; + case 1: + putstg("Top Pri task "); + putspaces(12); + break; + case 2: + putstg("Top Pri task waiting"); + putspaces(5); + break; + case 3: + putstg("ALL tasks "); + putspaces(12); + break; + case 4: + putstg("ALL tasks waiting"); + putspaces(8); + break; + case 5: + putstg("Same priority"); + putspaces(4); + putbyte(tpptr->tskid_pri); + putspaces(4); + break; + case 6: + putstg("Same Pri waiting"); + putspaces(1); + putbyte(tpptr->tskid_pri); + putspaces(4); + break; + default: + putstg("Illegal mode "); + putspaces(12); + break; + } + putstg(" 0x"); + puthexword(tpptr->event_num); + putcrlf(); + } + else + { + putstg("CYCLIC Number out of range\r\n"); + keyflags.loop = FALSE; + } + if (keyflags.loop) + { + if (++hex_byte >= MAX_CYCLIC_TIMERS) + { + break; + } + } + else + { + break; + } + } + keyflags.cont = TRUE; + break; + } +} + +static void dump_queue(void) +{ + QUEHDR *queue_ptr; + + prompt_index = DUMP_QUEUES_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + common_prompt(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + if (hex_byte == '*') + { + keyflags.loop = TRUE; + hex_byte = 0; + } + else + { + keyflags.loop = FALSE; + } + putcrlf(); + putstg("QUEUE #, Status , Max Slots , Slots Used, Slots free, Slot size, QUE. Addr \r\n"); + while (1) + { + if (hex_byte < MAX_QUEUES) + { + queue_ptr = &queue[hex_byte]; /* get address of proper queue handler. */ + /* maybe change to decimal, later */ + putspaces(3); + putbyte(hex_byte); /* output task number */ + putspaces(4); + if (!queue_ptr->num_slots) + putstg("NOT CREATED "); + else if (!queue_ptr->queue_cnt) + putstg("EMPTY "); + else if (queue_ptr->queue_cnt == queue_ptr->num_slots) + putstg("FULL "); + else + putstg("PARTIAL "); + putspaces(3); + putword(queue_ptr->num_slots); + putspaces(6); + putword(queue_ptr->queue_cnt); + putspaces(7); + putword(queue_ptr->num_slots - queue_ptr->queue_cnt); + putspaces(7); + putbyte(queue_ptr->size_slot); + putstg(" 0x"); + if ((sizeof(char *)) == 4) + puthexlong((word32)(queue_ptr->base_ptr)); /* TCB address */ + else + puthexword((word16)(queue_ptr->base_ptr)); /* TCB address */ + putcrlf(); + } + else + { + putstg("QUEUE Number out of range\r\n"); + keyflags.loop = FALSE; + } + if (keyflags.loop) + { + if (++hex_byte >= MAX_QUEUES) + { + break; + } + } + else + { + break; + } + } + keyflags.cont = TRUE; + break; + } +} + +static void dump_mailbox(void) +{ + MAILBOX *mail_ptr; + MSG *link; /* scratch pointer */ + word16 ctr; + + prompt_index = DUMP_MAILBOX_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + common_prompt(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + if (hex_byte == '*') + { + keyflags.loop = TRUE; + hex_byte = 0; + } + else + { + keyflags.loop = FALSE; + } + putcrlf(); + putstg("MAILBOX #, # of MESG, TASK waiting , TASK to Sig , EVENT\r\n"); + while (1) + { + if (hex_byte < MAX_MAILBOXES) + { + mail_ptr = &mail_box[hex_byte]; /* get address of proper queue handler. */ + /* maybe change to decimal, later */ + putspaces(3); + putbyte(hex_byte); /* output task number */ + putspaces(6); + ctr = 0; + link = mail_ptr->first_lnk; /* get first link. */ + while(1) + { + if (!link) + break; + link = link->link; + ctr++; + } + putword(ctr); + putspaces(4); + if (mail_ptr->waiter) /* task waiting on this mailbox */ + { + if (task_name[mail_ptr->waiter - cmx_tcb]) + putname(task_name[mail_ptr->waiter - cmx_tcb]); + else + putspaces(12); + } + else + putstg(" NONE "); + if (mail_ptr->task_num) + { + putspaces(1); + if (task_name[mail_ptr->task_num]) + putname(task_name[mail_ptr->task_num]); + else + putspaces(12); + putstg(" 0x"); + puthexword(mail_ptr->event_num); + } + putcrlf(); + } + else + { + putstg("MAILBOX Number out of range\r\n"); + keyflags.loop = FALSE; + } + if (keyflags.loop) + { + if (++hex_byte >= MAX_MAILBOXES) + { + break; + } + } + else + { + break; + } + } + keyflags.cont = TRUE; + break; + } +} + +static void dump_memory_ram(void) +{ + byte row; + byte ctr; + + prompt_index = DUMP_RAM_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + keyflags.allow_hex = FALSE; + putcrlf(); + prompt_out(); + break; + case 0x80: /* process card number prompt */ + keyflags.allow_hex = FALSE; + func_offset &= 0x7f; + from_ptr = (mem_size_ptr)hex_long; + func_offset = 0x01; + prompt_out(); + break; + case 0x81: /* process card number prompt */ + keyflags.allow_hex = FALSE; + func_offset &= 0x7f; + if (!keyflags.scroll) + { + thru_ptr = (mem_size_ptr)hex_long; + if (thru_ptr < from_ptr) + { + putstg("\r\nEnding address MUST be equal or greater from address"); + prompt_out(); + break; + } + } + putcrlf(); + putstg("\r\n 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\r\n"); + for (ctr = 0; ctr < 16; ctr++) + { + putcrlf(); + putspaces(1); + puthexlong((word32)from_ptr & 0xfffff0); + putspaces(2); + for (row = 0; row < 16; row++) + { + if (((word32)from_ptr & 0x00000f) == row) + break; + putspaces(3); + } + for (; row < 16; row++) + { + puthexbyte(*from_ptr); + if (from_ptr++ == thru_ptr) + { + keyflags.scroll = FALSE; + row = 0xff; + break; + } + putspaces(1); + } + if (row == 0xff) + break; + } + if (row < 0xff) + { + keyflags.scroll = TRUE; + putstg("\r\n\r\nEnter to continue"); + return; + } + keyflags.cont = TRUE; + break; + } +} + +static void change_rtc_scale(void) +{ + prompt_index = RTC_SCALE_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + putbyte(RTC_SCALE); + func_offset++; + prompt_out(); + break; + case 0x81: /* process card number prompt */ + func_offset &= 0x7f; + if (hex_byte) + RTC_SCALE = hex_byte; + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + break; + } +} + +static void change_tslice_scale(void) +{ + prompt_index = TSLICE_SCALE_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + putbyte(TSLICE_SCALE); + func_offset++; + prompt_out(); + break; + case 0x81: /* process card number prompt */ + func_offset &= 0x7f; + if (hex_byte) + TSLICE_SCALE = hex_byte; + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + break; + } +} + +static void enable_tslice(void) +{ + prompt_index = ENABLE_SLICE_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + if (SLICE_ON) + putstg("Enabled"); + else + putstg("Disabled"); + func_offset++; + prompt_out(); + break; + case 0x81: /* process card number prompt */ + func_offset &= 0x7f; + if (hex_byte) + SLICE_ON = 1; + else + SLICE_ON = 0; + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + break; + } +} + +static void delay_tick(void) +{ + prompt_index = DELAY_TICK_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + /* maybe change to decimal, later */ + if (hex_long < 0xffff && hex_long) + { + putstg("\r\nBUG task, waiting for the following number of TICKS "); + putword(hex_long); + CMXBUG_ACTIVE = 0; + locked_out = 0; + K_Task_Wait(hex_long); + locked_out = 1; + CMXBUG_ACTIVE = 1; + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + break; + } + else + { + putstg("\r\nMust be non zero number and less 65536!"); + func_offset = 0; + keyflags.cont = TRUE; + break; + } + } +} + +static void quick_tick(void) +{ + CMXBUG_ACTIVE = 0; + locked_out = 0; + K_Task_Wait(1); + locked_out = 1; + CMXBUG_ACTIVE = 1; + keyflags.f_key = TRUE; + keyflags.cont = TRUE; +} + + +static void stat_display(void) +{ + word32 tick_out; + + if (!keyflags.loop) + { + keyflags.loop = TRUE; + total_ticks = 0; + for (hex_byte = 0; hex_byte <= MAX_TASKS; hex_byte++) + total_ticks += stat_array[hex_byte]; + hex_byte = 1; + } + if (!total_ticks) + { + if (!keyflags.scroll) + { + keyflags.scroll = TRUE; + hex_byte = 0xFF; + putstg("\r\n\r\nThe TIME ANALYSIS array is empty\r\n"); + putstg("Enter to EXIT"); + return; + } + } + putcrlf(); + if (hex_byte != 0xFF) + putstg("SLOT #, NAME , Number of Ticks, % of TICKS\r\n"); + + tick_out = stat_array[activetcb - cmx_tcb]; /* get number of bug ticks */ + stat_array[activetcb - cmx_tcb] = 0; + stat_array[0] += tick_out; + while (1) + { + if (hex_byte <= MAX_TASKS) + { + /* MUST change to relect slot number and name */ + putspaces(1); + putbyte(hex_byte); /* output task number */ + putspaces(2); + if (task_name[hex_byte]) + putname(task_name[hex_byte]); + else + putspaces(12); + putspaces(3); + if (stat_array[hex_byte]) + { + putlong(stat_array[hex_byte]); + } + else + { + if (cmx_tcb[hex_byte].tcbstate && cmx_tcb[hex_byte].tcbstate & ~IDLE) + { + putstg(" < 1"); + } + else + { + putstg(" 0"); + } + } + putstg(" %"); + tick_out = ((byte)((stat_array[hex_byte] * 100) / total_ticks)); + putpercent((byte)(tick_out),0); + putstg("."); + putpercent((byte)((((stat_array[hex_byte] * 100) - (tick_out * total_ticks)) * 100) / total_ticks),1); + putcrlf(); + } + else + { + if (hex_byte == 0xFF) + { + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + keyflags.loop = FALSE; + keyflags.scroll = FALSE; + return; + } + } + if (++hex_byte > MAX_TASKS) + { + keyflags.scroll = TRUE; + hex_byte = 0xFF; + putstg(" IDLE "); /* output task number */ + putlong(stat_array[0]); + putstg(" %"); + tick_out = ((byte)((stat_array[0] * 100) / total_ticks)); + putpercent((byte)(tick_out),0); + putstg("."); + putpercent((byte)((((stat_array[0] * 100) - (tick_out * total_ticks)) * 100) / total_ticks),1); + putcrlf(); + putstg("Enter to EXIT"); + return; + } + else + { + if (hex_byte % SCROLL_SIZE == 0) + { + keyflags.scroll = TRUE; + putstg("Enter to continue"); + return; + } + } + } +} + +static void stat_reset(void) +{ + prompt_index = STATS_RESET_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + if (hex_byte) + { + for (hex_byte = 0; hex_byte <= MAX_TASKS; hex_byte++) + stat_array[hex_byte] = 0; + } + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + break; + } +} + +static void task_ctrl_func(void) +{ + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + keyflags.string_allowed = TRUE; + keyflags.string = FALSE; + prompt_index = TASK_CTRL_PROMPT; + putcrlf(); + do { + prompt_out(); + } while (++func_offset < 6); + func_offset = 0; + prompt_index = TASK_CTRL_PROMPT + 5; + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + switch (hex_byte) { + case 1: + func_offset = 1; + prompt_out(); + com1_prompt(); + break; + case 2: + func_offset = 2; + prompt_out(); + com1_prompt(); + break; + case 3: + func_offset = 3; + prompt_out(); + com1_prompt(); + break; + case 9: + current_func = WHAT_FUNCTION; + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + return; + default: + keyflags.cont = TRUE; + break; + } + break; + case 0x81: /* start task */ + func_offset = 0x00; + if (keyflags.string) + { + for (hex_byte = 1; hex_byte <= MAX_TASKS;hex_byte++) + { + if (!strncmp((char *)keys_in_buff,task_name[hex_byte],num_chars_in)) + break; + } + if (hex_byte > MAX_TASKS) + { + putstg("\r\nTask name NOT found"); + keyflags.cont = TRUE; + break; + } + } + if ((activetcb - cmx_tcb) == hex_byte) + putstg("\r\nManipulating CMXBug task is Illegal"); + else if (hex_byte > MAX_TASKS) + putstg("\r\nTask number out of range"); + else if (cmx_tcb[hex_byte].nxttcb) + { + putstg("\r\nTask -- "); + if (task_name[hex_byte]) + putname(task_name[hex_byte]); + else + putspaces(12); + putstg(" --, has been STARTED"); + K_Task_Start(hex_byte); + } + else + putstg("\r\nTask is either not created or has been deleted"); + keyflags.cont = TRUE; + break; + case 0x82: /* stop task */ + func_offset = 0x00; + if (keyflags.string) + { + for (hex_byte = 1; hex_byte <= MAX_TASKS;hex_byte++) + { + if (!strncmp((char *)keys_in_buff,task_name[hex_byte],num_chars_in)) + break; + } + if (hex_byte > MAX_TASKS) + { + putstg("\r\nTask name NOT found"); + keyflags.cont = TRUE; + break; + } + } + if ((activetcb - cmx_tcb) == hex_byte) + putstg("\r\nManipulating CMXBug task is Illegal"); + else if (hex_byte > MAX_TASKS) + putstg("\r\nTask number out of range"); + else if (!cmx_tcb[hex_byte].nxttcb) + putstg("\r\nTask is either not created or has been deleted"); + else if (cmx_tcb[hex_byte].tcbstate == IDLE || \ + cmx_tcb[hex_byte].tcbstate == READY) + putstg("\r\nTask is NOT started"); + else if (cmx_tcb[hex_byte].tcbstate & ANY_WAIT) + putstg("\r\nTask is already WAITING on some entity"); + else + { + putstg("\r\nTask -- "); + if (task_name[hex_byte]) + putname(task_name[hex_byte]); + else + putspaces(12); + putstg(" --, has been STOPPED"); + cmx_tcb[hex_byte].tcbstate = WAIT; + } + keyflags.cont = TRUE; + break; + case 0x83: /* process card number prompt */ + func_offset = 0x00; + if (keyflags.string) + { + for (hex_byte = 1; hex_byte <= MAX_TASKS;hex_byte++) + { + if (!strncmp((char *)keys_in_buff,task_name[hex_byte],num_chars_in)) + break; + } + if (hex_byte > MAX_TASKS) + { + putstg("\r\nTask name NOT found"); + keyflags.cont = TRUE; + break; + } + } + if ((activetcb - cmx_tcb) == hex_byte) + putstg("\r\nManipulating CMXBug task is Illegal"); + else if (hex_byte > MAX_TASKS) + putstg("\r\nTask number out of range"); + else if (!cmx_tcb[hex_byte].nxttcb) + putstg("\r\nTask is either not created or has been deleted"); + else if (!(cmx_tcb[hex_byte].tcbstate & ANY_WAIT)) + putstg("\r\nTask is NOT waiting on some entity"); + else + { + putstg("\r\nTask -- "); + if (task_name[hex_byte]) + putname(task_name[hex_byte]); + else + putspaces(12); + putstg(" --, has been WOKEN"); + K_Task_Wake_Force(hex_byte); + } + keyflags.cont = TRUE; + break; + } +} diff --git a/src/kernel/cmx/cmxbug.h b/src/kernel/cmx/cmxbug.h new file mode 100755 index 00000000..bc647c87 --- /dev/null +++ b/src/kernel/cmx/cmxbug.h @@ -0,0 +1,33 @@ +#if (!defined(INC_CMXBUG)) +#define INC_CMXBUG 1 + +/* include this file after including cxfuncs.h so cmx_reentrant is + defined properly. +*/ +#ifndef cmx_reentrant +#define cmx_reentrant +#endif +#ifndef cmx_xdata +#define cmx_xdata +#endif +#ifndef cmx_code +#define cmx_code const +#endif + +#if (defined(CMX_INIT_MODULE)) +extern byte cmxbug_slot; +extern void cmxbug(void) cmx_reentrant; +byte CMXBUG_ACTIVE; +#if (defined(WINBUG)) +extern byte cmx_xdata bug_step_one; +extern word16 cmx_xdata bug_step_count; +#endif /* #if (defined(WINBUG)) */ +#endif /* #if (defined(CMX_INIT_MODULE)) */ + +#if (defined(WINBUG)) +/* user-callable cmxbug functions */ +void setbaud(void); +void cmxbug_activate(void) cmx_reentrant; +#endif /* #if (defined(WINBUG)) */ + +#endif /* #if (!defined(INC_CMXBUG)) */ diff --git a/src/kernel/cmx/cmxintb.asm b/src/kernel/cmx/cmxintb.asm new file mode 100755 index 00000000..ae5b3aad --- /dev/null +++ b/src/kernel/cmx/cmxintb.asm @@ -0,0 +1,114 @@ +; cmxintb.asm +; Extremely basic interrupt system for Hytech CMX (banked) + +$ io64180.inc + + extern abyte + extern ahexw + extern acrlf + extern _K_OS_Intrp_Entry + extern _K_OS_Intrp_Exit + extern _timer0_handler + + public _timer0_setup + public _timer0_vector + + EXTERN ?BANK_CALL_DIRECT_L08 + EXTERN ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + +;tmdr0l_r EQU 0ch +;tmdr0h_r EQU 0dh +;rldr0l_r EQU 0eh +;rldr0h_r EQU 0fh +;tcr_r EQU 10h + +; RSEG RCODE +; +; COMMON INTVEC +; org $ + 4h +; +;VECT2: +; DEFW timer0_vect + +; ----------------------------------------------------------------------------- + + RSEG CODE + +_timer0_setup:: +; push bc +; push de + +; ld a,01 +; ld i,a ;set i to 1, thus intenal interrupts start at 0x100 + + ld a,0bh +; ld a,20h + out0 (TMDR0H),A + out0 (RLDR0H),A + ld a,0b8h + out0 (TMDR0L),a + out0 (RLDR0L),a + ld a,11h + out0 (TCR),a + +; pop de +; pop bc +; ret + jp LWRD ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + RSEG RCODE + +_timer0_vector:: + .if 1 + push af + in0 a,(TCR) + in0 a,(TMDR0L) + pop af + ei + ret + .endif + + .if 0 + push af + ld a,0 + inc a + ld ($-2),a + or a + jr z,silly + in0 a,(TCR) + in0 a,(TMDR0L) + pop af + ei + ret ;i +silly: + pop af + .endif + .if 0 + push af + ld a,'x' + call abyte + pop af + .endif + call _K_OS_Intrp_Entry + .if 0 + ld a,'y' + call abyte + .endif + in0 a,(TCR) + in0 a,(TMDR0L) + ld a,BYTE3 _timer0_handler + ld hl,LWRD _timer0_handler ;load hl with cmx_tic address + call LWRD ?BANK_CALL_DIRECT_L08 + .if 0 + ld a,'z' + call abyte + .endif + call _K_OS_Intrp_Exit + +; ----------------------------------------------------------------------------- + + END diff --git a/src/kernel/cmx/cmxio3.c b/src/kernel/cmx/cmxio3.c new file mode 100755 index 00000000..ec83b4a2 --- /dev/null +++ b/src/kernel/cmx/cmxio3.c @@ -0,0 +1,665 @@ +/********************************************************* + +Copyright (c) CMX Company. 1993-1995. All rights reserved + +*********************************************************/ +/* version 3.00 */ + +#include +#include /* get cmx include header file */ +/* Nick #include /* get 64180 io configuration file */ + +/* WARNING ---- UPDATE ---- WARNING + +The uart_update() function has been broken into 2 (two) different +functions, which are the K_Update_Recv function and the +K_Update_Xmit function, call respectively by the reciever +and transmitter interrupt handlers + +WARNING ---- UPDATE ---- WARNING */ + +/************************************************************** + + !!! CAUTION !!! + +It is up to the interrupt handler that either calls the K_Update_Recv +and K_Update_Xmit functions to clear or set any needed bits in the UART +registers (IF NEED BE), so as to properly handle the sending and recieving +of characters thru the UART. This may include reloading a timer, clearing +the recieve char bit, error flags, etc, depending upon the processor and +mode that the UART is operating in. + +CMX does NOT do anything to any UART register bits. It will just recieve +a character and transmit a character. However it will start the transmitter +when need be, according to the XMIT_INT_ON define set below by user. + +**************************************************************/ + +/************************************************************** + The user MAY have to tweak some of the following code, depending +upon the processor that they are working with. This is because +there are many different ways to configure a UART and many modes +that a UART can operate under. + + Probally the most the user will have to do is to properly enable the +UART transmitter and possibly properly clear the reciever ready flag +if needed to be done by software. Also the user must tell the "C" +functions where the UART registers are located. The user will +have to at the most, possibly manipulate the following functions: + +K_Init_Xmit() initialize transmitter +K_Init_Recv() initialize reciever + + NOTE: in most cases the processor and "C" compiler will +allow you to access the IO registers by either including +the proper *.h file or by casting the register +to an absolute address. However their are some exceptions +to this, and if so, the user must create their own +assembly routines to properly set, clear and test bits and +to get and send a byte or word to these register. +********************************************************/ + +/************************************************************** + The user must set these to the CPU that they are working with + +#define XMIT_INT_ON ??? enable the transmitter +#define RECV_REG reciever register +#define XMIT_REG transmit register +***************************************************************/ + +/****************************************************** + The following is for the 68HC12 family + +********************************************************/ + +#if 0 +#define RECV_REG RDR0 /* reciever register */ +#define XMIT_REG TDR0 /* transmit register */ + +#define TIE 0x01 /* transmit interrupt enable bit */ + +#define XMIT_INT_ON() { (STAT0 |= TIE); } /* enable transmitter. */ + +#define XMIT_SIZE 256 /* size of transmitter buffer */ +#define RECV_SIZE 256 /* size of reciever buffer */ +#endif + + +word16 K_I_Get_Char_Common(byte port, byte *byte_ptr, word16 cnt, + word16 timecnt, byte wait); +byte K_I_Put_Char_Common(byte port, byte *byte_ptr, word16 cnt, + word16 timecnt, byte wait); +byte K_I_Remove_Link(void); +void K_I_Insert_Link(word16); + +/* NOTES: + The recieve interrupt could determine that the last character came in + and signal an event indicating this, or wake a task, etc. +*/ +/* THE FOLLOWING ARE TRANSMITTER FLAGS */ +#define XMIT_BUSY 0x01 + +/* THE FOLLOWING ARE RECIEVER FLAGS */ +#define OE 0x02 +#define FE 0x04 +#define PE 0x08 +#define FULL 0x20 +#define RECV_BUFF_ERR 0x40 + +#define AER_UART_BUSY 0x20 /* error code pass back to calling task */ + +SDEV sdevs[PORTS]; /* Nick */ +byte xmit_bufs[PORTS][XMIT_SIZE]; /* Nick */ +byte recv_bufs[PORTS][RECV_SIZE]; /* Nick */ + +void K_Init_Sdevs(void) +{ + byte i; + SDEV *device; + + device = &sdevs[0]; + for (i = 0; i < PORTS; i++) + { + device->port = i; + device->tx_vector = K_Update_Xmit; + + /* for serial devices, set the usual incoming data handler */ + /* for API BUS devices, throw away incoming data by default */ + if (i < 4) + { + device->rx_vector = K_Update_Recv; + } + else + { + device->rx_vector = K_Update_Dummy; + } + + device->modem_status_vector = K_Update_Dummy; + device->error_status_vector = K_Update_Dummy; + device->tx_enable_vector = K_Update_Dummy; + device->tx_disable_vector = K_Update_Dummy; + + device->xmit.buff = xmit_bufs[i]; + device->recv.buff = recv_bufs[i]; + + K_Init_Xmit(device); + K_Init_Recv(device); + + device++; + } +} + +void K_Init_Xmit(SDEV *device) +{ + /* set up BAUD rate, parity, data bits, stop bits */ + device->xmit.flag = 0x00; /* clear flags. */ + device->xmit.head = device->xmit.tail = &device->xmit.buff[0]; +} + +void K_Init_Recv(SDEV *device) +{ + /* set up BAUD rate, parity, data bits, stop bits */ + /* also enable reciever, if need be. */ + device->recv.flag = 0x00; /* clear flags. */ + device->recv.head = device->recv.tail = &device->recv.buff[0]; +} + +/* The following can only be called by the interrupt. No + Parameters are passed. */ +#if 1 +word16 +#else +void +#endif +K_Update_Xmit(SDEV *device) +{ +#if 1 + byte data; +#endif + +#if 0 + if (device->xmit.flag & XMIT_BUSY) /* see if transmitter should transmit. */ + { +#endif + if (device->xmit.bytes_out) /* decrement count and send. */ + { +#if 1 + if (device->xmit.bytes_wanted) /* is task waiting for number of bytes. */ + { + if (!(--device->xmit.bytes_wanted)) /* yes, decrement and test. */ + { + if (device->xmit.tcbptr->tcbstate & WAIT) /* see if task waiting. */ + { + device->xmit.tcbptr->tcbstate = RESUME; /* yes, wake task. */ + if (device->xmit.tcbptr->priority < active_priority) + PREEMPTED; /*cmx_flag1 |= preempted;*/ /* yes, set preempted K_I_Scheduler flag */ + } + } + } +#endif +#if 1 + data = *device->xmit.tail; + if (++device->xmit.tail == &device->xmit.buff[XMIT_SIZE]) /* see if wrap. */ + device->xmit.tail = &device->xmit.buff[0]; + device->xmit.bytes_out--; +#if 0 + _asm + or a ; cf=0 indicates char available + _endasm; +#endif + return data; +#else + XMIT_REG = *device->xmit.tail++; /* send character out. */ + device->xmit.bytes_out--; +#endif + } +#if 0 + else + { +#if 0 + device->xmit.flag &= ~XMIT_BUSY; /* transmitter done. */ +#endif + if (device->xmit.tcbptr) /* see if task needs to be notified. */ + { + if (device->xmit.tcbptr->tcbstate & WAIT) + { + device->xmit.tcbptr->tcbstate = RESUME; /* allow task to resume. */ + if (device->xmit.tcbptr->priority < active_priority) + PREEMPTED; /*cmx_flag1 |= preempted;*/ /* yes, set preempted K_I_Scheduler flag */ + } + } + } + } +#endif +#if 1 + return -1; /* h=0ffh says theres no char for tx */ +#else + _asm + scf ; cf=1 says theres no char for tx + _endasm; +#endif +} + +word16 K_Update_Dummy(SDEV *device) +{ + return -1; /* if installed as tx handler, says tx should be stopped */ +} + +/* The following can only be called by the interrupt. No + Parameters are passed. */ +void K_Update_Recv(SDEV *device, byte data) +{ +/* abyte('<'); */ +/* ++device->recv.bytes_in; */ +/* return; */ +#if 1 + if (device->recv.bytes_in < RECV_SIZE) /* is buffer full. */ +#else + if (!(device->recv.flag & FULL)) /* see if reciever NOT full. */ +#endif + { +#if 1 + *device->recv.head = data; /* store value from receiver int */ + if (++device->recv.head == &device->recv.buff[RECV_SIZE]) /* see if wrap. */ + device->recv.head = &device->recv.buff[0]; + device->recv.bytes_in++; +#else + *device->recv.head = RECV_REG; /* get character and store in buffer. */ + if (++device->recv.head == &device->recv.buff[RECV_SIZE]) /* see if wrap. */ + device->recv.head = &device->recv.buff[0]; +#if 1 + if (++device->recv.bytes_in == RECV_SIZE) /* is buffer full. */ +#else + if (device->recv.bytes_in++ == RECV_SIZE) /* is buffer full. */ +#endif + { + device->recv.flag |= FULL; /* yes set flag. */ + } +#endif + if (device->recv.bytes_wanted) /* is task waiting for number of bytes. */ + { + if (!(--device->recv.bytes_wanted)) /* yes, decrement and test. */ + { + if (device->recv.tcbptr->tcbstate & WAIT) /* see if task waiting. */ + { +/* abyte('!'); */ + device->recv.tcbptr->tcbstate = RESUME; /* yes, wake task. */ + if (device->recv.tcbptr->priority < active_priority) + PREEMPTED; /*cmx_flag1 |= preempted;*/ /* yes, set preempted K_I_Scheduler flag */ + } + } + } + } + else + { + device->recv.flag |= RECV_BUFF_ERR; /* flag that buffer overrun + occurred char lost. */ + } +/* abyte('|'); */ +} + +byte K_I_Put_Char_Common(byte port, byte *byte_ptr, word16 cnt, + word16 timecnt, byte wait) +{ + SDEV *device; +#if 1 + word16 count, rem; +#endif + + if (port >= PORTS || cnt > XMIT_SIZE) + { + return K_ERROR; + } + device = &sdevs[port]; + + K_I_Disable_Sched(); /* set task block. */ +/* abyte ('<'); */ + K_OS_Disable_Interrupts(); /* DISABLE INTERRUPTS. */ +#if 1 + rem = XMIT_SIZE - device->xmit.bytes_out; + if (cnt > rem) /* is transmitter buffer too full? */ +#else + if (device->xmit.flag & XMIT_BUSY) /* is transmitter busy. */ +#endif + { + if (wait) /* should task wait. */ + { + if (timecnt) /* wait on time too? */ + activetcb->tcbstate = WAIT | TIME; /* put task to sleep, idicating why */ + else + activetcb->tcbstate = WAIT; /* put task to sleep, idicating why */ + device->xmit.tcbptr = activetcb; /* tell transmitter task waiting. */ +#if 1 + /* calculate number of bytes needed to satisfy. */ + device->xmit.bytes_wanted = cnt - rem; +#endif + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + K_I_Insert_Link(timecnt); /* insert it into time link. */ + device->xmit.tcbptr = NULL; /* task will return to here. */ + K_I_Disable_Sched(); /* set task block. */ + if(K_I_Remove_Link()) /* remove from link. */ + { + K_I_Func_Return(); /* time out occurred. */ + return(K_TIMEOUT); + } + } + else + { + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + K_I_Func_Return(); /* release task lock. */ + return(AER_UART_BUSY); /* return error that transmitter busy. */ + } + } + else + { +/* abyte('u'); */ + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ +/* abyte('v'); */ + } + /* the following sets up the transmitter buffer, and starts transmission. */ +#if 0 + device->xmit.flag |= XMIT_BUSY; +#endif +#if 1 + /* bytes to be given to the queue after copying into the queue */ + count = cnt; +/* abyte('w'); */ + + /* calculate remaining bytes of contiguous buffer space after head */ + rem = &device->xmit.buff[XMIT_SIZE] - device->xmit.head; +/* abyte('x'); */ + + /* we must ensure this gets executed if the queue is going to wrap! */ + if (cnt >= rem) + { + /* queue wrap is going to occur, fill queue up to wrap spot */ + cnt -= rem; + while (rem--) + { + *device->xmit.head++ = *byte_ptr++; + } + device->xmit.head = &device->xmit.buff[0]; + } +/* abyte('y'); */ + + /* if the queue wrapped, cnt may be zero in which case we do nothing */ + while(cnt--) + { + *device->xmit.head++ = *byte_ptr++; + } +/* abyte('z'); */ + + /* only now can we tell the interrupt that it has characters waiting */ + K_OS_Disable_Interrupts(); /* DISABLE INTERRUPTS. */ + device->xmit.bytes_out += count; /* number of characters to transmit */ + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + +/* ahexw(count); */ + (*device->tx_enable_vector)(device); /* Nick */ +/* abyte('>'); */ +#else + device->xmit.bytes_out = cnt; /* number of characters to transmit. */ + device->xmit.head = &device->xmit.buff[0]; /* reset head. */ + device->xmit.tail = &device->xmit.buff[0]; /* reset tail. */ + while(cnt--) + { + *device->xmit.head++ = *byte_ptr++; /* load bytes in. */ + } + + XMIT_INT_ON(); /* enable transmitter. */ +#endif + K_I_Func_Return(); + return(K_OK); +} +/* for sending out characters to uart buffer*/ +/* this works with uart buffer */ +byte K_Put_Str(byte port, void *byte_ptr, word16 cnt) +{ + return(K_I_Put_Char_Common(port, (byte *)byte_ptr, cnt, 0, 0)); +} + +byte K_Put_Str_Wait(byte port, void *byte_ptr, word16 cnt, word16 timecnt) +{ + return(K_I_Put_Char_Common(port, (byte *)byte_ptr, cnt, timecnt, 1)); +} + +byte K_Put_Char(byte port, void *byte_ptr) +{ + return(K_I_Put_Char_Common(port, (byte *)byte_ptr, 1, 0, 0)); +} + +byte K_Put_Char_Wait(byte port, void *byte_ptr, word16 timecnt) +{ + return(K_I_Put_Char_Common(port, (byte *)byte_ptr, 1, timecnt, 1)); +} + + + +/* for recieving characters from uart buffer*/ +/* this works with uart buffer */ +word16 K_I_Get_Char_Common(byte port, byte *byte_ptr, word16 cnt, + word16 timecnt, byte wait) +{ + SDEV *device; + word16 count; +#if 1 + word16 rem; +#endif + + if (port >= PORTS || cnt > RECV_SIZE) + { + return 0; /* pretend UART busy, can't return K_ERROR; */ + } + device = &sdevs[port]; + + K_I_Disable_Sched(); /* set task lock. */ + K_OS_Disable_Interrupts(); /* DISABLE INTERRUPTS. */ + if (!cnt) /* vaiable length command, get current contents */ + { + cnt = device->recv.bytes_in; /* get number of chars. already in. */ + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + } + else + { + if (cnt > device->recv.bytes_in) /* see if in count > then requested. */ + { + if (wait) /* should task wait. */ + { + if (timecnt) /* yes, also time period. */ + activetcb->tcbstate = WAIT | TIME; /* put task to sleep, idicating why */ + else + activetcb->tcbstate = WAIT; /* put task to sleep, idicating why */ + device->recv.tcbptr = activetcb; /* tell reciever. */ + /* calculate number of bytes needed to satisfy. */ + device->recv.bytes_wanted = (cnt - device->recv.bytes_in); + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + K_I_Insert_Link(timecnt); /* insert into time link. */ + K_I_Disable_Sched(); /* set task lock. */ + device->recv.bytes_wanted = 0; /* reset wanted count. */ + if(K_I_Remove_Link()) /* remove from link if need be. */ + { + if (wait == 0x02) /* see if variable count mode. */ + { + K_OS_Disable_Interrupts(); /* DISABLE INTERRUPTS. */ + cnt = device->recv.bytes_in; /* set number of bytes to move. */ + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + } + else + { + K_I_Func_Return(); /* release task block. */ + return(0); /* return error status. */ + } + } + } + else + { + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + K_I_Func_Return(); /* release task block. */ + return(0); /* return uart busy status. */ + } + } + else + { + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + } + } +#if 1 +/* abyte('a'); */ + /* bytes to be taken from the queue after copying out of the queue */ + count = cnt; + + /* calculate remaining bytes of contiguous buffer space after head */ + rem = &device->recv.buff[RECV_SIZE] - device->recv.tail; + + /* we must ensure this gets executed if the queue is going to wrap! */ + if (cnt >= rem) + { + /* queue wrap is going to occur, suck queue up to wrap spot */ + cnt -= rem; + while (rem--) + { +/* abyte('b'); */ + *byte_ptr++ = *device->recv.tail++; + } + device->recv.tail = &device->recv.buff[0]; + } + + /* if the queue wrapped, cnt may be zero in which case we do nothing */ + while(cnt--) + { +/* abyte('c'); */ + *byte_ptr++ = *device->recv.tail++; + } + + /* only now can we tell the interrupt that we freed some queue space */ + K_OS_Disable_Interrupts(); /* DISABLE INTERRUPTS. */ + device->recv.bytes_in -= count; /* number of characters now freed. */ +#if 0 + device->recv.flag &= ~FULL; /* reset flag. (THIS IS SILLINESS!) */ +#endif + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ +/* abyte('d'); */ +#else + count = 0; + /* load callers pointer with bytes. */ + while (cnt-- && device->recv.bytes_in) + { + *byte_ptr++ = *device->recv.tail; + /* see if wrap. */ + if (++device->recv.tail == &device->recv.buff[RECV_SIZE]) + device->recv.tail = &device->recv.buff[0]; + count++; /* increment count. */ + K_OS_Disable_Interrupts(); /* disable interrupts. */ + --device->recv.bytes_in; /* decrement count of number of bytes in reciever. */ +#if 0 + device->recv.flag &= ~FULL; /* reset flag. */ +#endif + K_OS_Enable_Interrupts(); /* re-enable interrupts. */ + } +#endif + K_I_Func_Return(); +/* abyte('e'); */ + return(count); +} + +word16 K_Recv_Count(byte port) +{ + SDEV *device; + + if (port >= PORTS) + { + return K_ERROR; + } + device = &sdevs[port]; + + return(device->recv.bytes_in); +} + +/* get single character, no time out, no wait */ +word16 K_Get_Char(byte port, void *byte_ptr) +{ + return(K_I_Get_Char_Common(port, (byte *)byte_ptr, 1, 0, 0)); +} + +/* get single character, wait, if after wait no character, return nothing */ +word16 K_Get_Char_Wait(byte port, void *byte_ptr, word16 timecnt) +{ + return(K_I_Get_Char_Common(port, (byte *)byte_ptr, 1, + timecnt, 1)); +} + +/* get requested number of char. , if number requested +not there, return nothing, NO wait */ +word16 K_Get_Str(byte port, void *byte_ptr, word16 cnt) +{ + return(K_I_Get_Char_Common(port, (byte *)byte_ptr, cnt, 0, 0)); +} + +/* get requested number of char. , wait for timeout if number requested +not there, if after wait correct number NOT there , return nothing */ +word16 K_Get_Str_Wait(byte port, void *byte_ptr, word16 cnt, word16 timecnt) +{ + return(K_I_Get_Char_Common(port, (byte *)byte_ptr, cnt, + timecnt, 1)); +} + +/* get requested number of char. , wait for timeout if number requested +not there, if after wait correct number NOT there , return the +number that came in */ +word16 K_Get_Str_Wait_Return(byte port, void *byte_ptr, + word16 cnt, word16 timecnt) +{ + return(K_I_Get_Char_Common(port, (byte *)byte_ptr, cnt, + timecnt, 2)); +} + +/* get ALL character in buffer, do not wait */ +word16 K_Get_Str_Return(byte port, void *byte_ptr) +{ + return(K_I_Get_Char_Common(port, (byte *)byte_ptr, 0, 0, 0)); +} + +/* inset task into time wait link, if need be. */ +void K_I_Insert_Link(word16 timecnt) +{ + activetcb->tcbtimer = timecnt; /* load task time counter with proper time */ + if (timecnt) /* put into timer chain ?? */ + { + /* let task sleep, indicating why and also waiting on time */ + if (tsk_timer_lnk->ftlink != (tcbpointer)tsk_timer_lnk) + { + activetcb->ftlink = tsk_timer_lnk->btlink->ftlink; + tsk_timer_lnk->btlink->ftlink = activetcb; + activetcb->btlink = tsk_timer_lnk->btlink; + } + else + { + activetcb->ftlink = activetcb->btlink = (tcbpointer)tsk_timer_lnk; + tsk_timer_lnk->ftlink = activetcb; + } + tsk_timer_lnk->btlink = activetcb; + } + PREEMPTED; /*cmx_flag1 |= preempted;*/ /* set the K_I_Scheduler flag */ + K_I_Func_Return(); /* release task block */ +} + +/* remove from time link, if need be. */ +byte K_I_Remove_Link() +{ + if (activetcb->tcbtimer) + { + activetcb->ftlink->btlink = activetcb->btlink; + activetcb->btlink->ftlink = activetcb->ftlink; + } + /* see if task was woken, because the thing it was waiting for happened, + or that the time period specified has elapsed */ + if (activetcb->tcbstate & TIME_EXPIRED) + { + return(K_TIMEOUT); /* return the warning: that the time period expired */ + } + else + { + return(K_OK); /* return good, time period did NOT expire. */ + } +} + diff --git a/src/kernel/cmx/cmxtrack.c b/src/kernel/cmx/cmxtrack.c new file mode 100755 index 00000000..24d1b0a0 --- /dev/null +++ b/src/kernel/cmx/cmxtrack.c @@ -0,0 +1,1466 @@ +#include +#include /* get cmx include header file */ + +#include /* get cmx include header file */ + +#define BIG_ENDIAN 0 +#define LARGE 0 /* Nick 1 */ +#define STACK_MSB 0 /* set to 1, if stack pointer points to MSB of long, when pushed */ +#define large_ptr void * + +#define MAX_MEM_DECIMAL 0x05 /* max decimal size */ +#define MAX_MEM_HEX 0x04 /* max hex size */ +#define MAX_FIELD_LENGTH 12 /* the maximum field length of any field */ +#define SCROLL_SIZE 18 +#define HOME 71 +#define PAGE_UP 73 +#define PAGE_DOWN 81 +#define END 79 + +#define LOG_DISPLAY_LEN 18 + +#define WHAT_FUNCTION 0 +#define CMXTRACKER_VIEW 1 +#define CMXTRACKER_RESET 2 +#define DELAY_TICK 3 +#define QUICK_TICK 4 +#define EXIT_BUG 99 + +#define WHAT_FUNCTION_PROMPT 00 /* 1 */ +#define CMXTRACKER_VIEW_PROMPT WHAT_FUNCTION_PROMPT + 1 /* 1 */ +#define CMXTRACKER_RESET_PROMPT CMXTRACKER_VIEW_PROMPT + 1 /* 1 */ +#define DELAY_TICK_PROMPT CMXTRACKER_RESET_PROMPT + 1 /* 1 */ +struct prompt { + char *word; + byte in_length; + }; + +/* prompt char., length of field */ +static /* Nick */ const struct prompt prpt_array [] = { + { " Enter Function? \n",0x02}, + { "\r\nCMXTRACKER dump",0x01}, + { "\r\nEnter Y/y to reset CMXTRACKER array or to leave as is ",0x03}, + { "\r\nEnter the number of ticks to wait or to leave? ",0x05} + }; + +/* keyboard flags */ +struct track_keyflag { /* bit structure */ + bit_word16 f_key:1; + bit_word16 e_key:1; + bit_word16 non_zero:1; + bit_word16 cont:1; + bit_word16 e_jmp:1; + bit_word16 input_func:1; + bit_word16 allow_hex:1; + bit_word16 echo_off:1; + bit_word16 short_str:1; + bit_word16 int_action:1; + bit_word16 timer_task:1; + bit_word16 end_key:1; + }; + +static struct track_keyflag keyflags; +static byte key_pressed; /* byte for scan code of keypad 0x00 thru 0x0f */ +static byte num_chars_in; +static byte * in_char_ptr; +static byte max_chars_in; +static byte current_func; +static byte keys_in_buff[MAX_FIELD_LENGTH]; +static byte prompt_index; +static byte hex_byte; +static long hex_long; +static byte func_offset; +static byte input_index; +static const struct prompt * prpt_ptr; +static word16 c5; +static byte * c6; + +void delay_tick(void); +void quick_tick(void); +static void cmxtracker_view(void); +static void zerofill(byte *); +static void clear_chars_in(void); +static void conv_hex(void); +static void display_char(char); +static void putstg(const char *); +static void putbyte(byte); +static void putword(word16); +static void puttime(void); +static void pichexlong(large_ptr,byte); +static void pichexword(void *,byte); +static void puthexbyte(byte); +static void puthexword(word16); +static void putname(char c2); + +void cmxtracker_reset(void); +static void putcrlf(void); +static void prompt_out(void); +static byte cmxtracker_wake; +static byte cmxtracker_mode_byte; +static word16 cmxtracker_count; + +static const char nibs[] = "0123456789ABCDEF"; + +/* non-statics */ + +byte * cmxtracker_in_ptr; +byte * cmxtracker_out_ptr; +word16 cmxtracker_ctr; +word16 num_records; +word16 record_cnt; +byte cmxtracker_slot; + +extern byte cmxtracker_array[]; +extern char * task_name[]; +extern word16 rec_cnt[]; + +extern byte CMXTRACKER_ACTIVE; +extern byte BUG_WAIT_TICKS; +extern void init_cmxtracker(void); +extern byte K_Track_Getchr(byte *ptr); +extern void K_Track_Putchr(byte); + +void bug_putstg(byte *); +void cmxtracker(void); + +void cmxtracker(void) +{ + byte status; + + /* abyte('t'); */ + + /* process */ + CMXTRACKER_ACTIVE = 0; /*1; /* Nick 0; */ + while(1) + { + /* abyte('u'); */ + + if (!keyflags.cont) { + while(1) + { + /* abyte('v'); */ + + if (cmxtracker_wake) + { + key_pressed = '+'; + break; + } + status = K_Track_Getchr(&key_pressed); + if (status) + break; + if (!CMXTRACKER_ACTIVE) + { + /* abyte('w'); */ + K_Task_Wait(BUG_WAIT_TICKS); + /* abyte('x'); */ + } + } + cmxtracker_wake = 0; + /* abyte('('); */ + /* abyte(key_pressed); */ + /* abyte(')'); */ + switch (key_pressed) { + case '+': + locked_out = 1; + + CMXTRACKER_ON = 0; + CMXTRACKER_ACTIVE = 1; + keyflags.f_key = TRUE; + break; + + case 'p': + case 'P': + if (keyflags.echo_off) + keyflags.echo_off = FALSE; + else + keyflags.echo_off = TRUE; + break; + + case '\r': + if (!keyflags.non_zero) + { + keyflags.f_key = TRUE; + break; + } + + if (num_chars_in > 0 || keyflags.input_func) + { + keyflags.e_key = TRUE; + } + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (num_chars_in < max_chars_in && !keyflags.input_func) + { + keyflags.non_zero = TRUE; + display_char(key_pressed); +#if 1 + *in_char_ptr = key_pressed & 0x0f; + abyte('I'); + ahexw(*in_char_ptr); + abyte(' '); + in_char_ptr++; +#else + *in_char_ptr++ = key_pressed & 0x0f; +#endif + num_chars_in++; + } + break; + case '*': + if (num_chars_in < max_chars_in &&!keyflags.input_func) + { + keyflags.non_zero = TRUE; + display_char(key_pressed); + hex_byte = key_pressed; + keyflags.e_jmp = TRUE; + func_offset |= 0x80; /* set done entry flag */ + num_chars_in++; + } + break; + + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + if (!keyflags.allow_hex) + break; + if (num_chars_in < max_chars_in &&!keyflags.input_func) + { + keyflags.non_zero = TRUE; + display_char(key_pressed); + *in_char_ptr++ = ((key_pressed & 0x0f) + 0x09); + num_chars_in++; + } + break; + + case 'X': + case 'x': + if (!keyflags.non_zero) + { + display_char('x'); + keyflags.allow_hex = TRUE; + if (max_chars_in == MAX_MEM_DECIMAL) + max_chars_in = MAX_MEM_HEX; + } + break; + + case 'Y': + case 'y': + hex_byte = 1; + keyflags.e_jmp = TRUE; + keyflags.e_key = TRUE; + K_Track_Putchr('Y'); + func_offset |= 0x80; /* set done entry flag */ + break; + + case 'N': + case 'n': + hex_byte = 0; + keyflags.e_jmp = TRUE; + keyflags.e_key = TRUE; + K_Track_Putchr('N'); + func_offset |= 0x80; /* set done entry flag */ + break; + + default: + break; + } /* end of switch */ + } /* END OF KEYBOARD.CONT IF */ + + if (keyflags.cont) + { + keyflags.cont = FALSE; + keyflags.e_key = TRUE; + keyflags.e_jmp = TRUE; + func_offset = 0; + } + if (keyflags.f_key) + { + keyflags.f_key = FALSE; + keyflags.e_key = FALSE; + keyflags.e_jmp = FALSE; + keyflags.allow_hex = FALSE; + keyflags.cont = FALSE; + keyflags.input_func = FALSE; + func_offset = 0; + current_func = WHAT_FUNCTION; + prompt_index = WHAT_FUNCTION_PROMPT; + /* clear all normal flags, etc. */ + clear_chars_in(); + max_chars_in = 2; + putstg("\r\nEnter 1 to DISPLAY LOG\r\n"); + putstg("Enter 2 RESET LOG\r\n"); + putstg("Enter 3 GO and RESUME CMXTracker\r\n"); + putstg("Enter 4 Quick GO and RESUME CMXTracker\r\n"); + putstg("Enter 99 EXIT CMXTracker\r\n"); + putstg("Enter P/p to toggle ECHO mode, currently "); + if (!keyflags.echo_off) + { + putstg("ON"); + } + else + { + putstg("OFF"); + } + putstg("\r\nYour choice? "); + } + if (keyflags.e_key && CMXTRACKER_ACTIVE) + { + keyflags.e_key = FALSE; + if (!keyflags.e_jmp) + { + zerofill(&keys_in_buff[max_chars_in]); /* go zero fill, for proper entry */ + conv_hex(); /* go put characters into hex form, just 2 lsd */ + func_offset |= 0x80; /* set done entry flag */ + } + else + keyflags.e_jmp = FALSE; + if (current_func == WHAT_FUNCTION) + { + func_offset = 0; + current_func = hex_byte; + abyte(' '); + ahexw(current_func); + abyte(' '); + switch(current_func) { + case WHAT_FUNCTION: + break; + case CMXTRACKER_VIEW: + break; + case CMXTRACKER_RESET: + break; + case QUICK_TICK: + break; + case DELAY_TICK: + break; + case EXIT_BUG: + break; + default: + current_func = WHAT_FUNCTION; + keyflags.f_key = TRUE; + putstg("\r\n\r\nInvalid entry, press any key to continue\r\n"); + break; + } + } + switch(current_func) { + case CMXTRACKER_VIEW: + cmxtracker_view(); + break; + case CMXTRACKER_RESET: + cmxtracker_reset(); + break; + case QUICK_TICK: + quick_tick(); + break; + case DELAY_TICK: + delay_tick(); + break; + case EXIT_BUG: + cmxtracker_mode_byte = 0x00; + locked_out = 0; + CMXTRACKER_ACTIVE = 0; + CMXTRACKER_ON = 1; + putstg("\r\n\r\n You have exited CMXTracker(TM), press <+> (plus key) to enter CMXTracker again!\r\n"); + break; + default: + break; + } /* end of switch */ + } /* end of e key brace */ + } /* end of endless while loop */ +} + +void cmxtracker_in_task(void) +{ + /* abyte('('); */ + cmxtracker_in(3,TASK_RUNNING,0,0,0); + /* abyte(')'); */ +} + +/* +mode: +bit 0 = on +bit 1 = +bit 2 = number of ticks +bit 3 = number of entries +bit 7 = autowake cmxtracker task +*/ +void cmxtracker_mode(byte mode, word16 count) +{ + cmxtracker_mode_byte = mode; + cmxtracker_count = count; +} + +void cmxtracker_in(byte count,byte c1,byte c2,word16 c3,void *c4) +{ + byte *copy_in_ptr; + + /* abyte('&'); */ + /* ahexw(c1 | (word16)count << 8); */ + /* abyte(' '); */ + if (CMXTRACKER_ON) + { + PROC_SAVE_INT; /* save interrupt state & disable interrupts */ + if (cmxtracker_ctr >= count) + { + cmxtracker_ctr -= count; + copy_in_ptr = cmxtracker_in_ptr; + cmxtracker_in_ptr += count; + PROC_RESTORE_INT; + + *copy_in_ptr++ = count; + *copy_in_ptr++ = activetcb - cmx_tcb; + *copy_in_ptr++ = c1; + if (count >= 4) + *copy_in_ptr++ = c2; + if (count == 5) + *copy_in_ptr++ = (c3 & 0xff); + if (count >= 6) + { + if (c1 & 0x80) + { + *copy_in_ptr++ = ((c3 >> 8) & 0xff); + *copy_in_ptr++ = (c3 & 0xff); + } + else + { +#if LARGE > 0 +#if STACK_MSB > 0 + *copy_in_ptr++ = *(((byte *) &(c4)) + 0); + *copy_in_ptr++ = *(((byte *) &(c4)) + 1); + *copy_in_ptr++ = *(((byte *) &(c4)) + 2); + *copy_in_ptr++ = *(((byte *) &(c4)) + 3); +#else + *copy_in_ptr++ = *(((byte *) &(c4)) + 3); + *copy_in_ptr++ = *(((byte *) &(c4)) + 2); + *copy_in_ptr++ = *(((byte *) &(c4)) + 1); + *copy_in_ptr++ = *(((byte *) &(c4)) + 0); +#endif +#else +#if STACK_MSB > 0 + *copy_in_ptr++ = *(((byte *) &(c4)) + 0); + *copy_in_ptr++ = *(((byte *) &(c4)) + 1); +#else + *copy_in_ptr++ = *(((byte *) &(c4)) + 1); + *copy_in_ptr++ = *(((byte *) &(c4)) + 0); +#endif +#endif + } + } + num_records++; + if (cmxtracker_mode_byte & 0x0c) + { + if (cmxtracker_count) + { + if ((cmxtracker_mode_byte & 0x08) || c1 == CMX_TIC_CALL) + if (!(--cmxtracker_count)) + if (cmxtracker_mode_byte & 0x80) + { + cmx_tcb[cmxtracker_slot].tcbstate = RESUME | TIME_EXPIRED; + PREEMPTED; + CMXTRACKER_ON = 0; + cmxtracker_wake = 1; + } + } + } + } + else + { + PROC_RESTORE_INT; + } + } +} + +static void putstg(const char *s) /* display null-terminated ASCII string thru serial port */ +{ + byte cnt; + + cnt = 0; + + while (*s) + { + if (keyflags.short_str) + { + if (cnt++ == 15) + break; + if (cnt > 12) + { + K_Track_Putchr('.'); + continue; + } + } + K_Track_Putchr(*s++); + } + keyflags.short_str = FALSE; +} + +static void cmxtracker_view(void) +{ + byte key; + byte status; + word16 record_cnt; + byte page_ctrl = 0; + byte update; + word16 temp_cnt; + byte out_cnt; + byte task_num; + byte cmx_key; + word16 page; + byte c2,c3,copy_c2 = 0; /* Nick has initialised copy_c2 = 0 for sdcc */ + byte parm1,parm2; + +#if LARGE > 0 + byte parm3,parm4; + word16 parm5,parm6; +#endif + + status = 1; + key = HOME; + page = 1; + keyflags.int_action = FALSE; + keyflags.timer_task = FALSE; + keyflags.end_key = FALSE; + + while(1) + { + if (!status) { + while(1) + { + if (keyflags.end_key) + { + key = PAGE_DOWN; + break; + } + status = K_Track_Getchr(&key); + if (status) + break; + } + } + status = 0; + switch(key) { + case 0x0D: + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + return; + break; + case HOME: + keyflags.int_action = FALSE; + keyflags.timer_task = FALSE; + update = 1; + page = 1; + record_cnt = 0; + break; + case END: + keyflags.int_action = FALSE; + keyflags.timer_task = FALSE; + putstg("\r\n\r\n Computing END ...\r\n"); + keyflags.end_key = TRUE; + update = 1; + page = 1; + record_cnt = 0; + break; + case PAGE_DOWN: + page_ctrl = 2; + update = 1; + break; + case PAGE_UP: + page_ctrl = 1; + update = 1; + break; + default: + break; + } + if (update) + { + if (page_ctrl == 1) + { + keyflags.int_action = FALSE; + keyflags.timer_task = FALSE; + /* page up */ + if (page >= 2) + { + page--; + record_cnt = rec_cnt[page]; + } + else + { + update = 0; + page_ctrl = 0; + continue; + } + } + else if (page_ctrl == 2) + { + /* page down */ + if (record_cnt >= (num_records)) + { + if (keyflags.end_key) + { + keyflags.end_key = FALSE; + record_cnt = rec_cnt[page]; + } + else + { + update = 0; + page_ctrl = 0; + continue; + } + } + else + { + page++; + } + } + update = 0; + page_ctrl = 0; + if (record_cnt < (num_records - 1)) + { + cmxtracker_out_ptr = cmxtracker_array; + for (temp_cnt = record_cnt; temp_cnt > 0; --temp_cnt) + { + cmxtracker_out_ptr += *cmxtracker_out_ptr; + } + } + if (!keyflags.end_key) + { + putstg("\r\n\r\n View CMXTRACKER contents, , , , or to quit"); + putstg("\r\n\r\n PAGE Number "); + putword(page); + putstg("\r\n"); + } + rec_cnt[page] = record_cnt; + for (temp_cnt = 0; (temp_cnt < LOG_DISPLAY_LEN) || (temp_cnt == 0xffff); temp_cnt++) + { + if (record_cnt < (num_records)) + { + out_cnt = *cmxtracker_out_ptr++; + task_num = *cmxtracker_out_ptr++; + cmx_key = *cmxtracker_out_ptr++; + abyte('^'); + ahexw(cmx_key | (word16)out_cnt << 8); + abyte(' '); + if (out_cnt > 3) + { + c2 = *cmxtracker_out_ptr++; + } + if (out_cnt == 5) + { + c3 = *cmxtracker_out_ptr++; + } + if (out_cnt >= 6) + { + if (cmx_key & 0x80) + { + cmx_key &= 0x7f; + parm1 = *(byte *)cmxtracker_out_ptr++; + parm2 = *(byte *)cmxtracker_out_ptr++; + c5 = (parm1 * 256) + parm2; + } + else + { +#if LARGE > 0 + parm1 = *(byte *)cmxtracker_out_ptr++; + parm2 = *(byte *)cmxtracker_out_ptr++; + parm5 = ((parm1 * 256) + parm2); + parm3 = *(byte *)cmxtracker_out_ptr++; + parm4 = *(byte *)cmxtracker_out_ptr++; + parm6 = ((parm3 * 256) + parm4); + c6 = (byte *)((parm5 * 65536) + parm6); +#else + parm1 = *(byte *)cmxtracker_out_ptr++; + parm2 = *(byte *)cmxtracker_out_ptr++; + c6 = (byte *)((parm1 * 256) + parm2); +#endif + } + } + if (cmx_key != CMX_TIC_CALL && cmx_key != INT_ACTION && cmx_key != TIMER_TASK_ACTION) + { + if (keyflags.end_key) + { + keyflags.timer_task = FALSE; + keyflags.int_action = FALSE; + record_cnt++; + continue; + } + if (keyflags.timer_task) + { + keyflags.timer_task = FALSE; + putstg("\r\n--CYCLIC "); + putbyte(copy_c2); + } + else if (keyflags.int_action) + { + keyflags.int_action = FALSE; + putstg("\r\n++INTERRUPT "); + } + else + { + if (task_num) + { + if (task_name[task_num]) + { + putstg("\r\n"); + keyflags.short_str = TRUE; + putname(task_num); + keyflags.short_str = FALSE; + } + else + { + putstg("\r\nSlot # "); + putbyte(task_num); + } + } + else + { + putstg("\r\nUSER CODE "); + } + } + } + else + { + if (keyflags.end_key) + { + if (cmx_key == INT_ACTION || cmx_key == TIMER_TASK_ACTION) + temp_cnt--; + record_cnt++; + continue; + } + } + switch(cmx_key) { + case CMX_TIC_CALL: + putstg("\r\n>>>> CMX Tick <<<<"); + break; + case INT_ACTION: + temp_cnt--; + keyflags.int_action = TRUE; + break; + case TIMER_TASK_ACTION: + temp_cnt--; + copy_c2 = c2; + keyflags.timer_task = TRUE; + break; + case ENABLE_SLICE_CALL: + putstg("K_OS_Slice_On "); + break; + case DISABLE_SLICE_CALL: + putstg("K_OS_Slice_Off "); + break; + case CXTEND_CALL: + putstg("K_Task_End"); + break; + case CXTCRE_K_ERROR: + putstg("K_Task_Create, ERROR"); + break; + case CXTCRE_K_OK: + putstg("K_Task_Create, Successful"); + break; + case CXTPRI_K_ERROR: + putstg("K_Task_Priority, ERROR-> "); + putname(c2); + break; + case CXTPRI_K_OK: + putstg("K_Task_Priority, Successful, "); + putname(c2); + putstg(" ,NEW PRI. is"); + putbyte(c3); + break; + case CXTTRIG_K_ERROR: + putstg("K_Task_Start, ERROR-> "); + putname(c2); + break; + case CXTTRIG_K_OK: + putstg("K_Task_Start, Successful, "); + putname(c2); + break; + case CXTWATM_CALL: + putstg("K_Task_Wait "); + puttime(); + break; + case CXTWATM_DELAY_K_ERROR: + putstg("K_Task_Wait, Timed Out"); + break; + case CXTWATM_DELAY_K_OK: + putstg("K_Task_Wait, woken by K_Task_Wake"); + break; + case CXTWAK_K_ERROR: + putstg("K_Task_Wake, ERROR-> task "); + putname(c2); + break; + case CXTWAK_K_OK: + putstg("K_Task_Wake, Successful, "); + putname(c2); + break; + case CXTWAK_K_NOT_WAITING: + putstg("K_Task_Wake, ERROR-> not waiting, "); + putname(c2); + break; + case CXPRVR_CALL: + putstg("K_Task_Lock, Successful"); + break; + case CXPRVL_CALL: + putstg("K_Task_Unlock, Successful"); + break; + case CXSCHED_CALL: + putstg("K_Task_Coop_Sched"); + break; + case CXTRMV_K_ERROR: + putstg("K_Task_Delete, ERROR-> "); + putname(c2); + break; + case CXTRMV_WAIT_K_ERROR: + putstg("K_Task_Delete, ERROR-> BUSY, "); + putname(c2); + break; + case CXTRMV_K_OK: + putstg("K_Task_Delete, Successful, "); + putname(c2); + break; + case CXERST_K_ERROR: + putstg("K_Event_Reset, ERROR-> "); + putname(c2); + break; + case CXERST_K_OK: + putstg("K_Event_Reset, Successful, "); + putname(c2); + putstg(" Event bits reset = 0x"); + puthexword(c5); + break; + case CXEWATM_CALL: + putstg("K_Event_Wait "); + puttime(); + break; + case CXEWATM_DELAY_K_TIMEOUT: + putstg("K_Event_Wait, Timed Out"); + break; + case CXEWATM_K_OK: + putstg("K_Event_Wait, Successful, Event bits match = 0x"); + puthexword(c5); + break; + case CXESIG_MODE: + putstg("K_Event_Signal, ERROR-> mode # "); + putbyte(c2); + break; + case CXESIG_K_ERROR: + putstg("K_Event_Signal, ERROR-> "); + putname(c2); + break; + case CXESIG_K_OK: + putstg("K_Event_Signal, Successful, Mode "); + putbyte(c2); + if (c2 < 3) + { + putname(c3); + } + else if (c2 == 3) + { + putstg("ALL Tasks"); + } + else if (c2 == 4) + { + putstg("ALL Tasks Waiting"); + } + else if (c2 == 5) + { + putstg("ALL Tasks same PRI."); + } + else if (c2 == 6) + { + putstg("ALL Tasks same PRI. Waiting"); + } + break; + case CXRSRSV_K_ERROR: + if (c3) + putstg("K_Resource_Get, ERROR-> resource # "); + else + putstg("K_Resource_Wait, ERROR-> resource # "); + putbyte(c2); + break; + case CXRSRSV_K_RESOURCE_OWNED: + putstg("K_Resource_Get, ERROR-> already owned, resource # "); + putbyte(c2); + break; + case CXRSRSV_CALL: + putstg("K_Resource_Wait, resource # "); + putbyte(c2); + puttime(); + break; + case CXRSRSV_DELAY_K_TIMEOUT: + putstg("K_Resource_Wait, Timed Out"); + break; + case CXRSRSV_K_OK: + if (c3) + putstg("K_Resource_Get, Successful, resource # "); + else + putstg("K_Resource_Wait, Successful, resource # "); + putbyte(c2); + break; + case CXRSREL_K_ERROR: + putstg("K_Resource_Release, ERROR-> resource # "); + putbyte(c2); + break; + case CXRSREL_K_RESOURCE_NOT_OWNED: + putstg("K_Resource_Release, ERROR-> not owned, resource # "); + putbyte(c2); + break; + case CXRSREL_K_OK: + putstg("K_Resource_Release, Successful, resource # "); + putbyte(c2); + break; + case CXQCRE_K_ERROR: + putstg("K_Que_Create, ERROR-> queue # "); + putbyte(c2); + break; + case CXQCRE_K_OK: + putstg("K_Que_Create, Successful, queue # "); + putbyte(c2); + break; + case CXQRST_K_ERROR: + putstg("K_Que_Reset, ERROR-> queue # "); + putbyte(c2); + break; + case CXQRST_K_OK: + putstg("K_Que_Reset, Successful, queue # "); + putbyte(c2); + break; + case CXQADD_K_ERROR: + putstg("K_I_Que_Add_Common, ERROR-> Range: queue # "); + putbyte(c2); + break; + case CXQADD_FULL: + putstg("K_I_Que_Add_Common, ERROR-> Full: queue # "); + putbyte(c2); + break; + case CXQADD_K_OK: + putstg("K_I_Que_Add_Common, Successful, queue # "); + putbyte(c2); + break; + case CXQRMV_K_ERROR: + putstg("K_I_Que_Get_Common, ERROR-> Range: queue # "); + putbyte(c2); + break; + case CXQRMV_EMPTY: + putstg("K_I_Que_Get_Common, ERROR-> Empty: queue # "); + putbyte(c2); + break; + case CXQRMV_K_OK: + putstg("K_I_Que_Get_Common, Successful, queue # "); + putbyte(c2); + break; + case CXMSWATM_K_ERROR: + if (c3) + putstg("K_Mesg_Get, ERROR-> range, MBOX # "); + else + putstg("K_Mesg_Wait, ERROR-> range, MBOX # "); + putbyte(c2); + break; + case CXMSWATM_MAILBOX_K_ERROR: + if (c3) + putstg("K_Mesg_Get, ERROR-> MBOX owned, MBOX # "); + else + putstg("K_Mesg_Wait, ERROR-> MBOX owned, MBOX # "); + putbyte(c2); + break; + case CXMSWATM_NOMESG_K_ERROR: + putstg("K_Mesg_Wait, ERROR-> Timed Out, no messages, MBOX # "); + putbyte(c2); + break; + case CXMSGET_NOMESG_K_ERROR: + putstg("K_Mesg_Get, ERROR-> no messages, MBOX # "); + putbyte(c2); + break; + case CXMSWATM_CALL: + putstg("K_Mesg_Wait, MBOX # "); + putbyte(c2); + puttime(); + break; + case CXMSGET_K_OK: + putstg("K_Mesg_Get, Successful, MBOX # "); + putbyte(c2); + putstg(" Mesg. recv = "); + keyflags.short_str = TRUE; + putstg((char *)c6); + break; + case CXMSWATM_K_OK: + putstg("K_Mesg_Wait, Successful, MBOX # "); + putbyte(c2); + putstg(" Mesg. recv = "); + keyflags.short_str = TRUE; + putstg((char *)c6); + break; + case CXMSSEND_K_ERROR: + if (c3) + putstg("K_Mesg_Send_Wait, ERROR-> Range/NO MSG slots, MBOX # "); + else + putstg("K_Mesg_Send, ERROR-> Range/NO MSG slots, MBOX # "); + putbyte(c2); + break; + case CXMSSENW_K_OK: + putstg("K_Mesg_Send_Wait, Successful, MBOX # "); + putbyte(c2); + putstg(" Mesg. sent = "); + keyflags.short_str = TRUE; + putstg((char *)c6); + break; + case CXMSSEND_CALL: + putstg("K_Mesg_Send_Wait, MBOX # "); + putbyte(c2); + puttime(); + break; + case CXMSSEND_K_TIMEOUT: + putstg("K_Mesg_Send_Wait, ERROR-> Timed Out WAITING for ACK, MBOX # "); + putbyte(c2); + break; + case CXMSSEND_K_OK: + putstg("K_Mesg_Send_Wait, Successful, ACKED by receiving task, MBOX # "); + putbyte(c2); + break; + case CXMSSEND_K_OK1: + putstg("K_Mesg_Send, Successful, MBOX # "); + putbyte(c2); + putstg(" Mesg. sent = "); + keyflags.short_str = TRUE; + putstg((char *)c6); + break; + case CXMSBXEV_K_ERROR: + putstg("K_Mbox_Event_Set, ERROR-> range, MBOX # "); + putbyte(c2); + break; + case CXMSBXEV_K_OK: + putstg("K_Mbox_Event_Set, Successful, MBOX # "); + putbyte(c2); + break; + case CXMSACK_K_OK: + putstg("K_Mesg_Ack_Sender, Successful, "); + putname(c2); + break; + case CXCTCRE_K_ERROR: + putstg("K_Timer_Create, ERROR-> Range: cyclic timer # "); + putbyte(c2); + break; + case CXCTCRE_K_OK: + putstg("K_Timer_Create, Successful, cyclic timer # "); + putbyte(c2); + break; + case CXCTCOM_K_ERROR: + putstg("K_I_Cyclic_Common, ERROR-> Range: cyclic timer # "); + putbyte(c2); + break; + case CXCTSTT_K_OK: + putstg("K_Timer_Start, Successful, cyclic timer # "); + putbyte(c2); + break; + case CXCTRSTC_K_OK: + putstg("K_Timer_Cyclic, Successful, cyclic timer # "); + putbyte(c2); + break; + case CXCTRSTI_K_OK: + putstg("K_Timer_Initial, Successful, cyclic timer # "); + putbyte(c2); + break; + case CXCTRSTT_K_OK: + putstg("K_Timer_Restart, Successful, cyclic timer # "); + putbyte(c2); + break; + case CXCTSTP_K_ERROR: + putstg("K_Timer_Stop, ERROR-> Range: cyclic timer # "); + putbyte(c2); + break; + case CXCTSTP_K_OK: + putstg("K_Timer_Stop, Successful, cyclic timer # "); + putbyte(c2); + break; + case CXBFCRE_K_OK: + putstg("K_Mem_FB_Create, Successful, Memory Block BASE address 0x"); +#if LARGE > 0 + pichexlong(((large_ptr)(c6)),0); /* address */ +#else + pichexword(((void *)(c6)),0); /* address */ +#endif + break; + case CXBFGET_K_OK: + putstg("K_Mem_FB_Get, Successful, Memory address is 0x"); +#if LARGE > 0 + pichexlong(((large_ptr)(c6)),0); /* address */ +#else + pichexword(((void *)(c6)),0); /* address */ +#endif + break; + case CXBFGET_K_ERROR: + putstg("K_Mem_FB_Get, ERROR-> none free, Memory Block base address 0x"); +#if LARGE > 0 + pichexlong(((large_ptr)(c6)),0); /* address */ +#else + pichexword(((void *)(c6)),0); /* address */ +#endif + break; + case CXBFREL_K_OK: + putstg("K_Mem_FB_Release, Successful, Memory address returned 0x"); +#if LARGE > 0 + pichexlong(((large_ptr)(c6)),0); /* address */ +#else + pichexword(((void *)(c6)),0); /* address */ +#endif + break; + case TASK_RUNNING: + putstg("EXECUTING"); + break; + case INT_ENTRY: + putstg("INTERRUPT # "); + putbyte(c2); + break; + case USER_ENTRY: + putstg("USER ENTRY, entry # "); + putbyte(c2); + break; + default: + putstg("Not valid command"); + break; + } + record_cnt++; + } + } + if (!keyflags.end_key) + putstg("\r\n"); + } + } +} + +void delay_tick(void) +{ + + prompt_index = DELAY_TICK_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + /* maybe change to decimal, later */ + if (hex_long < 0xffff && hex_long) + { + putstg("\r\nBUG task, waiting for the following number of TICKS "); + putword((word16)hex_long); + cmxtracker_mode_byte = 0x00; + CMXTRACKER_ON = 1; + CMXTRACKER_ACTIVE = 0; + locked_out = 0; + K_Task_Wait((word16)hex_long); + locked_out = 1; + CMXTRACKER_ACTIVE = 1; + CMXTRACKER_ON = 0; + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + break; + } + else + { + putstg("\r\nMust be non zero number and less 65536!"); + func_offset = 0; + keyflags.cont = TRUE; + break; + } + } +} + +void quick_tick(void) +{ + cmxtracker_mode_byte = 0x00; + CMXTRACKER_ON = 1; + CMXTRACKER_ACTIVE = 0; + locked_out = 0; + K_Task_Wait(1); + locked_out = 1; + CMXTRACKER_ACTIVE = 1; + CMXTRACKER_ON = 0; + keyflags.f_key = TRUE; + keyflags.cont = TRUE; +} + +static void clear_chars_in(void) +{ + in_char_ptr = keys_in_buff; + do { + *in_char_ptr++ = 0; + } while (in_char_ptr != &keys_in_buff[sizeof keys_in_buff]); + in_char_ptr = keys_in_buff; + num_chars_in = 0; +} + +static void conv_hex(void) +{ + + byte *hex_char_ptr; + word16 multiplier; + + abyte('!'); + + multiplier = 1; + hex_long = 0; + if (max_chars_in == 1) + { + hex_char_ptr = keys_in_buff; + hex_byte = *hex_char_ptr; + hex_long = (long)hex_byte; + } + else + { + hex_char_ptr = &keys_in_buff[max_chars_in-2]; + if (keyflags.allow_hex) + { + hex_byte = *hex_char_ptr * 16; + hex_char_ptr++; + hex_byte += *hex_char_ptr; + } + else + { +#if 0 + abyte('H'); + ahexw(*hex_char_ptr); + abyte(' '); +#endif + hex_byte = *hex_char_ptr * 10; + hex_char_ptr++; +#if 0 + abyte('L'); + ahexw(*hex_char_ptr); + abyte(' '); +#endif + hex_byte += *hex_char_ptr; + } + for (hex_char_ptr = &keys_in_buff[max_chars_in - 1]; + hex_char_ptr >= keys_in_buff; --hex_char_ptr) + { + hex_long += *hex_char_ptr * multiplier; + if (keyflags.allow_hex) + multiplier *= 16; + else + multiplier *= 10; + } + } + + abyte('@'); +} + +static void zerofill(byte *mov_char_ptr) +{ + byte count; + byte *copy_in_char_ptr; + + if (num_chars_in != max_chars_in) + { + copy_in_char_ptr = in_char_ptr; + for (count = 0; count < num_chars_in; count++) + { + *(--mov_char_ptr) = *(--in_char_ptr); +#if 0 + abyte('M'); + ahexw(*mov_char_ptr); + abyte(' '); +#endif + } + for (count = num_chars_in; count < max_chars_in; count++) + { + *(--mov_char_ptr) = 0x00; + } + in_char_ptr = copy_in_char_ptr; + } +} +static void display_char(char x) +{ + if (!keyflags.echo_off) + K_Track_Putchr(x); +} +void cmxtracker_reset(void) +{ + prompt_index = CMXTRACKER_RESET_PROMPT; + + switch (func_offset) { + case 0x00: /* display 1'st prompt */ + putcrlf(); + prompt_out(); + break; + case 0x80: /* process card number prompt */ + func_offset &= 0x7f; + if (hex_byte) + { + init_cmxtracker(); + } + keyflags.f_key = TRUE; + keyflags.cont = TRUE; + break; + } +} +static void putcrlf(void) +{ + K_Track_Putchr(0x0d); + K_Track_Putchr(0x0a); +} /* putcrlf */ +static void prompt_out(void) +{ + + prpt_ptr = &prpt_array[prompt_index + func_offset]; + /* chars_in(); */ + keyflags.non_zero = FALSE; + max_chars_in = prpt_ptr->in_length; + clear_chars_in(); + putstg(prpt_ptr->word); +} + +static void putbyte(byte num) /* output a number (decimal) */ +{ + + byte digit,suppress; + byte divisor; + + divisor = 100; + suppress = 1; + + while( !( divisor == 1 )){ + digit = num / divisor; + num = num - (digit * divisor); + divisor = divisor / 10; + if( suppress && digit ) + suppress = 0; + if( !suppress ) + digit |= '0'; + else + digit = ' '; + K_Track_Putchr(digit); + } + K_Track_Putchr(num+'0'); + K_Track_Putchr(' '); +} + +static void putword(word16 num) /* output a number (decimal) */ +{ + + byte digit,suppress; + word16 divisor; + + divisor = 10000; + suppress = 1; + + while( !( divisor == 1 )){ + digit = num / divisor; + num = num - (digit * divisor); + divisor = divisor / 10; + if( suppress && digit ) + suppress = 0; + if( !suppress ) + digit |= '0'; + else + digit = ' '; + K_Track_Putchr(digit); + } + K_Track_Putchr((char)(num+'0')); +} + +static void puttime(void) +{ + putstg(" TIME PERIOD = "); + putword(c5); +} + +static void pichexlong(large_ptr w,byte m) /* puts out long word in hex */ +{ +#if BIG_ENDIAN > 0 + puthexbyte(*(((byte *) &(w)) + 0)); + puthexbyte(*(((byte *) &(w)) + 1)); + K_Track_Putchr(':'); + puthexbyte(*(((byte *) &(w)) + 2)); + if (m) + puthexbyte((*(((byte *) &(w)) + 3)) & 0xf0); + else + puthexbyte(*(((byte *) &(w)) + 3)); + K_Track_Putchr(' '); +#else + puthexbyte(*(((byte *) &(w)) + 3)); + puthexbyte(*(((byte *) &(w)) + 2)); + K_Track_Putchr(':'); + puthexbyte(*(((byte *) &(w)) + 1)); + if (m) + puthexbyte((*(((byte *) &(w)) + 0)) & 0xf0); + else + puthexbyte(*(((byte *) &(w)) + 0)); + K_Track_Putchr(' '); +#endif +} /* pichexlong */ + +static void pichexword(void *w,byte m) /* puts out long word in hex */ +{ +#if BIG_ENDIAN > 0 + puthexbyte(*(((byte *) &(w)) + 0)); + if (m) + puthexbyte((*(((byte *) &(w)) + 1)) & 0xf0); + else + puthexbyte(*(((byte *) &(w)) + 1)); + K_Track_Putchr(' '); +#else + puthexbyte(*(((byte *) &(w)) + 1)); + if (m) + puthexbyte((*(((byte *) &(w)) + 0)) & 0xf0); + else + puthexbyte(*(((byte *) &(w)) + 0)); + K_Track_Putchr(' '); +#endif +} /* pichexword */ + +static void puthexbyte(byte b) /* puts out byte in ASCII hex, to serial port */ +{ + K_Track_Putchr(nibs[ b >> 4 ]); + K_Track_Putchr(nibs[ b & 0x0F ]); +} /* puthexbyte */ + +static void puthexword(word16 w) +/* Put out word in hex, high byte first. */ +{ + puthexbyte((byte)(w>>8)); + puthexbyte((byte)(w & 0xff)); +} /* puthexword */ + +static void putname(char c2) /* display null-terminated ASCII string thru serial port */ +{ + byte ctr; + char *s; + + if (!c2) + return; + if (!task_name[c2]) + { + putstg("Slot # "); + putbyte(c2); + putstg(" "); + } + else + { + ctr = 0; + if (!keyflags.short_str) + putstg("Task "); + s = task_name[c2]; + do { + if (*s) + K_Track_Putchr(*s++); + else + K_Track_Putchr(' '); + } while (++ctr < 13 ); + } +} + diff --git a/src/kernel/cmx/cmxtrack.h b/src/kernel/cmx/cmxtrack.h new file mode 100755 index 00000000..a815352e --- /dev/null +++ b/src/kernel/cmx/cmxtrack.h @@ -0,0 +1,92 @@ +enum cmxtracker_types {CMX_TIC_CALL = 0x20, + INT_ACTION, + TIMER_TASK_ACTION, + ENABLE_SLICE_CALL, + DISABLE_SLICE_CALL, + CXTEND_CALL, + CXTCRE_K_ERROR, + CXTCRE_K_OK, + CXTPRI_K_ERROR, + CXTPRI_K_OK, + CXTTRIG_K_ERROR, + CXTTRIG_K_OK, + CXTWATM_CALL, + CXTWATM_DELAY_K_ERROR, + CXTWATM_DELAY_K_OK, + CXTWAK_K_ERROR, + CXTWAK_K_OK, + CXTWAK_K_NOT_WAITING, + CXPRVR_CALL, + CXPRVL_CALL, + CXSCHED_CALL, + CXTRMV_K_ERROR, + CXTRMV_WAIT_K_ERROR, + CXTRMV_K_OK, + CXERST_K_ERROR, + CXERST_K_OK, + CXEWATM_CALL, + CXEWATM_DELAY_K_TIMEOUT, + CXEWATM_K_OK, + CXESIG_MODE, + CXESIG_K_ERROR, + CXESIG_K_OK, + CXRSRSV_K_ERROR, + CXRSRSV_K_RESOURCE_OWNED, + CXRSRSV_CALL, + CXRSRSV_DELAY_K_TIMEOUT, + CXRSRSV_K_OK, + CXRSREL_K_ERROR, + CXRSREL_K_RESOURCE_NOT_OWNED, + CXRSREL_K_OK, + CXQCRE_K_ERROR, + CXQCRE_K_OK, + CXQRST_K_ERROR, + CXQRST_K_OK, + CXQADD_K_ERROR, + CXQADD_FULL, + CXQADD_K_OK, + CXQRMV_K_ERROR, + CXQRMV_EMPTY, + CXQRMV_K_OK, + CXMSWATM_K_ERROR, + CXMSWATM_MAILBOX_K_ERROR, + CXMSWATM_NOMESG_K_ERROR, + CXMSGET_NOMESG_K_ERROR, + CXMSWATM_CALL, + CXMSGET_K_OK, + CXMSWATM_K_OK, + CXMSSEND_K_ERROR, + CXMSSENW_K_OK, + CXMSSEND_CALL, + CXMSSEND_K_TIMEOUT, + CXMSSEND_K_OK, + CXMSSEND_K_OK1, + CXMSBXEV_K_ERROR, + CXMSBXEV_K_OK, + CXMSACK_K_OK, + CXCTCRE_K_ERROR, + CXCTCRE_K_OK, + CXCTCOM_K_ERROR, + CXCTSTT_K_OK, + CXCTRSTC_K_OK, + CXCTRSTI_K_OK, + CXCTRSTT_K_OK, + CXCTSTP_K_ERROR, + CXCTSTP_K_OK, + CXBFCRE_K_OK, + CXBFGET_K_OK, + CXBFGET_K_ERROR, + CXBFREL_K_OK, + TASK_RUNNING, + INT_ENTRY, + USER_ENTRY + }; + +void cmxtracker_in(byte,byte,byte,word16,void *); + +#define cmxtracker_in1(A) cmxtracker_in(3,A,0,0,0) +#define cmxtracker_in2(A,B) cmxtracker_in(4,A,B,0,0) +#define cmxtracker_in3(A,B,C) cmxtracker_in(5,A,B,C,0) +#define cmxtracker_in4(A,B,C) cmxtracker_in(6,(byte)(A | 0x80),B,C,0) +#define cmxtracker_in5(A,B,C) cmxtracker_in((byte)((sizeof (byte *) + 4)),A,B,0,C) + diff --git a/src/kernel/cmx/cmxtrack.txt b/src/kernel/cmx/cmxtrack.txt new file mode 100755 index 00000000..3713e034 --- /dev/null +++ b/src/kernel/cmx/cmxtrack.txt @@ -0,0 +1,82 @@ +20 CMX_TIC_CALL +21 INT_ACTION +22 TIMER_TASK_ACTION +23 ENABLE_SLICE_CALL +24 DISABLE_SLICE_CALL +25 CXTEND_CALL +26 CXTCRE_K_ERROR +27 CXTCRE_K_OK +28 CXTPRI_K_ERROR +29 CXTPRI_K_OK +2A CXTTRIG_K_ERROR +2B CXTTRIG_K_OK +2C CXTWATM_CALL +2D CXTWATM_DELAY_K_ERROR +2E CXTWATM_DELAY_K_OK +2F CXTWAK_K_ERROR +30 CXTWAK_K_OK +31 CXTWAK_K_NOT_WAITING +32 CXPRVR_CALL +33 CXPRVL_CALL +34 CXSCHED_CALL +35 CXTRMV_K_ERROR +36 CXTRMV_WAIT_K_ERROR +37 CXTRMV_K_OK +38 CXERST_K_ERROR +39 CXERST_K_OK +3A CXEWATM_CALL +3B CXEWATM_DELAY_K_TIMEOUT +3C CXEWATM_K_OK +3D CXESIG_MODE +3E CXESIG_K_ERROR +3F CXESIG_K_OK +40 CXRSRSV_K_ERROR +41 CXRSRSV_K_RESOURCE_OWNED +42 CXRSRSV_CALL +43 CXRSRSV_DELAY_K_TIMEOUT +44 CXRSRSV_K_OK +45 CXRSREL_K_ERROR +46 CXRSREL_K_RESOURCE_NOT_OWNED +47 CXRSREL_K_OK +48 CXQCRE_K_ERROR +49 CXQCRE_K_OK +4A CXQRST_K_ERROR +4B CXQRST_K_OK +4C CXQADD_K_ERROR +4D CXQADD_FULL +4E CXQADD_K_OK +4F CXQRMV_K_ERROR +50 CXQRMV_EMPTY +51 CXQRMV_K_OK +52 CXMSWATM_K_ERROR +53 CXMSWATM_MAILBOX_K_ERROR +54 CXMSWATM_NOMESG_K_ERROR +55 CXMSGET_NOMESG_K_ERROR +56 CXMSWATM_CALL +57 CXMSGET_K_OK +58 CXMSWATM_K_OK +59 CXMSSEND_K_ERROR +5A CXMSSENW_K_OK +5B CXMSSEND_CALL +5C CXMSSEND_K_TIMEOUT +5D CXMSSEND_K_OK +5E CXMSSEND_K_OK1 +5F CXMSBXEV_K_ERROR +60 CXMSBXEV_K_OK +61 CXMSACK_K_OK +62 CXCTCRE_K_ERROR +63 CXCTCRE_K_OK +64 CXCTCOM_K_ERROR +65 CXCTSTT_K_OK +66 CXCTRSTC_K_OK +67 CXCTRSTI_K_OK +68 CXCTRSTT_K_OK +69 CXCTSTP_K_ERROR +6A CXCTSTP_K_OK +6B CXBFCRE_K_OK +6C CXBFGET_K_OK +6D CXBFGET_K_ERROR +6E CXBFREL_K_OK +6F TASK_RUNNING +70 INT_ENTRY +71 USER_ENTRY diff --git a/src/kernel/cmx/copyr.asm b/src/kernel/cmx/copyr.asm new file mode 100755 index 00000000..7b1af16d --- /dev/null +++ b/src/kernel/cmx/copyr.asm @@ -0,0 +1,310 @@ +; copyr.asm +; Reentrant DMA copy routine for Hytech CMX, doesn't disable ints for too long + +; ----------------------------------------------------------------------------- + +$ io64180.inc + +BITE equ 32 +BITELOG equ 5 + +PBITE equ 16 +PBITELOG equ 4 + + extern abyte, ahexw, ahexn, acrlf + +; copy routine +; ------------ + +; copy bc bytes from d:iy --> e:hl + +; 10 bits @ 38400 == 260 usec +; 1 dma cycle (read+write) == 6 t-states == .977 usec +; so 266 dma cycles burst per character 6*266 = 1596 +; we will use a max of 256 characters burst mode 6*256 = 1536 + + rseg RCODE + + public _copyr + +_copyr: push iy + + push de + pop iy + ld d,c ; d:iy = entry c:de -> source data + + ld hl,9 + add hl,sp + ld b,(hl) + dec hl + ld c,(hl) ; bc = entry (sp+6) = byte count + + dec hl + dec hl + ld e,(hl) + dec hl + ld a,(hl) + dec hl + ld l,(hl) + ld h,a ; e:hl = entry (sp+2) -> destination + call copyr + + pop iy + ret + + public copyb + +copyb: ld bc,1 + + public copyr + +copyr: + .if 0 ; diagnostic + push hl + + ld a,d + call ahexn + ld a,':' + call abyte + + push iy + pop hl + call ahexw + + ld a,' ' + call abyte + + ld a,e + call ahexn + ld a,':' + call abyte + + pop hl + push hl + call ahexw + + ld a,' ' + call abyte + + ld l,c + ld h,b + call ahexw + + call acrlf + + pop hl + .endif + ld a,e + cp 4 + .if 1 + jp nc,copyrp + .else + jr nc,copyrp + .endif + + .if 1 + LD A,C + AND BITE-1 ;00011111B +; JR Z,CPYL0 + PUSH BC + LD C,A + LD B,0 + .if 1 + di +; out0 (BCR0L),c + call cpyst0 + inc c + dec c + jr z,cpyl0 + in0 a,(DSTAT) + xor 01010000b + out0 (DSTAT),a + add iy,bc + call c,inc_d + add hl,bc + call c,inc_e +cpyl0: + .else + CALL CPYBC + .endif + .if 0 +; POP BC +; .if 0 +; LD A,C +; AND .binnot.(BITE-1) ;11100000B +; LD C,A +; .endif +;CPYL0: +; POP AF ; HIGH ORDER CNT +; PUSH HL +; LD L,C +; LD H,B + ex (sp),hl + sub a ; high order count + LD B,8-BITELOG ;3 +CPYL1: ADD HL,HL + ADC A,A + DJNZ CPYL1 ; A:H = A:HL/BITE ;32 + LD C,H + LD B,A + POP HL + .else + pop bc + ld a,BITELOG ;5 +cpyl30: srl b + rr c + dec a + jr nz,cpyl30 ; bc = bc/BITE ;32 + .endif + JR CPYL3 +CPYL2: PUSH BC + LD BC,BITE ;32 + .if 1 + ei +; out0 (BCR0L+1),b + out0 (BCR0L),c + di +; in0 (BCR0L+1) ;f,(BCR0L+1) +; call z,cpyst0 + in0 (BCR0L) + call z,cpyst0 + in0 a,(DSTAT) + xor 01010000b + out0 (DSTAT),a + add iy,bc + call c,inc_d + add hl,bc + call c,inc_e + .else + CALL CPYBCI + .endif + POP BC + DEC BC +CPYL3: LD A,B + OR C + JR NZ,CPYL2 + .else + push bc + ld b,0 + di +; out0 (BCR0L),c + call cpyst0 + inc c + dec c + jr z,cpyl0 + in0 a,(DSTAT) + xor 01010000b + out0 (DSTAT),a + add iy,bc + call c,inc_d + add hl,bc + call c,inc_e +cpyl0: pop bc + inc b + jr cpyl1 +cpyl2: push bc + ld bc,100h + ei + out0 (BCR0L+1),b + di + in0 (BCR0L+1) ;f,(BCR0L+1) + call z,cpyst0 + in0 a,(DSTAT) + xor 01010000b + out0 (DSTAT),a + add iy,bc + call c,inc_d + add hl,bc + call c,inc_e + pop bc +cpyl1: djnz cpyl2 + .endif + ei + ret + +cpyst0: + out0 (BCR0L),c + out0 (BCR0L+1),b + jr cpyst2 +cpyst1: ld a,1 + out0 (BCR0L),a +cpyst2: push hl + push iy + out0 (DAR0L),l + out0 (DAR0L+1),h + out0 (DAR0L+2),e + pop hl + out0 (SAR0L),l + out0 (SAR0L+1),h + out0 (SAR0L+2),d + pop hl + ld a,2 ; memory+ --> memory+, burst mode + out0 (DMODE),a + ret + +inc_d: inc d + ret +inc_e: inc e + ret + +copyrp: push bc + xor a + di + out0 (BCR0L),a + out0 (BCR0L+1),a + .if 0 + push hl + ld l,c + ld h,b + sub a ; high order count + LD B,8-PBITELOG +CPYL1X: ADD HL,HL + ADC A,A + DJNZ CPYL1X ; A:H = A:HL/PBITE ;32 + LD C,H + LD B,A + pop hl + .else + ld a,PBITELOG ;5 +cpyl31: srl b + rr c + dec a + jr nz,cpyl31 ; bc = bc/PBITE ;32 + .endif + ld a,b + or c + jr z,cpyc0 +cpyl4: push bc ; 1464 t-states for this loop + ld bc,PBITE + call cpybc0 + pop bc + dec bc + di + ld a,b + or c + jr nz,cpyl4 +cpyc0: pop bc + ld b,a ; 0 + ld a,c + and PBITE-1 ;00011111b + jr z,cpyl5 + ld c,a +cpybc0: in0 (BCR0L) ;f,(BCR0L) + call z,cpyst1 + add iy,bc ; 1396 t-states for this subroutine + call c,inc_d ; 32 bytes, no boundary + add hl,bc ; no interrupt, no dma1 cycle steal + call c,inc_e + ld b,c + ld c,1 + in0 a,(DSTAT) + xor 01010000b +cpybc1: out0 (DSTAT),a + out0 (BCR0L),c + djnz cpybc1 +cpyl5: ei + ret + +; ----------------------------------------------------------------------------- + + END diff --git a/src/kernel/cmx/cxconfig.h b/src/kernel/cmx/cxconfig.h new file mode 100755 index 00000000..fcd64b92 --- /dev/null +++ b/src/kernel/cmx/cxconfig.h @@ -0,0 +1,58 @@ +/********************************************************************* + The following will be included when the cmx_init.c program gets + compiled. These are set the maximums for a variety of things. This way + CMX can pre-allocate the needed memory to accomplish the user + needs. This is so no memory allocation functions are needed by + CMX, and no delays are introduced to obtain the needed memory during + run time. + + The user is free to make a copy of this file for each application + program, so each application program will have their own "cxconfig.h" + file. Also the user should probally copy the cmx_init.c file to a "user + name file", for each application program. This way the user does not + have to change "this" file each time a different application program + is worked with. Just remember to make sure you change the + #include line in the user named ("cmx_init.c") file + to include the proper user named "cxconfig.h" file. + + Also if any of these defines ARE changed, then the user must be + sure to compile the cmx_init.c file (or equalivent user file) + so these NEW values take effect. +*********************************************************************/ +#define C_MAX_TASKS 10 /* Maximum number of tasks for this program. */ +#define C_MAX_RESOURCES 3 /* Maximum number of resources. */ +#define C_MAX_CYCLIC_TIMERS 5 /* Maximum number of cyclic timers. */ +#define C_MAX_MESSAGES 10 /* Maximum number of messages. */ +#define C_MAX_QUEUES 5 /* Maximum number of queues. */ +#define C_MAX_MAILBOXES 5 /* Maximum number of mailboxes. */ +#define C_MAX_SEMAPHORES 3 /* Maximum number of mailboxes. */ +#define C_TASK_STK_SIZE 1280 /* Maximum stack size of ALL tasks stacks + added together, does NOT include timer task */ +#define C_INTERRUPT_SIZE 512 /* Nick 64 /* Size of interrupt stack. The CMX timer task + K_I_Scheduler, and K_I_Intrp_Pipe_Out function use this. */ +#define C_RTC_SCALE 1 /* number of timer interrupt ticks, before CMX + tick. All time counters based on this. */ +#define C_TSLICE_SCALE 4 /* The number of timer interrupt ticks, before + forcing task to do time slice task switch. */ + +#define C_PIPE_SIZE 32 /* the size of the interrupt pipe. up to 255 big. */ + +#define CMXBUG_ENABLE 0 /* ENABLE or DISABLE CMXBug(TM) inclusion. + Set to 1 to ENABLE, set to 0 (zero) to DISABLE. + The use still must link in cmxbug.obj, for the + CMXBug code to be functional */ + +#define CMXTRACKER_ENABLE 0 /* ENABLE or DISABLE CMXTracker(TM) inclusion. + Set to 1 to ENABLE, set to 0 (zero) to DISABLE */ + +#define CMXTRACKER_SIZE 4096 /* SIZE IN BYTES of the buffer to hold the + CMXTracker COMPRESSED information. */ + +#define CMX_RAM_INIT 0 /* ENABLE or DISABLE the initialization of CMX RAM + variables. Usually done by Compiler start up code + in most cases. If not, MUST be ENABLED. Normally + compiler code will set GLOBAL variables that are + initialized and set non-initialize variables to + 0 (zero). Set to 1 to ENABLE CMX code to initialize + it's variables, set to 0 (zero) to DISABLE */ + diff --git a/src/kernel/cmx/cxdefine.h b/src/kernel/cmx/cxdefine.h new file mode 100755 index 00000000..d845448a --- /dev/null +++ b/src/kernel/cmx/cxdefine.h @@ -0,0 +1,47 @@ +#undef word16 +#undef word32 +typedef unsigned char byte; +typedef unsigned short word16; +typedef unsigned int bit_word16; +typedef signed short sign_word16; +typedef unsigned long word32; +#ifndef NULL +#define NULL 0x00 +#endif +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + + +#define RESOURCE 0x01 /* waiting on resource */ +#define WAIT 0x02 /* wait for wake */ +#define SEND_MESG 0x08 /* waiting for task that recieve message to wake me */ +#define WAIT_MESG 0x10 /* waiting on message */ +#define FLAGS 0x20 /* waiting for task user flags */ +#define TIME_EXPIRED 0x40 /* flag indicating time expired */ +#define SEMAPHORE 0x80 /* waiting for semaphore */ + +#define IDLE 0x0100 /* the task is idle state */ +#define READY 0x0200 /* the task is ready to run (from beginning) */ +#define RESUME 0X0400 /* the task is ready to run (not from beginning) */ +#define RUNNING 0x0800 /* the task is running */ +#define TIME 0x1000 /* wait on time */ + +#define ANY_WAIT (WAIT|SEND_MESG|WAIT_MESG|FLAGS|RESOURCE|SEMAPHORE) + + +/* status return values */ +#define K_OK 0x00 /* successful call */ +#define K_TIMEOUT 0x01 /* warning, time period expired or K_Task_Wake_Force was used */ +#define K_NOT_WAITING 0x02 /* error: task not waiting */ +#define K_RESOURCE_OWNED 0x05 /* error: task does not own resource */ +#define K_RESOURCE_NOT_OWNED 0x06 /* error: resource already owned */ +#define K_QUE_FULL 0x0a /* error: queue is full */ +#define K_QUE_EMPTY 0x0b /* error: queue is empty */ +#define K_SEMAPHORE_NONE 0x0c /* no semaphore posted, returned (only cxsemget call */ +#define K_ERROR 0xff /* error: general error value */ + +#define K_I_Disable_Sched() (++locked_out) /* disable task switching */ +#define K_I_Enable_Sched() {if ((cmx_flag1 & 0x37) && (locked_out == 1)) K_I_Sched(); else --locked_out; } +/* #define K_I_Enable_Sched() {abyte('!'); if ((cmx_flag1 & 0x37) && (abyte('@'), (locked_out == 1))) { abyte('#'); K_I_Sched(); } else { abyte('$'); --locked_out; } abyte('%'); } */ diff --git a/src/kernel/cmx/cxextern.h b/src/kernel/cmx/cxextern.h new file mode 100755 index 00000000..14e36f76 --- /dev/null +++ b/src/kernel/cmx/cxextern.h @@ -0,0 +1,52 @@ +extern byte MAX_TASKS; +extern byte MAX_RESOURCES; +extern byte MAX_CYCLIC_TIMERS; +extern byte MAX_MAILBOXES; +extern byte MAX_QUEUES; +extern byte RTC_SCALE; +extern byte MAX_SEMAPHORES; +extern byte TSLICE_SCALE; +extern byte SLICE_ON; + +extern struct _tcb cmx_tcb[]; + +extern MAILBOX mail_box[]; + +extern MSG message_box[]; + +extern MSG *message_ptr; +extern word16 message_free; + +extern QUEHDR queue[]; + +extern CYCLIC_TIMERS tcproc[]; + +extern CYCLIC_LNK *cyclic_lnk; + +extern CYCLIC_LNK cyclic_buf; + +extern TSK_TIMER_LNK *tsk_timer_lnk; + +extern TSK_TIMER_LNK tsk_timer_buf; + +extern RESHDR res_que[]; + +#ifdef CMXTRACKER +extern byte CMXTRACKER_ON; +#endif + +extern word16 *stack_blk; + +extern SEM sem_array[]; + +extern tcbpointer timertask; +extern byte rtc_count; + +extern tcbpointer activetcb; +extern byte active_priority; +extern byte tslice_count; + +extern word32 cmx_tick_count; + + + diff --git a/src/kernel/cmx/cxfuncs.h b/src/kernel/cmx/cxfuncs.h new file mode 100755 index 00000000..d1d0bc4b --- /dev/null +++ b/src/kernel/cmx/cxfuncs.h @@ -0,0 +1,217 @@ +#include +#include +#include + +byte K_Task_Create(byte,byte *,CMX_FP,word16); /* create task. */ +byte K_Task_Create_Stack(byte,byte *,CMX_FP,word16 *); /* create task,user supplied stack. */ +byte K_Task_Start(byte); /* start task */ +byte K_Task_Wait(word16); /* have task wait, with or without time period */ +byte K_I_Wake_Common(byte,byte); /* common wake routine */ +#define K_Task_Wake(A) K_I_Wake_Common(A,0) /* wake a task that was waiting. */ +#define K_Task_Wake_Force(A) K_I_Wake_Common(A,1) /* wake a task, regardless of what task waiting on */ +byte K_Task_Priority(byte,byte); /* change a task priority. */ +void K_Task_Lock(void); /* disable task switching */ +void K_Task_Unlock(void); /* re-enable task switching. */ +void K_Task_Coop_Sched(void); /* do a cooperative task switch. */ +void K_Task_End(void); /* must be called by all task prior to end brace. */ +byte K_Task_Delete(byte); /* remove a task. */ +byte K_Task_Name(byte,char *); /* declare a name for task. */ + +word16 K_Event_Wait(word16,word16,byte); /* wait on events, with/without time period */ +byte K_Event_Signal(byte,byte,word16); /* signal an event */ +byte K_Event_Reset(byte tskid,word16 event); /* reset events bits */ + +byte K_I_Resource_Common(byte,word16,byte); /* common resource reserve/get function */ +#define K_Resource_Wait(A,B) K_I_Resource_Common(A,B,0) /* reserve a resource, with or without time period */ +#define K_Resource_Get(A) K_I_Resource_Common(A,0,1) /* get a resource if free */ +byte K_Resource_Release(byte); /* release a resource */ + +byte K_Que_Create(sign_word16,byte,byte *,byte); /* create a circular queue */ +byte K_Que_Reset(byte); /* reset a queue */ +byte K_I_Que_Add_Common(byte,void *,sign_word16); /* common add to queue routine */ +#define K_Que_Add_Top(A,B) K_I_Que_Add_Common(A,B,1) /* add to queues top */ +#define K_Que_Add_Bottom(A,B) K_I_Que_Add_Common(A,B,0) /* add to queue's bottom */ +byte K_I_Que_Get_Common(byte,void *,sign_word16); /* common remove from queue routine */ +#define K_Que_Get_Top(A,B) K_I_Que_Get_Common(A,B,1) /* remove from queue's top */ +#define K_Que_Get_Bottom(A,B) K_I_Que_Get_Common(A,B,0) /* remove from queue's bottom */ + +void * K_I_Mesg_Wait_Common(byte,word16,byte); /* common message get/wait function */ +#define K_Mesg_Wait(A,B) K_I_Mesg_Wait_Common(A,B,0) /* wait for message, with or without time period */ +#define K_Mesg_Get(A) K_I_Mesg_Wait_Common(A,0,1) /* get a message if one is available */ +byte K_I_Mesg_Send_Common(byte,word16,void *,byte); /* common message send/wait function */ +#define K_Mesg_Send(A,B) K_I_Mesg_Send_Common(A,0,B,0) /* send message to a mailbox */ +#define K_Mesg_Send_Wait(A,B,C) K_I_Mesg_Send_Common(A,B,C,1) /* send message, wait for reciever to ACK */ +byte K_Mbox_Event_Set(byte,byte,word16); /* mailbox event setting parameters */ +byte K_Mesg_Ack_Sender(void); /* wake task that sent message */ + +byte K_Timer_Create(byte,byte,byte,word16); /* create cyclic timer */ +byte K_I_Cyclic_Common(byte,word16,word16,byte); /* common function for next 4 functions */ +#define K_Timer_Start(A,B,C) K_I_Cyclic_Common(A,B,C,3) /* start cyclic timer */ +#define K_Timer_Restart(A) K_I_Cyclic_Common(A,0,0,0) /* re-start cyclic timer */ +#define K_Timer_Initial(A,B) K_I_Cyclic_Common(A,B,0,1) /* re-start timer, with new initial time */ +#define K_Timer_Cyclic(A,B) K_I_Cyclic_Common(A,0,B,2) /* re-start timer, with new cyclic time */ +byte K_Timer_Stop(byte); /* stop cyclic timer */ + +void K_Mem_FB_Create(void *,word16,word16); /* create fixed memory block */ +byte K_Mem_FB_Get(void *,byte **); /* get a block of memory */ +void K_Mem_FB_Release(void *,byte *); /* release a block of memory */ + +byte K_I_Semaphore_Get_Common(byte,word16,byte); +#define K_Semaphore_Get(A) K_I_Semaphore_Get_Common(A,0,1) +#define K_Semaphore_Wait(A,B) K_I_Semaphore_Get_Common(A,B,0) +byte K_Semaphore_Post(byte); +byte K_Semaphore_Create(byte,word16); +byte K_Semaphore_Reset(byte,byte); +byte K_OS_Task_Slot_Get(void); +word32 K_OS_Tick_Get_Ctr(void); + +void K_OS_Slice_On(void); /* Enable time slicing */ +void K_OS_Slice_Off(void); /* Disable time slicing */ + +void K_OS_Init(void); /* initialize CMX */ +void K_OS_Low_Power_Func(void); /* reduced CPU power down function */ +void K_I_Intrp_Pipe_Out(void); /* executes the interrupts CMX function requests */ +void K_OS_Start(void); /* enter CMX OS */ + +void K_I_Timer_Task(void); /* CMX's timer task */ +void K_OS_Tick_Update(void); /* called by interrupt, system tick */ + +/**************************************************** + The following functions are for the CMX UART module +****************************************************/ +#if 1 /* Nick has now allowed for multiple UART ports */ +#define PORTS 13 /* total number of serial or apibus ports */ +#define XMIT_SIZE 256 /* size of transmitter buffer */ +#define RECV_SIZE 256 /* size of reciever buffer */ + +typedef struct { + byte *head; /* head pointer for characters going into buffer. */ + byte *tail; /* tail pointer for characters going out of buffer. */ + word16 bytes_out; /* number of bytes to transmit. */ + word16 bytes_wanted; /* number of bytes wanted. */ + byte flag; /* the transmit flags. */ + tcbpointer tcbptr; /* the task is waiting for transmitter to finish. */ +#if 1 + byte *buff; /* transmitter buffer from xmit_bufs[] array */ +#else + byte buff[XMIT_SIZE]; /* the transmit buufer. */ +#endif + } XMIT; + +typedef struct { + byte *head; /* head pointer for characters going into buffer. */ + byte *tail; /* tail pointer for characters going out of buffer. */ + word16 bytes_in; /* number of bytes in reciever . */ + word16 bytes_wanted; /* number of bytes wanted. */ + byte flag; /* the reciever flags. */ + tcbpointer tcbptr; /* the task that is waiting on the reciever. */ +#if 1 + byte *buff; /* receiver buffer from recv_bufs[] array */ +#else + byte buff[RECV_SIZE]; /* the reciever buffer. */ +#endif + } RECV; + +typedef struct { + XMIT xmit; /* for the moment all ports bidirectional */ + RECV recv; /* for the moment all ports bidirectional */ + byte port; /* allows us to xlate back from ptr to index */ + word16 (*tx_vector)(); /* vector called by interrupt, returns l=chr */ + void (*rx_vector)(); /* vector called by interrupt, passed c=chr */ + void (*modem_status_vector)(); /* called by interrupt, passed c=bits */ + void (*error_status_vector)(); /* called by interrupt, passed c=bits */ + void (*tx_enable_vector)(); /* vector to start asci/escc transmitter */ + void (*tx_disable_vector)(); /* vector to stop asci/escc transmitter */ + byte stat; /* address to read status (8530 02xxh) */ + byte txdr; /* address to write tx data (8530 02xxh) */ + byte rxdr; /* address to read rx data (8530 02xxh) */ + byte swr1; /* wr1 contents (interrupt enable bits) */ + byte swr5; /* wr5 contents (modem control outputs) */ + byte swr15; /* wr15 contents (modem control int enable) */ + byte sinint; /* says whether wr1 really reflects wr1! */ + } SDEV; + +extern SDEV sdevs[PORTS]; +#if 1 +extern byte xmit_bufs[PORTS][XMIT_SIZE]; +extern byte recv_bufs[PORTS][RECV_SIZE]; +#endif + +void K_Init_Sdevs(void); +void K_Init_Xmit(SDEV *device); +void K_Init_Recv(SDEV *device); +word16 K_Update_Dummy(SDEV *device); +#if 1 +word16 +#else +void +#endif +K_Update_Xmit(SDEV *device); +void K_Update_Recv(SDEV *device, byte data); +byte K_Put_Str(byte port, void *byte_ptr, word16 cnt); +byte K_Put_Str_Wait(byte port, void *byte_ptr, word16 cnt, word16 timecnt); +byte K_Put_Char(byte port, void *byte_ptr); +byte K_Put_Char_Wait(byte port, void *byte_ptr, word16 timecnt); +word16 K_Recv_Count(byte port); +word16 K_Get_Char(byte port, void *byte_ptr); +word16 K_Get_Char_Wait(byte port, void *byte_ptr, word16 timecnt); +word16 K_Get_Str(byte port, void *byte_ptr, word16 cnt); +word16 K_Get_Str_Wait(byte port, void *byte_ptr, word16 cnt, word16 timecnt); +word16 K_Get_Str_Wait_Return(byte port, void *byte_ptr, + word16 cnt, word16 timecnt); +word16 K_Get_Str_Return(byte port, void *byte_ptr); +#else +void K_Init_Xmit(void); /* initialize transmitter and buffer */ +void K_Init_Recv(void); /* initailize reciever and buffer */ +void K_Update_Xmit(void); /* called by transmitter interrupt handler. */ +void K_Update_Recv(void); /* called by reciever interrupt handler. */ +byte K_Put_Str(void *,word16); /* put chars into transmit buffer */ +byte K_Put_Str_Wait(void *,word16,word16); /* same as above and wait if need be*/ +byte K_Put_Char(void *); /* put 1 char into transmit buffer */ +byte K_Put_Char_Wait(void *,word16); /* same as above and wait if need be */ +word16 K_Get_Str(void *,word16); /* get chars from reciever buffer */ +word16 K_Get_Str_Wait(void *,word16,word16); /* same as above with wait */ +word16 K_Get_Char(void *); /* get single char from recieve buffer */ +word16 K_Get_Char_Wait(void *,word16); /* same as above with wait */ +word16 K_Get_Str_Wait_Return(void *,word16,word16); /* get requested number with wait */ +word16 K_Get_Str_Return(void *); /* get variable number from buffer */ +word16 K_Recv_Count(void); /* current count in receive buffer */ +#endif + +/*************************************************************** + external assembly routines +***************************************************************/ +#pragma function = non_banked +void K_OS_Disable_Interrupts(void); /* clears JUST I BIT */ +void K_OS_Enable_Interrupts(void); /* sets JUST I BIT */ +void K_OS_Save_Interrupts(void); /* clears JUST I BIT */ +void K_OS_Restore_Interrupts(void); /* sets JUST I BIT */ + +extern void K_I_Sched(void); +extern void K_I_Scheduler(void); +extern void K_OS_Intrp_Entry(void); +extern void K_OS_Intrp_Exit(void); +#pragma function = default +/******************************************************* +* the following functions are not to be called by user * +* used ONLY by other cmx functions * +*******************************************************/ + +void K_I_Unlink(tcbpointer); +void K_I_Priority_In(tcbpointer,byte); +void K_I_Copy(byte *,byte *,byte); +byte K_I_Get_Ptr(byte,tcbpointer *); +void K_I_Func_Return(void); +byte K_I_Time_Common(word16,byte); + +byte K_I_Intrp_Pipe_In(byte,byte,byte,word16,void *); +#define K_Intrp_Task_Wake(A) K_I_Intrp_Pipe_In(0,A,0,0,0) +#define K_Intrp_Task_Wake_Force(A) K_I_Intrp_Pipe_In(1,A,0,0,0) +#define K_Intrp_Task_Start(A) K_I_Intrp_Pipe_In(2,A,0,0,0) +#define K_Intrp_Timer_Stop(A) K_I_Intrp_Pipe_In(3,A,0,0,0) +#define K_Intrp_Timer_Restart(A) K_I_Intrp_Pipe_In(4,A,0,0,0) +#define K_Intrp_Timer_Initial(A,B) K_I_Intrp_Pipe_In(5,A,0,B,0) +#define K_Intrp_Timer_Cyclic(A,B) K_I_Intrp_Pipe_In(6,A,0,B,0) +#define K_Intrp_Mesg_Send(A,B) K_I_Intrp_Pipe_In(7,A,0,0,B) +#define K_Intrp_Event_Signal(A,B,C) K_I_Intrp_Pipe_In(8,A,B,C,0) +#define K_Intrp_Semaphore_Post(A) K_I_Intrp_Pipe_In(9,A,0,0,0) diff --git a/src/kernel/cmx/cxskv5b.asm b/src/kernel/cmx/cxskv5b.asm new file mode 100755 index 00000000..834d984f --- /dev/null +++ b/src/kernel/cmx/cxskv5b.asm @@ -0,0 +1,645 @@ +; cxskv5b.asm + +;****************************************************** +; +; Copyright (C) 2002 +; CMX Systems Inc. +; 12276 San Jose Blvd, #119 +; Jacksonville, FL 32223 +; +; All Rights Reserved +; +;******************************************************* +; +; NOTE: for BANKED MEMORY MODELS +; Also this assembly file will work with the Archimedes l08.s01 +; banked switching assembly module. This is for the 64180/Z180 +; processors. For those if you that are trying to do bank switching +; with the Z80 MUST manipulate this code to match their bank switch +; code that they devise. +; +; NOTE: integers (words) are stored low byte first,high byte second +; + +$ io64180.inc ; Nick + +fwlink equ 00h ;forward wait link +bwlink equ 02h ;backward wait link +ftlink equ 04h ;forward time link +btlink equ 06h ;backward time link +tcbstate equ 08h ;task state +trig equ 0ah ;the number of triggers (starts) for task +priority equ 0bh ;task priority, 0 is highest +tcbtimer equ 0ch ;task countdown delay timer +nxttcb equ 0eh ;ptr to next TCB (task control block) +task_addr equ 10h ;address of where task's code begins +stk_start equ 13h ;the tasks beginning stack's address +stk_save equ 15h ;the task's resume stack address +cbr_save equ 1Dh ; Nick, used to get back to task's stack +bbr_save equ 1Eh ; Nick, used to get back to task's code + +; tcbstate low byte +RESOURCE equ 01h ;waiting on resource +WAIT equ 02h ;waiting +SEND_MESG equ 08h ;waiting for task that recieved message,to wake me +WAIT_MESG equ 10h ;waiting for message +FLAGS equ 20h ;waiting on event +TIME_EXPIRED equ 40h ;the time period specified has ellapsed + +; tcbstate high byte +IDLE equ 01h ;task not able to run, no triggers +READY equ 02h ;the task ready to run +RESUME equ 04h ;the task ready to run, resume where it left off +RUNNING equ 08h ;the task is the running task +TIME equ 10h ;waiting on time + + extern abyte + extern ahexw + extern acrlf + extern _stack_holder + extern _interrupt_stack + extern _activetcb + extern _active_priority + extern _cmx_tcb + extern _K_I_Intrp_Pipe_Out + extern _K_I_Timer_Task + extern _K_OS_Low_Power_Func + extern _TSLICE_SCALE + extern _SLICE_ON + extern _tslice_count + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + extern _int_count ; now done here + extern _locked_out + extern _cmx_flag1 + extern _ie_copy + extern _os_bank ; Nick... the CBR value for CMX data + +preempted equ 01h +do_timer_tsk equ 02h +do_time_slice equ 04h +slice_enable equ 08h +do_coop_sched equ 10h +do_int_pipe equ 20h +idle_flag equ 40h +cmx_active equ 80h + +bit_preempted equ 0 +bit_do_timer_tsk equ 1 +bit_do_time_slice equ 2 +bit_slice_enable equ 3 +bit_do_coop_sched equ 4 +bit_do_int_pipe equ 5 +bit_idle_flag equ 6 +bit_cmx_active equ 7 + + +SAVE_ALT_GR EQU 1 ;Set to 1 if user or "C" compiler uses + ;alternate gr register set + +LOW_POWER_ACTIVE EQU 0 ;set to 1, to enable cmx_power function + +SLICE_ENABLE EQU 1 ;set to 1, to enable time slicing code testing + +CMXTRACKER_ENABLE equ 0 ;Set to 1, for CMXTracker capabilities + + .IF CMXTRACKER_ENABLE > 0 + extern _previoustcb + extern _cmxtracker_in_task + extern _CMXTRACKER_ACTIVE + .ENDIF + +;#define proc64180 (__TID__&0x010=0x010) +;#if proc64180 +; .if 0 ; Nick +;BBR EQU 39H +; .endif +;#else +; EXTERN ?BANK_SWITCH_PORT_L08 +;#endif + + EXTERN ?BANK_CALL_DIRECT_L08 + EXTERN ?BANK_FAST_LEAVE_L08 + +; WARNING: Must be root code + RSEG RCODE + + PUBLIC _K_OS_Intrp_Entry + PUBLIC _K_OS_Intrp_Exit + PUBLIC _K_I_Sched + PUBLIC _K_I_Scheduler + PUBLIC _K_OS_Enable_Interrupts + PUBLIC _K_OS_Disable_Interrupts + PUBLIC _K_OS_Save_Interrupts + PUBLIC _K_OS_Restore_Interrupts + +_K_I_Sched: + push ix + push af ;save all registers + push bc + push de + push hl + push iy +;if gr' regs used + .IF SAVE_ALT_GR + + ex af,af' + push af + exx + push bc + push de + push hl + + .ENDIF + +;#if proc64180 + .if 1 ; Nick + in0 e,(CBR) + in0 d,(BBR) + ld a,(_os_bank) + out0 (CBR),a + .else + in0 a,(BBR) ; get actual page number + push af ; save it + .endif +;#else +; IN A,(?BANK_SWITCH_PORT_L08) +; push af ; save it +;#endif + +sched_int: +; ld a,'\\' +; call abyte + + ld ix,(_activetcb) ;get current running task pointer + .if 1 ; Nick + ld (ix+cbr_save),e + ld (ix+bbr_save),d + .endif + + ld a,(ix+tcbstate+1) ;get task states + and RUNNING ;see if running + jr nz,set_resume + ld a,0ffh + ld (_active_priority),a ;load it + jp LWRD sched_cont +set_resume: + ld a,RESUME ;yes, identify that task can resume + ld (ix+tcbstate+1),a ;save task new state, if need be +sched_cont: + ld hl,0 + add hl,sp ;save the current stack pointer of task + ld (ix+stk_save+1),h + ld (ix+stk_save),l +_K_I_Scheduler: + di ;disable interrupts + ld hl,(_interrupt_stack) ;load in interrupt stack (also + ;scheduler's and timer task stack + ld sp,hl + ld a,1 ;set proper lock out states + ld (_int_count),a ;locked out interrupt stack swapping + ld (_locked_out),a ;so int_action and timer task routine + ;forced back to scheduler +sched_again: + ei ;enable interrupts +rescan1: + ld hl,_cmx_flag1 ;now test the scheduler flags + bit bit_do_timer_tsk,(hl) ;should we do timer task + jr z,rescan2 ;no + res bit_do_timer_tsk,(hl) ;yes, go do it + push ix ;save ix reg + LD A,BYTE3 _K_I_Timer_Task + ld hl,LWRD _K_I_Timer_Task ;load hl with timer task address + CALL LWRD ?BANK_CALL_DIRECT_L08 + ld hl,_cmx_flag1 ;restore hl to point to _cmx_flag1 + pop ix ;restore __activetcb +rescan2: + bit bit_do_int_pipe,(hl) ;should we do interrupt pipe + jr z,rescan4 ;no + push ix + LD A,BYTE3 _K_I_Intrp_Pipe_Out + ld hl,LWRD _K_I_Intrp_Pipe_Out ;go do pipe requests + CALL LWRD ?BANK_CALL_DIRECT_L08 + ld hl,_cmx_flag1 + pop ix ;restore __activetcb +rescan4: + ld a,(hl) ;really _cmx_flag1 + bit bit_preempted,a ;is preempted flag set + jr z,rescan5 ;no, continue + and .BINNOT.(preempted.BINOR.do_coop_sched.BINOR.do_time_slice.BINOR.slice_enable) + or idle_flag ;set flag that we now test for idle condition + ld (hl),a ;new _cmx_flag1 contents + ld ix,_cmx_tcb ;load the highest priority task + ;(CMX timer task) + ld b,(ix+nxttcb+1) ;get next task in line, according to priority + ld c,(ix+nxttcb) + push bc + pop ix ;now pointing at highest puser priority task + jp LWRD midpaus2 ;now jump and test highest task +rescan5: + ld a,(hl) ;get cmx_flags + bit bit_do_coop_sched,a ;is cooperative scheduling flag set + jr z,rescan6 ;no, continue + and .BINNOT.(do_coop_sched.BINOR.do_time_slice.BINOR.slice_enable) + ld (hl),a ;load new _cmx_flag1 byte + jp LWRD findready ;get next task able to run +rescan6: + .IF SLICE_ENABLE > 0 + bit bit_do_time_slice,(hl) ;see if time slice time up + jr nz,findready ;yes, go see if another task with + ;same priority capable of running + .ENDIF +midpaus2: + ld a,(ix+tcbstate+1) ;get task states + and RESUME.BINOR.READY ;see if task able to run or resume + jr nz,task_resume ;task is allowed to become the running task + ;task not able to run +findready: + ld b,(ix+nxttcb+1) ;get next task in line, according to priority + ld c,(ix+nxttcb) + push bc + pop ix + ld a,.high._cmx_tcb ;test to see if we have reached end of TCB + cp b + jr nz,midpaus2 ;no, we haven't + ld a,.low._cmx_tcb + cp c + jr nz,midpaus2 ;no, we haven't +; here means that we have gone to end of list + .IF LOW_POWER_ACTIVE + +; if idle flag set and list_complete flag set go to idle state + bit bit_idle_flag,(hl) ;test to see if we have looped thru all tasks + jr z,no_power_down ;no, test for more ready tasks +power_down: + push ix ;yes, save ix reg + LD A,BYTE3 _K_OS_Low_Power_Func + ld hl,LWRD _K_OS_Low_Power_Func ;call reduced power function, by user + CALL LWRD ?BANK_CALL_DIRECT_L08 + pop ix ;restore ix + + .ENDIF + +no_power_down: + ld ix,_cmx_tcb ;load the highest priority task + ;(CMX timer task) + ld b,(ix+nxttcb+1) ;get next task in line, according to priority + ld c,(ix+nxttcb) + push bc + pop ix ;now pointing at highest puser priority task + jp LWRD rescan1 ;go test next task +task_resume: +; The following may look a little out of place, but the +; reason behind all this is so interrupts will be disable +; for the least amount of time possible + ld c,a ;save a into c, (task state) + ld a,(ix+priority) ;get priority of task + ld (_active_priority),a ;load it + ld (_activetcb),ix ;save current active task + ld a,(hl) ;_cmx_flag1 + and .BINNOT.(idle_flag.BINOR.do_time_slice) ;mask out proper bits + ld (hl),a ;store it + ld d,(ix+stk_start+1) ;get the beginning address of task's stack + ld e,(ix+stk_start) + bit 1,c ;READY, test to see if task just starting it's code + jr nz,task_res_cont ;yes, jump + ld d,(ix+stk_save+1) ;reload the stack pointer of task's save stack + ld e,(ix+stk_save) +task_res_cont: ;NOTE: number of states in parenthesis + ; for 64180 processor + + di ;disable interrupts + ld a,(hl) ;get the _cmx_flag1 byte + and do_int_pipe.BINOR.do_timer_tsk ;(6)see if interrupt set flags + jr z,res_cont1 ;see if either flag became set + jp LWRD sched_again ;(6 if no branch or 8) +res_cont1: + ld a,0 ;(6) if no branch, then set interrupt count + ld (_int_count),a ;(13) to zero + ld (_locked_out),a ;(13) to zero + .IF SLICE_ENABLE > 0 + ld a,(_SLICE_ON) ;see if time slicing enabled + or a ;set condition flag + jr z,no_slice ;if 0, not set, so jump + bit bit_slice_enable,(hl) ;see if slice enable set + jr nz,no_slice ;yes, jump + set bit_slice_enable,(hl) ;set flag + ld a,(_TSLICE_SCALE) ;put slice count into counter + ld (_tslice_count),a +no_slice: + .ENDIF + .IF CMXTRACKER_ENABLE > 0 + push ix + pop bc + ld a,(_previoustcb+1) ;test to see if we have reached end of TCB + cp b + jr nz,not_same + ld a,(_previoustcb) ;test to see if we have reached end of TCB + cp c + jr z,same +not_same: + ld (_previoustcb),ix ;save current active task + push ix ;yes, save ix reg + LD A,BYTE3 _cmxtracker_in_task + ld hl,LWRD _cmxtracker_in_task ;go log new task executing/resuming + CALL LWRD ?BANK_CALL_DIRECT_L08 + pop ix ;restore ix +same: + ld a,(ix+tcbstate+1) ;get task states + ld c,a ;save a into c, (task state) + .ENDIF + ld (ix+tcbstate+1),RUNNING ;(14) load in RUNNING state into task's tcbstate + bit 1,c ;(6) see if task was READY, test to see + ;if task just starting it's code + jr nz,task_ready ;(6 if no branch or 8) yes, jump + ex de,hl ;(3) task is RESUMING + ld sp,hl ;(4) load stack pointer to proper address + .if 1 ; Nick + ld e,(ix+cbr_save) + ld d,(ix+bbr_save) + .endif + +; ld a,'/' +; call abyte + +done_scheduler: +; restore all register of either interrupt or task, then return + +;#if proc64180 + .if 1 ; Nick + out0 (CBR),e + out0 (BBR),d + .else + POP AF ;(9) pop page address + OUT0 (BBR),A ;(13) set new page + .endif +;#else +; POP AF ;(9) pop page address +; OUT (?BANK_SWITCH_PORT_L08),A +;#endif + +;if gr' regs used + .IF SAVE_ALT_GR + + pop hl ;(9) + pop de ;(9) + pop bc ;(9) + exx ;(3) + pop af ;(9) + ex af,af' ;(4) + + .ENDIF + + pop iy + pop hl + pop de + pop bc + pop af + pop ix + ei + ret +task_ready: + ex de,hl ;(3) get task beginning address of stack + ld sp,hl ;(4) load it into stack pointer + ld c,(ix+task_addr) ;(14) LOW BYTE of address + ld b,(ix+task_addr+1) ;(14) MID BYTE of address + ld a,(ix+task_addr+2) ;(14) HIGH BYTE of address + push bc ;(11) the true address of code on stack + +;#if proc64180 + .if 1 ; Nick + ; in this case, no need to mess with CBR, use the CMX data segment + .endif + .if 1 ; virtual memory +; push hl + ld h,80h + ld l,a ; hl -> 8000h + entry a value + ld a,(hl) ; translate bbr via virt memory table +; pop hl +; +; or a ; check for unused virt memory pages +; ret z ; just to be extra paranoid + .endif + OUT0 (BBR),A ;(13) set new page +;#else +; OUT (?BANK_SWITCH_PORT_L08),A +;#endif +; ld a,'|' +; call abyte + + ei ;enable interrupts + ret ;will return to tasks beginning code address +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;; CAUTION to anyone writing interrupt service routines! ;;;;;; +; +; The system tick timer interrupt MUST call these routines +; +; Any interrupt that wants to use ANY of the CMX functions +; MUST call these routines. +; +; Here's an example of an interrupt service routine that uses +; this method: +; +; interrupt vector: interrupt vectors to here. +; call cxint_in +; set interrupt masks if user wants +; ei ;re-enable interrupts if user wants +; ...miscellaneous user ISR code, including... +; call cxint_ex ;replaces rti instruction +; +; interrupt vector: +; call cxint_in +; set interrupt masks if user wants +; ei ;re-enable interrupts is user wants +; call C_WRITTEN_INTERRUPT_CODE +; call cxint_ex +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WARNING: for use with external chips that monitor +; the z80 (z180) RETI instruction +; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; the following is a problem, it does .BINNOT. distinquish +; between an internal interrupt or an external interrupt +; the internal interrupts should just use the RET instruction +; and the external interrupts the RETI instruction. +; Solution: change the code as follows in proper area +;no_stack_load: +; inc a +; ld (_int_count),a +; ;;; ADD the following ;;; +; ld bc,cxint_ex +; push bc +; ;;; back to regular instruction +; jp (ix) + +; +; now interrupts will have to have the RET or RETI instruction at the +; end INSTEAD of the cxint_ex instruction. +; +; NOTE: also remove (comment out) the instructions "pop hl" and +; "call notify_int" which are no longer needed. +; +_K_OS_Intrp_Exit: +; ;CALL here instead of executing RETI at the end of an ISR. +; ;Only use this if cxint_in was called first. +; ;use a call cxint_ex instruction + .if 0 + ex (sp),hl + push af + ld a,'j' + call abyte + call ahexw + pop af + ex (sp),hl + .endif + di ;(3) disable interrupts + pop hl ;(9) add 2 to stack pointer because of call + .if 0 ; Nick + call LWRD notify_int ;(16) notify the hardware there were done with + ;the interrupt (almost in reality) + .endif + .if 1 ; Nick + pop de + .endif + + ld a,(_cmx_flag1) ;see if cmx has been entered + bit bit_cmx_active,a + jr z,done_scheduler ;no, exit out + + ld hl,_int_count ;(9) load hl with interrupt count address + dec (hl) ;(10) decrement the interrupt count + jr nz,done_scheduler ;(6 or 8) if non zero (0), return to + ;lower priority interrupt + ld hl,(_stack_holder) ;(15) load in interrupted task stack + ld sp,hl ;(4) restore stack pointer + ld a,(_locked_out) ;(12) see if we are locked out + or a ;(6) set or clear z flag + jr nz,done_scheduler ;(6 or 8) if locked out, MUST finish + ;what we were doing prior to interrupt + ld a,(_cmx_flag1) ;(12) see if any scheduler flags set + and do_int_pipe.BINOR.preempted.BINOR.do_timer_tsk.BINOR.do_time_slice.BINOR.do_coop_sched + jr z,done_scheduler ;(6 or 8) resume task if no flags set +;goto_scheduler: + ld hl,_locked_out ;(9) load hl with locked out address + inc (hl) ;(10) increment locked out flag + ei ;(3) re-enable interrupts + jp LWRD sched_int ;(9) go save rest of interrupted task's state + .if 0 ; Nick +notify_int: + reti + .endif + +_K_OS_Intrp_Entry: + .if 0 + ex (sp),hl + push af + ld a,'i' + call abyte + call ahexw + pop af + ex (sp),hl + .endif + ex (sp),ix ;save ix on stack, get return address into ix + push af ;save all registers + push bc + push de + push hl + push iy +;if gr' regs used + .IF SAVE_ALT_GR + + ex af,af' + push af + exx + push bc + push de + push hl + + .ENDIF + +;#if proc64180 + .if 1 ; Nick + in0 e,(CBR) + in0 d,(BBR) + ld a,(_os_bank) + out0 (CBR),a + .else + in0 a,(BBR) ; get actual page number + push af ; save it + .endif +;#else +; IN A,(?BANK_SWITCH_PORT_L08) +; push af ; save it +;#endif + + ld a,(_cmx_flag1) ;see if cmx has been entered? + bit bit_cmx_active,a + jr z,cxint_in_exit ;no, get out + + ld a,(_int_count) ;see if interrupt nesting count 0 + or a + jr nz,no_stack_load ;no, another interrupt was preempted (nesting) + ld hl,0 ;first interrupt + add hl,sp ;save the current stack pointer of task + ld (_stack_holder),hl + ld hl,(_interrupt_stack) ;load in interrupt stack (also + ;scheduler's stack + ld sp,hl +no_stack_load: + inc a ;increment interrupt nesting counter + ld (_int_count),a +cxint_in_exit: + .if 1 ; Nick + push de + .endif + jp (ix) ;go back to interrupt + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +_K_OS_Disable_Interrupts: + di + ret + +_K_OS_Enable_Interrupts: + ei + ret + +_K_OS_Save_Interrupts: + ld a,i ;get iff2 flag, copy of iff1 + jp pe,LWRD save_int1 + di + ld a,0 + ld (_ie_copy),a ;save copy of interrupt enable flag + ret +save_int1: + di + ld a,1 + ld (_ie_copy),a ;save copy of interrupt enable flag + ret + +_K_OS_Restore_Interrupts: +; restore interrupt enable flag + ld a,(_ie_copy) ;see if interrupts were enable / disabled + or a + jr z,LWRD no1_ei_on + ei +no1_ei_on: + ret + +; ----------------------------------------------------------------------------- +; variables placed here by Nick, formerly defined via #ifdef CMX_INIT_MODULE +; these have to be in RCODE !! as we are now saving and restoring CBR in sched + +;_locked_out: defb 0 ; disable task switching +;_in_ctr: defb 0 ; position within interrupt pipe to place bytes +;_out_ctr: defb 0 ; position within interrupt pipe to remove bytes +;_cmx_flag1: defb 0 ; contains flags, for CMX internal use +;_int_count: defb 0 ; interrupt nested level count +;_pipe_slots_avail: defb 0 +;_ie_copy: defb 0 + +; ----------------------------------------------------------------------------- + + END + diff --git a/src/kernel/cmx/cxstruct.h b/src/kernel/cmx/cxstruct.h new file mode 100755 index 00000000..d5b8a353 --- /dev/null +++ b/src/kernel/cmx/cxstruct.h @@ -0,0 +1,104 @@ +/******************************************* + The following are CMX structures +********************************************/ +struct _tcb { + struct _tcb *fwlink; /* forward wait link */ + struct _tcb *bwlink; /* backward wait link */ + struct _tcb *ftlink; /* forward time wait link */ + struct _tcb *btlink; /* backward time wait link */ + word16 tcbstate; + byte trig; /* the number of triggers (start requests) */ + byte priority; /* the priority of this task */ + word16 tcbtimer; /* the timer counter */ + struct _tcb *nxttcb; /* points to next task, according to priority */ + void (*task_addr)(); /* the task's CODE address */ + word16 *stk_start; /* location in external ram, of where to save + task's context */ + word16 *stk_save; /* location in external ram, of where to save + task's context */ + struct _tcb *mesg_sender; + word16 e_flags; /* flags for this task */ + word16 e_match; /* the flags states for match */ + byte cbr_save; /* Nick, used to get back to task's stack */ + byte bbr_save; /* Nick, used to get back to task's code */ +}; + +typedef struct _tcb *tcbpointer; + +typedef struct tsk_time_lnk { + struct _tcb *dum1; /* forward wait link */ + struct _tcb *dum2; /* backward wait link */ + struct _tcb *ftlink; /* forward time link */ + struct _tcb *btlink; /* backward time link */ + } TSK_TIMER_LNK; + +typedef struct cmxmesg { + struct cmxmesg *env_link; /* link to next message block. */ + struct cmxmesg *link; /* link to mailbox. */ + tcbpointer sender; /* task who sent message. */ + byte *message; /* address of message. */ + } MSG; + + +typedef struct cmxmbox { + MSG *first_lnk; /* link to message block. */ + MSG *next_lnk; /* link to message block. */ + tcbpointer waiter; /* what task is waiting for message. */ + byte task_num; /* task number for setting event bit */ + word16 event_num; /* event number */ + } MAILBOX; + + +typedef struct cmxqueue { + byte *base_ptr; /* address of user supplied memory for queue. */ + sign_word16 num_slots; /* the number of slots within this queue */ + sign_word16 queue_cnt; /* the number of slots used */ + byte size_slot; /* size of slots */ + sign_word16 head; /* must be signed to test for < 0 */ + sign_word16 tail; /* must be signed to test for < 0 */ + } QUEHDR; + + + +/* the cyclic timers structure */ +typedef struct _tcproc { + struct _tcproc *ftlink; /* forward time link */ + struct _tcproc *btlink; /* backward time link */ + byte tproc_start; /* byte indicating timed procedure stopped / started */ + word16 tproc_timer; /* the timer counter */ + word16 reload_time; /* the cyclic time that will be reloaded */ + word16 event_num; /* the event to set. */ + byte mode; /* what mode to sent to K_Event_Signal function. */ + byte tskid_pri; /* task slot number or priority (may not be used). */ + } CYCLIC_TIMERS; + +typedef struct cyclic_tmrs_link { + struct _tcproc *ftlink; /* forward time link */ + struct _tcproc *btlink; /* backward time link */ + } CYCLIC_LNK; + +/* the resource structure */ +typedef struct cmxresource { + tcbpointer fwlink; /* forward wait link. */ + tcbpointer bwlink; /* backward wait link. */ + tcbpointer owner; /* The task that owns resource. */ + byte owner_priority; + } RESHDR; + +typedef struct semaphore { + tcbpointer fwlink; /* forward wait link. */ + tcbpointer bwlink; /* backward wait link. */ + word16 sem_count; + word16 sem_n; + } SEM; + +typedef struct pipe_element { + byte identifier; + byte p1; /* parameter 1 */ + byte p2; /* parameter 2 */ + union { + word16 p3; /* parameter 3 */ + void *p4; /* address of message. */ + } pipe_u; + } PIPE_STRUC; + diff --git a/src/kernel/cmx/cxvendor.h b/src/kernel/cmx/cxvendor.h new file mode 100755 index 00000000..1e084baf --- /dev/null +++ b/src/kernel/cmx/cxvendor.h @@ -0,0 +1,241 @@ +/* for IAR Z80/180/64180 */ + +#define PROCESSOR Z80 + +#define PROC_DISABLE_INT K_OS_Disable_Interrupts() +#define PROC_ENABLE_INT K_OS_Enable_Interrupts() + +#define PROC_SAVE_INT K_OS_Save_Interrupts() +#define PROC_RESTORE_INT K_OS_Restore_Interrupts() + +typedef void (*CMX_FP)(); +/* or +typedef void (far *CMX_FP)(); +typedef void (*CMX_FP)(); +*/ + +/* load in tasks STACK address. */ +/* adjust stack memory block. */ + +#define CXTCRE_SPECIFIC() {tcbptr->stk_start = stack_blk; stack_blk -= stack_size / 2; } + +#if 1 /* Nick, for IAR, this has to come before any hard data is defined */ +#define abyte _abyte +#define acrlf _acrlf +#define active_priority _active_priority +#define activetcb _activetcb +#define ahexw _ahexw +#define amess _amess +#define asci0_setup _asci0_setup +#define asci1_setup _asci1_setup +#define escc0_setup _escc0_setup +#define escc1_setup _escc1_setup +#define apibus_setup _apibus_setup +#define cmx_flag1 _cmx_flag1 +#define cmx_tcb _cmx_tcb +#define CMXTRACKER_ACTIVE _CMXTRACKER_ACTIVE +#define cmxtracker_in_task _cmxtracker_in_task +#define copyr _copyr +#define ie_copy _ie_copy +#define int_count _int_count +#define interrupt_stack _interrupt_stack +#define K_I_Intrp_Pipe_Out _K_I_Intrp_Pipe_Out +#define K_I_Sched _K_I_Sched +#define K_I_Scheduler _K_I_Scheduler +#define K_I_Timer_Task _K_I_Timer_Task +#define K_Init_Recv _K_Init_Recv +#define K_Init_Xmit _K_Init_Xmit +#define K_OS_Disable_Interrupts _K_OS_Disable_Interrupts +#define K_OS_Enable_Interrupts _K_OS_Enable_Interrupts +#define K_OS_Low_Power_Func _K_OS_Low_Power_Func +#define K_OS_Restore_Interrupts _K_OS_Restore_Interrupts +#define K_OS_Save_Interrupts _K_OS_Save_Interrupts +#define K_Update_Recv _K_Update_Recv +#define K_Update_Xmit _K_Update_Xmit +#define locked_out _locked_out +#define main _main +#define os_bank _os_bank +#define previoustcb _previoustcb +#define sdevs _sdevs +#define SLICE_ON _SLICE_ON +#define stack_holder _stack_holder +#define timer0_handler _timer0_handler +#define timer0_setup _timer0_setup +#define timer0_vector _timer0_vector +#define tslice_count _tslice_count +#define TSLICE_SCALE _TSLICE_SCALE +#endif + +#ifdef CMX_INIT_MODULE + +byte locked_out; /* disable task switching */ +byte in_ctr; /* position within interrupt pipe to place bytes */ +byte out_ctr; /* position within interrupt pipe to remove bytes */ +byte cmx_flag1; /* contains flags, for CMX internal use */ +byte int_count; /* interrupt nested level count */ +byte pipe_slots_avail; +byte ie_copy; + +#else + +extern byte locked_out; +extern byte in_ctr; +extern byte out_ctr; +extern byte cmx_flag1; +extern byte int_count; +extern byte ie_copy; + +#ifdef CMXTRACKER +extern byte CMXTRACKER_ON; +#endif + +#endif + +#define preempted 0x01 /* preempted flag */ +#define do_timer_tsk 0x02 /* do timer task flag */ +#define do_time_slice 0x04 /* do time slice, next task to slice */ +#define slice_enable 0x08 /* time slicing enabled */ +#define do_coop_sched 0x10 /* do a cooperative schedule, to NEXT task that can run */ +#define do_int_pipe 0x20 /* process interrupt pipe */ +#define idle_flag 0x40 /* helps determines power down mode */ +#define cmx_active 0x80 /* identifies that CMX RTOS entered */ + +#define TEST_NOT_PREEMPTED !(cmx_flag1 & preempted) +#define CMX_ACTIVE cmx_flag1 |= cmx_active +#define TEST_CMX_ACTIVE cmx_flag1 & cmx_active +#define CLR_DO_INT_PIPE cmx_flag1 &= ~do_int_pipe +#define TEST_SLICE_ENABLE cmx_flag1 & slice_enable + +/* + The following must use instructions that are ATOMIC. If NOT then + CMX must go out side it's normal thinking and put a fence around + the bit setting and clearing within the cmx_flag1 variable. This + is because the CMX functions int_pipe and/or cmx_tic can be called + at any time by an interrupt, thus setting the CMX 'do_int_pipe' flag + or 'do_timer_tsk' flag and possibly having the flag NOT be taken, + for instructions that were manipulating the cmx_flag1 variable was + going to write it back, thus destroying the flags! + + Note that CMX tries to use the processor memory area that allows + manipulation of bits, using one of the instructions, thus making it + atomic. Some times the compiler will not either allow CMX to take + advantage of this memory are OR because of optimization (none or + little that is). + + The user should check the code generated by compiler (and compiler + options [optimize, etc] used), to ensure that ATOMIC instructions + are used. Most likely, you will see instructions that either set or + clear the cmx_flag1 bits directly or instructions that ACT on the + cmx_flag1 variable directly such as follows: + AND instructions (AND,ANL, etc) cmx_flag1,#??h. + OR instructions (OR,ORL, etc) cmx_flag1,#??h. + + Failure to ensure this may result in stange behavoir! + +*/ + +#define ATOMIC 0 /* if 0, then FENCE will be placed around cmx_flag1 + bit manipulation coding. Normally will be 1 (one). */ + + +#if ATOMIC > 0 + +#define PREEMPTED cmx_flag1 |= preempted +#define DO_TIMER_TSK cmx_flag1 |= do_timer_tsk +#define DO_TIME_SLICE cmx_flag1 |= do_time_slice +#define SLICE_DISABLE cmx_flag1 &= ~slice_enable +#define SLICE_ENABLE cmx_flag1 |= slice_enable +#define DO_COOP_SCHED cmx_flag1 |= do_coop_sched +#define DO_INT_PIPE cmx_flag1 |= do_int_pipe + +#else + +/* #include */ +/* for intrinsic disable_interrupt and enable_interrupt */ + +#if 1 /* Nick */ + +#define PREEMPTED {K_OS_Save_Interrupts(); cmx_flag1 |= preempted; K_OS_Restore_Interrupts();} +#define DO_TIMER_TSK {K_OS_Save_Interrupts(); cmx_flag1 |= do_timer_tsk; K_OS_Restore_Interrupts();} +#define DO_TIME_SLICE {K_OS_Save_Interrupts(); cmx_flag1 |= do_time_slice; K_OS_Restore_Interrupts();} +#define SLICE_DISABLE {K_OS_Save_Interrupts(); cmx_flag1 &= ~slice_enable; K_OS_Restore_Interrupts();} +#define SLICE_ENABLE {K_OS_Save_Interrupts(); cmx_flag1 |= slice_enable; K_OS_Restore_Interrupts();} +#define DO_COOP_SCHED {K_OS_Save_Interrupts(); cmx_flag1 |= do_coop_sched; K_OS_Restore_Interrupts();} +#define DO_INT_PIPE {K_OS_Save_Interrupts(); cmx_flag1 |= do_int_pipe; K_OS_Restore_Interrupts();} + +#else + +/* The following is better, but IAR does NOT support inline assembly */ + +#define PREEMPTED {_asm \ +.globl _cmx_flag1 _newline \ +push hl _newline \ +ld hl,_cmx_flag1 _newline \ +set 0,(hl) _newline \ +pop hl _newline \ +_endasm;} + +#define DO_TIMER_TSK {_asm \ +.globl _cmx_flag1 _newline \ +push hl _newline \ +ld hl,_cmx_flag1 _newline \ +set 1,(hl) _newline \ +pop hl _newline \ +_endasm;} + +#define DO_TIME_SLICE {_asm \ +.globl _cmx_flag1 _newline \ +push hl _newline \ +ld hl,_cmx_flag1 _newline \ +set 2,(hl) _newline \ +pop hl _newline \ +_endasm;} + +#define SLICE_DISABLE {_asm \ +.globl _cmx_flag1 _newline \ +push hl _newline \ +ld hl,_cmx_flag1 _newline \ +res 3,(hl) _newline \ +pop hl _newline \ +_endasm;} + +#define SLICE_ENABLE {_asm \ +.globl _cmx_flag1 _newline \ +push hl _newline \ +ld hl,_cmx_flag1 _newline \ +set 3,(hl) _newline \ +pop hl _newline \ +_endasm;} + +#define DO_COOP_SCHED {_asm \ +.globl _cmx_flag1 _newline \ +push hl _newline \ +ld hl,_cmx_flag1 _newline \ +set 4,(hl) _newline \ +pop hl _newline \ +_endasm;} + +#define DO_INT_PIPE {_asm \ +.globl _cmx_flag1 _newline \ +push hl _newline \ +ld hl,_cmx_flag1 _newline \ +set 5,(hl) _newline \ +pop hl _newline \ +_endasm;} + +#endif + +#endif + +#pragma function = non_banked + +void abyte(char data); +void acrlf(void); +void ahexw(int data); +void amess(char *ptr); + +void copyr(long source, long destination, unsigned int count); + +#pragma function = default + + diff --git a/src/kernel/cmx/cxver5.c b/src/kernel/cmx/cxver5.c new file mode 100755 index 00000000..b5fa7b7c --- /dev/null +++ b/src/kernel/cmx/cxver5.c @@ -0,0 +1,2033 @@ +/********************************************************* + +Copyright (c) CMX Company. 1999. All rights reserved + +*********************************************************/ +/* version 5.30 */ + +#define CMXMODULE 1 + +#include /* get cmx include header file */ +#include /* get cmx include header file */ + +#ifdef CMXTRACKER +#include /* get cmx include header file */ +#endif + +void K_OS_Slice_On(void) +{ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(ENABLE_SLICE_CALL); + } +#endif + SLICE_ON = 1; /* enable time slicing */ + tslice_count = TSLICE_SCALE; /* load the time slice counter, + with the scale dictated by user in confiquration module. */ + SLICE_ENABLE; /* inform CMX that time slicing is now active. */ +} + +void K_OS_Slice_Off(void) +{ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(DISABLE_SLICE_CALL); + } +#endif + SLICE_ON = 0; /* this will disable time slicing. */ +} + + +/* K_I_Copy = dest,source,count */ + +void K_I_Copy(byte *dest,byte *src,byte count) +{ + /* this will move the source bytes to the destination */ + + while (count--) /* post decrement counter, and test */ + *dest++ = *src++; /* increment the source and destination pointers */ +} + +/************************************************************ + task done routine, all task's that are finished their code, + will MUST be returned to here. If a task is going to hit it's + end brace, it MUST call the following function. + + This function will then decide if the task should be + placed into the IDLE state or READY state because outstanding + triggers (caused by the K_Task_Start function) are present. +**************************************************************/ +void K_Task_End(void) +{ + K_I_Disable_Sched(); /* set task block */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXTEND_CALL); + } +#endif + /* now test to see if task has any outstanding start requests. + If so, place task into READY state, if not IDLE state. */ + activetcb->tcbstate = (--activetcb->trig) ? READY : IDLE; + PREEMPTED; /* set the preempted scheduling flag */ + K_I_Func_Return(); /* release task block */ +} + +/*************************************************************** + This function gets the address of a task's task control block. + also tests to see if task was created and if so not removed. + passes back requested task's address so the function that call + this function will be able to work with the requested task's + task control block. +*****************************************************************/ + +byte K_I_Get_Ptr(byte tskid,tcbpointer *tcbptr) +{ + if (tskid > MAX_TASKS || !tskid) /* see if task exists */ + return(K_ERROR); /* no, return error */ + *tcbptr = &cmx_tcb[tskid]; /* pass address of task TCB back */ + if (((tcbpointer)(*tcbptr))->nxttcb) /* see if NOT NULL */ + return(K_OK); /* return good status */ + else + return(K_ERROR); /* it was so return error */ +} + +/*********************************************************************** + This function will create a task. The task will be defined to the + task's control block array. +************************************************************************/ + +byte K_Task_Create(byte priority,byte *tskid,CMX_FP task_addr,word16 stack_size) +{ + tcbpointer tcbptr; + byte i; + + /* abyte('A'); */ + + K_I_Disable_Sched(); /* set task block */ + tcbptr = cmx_tcb; /* start at beginning of linked list. */ + for (i = 0; ;i++) + { + /* abyte('B'); */ + + if (tcbptr->nxttcb) /* not NULL */ + { + /* abyte('!'); */ + if ((++tcbptr) > &cmx_tcb[MAX_TASKS]) /* past MAXIMUM? */ + { + /* abyte('@'); */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXTCRE_K_ERROR); + } + /* abyte('#'); */ +#endif + K_I_Func_Return(); /* yes, return because no more room. */ + /* abyte('$'); */ + return(K_ERROR); /* return ERROR. */ + } + } + else + { + /* abyte('%'); */ + break; /* OK, exit out of for loop. */ + } + } + /* abyte('C'); */ + + K_I_Priority_In(tcbptr,priority); /* go load in task into priority chain */ + *tskid = i; /* load in slot number */ + + tcbptr->task_addr = task_addr; /* load in task's CODE address */ + + CXTCRE_SPECIFIC(); + /* abyte('D'); */ + + tcbptr->tcbstate = IDLE; /* put the task into the IDLE state */ + tcbptr->trig = 0; /* load the start counter with 0, no starts */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXTCRE_K_OK); + } +#endif + /* abyte('E'); */ + + K_I_Func_Return(); /* release task block */ + /* abyte('F'); */ + + return(K_OK); /* return good status */ +} + +/************************************************************ +The following has been added, so user can pass the starting +address of a task, so as to allow multiple creations and +removing of tasks stacks, for when a task is removed after +using the 'normal' K_Task_Create function, the stack area is NOT +reclaimed. + +This will allow stack area to be reclaimed if need be and if +user wants, also the ability to have different task use same +stack area, as long as they be CAREFUL to ensure that the tasks +sharing same stack do not run concurrently. +************************************************************/ + +byte K_Task_Create_Stack(byte priority,byte *tskid,CMX_FP task_addr,word16 *stack_start) +{ + tcbpointer tcbptr; + byte i; + + K_I_Disable_Sched(); /* set task block */ + tcbptr = cmx_tcb; /* start at beginning of linked list. */ + for (i = 0; ;i++) + { + if (tcbptr->nxttcb) /* not NULL */ + { + if ((++tcbptr) > &cmx_tcb[MAX_TASKS]) /* past MAXIMUM? */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXTCRE_K_ERROR); + } +#endif + K_I_Func_Return(); /* yes, return because no more room. */ + return(K_ERROR); /* return ERROR. */ + } + } + else + { + break; /* OK, exit out of for loop. */ + } + } + K_I_Priority_In(tcbptr,priority); /* go load in task into priority chain */ + *tskid = i; /* load in slot number */ + + tcbptr->task_addr = task_addr; /* load in task's CODE address */ + tcbptr->stk_start = stack_start; + tcbptr->tcbstate = IDLE; /* put the task into the IDLE state */ + tcbptr->trig = 0; /* load the start counter with 0, no starts */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXTCRE_K_OK); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status */ +} + +/****************************************************** + This function will change the priority of a task, will possibly + re-adjust the linked TCB chain. +******************************************************/ +byte K_Task_Priority(byte tskid,byte new_priority) +{ + tcbpointer tcbptr; + + if(K_I_Get_Ptr(tskid,&tcbptr)) /* send address of pointer */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXTPRI_K_ERROR,tskid); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block */ + K_I_Unlink(tcbptr); /* take task out of priority chain */ + K_I_Priority_In(tcbptr,new_priority); /* now insert the task back into the + priority chain link list */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in3(CXTPRI_K_OK,tskid,new_priority); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status */ +} + +/****************************************************** + This function will remove a task from the linked list of TCB's. +******************************************************/ +void K_I_Unlink(tcbpointer tcbptr) +{ + tcbpointer prevtcb; + + /* remove the task from linked list */ + prevtcb = cmx_tcb; + + /* scan TCB's looking for TCB that points to this TCB */ + while (prevtcb->nxttcb != tcbptr) + { + prevtcb = prevtcb->nxttcb; + } + prevtcb->nxttcb = tcbptr->nxttcb; + /* the previous tcb nxttcb points to the delink tcb nxttcb */ + tcbptr->nxttcb = 0; + /* identify that this task no longers exist */ +} + +/******************************************************* + This function will place the task into the proper linked list + slot, according to priority. Remember the lower the priority + number, the higher the priority is for this task in relationship + to others. +*******************************************************/ +void K_I_Priority_In(tcbpointer tcbptr,byte priority) +{ + tcbpointer prevtcb; + tcbpointer tp; + + tp = cmx_tcb; /* address of TCB link list. */ + do /* insert new tcb at appropriate priority slot in chain...*/ + { + prevtcb = tp; + tp = tp->nxttcb; + } while ((tp != cmx_tcb) && (tp->priority <= priority)); + /* We should insert it just after prevtcb, just before tp. */ + + tcbptr->nxttcb = tp; /* adjust priority slot chain */ + prevtcb->nxttcb = tcbptr; + tcbptr->priority = priority; /* load in task's priority */ +} +/**************************************************************** + This function will place a task into the READY state, if in the + IDLE state. If the task is already triggered, then this will + be queued up. The maximum number of starts for a task, can be + 255. +*****************************************************************/ +byte K_Task_Start(byte tskid) +{ + tcbpointer tcbptr; + + if(K_I_Get_Ptr(tskid,&tcbptr)) /* send address of pointer */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXTTRIG_K_ERROR,tskid); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block */ + if (tcbptr->trig != 0xff) /* see if 0xFF, bypass if so */ + { + if (++tcbptr->trig == 1) /* increment the task start count byte */ + { + /* if count = 1, then put task into READY state */ + tcbptr->tcbstate = READY; + + /* see if this task has a higher priority then current RUNNING task */ + if (tcbptr->priority < active_priority) + PREEMPTED; /* yes, set preempted scheduling flag */ + } + } +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXTTRIG_K_OK,tskid); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status */ +} + +/************************************************************** + The following will place a task into the doubly linked list of + tasks that are waiting on time, if the CMX function was called + specifying a time wait period of non 0 (zero). Also the task + will be put to sleep, for the entity that the task was looking + for, was not present at the time of the function call. +**************************************************************/ +byte K_I_Time_Common(word16 timecnt,byte STATE) +{ + activetcb->tcbtimer = timecnt; /* load task time counter with proper time */ + activetcb->tcbstate = STATE; /* put task to sleep, idicating why */ + if (timecnt) /* put into timer chain ?? */ + { + /* let task sleep, indicating why and also waiting on time */ + activetcb->tcbstate |= TIME; + /* place into the doubly linked list. */ + if (tsk_timer_lnk->ftlink != (tcbpointer)tsk_timer_lnk) + { + activetcb->ftlink = tsk_timer_lnk->btlink->ftlink; + tsk_timer_lnk->btlink->ftlink = activetcb; + activetcb->btlink = tsk_timer_lnk->btlink; + } + else + { + activetcb->ftlink = activetcb->btlink = (tcbpointer)tsk_timer_lnk; + tsk_timer_lnk->ftlink = activetcb; + } + tsk_timer_lnk->btlink = activetcb; + } + PREEMPTED; /* set the preempted scheduling flag */ + K_I_Func_Return(); /* release task block */ + + /* the task WILL return to here, when it resumes execution. */ + K_I_Disable_Sched(); /* set lock out count. */ + if (activetcb->tcbtimer) /* see if timer non 0. */ + { + /* if so, remove from link list. */ + activetcb->ftlink->btlink = activetcb->btlink; + activetcb->btlink->ftlink = activetcb->ftlink; + } + /* see if task was woken, because the thing it was waiting for happened, + or that the time period specified has elapsed */ + if (activetcb->tcbstate & TIME_EXPIRED) + { + K_I_Func_Return(); /* release task block */ + return(K_TIMEOUT); /* return the warning: that the time period expired */ + } + else + { + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status */ + } +} +/************************************************************ + This function allows a task to wait for the desired time + period to expire or indefinitely. The K_Task_Wake and K_Task_Wake_Force + function may be used to wake this task, prior to the time + period expiring. +************************************************************/ +byte K_Task_Wait(word16 timecnt) +{ + K_I_Disable_Sched(); /* set task block */ + +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in4(CXTWATM_CALL,0,timecnt); + } +#endif + /* call the function that will suspend this task, indicate the + reason to suspend this task */ + if (K_I_Time_Common(timecnt,WAIT)) + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXTWATM_DELAY_K_ERROR); + } +#endif + return(K_TIMEOUT); + } + else + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXTWATM_DELAY_K_OK); + } +#endif + return(K_OK); + } +} + +/************************************************************ + The following function will be called by both the K_Task_Wake and + K_Task_Wake_Force functions. This will determine whether a task will + be forced to wake up, or to normally be woken up. + + if force = 0, then wake task only if task had called K_Task_Wait + + if force = 1, then wake task regardless of what function + was called, that suspended task + +************************************************************/ +byte K_I_Wake_Common(byte tskid,byte force) +{ + tcbpointer tcbptr; + + if(K_I_Get_Ptr(tskid,&tcbptr)) /* send address of pointer */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXTWAK_K_ERROR,tskid); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block */ + + /* if force non 0, then wake task, regardless of what it + was waiting for. If force = 0, then only wake task + if it was waiting on time or indefinitely. */ + if (tcbptr->tcbstate & (force ? ANY_WAIT : WAIT)) + { + /* see if task was waiting for a resource */ + if (tcbptr->tcbstate & (RESOURCE | SEMAPHORE)) + { + /* yes, remove task from resource wait linked list. */ + tcbptr->fwlink->bwlink = tcbptr->bwlink; + tcbptr->bwlink->fwlink = tcbptr->fwlink; + } + /* put task into the RESUME state, also possibly indicate time + expired, though it may not in the true sense */ + if (force) + tcbptr->tcbstate = RESUME | TIME_EXPIRED; + else + tcbptr->tcbstate = RESUME; + + /* see if this task has a higher priority then the current RUNNING task */ + if (tcbptr->priority < active_priority) + { + PREEMPTED; /* yes, set the preempted scheduling flag */ + } +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXTWAK_K_OK,tskid); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status */ + } + else + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXTWAK_K_NOT_WAITING); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_NOT_WAITING); /* return error that task was not waiting */ + } +} + +/***************************************************************** + !!! WARNING: the CMX timer task will not run !!!! + The CMX timer task will not be executed, nor the interrupt pipe + if this function is called. The task that called this function should + release it, by using the K_Task_Unlock function as soon as possible. + In most cases this function should NOT be used. Improper use is + abuse. Also the task that calls this function, MUST NOT call any + function that may suspend this task +*****************************************************************/ +void K_Task_Lock(void) +{ + /* set the task lock flag. This will stop the K_I_Scheduler + from re-scheduling, until the K_Task_Unlock function is called */ + + K_I_Disable_Sched(); +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXPRVR_CALL); + } +#endif +} +/**************************************************************** + Should be used ONLY if the task used the K_Task_Lock function. +*****************************************************************/ +void K_Task_Unlock(void) +{ + /* lower the task privilege flag. See if the K_I_Scheduler + should be invoked */ + +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXPRVL_CALL); + } +#endif + K_I_Func_Return(); +} +/*************************************************************** + The following function performs a cooperative scheduling. +***************************************************************/ +void K_Task_Coop_Sched(void) +{ + K_I_Disable_Sched(); /* set task block */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXSCHED_CALL); + } +#endif + DO_COOP_SCHED; /* set the cooperative scheduling flag */ + K_I_Func_Return(); /* release task block */ +} + +/*********************************************************** + Remove a task. Once removed this task can not be used in anyway + Also the task MUST NOT be waiting on anything, foe it will not + be removed if so. +***********************************************************/ +byte K_Task_Delete(byte tskid) +{ + tcbpointer tcbptr; + + if(K_I_Get_Ptr(tskid,&tcbptr)) /* send address of pointer */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXTRMV_K_ERROR,tskid); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block */ + if (tcbptr->tcbstate & ANY_WAIT) /* see if task waiting */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXTRMV_WAIT_K_ERROR,tskid); + } +#endif + K_I_Func_Return(); /* task was waiting, cannot terminate this task */ + return(K_ERROR); /* return error status, task was not terminated */ + } + else + { + K_I_Unlink(tcbptr); /* no, task not waiting. Remove task from TCB */ + if (tcbptr == activetcb) /* is task trying to commit suicide */ + { + activetcb->tcbstate = 0; /* load in highest priority task */ + PREEMPTED; /* set the preempted scheduling flag */ + } + } +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXTRMV_K_OK,tskid); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status, if task not committing suicide */ +} + +/*********************************************************************** + + TASK GENERAL PURPOSE FLAGS SYNCHRONIZATION + +************************************************************************/ +/*************************************************************** + This allows a task to reset a task's event flags that they + would like to be cleared. +***************************************************************/ +byte K_Event_Reset(byte tskid,word16 event) +{ + tcbpointer tcbptr; + + if(K_I_Get_Ptr(tskid,&tcbptr)) /* send address of pointer */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXERST_K_ERROR,tskid); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block */ + tcbptr->e_flags &= (~event); /* place the event bit(s) into clear state, indicated by mask. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in4(CXERST_K_OK,tskid,event); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status, if task not committing suicide */ +} +/*************************************************************** + The following allows a task to wait for 1 or more events to be + set, if they are not. Also a time period may be specified on how + long the task will wait for at least 1 event to be set, in which + the task wants. +MODE: += 0 nothing += 1 clear at beginning += 2 auto clear on match += 3 both 1 and 2 +***************************************************************/ +word16 K_Event_Wait(word16 match,word16 timecnt,byte mode) +{ + word16 good_bits; + + K_I_Disable_Sched(); /* set task block */ + if (mode & 0x01) /* see if we should clear specified events at beginning. */ + { + activetcb->e_flags &= (~match); /* yes, clear them. */ + } + /* see if ANY task flags match */ + if (!(activetcb->e_flags & (activetcb->e_match = match))) + { + /* NO, so call CMX function that will suspend task. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in4(CXEWATM_CALL,0,timecnt); + } +#endif + if (K_I_Time_Common(timecnt,FLAGS)) + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXEWATM_DELAY_K_TIMEOUT); + } +#endif + return(0); /* return the warning: that the time period expired */ + } + K_I_Disable_Sched(); /* set task block. */ + } + good_bits = activetcb->e_flags & match; /* what event bits matched. */ + if (mode & 0x02) /* should we clear the events now? */ + { + activetcb->e_flags &= ~match; /* yes, clear them. */ + } +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in4(CXEWATM_K_OK,0,good_bits); + } +#endif + K_I_Func_Return(); /* release task lock. */ + return(good_bits); /* return events that were set according to mask. */ +} + +/********************************************************************** + The following function will set possibly set an event. + +byte mode: 0 = specific task + 1 = highest priority (single task even if more then one of same) + 2 = highest priority waiting task on THIS EVENT + 3 = all tasks + 4 = all waiting tasks THIS EVENT + 5 = all with same priority (specify priority) + 6 = all waiting with same priority (specify priority) THIS EVENT +************************************************************************/ +byte K_Event_Signal(byte mode, byte tskid_pri,word16 flag) +{ + tcbpointer tcbptr; +#ifdef CMXTRACKER + byte cmxtracker_sent; +#endif + + if (mode > 0x06) /* see if mode greater then maximum allowed. */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXESIG_MODE,mode); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block */ +#ifdef CMXTRACKER + cmxtracker_sent = 0; +#endif + if (!mode) /* is mode 0. */ + { + if(K_I_Get_Ptr(tskid_pri,&tcbptr)) /* send address of pointer */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXESIG_K_ERROR,tskid_pri); + } +#endif + K_I_Func_Return(); + return(K_ERROR); + } + goto test_event; + } + else + { + tcbptr = timertask->nxttcb; /* start at head of linked list. */ + } + for (; tcbptr != cmx_tcb; tcbptr = tcbptr->nxttcb) /* see if we tested all. */ + { + if (mode > 0x04) /* is mode greater then 4? */ + { + if (tcbptr->priority != tskid_pri) /* see if priority match. */ + continue; + } + if (!(mode & 0x01)) /* see if task must be waiting on this EVENT */ + { + if (!((tcbptr->e_match & flag) && + (tcbptr->tcbstate & FLAGS))) + { + continue; /* continue if task was not. */ + } + } +test_event: +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + if (!cmxtracker_sent) + { + cmxtracker_sent = tcbptr - cmx_tcb; + } + } +#endif + /* see if task event(s) match. */ + if (tcbptr->e_match & (tcbptr->e_flags |= flag)) + { + if (tcbptr->tcbstate & FLAGS) /* see if task was waiting on EVENT. */ + { + tcbptr->tcbstate = RESUME; /* yes, the task may now resume. */ + + if (TEST_NOT_PREEMPTED) /* see if preempted flag not set yet. */ + { + if (tcbptr->priority < active_priority) + PREEMPTED; /* yes, set the preempted scheduling flag */ + } + if (mode < 0x03) /* see if we should exit function. */ + break; + } + } + if (mode < 0x02) /* see if we should exit function. */ + break; + } +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in3(CXESIG_K_OK,mode,cmxtracker_sent); + } +#endif + K_I_Func_Return(); /* call CMX function, that will release task block */ + return(K_OK); /* return good status */ +} + +/******************************************************************* + RESOURCE MANAGER +********************************************************************/ + +/******************************************************************* + This function allows a task to reserve or get this resource. + + if func_mode = 1, then means get resource if free, otherwise return + + if func_mode = 0, then if the resource is "owned" by another task, + then this task will be suspended until this resource is free or time + period expires. +*******************************************************************/ +byte K_I_Resource_Common(byte res_grp,word16 timecnt,byte func_mode) +{ + RESHDR *res_ptr; + tcbpointer tp; + + if (res_grp >= MAX_RESOURCES) /* see if resource number allowed */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in3(CXRSRSV_K_ERROR,res_grp,func_mode); + } +#endif + return(K_ERROR); /* no, return error status */ + } + + K_I_Disable_Sched(); /* set task block */ + + res_ptr = &res_que[res_grp]; /* get address of resource */ + + if (res_ptr->owner) /* does a task own this resource? */ + { + /* yes, what function was used. */ + if (func_mode) /* did the K_Resource_Get function call this function */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXRSRSV_K_RESOURCE_OWNED,res_grp); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_RESOURCE_OWNED); /* return error that resource is already owned */ + } +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in4(CXRSRSV_CALL,res_grp,timecnt); + } +#endif + /* place the task into the resource doubly linked wait list. */ + + tp = (tcbpointer)res_ptr; /* address of resource link list. */ + do /* insert tcb at appropriate wait slot, based on priority. */ + { +#if 0 +#if 1 + _asm + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + _endasm; +#else + abyte('.'); +#endif +#endif + + tp = tp->fwlink; + } while ((tp != (tcbpointer)res_ptr) && (tp->priority <= activetcb->priority)); + /* We should insert it just after prevtcb, just before tp. */ + + activetcb->fwlink = tp->bwlink->fwlink; + tp->bwlink->fwlink = activetcb; + activetcb->bwlink = tp->bwlink; + tp->bwlink = activetcb; + + if (res_ptr->fwlink->priority < res_ptr->owner->priority) + { + res_ptr->owner->priority = res_ptr->fwlink->priority; + /* update linked list to put owner in correct spot */ + K_I_Unlink(res_ptr->owner); + K_I_Priority_In(res_ptr->owner,res_ptr->owner->priority); + } + /* + res_ptr->fwlink->priority is highest priority !!! + which we will then raise owner to highest !!! + */ + /* go place task into suspended state. */ + if (K_I_Time_Common(timecnt,RESOURCE)) + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in1(CXRSRSV_DELAY_K_TIMEOUT); + } +#endif + return(K_TIMEOUT); /* return the warning: that the time period expired */ + } + else + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXRSRSV_K_OK,res_grp); + } +#endif + return(K_OK); + } + } + /* NO, no task owned this resource. This task is now the owner of + this resource */ + res_ptr->fwlink = res_ptr->bwlink = (tcbpointer)(res_ptr); + res_ptr->owner = activetcb; + res_ptr->owner_priority = activetcb->priority; +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in3(CXRSRSV_K_OK,res_grp,func_mode); + } +#endif + K_I_Func_Return(); /* release task block. */ + return(K_OK); /* return good status. */ +} + +/***************************************************************** + This lets a task that owns a resource, to release it. Once the resource + is released, if another task is waiting for it, then that task will + automatically become the owner. +******************************************************************/ +byte K_Resource_Release(byte res_grp) +{ + RESHDR *res_ptr; + + if (res_grp >= MAX_RESOURCES) /* see if resource group OK */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXRSREL_K_ERROR,res_grp); + } +#endif + return(K_ERROR); /* no, return error status */ + } + + res_ptr = &res_que[res_grp]; /* get address of resource */ + if (res_ptr->owner != activetcb) /* see if task really "owns" this. */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXRSREL_K_RESOURCE_NOT_OWNED,res_grp); + } +#endif + return(K_RESOURCE_NOT_OWNED); /* resource not owned by this task */ + } + K_I_Disable_Sched(); /* set task block */ + /* restore original task's priority */ + active_priority = res_ptr->owner_priority; + if (res_ptr->owner->priority != active_priority) + { + /* update linked list to put owner in correct spot */ + K_I_Unlink(res_ptr->owner); + K_I_Priority_In(res_ptr->owner,active_priority); + } + /* see if another task waiting for this resource. */ + if ((res_ptr->owner = res_ptr->fwlink) != (tcbpointer)res_ptr) + { + /* properly adjust the linked list. */ + res_ptr->fwlink = res_ptr->fwlink->fwlink; + res_ptr->fwlink->bwlink = res_ptr->owner->bwlink; + res_ptr->owner->tcbstate = RESUME; /* wake task that was sleeping. */ + if (res_ptr->owner->priority < active_priority) + PREEMPTED; /* yes, set the preempted scheduling flag */ + res_ptr->owner_priority = res_ptr->owner->priority; + } + else + { + res_ptr->owner = NULL; + } +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXRSREL_K_OK,res_grp); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status to caller */ +} + +/***************************************************************** + + QUEUE MANAGER + +******************************************************************/ +byte K_Que_Create(sign_word16 num_slots,byte slot_size,byte *queuearray,byte queuenum) +{ + QUEHDR *queue_ptr; + + if (queuenum >= MAX_QUEUES) /* see if queue number OK. */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQCRE_K_ERROR,queuenum); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQCRE_K_OK,queuenum); + } +#endif + queue_ptr = &queue[queuenum]; /* get address of proper queue handler. */ + queue_ptr->base_ptr = queuearray; /* tell CMX where queue begins. */ + queue_ptr->num_slots = num_slots; /* load number of slots */ + queue_ptr->size_slot = slot_size; /* load in the size of slots */ + K_Que_Reset(queuenum); /* reset the queue, all slots empty. */ + K_I_Func_Return(); /* release task block */ + return(K_OK); +} +byte K_Que_Reset(byte queuenum) +{ + QUEHDR *queue_ptr; + + if (queuenum >= MAX_QUEUES) /* see if queue number within range. */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQRST_K_ERROR,queuenum); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block. */ + queue_ptr = &queue[queuenum]; /* get address of proper queue handler. */ + /* reset the queue_ptr's variables, that maintain the queue_ptr */ + queue_ptr->queue_cnt = queue_ptr->head = queue_ptr->tail = 0; +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQRST_K_OK,queuenum); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status. */ +} + + +/************************************************************ + CMX general add to queue function. + called by K_Que_Add_Top and K_Que_Add_Bottom functions. + + test: if testing for less then 0, then pointer = num_slots - 1 + if testing for equal to num_slots then pointer = 0 + + when adding to top + add to where head points + increment head and test. + + when adding to bottom. + decrement tail and test + add to where tail points + + when removing from top + decrement head and test + remove from where head points + + when removing from bottom + remove from where tail points + increment tail and test + + top = 0: add to bottom + top = 1: add to top + +*************************************************************/ + +byte K_I_Que_Add_Common(byte queuenum,void *byteptr,sign_word16 top) +{ + QUEHDR *queue_ptr; + + queue_ptr = &queue[queuenum]; /* get address of proper queue handler. */ + if (queuenum >= MAX_QUEUES || (!queue_ptr->size_slot)) + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQADD_K_ERROR,queuenum); + } +#endif + return(K_ERROR); + } + + K_I_Disable_Sched(); /* set task block */ + + /* see if queue is full already */ + if (queue_ptr->queue_cnt == queue_ptr->num_slots) + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQADD_FULL,queuenum); + } +#endif + K_I_Func_Return(); /* release task block. */ + return(K_ERROR); /* return proper status. */ + } + if (top) /* see if adding to top of queue */ + { + top = queue_ptr->head; /* top will now be our index into array. */ + + /* see if head equals the max number slots, and + if so, set pointer to bottom of queue */ + if (++queue_ptr->head == queue_ptr->num_slots) + queue_ptr->head = 0; + } + else + { + /* were adding to bottom of queue, use tail pointer */ + if (--queue_ptr->tail < 0) /* decrement tail pointer and test */ + queue_ptr->tail = (queue_ptr->num_slots - 1); + + top = queue_ptr->tail; /* top will now be our index into array. */ + } + /* K_I_Copy = dest,source,count */ + K_I_Copy((&(queue_ptr->base_ptr[top * + queue_ptr->size_slot])),byteptr,queue_ptr->size_slot); + +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQADD_K_OK,queuenum); + } +#endif + /* see if queue now full */ + if (++queue_ptr->queue_cnt == queue_ptr->num_slots) + { + K_I_Func_Return(); + return(K_QUE_FULL); /* return status indicating queue now full. */ + } + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status */ +} + +/******************************************************** + test: if testing for less then 0 then pointer = num_slots - 1 + if testing for equal to num_slots then pointer = 0 + + when removing from top + decrement head and test + remove from where head points + + when removing from bottom + remove from where tail points + increment tail and test + + top = 0: remove from bottom + top = 1: remove from top + +*********************************************************/ + +byte K_I_Que_Get_Common(byte queuenum,void *byteptr,sign_word16 top) +{ + QUEHDR *queue_ptr; + + queue_ptr = &queue[queuenum]; /* get address of proper queue handler. */ + if (queuenum >= MAX_QUEUES || (!queue_ptr->size_slot)) + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQRMV_K_ERROR,queuenum); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block */ + /* see if queue_ptr has any slots filled */ + if (!(queue_ptr->queue_cnt)) + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQRMV_EMPTY,queuenum); + } +#endif + K_I_Func_Return(); + return(K_ERROR); /* no, return error */ + } + if (top) /* see if request was to remove top slot contents */ + { + /* decrement head and test to see if head less then 0 */ + if (--queue_ptr->head < 0) + queue_ptr->head = (queue_ptr->num_slots - 1); + + top = queue_ptr->head; /* top will now be our index into array. */ + } + else + { + /* request was to remove from bottom slot */ + + top = queue_ptr->tail; /* top will now be our index into array. */ + + /* see if tail pointer has reached it's maximum count and set + to 0, if so */ + if (++queue_ptr->tail == queue_ptr->num_slots) + queue_ptr->tail = 0; + } + /* K_I_Copy = dest,source,count */ + K_I_Copy(byteptr,(&(queue_ptr->base_ptr[top * + queue_ptr->size_slot])),queue_ptr->size_slot); +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXQRMV_K_OK,queuenum); + } +#endif + /* see if queue_ptr now empty */ + if (--queue_ptr->queue_cnt) + { + K_I_Func_Return(); /* no, release task block */ + return(K_OK); /* return good operation */ + } + K_I_Func_Return(); /* yes, queue empty, release task block */ + return(K_QUE_EMPTY); /* return warning that queue now empty */ +} + +/*********************************************************** + MESSAGE FUNCTIONS +**********************************************************/ +/********************************************************** + The following is the generalize message wait function + + is_get = 0, means to wait for message, with possible timeout + + is_get = 1, means don't wait for message, if none. + +**********************************************************/ +void * K_I_Mesg_Wait_Common(byte mailbox,word16 timecnt,byte is_get) +{ + MAILBOX *mail_ptr; + byte *copy_ptr; + MSG *link; + + if (mailbox >= MAX_MAILBOXES) /* see if mailbox number OK. */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in3(CXMSWATM_K_ERROR,mailbox,is_get); + } +#endif + return(NULL); /* no, return null idicating error. */ + } + K_I_Disable_Sched(); /* set task block. */ + mail_ptr = &mail_box[mailbox]; /* address of the CMX mailbox handler. */ + if (mail_ptr->waiter) /* see if another task already "owns" this mailbox. */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in3(CXMSWATM_MAILBOX_K_ERROR,mailbox,is_get); + } +#endif + K_I_Func_Return(); /* release task block. */ + return(NULL); /* return error, for only one task may wait on mailbox. */ + } + if (!mail_ptr->first_lnk) /* any messages present in mailbox, null = no */ + { + if (is_get) /* K_Mesg_Get function used, do not wait */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXMSGET_NOMESG_K_ERROR,mailbox); + } +#endif + K_I_Func_Return(); /* release task block. */ + return(NULL); /* return error. */ + } + mail_ptr->waiter = activetcb; /* identify who "owns" mailbox. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in4(CXMSWATM_CALL,mailbox,timecnt); + } +#endif + K_I_Time_Common(timecnt,WAIT_MESG); /* go suspend task. */ + + /* task will be return to here by the K_I_Time_Common function. */ + mail_ptr->waiter = NULL; /* now task will NOT own mailbox. */ + /* test to see if time expired or task forcefully woken, prior + to a message being set to this mailbox. */ + if (activetcb->tcbstate & TIME_EXPIRED) + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXMSWATM_NOMESG_K_ERROR,mailbox); + } +#endif + return(NULL); /* yes, pass back null, indicating no message. */ + } + else + { + K_I_Disable_Sched(); /* set task lock */ + } + } + + link = mail_ptr->first_lnk; /* get first link. */ + link->env_link = message_ptr->env_link; /* re-arrange linked list. */ + message_ptr->env_link = link; + message_free++; /* increment message free counter. */ + + copy_ptr = link->message; /* address of message */ + activetcb->mesg_sender = link->sender; /* what task sent this message. */ + + /* update link to point to next message link, also test if more messages + present. */ + if ((mail_ptr->first_lnk = link->link)) + { + if (mail_ptr->task_num) /* see if mailbox is suppose to signal event, + that it has messages. */ + /* yes, then go set proper event bit. */ + K_Event_Signal(0,mail_ptr->task_num,mail_ptr->event_num); + } + link->link = NULL; /* set message link to NULL. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + if (is_get) + cmxtracker_in5(CXMSGET_K_OK,mailbox,copy_ptr); + else + cmxtracker_in5(CXMSWATM_K_OK,mailbox,copy_ptr); + } +#endif + K_I_Func_Return(); /* release task block */ + return((void *)copy_ptr); /* return good status to caller */ +} + +/******************************************************************* + General function for sending a message to a mailbox. + + wait = 0, do not wait after sending message + + wait = 1, wait after sending message, for receiver to wake us + +*******************************************************************/ +byte K_I_Mesg_Send_Common(byte mailbox,word16 timecnt,void *mesg,byte wait) +{ + MAILBOX *mail_ptr; + MSG *link; /* scratch pointer */ + + K_I_Disable_Sched(); + /* see if mailbox within range and that there are + message links available. */ + if ((mailbox >= MAX_MAILBOXES) || (!message_free)) + { + /* error */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in3(CXMSSEND_K_ERROR,mailbox,wait); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_ERROR); /* return good status to caller */ + } + mail_ptr = &mail_box[mailbox]; /* CMX mailbox handler. */ + if (mail_ptr->waiter) /* task waiting on this mailbox */ + { + mail_ptr->waiter->tcbstate = RESUME; /* allow task to run again */ + if (mail_ptr->waiter->priority < active_priority) + PREEMPTED; /* yes, so set the preempted scheduling flag */ + } + + link = message_ptr; /* link now points to message header */ + message_ptr = link->env_link; /* update linked list */ + + if (mail_ptr->first_lnk) /* see if first link set */ + { + mail_ptr->next_lnk->link = link; /* yes, set next link. */ + } + else + { + mail_ptr->first_lnk = link; /* set first link. */ + /* because this is the first message into the mailbox + see if mailbox is suppose to notify task that there + are messages now residing in mailbox. */ + if (mail_ptr->task_num) /* does task want to be notified? */ + /* yes, go set event. */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + if (locked_out == 2) + { + cmxtracker_in1(INT_ACTION); + } + } +#endif + K_Event_Signal(0,mail_ptr->task_num,mail_ptr->event_num); + } + } + mail_ptr->next_lnk = link; /* set mailbox next link. */ + link->message = (byte *)mesg; /* load address of message. */ + link->sender = NULL; /* set sender to NULL. This way interrupt will be covered */ + --message_free; /* decrement message free */ + + if (wait) /* is this the send and wait call function */ + { + link->sender = activetcb; /* load what task sent message. */ + /* this task will now be suspended. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in5(CXMSSENW_K_OK,mailbox,mesg); + cmxtracker_in4(CXMSSEND_CALL,mailbox,timecnt); + } +#endif + if (K_I_Time_Common(timecnt,SEND_MESG)) + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXMSSEND_K_TIMEOUT,mailbox); + } +#endif + return(K_TIMEOUT); + } + else + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXMSSEND_K_OK,mailbox); + } +#endif + return(K_OK); + } + } + else + { + link->sender = NULL; /* set sender to NULL. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in5(CXMSSEND_K_OK1,mailbox,mesg); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status to caller */ + } +} + +/************************************************************ + the following function sets up a mailbox to automatically + set an event of a particular task, when and if this mailbox + has messages in it. +*************************************************************/ +byte K_Mbox_Event_Set(byte mailbox,byte taskid,word16 event_num) +{ + MAILBOX *mail_ptr; + + if (mailbox >= MAX_MAILBOXES) /* see if mailbox number OK. */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXMSBXEV_K_ERROR,mailbox); + } +#endif + return(K_ERROR); /* NO, send error status. */ + } + K_I_Disable_Sched(); /* set task block. */ + + mail_ptr = &mail_box[mailbox]; /* get CMX mailbox handler */ + mail_ptr->task_num = taskid; /* load task_num with task slot number. */ + mail_ptr->event_num = event_num; /* what event bit will be set. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXMSBXEV_K_OK,mailbox); + } +#endif + K_I_Func_Return(); /* release task block. */ + return(K_OK); /* return good status. */ +} + +/***************************************************************** + This function allows a task that recieved a message to go wake + the task that sent this message, if the task is waiting for an + acknowledgement. +*****************************************************************/ +byte K_Mesg_Ack_Sender(void) +{ + K_I_Disable_Sched(); /* set task block. */ + if (activetcb->mesg_sender) /* see if message was sent by a task. */ + { + /* see if the task that sent message waiting for acknowledgement. */ + if (activetcb->mesg_sender->tcbstate & SEND_MESG) + { + activetcb->mesg_sender->tcbstate = RESUME; /* yes, wake task. */ + /* see if this task has a higher priority, then current running task. */ + if (activetcb->mesg_sender->priority < active_priority) + PREEMPTED; /* yes, so set the preempted scheduling flag */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXMSACK_K_OK,(byte)(activetcb->mesg_sender - cmx_tcb)); + } +#endif + } + } + K_I_Func_Return(); /* release task block. */ + return(K_OK); /* always return good status */ +} + +/******************************************************************** + CYCLIC TIMER FUNCTIONS +*********************************************************************/ +/* tproc_start states: + 0 = stopped + 1 = started +*/ + +/******************************************************************** + This function sets up the cyclic timer's event parameters. +********************************************************************/ +byte K_Timer_Create(byte timed_num,byte mode,byte tskid_pri,word16 event_num) +{ + struct _tcproc *tpptr; + + if (timed_num >= MAX_CYCLIC_TIMERS) /* have we exceeded the maximum number */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXCTCRE_K_ERROR,timed_num); + } +#endif + return(K_ERROR); /* yes, return error status */ + } + K_I_Disable_Sched(); /* set task block */ + tpptr = &tcproc[timed_num]; /* get address of cyclic timer handler */ + tpptr->mode = mode; /* load K_Event_Signal MODE */ + tpptr->tskid_pri = tskid_pri; /* load in the tasks slot number + or priority. May not be used. */ + tpptr->event_num = event_num; /* load in the event to be set. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXCTCRE_K_OK,timed_num); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status */ +} + +/****************************************************************** + This is the common routine that the most of the cyclic timer functions + will call. This function starts, or restarts a cyclic timer and possibly + also changes the cyclic timer's time parameters. + +mode: += 0: = just restart timer if not started += 1: = change only initial time and start += 2: = change only cyclic time and start += 3: = change both initial time and cyclic time and start +**************************************************************************/ +byte K_I_Cyclic_Common(byte timed_num,word16 timecnt, word16 cyclic,byte mode) +{ + struct _tcproc *tpptr; + + if (timed_num >= MAX_CYCLIC_TIMERS) /* have we exceeded the maximum number */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXCTCOM_K_ERROR,timed_num); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block */ + tpptr = &tcproc[timed_num]; /* get the CMX handler for this cyclic timer. */ + if (mode & 0x01) /* see if mode bit 0 set. */ + { + tpptr->tproc_timer = timecnt; /* load time period into counter */ + } + if (mode & 0x02) /* see if mode bit 1 set. */ + { + tpptr->reload_time = cyclic; /* load cyclic time into counter */ + } + if (!(tpptr->tproc_start)) /* see if 0 */ + { + tpptr->tproc_start = 1; /* start the timed procedure */ + /* add to the cyclic timers doubly linked list. */ + if (cyclic_lnk->ftlink != (struct _tcproc *)cyclic_lnk) + { + tpptr->ftlink = cyclic_lnk->btlink->ftlink; + cyclic_lnk->btlink->ftlink = tpptr; + tpptr->btlink = cyclic_lnk->btlink; + } + else + { + tpptr->ftlink = tpptr->btlink = (struct _tcproc *)cyclic_lnk; + cyclic_lnk->ftlink = tpptr; + } + cyclic_lnk->btlink = tpptr; + } +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + if (mode == 3) + { + cmxtracker_in2(CXCTSTT_K_OK,timed_num); + } + else if (mode == 2) + { + cmxtracker_in2(CXCTRSTC_K_OK,timed_num); + } + else if (mode == 1) + { + cmxtracker_in2(CXCTRSTI_K_OK,timed_num); + } + else + { + cmxtracker_in2(CXCTRSTT_K_OK,timed_num); + } + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status */ +} + +/****************************************************************** + stop a cyclic timer function +******************************************************************/ +byte K_Timer_Stop(byte timed_num) +{ + struct _tcproc *tpptr; + + if (timed_num >= MAX_CYCLIC_TIMERS) /* have we exceeded the maximum number */ + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXCTSTP_K_ERROR,timed_num); + } +#endif + return(K_ERROR); + } + K_I_Disable_Sched(); /* set task block */ + tpptr = &tcproc[timed_num]; /* address of cyclic timer structure. */ + if (tpptr->tproc_start) /* see if non 0 */ + { + tpptr->tproc_start = 0; /* stop cyclic timer. */ + /* the following removes the cyclic timer from + the doubly linked list of started cyclic timers. */ + tpptr->ftlink->btlink = tpptr->btlink; + tpptr->btlink->ftlink = tpptr->ftlink; + } +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(CXCTSTP_K_OK,timed_num); + } +#endif + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status */ +} + + +/********************************************************************* + + memory manager + +**********************************************************************/ +/* here's what a memory partition will look like + ptr head; ptr to head of free list_ptr + byte body; body of memory partition starts here + does not test to ensure size of array is large enough for + block size times the number of blocks */ + +/**************************************************************** + This function creates a fixed memory block according to the + parameters passed. Make note, that the memory address supplied + as the beginning of this fixed memory block is not tested as + to legal CPU boundries and that the size of this memory block + is free to be used. +****************************************************************/ +void K_Mem_FB_Create(void *part,word16 bsize,word16 nblocks) +{ + byte *link; /* scratch pointer */ + +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in5(CXBFCRE_K_OK,0,part); + } +#endif + link = (byte *)part + sizeof(byte *); /* address of 1st block */ + *(byte **) part = link; /* point head at 1st block */ + + while (nblocks--) + { + part = link; /* skip to next block */ + /* compute addr of next block */ + link += bsize; /* compute addr of next block */ + *(byte **) part = link; /* create link to it */ + } + *(word16 **) part = 0; /* last link in chain is null */ +} + +/**************************************************************** + this function passes a pointer of a free fixed memory block + if one is available, to the caller. +****************************************************************/ +byte K_Mem_FB_Get(void *part,byte **addr) +{ + byte *link; /* scratch pointer */ + + K_I_Disable_Sched(); /* prevent interruption by another task */ + link = *(byte **) part; /* get head of free memory block */ + if (link != NULL) /* exhausted if link is null */ + { + *(byte **) part = *(byte **) link; /* update head */ + *addr = link; /* load address of memory block to user pointer */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in5(CXBFGET_K_OK,0,link); + } +#endif + K_I_Func_Return(); /* release task block. */ + return(K_OK); /* return good status. */ + } + else + { +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in5(CXBFGET_K_ERROR,0,part); + } +#endif + K_I_Func_Return(); /* release task block. */ + return(K_ERROR); /* Error: no more memory blocks available */ + } +} + + +/**************************************************************** + this function releases fixed memory block, back into the fixed block + memory pool. +****************************************************************/ +void K_Mem_FB_Release(void *part,byte *addr) +{ + byte *link; /* scratch pointer */ + + K_I_Disable_Sched(); /* set task block. */ + link = *(byte **) part; /* save old head of free memory */ + *(byte **) addr = link; /* point released block at old head */ + *(byte **) part = addr; /* point head at released block */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in5(CXBFREL_K_OK,0,addr); + } +#endif + K_I_Func_Return(); /* release task block. */ + +} + +void K_OS_Start(void) +{ + PROC_DISABLE_INT; /* disable interrupts. */ + PREEMPTED; /* set preempted K_I_Scheduler flag. */ + CMX_ACTIVE; /* identify that were CMX OS active. */ + K_I_Scheduler(); /* invoke K_I_Scheduler */ +} + +/******************************************************************* + The following is the CMX timer task. This will see if any tasks + need their time counters decremented (because they have specified + a time period, and thier waiting). If so then this will use the doubly + linked list of tasks that need their time counters decremented. Once a + task has it's time counter decrement to 0, then the task will be place + into the RESUME state, and remove from the linked list. + + Also the cyclic timers linked list will be tested to see if any cyclic + timers need thier respective time counters decremented. If so then this + will use the doubly linked list of cyclic timers that need their time + counters decremented. Once a cyclic timer has it's time counter decrement + to 0, then the cyclic timer will have its K_Event_Signal parameters executed + and also the cyclic time will be reloaded, if non zero. +****************************************************************/ + +void K_I_Timer_Task(void) +{ + tcbpointer x; + struct _tcproc *tpptr; + + tpptr = cyclic_lnk->ftlink; /* set pointer to cyclic linked list. */ + while (tpptr != (struct _tcproc *)cyclic_lnk) /* test for done of list. */ + { + if (!(--tpptr->tproc_timer)) /* decrement time counter and test. */ + { + /* if 0, then reload time counter, with cyclic time. */ + if ((tpptr->tproc_timer = tpptr->reload_time) == 0) + { + /* if cyclic time period 0, then stop cyclic timer + and remove from linked list. */ + tpptr->tproc_start = 0; + tpptr->ftlink->btlink = tpptr->btlink; + tpptr->btlink->ftlink = tpptr->ftlink; + } + /* execute the cyclic timer's K_Event_Signal function parameters. */ +#ifdef CMXTRACKER + if (CMXTRACKER_ON) + { + cmxtracker_in2(TIMER_TASK_ACTION,(byte)(tpptr - tcproc)); + } +#endif + K_Event_Signal(tpptr->mode,tpptr->tskid_pri,tpptr->event_num); + } + /* adjust pointer to next linked list member. */ + tpptr = tpptr->ftlink; + } /* while loop */ + /* set pointer to beginning of task timer link list. */ + x = tsk_timer_lnk->ftlink; + while (x != (tcbpointer)tsk_timer_lnk) /* if not end of linked list. */ + { + if (x->tcbstate & TIME) /* see if task really waiting on time out. */ + { + if (!(--x->tcbtimer)) /* yes, go decrement the task time counter. */ + { + /* if time expired, test to see if task waiting on resource. */ + if (x->tcbstate & (RESOURCE | SEMAPHORE)) + { + /* yes, remove task from resource wait linked list. */ + x->fwlink->bwlink = x->bwlink; + x->bwlink->fwlink = x->fwlink; + } + /* set the task into the RESUME state. */ + x->tcbstate = RESUME | TIME_EXPIRED; + /* indicate we should remove task from link list, this + will be done by the function that place this task + into the wait (sleep) state. This way we do NOT + waste time in here performing this. */ + x->tcbtimer = 1; + if (x->priority < active_priority) + PREEMPTED; /* yes, set preempted scheduling flag */ + } + } + x = x->ftlink; /* point to next link. */ + } +} /* K_I_Timer_Task */ + +/***************************************************************** + Semaphore stuff +******************************************************************/ +/* + Pend on semaphore, if count 0, otherwise return with semaphore + + mode 0 : wait if semaphore not present + mode 1 : do NOT wait if semaphore not present, return immediatedly + +*/ + +byte K_I_Semaphore_Get_Common(byte sem_num, word16 timecnt, byte mode) +{ + SEM *sem_ptr; + + if (sem_num >= MAX_SEMAPHORES) + { + return(K_ERROR); /* return good status to caller */ + } + K_I_Disable_Sched(); + sem_ptr = &sem_array[sem_num]; /* CMX semaphore handler. */ + if (sem_ptr->fwlink == NULL) + { + K_I_Func_Return(); /* release task block */ + return(K_ERROR); /* return good status to caller */ + } + if (!sem_ptr->sem_count) + { + if (mode) + { + K_I_Func_Return(); /* release task block */ + return(K_SEMAPHORE_NONE); /* return error that semaphore + had not been posted to */ + } + if (sem_ptr->fwlink != (tcbpointer)sem_ptr) /* is at least one task waiting + on is semaphore */ + { + activetcb->fwlink = sem_ptr->bwlink->fwlink; + sem_ptr->bwlink->fwlink = activetcb; + activetcb->bwlink = sem_ptr->bwlink; + sem_ptr->bwlink = activetcb; + } + else + { + sem_ptr->fwlink = sem_ptr->bwlink = activetcb; + activetcb->fwlink = activetcb->bwlink = (tcbpointer)sem_ptr; + } + if (K_I_Time_Common(timecnt,SEMAPHORE)) /* go suspend task. */ + return(K_TIMEOUT); /* return the warning: that the time period expired */ + else + return(K_OK); + } + --sem_ptr->sem_count; + K_I_Func_Return(); + return(K_OK); +} /* K_I_Semaphore_Get_Common */ + +byte K_Semaphore_Post(byte sem_num) +{ + SEM *sem_ptr; + tcbpointer tp; + + if (sem_num >= MAX_SEMAPHORES) + { + return(K_ERROR); /* return good status to caller */ + } + K_I_Disable_Sched(); + sem_ptr = &sem_array[sem_num]; /* CMX semaphore handler. */ + if (sem_ptr->fwlink == NULL) + { + K_I_Func_Return(); /* release task block */ + return(K_ERROR); /* return good status to caller */ + } + ++sem_ptr->sem_count; + if (sem_ptr->fwlink != (tcbpointer)sem_ptr) /* does a task own this semaphore */ + { + sem_ptr->fwlink->tcbstate = RESUME; /* allow task to run again */ + if (sem_ptr->fwlink->priority < active_priority) + PREEMPTED; /* yes, so set the preempted scheduling flag */ + tp = sem_ptr->fwlink; + tp->fwlink->bwlink = tp->bwlink; + sem_ptr->fwlink = tp->fwlink; + --sem_ptr->sem_count; /* reduce count again, because this task now + has semaphore */ + } + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status to caller */ +} /* K_Semaphore_Post */ + +byte K_Semaphore_Create(byte sem_num, word16 n) +{ + SEM *sem_ptr; + + if (sem_num >= MAX_SEMAPHORES) + { + return(K_ERROR); /* return good status to caller */ + } + K_I_Disable_Sched(); + sem_ptr = &sem_array[sem_num]; /* CMX semaphore handler. */ + sem_ptr->fwlink = (tcbpointer)sem_ptr; + sem_ptr->bwlink = (tcbpointer)sem_ptr; + sem_ptr->sem_n = sem_ptr->sem_count = n; + K_I_Func_Return(); /* release task block */ + return(K_OK); /* return good status to caller */ +} + +/* +mode = 0 = do not flush if task owns semaphore +mode = 1 = do flush if task owns semaphore +also reset count to original value +*/ +byte K_Semaphore_Reset(byte sem_num,byte mode) +{ + SEM *sem_ptr; + + if (sem_num >= MAX_SEMAPHORES) + { + return(K_ERROR); /* return good status to caller */ + } + K_I_Disable_Sched(); + sem_ptr = &sem_array[sem_num]; /* CMX semaphore handler. */ + if (sem_ptr->fwlink == NULL) + { + K_I_Func_Return(); /* release task block */ + return(K_ERROR); /* return good status to caller */ + } + if (sem_ptr->fwlink != (tcbpointer)sem_ptr) /* see if another task already "owns" this semaphore. */ + { + if (!mode) + { + K_I_Func_Return(); /* release task block. */ + return(K_ERROR); + } + else + { + do { + sem_ptr->fwlink->tcbstate = RESUME | TIME_EXPIRED; /* allow task to run again */ + if (sem_ptr->fwlink->priority < active_priority) + PREEMPTED; /* yes, so set the preempted scheduling flag */ + if ((sem_ptr->fwlink = sem_ptr->fwlink->fwlink) == (tcbpointer)sem_ptr) + sem_ptr->bwlink = (tcbpointer)sem_ptr; + } + while(sem_ptr->fwlink != (tcbpointer)sem_ptr); + } + } + sem_ptr->sem_count = sem_ptr->sem_n; + K_I_Func_Return(); /* release task block. */ + return(K_OK); +} + + + diff --git a/src/kernel/cmx/diag.asm b/src/kernel/cmx/diag.asm new file mode 100755 index 00000000..c741e491 --- /dev/null +++ b/src/kernel/cmx/diag.asm @@ -0,0 +1,157 @@ +; diag.asm +; Polled mode serial output for built in Z180 port SERIAL 0 (Hytech CMX) + +; ----------------------------------------------------------------------------- + +$ io64180.inc + +; .area _CODE + rseg RCODE + +; ----------------------------------------------------------------------------- + + public _abyte + +_abyte:: + .if 0 ; SDCC + ld hl,2 + add hl,sp + ld a,(hl) + .else ; IAR + ld a,e + .endif + + public abyte + +abyte:: + .if 0 ; 0=enable abytes, 1=disable abytes (doesn't affect the code size) + ret + .else + push af + .endif + + .if 0 ; checking to see when memory corruption occurs + extern _osBank + ld a,(_osBank) + cp 0 + jr z,ok + pop af + ld a,'_' + push af +ok: + .endif + +L1$: in0 a,(STAT1) ;(STAT0) + and 10b + jr z,L1$ + + pop af + out0 (TDR1),a ;(TDR0),a + + .if 0 + di + .endif + .if 0 + ei + .endif + ret + + public _acrlf + +_acrlf:: + + public acrlf + +acrlf:: + ld a,0dh + call abyte + ld a,0ah + jr abyte + + public _ahexw + +_ahexw:: + .if 0 ; SDCC + ld hl,2 + add hl,sp + ld e,(hl) + inc hl + ld d,(hl) + .endif + ex de,hl + + public ahexw + +ahexw:: + ld a,h + call ahexb + ld a,l + + public ahexb + +ahexb:: + push af + rrca + rrca + rrca + rrca + call ahexn + pop af + + public ahexn + +ahexn:: + and 0fh + add a,90h + daa + adc a,40h + daa + jr abyte + + public _amess + +_amess:: + .if 0 ; SDCC + ld hl,2 + add hl,sp + ld e,(hl) + inc hl + ld d,(hl) + .endif + ex de,hl + +amess_loop: + ld a,(hl) + inc hl + or a + ret z + + call abyte + jr amess_loop + + public amess + +amess:: + ex (sp),hl + push af + + .if 1 + call amess_loop + .else +L01$: ld a,(hl) + inc hl + or a + jr z,L02$ + + call abyte + jr L01$ + +L02$: + .endif + pop af + ex (sp),hl + ret + +; ----------------------------------------------------------------------------- + + END diff --git a/src/kernel/cmx/escc.asm b/src/kernel/cmx/escc.asm new file mode 100755 index 00000000..8ba7ba6e --- /dev/null +++ b/src/kernel/cmx/escc.asm @@ -0,0 +1,980 @@ +; escc.asm +; Interrupt driven serial driver for built in Z180 ports (Hytech CMX) + +; ----------------------------------------------------------------------------- + +$ io64180.inc + + extern _sdevs + extern _K_OS_Intrp_Entry + extern _K_OS_Intrp_Exit + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern abyte + +XMIT_SIZE equ 256 ; must match cxfuncs.h, size of transmitter buffer +RECV_SIZE equ 256 ; must match cxfuncs.h, size of reciever buffer + +; must match cxfuncs.h, fields in SDEV structure: ** ASSUMES 3 BYTE CODE PTRS! +sxmit equ 0 ; offset of embedded CMX XMIT structure +srecv equ 13 ; offset of embedded CMX RECV structure +sport equ 13+13 +stxvec equ 13+13+1 ; called by interrupt, returns l=chr +srxvec equ 13+13+4 ; called by interrupt, passed c=chr +smsvec equ 13+13+7 ; called by interrupt, passed c=bits +sesvec equ 13+13+10 ; called by interrupt, passed c=bits +stevec equ 13+13+13 ; vector to start asci/escc transmitter +stdvec equ 13+13+16 ; vector to stop asci/escc transmitter +sstat equ 13+13+19 ; address to read status (8530 02xxh) +stxdr equ 13+13+20 ; address to write tx data (8530 02xxh) +srxdr equ 13+13+21 ; address to read rx data (8530 02xxh) +swr1 equ 13+13+22 ; wr1 contents (interrupt enable bits) +swr5 equ 13+13+23 ; wr5 contents (modem control outputs) +swr15 equ 13+13+24 ; wr15 contents (modem control int ena) +sinint equ 13+13+25 ; says whether wr1 really reflects wr1! +sdvlen equ 13+13+26 ; byte size of block per serial port + +; ----------------------------------------------------------------------------- + + rseg CODE + + public _escc0_setup + +_escc0_setup:: + push bc + push de + + ld iy,_sdevs+2*sdvlen + ld (iy+sstat),.low.AC8530 + ld (iy+stxdr),.low.AD8530 + ld (iy+srxdr),.low.AD8530 + ld (iy+stevec),.low._escc_tx_enable + ld (iy+stevec+1),.high._escc_tx_enable + ld (iy+stevec+2),BYTE3 _escc_tx_enable + + ld bc,AC8530 + di ; so int doesn't corrupt address reg + in (c) ;f,(c) ; reset pointer bits + + ld d,9 + out (c),d ; address WR9 + ld a,00000010b + out (c),a ; mie off, status lo, no vector + + nop ; ld d,9 + out (c),d ; address WR9 + ld a,10000010b + out (c),a ; channel reset A, status lo, no vector + + ; allow at least 4 clock cycles for reset + + ld d,5 + out (c),d ; address WR5 + ld a,11101010b + out (c),a ; dtr on, 8 data, tx enable, rts on + ld (iy+swr5),a ; set up shadow for swr5sb, swr5rb + + ld d,2 + out (c),d ; address WR2 + sub a + out (c),a ; redundantly set up interrupt vector + + ld d,4 + out (c),d ; address WR4 + ld a,01000100b ; *16 with 1 stop bit, no parity + out (c),a + + ld d,3 + out (c),d ; address WR3 + ld a,11000001b + out (c),a ; 8 data, auto disable, rx enable + + ld d,15 + out (c),d ; address WR15 + sub a + out (c),a ; modem status interrupts disabled + ld (iy+swr15),a ; set up shadow for swr15s, swr15r + + dec d ; ld d,14 + out (c),d ; address WR14 + sub a + out (c),a ; disable baud rate generator + + ld d,12 + out (c),d ; address WR12 + ld a,6 ; 6=57600 4=76800 2=115200 + out (c),a ; divisor 0002h indicates 115200 bps + inc d ; ld d,13 + out (c),d ; address WR13 + sub a + out (c),a ; divisor 0002h indicates 115200 bps + inc d ; ld d,14 + out (c),d ; address WR14 + ld a,00000010b + out (c),a ; set pclk input + nop ; ld d,14 + out (c),d ; address WR14 + or 1 + out (c),a ; enable baud rate generator + ld d,11 + out (c),d ; address WR11 + ld a,01010010b ; use baud rate generator + out (c),a + + ld d,1 + out (c),d ; address WR1 + ld a,00010001b + out (c),a ; rx int on all, no tx int, ext int + ld (iy+swr1),a ; set up shadow for swr1sb, swr1rb + + ld a,00010000b ; reset ext status ints + out (c),a + + ld d,9 + out (c),d ; address WR9 + ld a,00001010b ; mie on, status lo, no vector + out (c),a + +; not yet... this will be done by the escc1 setup routine when both ports ok +; in0 a,(ITC) +; or INT2SW +; out0 (ITC),a + + ei + + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + + public _escc1_setup + +_escc1_setup:: + push bc + push de + + ld iy,_sdevs+3*sdvlen + ld (iy+sstat),.low.BC8530 + ld (iy+stxdr),.low.BD8530 + ld (iy+srxdr),.low.BD8530 + ld (iy+stevec),.low._escc_tx_enable + ld (iy+stevec+1),.high._escc_tx_enable + ld (iy+stevec+2),BYTE3 _escc_tx_enable + + ld bc,BC8530 + di ; so int doesn't corrupt address reg + in (c) ;f,(c) ; reset pointer bits + + ld d,9 + out (c),d ; address WR9 + ld a,00000010b + out (c),a ; mie off, status lo, no vector + + nop ; ld d,9 + out (c),d ; address WR9 + ld a,01000010b + out (c),a ; channel reset B, status lo, no vector + + ; allow at least 4 clock cycles for reset + + ld d,5 + out (c),d ; address WR5 + ld a,11101010b + out (c),a ; dtr on, 8 data, tx enable, rts on + ld (iy+swr5),a ; set up shadow for swr5sb, swr5rb + + ld d,2 + out (c),d ; address WR2 + sub a + out (c),a ; redundantly set up interrupt vector + + ld d,4 + out (c),d ; address WR4 + ld a,01000100b ; *16 with 1 stop bit, no parity + out (c),a + + ld d,3 + out (c),d ; address WR3 + ld a,11000001b + out (c),a ; 8 data, auto disable, rx enable + + ld d,15 + out (c),d ; address WR15 + sub a + out (c),a ; modem status interrupts disabled + ld (iy+swr15),a ; set up shadow for swr15s, swr15r + + dec d ; ld d,14 + out (c),d ; address WR14 + sub a + out (c),a ; disable baud rate generator + + ld d,12 + out (c),d ; address WR12 + ld a,6 ; 6=57600 4=76800 2=115200 + out (c),a ; divisor 0002h indicates 115200 bps + inc d ; ld d,13 + out (c),d ; address WR13 + sub a + out (c),a ; divisor 0002h indicates 115200 bps + inc d ; ld d,14 + out (c),d ; address WR14 + ld a,00000010b + out (c),a ; set pclk input + nop ; ld d,14 + out (c),d ; address WR14 + inc a ; or 1 + out (c),a ; enable baud rate generator + ld d,11 + out (c),d ; address WR11 + ld a,01010010b ; use baud rate generator + out (c),a + + ld d,1 + out (c),d ; address WR1 + ld a,00010001b + out (c),a ; rx int on all, no tx int, ext int + ld (iy+swr1),a ; set up shadow for swr1sb, swr1rb + +; this is only done for S3DEV, and is intended to disconnect LAN optocoupler + ld d,5 + out (c),d ; address WR5 + ld a,11101000b + out (c),a ; dtr on, 8 data, tx enable, rts off + ld (iy+swr5),a ; update our knowledge of wr5 contents + + ld a,00010000b ; reset ext status ints + out (c),a + + ld d,9 + out (c),d ; address WR9 + ld a,00001010b ; mie on, status lo, no vector + out (c),a + + in0 a,(ITC) + or INT2SW + out0 (ITC),a + + ei + + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + public _escc_tx_enable + +_escc_tx_enable:: + push bc + push de + +; ld iy,_sdevs+0*sdvlen + push de + pop iy + di + .if 1 + ld hl,LWRD swr1te + ld a,BYTE3 swr1te + call ?BANK_CALL_DIRECT_L08 + .else + call swr1te + .endif + ei + + pop de + pop bc +; ret + jp ?BANK_FAST_LEAVE_L08 + + public _escc_tx_disable + +_escc_tx_disable:: + push bc + push de + +; ld iy,_sdevs+0*sdvlen + push de + pop iy + di + .if 1 + ld hl,LWRD swr1td + ld a,BYTE3 swr1td + call ?BANK_CALL_DIRECT_L08 + .else + call swr1td + .endif + ei + + pop de + pop bc +; ret + jp ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + rseg RCODE + + public _int2_vector + +_int2_vector:: + .if 1 + ;ld a,'.' + ;out0 (TDR1),a + call _K_OS_Intrp_Entry + .else + push af + push bc + push de + push hl + push iy + .endif + + .if 1 + ld bc,AC8530 + in (c) ;f,(c) ; reset pointer bits + + ld d,9 + out (c),d ; address WR9 + ld a,00000010b + out (c),a ; mie off, status lo, no vector + ei ; allow other interrupts to occur + .endif + + .if 1 + .if 1 ; prevent overrun by polling the ports after each interrupt + ld hl,LWRD si23iv + ld a,BYTE3 si23iv + call ?BANK_CALL_DIRECT_L08 + + ; routine to allow arbitrary tests for rx char (prevents overrun) + ld bc,AC8530 ; enter with interrupts disabled!! + in a,(c) ; read rr0 (channel a = s2dev) + rra ; test bit 0 = rx char available + + ld hl,LWRD si2rx + ld a,BYTE3 si2rx + call c,?BANK_CALL_DIRECT_L08 ; something ready, use the normal si2rx + ; (this clobbers bc if char received) + ld bc,BC8530 + in a,(c) ; read rr0 + rra ; test bit 0 = rx char available + + ld hl,LWRD si3rx + ld a,BYTE3 si3rx + call c,?BANK_CALL_DIRECT_L08 ; something ready, use the normal si2rx + ; (this clobbers bc if char received) + .else + ld hl,LWRD si23 + ld a,BYTE3 si23 + call ?BANK_CALL_DIRECT_L08 + .endif + .else + call si23 + .endif + + .if 1 + ld bc,AC8530 + di ; prevent ints occurring immediately + in (c) ;f,(c) ; reset pointer bits + + ld d,9 + out (c),d ; address WR9 + ld a,00001010b + out (c),a ; mie on, status lo, no vector + .endif + + .if 1 + call _K_OS_Intrp_Exit + .else + pop iy + pop hl + pop de + pop bc + pop af + ei + ret + .endif + +; ----------------------------------------------------------------------------- + + rseg CODE + + .if 0 ; 17sep02 routine to allow arbitrary tests for rx char (prevents overrun) + .if 1 ; 17sep02 enhancement for extra safety against overruns (esp. @ 6.144 mhz) +public si23 + +si23: + .if 1 + ld hl,LWRD si23iv + ld a,BYTE3 si23iv + call ?BANK_CALL_DIRECT_L08 + .else + call LWRD si23iv ; first process interrupt via vector + .endif + ; fall into si23rx routine (it could also be useful during other ints!) + .endif + +public si23rx + +si23rx: ; routine to allow arbitrary tests for rx char (prevents overrun) + ld bc,AC8530 ; enter with interrupts disabled!! + in a,(c) ; read rr0 (channel a = s2dev) + rra ; test bit 0 = rx char available + .if 1 + ld hl,LWRD si2rx + ld a,BYTE3 si2rx + call c,?BANK_CALL_DIRECT_L08 ; something ready, use the normal si2rx + .else + call c,LWRD si2rx ; something ready, use the normal si2rx + .endif + ; (this clobbers bc if char received) + ld bc,BC8530 + in a,(c) ; read rr0 + rra ; test bit 0 = rx char available + .if 1 + jp nc,?BANK_FAST_LEAVE_L08 ; nothing ready, no-op (ints disabled) + .else + ret nc ; nothing ready, no-op (ints disabled) + .endif + ; fall into the same si3rx routine as used by the interrupt system + jp LWRD si3rx + .endif + + .if 0 +silly: ; enter with special receive condition status byte in e + ld a,e + rrca + rrca + rrca + rrca + and 7 + add a,'0' + rst 18h ;call abyte + ret + .endif + + .if 0 +sillyx: ; enter with modem control input status byte in e + ld a,e + and 28h + rrca ; 14h + rrca ; 0ah + rrca ; 05h + add a,'0' + rst 18h ;call abyte + ret + .endif + +si3tx: + .if 1 + ld iy,_sdevs+3*sdvlen + .endif + + .if 1 + ld de,_sdevs+3*sdvlen ; de = 1st parameter (word16) + + ld hl,(_sdevs+3*sdvlen+stxvec) + ld a,(_sdevs+3*sdvlen+stxvec+2) + call ?BANK_CALL_DIRECT_L08 + + inc h ; hl = 0ffffh indicates no char for tx + jp z,LWRD swr1td + + ; client has provided character for tx, send it + ld bc,BD8530 + out (c),l ; send char on behalf of client + .else + ld bc,(_sdevs+3*sdvlen+stxvec) + call 0eb53h ; winved + di ;;!! 24may02 for no good reason + jp c,swr1td ;jr c,si3td + + ; client has provided character for tx, send it + ld bc,BD8530 + out (c),e ; send char on behalf of client + .endif + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret ;jr si23 ; check for further interrupts pending + .endif + +;si3td: call swr1td ; serial write register 1 tx disable +; ret ;jr si23 ; check for further interrupts pending + + .if 1 ; 16dec01 so that swint can be a regular modem status handler +si3ms: + .if 0 + ld iy,_sdevs+3*sdvlen + .endif + in e,(c) ; read modem status inputs for client + + .if 0 + call sillyx + .endif + + ld a,00010000b ; reset ext status interrupts + out (c),a + + .if 1 + ld c,e ; c = 2nd parameter (byte) + ld de,_sdevs+3*sdvlen ; de = 1st parameter (word16) + + ld hl,(_sdevs+3*sdvlen+smsvec) + ld a,(_sdevs+3*sdvlen+smsvec+2) + .if 1 + jp LWRD ?BANK_JMP_DIRECT_L08 + .else + jp ?BANK_CALL_DIRECT_L08 + .endif + .else + ld bc,(_sdevs+3*sdvlen+smsvec) +; call 0eb53h ; winved, ignore the cf return for now +; ret ;jr si23 ; check for further interrupts pending + jp 0eb53h ; winved, ignore the cf return for now + .endif + .else +si3ms: ; bc is already set up to read channel b modem status +; call swint +; ret ;jr si23 ; check for further interrupts pending + jp swint + .endif + +si3rx: + .if 0 + ld iy,_sdevs+3*sdvlen + .endif + + ld c,low BD8530 + .if 1 + in c,(c) ; c = 2nd parameter (byte) + ld de,_sdevs+3*sdvlen ; de = 1st parameter (word16) + + ld hl,(_sdevs+3*sdvlen+srxvec) + ld a,(_sdevs+3*sdvlen+srxvec+2) + .if 1 + jp LWRD ?BANK_JMP_DIRECT_L08 + .else + jp ?BANK_CALL_DIRECT_L08 + .endif + .else + in e,(c) ; read character for client + + ld bc,(_sdevs+3*sdvlen+srxvec) +; call 0eb53h ; winved, ignore the cf return for now +; ret ;jr si23 ; check for further interrupts pending + jp 0eb53h ; winved, ignore the cf return for now + .endif + +si3es: dec d ; ld d,1 + out (c),d ; select rr1 + .if 0 + ld iy,_sdevs+3*sdvlen + .else + nop + .endif + in e,(c) ; read special receive condition status + + .if 0 + call silly + .endif + + .if 0 ; 16dec01 when nothing pending, go to clkint via s3dev error status + .if 1 ; 16oct02 make sure we don't depend on ckimsr when the hardware is new + ld a,(hwtype) + or a + jr nz,skpclk + .endif + ld a,e + and 01110000b ; bit 6=framing, 5=overrun, 4=parity + ;jp z,int2c ; in ser.mac for no good reason + jr z,int2c ; 14jun02 now here, & proper ret logic + .if 1 ; 16oct02 make sure we don't depend on ckimsr when the hardware is new +skpclk: + .endif + .endif + + .if 0 + ld a,'%' + rst 18h ;call abyte + .endif + + ld a,00110000b ; error reset + out (c),a + + .if 1 + ld c,e ; c = 2nd parameter (byte) + ld de,_sdevs+3*sdvlen ; de = 1st parameter (word16) + + ld hl,(_sdevs+3*sdvlen+sesvec) + ld a,(_sdevs+3*sdvlen+sesvec+2) + .if 1 + jp LWRD ?BANK_JMP_DIRECT_L08 + .else + jp ?BANK_CALL_DIRECT_L08 + .endif + .else + ld bc,(_sdevs+3*sdvlen+sesvec) +; call 0eb53h ; winved, ignore the cf return for now +; ret ;jr si23 ; check for further interrupts pending + jp 0eb53h ; winved, ignore the cf return for now + .endif + + .if 0 ; 14jun02 this is now moved to ser.inc as it was misleading +int2c: + .if noints + ld bc,ckimsr + in a,(c) ; reset irq + ret ;jr si23 + .else + wjpd clkint ; clock is interrupting + ; clkint should be modified, + ; as it no longer needs to preserve de/hl/iy + .endif + .endif + +; ----------------------------------------------------------------------------- + + .if 1 ; 17sep02 enhancement for extra safety against overruns (esp. 6.144 MHz) +si23iv: ; routine to perform interrupt vectoring... not the main int. handler! + .else +public si23 + +si23: ; without the enhancement, this routine is also the main int. handler! + .endif + .if 0 ; 20may02 hope this works (it does, but see below) + ld a,'.' + call abyte + .endif + ld bc,BC8530 + ld d,2 + out (c),d ; select rr2 + ld hl,LWRD si23jt-200h ; we'll also rely on d=2 later + in e,(c) ; read interrupt vector with status + .if 0;xyz1 ; 15dec01 diagnostic interrupt vector output, requires abfast + ld a,e + rrca + add a,10h + ;bit 1,e ; 0 indicates tx/rx int, 1 indicates modem/error int + ;call nz,abyte + out0 (TDR1),a + .endif + add hl,de + jp (hl) + +si23jt: jr si3tx + jr si3ms + jr si3rx + jr si3es + jr si2tx + jr si2ms + jr si2rx + jr si2es + +; ----------------------------------------------------------------------------- + +si2tx: + .if 1 + ld iy,_sdevs+2*sdvlen + .endif + + .if 1 + ld de,_sdevs+2*sdvlen ; de = 1st parameter (word16) + + ld hl,(_sdevs+2*sdvlen+stxvec) + ld a,(_sdevs+2*sdvlen+stxvec+2) + call ?BANK_CALL_DIRECT_L08 + + inc h ; hl = 0ffffh indicates no char for tx + jp z,LWRD swr1td + + ; client has provided character for tx, send it + ld bc,AD8530 + out (c),l ; send char on behalf of client + .else + ld bc,(_sdevs+2*sdvlen+stxvec) + call 0eb53h ; winved + di ;;!! 24may02 for no good reason + jp c,swr1td ;jr c,si2td + + ; client has provided character for tx, send it + ld bc,AD8530 + out (c),e ; send char on behalf of client + .endif +; ld a,e +; jp abyte + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret ;jr si23 ; check for further interrupts pending + .endif + +;si2td: call swr1td ; serial write register 1 tx disable +; ret ;jr si23 ; check for further interrupts pending + +si2ms: + .if 0 + ld iy,_sdevs+2*sdvlen + .endif + + inc c ; ld c,low AC8530 + in e,(c) ; read modem status inputs for client + + ld a,00010000b ; reset ext status interrupts + out (c),a + + .if 1 + ld c,e ; c = 2nd parameter (byte) + ld de,_sdevs+2*sdvlen ; de = 1st parameter (word16) + + ld hl,(_sdevs+2*sdvlen+smsvec) + ld a,(_sdevs+2*sdvlen+smsvec+2) + .if 1 + jp LWRD ?BANK_JMP_DIRECT_L08 + .else + jp ?BANK_CALL_DIRECT_L08 + .endif + .else + ld bc,(_sdevs+2*sdvlen+smsvec) +; call 0eb53h ; winved, ignore the cf return for now +; ret ;jr si23 ; check for further interrupts pending + jp 0eb53h ; winved, ignore the cf return for now + .endif + +si2rx: + .if 0 + ld iy,_sdevs+2*sdvlen + .endif + + ld c,low AD8530 + .if 1 + in c,(c) ; c = 2nd parameter (byte) + ld de,_sdevs+2*sdvlen ; de = 1st parameter (word16) + + ld hl,(_sdevs+2*sdvlen+srxvec) + ld a,(_sdevs+2*sdvlen+srxvec+2) + .if 1 + jp LWRD ?BANK_JMP_DIRECT_L08 + .else + jp ?BANK_CALL_DIRECT_L08 + .endif + .else + in e,(c) ; read character for client + + ld bc,(_sdevs+2*sdvlen+srxvec) +; call 0eb53h ; winved, ignore the cf return for now +; ret ;jr si23 ; check for further interrupts pending + jp 0eb53h ; winved, ignore the cf return for now + .endif + +si2es: inc c ; ld c,low AC8530 + dec d ; ld d,1 + out (c),d ; select rr1 + .if 0 + ld iy,_sdevs+2*sdvlen + .else + nop + .endif + in e,(c) ; read special receive condition status + + ld a,00110000b ; error reset + out (c),a + + .if 1 + ld c,e ; c = 2nd parameter (byte) + ld de,_sdevs+2*sdvlen ; de = 1st parameter (word16) + + ld hl,(_sdevs+2*sdvlen+sesvec) + ld a,(_sdevs+2*sdvlen+sesvec+2) + .if 1 + jp LWRD ?BANK_JMP_DIRECT_L08 + .else + jp ?BANK_CALL_DIRECT_L08 + .endif + .else + ld bc,(_sdevs+2*sdvlen+sesvec) +; call 0eb53h ; winved, ignore the cf return for now +; ret ;jr si23 ; check for further interrupts pending + jp 0eb53h ; winved, ignore the cf return for now + .endif + +; rather silly routine provided to save code space in the handlers above: + +?BANK_JMP_DIRECT_L08: + call ?BANK_CALL_DIRECT_L08 + jp ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- +; utility subroutines for use by our clients - 8530 ports (serial 2/3) + +swr1te: ; serial write register 1 transmit enable - enter with di + ;ld a,(iy+sdev) + ;cp s2dev + ;ld a,'e' + ;call z,abyte + +; ld a,(iy+sdev) +; cp s2dev +; jr nz,twatx +; call twatx +; jp abyte +;twatx: + bit 1,(iy+swr1) +; ld a,'a' + .if 1 + jp nz,?BANK_FAST_LEAVE_L08 ; transmit interrupt already enabled + .else + ret nz ; transmit interrupt already enabled + .endif + + .if 1 + push iy + pop de ; de = 1st parameter (word16) + + ld l,(iy+stxvec) + ld h,(iy+stxvec+1) + ld a,(iy+stxvec+2) + call ?BANK_CALL_DIRECT_L08 + + inc h ; hl = 0ffffh indicates no char for tx +; ld a,'b' + .if 1 + jp z,?BANK_FAST_LEAVE_L08 + .else + ret z + .endif + .else + ld c,(iy+stxvec) + ld b,(iy+stxvec+1) + call 0eb53h ; winved +; ld a,'b' + ret c ; there was really nothing to transmit + ld l,e + .endif + + ld e,2 + .if 1 + push hl ; oops ! + ld hl,LWRD swr1sb + ld a,BYTE3 swr1sb + call ?BANK_CALL_DIRECT_L08 ; explicitly enable transmit interrupt + pop hl ; oops ! + .else + call LWRD swr1sb ; explicitly enable transmit interrupt + .endif + + ld c,(iy+stxdr) + out (c),l ; send char on behalf of client +; ld a,(iy+sdev) +; cp s2dev +; ret nz +; ld a,55h +; call abyte +; ld a,l +; jp abyte +; ld a,'c' + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +swr1sb: ; serial write register 1 set bits - enter with di + ld c,(iy+sstat) + ld b,2 ;(iy+sbase) + ld d,1 + out (c),d + ld a,e + or (iy+swr1) + out (c),a + ld (iy+swr1),a + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +swr1td: ; serial write register 1 transmit disable - enter with di + ;ld a,(iy+sdev) + ;cp s2dev + ;ld a,'d' + ;call z,abyte + ld e,0fdh +swr1rb: ; serial write register 1 reset bits - enter with di + ld c,(iy+sstat) + ld b,2 ;(iy+sbase) + ld d,1 + out (c),d + ld a,e + and (iy+swr1) + out (c),a + ld (iy+swr1),a + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +swr5sb: ; serial write register 5 set bits - enter with di + ld c,(iy+sstat) + ld b,2 ;(iy+sbase) + ld d,5 + out (c),d + ld a,e + or (iy+swr5) + out (c),a + ld (iy+swr5),a + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +swr5rb: ; serial write register 5 reset bits - enter with di + ld c,(iy+sstat) + ld b,2 ;(iy+sbase) + ld d,5 + out (c),d + ld a,e + and (iy+swr5) + out (c),a + ld (iy+swr5),a + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +swr15s: ; serial write register 15 set bits - enter with di + ld c,(iy+sstat) + ld b,2 ;(iy+sbase) + ld d,15 + out (c),d + ld a,e + or (iy+swr15) + out (c),a + ld (iy+swr15),a + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +swr15r: ; serial write register 15 reset bits - enter with di + ld c,(iy+sstat) + ld b,2 ;(iy+sbase) + ld d,15 + out (c),d + ld a,e + and (iy+swr15) + out (c),a + ld (iy+swr15),a + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +; ----------------------------------------------------------------------------- + + END diff --git a/src/kernel/cmx/io64180.h b/src/kernel/cmx/io64180.h new file mode 100755 index 00000000..9414e0b7 --- /dev/null +++ b/src/kernel/cmx/io64180.h @@ -0,0 +1,134 @@ +/* - 64180.inc - + + This files defines the internal register addresses + for HD64180 + + File version: $Revision: 1.4 $ + +*/ + +#pragma language=extended + +/* ==================================== */ +/* */ +/* ASCI Channel Control Registers */ +/* */ +/* ==================================== */ + +sfr CNTLA0 = 0x00; /* ASCI Ctrl Reg A, Ch 0 */ +sfr CNTLA1 = 0x01; /* ASCI Ctrl Reg A, Ch 1 */ +sfr CNTLB0 = 0x02; /* ASCI Ctrl Reg B, Ch 0 */ +sfr CNTLB1 = 0x03; /* ASCI Ctrl Reg B, Ch 1 */ +/*------------------------------------------------------------------------- */ +sfr STAT0 = 0x04; /* ASCI Status Reg, Ch 0 */ +sfr STAT1 = 0x05; /* ASCI Status Reg, Ch 1 */ +/*------------------------------------------------------------------------- */ +sfr TDR0 = 0x06; /* ASCI Transmit Data Reg, Ch 0 */ +sfr TDR1 = 0x07; /* ASCI Transmit Data Reg, Ch 1 */ +sfr RDR0 = 0x08; /* ASCI Receive Data Reg, Ch 0 */ +sfr RDR1 = 0x09; /* ASCI Receive Data Reg, Ch 1 */ + +/* ==================================== */ +/* */ +/* CSI/O Registers */ +/* */ +/* ==================================== */ + +sfr CNTR = 0x0A; /* CSI/O Ctrl Reg */ +sfr TRDR = 0x0B; /* CSI/O Trans/Rec Data Reg */ + +/* ==================================== */ +/* */ +/* Timer Registers */ +/* */ +/* ==================================== */ + +sfr TMDR0L = 0x0C; /* Timer 0 Data Reg L */ +sfr TMDR0H = 0x0D; /* Timer 0 Data Reg H */ +sfr TMDR1L = 0x014; /* Timer 1 Data Reg L */ +sfr TMDR1H = 0x015; /* Timer 1 Data Reg H */ +/*------------------------------------------------------------------------- */ +sfr RLDR0L = 0x0E; /* Timer 0 Reload Reg L */ +sfr RLDR0H = 0x0F; /* Timer 0 Reload Reg H */ +sfr RLDR1L = 0x016; /* Timer 1 Reload Reg L */ +sfr RLDR1H = 0x017; /* Timer 1 Reload Reg H */ +/*------------------------------------------------------------------------- */ +sfr TCR = 0x010; /* Timer Ctrl Reg */ + +/* ==================================== */ +/* */ +/* Free Running Counter */ +/* */ +/* ==================================== */ + +sfr FRC = 0x018; /* Free Running Counter */ + +/* ==================================== */ +/* */ +/* DMA Registers */ +/* */ +/* ==================================== */ + +sfr SAR0L = 0x020; /* DMA 0 Source Addr Reg */ +sfr SAR0H = 0x021; /* DMA 0 Source Addr Reg */ +sfr SAR0B = 0x022; /* DMA 0 Source Addr Reg */ +/*------------------------------------------------------------------------- */ +sfr DAR0L = 0x023; /* DMA 0 Destination Addr Reg */ +sfr DAR0H = 0x024; /* DMA 0 Destination Addr Reg */ +sfr DAR0B = 0x025; /* DMA 0 Destination Addr Reg */ +/*------------------------------------------------------------------------- */ +sfr BCR0L = 0x026; /* DMA 0 Counter Reg */ +sfr BCR0H = 0x027; /* DMA 0 Counter Reg */ +/*------------------------------------------------------------------------- */ +sfr MAR1L = 0x028; /* DMA 1 Memory Addr Reg */ +sfr MAR1H = 0x029; /* DMA 1 Memory Addr Reg */ +sfr MAR1B = 0x02A; /* DMA 1 Memory Addr Reg */ +/*------------------------------------------------------------------------- */ +sfr IAR1L = 0x02B; /* DMA I/O Addr Reg */ +sfr IAR1H = 0x02C; /* DMA I/O Addr Reg */ +/*------------------------------------------------------------------------- */ +sfr BCR1L = 0x02E; /* DMA 1 Byte Count Reg */ +sfr BCR1H = 0x02F; /* DMA 1 Byte Count Reg */ +/*------------------------------------------------------------------------- */ +sfr DSTAT = 0x030; /* DMA Status Reg */ +sfr DMODE = 0x031; /* DMA Mode Reg */ +sfr DCNTL = 0x032; /* DMA/WAIT Ctrl Reg */ + +/* ==================================== */ +/* */ +/* MMU Registers */ +/* */ +/* ==================================== */ + +sfr CBR_location = 0x038; /* MMU Common Base Reg */ +sfr BBR_location = 0x039; /* MMU Bank Base Reg */ +sfr CBAR_location = 0x03A; /* MMU Bank/Common Area Reg */ +#define CBR CBR_location +#define BBR BBR_location +#define CBAR CBAR_location + + +/* ==================================== */ +/* */ +/* Interrupt Registers */ +/* */ +/* ==================================== */ + +sfr IL = 0x033; /* Int Vect Low Reg */ +sfr ITC = 0x034; /* Int/Trap Ctrl Reg */ + +/* ==================================== */ +/* */ +/* Refresh Registers */ +/* */ +/* ==================================== */ + +sfr RCR = 0x036; /* Refresh Ctrl Reg */ + +/* ==================================== */ +/* */ +/* I/O Registers */ +/* */ +/* ==================================== */ + +sfr ICR = 0x03F; /* I/O Ctrl Reg */ diff --git a/src/kernel/cmx/io64180.inc b/src/kernel/cmx/io64180.inc new file mode 100755 index 00000000..01380ae1 --- /dev/null +++ b/src/kernel/cmx/io64180.inc @@ -0,0 +1,155 @@ +; /* - 64180.inc - +; +; This files defines the internal register addresses +; for HD64180 +; +; File version: $Revision: 1.4 $ +; +; */ +; +; /* ================================== */ +; /* */ +; /* ASCI Channel Control Registers */ +; /* */ +; /* ================================== */ + +CNTLA0 = 0x00; /* ASCI Ctrl Reg A, Ch 0 */ +CNTLA1 = 0x01; /* ASCI Ctrl Reg A, Ch 1 */ +CNTLB0 = 0x02; /* ASCI Ctrl Reg B, Ch 0 */ +CNTLB1 = 0x03; /* ASCI Ctrl Reg B, Ch 1 */ +; ----------------------------------------------------------------------------- +STAT0 = 0x04; /* ASCI Status Reg, Ch 0 */ +STAT1 = 0x05; /* ASCI Status Reg, Ch 1 */ +; ----------------------------------------------------------------------------- +TDR0 = 0x06; /* ASCI Transmit Data Reg, Ch 0 */ +TDR1 = 0x07; /* ASCI Transmit Data Reg, Ch 1 */ +RDR0 = 0x08; /* ASCI Receive Data Reg, Ch 0 */ +RDR1 = 0x09; /* ASCI Receive Data Reg, Ch 1 */ + +; /* ================================== */ +; /* */ +; /* CSI/O Registers */ +; /* */ +; /* ================================== */ + +CNTR = 0x0A; /* CSI/O Ctrl Reg */ +TRDR = 0x0B; /* CSI/O Trans/Rec Data Reg */ + +; /* ================================== */ +; /* */ +; /* Timer Registers */ +; /* */ +; /* ================================== */ + +TMDR0L = 0x0C; /* Timer 0 Data Reg L */ +TMDR0H = 0x0D; /* Timer 0 Data Reg H */ +TMDR1L = 0x14; /* Timer 1 Data Reg L */ +TMDR1H = 0x15; /* Timer 1 Data Reg H */ +; ----------------------------------------------------------------------------- +RLDR0L = 0x0E; /* Timer 0 Reload Reg L */ +RLDR0H = 0x0F; /* Timer 0 Reload Reg H */ +RLDR1L = 0x16; /* Timer 1 Reload Reg L */ +RLDR1H = 0x17; /* Timer 1 Reload Reg H */ +; ----------------------------------------------------------------------------- +TCR = 0x10; /* Timer Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* Free Running Counter */ +; /* */ +; /* ================================== */ + +FRC = 0x18; /* Free Running Counter */ + +; /* ================================== */ +; /* */ +; /* DMA Registers */ +; /* */ +; /* ================================== */ + +SAR0L = 0x20; /* DMA 0 Source Addr Reg */ +SAR0H = 0x21; /* DMA 0 Source Addr Reg */ +SAR0B = 0x22; /* DMA 0 Source Addr Reg */ +; ----------------------------------------------------------------------------- +DAR0L = 0x23; /* DMA 0 Destination Addr Reg */ +DAR0H = 0x24; /* DMA 0 Destination Addr Reg */ +DAR0B = 0x25; /* DMA 0 Destination Addr Reg */ +; ----------------------------------------------------------------------------- +BCR0L = 0x26; /* DMA 0 Counter Reg */ +BCR0H = 0x27; /* DMA 0 Counter Reg */ +; ----------------------------------------------------------------------------- +MAR1L = 0x28; /* DMA 1 Memory Addr Reg */ +MAR1H = 0x29; /* DMA 1 Memory Addr Reg */ +MAR1B = 0x2A; /* DMA 1 Memory Addr Reg */ +; ----------------------------------------------------------------------------- +IAR1L = 0x2B; /* DMA I/O Addr Reg */ +IAR1H = 0x2C; /* DMA I/O Addr Reg */ +; ----------------------------------------------------------------------------- +BCR1L = 0x2E; /* DMA 1 Byte Count Reg */ +BCR1H = 0x2F; /* DMA 1 Byte Count Reg */ +; ----------------------------------------------------------------------------- +DSTAT = 0x30; /* DMA Status Reg */ +DMODE = 0x31; /* DMA Mode Reg */ +DCNTL = 0x32; /* DMA/WAIT Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* MMU Registers */ +; /* */ +; /* ================================== */ + +CBR = 0x38; /* MMU Common Base Reg */ +BBR = 0x39; /* MMU Bank Base Reg */ +CBAR = 0x3A; /* MMU Bank/Common Area Reg */ +; CBR_location = 0x38; /* MMU Common Base Reg */ +; BBR_location = 0x39; /* MMU Bank Base Reg */ +; CBAR_location = 0x3A; /* MMU Bank/Common Area Reg */ +; #define CBR CBR_location +; #define BBR BBR_location +; #define CBAR CBAR_location + +; /* ================================== */ +; /* */ +; /* Interrupt Registers */ +; /* */ +; /* ================================== */ + +IL = 0x33; /* Int Vect Low Reg */ +ITC = 0x34; /* Int/Trap Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* Refresh Registers */ +; /* */ +; /* ================================== */ + +RCR = 0x36; /* Refresh Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* I/O Registers */ +; /* */ +; /* ================================== */ + +ICR = 0x3F; /* I/O Ctrl Reg */ + +; /* ================================== */ +; /* */ +; /* Bit Definitions */ +; /* */ +; /* ================================== */ + +INT0SW = 0x01; /* interrupt enable bits in ITC */ +INT1SW = 0x02; /* interrupt enable bits in ITC */ +INT2SW = 0x04; /* interrupt enable bits in ITC */ + +; ----------------------------------------------------------------------------- +; Hytech specific hardware: (For the WPO30-V5, Hytech 1000, Hytech 1500) + +BC8530 = 0x214; /* channel B control in 8530 */ +AC8530 = 0x215; /* channel A control in 8530 */ +BD8530 = 0x216; /* channel B data in 8530 */ +AD8530 = 0x217; /* channel A data in 8530 */ + +; ----------------------------------------------------------------------------- + diff --git a/src/kernel/kernel.lnk b/src/kernel/kernel.lnk new file mode 100755 index 00000000..7a7a699f --- /dev/null +++ b/src/kernel/kernel.lnk @@ -0,0 +1,53 @@ +-k ..\..\..\lib +-l libiar.lib +-m +-u +-i +-o kernel +-bl RCODE=0 +-bl ICODE=0x8100 +-bl CODE=0x804000,0x10000 +-bc CODE=0x4000 +c0k +cmx_init +cxver5 +cmxio3 +cxskv5b +cmxintb +asci +escc +apibus +copyr +diag +main +data +machasm +machdep +filesys +process +procasm +scall1 +scall2 +scall3 +devtty +devio +devhd +devmisc +devflop +flopasm +utils +systrace +xip +kprintf +vfprintf +itoa +ltoa +ultoa +strlen +strcat +strcpy +strncmp +memcpy +abort +exit +_exit diff --git a/src/kernel/libc/_exit.asm b/src/kernel/libc/_exit.asm new file mode 100755 index 00000000..d92ede3b --- /dev/null +++ b/src/kernel/libc/_exit.asm @@ -0,0 +1,69 @@ +; _exit.asm for UZI180 by Nick + +; ----------------------------------------------------------------------------- + + module _exit + + public _exit + + extern _abflag + extern abyte, ahexw, amess, acrlf + +$ io64180.inc + + extern _sdevs + +; must match cxfuncs.h, fields in SDEV structure: ** ASSUMES 3 BYTE CODE PTRS! +sxmit equ 0 ; offset of embedded CMX XMIT structure +srecv equ 13 ; offset of embedded CMX RECV structure +sport equ 13+13 +stxvec equ 13+13+1 ; called by interrupt, returns l=chr +srxvec equ 13+13+4 ; called by interrupt, passed c=chr +smsvec equ 13+13+7 ; called by interrupt, passed c=bits +sesvec equ 13+13+10 ; called by interrupt, passed c=bits +stevec equ 13+13+13 ; vector to start asci/escc transmitter +stdvec equ 13+13+16 ; vector to stop asci/escc transmitter +sstat equ 13+13+19 ; address to read status (8530 02xxh) +stxdr equ 13+13+20 ; address to write tx data (8530 02xxh) +srxdr equ 13+13+21 ; address to read rx data (8530 02xxh) +swr1 equ 13+13+22 ; wr1 contents (interrupt enable bits) +swr5 equ 13+13+23 ; wr5 contents (modem control outputs) +swr15 equ 13+13+24 ; wr15 contents (modem control int ena) +sinint equ 13+13+25 ; says whether wr1 really reflects wr1! +sdvlen equ 13+13+26 ; byte size of block per serial port + +; ----------------------------------------------------------------------------- + + rseg CODE + +_exit:: + .if 1 + ld hl,(_sdevs+1*sdvlen+sxmit+4) ; bytes_out + ld a,l + or h + jr nz,_exit ; wait for outgoing traffic to be sent + .endif + + call amess + defb 'kernel: rebooting: exitcode ',0 + ex de,hl + call ahexw + call acrlf + + ld hl,0 + ; wait for last character to be sent @ 9600 +reboot_delay: + dec hl + ld a,l + or h + jr nz,reboot_delay + + ld a,0aah + ld (_abflag),a + + ei + jr $ ; loop forever + +; ----------------------------------------------------------------------------- + + end diff --git a/src/kernel/libc/abort.c b/src/kernel/libc/abort.c new file mode 100755 index 00000000..d8cfe504 --- /dev/null +++ b/src/kernel/libc/abort.c @@ -0,0 +1,27 @@ +/* abort.c by Nick for UZI180 kernel */ + +#if 1 /* Nick, not sure what the other stuff is about */ +void exit(int val); /* #include */ /* for exit() prototype */ + +void abort(int val) + { + exit(val); + } +#else +/* + */ +#include +#include +#include +#include + +void abort(void) { + signal(SIGABRT, SIG_DFL); + kill(SIGABRT, getpid()); /* Correct one */ + pause(); /* System may just schedule */ + signal(SIGKILL, SIG_DFL); + kill(SIGKILL, getpid()); /* Can't trap this! */ + _exit(255); /* WHAT!! */ +} +#endif + diff --git a/src/kernel/libc/c0k.asm b/src/kernel/libc/c0k.asm new file mode 100755 index 00000000..a1ccb80b --- /dev/null +++ b/src/kernel/libc/c0k.asm @@ -0,0 +1,240 @@ +; c0k.asm by Nick for UZI180 banked memory model (creates a kernel executable) + +; ----------------------------------------------------------------------------- + + .if 1 +$ io64180.inc + .endif + + module _c0k + + public init ; vendor _init + extern _main + extern exit ; vendor _exit + .if 1 + extern abyte + .endif + extern copyr + + extern e_RCODE ; e_hsize + extern s_ICODE ; e_idata + extern s_UDATA0 ; e_udata + extern s_CSTACK ; e_stack + extern e_CSTACK ; e_break + + extern _int1_vector + extern _int2_vector + extern _timer0_vector + extern _csio_vector + extern _asci0_vector + extern _asci1_vector + + extern ?BANK_CALL_DIRECT_L08 + +E_MAGIC equ 0a6c9h +E_FORMAT_KERNEL equ 3 +E_STACK_SIZE equ 1000h + +; ----------------------------------------------------------------------------- +; forward definitions of segments, to set the linkage order (c0k must be first) + + rseg RCODE + rseg ICODE +; rseg TEMP +; rseg DATA0 +; rseg WCSTR + rseg CONST + rseg CSTR + rseg IDATA0(NUL) + rseg CDATA0 + rseg ECSTR(NUL) + rseg CCSTR + rseg CODE(NUL) ; needs to be at end for banked model + rseg UDATA0 + rseg CSTACK + +; ----------------------------------------------------------------------------- + + rseg _DEFAULT ; means header is discarded at loading + + defw E_MAGIC ; e_magic + defw E_FORMAT_KERNEL ; e_format + defd 12345678h ; e_size + defw e_RCODE+14h ; e_hsize (14h = l__DEFAULT) + defw s_ICODE ; e_idata + defw init ; e_entry + defw s_UDATA0 ; e_udata + defw s_CSTACK ; e_stack + defw e_CSTACK ; e_break + +; ----------------------------------------------------------------------------- + + rseg ICODE + +init:: + .if 0 + ld a,'A' + call abyte + .endif + + .if 1 + ld a,.low.vector_table + out0 (IL),a ; set interrupt vectors low byte + ld a,.high.vector_table + ld i,a ; set interrupt vectors high byte + + in0 a,(CBR) + ld (_os_bank),a ; for the CMX scheduler, and others + + ei ; now got a stack and interrupt vectors + .endif + + .if 1 + ld e,.high._rom_serial_no + ld d,0 + + ld a,(_os_bank) ; CBR value for kernel data segment + ld l,a + ld h,d ;0 + + add hl,hl + add hl,hl + add hl,hl + add hl,hl ; convert to absolute base address + add hl,de ; adjust for dest, carry into segment + + ld e,h ; e = segment no. for copy destination + ld h,l + ld l,.low._rom_serial_no ; e:hl -> copy dest (in kernel data) + + ld iy,0fc81h + ;ld d,0 ; d:iy -> copy source (in EPROM) + + ld bc,5 + call copyr + +; not necessary as this will have been zeroed by seg_init (it's in UDATA0): +; sub a +; ld (_rom_sn+5),a + .endif + + .if 0 + ld a,'B' + call abyte + .endif + +; now there are the next stack structure: +; +4 envp +; +2 argv +; sp-> +0 argc + pop de + ld (_argc),de ; vendor __argc (2nd argument to main) + pop bc + ld (_argv),bc ; vendor __argv (1st argument to main) + pop hl + ld (environ),hl ; vendor _environ + + ld HL,LWRD _main ; banked call to _main() + ld A,BYTE3 _main + call ?BANK_CALL_DIRECT_L08 + + ex de,hl ; de = exitcode (1st argument to exit) + + ld HL,LWRD exit ; banked call to _exit() + ld A,BYTE3 exit + jp ?BANK_CALL_DIRECT_L08 + +; ----------------------------------------------------------------------------- + + rseg RCODE ; c0k must be the first module loaded ! + +common_start:: + jp init+4000h ; +4000h because we're not loaded yet + + org common_start+0x08 + ei + ret + org common_start+0x10 + ei + ret + org common_start+0x18 + ei + ret + org common_start+0x20 + ei + ret + org common_start+0x28 + ei + ret + org common_start+0x30 + ei + ret + org common_start+0x38 + ei + ret + + org common_start+0x40 + + public vector_table + +vector_table:: + defw _int1_vector + defw _int2_vector + defw _timer0_vector + defw _timer1_vector + defw _dma0_vector + defw _dma1_vector + defw _csio_vector + defw _asci0_vector + defw _asci1_vector + + public _timer1_vector + +_timer1_vector:: + + public _dma0_vector + +_dma0_vector:: + + public _dma1_vector + +_dma1_vector:: + ei + ret + +; ----------------------------------------------------------------------------- + + rseg RCODE + +; Nick has added read/write data here (must be in RCODE) + + public _os_bank + +_os_bank: defb 0 ; the CBR value for CMX/UZI data seg + +; Nick has added read/write data here (doesn't need to be in RCODE) + + rseg UDATA0 + + public _rom_serial_no + +_rom_serial_no: defs 6 ; for c:\uzi\kernel\main.c (hostname) + +; ----------------------------------------------------------------------------- + + public _argc, _argv, environ, errno, __cleanup + ;public __argc, __argv, _environ, _errno, ___cleanup + + rseg UDATA0 +_argc: defs 2 ; vendor __argc +_argv: defs 2 ; vendor __argv +environ: defs 2 ; vendor _environ +errno: defs 2 ; vendor _errno +__cleanup: defs 3 ; oopsy 2 ; vendor ___cleanup + + rseg CSTACK + defs E_STACK_SIZE + +; ----------------------------------------------------------------------------- + + END diff --git a/src/kernel/libc/exit.c b/src/kernel/libc/exit.c new file mode 100755 index 00000000..9435599f --- /dev/null +++ b/src/kernel/libc/exit.c @@ -0,0 +1,14 @@ +/* exit.c for UZI180 by Nick */ + +#include /* for exit() prototype */ +#include /* for _exit() prototype */ + +void exit(int val) + { + if (__cleanup != NULL) + { + (*__cleanup)(val, NULL); + } + _exit(val); + } + diff --git a/src/kernel/libc/itoa.c b/src/kernel/libc/itoa.c new file mode 100755 index 00000000..aa607e0f --- /dev/null +++ b/src/kernel/libc/itoa.c @@ -0,0 +1,213 @@ +/* itoa.c + * numeric/string conversions package + */ + +/* #include "cvt.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include "itoa.h" + +/**************************** ltoa.c ****************************/ +/* #ifdef L_itoa */ + +/* + * filename - ltoa.c + * + * function(s) + * itoa - converts an integer to a string + * ltoa - converts a long to a string + * ultoa - converts an unsigned long to a string + * __longtoa - converts a long to a character string + */ + +/* +Name __longtoa - converts a long to a character string +Usage char *__longtoa (unsigned long value, char *strP, int radix, + char maybeSigned, char hexStyle); +Prototype in stdlib.h + +Description converts a long to a character string. see itoa below. + +Return value pointer to the string +*/ + +/*#pragma warn -use*/ +char *__longtoa(unsigned long value, char *strP, int radix, + char maybeSigned, char hexStyle) +{ + char buf[34]; + register char *di = strP, *si = buf; +#ifdef __TURBOC__ + int *p = (int *)&value; + + hexStyle -= 10; + /* If the request is invalid, generate an empty result */ + if (radix > 36 || radix < 2) + goto lta_end; + if (((int *)&value)[1] < 0 && maybeSigned) { + *di++ = '-'; + value = -value; + } + /* Now loop, taking each digit as modulo radix, and reducing the value + * by dividing by radix, until the value is zeroed. Note that + * at least one loop occurs even if the value begins as 0, + * since we want "0" to be generated rather than "". + */ + /* BX = radix, CX:AX = value */ + _CX = radix; + if (((int *)&value)[1] == 0) + goto lta_shortLoop; + +lta_longLoop: + do { + _AX = ((int *)&value)[1]; + __emit__(0x33,0xD2); /* xor dx,dx */ + __emit__(0xF7,0xF1); /* div cx */ + p[1] = _AX; + _AX = ((int *)&value)[0]; + __emit__(0xF7,0xF1); /* div cx */ + p[0] = _AX; + *si++ = _DL; + } while (p[1] != 0); /* value does not fit in 16 bits */ + goto lta_shortTest; + +lta_shortLoop: + do { + _AX = ((int *)&value)[0]; + __emit__(0x33,0xD2); /* xor dx,dx */ + __emit__(0xF7,0xF1); /* div cx */ + p[0] = _AX; + *si++ = _DL; +lta_shortTest: ; + } while (p[0] != 0); + /* The value has now been reduced to zero and the + * digits are in the buffer. + */ + _CX = si-buf; /* CX = length of numeral */ + /* The digits in the buffer must now be copied in reverse order into + * the target string, translating to ASCII as they are moved. + */ + while ((int)--_CX >= 0) { + _AL = *--si; + if (_AL < 10) + _AL += '0'; + else _AL += hexStyle; + *di++ = _AL; + } +#else + uint *p = (uint *)&value; + uchar al, cx; + + hexStyle -= 10; + /* If the request is invalid, generate an empty result */ + if (radix > 36 || radix < 2) + goto lta_end; + if (p[1] & 0x8000 && maybeSigned) { + *di++ = '-'; + value = -value; + } + /* Now loop, taking each digit as modulo radix, and reducing the value + * by dividing by radix, until the value is zeroed. Note that + * at least one loop occurs even if the value begins as 0, + * since we want "0" to be generated rather than "". + */ + if (p[1] == 0) + goto lta_shortLoop; + do { + *si++ = (uchar)(value % radix); + value /= radix; + } while (p[1] != 0); /* value does not fit in 16 bits */ + goto lta_shortTest; + +lta_shortLoop: + do { + *si++ = (uchar)((uint)value % radix); + p[0] = ((uint)value / radix); +lta_shortTest: ; + } while (p[0] != 0); + /* The value has now been reduced to zero and the + * digits are in the buffer. + */ + cx = (uchar)(si-buf); /* length of numeral */ + /* The digits in the buffer must now be copied in reverse order into + * the target string, translating to ASCII as they are moved. + */ + while (cx != 0) { + al = *--si; + if (al < 10) + al += '0'; + else al += hexStyle; + *di++ = al; + --cx; + } +#endif + /* terminate the output string with a zero. */ +lta_end: + *di = 0; + return strP; /* return a pointer to the string */ +} +/*#pragma warn .use*/ + +/* +Name itoa - converts an integer to a string + ltoa - converts a long to a string + ultoa - converts an unsigned long to a string + +Usage char *itoa(int value, char *strP, int radix); + char *ltoa(long value, char *strP, int radix); + char *ultoa(unsigned long value, char *strP, int radix); + +Prototype in stdlib.h + +Description These functions convert value to a null-terminated string + and store the result in string. With itoa, value is an + integer; with ltoa it is a long; with ultoa it is an + unsigned long. __longtoa is the internal routine used for + all these conversions to ASCII. + + radix specifies the base to be used in converting value. it + must be between 2 and 36 (inclusive). With itoa and ltoa, + if value is negative, and radix is 10, the first character + of string is the minus sign (-). This does not occur with + ultoa. Also, ultoa performs no overflow checking. + + maybeSigned is treated as a boolean. If false then value is + treated as unsigned long and no sign will be placed in + *strP. + + hexStyle may take the values 'a' or 'A' and determines + whether lower or upper case alphabetics are used when the + radix is 11 or greater. + + Note: The space allocated for string must be large enough + to hold the returned string including the terminating null + character (\0). itoa can return up to 17 bytes; ltoa and + ultoa, up to 33 bytes. + +Return value All these functions return a pointer to string. There is no + error return. +*/ + +#if 1 /* Nick */ +char *itoa(int value, char *strP, int radix) +#else +char *itoa(value, strP, radix) + int value; + char *strP; + int radix; +#endif +{ + char hex = 'A'; + + if (radix < 0) { + hex = 'a'; + radix = -radix; + } + return __longtoa ((radix == 10) ? (long) value : + (unsigned long)((unsigned)value), + strP, radix, 1, hex); +} + +/* #endif L_itoa */ + diff --git a/src/kernel/libc/itoa.h b/src/kernel/libc/itoa.h new file mode 100755 index 00000000..db572b99 --- /dev/null +++ b/src/kernel/libc/itoa.h @@ -0,0 +1,11 @@ +/* itoa.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __ITOA_H +#define __ITOA_H + +char *__longtoa(unsigned long value, char *strP, int radix, + char maybeSigned, char hexStyle); +char *itoa(int value, char *strP, int radix); + +#endif /* __ITOA_H */ + diff --git a/src/kernel/libc/kprintf.c b/src/kernel/libc/kprintf.c new file mode 100755 index 00000000..459d5437 --- /dev/null +++ b/src/kernel/libc/kprintf.c @@ -0,0 +1,56 @@ +/* kprintf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +/* #include "printf.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include +#if 1 +#include +#define va_strt va_start +#else +#include +#define va_strt(p,i) va_start(p) +#endif + +#include +#include +#include + +/* #ifdef L_printf */ + +#if 1 +int kprintf(char *fmt, ...) +#else +int kprintf(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ptr; + int rv; + + va_strt(ptr, fmt); +#if 1 /* Nick */ + rv = vfprintf(NULL, fmt, ptr); +#else + rv = vfprintf(stdout, fmt, ptr); +#endif + va_end(ptr); + return rv; +} + +/* #endif L_printf */ + diff --git a/src/kernel/libc/kprintf.h b/src/kernel/libc/kprintf.h new file mode 100755 index 00000000..292eba85 --- /dev/null +++ b/src/kernel/libc/kprintf.h @@ -0,0 +1,9 @@ +/* kprintf.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __KPRINTF_H +#define __KPRINTF_H + +int kprintf(char *fmt, ...); + +#endif /* __KPRINTF_H */ + diff --git a/src/kernel/libc/ltoa.c b/src/kernel/libc/ltoa.c new file mode 100755 index 00000000..97b51c71 --- /dev/null +++ b/src/kernel/libc/ltoa.c @@ -0,0 +1,33 @@ +/* numeric/string conversions package + */ + +/* #include "cvt.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include "ltoa.h" +#include "itoa.h" + +/**************************** ltoa.c ****************************/ +/* #ifdef L_ltoa */ + +#if 1 /* Nick */ +char *ltoa(long value, char *strP, int radix) +#else +char *ltoa(value, strP, radix) + long value; + char *strP; + int radix; +#endif +{ + char hex = 'A'; + + if (radix < 0) { + hex = 'a'; + radix = -radix; + } + return __longtoa (value, strP, radix, (radix == 10), hex); +} + +/* #endif L_ltoa */ + diff --git a/src/kernel/libc/ltoa.h b/src/kernel/libc/ltoa.h new file mode 100755 index 00000000..4072f8a9 --- /dev/null +++ b/src/kernel/libc/ltoa.h @@ -0,0 +1,9 @@ +/* ltoa.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __LTOA_H +#define __LTOA_H + +char *ltoa(long value, char *strP, int radix); + +#endif /* __LTOA_H */ + diff --git a/src/kernel/libc/memcpy.c b/src/kernel/libc/memcpy.c new file mode 100755 index 00000000..4f53a587 --- /dev/null +++ b/src/kernel/libc/memcpy.c @@ -0,0 +1,53 @@ +/* memcpy.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* #include "mem-l.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include "memcpy.h" + +/********************** Function memcpy ************************************/ +/* #ifdef L_memcpy */ + +#if 1 /* Nick */ +void *memcpy(void *d, void *s, size_t l) +#else +void *memcpy(d, s, l) + void *d; + void *s; + size_t l; +#endif +{ +#ifndef HI_TECH_C + register char *s1 = d, *s2 = (char *) s; + + while (l-- != 0) + *((unsigned char *) s1++) = *((unsigned char *) s2++); + return d; +#else +_asm + ; HTC puts a "push ix" here + ld ix,0 + add ix,sp + ld h,b + ld l,c + ld c,(ix+4) + ld b,(ix+5) + push de + ld a,b + or c + jr z,_skip + ldir +_skip: + pop hl + ; HTC puts a "pop ix" here +_endasm +#endif +} + +/* #endif L_memcpy */ + diff --git a/src/kernel/libc/memcpy.h b/src/kernel/libc/memcpy.h new file mode 100755 index 00000000..7b44dc40 --- /dev/null +++ b/src/kernel/libc/memcpy.h @@ -0,0 +1,9 @@ +/* memcpy.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __MEMCPY_H +#define __MEMCPY_H + +void *memcpy(void *d, void *s, size_t l); + +#endif /* __MEMCPY_H */ + diff --git a/src/kernel/libc/strcat.c b/src/kernel/libc/strcat.c new file mode 100755 index 00000000..c9961aeb --- /dev/null +++ b/src/kernel/libc/strcat.c @@ -0,0 +1,29 @@ +/* strcat.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* #include "string-l.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include "strcat.h" + +/********************** Function strcat ************************************/ +/* #ifdef L_strcat */ + +#if 1 /* Nick */ +char *strcat(char *d, char *s) +#else +char *strcat(d, s) + char *d; + char *s; +#endif +{ + strcpy(d + strlen(d), s); + return d; +} + +/* #endif L_strcat */ + diff --git a/src/kernel/libc/strcat.h b/src/kernel/libc/strcat.h new file mode 100755 index 00000000..acfd2c4c --- /dev/null +++ b/src/kernel/libc/strcat.h @@ -0,0 +1,9 @@ +/* strcat.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __STRCAT_H +#define __STRCAT_H + +char *strcat(char *d, char *s); + +#endif /* __STRCAT_H */ + diff --git a/src/kernel/libc/strcpy.c b/src/kernel/libc/strcpy.c new file mode 100755 index 00000000..5d976bc0 --- /dev/null +++ b/src/kernel/libc/strcpy.c @@ -0,0 +1,29 @@ +/* strcpy.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* #include "string-l.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include "strcpy.h" +#include "memcpy.h" + +/********************** Function strcpy ************************************/ +/* #ifdef L_strcpy */ + +#if 1 /* Nick */ +char *strcpy(char *d, char *s) +#else +char *strcpy(d, s) + char *d; + char *s; +#endif +{ + return memcpy(d, s, strlen(s) + 1); +} + +/* #endif */ + diff --git a/src/kernel/libc/strcpy.h b/src/kernel/libc/strcpy.h new file mode 100755 index 00000000..fd1bb159 --- /dev/null +++ b/src/kernel/libc/strcpy.h @@ -0,0 +1,9 @@ +/* strcpy.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __STRCPY_H +#define __STRCPY_H + +char *strcpy(char *d, char *s); + +#endif /* __STRCPY_H */ + diff --git a/src/kernel/libc/strlen.c b/src/kernel/libc/strlen.c new file mode 100755 index 00000000..70fc845e --- /dev/null +++ b/src/kernel/libc/strlen.c @@ -0,0 +1,43 @@ +/* strlen.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* #include "string-l.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include "strlen.h" + +/********************** Function strlen ************************************/ +/* #ifdef L_strlen */ + +#if 1 /* Nick */ +size_t strlen(char *str) +#else +size_t strlen(str) + register char *str; +#endif +{ +#ifndef HI_TECH_C + register char *p = str; + + while (*p != 0) + ++p; + return (size_t)(p-str); +#else +_asm + ld h,d + ld l,e + ld bc,0ffffh + xor a + cpir + sbc hl,de + dec hl +_endasm +#endif +} + +/* #endif L_strlen */ + diff --git a/src/kernel/libc/strlen.h b/src/kernel/libc/strlen.h new file mode 100755 index 00000000..08024327 --- /dev/null +++ b/src/kernel/libc/strlen.h @@ -0,0 +1,9 @@ +/* strlen.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __STRLEN_H +#define __STRLEN_H + +size_t strlen(char *str); + +#endif /* __STRLEN_H */ + diff --git a/src/kernel/libc/strncmp.c b/src/kernel/libc/strncmp.c new file mode 100755 index 00000000..9f13ddf5 --- /dev/null +++ b/src/kernel/libc/strncmp.c @@ -0,0 +1,34 @@ +/* strncmp.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* #include "string-l.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include "strncmp.h" + +/********************** Function strncmp ************************************/ +/* #ifdef L_strncmp */ + +#if 1 /* Nick */ +int strncmp(char *d, char *s, size_t l) +#else +int strncmp(d, s, l) + char *d, *s; + size_t l; +#endif +{ + register char c1 = 0, c2 = 0; + + while (l-- != 0) { + if ((c1 = *d++) != (c2 = *s++) || c1 == '\0') + break; + } + return c1 - c2; +} + +/* #endif */ + diff --git a/src/kernel/libc/strncmp.h b/src/kernel/libc/strncmp.h new file mode 100755 index 00000000..a136991d --- /dev/null +++ b/src/kernel/libc/strncmp.h @@ -0,0 +1,9 @@ +/* strncmp.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __STRNCMP_H +#define __STRNCMP_H + +int strncmp(char *d, char *s, size_t l); + +#endif /* __STRNCMP_H */ + diff --git a/src/kernel/libc/ultoa.c b/src/kernel/libc/ultoa.c new file mode 100755 index 00000000..0174fcde --- /dev/null +++ b/src/kernel/libc/ultoa.c @@ -0,0 +1,33 @@ +/* numeric/string conversions package + */ + +/* #include "cvt.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include "ultoa.h" +#include "itoa.h" + +/**************************** ultoa.c ****************************/ +/* #ifdef L_ultoa */ + +#if 1 /* Nick */ +char *ultoa(unsigned long value, char *strP, int radix) +#else +char *ultoa(value, strP, radix) + unsigned long value; + char *strP; + int radix; +#endif +{ + char hex = 'A'; + + if (radix < 0) { + hex = 'a'; + radix = -radix; + } + return __longtoa (value, strP, radix, 0, hex); +} + +/* #endif L_ultoa */ + diff --git a/src/kernel/libc/ultoa.h b/src/kernel/libc/ultoa.h new file mode 100755 index 00000000..cf4a4211 --- /dev/null +++ b/src/kernel/libc/ultoa.h @@ -0,0 +1,9 @@ +/* ultoa.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __ULTOA_H +#define __ULTOA_H + +char *ultoa(unsigned long value, char *strP, int radix); + +#endif /* __ULTOA_H */ + diff --git a/src/kernel/libc/vendor.h b/src/kernel/libc/vendor.h new file mode 100755 index 00000000..7c5b7c44 --- /dev/null +++ b/src/kernel/libc/vendor.h @@ -0,0 +1,14 @@ +/* vendor.h for uzi180 by Nick - essential defines for the IAR compiler */ + +#ifndef UTIL /* ensures we don't do anything when compiling utils under MSVC */ + +#define kprintf _kprintf + +#if 1 /* Nick, see kprintf.c */ +int kprintf(char *, ...); /* ensures IAR won't try to pass register params */ +#else +void kprintf(char *, ...); /* ensures IAR won't try to pass register params */ +#endif + +#endif /* UTIL */ + diff --git a/src/kernel/libc/vfprintf.c b/src/kernel/libc/vfprintf.c new file mode 100755 index 00000000..3428dd35 --- /dev/null +++ b/src/kernel/libc/vfprintf.c @@ -0,0 +1,317 @@ +/* vfprintf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +/* #include "printf.h" */ +#include "vendor.h" /* Nick, must come first */ + +#include +#include +#if 1 +#include +#define va_strt va_start +#else +#include +#define va_strt(p,i) va_start(p) +#endif + +#include +#include +#include + +/* #ifdef L_vfprintf */ + +#ifdef FLOATS +extern void _fnum(double val, char fmt, int prec, char *ptmp); +#endif + +/* + * Output the given field in the manner specified by the arguments. Return + * the number of characters output. + */ +static int prtfld __P((FILE *op, unsigned char *buf, + int ljustf, char sign, char pad, + int width, int preci, int buffer_mode)); + +static int prtfld(op, buf, ljustf, sign, pad, width, preci, buffer_mode) + register FILE *op; + register unsigned char *buf; + int ljustf; + register char sign; + char pad; + register int width; + int preci; + int buffer_mode; +{ + register unsigned char ch; + register int cnt = 0, len = strlen(buf); + + if (*buf == '-') + sign = *buf++; + else if (sign) + len++; + if ((preci != -1) && (len > preci)) /* limit max data width */ + len = preci; + if (width < len) /* flexible field width or width overflow */ + width = len; + /* at this point: width = total field width, len = actual data width + * (including possible sign character) + */ + cnt = width; + width -= len; + while (width || len) { + if (!ljustf && width) { /* left padding */ + if (len && sign && (pad == '0')) + goto showsign; + ch = pad; + --width; + } + else if (len) { + if (sign) { +showsign: ch = sign; /* sign */ + sign = '\0'; + } + else ch = *buf++; /* main field */ + --len; + } + else { + ch = pad; /* right padding */ + --width; + } +#if 1 /* Nick */ + kputchar(ch); +#else + putc(ch, op); + if (ch == '\n' && buffer_mode == _IOLBF) + fflush(op); +#endif + } + return (cnt); +} + +#if 1 +int vfprintf(op, fmt, ap) /* Nick */ +#else +static int vfprintf(op, fmt, ap) +#endif + FILE *op; + register char *fmt; + register va_list ap; +{ + register int i, ljustf, lval, preci, dpoint, width, radix, cnt = 0; + char pad, sign, hash; + register char *ptmp, *add; + unsigned long val; + char tmp[64]; + int buffer_mode; + + /* This speeds things up a bit for unbuffered */ +#if 0 /* Nick */ + buffer_mode = (op->mode & __MODE_BUF); + op->mode &= (~__MODE_BUF); +#endif + while (*fmt) { + if (*fmt == '%') { +#if 0 /* Nick */ + if (buffer_mode == _IONBF) + fflush(op); +#endif + ljustf = 0; /* left justify flag */ + sign = '\0'; /* sign char & status */ + pad = ' '; /* justification padding char */ + width = -1; /* min field width */ + dpoint = 0; /* found decimal point */ + preci = -1; /* max data width */ + radix = 10; /* number base */ + ptmp = tmp; /* pointer to area to print */ + hash = 0; + lval = (sizeof(int) == sizeof(long)); /* long value flaged */ +fmtnxt: for (i = 0, ++fmt; ; ++fmt) { + if (*fmt < '0' || *fmt > '9') + break; + i *= 10; + i += (*fmt - '0'); + if (dpoint) + preci = i; + else if (!i && (pad == ' ')) { + pad = '0'; + goto fmtnxt; + } + else width = i; + } + switch (*fmt) { + case '\0': /* early EOS */ + --fmt; + goto charout; + + case '-': /* left justification */ + ljustf = 1; + goto fmtnxt; + + case ' ': + case '+': /* leading sign flag */ + sign = *fmt; + goto fmtnxt; + + case '#': + hash = 1; + goto fmtnxt; + + case '*': /* parameter width value */ + i = va_arg(ap, int); + if (dpoint) + preci = i; + else if ((width = i) < 0) { + ljustf = 1; + width = -i; + } + goto fmtnxt; + + case '.': /* secondary width field */ + dpoint = 1; + goto fmtnxt; + + case 'l': /* long data */ + lval = 1; + goto fmtnxt; + + case 'h': /* short data */ + lval = 0; + goto fmtnxt; + + case 'd': /* Signed decimal */ + case 'i': + ptmp = ltoa((long) ((lval) ? + va_arg(ap, long) : + va_arg(ap, short)), + tmp, 10); + goto printit; + + case 'b': /* Unsigned binary */ + radix = 2; + goto usproc; + + case 'o': /* Unsigned octal */ + radix = 8; + goto usproc; + + case 'p': /* Pointer */ + lval = (sizeof(char *) == sizeof(long)); + pad = '0'; + width = 5; + preci = 8; + /* fall thru */ + + case 'X': /* Unsigned hexadecimal 'ABC' */ + radix = 16; + goto usproc; + + case 'x': /* Unsigned hexadecimal 'abc' */ + radix = -16; + /* fall thru */ + + case 'u': /* Unsigned decimal */ +usproc: val = lval ? va_arg(ap, unsigned long) : + va_arg(ap, unsigned short); + ptmp = ultoa(val, tmp+4, radix); + add = ""; + if (hash) { + if (radix == 2) + add = "0b"; + else if (radix == 8) { + if (val != 0) + add = "0"; + } + else if (radix == 16) + add = "0x"; + else if (radix == -16) + add = "0X"; + if (*add) { + pad = '\0'; + strcpy(tmp,add); + ptmp = strcat(tmp,ptmp); + } + } + goto printit; + + case '!': /* inline Character */ + if ((i = fmt[1]) != 0) + ++fmt; + goto Chr; + + case 'c': /* Character */ + i = va_arg(ap, int); +Chr: ptmp[0] = i; + ptmp[1] = '\0'; + if (hash) { + pad = *ptmp; + goto chrpad; + } + goto nopad; + + case 's': /* String */ + ptmp = va_arg(ap, char *); +nopad: pad = ' '; +chrpad: sign = '\0'; +printit: cnt += prtfld(op, (unsigned char *)ptmp, + ljustf, sign, pad, width, preci, + buffer_mode); + break; + +#ifdef FLOATS + case 'e': /* float */ + case 'f': + case 'g': + case 'E': + case 'G': + _fnum (va_arg(ap, double), + *fmt, preci, ptmp); + /* double arg; + char fmt; (e/f/g/E/G) + int preci; (width, -1 if no) + char *ptmp; (where to print) + */ + preci = -1; + goto printit; + /* FALLTHROUGH if no floating printf available */ +#endif + default: /* unknown character */ + goto charout; + } + } + else { +charout: +#if 1 /* Nick */ + kputchar(*fmt); /* normal char out */ + ++cnt; +#else + putc(*fmt, op); /* normal char out */ + ++cnt; + if (*fmt == '\n' && buffer_mode == _IOLBF) + fflush(op); +#endif + } + ++fmt; + } +#if 0 /* Nick */ + op->mode |= buffer_mode; + if (buffer_mode == _IONBF) + fflush(op); + if (buffer_mode == _IOLBF) + op->bufwrite = op->bufstart; +#endif + return (cnt); +} + +/* #endif L_vfprintf */ + diff --git a/src/kernel/libc/vfprintf.h b/src/kernel/libc/vfprintf.h new file mode 100755 index 00000000..3005cd68 --- /dev/null +++ b/src/kernel/libc/vfprintf.h @@ -0,0 +1,9 @@ +/* vfprintf.h for uzi180 by Nick - subroutines based on /uzi/libc source */ + +#ifndef __VFPRINTF_H +#define __VFPRINTF_H + +int vfprintf(op, fmt, ap); + +#endif /* __VFPRINTF_H */ + diff --git a/src/kernel/n.bat b/src/kernel/n.bat new file mode 100755 index 00000000..723a7461 --- /dev/null +++ b/src/kernel/n.bat @@ -0,0 +1,6 @@ +md build +cd build +copy ..\kernel.lnk +copy ..\build.ban n.bat +call n +cd .. diff --git a/src/kernel/uzi/asmdef.inc b/src/kernel/uzi/asmdef.inc new file mode 100755 index 00000000..9b634fc8 --- /dev/null +++ b/src/kernel/uzi/asmdef.inc @@ -0,0 +1,107 @@ +; Conditional Flag Definitions. + +FALSE EQU 0 +TRUE EQU 1 + +; General-Purpose Ascii Character Equates. + +BS EQU 08H ; Ascii BackSpace +TAB EQU 09H ; Ascii Horizontal Tab +LF EQU 0AH ; Ascii Line Feed +CR EQU 0DH ; Ascii Carriage Return +ESC EQU 1BH ; Ascii ESCape Char + +; !!!!!-- Insure definitions match those in unix.h --!!!!! + +TICKSPERSEC EQU 50 ; Needed to compute Timer reload Value + +; Allowable syscall error codes (value of byte at _ub+OERR) added by Nick + +EAGAIN EQU 11 ; (NOT A COMPLETE SET FOR NOW... REVISIT !!!) + +; Allowable process status codes (value of byte at _ub->u_ptab) added by Nick + +P_EMPTY EQU 0 ; Unused slot +P_ZOMBIE EQU 1 ; 1. Exited. +P_FORKING EQU 2 ; 2. In process of forking; do not mess with +P_RUNNING EQU 3 ; 3. Currently running process +P_READY EQU 4 ; 4. Runnable process +P_SLEEP EQU 5 ; 5. Sleeping; can be awakened by signal +P_XSLEEP EQU 6 ; 6. Sleeping, don't wake up for signal +P_PAUSE EQU 7 ; 7. Sleeping for pause(); can wakeup on signal +P_WAIT EQU 8 ; 8. Executed a wait() + +; Byte Offsets into User Data Structure (udata/ub). +; !!!!!-- Insure definitions match udata struct in unix.h --!!!!! + +OSYS EQU 2 ; Offset in _ub for insys flag (Byte) +OCALL EQU 3 ; Offset in _ub for Function Call No. (Byte) +ORET EQU 4 ; Offset in _ub for Fcn Return Loc'n (Word) +ORVAL EQU 6 ; Offset in _ub for Fcn Return Value (Word) +ORVAL1 EQU 8 ;6 ; Offset in _ub for Fcn Return Value (Word) +OERR EQU 10 ;8 ; Offset in _ub to Error Status (Word) +OSP EQU 12 ;10 ; Offset in _ub to Stack Pointer (Word) +OARGN EQU 18 ;16 ; Offset in _ub to Argn Parameter (Word) +OPAGE EQU 139-10 ;121 + 16 ; NSIGS Nick ; Offset in _ub to Process' BBR Reg base + ; correction of -10 is for UFTSIZE, now moved it to the end of udata_t + +; TTY Ioctl Functions for UZI180. Used by EMU and TTYASM. +; !!!!!-- Insure definitions match those in unix.h --!!!!! + +TIOCGETP EQU 0 ; UZI ioctl Return tty Parms +TIOCSETP EQU 1 ; UZI ioctl Set tty Parms +TIOCSETN EQU 2 ; UZI ioctl Return buffer count +TIOCTLSET EQU 9 ; UZI ioctl Unique - Disable Ctl Char Proc +TIOCTLRES EQU 10 ; UZI ioctl Unique - Enable Ctl Char Proc + +; File Descriptors needed by EMU for Console IO. + +STDIN EQU 0 ; file descriptor value of keyboard +STDOUT EQU 1 ; file descriptor value of display + +; Z180/Z182 Hardware configurations. Set to provide initial base conditions. + +HISPEED EQU FALSE ; Set TRUE if operating Z8S180 or Z80182 with + ; "divide-by-1" vice default "divide-by-2" +MHZ DEFL 18 ; CPU Crystal Frequency, truncate to nearest + ; even MegaHertz (this actually 18.432 MHz) + .if HISPEED .eq. FALSE +MHZ DEFL MHZ / 2 ; At Low Speed (powerup default), Crystal + .endif ; frequency is divided by 2 + +PRTCONS EQU 51200 / TICKSPERSEC ; 51200 constant value for systems at + ; 6.144/9.216/18.432/36.864 MHz (use 50000 for + ; 8.0/16.0 MHz systems) Compute as: + ; (Clock_freq / 20) / MHZ whole # constant +RELOAD EQU PRTCONS * MHZ ; Programmable Reload Timer value + +MWAIT EQU 0 ; Additional Memory Wait States (0..3) +IOWAIT EQU 0 ; Additional IO Wait States (0..3) + +; Stack definitions. Need hard addresses to optimize data movements during +; Process swapping. + + .if 1 ; Nick, since _ub is now in RCODE below 4000h, rather than above 0f000h +KSTACK equ _ub+200h ; Kernel Stack at "_ub+512" working Down to ub +ISTACK equ _ub+1000h ;300h ; Timer Interrupt Stack at "_ub+768" working + ; Down to Kernel Stack. + .else +KSTACK EQU 0F200H ; Kernel Stack at "_ub+512" working Down to ub +ISTACK EQU 0F300H ; Timer Interrupt Stack at "_ub+768" working + ; Down to Kernel Stack. + .endif + +; A couple of CP/M-specific values used in EMU. + +fcb EQU 005CH ; Default CP/M FCB +buff EQU 0080H ; Default CP/M Buffer + +; ---- H/W Unique Definitions ---- + +ISLCD EQU TRUE ; Unique Hardware for YASBEC Laptop. (HFB) + +; definitions added by Nick + +PROGBASE equ 8100h ; see unix.h (by Nick, formerly 100h) +PROGTOP equ 0fffeh ; see unix.h (by Nick, same as original) + diff --git a/src/kernel/uzi/config.h b/src/kernel/uzi/config.h new file mode 100755 index 00000000..9e0ee5a9 --- /dev/null +++ b/src/kernel/uzi/config.h @@ -0,0 +1,91 @@ +/************************************************** +UZI (Unix Z80 Implementation) Kernel: config.h +***************************************************/ +/* ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! */ +/* ! ! ! Remake devio.c when this file is changed ! ! ! */ +/* ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! */ + +#ifdef DEVIO + +#if 1 /* Nick UZIX compatible */ +devsw_t dev_tab[] = /* The device driver switch table */ +{ +/* minors init open close read write ioctl */ +/*-------------------------------------------------------------------*/ + { 2, ok, wd_open, ok, wd_read, wd_write, nogood_ioctl }, /* 0 hdX */ + { 1, ok, ok, ok, ok_rdwr, null_write, nogood_ioctl }, /* 1 null */ + { 1, ok, ok, ok, ok_rdwr, null_write, nogood_ioctl }, /* 2 zero */ + { 1, ok, ok, ok, mem_read, mem_write, nogood_ioctl }, /* 3 kmem */ + { 10, ok, tty_open, tty_close, tty_read, tty_write, tty_ioctl } /* 4 ttyX */ +}; +#define DEV_TAB (sizeof(dev_tab)/sizeof(dev_tab[0])) +#else +extern wd_open(), wd_read(), wd_write(); +extern fd_open(), fd_read(), fd_write(); +extern tty_open(), tty_close(), tty_read(), tty_write(), tty_ioctl(); +extern lpr_open(), lpr_close(), lpr_write(); +extern mem_read(), mem_write(); +extern mt_read(), mt_write(), mt_open(), mt_close(); +extern null_write(); + +/*static*/ struct devsw dev_tab[] = /* The device driver switch table */ +{ + /* minor open close read write ioctl */ + /*-----------------------------------------------------*/ + { 0, wd_open, ok, wd_read, wd_write, nogood }, /* 0 HD0 */ + { 1, wd_open, ok, wd_read, wd_write, nogood }, /* 1 HD1 */ +#if 1 /* def UTIL */ + { 0, ok, ok, ok, null_write, nogood }, /* 2 Swap */ + { 0, ok, ok, ok, null_write, nogood }, /* 3 floppy */ + { 0, ok, ok, ok, null_write, nogood }, /* 4 printer */ + { 0, ok, ok, ok, null_write, nogood }, /* 5 /dev/mt */ +#else + { 2, wd_open, ok, wd_read, wd_write, nogood }, /* 2 Swap */ + { 0, fd_open, ok, fd_read, fd_write, nogood }, /* 3 floppy */ + { 0, lpr_open, lpr_close, nogood, lpr_write, nogood }, /* 4 printer */ + { 0, mt_open, mt_close, mt_read, mt_write, nogood }, /* 5 /dev/mt */ +#endif + { 0, ok, ok, ok, null_write, nogood }, /* 6 /dev/null */ + { 0, ok, ok, mem_read, mem_write, nogood }, /* 7 /dev/kmem */ + { 0, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 8 tty */ + { 1, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 9 tty0 */ + { 2, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 10 tty1 */ + { 3, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 11 tty2 */ + { 4, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 12 tty3 */ + { 5, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 13 scale */ + { 6, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 14 lcd0 */ + { 7, tty_open, tty_close, tty_read, tty_write, tty_ioctl }, /* 15 lcd1 */ + { 0, ok, ok, ok, null_write, nogood }, /* 16 unused */ + { 9, tty_open, tty_close, tty_read, tty_write, tty_ioctl } /* 17 lpr0 */ + /* Add more tty channels here if available, incrementing minor# */ +}; +#endif + +#else /* Nick */ + +extern devsw_t dev_tab[]; /* Nick */ + +#endif + +#define BOOT_TTY 0x402 /*10*/ /*9*/ /* Set this to default device for stdio, stderr */ + /* In this case, the default is the first TTY device */ + +#define NDEVS 3 /* Devices 0..NDEVS-1 are capable of being mounted */ + /* (add new mountable devices to beginning area. */ +#if 1 /* Nick UZIX compatible */ +#define BLK_DEVS 1 /* # of block (mountable) devices in table */ +#define NFS NDEVS /* max # of mounted filesystems */ +#endif + +#define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ +#define SWAPDEV 3 /* Device for swapping. */ +#define NBUFS 20 /*10*/ /* Number of block buffers */ + +#if 1 /* Nick UZIX compatibility */ + +#define HOST_MACHINE "WPO" /* World Post Office HYT1000 / HYT1500 */ +#define VERSION "1.0" /* UZIX version */ +#define RELEASE "0" /* UZIX release */ + +#endif + diff --git a/src/kernel/uzi/data.c b/src/kernel/uzi/data.c new file mode 100755 index 00000000..b2b26750 --- /dev/null +++ b/src/kernel/uzi/data.c @@ -0,0 +1,214 @@ +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: data.c +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + */ + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include /* prototypes added by Nick */ +#include /* prototypes added by Nick */ +#include /* prototypes added by Nick */ +#define MAIN + +#include /* This declares all the tables, etc */ + +int stdin, stdout, stderr; /* Necessary for library, but never referenced */ + +/* Dispatch table for system calls */ +#if 0 /* Nick UZIX compatible */ +int sys_access(void); +int sys_alarm(void); +int sys_brk(void); +int sys_chdir(void); +int sys_chmod(void); +int sys_chown(void); +int sys_close(void); +int sys_getset(void); +int sys_dup(void); +int sys_dup2(void); +int sys_execve(void); +int sys__exit(void); +int sys_fork(void); +int sys_fstat(void); +int sys_getfsys(void); +int sys_ioctl(void); +int sys_kill(void); +int sys_link(void); +int sys_mknod(void); +int sys_mount(void); +int sys_open(void); +int sys_pause(void); +int sys_pipe(void); +int sys_read(void); +int sys_sbrk(void); +int sys_seek(void); /* int sys_lseek(void); */ +int sys_signal(void); +int sys_stat(void); +int sys_stime(void); +int sys_sync(void); +int sys_time(void); +int sys_times(void); +int sys_umount(void); +int sys_unlink(void); +int sys_utime(void); +int sys_waitpid(void); +int sys_write(void); +int sys_reboot(void); +int sys_symlink(void); +int sys_chroot(void); +#endif + +#if 1 /* Nick UZIX compatible */ +int (*disp_tab[])() = + { + sys_access, + sys_alarm, + sys_brk, + sys_chdir, + sys_chmod, + sys_chown, + sys_close, + sys_getset, + sys_dup, + sys_dup2, + sys_execve, + sys__exit, + sys_fork, + sys_statfstat, /* sys_fstat, */ + sys_getfsys, + sys_ioctl, + sys_kill, + sys_link, + sys_mknod, + sys_mountumount, /* mount, */ + sys_open, + sys_pause, + sys_pipe, + sys_readwrite, /* sys_read, */ + sys_sbrk, + sys_lseek, /* sys_seek, */ + sys_signal, + sys_statfstat, /* sys_stat, */ + sys_stime, + sys_sync, + sys_time, + sys_times, + sys_mountumount, /* sys_umount, */ + sys_unlink, + sys_utime, + sys_waitpid, + sys_readwrite, /* sys_write, */ + sys_reboot, + sys_symlink, + sys_chroot +#if 1 /* Nick free bitmap */ + ,sys_falign +#endif + }; +#else +extern int + sys__exit(), + sys_open(), + sys_close(), + sys_creat(), + sys_mknod(), + sys_link(), + sys_unlink(), + sys_read(), + sys_write(), + sys_seek(), + sys_chdir(), + sys_sync(), + sys_access(), + sys_chmod(), + sys_chown(), + sys_stat(), + sys_fstat(), + sys_dup(), + sys_getpid(), + sys_getppid(), + sys_getuid(), + sys_umask(), + sys_getfsys(), + sys_execve(), + sys_wait(), + sys_setuid(), + sys_setgid(), + sys_time(), + sys_stime(), + sys_ioctl(), + sys_brk(), + sys_sbrk(), + sys_fork(), + sys_mount(), + sys_umount(), + sys_signal(), + sys_dup2(), + sys_pause(), + sys_alarm(), + sys_kill(), + sys_pipe(), + sys_getgid(), + sys_times(), + sys_utime(); + sys_geteuid(); + sys_getegid(); + +int (*disp_tab[])() = +{ sys__exit, + sys_open, + sys_close, + sys_creat, + sys_mknod, + sys_link, + sys_unlink, + sys_read, + sys_write, + sys_seek, + sys_chdir, + sys_sync, + sys_access, + sys_chmod, + sys_chown, + sys_stat, + sys_fstat, + sys_dup, + sys_getpid, + sys_getppid, + sys_getuid, + sys_umask, + sys_getfsys, + sys_execve, + sys_wait, + sys_setuid, + sys_setgid, + sys_time, + sys_stime, + sys_ioctl, + sys_brk, + sys_sbrk, + sys_fork, + sys_mount, + sys_umount, + sys_signal, + sys_dup2, + sys_pause, + sys_alarm, + sys_kill, + sys_pipe, + sys_getgid, + sys_times, + sys_utime, + sys_geteuid, + sys_getegid + }; +#endif + +int ncalls = sizeof (disp_tab) / sizeof (int(*)()); + diff --git a/src/kernel/uzi/devflop.c b/src/kernel/uzi/devflop.c new file mode 100755 index 00000000..9d0b2866 --- /dev/null +++ b/src/kernel/uzi/devflop.c @@ -0,0 +1,141 @@ +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: devflop.c +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + */ + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include + +extern ei(); + +extern int fdInit (int); /* Floppy Init Routine. 0 if drive exists */ +extern int fdread0(), fdwrite0(); +extern unsigned char ftrack, fsector, ferror; +extern char *fbuf; +extern struct drvTbl { + unsigned char logged; + unsigned char cbyte0; + unsigned char cbyte1; + unsigned char gap3; + unsigned char spt; + unsigned char sector1; + unsigned char format; + unsigned char spinup; + unsigned char curtrk; +} dTbl[4]; + +int secsiz [4] = {128, 256, 512, 1024}; /* Table of Sector Sizes */ + + +fd_read (minor, rawflag) +int16 minor; +int rawflag; +{ + int fd(); + return (fd (1, minor, rawflag)); +} + +fd_write (minor, rawflag) +int16 minor; +int rawflag; +{ + int fd(); + return (fd (0, minor, rawflag)); +} + + + +fd (rwflag, minor, rawflag) +int rwflag; +int minor; +int rawflag; +{ + register unsigned nblocks; + register unsigned firstblk; + + if (rawflag) + { + if (rawflag == 2) + { + nblocks = swapcnt >> 9; + fbuf = swapbase; + firstblk = swapblk; + } + else + { + nblocks = udata.u_count >> 9; + fbuf = udata.u_base; + firstblk = udata.u_offset >> BUFSIZELOG; /* Nick .o_blkno; */ + } + } + else + { + nblocks = 1; + fbuf = udata.u_buf->bf_data; + firstblk = udata.u_buf->bf_blk; + } + + ftrack = firstblk / dTbl[minor].spt; + fsector = firstblk % dTbl[minor].spt; /* Base 0 Sect # */ + ferror = 0; + + for (;;) + { + if (rwflag) + fdread0(); + else + fdwrite0(); + + ifnot (--nblocks) + break; + + if (++fsector > dTbl[minor].spt) + { + fsector = 0; + ++ftrack; + } + fbuf += secsiz[(unsigned int) (dTbl[minor].format&0x03)]; + } + + if (ferror) + { + kprintf ("fd_%s: error %d track %d sector %d\n", + rwflag?"read":"write", ferror, ftrack, fsector); + panic (""); + } + return (nblocks); +} + + +fd_open (minor) +int minor; +{ + if (fdInit (minor)) + { + udata.u_error = ENXIO; + return (-1); + } + return (0); +} + + +fd_close (minor) +int minor; +{ + dTbl[minor].logged = 0; /* Mark Drive as logged out */ + return (0); +} + + +fd_ioctl (minor) +int minor; +{ + return (-1); +} diff --git a/src/kernel/uzi/devhd.c b/src/kernel/uzi/devhd.c new file mode 100755 index 00000000..a542b882 --- /dev/null +++ b/src/kernel/uzi/devhd.c @@ -0,0 +1,241 @@ +/*************************************************************** +UZI (Unix Z80 Implementation) Kernel: devhd.c + Unique Hardware driver contained in hdasm.asz +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + * 1.1.98 - Added IDE and SCSI configurations. HFB + * 14.7.98 - Finalized config via HDCONF.H w/variables. HFB + */ + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include /* Add configuration-specific data */ +#include /* prototypes added by Nick */ + +#ifdef GIDE +extern unsigned char hdspt, hdhds; +#endif + + /* All Hard Disk Drivers pass Commands and Data via the cmdblk array. + * The definition of each byte in the array varies as: + * + * SCSI: Drivers use the short (6 byte) SCSI Read/Write Commands + * Byte 0 - SCSI Command (08H = Read, 0AH = Write, 03H = Read Sense) + * 1 - B7..5 = LUN, B4..0 = High 5 bits of Block Number + * 2 - Middle 8 bits of Block Number + * 3 - Low 8 bits of Block Number + * 4 - Number of 512-byte Blocks to Read + * 5 - Control Flags (unused, set to 0) + * IDE: Drivers use data in similar manner as SCSI as: + * Byte 0 - IDE Command (20H = Read, 30H = Write) + * 1 - High bits of Block Number + * 2 - Middle 8 bits of Block Number + * 3 - Low 8 bits of Block Number + * 4 - Number of 512-byte Blocks to Read + * 5 - (unused, set to 0) + * APIBUS: Things are nudged around to make an 'esc' sequence: + * Byte 0 - ESC + * 1 - CompactFlash command ('R' = Read, 'W' = Write) + * 2 - Bits 0.. 7 of LBA index for block + * 3 - Bits 8..15 of LBA index for block + * 4 - Bits 16..23 of LBA index for block + * 5 - Bits 24..31 of LBA index for block + * 6 - Checksum (0xff minus the sum of the preceding 4 bytes) + * 7 - Number of 512-byte Blocks to read (done in software) + */ +#ifdef APIBUS +char cmdblk[8] = { 0x1b, 0, 0, 0, 0, 0, 0, 0 }; /* GLOBAL. Used in main.c */ +#else +char cmdblk[6] = { 0, LUN<<5, 0, 0, 0, 0 }; /* GLOBAL. Used in hdasm.asz */ +#endif +#ifdef APIBUS +long hd_offset = 0; /* Sector offset for selected partition, used in main.c */ +long hd_sector = 0; /* Sector relative to offset given above, used in main.c */ +#else +unsigned hd_offset = 0; /* Track offset for Selected Unit, in hdasm.asz */ +#endif + +char *dptr = NULL; /* Ptr to Data Buffer for I/O */ +int dlen = 0; /* Length of Data I/O Transfer */ +char *cptr = NULL; /* Ptr to Code Buffer for I/O */ +int busid = 1; /* Hardware Unit (SCSI = 0,2,4,..64. Unit Bit) */ + +extern int scsiop(); + +int wd_read(uchar minor, uchar rawflag) +{ + int setup(); + +/* kputchar(minor + '0'); */ +#if DEBUG > 1 + kputchar('<'); + kputchar(8); +#endif + +#ifdef APIBUS + cmdblk[1] = RDCMD; +#else + cmdblk[0] = RDCMD; +#endif + if (setup (minor, rawflag)) + return -1; /* (0); */ +/* abyte('~'); */ + + chkstat (scsiop(), 1); + +#if DEBUG > 1 + kputchar(' '); + kputchar(8); +#endif + + return 0; /* success.. formerly count of bytes read */ +} + + +int wd_write(uchar minor, uchar rawflag) +{ + int setup(); + +/* kputchar(minor + '0'); */ +#if DEBUG > 1 + kputchar('>'); + kputchar(8); +#endif + +#ifdef APIBUS + cmdblk[1] = WRCMD; +#else + cmdblk[0] = WRCMD; +#endif + if (setup (minor, rawflag)) + return -1; /* (0); */ + + chkstat (scsiop(), 0); + +#if DEBUG > 1 + kputchar(' '); + kputchar(8); +#endif + + return 0; /* success.. formerly count of bytes written */ +} + +int setup(uchar minor, uchar rawflag) +{ + register blkno_t block; + +/* kprintf("setup(%u, %d)\n", minor, rawflag); */ + + cptr = cmdblk; + busid = 1; +#ifndef APIBUS + cmdblk[5] = 0; /* Clear Flags */ +#endif +#ifdef GIDE + hdspt = HD_Sector; /* Set physical drive params if IDE */ + hdhds = HD_Heads; +#endif + if (rawflag) + { + if (rawflag == 2) + { +#ifdef APIBUS + cmdblk[7] = swapcnt >> 9; +#else + cmdblk[4] = swapcnt >> 9; +#endif + dlen = swapcnt; + dptr = swapbase; + block = swapblk; + } + else + { +#ifdef APIBUS + cmdblk[7] = udata.u_count >> 9; +#else + cmdblk[4] = udata.u_count >> 9; +#endif + dlen = udata.u_count; + dptr = udata.u_base; + block = udata.u_offset >> BUFSIZELOG; /* Nick .o_blkno; */ + } + } + else + { +#ifdef APIBUS + cmdblk[7] = 1; +#else + cmdblk[4] = 1; +#endif + dlen = 512; + dptr = udata.u_buf->bf_data; + block = udata.u_buf->bf_blk; + } + + switch (minor) /* Also need to insure that ending + block # is valid on drive. HFB + */ + { + case 0: hd_offset = HD0_Start; +#ifdef APIBUS + if (block < HD0_Size) +#else + if (block < (HD0_Size << 4)) +#endif + goto setCDB; + else break; + case 1: hd_offset = HD1_Start; +#ifdef APIBUS + if (block < HD1_Size) +#else + if (block < (HD1_Size << 4)) +#endif + goto setCDB; + else break; + case 2: hd_offset = SWAP_Start; +#ifdef APIBUS + if (block < SWAP_Size) +#else + if (block < (SWAP_Size << 4)) +#endif + goto setCDB; + else break; + default: ; + } + udata.u_error = ENXIO; + return (1); + +setCDB: +#ifdef APIBUS + hd_sector = block; +#else + cmdblk[3] = block; + cmdblk[2] = block >> 8; + cmdblk[1] = LUN << 5; +#endif + return (0); +} + +/* Check results of operation returning (int)"stat". + * rdflag = 1 for Read, 0 for Write. + */ +void chkstat(int stat, int rdflag) +{ + if (stat) + { + kprintf ("HD %s failure stat: %x", rdflag ? "Read": "Write", stat); + panic (""); + } +} + +int wd_open(uchar minor) +{ + return (0); +} + diff --git a/src/kernel/uzi/devhd.h b/src/kernel/uzi/devhd.h new file mode 100755 index 00000000..56edaabd --- /dev/null +++ b/src/kernel/uzi/devhd.h @@ -0,0 +1,13 @@ +/* devhd.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __DEVHD_H +#define __DEVHD_H + +int wd_read(uchar minor, uchar rawflag); +int wd_write(uchar minor, uchar rawflag); +int setup(uchar minor, uchar rawflag); +void chkstat(int stat, int rdflag); +int wd_open(uchar minor); + +#endif /* __DEVHD_H */ + diff --git a/src/kernel/uzi/devio.c b/src/kernel/uzi/devio.c new file mode 100755 index 00000000..703bf291 --- /dev/null +++ b/src/kernel/uzi/devio.c @@ -0,0 +1,577 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + Buffer pool management and generic device I/O routines +**********************************************************/ + +#define __DEVIO__COMPILATION +#define NEED__DEVIO +#define NEED__MACHDEP +#define NEED__PROCESS + +#if 1 /* Nick */ +#define DEVIO /* creates the dev_tab array */ +#include "vendor.h" /* Nick, must come first */ +#include +#include /* prototypes added by Nick (must come before config.h!) */ +#include /* prototypes added by Nick (must come before config.h!) */ +#include /* prototypes added by Nick (must come before config.h!) */ +#include /* prototypes added by Nick (must come before config.h!) */ +#include +#include +#define __KERNEL__ /* temporary */ +#else +#include "uzix.h" +#ifdef SEPH +#include "types.h" +#include "signal.h" +#include "errno.h" +#include "sys\ioctl.h" +#endif +#include "unix.h" +#include "extern.h" +#include "config.h" +#endif + +extern char *baddevmsg; + +/* Buffer pool management and generic device I/O */ + +/* The high-level interface is through bread() and bfree(). + * + * Bread() is given a device and block number, and a rewrite flag. + * If rewrite is 0, the block is actually read if it is not already + * in the buffer pool. If rewrite is set, it is assumed that the caller + * plans to rewrite the entire contents of the block, and it will + * not be read in, but only have a buffer named after it. Also if + * rewrite great then 1 bread() zeroes allocated buffer. + * + * Bfree() is given a buffer pointer and a dirty flag. + * The dirty flag ored with buffer bf_dirty and if result is 0, the buffer + * is made available for further use, else the buffer is marked "dirty", and + * it will eventually be written out to disk. If the flag is 2, the buffer + * will be immediately written out to disk. + * + * Zerobuf() returns a buffer of zeroes not belonging to any device. + * It must be bfree'd after use, and must not be dirty. + * It is used when a read() wants to read an unallocated block of a file. + * + * Bufsync() write outs all dirty blocks (exclude ones with bf_prio set!) + * + * Note that a pointer to a buffer structure is the same as a + * pointer to the data. This is very important. + */ + +bufptr freebuf(uchar waitfor); + +uint bufclock = 0; /* Time-stamp counter for LRU */ + +#if DEBUG > 0 +uint buf_hits; /* buffer pool hits */ +uint buf_miss; /* buffer pool misses */ +uint buf_flsh; /* buffer pool flushes */ +#endif + +/* read block blk from device dev, return buffer with this block */ +void *bread(dev_t dev, blkno_t blk, uchar rewrite) +{ + register bufptr bp = bufpool; + +#if 1 /* Nick */ + if (bp = bfind(dev, blk)) + { + if (bp->bf_busy) + panic("want busy block %d, device %d", blk, dev); +#if DEBUG > 0 + ++buf_hits; +#endif +#if DEBUG > 10 + if (bp->bf_dev == 0 && bp->bf_blk == 222) + { + kprintf("chit 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + } +#endif + goto Done; + } +#else + /* find this block in buffer pool */ + while (bp < bufpool+NBUFS) { + if (bp->bf_dev == dev && bp->bf_blk == blk) { + if (bp->bf_busy) /* ??? */ + panic("want busy block %d at dev %d",blk,dev); +#if DEBUG > 0 + ++buf_hits; +#endif + goto Done; + } + ++bp; + } +#endif +#if DEBUG > 0 + ++buf_miss; +#endif + /* block not found in pool - allocate free buffer for them */ + if ((bp = freebuf(1)) == NULL) goto Err; + bp->bf_dev = dev; + bp->bf_blk = blk; + /* If rewrite is set, we are about to write over the entire block, + * so we don't need the previous contents + */ + if (rewrite == 0) { /* we must read block data */ + if (bdread(bp) < 0) { /* device can define the error */ + if (udata.u_error == 0) + udata.u_error = EIO; +Err: return NULL; + } +#if DEBUG > 10 + if (bp->bf_dev == 0 && bp->bf_blk == 222) + { + kprintf("read 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + } +#endif + } +Done: if (rewrite > 1) /* we need really zeroed block */ + { + bzero(bp->bf_data, BUFSIZE); +#if DEBUG > 10 + if (bp->bf_dev == 0 && bp->bf_blk == 222) + { + kprintf("zero 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + } +#endif + } + bp->bf_busy++; /* was always zero */ + bp->bf_time = ++bufclock; /* Time stamp it */ + return (bp->bf_data); +} + +/* free not needed now buffer */ +int bfree(bufptr bp, uchar dirty) +{ + bp->bf_dirty |= dirty; + bp->bf_busy = 0; + if (bp->bf_dirty && bp->bf_dev == NULLDEV) + panic("attempt to write-back zerobuf"); +#if 1 /* Nick */ + /* dirty_mask logic is now handled by i_sync() and wr_inode() */ + if (bp->bf_dirty >= 2) { /* Extra dirty */ +#else + if (bp->bf_dirty >= 2 && !dirty_mask) { /* Extra dirty */ +#endif +#if DEBUG > 10 + if (bp->bf_dev == 0 && bp->bf_blk == 222) + { + kprintf("wri2 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + } +#endif + if (bdwrite(bp) < 0) { + udata.u_error = EIO; + return (-1); + } + bp->bf_prio = bp->bf_dirty = 0; + } +#if DEBUG > 10 + else + { + if (bp->bf_dev == 0 && bp->bf_blk == 222) + { + kprintf("free 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + } + } +#endif + if (!bp->bf_prio) + wakeup(bufpool); + return 0; +} + +/* Returns a free zeroed buffer with no associated device. + * It is essentially a malloc for the kernel. Free it with brelse(). + * This procedure able to return NULL only if waitfor==0 + */ +void *zerobuf(uchar waitfor) +{ + static int blk = 0; + register bufptr bp = freebuf(waitfor); + + if (bp) { + bp->bf_dev = NULLDEV; + bp->bf_blk = ++blk; + bp->bf_busy = 1; + bp->bf_time = ++bufclock; + bzero(bp->bf_data, BUFSIZE); + return bp->bf_data; + } + return NULL; +} + +/* flush all dirty buffers (except ones with bf_prio set) */ +void bufsync(void) +{ + register bufptr bp = bufpool; + +#if 0 + /* dirty_mask logic is now handled by i_sync() and wr_inode() */ + dirty_mask = 0; +#endif + while (bp < bufpool+NBUFS) { + if (bp->bf_dev != NULLDEV && + bp->bf_dirty && + !bp->bf_prio) { +#if DEBUG > 10 + if (bp->bf_dev == 0 && bp->bf_blk == 222) + { + kprintf("sync 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + } +#endif + if (!bdwrite(bp)) + bp->bf_dirty = 0; + } + ++bp; + } +} + +#if 1 /* Nick */ +bufptr bfind(int dev, blkno_t blk) +{ + register bufptr bp; + +#if DEBUG > 1 + kprintf("bfind(%u, %u) starting\n", dev, blk); +#endif + + for (bp=bufpool; bp < bufpool+NBUFS; ++bp) + { + if (bp->bf_dev == dev && bp->bf_blk == blk) + { +#if DEBUG > 1 + kprintf("bfind() returning %d, found\n", bp - bufpool); +#endif + return (bp); + } + } +#if DEBUG > 1 + kprintf("bfind() returning NULL, not found\n"); +#endif + return (NULL); +} +#endif + +/* find free buffer in pool or freeing oldest + * This procedure able to return NULL only if waifor==0 + */ +bufptr freebuf(uchar waitfor) +{ + uchar i; + uint diff; + register bufptr bp; + register bufptr oldest = NULL; + register uint oldtime = 0; + + /* Try to find a non-busy buffer and + * write out the data if it is dirty + */ + for (;;) { + i = 1; + while (oldest == NULL) { + /* pass 1 - try to find non dirty buffer */ + /* pass 0 - try to find any buffer */ + bp = bufpool; + while (bp < bufpool+NBUFS) { + if (!bp->bf_busy && !bp->bf_prio && + !(bp->bf_dirty & i)) { + diff = bufclock - bp->bf_time; + if (diff >= oldtime) { + oldest = bp; + oldtime = diff; + } + } + ++bp; + } + i ^= 1; + } + if (oldest) /* buffer found */ + break; + if (!waitfor) + goto Err; + psleep(bufpool); /* wait for buffer */ + } + if (oldest->bf_dirty) { +#if 1 /* Nick */ + if (oldest->bf_dev == NULLDEV) + panic("attempt to write-back zerobuf"); +#endif +#if DEBUG > 0 + ++buf_flsh; +#endif +#if DEBUG > 10 + if (bp->bf_dev == 0 && bp->bf_blk == 222) + { + kprintf("wri1 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + } +#endif + if (bdwrite(oldest) < 0) { + udata.u_error = EIO; +Err: return NULL; + } + oldest->bf_dirty = 0; + } +#if DEBUG > 10 + else + { + if (bp->bf_dev == 0 && bp->bf_blk == 222) + { + kprintf("toss 0x%04x 0x%02x\n", bp, bp->bf_data[0x3f]); + } + } +#endif + return oldest; +} + +#if DEBUG > 0 +/* dump buffers info for debug */ +void bufdump(void) +{ + register bufptr bp = bufpool; + + kprintf("Buf hits/miss/flsh: %u/%u/%u\nBuffs:\tdev\tblock\tDBP\ttime\t(clock=%d)\n", + buf_hits, buf_miss, buf_flsh, bufclock); + while (bp < bufpool+NBUFS) { + kprintf("\t%p\t%u\t%c%c%c\t%u\n", + bp->bf_dev, bp->bf_blk, + bp->bf_dirty ? 'd' : '-', + bp->bf_busy ? 'b' : '-', + bp->bf_prio ? 'p' : '-', + bp->bf_time); + ++bp; + } + buf_miss = buf_hits = buf_flsh = 0; +} +#endif + +/* validate device number */ +devsw_t *validdev(dev_t dev, char *msg) +{ + register devsw_t *t = &dev_tab[MAJOR(dev)]; + + if (MAJOR(dev) < DEV_TAB && MINOR(dev) < t->minors) + return t; + if (msg != NULL) + panic(baddevmsg, msg, MAJOR(dev)); + udata.u_error = ENODEV; + return NULL; +} + +/* Bdread() and bdwrite() are the block device interface routines. + * They are given a buffer pointer, which contains the device, + * block number, and data location. + * They basically validate the device and vector the call. + * + * Cdread() and cdwrite() are the same for character (or "raw") devices, + * and are handed a device number. + * + * Udata.u_base, count, and offset have the rest of the data. + * + * The device driver read and write routines now have only two arguments, + * minor and rawflag. If rawflag is zero, a single block is desired, and + * the necessary data can be found in udata.u_buf. + * Otherwise, a "raw" or character read is desired, and udata.u_offset, + * udata.u_count, and udata.u_base should be consulted instead. + * + * Any device other than a disk will have only raw access. + */ + +/* block device read/write */ +int bdreadwrite(bufptr bp, uchar write) +{ + register dev_t dev = bp->bf_dev; + register devsw_t *dt = validdev(dev, !write ? "bdread" : "bdwrite"); + + udata.u_buf = bp; + if (write) + return (dt->dev_write)(MINOR(dev), 0); + return (dt->dev_read)(MINOR(dev), 0); +} + +/* character device read */ +int cdreadwrite(dev_t dev, uchar write) +{ + register devsw_t *dt = validdev(dev, !write ? "cdread" : "cdwrite"); + + if (write) + return (dt->dev_write)(MINOR(dev), 1); + return (dt->dev_read)(MINOR(dev), 1); +} + +int d_openclose(dev_t dev, uchar open) +{ + register devsw_t *dt = validdev(dev, open ? NULL : "d_close"); + + if (dt == NULL) + return (-1); + if (open) + return (dt->dev_open)(MINOR(dev)); + return (dt->dev_close)(MINOR(dev)); +} + +/* generic device ioctl */ +int d_ioctl(dev_t dev, int request, void *data) +{ + register devsw_t *dt = validdev(dev, NULL); + + if (dt == NULL) { + udata.u_error = ENXIO; + goto Err; + } + if ((dt->dev_ioctl)(MINOR(dev), request, data)) { + udata.u_error = EINVAL; +Err: return (-1); + } + return 0; +} + +/* all devices initialization */ +int d_init(void) +{ + register devsw_t *dt = dev_tab; + uchar minor; + + while (dt < dev_tab+DEV_TAB) { + minor = 0; + while (minor < dt->minors) { + if ((dt->dev_init)(minor) != 0) + return -1; + ++minor; + } + ++dt; + } + return 0; +} + +/* special filler for driver functions, which do nothing */ +int ok(uchar minor) +{ + /* NOTUSED(minor); */ + return 0; +} + +/* special filler for driver read/write functions, which do nothing */ +int ok_rdwr(uchar minor, uchar rawflag) +{ + /* NOTUSED(minor); */ + /* NOTUSED(rawflag); */ + return 0; +} + +/* special filler for driver functions, which return error */ +int nogood(uchar minor) +{ + /* NOTUSED(minor); */ + return -1; +} + +/* special filler for driver ioctl functions, which return error */ +int nogood_ioctl(uchar minor, int req, void *data) +{ + /* NOTUSED(minor); */ + /* NOTUSED(req); */ + /* NOTUSED(data); */ + return -1; +} + +#ifdef __KERNEL__ +/* + * Character queue management routines + */ + +/* add something to the queue tail */ +int insq(queue_t *q, uchar c) +{ + uchar retval = 0; + + di_absolute(); + if (q->q_count != q->q_size) { /* queue not full */ + *(q->q_tail) = c; /* save char */ + ++q->q_count; /* count them */ + if (++q->q_tail >= q->q_base + q->q_size) + q->q_tail = q->q_base; /* process pointer rollover */ + ++retval; + } + ei_absolute(); + return retval; +} + +/* Remove something from the queue head */ +int remq(queue_t *q, uchar *cp) +{ + uchar retval = 0; + + di_absolute(); + if (q->q_count != 0) { + *cp = *(q->q_head); /* get char from queue */ + --q->q_count; /* count them */ + if (++q->q_head >= q->q_base + q->q_size) + q->q_head = q->q_base; /* process pointer rollover */ + ++retval; + } + ei_absolute(); + return retval; +} + +/* Remove something from the tail; the most recently added char. */ +int uninsq(queue_t *q, uchar *cp) +{ + uchar retval = 0; + + di_absolute(); + if (q->q_count != 0) { + --q->q_count; /* count removed char */ + if (--q->q_tail < q->q_base) + q->q_tail = q->q_base + q->q_size - 1; + *cp = *(q->q_tail); /* save removed char */ + ++retval; + } + ei_absolute(); + return retval; +} + +/* Clear queue. */ +void clrq(queue_t *q) +{ + di_absolute(); + q->q_count = 0; + q->q_tail = q->q_base; + q->q_head = q->q_base; + ei_absolute(); +} + +#if 0 +/* Returns true if the queue has more characters than its wakeup number */ +/* not used now */ +int fullq(queue_t *q) +{ + uchar s; + + di_absolute(); + s = q->q_count > q->q_wakeup; + ei_absolute(); + return s; +} +#endif +#endif /* __KERNEL__ */ + diff --git a/src/kernel/uzi/devio.c$ b/src/kernel/uzi/devio.c$ new file mode 100755 index 00000000..0c4176ea --- /dev/null +++ b/src/kernel/uzi/devio.c$ @@ -0,0 +1,499 @@ +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: devio.c +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + */ + +int ok(), nogood(); +#define DEVIO + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include /* prototypes added by Nick */ + +/* Buffer pool management */ +/********************************************************************* +The high-level interface is through bread() and bfree(). +Bread() is given a device and block number, and a rewrite flag. If +rewrite is 0, the block is actually read if it is not already in the +buffer pool. If rewrite is set, it is assumed that the caller plans to +rewrite the entire contents of the block, and it will not be read in, +but only have a buffer named after it. + +Bfree() is given a buffer pointer and a dirty flag. If the dirty flag +is 0, the buffer is made available for further use. If the flag is 1, +the buffer is marked "dirty", and it will eventually be written out to +disk. If the flag is 2, it will be immediately written out. + +Zerobuf() returns a buffer of zeroes not belonging to any device. It +must be bfree'd after use, and must not be dirty. It is used when a +read() wants to read an unallocated block of a file. + +Bufsync() write outs all dirty blocks. + +Note that a pointer to a buffer structure is the same as a pointer to +the data. This is very important. +**********************************************************************/ + +uint16 bufclock = 0; /* Time-stamp counter for LRU */ + +char *bread(int dev, blkno_t blk, int rewrite) +{ + register bufptr bp; + bufptr bfind(); + bufptr freebuf(); + int bdread(); + +#if DEBUG > 1 + kprintf("bread(%u, %u, %u) starting\n", dev, blk, rewrite); +#endif + + if (bp = bfind (dev, blk)) + { + if (bp->bf_busy) + panic ("want busy block %d, device %d", blk, dev); + goto done; + } + bp = freebuf(); + bp->bf_dev = dev; + bp->bf_blk = blk; + + /* If rewrite is set, we are about to write over the entire block, + so we don't need the previous contents */ + + ifnot (rewrite) + if (bdread (bp) == -1) + { + udata.u_error = EIO; +#if DEBUG > 1 + kprintf("bread() returning NULL, error %u\n", udata.u_error); +#endif + return (NULL); + } + +#if 1 /* reinstated by Nick due to the UZIX bmap() function which needs it */ +done: + if (rewrite > 1) /* == 2) */ + bzero (bp->bf_data, 512); +#else +done: +#endif + bp->bf_busy = 1; + bp->bf_time = ++bufclock; /* Time stamp it */ +#if DEBUG > 1 + kprintf("bread() returning %u, success\n", bp - bufpool); +#endif + return (bp->bf_data); +} + + + +int brelse(bufptr bp) +{ + return bfree(bp, 0); +} + + +int bawrite(bufptr bp) +{ + return bfree(bp, 1); +} + + + +int bfree(bufptr bp, int dirty) +{ + int bdwrite(); + +#if DEBUG > 1 + kprintf("bfree(%u, %u) starting\n", bp - bufpool, dirty); +#endif + + bp->bf_dirty |= dirty; + bp->bf_busy = 0; + + if (dirty == 2) /* Extra dirty */ + { + if (bdwrite (bp) == -1) +#if 1 + { + udata.u_error = EIO; +#if DEBUG > 1 + kprintf("bfree() returning -1, error %u\n", udata.u_error); +#endif + return -1; + } + bp->bf_dirty = 0; +#else + udata.u_error = EIO; + bp->bf_dirty = 0; + return (-1); +#endif + } +#if DEBUG > 1 + kprintf("bfree() returning 0, success\n"); +#endif + return (0); +} + + +/* This returns a busy block not belonging to any device, with + * garbage contents. It is essentially a malloc for the kernel. + * Free it with brelse()! + */ +char *tmpbuf(void) +{ + bufptr bp; + bufptr freebuf(); + + bp = freebuf(); + bp->bf_dev = -1; + bp->bf_busy = 1; + bp->bf_time = ++bufclock; /* Time stamp it */ + return (bp->bf_data); +} + + +char *zerobuf(void) +{ + char *b; + char *tmpbuf(); + + b = tmpbuf(); + bzero (b, 512); + return (b); +} + + +void bufsync(void) +{ + register bufptr bp; + + for (bp=bufpool; bp < bufpool+NBUFS; ++bp) + { + if (bp->bf_dev != -1 && bp->bf_dirty) + { + bdwrite (bp); + if (!bp->bf_busy) + bp->bf_dirty = 0; + } + } +} + +#ifndef ASM_BUFIO + +bufptr bfind(int dev, blkno_t blk) +{ + register bufptr bp; + +#if DEBUG > 1 + kprintf("bfind(%u, %u) starting\n", dev, blk); +#endif + + for (bp=bufpool; bp < bufpool+NBUFS; ++bp) + { + if (bp->bf_dev == dev && bp->bf_blk == blk) + { +#if DEBUG > 1 + kprintf("bfind() returning %d, found\n", bp - bufpool); +#endif + return (bp); + } + } +#if DEBUG > 1 + kprintf("bfind() returning NULL, not found\n"); +#endif + return (NULL); +} + + +bufptr freebuf(void) +{ + register bufptr bp; + register bufptr oldest; + register int oldtime; + int bdwrite(); + +#if DEBUG > 1 + kprintf("freebuf() starting\n"); +#endif + + /* Try to find a non-busy buffer and write out the data if it is dirty */ + oldest = NULL; + oldtime = 0; + for (bp=bufpool; bp < bufpool+NBUFS; ++bp) + { + if (bufclock - bp->bf_time >= oldtime && !bp->bf_busy) + { + oldest = bp; + oldtime = bufclock - bp->bf_time; + } + } + ifnot (oldest) + panic ("no free buffers"); + + if (oldest->bf_dirty) + { + if (bdwrite (oldest) == -1) + udata.u_error = EIO; + oldest->bf_dirty = 0; + } +#if DEBUG > 1 + kprintf("freebuf() returning %d, found\n", oldest - bufpool); +#endif + return (oldest); +} + +#endif + + +void bufinit(void) +{ + register bufptr bp; + + for (bp=bufpool; bp < bufpool+NBUFS; ++bp) + { + bp->bf_dev = -1; + } +} + + +void bufdump(void) +{ + register bufptr j; + + kprintf ("\ndev\tblock\tdirty\tbusy\ttime clock %d\n", bufclock); + for (j=bufpool; j < bufpool+NBUFS; ++j) + kprintf ("%d\t%u\t%d\t%d\t%u\n", + j->bf_dev,j->bf_blk,j->bf_dirty,j->bf_busy,j->bf_time); +} + + +/********************************************************************* +Bdread() and bdwrite() are the block device interface routines. they +are given a buffer pointer, which contains the device, block number, +and data location. They basically validate the device and vector the +call. + +Cdread() and cdwrite are the same for character (or "raw") devices, +and are handed a device number. Udata.u_base, count, and offset have +the rest of the data. +**********************************************************************/ + +int bdread(bufptr bp) +{ + int validdev(); + + ifnot (validdev (bp->bf_dev)) + panic ("bdread: invalid dev"); + + udata.u_buf = bp; + return ((*dev_tab[bp->bf_dev].dev_read)(dev_tab[bp->bf_dev].minor, 0)); +} + + +int bdwrite(bufptr bp) +{ + int validdev(); + + ifnot (validdev (bp->bf_dev)) + panic ("bdwrite: invalid dev"); + + udata.u_buf = bp; + return ((*dev_tab[bp->bf_dev].dev_write)(dev_tab[bp->bf_dev].minor, 0)); +} + + +int cdread(int dev) +{ + int validdev(); + + ifnot (validdev (dev)) + panic ("cdread: invalid dev"); + return ((*dev_tab[dev].dev_read)(dev_tab[dev].minor, 1)); +} + + +int cdwrite(int dev) +{ + int validdev(); + + ifnot (validdev (dev)) + panic ("cdwrite: invalid dev"); + return ((*dev_tab[dev].dev_write)(dev_tab[dev].minor, 1)); +} + + +int swapread(int dev, blkno_t blkno, unsigned nbytes, char *buf) +{ + swapbase = buf; + swapcnt = nbytes; + swapblk = blkno; + return ((*dev_tab[dev].dev_read)(dev_tab[dev].minor, 2)); +} + + +int swapwrite(int dev, blkno_t blkno, unsigned nbytes, char *buf) +{ + swapbase = buf; + swapcnt = nbytes; + swapblk = blkno; + return ((*dev_tab[dev].dev_write)(dev_tab[dev].minor, 2)); +} + + +/********************************************************************* +The device driver read and write routines now have only two arguments, +minor and rawflag. If rawflag is zero, a single block is desired, and +the necessary data can be found in udata.u_buf. Otherwise, a "raw" or +character read is desired, and udata.u_offset, udata.u_count, and +udata.u_base should be consulted instead. +Any device other than a disk will have only raw access. +**********************************************************************/ + +int d_open(int dev) +{ + int validdev(); + + ifnot (validdev (dev)) + return (-1); + return ((*dev_tab[dev].dev_open)(dev_tab[dev].minor)); +} + + +int d_close(int dev) +{ + int validdev(); + + ifnot (validdev (dev)) + panic ("d_close: bad device"); + (*dev_tab[dev].dev_close)(dev_tab[dev].minor); +} + + +int d_ioctl(int dev, int request, char *data) +{ + int validdev(); + + ifnot (validdev (dev)) + { + udata.u_error = ENXIO; + return (-1); + } + if ((*dev_tab[dev].dev_ioctl)(dev_tab[dev].minor,request,data)) + { + udata.u_error = EINVAL; + return (-1); + } + return (0); +} + + +int ok(void) +{ + return (0); +} + + +int nogood(void) +{ + return (-1); +} + + +int validdev(int dev) +{ +/* kprintf("validating device 0x%x\n", dev); */ + return (dev >= 0 && dev < (sizeof(dev_tab)/sizeof(struct devsw))); +} + + +/********************************************************************* + Character queue management routines +**********************************************************************/ + +/* add something to the tail of the queue. + */ +int insq (struct s_queue *q, char c) +{ + di(); + if (q->q_count == q->q_size) + { + ei(); + return (0); + } + *(q->q_tail) = c; + ++q->q_count; + if (++q->q_tail >= q->q_base + q->q_size) + q->q_tail = q->q_base; + ei(); + return (1); +} + + +/* Remove something from the head of the queue. + */ +int remq(struct s_queue *q, char *cp) +{ + di(); + ifnot (q->q_count) + { + ei(); + return (0); + } + *cp = *(q->q_head); + --q->q_count; + if (++q->q_head >= q->q_base + q->q_size) + q->q_head = q->q_base; + ei(); + return (1); +} + + +/* Clear the queue to empty conditions. (UZI280 addition) + */ +void clrq(struct s_queue *q) +{ + q->q_head = q->q_tail = q->q_base; + q->q_count = 0; +} + + +/* Remove something from the tail; the most recently added char. + */ +int uninsq (struct s_queue *q, char *cp) +{ + di(); + ifnot (q->q_count) + { + ei(); + return (0); + } + --q->q_count; + if (--q->q_tail < q->q_base) + q->q_tail = q->q_base + q->q_size - 1; + *cp = *(q->q_tail); + ei(); + return (1); +} + + +/* Returns true if the queue has more characters than its wakeup number + */ +int fullq(struct s_queue *q) +{ + di(); + if (q->q_count > q->q_wakeup) + { + ei(); + return (1); + } + ei(); + return (0); +} diff --git a/src/kernel/uzi/devio.h b/src/kernel/uzi/devio.h new file mode 100755 index 00000000..597bfe69 --- /dev/null +++ b/src/kernel/uzi/devio.h @@ -0,0 +1,38 @@ +/* devio.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __DEVIO_H +#define __DEVIO_H + +void *bread(dev_t dev, blkno_t blk, uchar rewrite); +int bfree(bufptr bp, uchar dirty); +void *zerobuf(uchar waitfor); +void bufsync(void); +#if 1 /* Nick */ +bufptr bfind(int dev, blkno_t blk); +#endif +bufptr freebuf(uchar waitfor); +#if DEBUG > 0 +void bufdump(void); +#endif +devsw_t *validdev(dev_t dev, char *msg); +int bdreadwrite(bufptr bp, uchar write); +int cdreadwrite(dev_t dev, uchar write); +int d_openclose(dev_t dev, uchar open); +int d_ioctl(dev_t dev, int request, void *data); +int d_init(void); +int ok(uchar minor); +int ok_rdwr(uchar minor, uchar rawflag); +int nogood(uchar minor); +int nogood_ioctl(uchar minor, int req, void *data); +#if 1 /* def __KERNEL__ */ +int insq(queue_t *q, uchar c); +int remq(queue_t *q, uchar *cp); +int uninsq(queue_t *q, uchar *cp); +void clrq(queue_t *q); +#if 0 +int fullq(queue_t *q); +#endif +#endif + +#endif /* __DEVIO_H */ + diff --git a/src/kernel/uzi/devio.h$ b/src/kernel/uzi/devio.h$ new file mode 100755 index 00000000..a4872cae --- /dev/null +++ b/src/kernel/uzi/devio.h$ @@ -0,0 +1,36 @@ +/* devio.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __DEVIO_H +#define __DEVIO_H + +char *bread(int dev, blkno_t blk, int rewrite); +int brelse(bufptr bp); +int bawrite(bufptr bp); +int bfree(bufptr bp, int dirty); +char *tmpbuf(void); +char *zerobuf(void); +void bufsync(void); +bufptr bfind(int dev, blkno_t blk); +bufptr freebuf(void); +void bufinit(void); +void bufdump(void); +int bdread(bufptr bp); +int bdwrite(bufptr bp); +int cdread(int dev); +int cdwrite(int dev); +int swapread(int dev, blkno_t blkno, unsigned nbytes, char *buf); +int swapwrite(int dev, blkno_t blkno, unsigned nbytes, char *buf); +int d_open(int dev); +int d_close(int dev); +int d_ioctl(int dev, int request, char *data); +int ok(void); +int nogood(void); +int validdev(int dev); +int insq (struct s_queue *q, char c); +int remq(struct s_queue *q, char *cp); +void clrq(struct s_queue *q); +int uninsq (struct s_queue *q, char *cp); +int fullq(struct s_queue *q); + +#endif /* __DEVIO_H */ + diff --git a/src/kernel/uzi/devmisc.c b/src/kernel/uzi/devmisc.c new file mode 100755 index 00000000..946148ae --- /dev/null +++ b/src/kernel/uzi/devmisc.c @@ -0,0 +1,134 @@ +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: devmisc.c +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + * 25.12.97 - lpout moved to machine-dependent module. HFB + */ + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include /* prototypes added by Nick */ + +int mem_read(uchar minor, uchar rawflag) +{ + unsigned addr; + + addr = udata.u_offset; /* Nick 512*udata.u_offset.o_blkno+udata.u_offset.o_offset; */ + + if (addr < 0x006C) + return 1; + + if (udata.u_sysio) + bcopy ((char *)addr, udata.u_base, udata.u_count); + else + uput ((char *)addr, udata.u_base, udata.u_count); + + return udata.u_count; +} + + +int mem_write(uchar minor, uchar rawflag) +{ + unsigned addr; + + addr = udata.u_offset; /* Nick 512*udata.u_offset.o_blkno+udata.u_offset.o_offset; */ + + if (addr < 0x006C) + return 1; + + if (udata.u_sysio) + bcopy (udata.u_base, (char *)addr, udata.u_count); + else + uput (udata.u_base, (char *)addr, udata.u_count); + + return udata.u_count; +} + + + +int null_write(uchar minor, uchar rawflag) +{ + return udata.u_count; +} + + + +static char lop = 0; + +int lpr_open(uchar minor) +{ + lop = 1; + return 0; +} + + +int lpr_close(uchar minor) +{ + if (lop) + { + lop = 0; +/*7Jul98 lpout('\f');**/ + } + return 0; +} + + + +int lpr_write(uchar minor, uchar rawflag) +{ + unsigned n; + unsigned char c; +/* Nick int ugetc(); */ + + n = udata.u_count; + while (n--) { + if (udata.u_sysio) + c = *udata.u_base++; + else + c = ugetc (udata.u_base++); + lpout (c); + } + return udata.u_count; +} + +/* NOTE: lpout moved to Machine-dependent Assembly Module - HFB */ + +/* #include "devmt.c" */ + +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: devmisc.c + Magnetic Tape, Unimplemented. Currently a Null Device. +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + */ + +int mt_read(uchar minor, uchar rawflag) +{ + return -1; +} + +int mt_write(uchar minor, uchar rawflag) +{ + return -1; +} + +int mt_open(uchar minor) +{ + return -1; +} + +int mt_close(uchar minor) +{ + return 0; +} + diff --git a/src/kernel/uzi/devmisc.h b/src/kernel/uzi/devmisc.h new file mode 100755 index 00000000..fb6e8c26 --- /dev/null +++ b/src/kernel/uzi/devmisc.h @@ -0,0 +1,18 @@ +/* devmisc.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __DEVMISC_H +#define __DEVMISC_H + +int mem_read(uchar minor, uchar rawflag); +int mem_write(uchar minor, uchar rawflag); +int null_write(uchar minor, uchar rawflag); +int lpr_open(uchar minor); +int lpr_close(uchar minor); +int lpr_write(uchar minor, uchar rawflag); +int mt_read(uchar minor, uchar rawflag); +int mt_write(uchar minor, uchar rawflag); +int mt_open(uchar minor); +int mt_close(uchar minor); + +#endif /* __DEVMISC_H */ + diff --git a/src/kernel/uzi/devmt.c$ b/src/kernel/uzi/devmt.c$ new file mode 100755 index 00000000..1ad87af0 --- /dev/null +++ b/src/kernel/uzi/devmt.c$ @@ -0,0 +1,38 @@ +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: devmisc.c + Magnetic Tape, Unimplemented. Currently a Null Device. +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + */ + + +mt_read (minor, rawflag) +int minor; +int rawflag; +{ + return (-1); +} + + +mt_write (minor, rawflag) +int minor; +int rawflag; +{ + return (-1); +} + + +mt_open() +{ + return (-1); +} + + +mt_close() +{ + return (0); +} diff --git a/src/kernel/uzi/devtty.c b/src/kernel/uzi/devtty.c new file mode 100755 index 00000000..0513ec19 --- /dev/null +++ b/src/kernel/uzi/devtty.c @@ -0,0 +1,502 @@ +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: devtty.c +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + * 22.12.97 - Moved __putc & tty_int to MACHASM.ASZ. HFB + * 24.05.98 - Restructured tty_inproc, parse CTRL chars + * based on flag set bit (deletes CPM_CTRL in 280), add + * equate for Number of TTY terminals. HFB + */ + +#if 0 /* Nick */ +#define DEBUG /* UNdefine to delete debug code sequences */ + +#define NTTYS 9 /* 2 */ /* Number of TTY ports defined */ +#endif + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include "devtty.h" /* prototypes added by Nick */ + +struct s_tty_data tty_data[NTTYS+1]; /* tty_data[0] is not used */ + +struct s_tty_data tty_default = + { + 0, 0, '\b', CTRL('x'), DFLT_MODE, + CTRL('c'), CTRL('\\'), CTRL('q'), CTRL('s'), CTRL('d'), 0 + }; + +#if 1 /* Nick */ +void (*tty_vector[NTTYS+1])(int minor, char c) = + { + tty_inproc_dummy, /* this entry is never used */ + tty_inproc_dummy, + tty_inproc_dummy, + tty_inproc_dummy, + tty_inproc_dummy, + tty_inproc_dummy, + tty_inproc_dummy, + tty_inproc_dummy, + tty_inproc_dummy, + tty_inproc_dummy + }; + +extern char xmit_bufs[PORTS][XMIT_SIZE]; +extern char recv_bufs[PORTS][RECV_SIZE]; + +struct s_queue ttyinq[NTTYS+1] = + { + { NULL, NULL, NULL, 0, 0, 0 }, /* this entry is never used */ + { recv_bufs[0], recv_bufs[0], recv_bufs[0], TTYSIZ, 0, TTYSIZ/2 }, + { recv_bufs[1], recv_bufs[1], recv_bufs[1], TTYSIZ, 0, TTYSIZ/2 }, + { recv_bufs[2], recv_bufs[2], recv_bufs[2], TTYSIZ, 0, TTYSIZ/2 }, + { recv_bufs[3], recv_bufs[3], recv_bufs[3], TTYSIZ, 0, TTYSIZ/2 }, + { recv_bufs[4], recv_bufs[4], recv_bufs[4], TTYSIZ, 0, TTYSIZ/2 }, + { recv_bufs[5], recv_bufs[5], recv_bufs[5], TTYSIZ, 0, TTYSIZ/2 }, + { recv_bufs[6], recv_bufs[6], recv_bufs[6], TTYSIZ, 0, TTYSIZ/2 }, + { recv_bufs[7], recv_bufs[7], recv_bufs[7], TTYSIZ, 0, TTYSIZ/2 }, + { recv_bufs[8], recv_bufs[8], recv_bufs[8], TTYSIZ, 0, TTYSIZ/2 } + }; +#else +/* Character Input Queue size */ +#define TTYSIZ 132 + +char tbuf1[TTYSIZ]; +char tbuf2[TTYSIZ]; + +struct s_queue ttyinq[NTTYS+1] = { /* ttyinq[0] is never used */ +{ NULL, NULL, NULL, 0, 0, 0 }, +{ tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ/2 }, +{ tbuf2, tbuf2, tbuf2, TTYSIZ, 0, TTYSIZ/2 } +}; +#endif + +int stopflag[NTTYS+1]; /* Flag for ^S/^Q */ +int flshflag[NTTYS+1]; /* Flag for ^O */ + +int tty_read(uchar minor, uchar rawflag) +{ + int nread; + char c; + int remq(); + +#if DEBUG > 1 + kprintf("tty_read(%d, %d) starting\n", minor, rawflag); +#endif + + /* Minor == 0 means that it is the controlling tty of the process */ + ifnot (minor) + minor = udata.u_ptab->p_tty; + ifnot (udata.u_ptab->p_tty) + udata.u_ptab->p_tty = minor; + + if ((minor < 1) || (minor > NTTYS+1)) { + udata.u_error = ENODEV; +#if DEBUG > 1 + kprintf("tty_read() returning -1, error %d\n", udata.u_error); +#endif + return (-1); + } + + nread = 0; + while (nread < udata.u_count) + { + for (;;) + { + di_absolute(); /* Nick */ + if (remq (&ttyinq[minor], &c)) { +#if 1 /* Nick */ + ei_absolute(); /* Nick */ +#endif + if (udata.u_sysio) + *udata.u_base = c; + else + uputc (c, udata.u_base); + break; + } +#if 1 /* Nick */ + ei_absolute(); +#endif +#if 1 /* Nick */ + /* In unbuffered mode, don't wait when no input */ + if (tty_data[minor].t_flags & UNBUFF) + { +#if DEBUG > 1 + kprintf("tty_read() returning %d, success\n", nread); +#endif + return(nread); + } +#endif +#if 1 /* Nick, original uzi code, it can be handy to disable this sometimes */ + psleep (&ttyinq[minor]); + if (udata.u_cursig || udata.u_ptab->p_pending) { /* messy */ + udata.u_error = EINTR; +#if DEBUG > 1 + kprintf("tty_read() returning -1, error %d\n", udata.u_error); +#endif + return (-1); + } +#endif + } +#if 0 /* Nick, removed as this is now done immediately after calling remq */ + ei_absolute(); /* Nick */ +#endif + if ((nread++ == 0) && (c == tty_data[minor].t_eof)) /* ^D */ + { +#if DEBUG > 1 + kprintf("tty_read() returning 0, eof\n"); +#endif + return(0); + } + + /* In raw or cbreak mode, return after one char */ +#if 1 /* Nick */ + if ((tty_data[minor].t_flags & UNBUFF) == 0 && + (c == '\n' || tty_data[minor].t_flags & (RAW|CBREAK))) + { + break; + } +#else + if (tty_data[minor].t_flags & (RAW|CBREAK)) + break; + if (c == '\n') + break; +#endif + ++udata.u_base; + } +#if DEBUG > 1 + kprintf("tty_read() returning %d, success\n", nread); +#endif + return(nread); +} + + + +int tty_write(uchar minor, uchar rawflag) +{ + int towrite, c; +/* Nick int ugetc(); */ + + /* Minor == 0 means that it is the controlling tty of the process */ + ifnot (minor) + minor = udata.u_ptab->p_tty; + ifnot (udata.u_ptab->p_tty) + udata.u_ptab->p_tty = minor; + + if ((minor < 1) || (minor > NTTYS+1)) { + udata.u_error = ENODEV; + return (-1); + } + + towrite = udata.u_count; + + while (udata.u_count-- != 0) + { + for (;;) /* Wait on the ^S/^Q flag */ + { + di_absolute(); /* Nick */ + ifnot (stopflag[minor]) + break; + psleep (&stopflag[minor]); + if (udata.u_cursig || udata.u_ptab->p_pending) /* messy */ + { + udata.u_error = EINTR; + return (-1); + } + } + ei_absolute(); /* Nick */ + + ifnot (flshflag[minor]) + { + if (udata.u_sysio) + c = *udata.u_base; + else + c = ugetc (udata.u_base); + + if (c == '\n' && (tty_data[minor].t_flags & CRMOD)) + _putc (minor, '\r'); + _putc (minor, c); + } + ++udata.u_base; + } + return (towrite); +} + + + +int tty_open(uchar minor) +{ + /* Minor == 0 means that it is the controlling tty of the process */ + ifnot (minor) + minor = udata.u_ptab->p_tty; + +#if 1 /* Nick */ + if ((minor < 1) || (minor > NTTYS+1)) + { + udata.u_error = ENODEV; + return (-1); + } +#endif + + /* If there is no controlling tty for the process, establish it */ + ifnot (udata.u_ptab->p_tty) + udata.u_ptab->p_tty = minor; + + /* Initialize the tty_data */ + bcopy (&tty_default, &tty_data[minor], sizeof (struct s_tty_data)); + +#if 1 /* Nick */ + di_absolute(); + tty_vector[minor] = tty_inproc; + ei_absolute(); +#endif + + return (0); +} + + +int tty_close(uchar minor) +{ + /* If we are closing the controlling tty, make note */ + if (minor == udata.u_ptab->p_tty) + udata.u_ptab->p_tty = 0; + +#if 1 /* Nick */ + if ((minor < 1) || (minor > NTTYS+1)) + { + udata.u_error = ENODEV; + return (-1); + } +#endif + +#if 1 /* Nick */ + di_absolute(); + tty_vector[minor] = tty_inproc_dummy; + ei_absolute(); +#endif + + return (0); +} + + +/* Data in User Space */ +int tty_ioctl(uchar minor, int request, char *data) +{ + /* Minor == 0 means that it is the controlling tty of the process */ + ifnot (minor) + minor = udata.u_ptab->p_tty; + if ((minor < 1) || (minor > NTTYS+1)) { + udata.u_error = ENODEV; + return (-1); + } + switch (request) + { + case TIOCGETP: + uput (&tty_data[minor], data, 6); + break; + case TIOCSETP: + uget (data, &tty_data[minor], 6); + break; + case TIOCGETC: + uput (&tty_data[minor].t_intr, data, 5); + break; + case TIOCSETC: + uget (data, &tty_data[minor].t_intr, 5); + break; + case TIOCSETN: + uput (&ttyinq[minor].q_count, data, 2); + break; + case TIOCFLUSH: + clrq (&tty_data[minor]); + break; + case TIOCTLSET: + tty_data[minor].ctl_char = 1; + break; + case TIOCTLRES: + tty_data[minor].ctl_char = 0; + break; + default: + udata.u_error = EINVAL; + return (-1); + } + return (0); +} + + +/* This routine processes a character in response to an interrupt. It + * adds the character to the tty input queue, echoing and processing + * backspace and carriage return. If the queue contains a full line, + * it wakes up anything waiting on it. If it is totally full, it beeps + * at the user. + * UZI180 - This routine is called from the raw Hardware read routine, + * either interrupt or polled, to process the input character. HFB + */ + +void tty_inproc(int minor, char c) +{ + char oc; + struct s_tty_data *td; + int mode; + int insq(), uninsq(); + + td = &tty_data[minor]; +#if 1 /* Nick */ + if ((td->t_flags & (RAW|CBREAK|COOKED|UNBUFF)) == (RAW|UNBUFF)) + { + insq (&ttyinq[minor], c); + return; /* don't bother checking for error or waking task */ + } +#endif + mode = td->t_flags & (RAW|CBREAK|COOKED); + +/*** if (c == 0x1b && td->t_flags == DFLT_MODE) +/*** return; /* my terminal hates it SN */ + + if (mode != RAW) + { /* Nick */ + c &= 0x7f; /* Strip off parity */ + if (!c) + return; /* Simply quit if Null character */ + } /* Nick */ + + if (td->ctl_char == 0) /* Don't parse ctl chars if Non-0 */ + { + if ((mode & RAW) == 0) /* if mode == COOKED or CBREAK */ + { +#ifdef DEBUG + if (c == 0x1a) /* ^Z */ + { + idump(); /* (For debugging) */ + return; + } + else if (c == 0x0e) /* ^N Nick */ + { + traceon = !traceon; + return; + } +#endif + + if (c == '\r' && (td->t_flags & CRMOD)) + c = '\n'; + + if (c == td->t_intr) { /* ^C */ + sgrpsig (minor, SIGQUIT); + clrq (&ttyinq[minor]); + stopflag[minor] = flshflag[minor] = 0; + return; + } + else if (c == td->t_quit) { /* ^\ */ + sgrpsig (minor, SIGINT); + clrq (&ttyinq[minor]); + stopflag[minor] = flshflag[minor] = 0; + return; + } + else if (c == '\017') { /* ^O */ + flshflag[minor] = !flshflag[minor]; + return; + } + else if (c == td->t_stop) { /* ^S */ + stopflag[minor] = 1; + return; + } + else if (c == td->t_start) { /* ^Q */ + stopflag[minor] = 0; + wakeup (&stopflag[minor]); + return; + } + } + + if (mode == COOKED) + { + if (c == td->t_erase) + { + if (uninsq (&ttyinq[minor], &oc)) + { + if (oc == '\n') + insq (&ttyinq[minor], oc); /* Don't erase past nl */ + else + { + echo (minor, '\b'); + echo (minor, ' '); + echo (minor, '\b'); + } + } + return; + } + else if (c == td->t_kill) + { + while (uninsq (&ttyinq[minor], &oc)) + { + if (oc == '\n') + { + insq (&ttyinq[minor], oc); /* Don't erase past nl */ + break; + } + echo (minor, '\b'); + echo (minor, ' '); + echo (minor, '\b'); + } + return; + } + } + } + /* All modes come here */ + + if (c == '\n' && (td->t_flags & CRMOD)) + echo (minor, '\r'); + + if (insq (&ttyinq[minor], c)) + echo (minor, c); + else + _putc (minor, '\007'); /* Beep if no more room */ + + if ((mode != COOKED || c == '\n' || c == td->t_eof) + && (td->ctl_char == 0)) /* ^D */ + wakeup (&ttyinq[minor]); +/* abyte('^'); */ +/* abyte(c); */ +/* while (1) */ +/* ; */ +} + + +#if 1 /* Nick */ +void tty_inproc_dummy(int minor, char c) + { + } +#endif + + +void echo(int minor, char c) +{ + if (tty_data[minor].t_flags & ECHO) + _putc (minor, c); +} + + +#if 0 +char silly_pause(void) + { + char c; + + for (;;) + { + di_absolute(); /* Nick */ + if (remq (&ttyinq[2], &c)) + { + return c; + } +#if 1 /* Nick... very temporary!! */ + ei_absolute(); +#endif + } + } +#endif + + diff --git a/src/kernel/uzi/devtty.h b/src/kernel/uzi/devtty.h new file mode 100755 index 00000000..e02026b4 --- /dev/null +++ b/src/kernel/uzi/devtty.h @@ -0,0 +1,68 @@ +/* devtty.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __DEVTTY_H +#define __DEVTTY_H + +#define NTTYS 9 /* Number of TTY ports defined */ +#define TTYSIZ 132 /* Character Input Queue size */ + +#define PORTS 13 /* total number of serial or apibus ports */ +#define XMIT_SIZE 256 /* size of transmitter buffer */ +#define RECV_SIZE 256 /* size of reciever buffer */ + +#define TIOCGETP 0 +#define TIOCSETP 1 +#define TIOCSETN 2 +#define TIOCEXCL 3 /** currently not implemented SN **/ +#define UARTSLOW 4 /* Normal interrupt routine (UZI280) */ +#define UARTFAST 5 /* Fast interrupt routine for modem usage (UZI280) */ +#define TIOCFLUSH 6 +#define TIOCGETC 7 +#define TIOCSETC 8 + /* UZI280 extensions used by UZI180 in the CP/M 2.2 Emulator */ +#define TIOCTLSET 9 /* Don't parse ctrl-chars */ +#define TIOCTLRES 10 /* Normal Parse */ + +#define XTABS 0006000 +#define UNBUFF 0000100 /* Nick */ +#define RAW 0000040 +#define CRMOD 0000020 +#define ECHO 0000010 +#define LCASE 0000004 +#define CBREAK 0000002 +#define COOKED 0000000 + +#define DFLT_MODE RAW /* XTABS | CRMOD | ECHO | COOKED */ + +#define CTRL(c) (c & 0x1f) + +struct s_tty_data { + char t_ispeed; + char t_ospeed; + char t_erase; + char t_kill; + int t_flags; + + char t_intr; + char t_quit; + char t_start; + char t_stop; + char t_eof; + + char ctl_char; +}; + +int tty_read(uchar minor, uchar rawflag); +int tty_write(uchar minor, uchar rawflag); +int tty_open(uchar minor); +int tty_close(uchar minor); +int tty_ioctl(uchar minor, int request, char *data); +void tty_inproc(int minor, char c); +void tty_inproc_dummy(int minor, char c); +void echo(int minor, char c); + +extern struct s_tty_data tty_data[NTTYS+1]; /* tty_data[0] is not used */ +extern void (*tty_vector[NTTYS+1])(int minor, char c); /* [0] is not used */ + +#endif /* __DEVTTY_H */ + diff --git a/src/kernel/uzi/dispatch b/src/kernel/uzi/dispatch new file mode 100755 index 00000000..095d72da --- /dev/null +++ b/src/kernel/uzi/dispatch @@ -0,0 +1,40 @@ +access +alarm +brk +chdir +chmod +chown +close +getset +dup +dup2 +execve +exit +fork +fstat +getfsys +ioctl +kill +link +mknod +mount +open +pause +pipe +read +sbrk +lseek +signal +stat +stime +sync +time +times +umount +unlink +utime +waitpid +write +reboot +symlink +chroot diff --git a/src/kernel/uzi/emu.asm b/src/kernel/uzi/emu.asm new file mode 100755 index 00000000..d8abe583 --- /dev/null +++ b/src/kernel/uzi/emu.asm @@ -0,0 +1,1389 @@ +; emu.asm +; currently not in use for the Hytech kernel + +;---------------------------------------------------------- +; CP/M 2.2 emulator for UZI180 +; extended from AS.C by Doug Braun +; Copyright (C) 1998 by Harold F. Bower +;---------------------------------------------------------- +; This module may begin on any arbitrary Page (mod 256) +; boundary to insure that the BIOS jump table is so aligned. +; It provides a minimal CP/M 2.2 functional subset to allow +; applications to execute in an UZI process. The only +; requirement on CP/M executables is that the first byte in +; the .COM file be a Far Jump (0C3H opcode). The Bdos code +; originated with AS.C by Doug Braun, but has been converted +; to assembly and extensively modified. H.F.Bower +;---------------------------------------------------------- + + public __bdos, __bios, EStart ; External Entry Points + public CPMSIZ + +$ asmdef.inc + +;=========================================================== +; Provide a global label in previous segment for move point + + rseg cpm22 ; while code in new segment +;=========================================================== + +; Initialize both FCB entries to blank values + +EStart: LD HL,fcbDat ; Move initial FCB + LD DE,fcb ; into + LD BC,16 ; position + LDIR + LD HL,fcbDat + LD C,16 ; init 2nd entry + LDIR + +; Catenate argv[] elements into default buffer + + POP IX ; Get Ptr to argv[] + LD DE,buff+1 ; Pt to CP/M Dflt Buffer + LD C,0 ; Cnt to 0 + INC IX ; Skip Argv[0] + INC IX +Cold0: LD L,(IX+0) ; Get Ptr to Arg element + INC IX + LD H,(IX+0) + INC IX + LD A,H + OR L ; End? + JR Z,Cold2 ; ..exit if Yes + LD A,' ' ; Add space separator for args + LD (DE),A + INC DE + INC C ; bump count +Cold1: LD A,(HL) + OR A ; End of string? + JR Z,Cold0 ; ..try next if Yes + CP 'a' ; insure + JR C,NoCap ; it + CP 'z'+1 ; is + JR NC,NoCap ; UCase + AND 5FH +NoCap: LD (DE),A ; Move a byte + INC HL + INC DE ; bump ptrs + INC C ; bump count + BIT 7,E ; buff overflow? + JR NZ,Cold1 ; ..get next byte if No + ;..else 0FF->100H, terminate + DEC DE ; (back up for Null-termination) +Cold2: XOR A + LD (DE),A ; Null-terminate for safety + + LD HL,buff ; Pt to count loc'n in buff + LD (HL),C ; save total arg count + INC HL ; advance to 1st char + LD DE,fcb+1 + CALL FilNm ; Get Name/Typ in 1st FCB + OR A ; (set End flag) + LD DE,fcb+17 ; (prepare) + CALL NZ,FilNm ; Get Tame/Typ in 2nd FCB if present + + LD DE,dir + LD B,128 + CALL ZeroDE ; Clear Directory Buffer + + LD HL,0 + LD (0003H),HL ; Clear IOBYTE and Default Drive/User + + JP __bios ; Go to Cold Start setup + +; Fill FCB Name.Typ fields with any present data + +FilNm: LD A,(HL) ; Get char + INC HL ; bump + OR A ; End of String? + RET Z + CP ' ' ; "Whitespace"? + JR Z,FilNm0 ; ..jump if Yes + CP TAB + JR NZ,FilNm1 ; ..jump if No +FilNm0: DEC C ; Count down total length + LD A,C ; (prepare) + JR NZ,FilNm ; ..loop if Not End + RET ; ..else Exit showing EOL + +FilNm1: LD B,8 ; Set length of Name field + PUSH DE ; save Ptr to Name[0] + CALL FilFl0 ; Get Name + POP DE ; restore Ptr to Name + OR A + RET Z ; ..return if End-of-Line + CP ' ' + RET Z ; ..return if separator + CP '.' + JR Z,FilNm2 ; ..bypass char skip + +FilNm3: LD A,(HL) + INC HL + OR A + RET Z ; Exit if End of Line + CP ' ' + RET Z ; or End of Field + CP '.' + JR NZ,FilNm3 ; ..loop til End or period + +FilNm2: LD A,E + ADD A,8 ; Adjust FCB ptr to type field + LD E,A + LD B,3 + ;..fall thru to get next char.. +; Move bytes from (HL) to (DE) for Count in C, Count in B or Ch in {' ','.',0} + +FilFld: LD A,(HL) ; Get Char + INC HL ; bump ptr + OR A ; End of String? + RET Z ; ..return if Yes +FilFl0: CP '.' ; Period? + RET Z + CP ' ' ; Space? + RET Z + LD (DE),A ; Else Store byte + INC DE ; bump dest ptr + DEC C ; End of Input String? + LD A,C ; (prepare) + RET Z ; .return End if Yes + DJNZ FilFld ; ..loop til field counter ends + OR 0FFH ; Return flag + RET + +fcbDat: DEFB 0 + DEFM ' ' + DEFB 0,0,0,0 + +;========================================================== +; Resident Portion of Basic Disk Operating System +;========================================================== +; bdos() +; { +__bdos: JP _bdos0 +; } + +;..... +; BDOS Function Dispatch Table + +fcnTbl: defw Fcn0 ; Warm Boot + defw Fcn1 ; ConIn + defw Fcn2 ; ConOut + defw Fcn3 ; Reader In + defw Fcn4 ; Punch Out + defw Fcn5 ; List Output + defw Fcn6 ; Direct Console IO + defw Fcn7 ; Get IOBYTE + defw Fcn8 ; Set IOBYTE + defw Fcn9 ; WrBuf + defw Fcn10 ; RdBuf + defw Fcn11 ; Get Console Status + defw Fcn12 ; Return Version # + defw Fcn13 ; Reset Disk Drive + defw Fcn14 ; Select Disk + defw Fcn15 ; Open File + defw Fcn16 ; Close File + defw Fcn17 ; Search First Occurance + defw Fcn18 ; Search Next Occurance + defw Fcn19 ; Delete File + defw Fcn20 ; Read File + defw Fcn21 ; Write File + defw Fcn22 ; Create File + defw Fcn23 ; Rename File + defw Fcn24 ; Return Disk Login Vector + defw Fcn25 ; Return Current Disk + defw Fcn26 ; Set DMA + defw Fcn27 ; Get Allocation Map + defw Fcn28 ; Write Protect Disk + defw Fcn29 ; Get R/O Vector Address + defw Fcn30 ; Set File Attributes + defw Fcn31 ; Get Disk Parameter Table Address + defw Fcn32 ; Set/Get User Code + defw Fcn33 ; Read Random + defw Fcn34 ; Write Random + defw Fcn35 ; Compute File Size + defw Fcn36 ; Set Random Record Field in FCB +; defw Fcn37 ; Reset Multiple Drives +; defw null ; (Fcn38 not implemented) +; defw Fcn39 ; Get Fixed Disk Vector +; defw Fcn40 ; Write Random +TBLSZ EQU $-fcnTbl +MAXFCN EQU TBLSZ/2 + +;------------------------------------------------ +; bdos0() +; { + +_bdos0: LD (_arg),DE + LD A,C + LD (_call),A + CP MAXFCN ; Legal Function? + LD A,0FFH ; Prepare Error code + LD L,A + RET NC ; ..return if Illegal + PUSH IX + PUSH IY + LD B,0 ; Fcn # to Word + LD HL,_bdosX + PUSH HL ; (ret Addr to Stack) + LD HL,fcnTbl + ADD HL,BC + ADD HL,BC ; Pt to Fcn entry in Table + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + JP (HL) ; "Call" Function # + +_bdosX: POP IY + POP IX + LD DE,(_arg) ; Return Orig contents of DE + LD A,(_call) + LD C,A ; Return Orig contents of C + LD A,L + LD B,H ; Strict compatibility + OR A + RET +; } + +;------------------------------------------------ +; case 0: _exit(); /* Warm Boot */ + +Fcn0: JP WBoot + + +;------------------------------------------------ +; case 6: if (arg < 0xfe) /* Direct Console I/O */ +; goto conout; +; else if (arg == 0xfe) +; return (ConSt); +; else if (ConSt) /* 0xff */ +; goto conout; +; else return (0); + +Fcn6: LD A,E ; _arg in DE + CP 0FEH ; < 0FE ? + JR C,Fcn2 ; ..jump if Write if Yes + PUSH AF + CALL BConSt ; Else get Console Status + POP AF + RET Z ; ..exit if 0feh + LD A,H + OR L ; Any char ready? + RET Z ; ..exit if Nothing available + ;..else fall thru to Fcn1.. +;------------------------------------------------ +; case 1: /* Console Input */ +; conin: read (0, &c, 1); +; if (c == '\n') +; c = '\r'; +; return (c); + +Fcn1: CALL BConIn ; Get Char from Bios +Fcn1A: LD H,0 + CP 0AH ; \n? + LD L,A ; (prepare for return + RET NZ ; ..return if Not + LD L,0DH ; Else return CR + RET + +;------------------------------------------------ +; case 3: /* Reader (Aux) Input */ +; conin: read (0, &c, 1); +; if (c == '\n') +; c = '\r'; +; return (c); + +Fcn3: CALL AuxIn ; Get Char from Bios + JR Fcn1A ; ..exit via common code + +;------------------------------------------------ +; case 2: /* Console Output */ +; conout: if (arg == '\r') +; return (0); +; c = arg; +; write (1, &c, 1); +; break; + +Fcn2: LD C,E ; _arg in DE, need char in C + JP BConOu + +;------------------------------------------------ +; case 4: /* Punch (Aux) Output */ +; conout: if (arg == '\r') +; return (0); +; c = arg; +; write (1, &c, 1); +; break; + +Fcn4: LD C,E ; _arg in DE, need char in C + JP AuxOut + +;------------------------------------------------ +; case 5: if (arg == '\r') /* List (Prntr) Output */ +; return (0); +; c = arg; +; write (2, &c, 1); +; break; + +Fcn5: LD A,E ; _arg in DE + CP 13 ; \r? + RET Z + JP List ; ..go to Bios + +;------------------------------------------------ +; case 9: ptr = (char *)arg; /* Print '$'-term String */ +; while (*ptr != '$') +; { +; if (*ptr != '\r') +; write (1, ptr, 1); +; ++ptr; +; } +; break; + ; Enter: DE -> String (arg) +Fcn9: LD A,(DE) ; Get char + INC DE ; pt to Next + CP '$' ; End? + RET Z ; ..quit if Yes + LD C,A + PUSH DE + CALL BConOu + POP DE + JR Fcn9 ; ..loop Til done + +;------------------------------------------------ +; case 10: rdbuf (arg); +; break; +; rdbuf (arg) +; char *arg; +; { +; int nread; + +; nread = read (0, arg+2, *arg & 0xff); + +Fcn10: LD A,(DE) ; Enter DE -> Buffer + LD C,A + LD B,0 + PUSH BC ; cnt (*arg & 0xff) + PUSH DE ; (save ptr to buffer) + INC DE + INC DE + PUSH DE ; arg+2 + LD C,0 + PUSH BC ; 0 (stdin) + LD HL,7 ; UZI Read Fcn # + PUSH HL + RST 30H ; Execute! + POP BC ; Clean Stack + POP BC + POP BC + POP BC + POP DE ; Restore Ptr to Buff + +; --nread; /* Forget about newline */ + + DEC HL + LD A,L + +; arg[nread+2] = '\0'; /* Remove newline */ + + ADD HL,DE + INC HL + INC HL + LD (HL),0 + +; arg[1] = nread; + + INC DE + LD (DE),A +; } + RET + +;------------------------------------------------ +; case 12: /* Return Version # */ + +Fcn12: LD HL,0022H ; Say this is CP/M 2.2 + RET + +;------------------------------------------------ +; case 7: /* Get IO Byte */ +; case 8: break; /* Set IO Byte */ +; case 11: /* Get Console Status */ +; case 13: /* Reset Disk Drive */ +; case 14: break; /* Select Disk +; case 25: break; /* Return Current Disk */ +; case 28: break; /* Write Protect Disk */ +; case 30: break; /* Set File Attribytes */ +; case 32: break; /* Get/Set User Code */ +Fcn7: +Fcn8: +Fcn11: +Fcn13: +Fcn14: +Fcn25: ; 0 = Drive A +Fcn28: +Fcn30: +Fcn32: ; Return User 0 +; default: break; +; } +; return (0); + +Exit0: LD HL,0 + RET + +;------------------------------------------------ +; case 15: return (openfile (arg)); /* Open File */ +; openfile (blk) +; { +; desc = open (getname (arg), 2); + ; DE -> arg +Fcn15: CALL CkSrch ; Insure Search file closed + ; (_arg still in DE) + CALL Fcn17 ; Does this file exist? + LD A,H + AND L + INC A ; File Not Found (-1)? + RET Z ; ..return -1 if File doesn't exist + + LD DE,(_arg) ; Else + CALL GetNam ; Parse FCB Fn.Ft to String + + LD DE,2 ; Open for R/W + CALL OpenF ; _open (Path, Mode); + +; arg.recno = 0; + + LD IY,(_arg) + LD (IY+32),0 ; Init Current Record # + +; if (desc == -1) +; return (255); + + RET Z ; ..return -1 if Yes + +; blk->desc = desc; + +OpEx0: EX DE,HL + LD HL,(_arg) + LD BC,16 + ADD HL,BC + LD (HL),E ; Store File Desc in FCB + INC HL + LD (HL),D + +; return (0); + + JR Exit0 ; Return Dir Code for Entry +; } + +;..... +; Common File Open Routine. Used by Open and Search First. +; Enter: DE = File Mode +; HL = Ptr to Null-terminated Path String +; Exit : A = 0 if Error, HL = -1 +; File Descriptor, A <> 0 if Ok + +OpenF: PUSH DE ; Mode + PUSH HL ; Path + LD HL,1 ; UZI Open Fcn # + PUSH HL + RST 30H ; _open (Path, Mode); + POP BC ; Clean Stack + POP BC + POP BC + + LD A,H + AND L + INC A ; FF -> 0? + RET ; ..return (HL=-1/A=0 if Err, HL=fd/A<>0 of Ok) + +;------------------------------------------------ +; case 16: return (closefile (arg)); /* Close File */ + +; if (close (arg->desc) == -1) + +Fcn16: CALL RWprep ; prepare for file access + ; (desc (fd) still in DE) + ; Internal entry Point +CloseV: PUSH DE + LD HL,2 ; UZI Close Fcn # + PUSH HL + RST 30H ; Execute! + POP BC ; Clean Stack + POP BC + +OpEx1: LD A,H ;--- Common Exit Code with Delete --- + AND L + INC A ; FF->0? + JR NZ,Exit0 ; return Ok if No + +; return (255); + + LD HL,-1 + RET + +; return (0); +; } + +;------------------------------------------------ +; case 17: /* Search First */ + +Fcn17: LD HL,'.' ; Open current directory + LD (RName),HL ; store name in Secondary work string + LD DE,0 ; Open Read-Only + LD HL,RName + CALL OpenF ; _open ('.', 0); + RET Z ; HL = -1, A = 0 if Can't Open + + LD (srchFD),HL ; Else Ok, Save File Descriptor + LD (curFil),HL ; Duplicate for Reading + ;..fall thru to read one entry.. +;------------------------------------------------ +; case 18: return (255); /* Search Next */ + +Fcn18: LD HL,(dmaadr) + LD (dmaSav),HL ; Save "real" DMA +Fcn18A: LD HL,dir+16 + LD (dmaadr),HL ; Set DMA for Dir Op'n + LD A,7 ; UZI Read Function # + LD DE,16 ; Len of Dir entries + CALL RdWrt0 ; Read an Entry + JR C,Fcn18E ; Error if Carry Set + OR A ; Read Ok? + JR Z,Fcn18E ; ..Return HL=-1 if EOF + CALL ChkDir ; Else Set Dir to CP/M, Check Match + OR A + JR NZ,Fcn18A ; ..loop if No Match + + LD A,(_call) + CP 15 ; Is this a File Open internal Call? + LD HL,0 ; (set Success, Index 0) + JR Z,Fcn18X ; ..exit now if Yes + + LD HL,dir ; Else + LD DE,(dmaSav) ; Move Dir Buffer to "real" DMA + LD BC,128 + LDIR + LD L,B ; Use 0 in BC + LD H,C ; to show Index 0 (success) + JR Fcn18X ; ..exit + +Fcn18E: LD HL,-1 +Fcn18X: LD DE,(dmaSav) + LD (dmaadr),DE ; Restore "real" DMA Addr + RET + +;------------------------------------------------ +; case 19: return (delete (arg)); /* Delete File */ + +Fcn19: CALL CkSrch ; Insure Search file closed + +; if (unlink (getname (arg)) == -1) + ; DE -> arg + CALL GetNam ; Parse to String + PUSH HL ; String + LD HL,6 ; UZI Unlink Fcn # + PUSH HL + RST 30H ; Execute! + POP BC ; Clean Stack + POP BC + +; return (255); +; return (0); + + JR OpEx1 ; ..go to Common Exit + +;------------------------------------------------ +; case 33: /* Read File Random */ +; readrandom (fcb) +; { +; /* CAUTION the seek calls MUST be in this order */ +; _seek (f, (int)(fcb+33) % 128, 0); /* byte seek */ + ; DE -> fcb +Fcn33: CALL RWprep ; Prepare File for access (fd to DE) + CALL SkOff ; Seek to Offset (128-byte rec in Block) + +; _seek (f, (int)(fcb+33) / 128, 3); /* block seek */ + + CALL SkBlk ; Seek to 512-byte Block + JR Fcn20A ; ..Now Read as Normal.. + +;------------------------------------------------ +; case 20: return (readfile (arg)); /* Read File */ +; readfile (arg) +; { +; nread = read (blk->desc, dmaadr, 128); + ; DE -> arg (FCB) +Fcn20: CALL RWprep ; Prepare file for access +Fcn20A: CALL BRead ; Read 1 Sector + JR C,FilErr ; ..Error if Carry Set + +; arg.recno++; + +RWEx: LD IY,(_arg) + INC (IY+32) ; Bump current Record # + +; if (nread == 0) +; return (0); + + OR A ; Good Read? + JP Z,Exit0 ; exit w/0 if Yes + +; else return (-1) + +FilErr: LD HL,-1 + RET + +;------------------------------------------------ +; case 34: /* Write File Random */ +; writerandom (fcb) +; { +; /* CAUTION the seek calls MUST be in this order */ +; _seek (f, (int)(fcb+33) % 128, 0); /* byte seek */ +Fcn34: CALL RWprep ; Prepare file for access + CALL SkOff ; Seek to Offset (128-byte rec in Block) + +; _seek (f, (int)(fcb+33) / 128, 3); /* block seek */ + + CALL SkBlk ; Seek to 512-byte Block + JR Fcn21A ; ..now Write as Normal.. + +;------------------------------------------------ +; case 21: return (writefile (arg)); /* Write File */ +; writefile (arg) +; { +; if (write (blk->desc, dmaadr, 128) != 128) + + ; DE -> arg (FCB) +Fcn21: CALL RWprep ; Prepare file for access +Fcn21A: CALL BWrit ; Write + +; return (255); +; return (0); + + JR RWEx ; ..exit via Common R/W Code +; } + +;------------------------------------------------ +; case 22: return (makefile (arg)); /* Create File */ +; makefile (arg) +; { +; desc = creat (getname (blk), 0666); + +Fcn22: CALL CkSrch ; Insure Search file closed + LD HL,0666Q ; Own/Grp/Oth are Read/Execute + PUSH HL ; DE -> arg + CALL GetNam ; This name string + PUSH HL + LD HL,3 ; UZI Creat Fcn # + PUSH HL + RST 30H ; Execute! + POP BC ; Clean Stack + POP BC + POP BC + +; if (desc == -1) + + LD A,H + AND L + INC A ; FF -> 0? + +; return (255); + + RET Z ; ..return -1 if Yes + +; arg.recno = 0; + + LD IY,(_arg) + LD (IY+32),0 ; Init Current Record # + +; blk->desc = desc; +; return (0); + + JP OpEx0 ; ..finish up in Open +; } + +;------------------------------------------------ +; case 23: return (rename (arg)); /* Rename File */ +; rename (arg) +; { +; RName = getname (arg); + +Fcn23: CALL CkSrch ; Insure Search file closed + PUSH DE ; Save FCB Ptr + CALL GetNam ; parse to UZI String + + LD HL,FName + LD DE,RName + LD BC,12 + LDIR ; Copy to Rename string + +; FName = getname (arg+16); + + POP DE ; DE -> _arg + LD HL,16 + ADD HL,DE ; Offset to New Name + EX DE,HL + CALL GetNam ; parse it returning HL -> FName + +; if (link (RName, FName) < 0) { + + PUSH HL ; New Name + LD HL,RName ; Old Name + PUSH HL + LD HL,5 ; UZI link Fcn # + PUSH HL + RST 30H ; Execute! + POP BC ; Clean Stack + POP BC + POP BC + +; return (-1); + + JP C,FilErr ; Exit w/Err if Bad +; } +; if (unlink (RName) < 0) { + + LD HL,RName ; Old Name + PUSH HL + LD HL,6 ; UZI unlink Fcn # + PUSH HL + RST 30H ; Execute! + POP BC ; Clean Stack + POP BC + JP NC,Exit0 ; exit w/0 if Ok + +; unlink (FName); + ; Else remove the new iNode + LD HL,FName ; New Name + PUSH HL + LD HL,6 ; UZI unlink Fcn # + PUSH HL + RST 30H ; Execute! + POP BC ; Clean Stack + POP BC + +; return (-1); + + JP C,FilErr ; return -1 if Bad +; } +; return (0); + + JP Exit0 ; else return Ok +; } + +;------------------------------------------------ +; case 24: return (1); /* Return Disk Login Vector */ + +Fcn24: LD HL,1 + RET + +;------------------------------------------------ +; case 26: dmaadr = (char *)arg; /* Set DMA Address */ +; break; + ; Enter DE = DMA Address +Fcn26: LD C,E + LD B,D ; Move to Bios Regs + JP BSDma ; Set in Bios & return + +;------------------------------------------------ +; case 27: return (-1) /* Get Allocation Map */ +; case 29: return (-1) /* Get R/O Vector Address */ +Fcn27: +Fcn29: LD HL,-1 + RET + +;------------------------------------------------ +; case 31: return (&dpb); /* Get Disk Param Table Addr */ + +Fcn31: LD HL,dpb + RET +; } + +;------------------------------------------------ +; case 35: /* Return File Size in FCB */ +; /* Use stat fcn, rounding up to mod-128 */ +; if (_stat (dname, &statbuf) == 0) { + ; DE -> fcb +Fcn35: CALL CkSrch ; Insure Search file closed + CALL GetNam ; parse to UZI String + LD DE,stBuf + PUSH DE ; &statbuf + PUSH HL ; dname + LD HL,15 ; UZI stat Fcn # + PUSH HL + RST 30H ; Execute! + POP BC ; Clean Stk + POP BC + POP BC + LD IY,(_arg) + LD A,H + OR L ; 0? + JR NZ,Fcn35X ; ..jump if Bad + +; (int)fcb+33 = ((512 * statbuf.st_size.o_blkno +; + statbuf.st_size.o_offset) +; + 127) +; >> 7; + LD HL,(stBuf+14) ; Get Offset + LD DE,127 + ADD HL,DE ; round up to next 128-byte block + ADD HL,HL ; Shift so H has 128-byte blk # + LD E,H ; position in DE + LD HL,(stBuf+16) ; Get Block + ADD HL,HL ; * 2 + ADD HL,HL ; * 4 for 128-byte Block Count + ADD HL,DE ; Now have CP/M Record Size + LD (IY+33),L + LD (IY+34),H ; Store in RR fields in FCB + +; return (0); + + LD L,D + LD H,D ; HL = 0 + RET + +; else { +; (int)fcb+33 = 0; + +Fcn35X: LD (IY+33),0 + LD (IY+34),0 + +; return (-1); + + LD HL,-1 +; } + RET + +;------------------------------------------------ +; case 36: /* Set Random Record Field in FCB */ + +Fcn36: LD HL,32 ; Offset to RecNo + LD A,(HL) ; Fetch + INC HL + LD (HL),A ; place in LSB of RR field + INC HL + LD (HL),0 ; Clear Hi byte of RR + + LD HL,0 ; Return Ok + RET + +;=========================================================== +; BDos Support Routines +;=========================================================== +; char * +; getname (struct fcb *blk) +; { +; int j; +; static char name[16]; +; char *p; + +; p = name; + ; Enter: DE -> FCB drive byte +GetNam: LD IX,FName ; Dest to string + EX DE,HL + PUSH HL ; (save) + INC HL ; adv to 1st char of FN + +; for (j = 0; j < 8; ++j) +; { +; if (!blk->name[j] || blk->name[j] == ' ') +; break; + + LD B,8 +GetN0: LD A,(HL) + INC HL + OR A + JR Z,GetN1 + CP ' ' + JR Z,GetN1 + +; *p++ = chlower (blk->name[j]); + + CALL ChLower + LD (IX+0),A + INC IX + DJNZ GetN0 +; } + +GetN1: POP HL + LD DE,9 + ADD HL,DE ; Pt to 1st char of FT + LD A,(HL) + CP ' ' ; Any Type? + JR Z,GetNX ; ..quit if Not + +; *p++ = '.'; + + LD (IX+0),'.' + INC IX + +; for (j = 0; j < 3; ++j) + + LD B,3 + +; { +; if (!blk->ext[j] || blk->ext[j] == ' ') +; break; + +GetN2: LD A,(HL) + INC HL + CP ' ' + JR Z,GetNX + +; *p++ = chlower (blk->ext[j]); + + CALL ChLower + LD (IX+0),A + INC IX + DJNZ GetN2 + +; } +; *p = '\0'; + +GetNX: LD (IX+0),0 + +; return (name); + + LD HL,FName + RET +; } + +;..... +; Seek Offset. Uses Random Address to set 128-byte offset in 512-byte Sctr. + +SkOff: LD BC,0 + PUSH BC ; 0 Mode (Absolute Offset Position) + LD IY,(_arg) ; Pt to current fcb + LD A,(IY+33) ; Fetch Lo Byte of Offset + AND 03H ; (kill all but mod 512, 2 bits) + LD B,A + SRL B + RR C ; Offset is pos'n within 512-byte Rec + JR SeekV ; ..finish in Common Code + +;..... +; Seek Block. Uses Random Address to set Div-512 Block Number + +SkBlk: LD HL,3 ; 3 Mode (Absolute Block Position) + PUSH HL ; to Stk + LD IY,(_arg) + LD C,(IY+33) + LD B,(IY+34) + SRL B + RR C + SRL B + RR C ; Blk # is DIV 512 +SeekV: PUSH BC + LD HL,(curFil) ; fd + PUSH HL + LD HL,9 ; UZI Seek Fcn # + PUSH HL + RST 30H ; Execute! + POP BC + POP BC + POP BC + POP BC + RET + +;..... +; Perform File Access Preparatory actions; Clear Directory Ops, Close Dir, +; load File Descriptor from storage in FCB to Bios Storage as current file. + +RWprep: CALL CkSrch ; Insure Search file closed + LD HL,16 + ADD HL,DE ; Offset to file desc in FCB + LD E,(HL) + INC HL + LD D,(HL) + LD (curFil),DE ; store for Bios + RET + +;..... +; Convert UZI Directory Entry at dir+16 to CP/M FCB entry at dir, Zero rest. +; Ambiguously compare FCB FN.FT at dir to that passed at arg, returning Zero +; if Match, Non-Zero if mismatch. + +ChkDir: LD DE,dir + LD HL,dir+16+2 ; Pt to 1st char of Name + XOR A + LD (DE),A ; Zero Drive field + INC DE ; Pt to 1st char of FN + LD B,8 + CALL ChkD0 ; Fix Name + LD B,3 + CALL ChkD0 ; & Type + LD B,21 + CALL ZeroDE ; Clear rest of Dir entry + + LD DE,(_arg) + INC DE ; Pt to 1st char of FN + LD A,(DE) + CP ' ' ; Any Name present? + JR NZ,ChkFN0 ; ..jump if Yes + LD HL,8 + ADD HL,DE ; Else offset to 1st char of FT + LD A,(HL) + CP ' ' ; Type present? + LD A,0FFH ; (Assume Error) + RET Z ; Return w/Err Flag if no Type either + +ChkFN0: LD HL,dir+1 ; Else Compare name/type fields + LD B,11 + ; Ambiguous FN.FT compare of (HL) to (DE) +ChkL: LD A,(DE) + CP '?' ; Accept anything? + JR Z,ChkL0 ; ..jump if ambiguous + XOR (HL) + AND 7FH ; Match? + RET NZ ; .Return Non-Zero if Not +ChkL0: INC HL + INC DE + DJNZ ChkL ; ..loop til Done + RET ; return Zero for Match + +;..... +; Parse FileSpec addressed by HL into FN.FT Spec addressed by DE. + +ChkD0: LD A,(HL) ; Get Char + CP 'a' + JR C,ChkD1 + CP 'z'+1 + JR NC,ChkD1 + AND 5FH ; Convert to Uppercase +ChkD1: OR A ; End of String? + JR Z,ChkDE ; ..jump if End + INC HL ; (bump Inp Ptr if Not End) + CP '.' + JR Z,ChkDE ; ..or Period field separator + LD (DE),A ; Store char + INC DE ; bump Dest + DJNZ ChkD0 ; ..loop til field done +ChkD2: LD A,(HL) ; Get Next + OR A + RET Z ; Exit at End of string + INC HL ; (adv to next) + CP '.' + RET Z ; or field separator + JR ChkD2 ; ..loop til end found + +ChkDE: LD A,' ' ; Fill rest w/Spaces +ChkD3: INC B + DEC B ; More in field? + RET Z ; ..exit if Not + JR ZeroL ; ..else stuff spaces til field ends + +;..... +; Zero area addressed by DE for B Bytes. Uses A,B,DE. + +ZeroDE: XOR A +ZeroL: LD (DE),A + INC DE + DJNZ ZeroL + RET + +;..... +; Close the Directory if we just exitted a SearchF/SearchN sequence + +CkSrch: PUSH DE ; Save Regs + PUSH HL + LD DE,(srchFD) ; Get File Desc + LD A,D + OR E ; Anything open? + CALL NZ,CloseV ; Close file if Yes + LD HL,0 + LD (srchFD),HL ; Mark as closed + POP HL ; (ignore Errors) + POP DE + RET + +;..... +; Convert char in A to Lowercase Ascii + +ChLower: CP 'A' + RET C + CP 'Z'+1 + RET NC + OR 20H ; Convert to Lcase + RET + +;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +; Bdos data in Text Segment for treating as single module + +; struct fcb { +; char drive; +; char name[8]; +; char ext[3]; +; char junk1[4]; +; char desc; /* This byte & 1st byte of Name used for file desc */ +; char name2[8]; +; char ext2[3]; +; char junk2[4]; +; char junk3; +; }; + +_arg: DEFW 00 ; Argument passed to Bdos (char *arg;) +_call: DEFB 0 ; Bdos Function # (char call;) +FName: DEFM ' ' ; Storage for FCB "name" String +RName: DEFM ' ' ; 2nd Storage for FCB "name" String (rename) + +curFil: DEFW 00 ; Storage for File Descriptor of FCB + ; (set by Bdos, Used by Bios) +stBuf: DEFS 30 ; Buffer for stat() results + +DOSSIZ EQU $-EStart +RESV EQU 100H-(DOSSIZ&0FFH) + DEFS RESV ; Pad to make Bios start on even mult of 256 + +;============================================================ +; The Bios Jump table MUST start on an even MOD 256 boundary +;============================================================ + +__bios: JP __cold ; 0 Cold Boot +WBoot: JP Exit ; 1 Warm Boot +BConSt: JP ConSt ; 2 Console Status +BConIn: JP ConIn ; 3 Console Input +BConOu: JP ConOut ; 4 Console Output + JP List ; 5 Printer Output + JP AuxOut ; 6 Auxiliary Output (Punch) + JP AuxIn ; 7 Auxiliary Input (Reader) + JP Home ; 8 Home drive head + JP SelDsk ; 9 Select Drive + JP SetTrk ; 10 Set Track + JP SetSec ; 11 Set Sector +BSDma: JP SetDMA ; 12 Set DMA Address +BRead: JP Read_Sector ; 13 Read Sector +BWrit: JP Write_Sector ; 14 Write Sector + JP ListSt ; 15 Printer Status + JP SecTrn ; 16 Translate Sector + +;------------------------------------------------ +; Cold Entry. Set up CP/M vectors and Stack, Get +; Current TTY Parms, Save for Exit, and begin + +__cold: LD A,0C3H + LD HL,__bdos + LD SP,HL ; Set CP/M Stack for execution + LD (0005H),A ; Set Bdos Vector + LD (0006H),HL + LD HL,WBoot + LD (0000H),A ; Set Bios Warm Boot Vector + LD (0001H),HL + + LD HL,ttDatO ; & buf + LD DE,TIOCGETP ; ioctl fcn to Get Parms + CALL IoCtl ; Execute ioctl fcn on STDIN + LD HL,ttDatO + LD DE,ttDat + LD BC,6 + LDIR ; Move to Work Area + ; Now we need to Change Modes defined in DEVTTY as: + ; RAW = 20H (0000040) + ; CRMOD = 10H (0000020) + ; ECHO = 08H (0000010) + ; CBREAK = 02H (0000002) + ; COOKED = 00H (0000000) + LD A,(ttDat+4) + AND 0C4H ; Kill CRMOD, ECHO, CBREAK BITS + OR 20H ; Set RAW Mode + LD (ttDat+4),A + LD HL,ttDat ; &buf + LD DE,TIOCSETP ; ioctl Set TTY Parms Function + CALL IoCtl ; Execute ioctl fcn on STDIN + LD DE,TIOCTLSET + CALL IoCtl ; Disable Control Char Processing + JP 0100H ; ..Execute! + +;..... +; 1 - Warm Boot Vector (Exits back to UZI) {exit (0);} +; TTY Port Settings are restored to original state. + +Exit: LD HL,ttDatO ; & buf + LD DE,TIOCSETP ; ioctl fcn to Set Parms + CALL IoCtl ; Execute ioctl Fcn on STDIN + LD DE,TIOCTLRES + CALL IoCtl ; Re-Enable Control Char Processing + + LD HL,0 ; Exit Good Status + PUSH HL + PUSH HL ; UZI Fcn 0 (_exit) + RST 30H ; Execute! + DI + HALT + +;..... +; 2 - Return Console Input Status + +ConSt: LD HL,cnt ; &buf + LD DE,TIOCSETN ; ioctl fcn to read queue count + CALL IoCtl ; Execute ioctl on STDIN + LD HL,(cnt) + LD A,H + OR L ; Anything There? + RET Z ; ..return Zero if Not + OR 0FFH ; Else signify char waiting + RET + +;..... +; 3 - Read Console Input Char {read (stdin, &char, 1);} + +ConIn: LD HL,1 ; 1 char + PUSH HL + LD DE,char ; Addr to put char + PUSH DE + LD L,STDIN ; fd + PUSH HL + LD L,7 ; UZI Read Fcn +ChrV0: PUSH HL + RST 30H ; Execute + POP BC + POP BC + POP BC + POP BC + LD A,(char) + RET + +;..... +; 4 - Write Char in C to Console {write (stdout, &char, 1);} + +ConOut: LD A,C + LD DE,char + LD (DE),A ; Stash char + LD HL,1 ; 1 char + PUSH HL + PUSH DE ; Addr to get char + LD L,STDOUT ; fd + PUSH HL + LD L,8 ; UZI Write Fcn + JR ChrV0 ; ..go to common code + +;..... + +List: ; Bios Fcn 5 +AuxOut: ; Bios Fcn 6 +AuxIn: ; Bios Fcn 7 +Home: ; Bios Fcn 8 +SetTrk: ; Bios Fcn 10 +SetSec: ; Bios Fcn 11 +ListSt: ; Bios Fcn 15 +SecTrn: XOR A ; Bios Fcn 16. These are No-Ops + RET + +;..... +; 9 - Select Disk. Simply return the DPH pointer + +SelDsk: LD HL,dph ; Return DPH Pointer + RET + +;..... +; 12 - Set DMA Transfer Address + +SetDMA: LD (dmaadr),BC ; Save Address + Ret + +;..... +; 13 - Read a "Sector" to DMA Address {read (curFil, dmaadr, 128);} + +Read_Sector: + LD A,7 ; Set UZI Read Fcn + CALL RdWrt ; Do the work + RET C ; ..exit if Error + OR A ; 0 bytes Read? + JR Z,XErr ; ..Return Error if Yes (EOF) + SUB 128 ; A full 128 bytes Read? + RET Z ; return Ok if Yes + LD DE,(dmaadr) + ADD HL,DE ; Else offset to byte after end + LD (HL),1AH ; stuff EOF in case of text + XOR A ; set Ok status + RET ; and exit + +;..... +; 14 - Write a "Sector" from DMA Address {write (curFil, dmaadr, 128);} + +Write_Sector: + LD A,8 ; Set UZI Write Fcn + CALL RdWrt ; Do the work + RET C ; ..exit if Error + SUB 128 ; Good Write? + RET Z ; return Ok if Yes + JR XErr ; Else Return Error + +; Common Read/Write Support Routine + +RdWrt: LD DE,128 ; 1 "Sector" char + ; Entry Point accessed by Search Next (BDos) +RdWrt0: PUSH DE + LD HL,(dmaadr) ; from here + PUSH HL + LD HL,(curFil) ; to this file + PUSH HL + LD E,A ; Position R/W Fcn # + PUSH DE + RST 30H ; Execute! + POP BC ; Clear Stack + POP BC + POP BC + POP BC + LD A,L ; Shuffle possible byte quantity + RET NC ; ..return if No Error +XErr: LD A,01H ; Else Signal Error (keeping Carry) + RET + +;========================================================== +; Bios Support Utilities +;========================================================== +;..... +; Execute ioctl Function on STDIN +; Enter: HL = Addr of Parm Block +; DE = ioctl Function to execute +; Exit : None +; Uses : AF,BC,DE,HL + +IoCtl: PUSH HL ; &buf + PUSH DE ; ioctl fcn + LD E,STDIN ; fd + PUSH DE + LD E,29 ; UZI ioctl Fcn # + PUSH DE + RST 30H ; Execute! + POP BC ; Clean Stack + POP BC + POP BC + POP BC + RET + +;- - - - - - - - - - Data Structures - - - - - - - - - + +dph: DEFW 0 ; Ptr to Skew Table + DEFW 0,0,0 ; Scratch Words for BDos use + DEFW dir ; Ptr to Directory Buffer + DEFW dpb ; Ptr to DPB + DEFW 0 ; Ptr to Disk Checksum Buffer + DEFW 0 ; Ptr to ALV Buffer + + +dpb: DEFW 64 ; Dummy Disk Parameter Block + DEFB 4 + DEFB 15 + DEFW 0FFFFH + DEFW 1023 + DEFB 0FFH,0 + DEFB 0,0,0,0 + +;----------------------- Data ----------------------- + +dmaadr: DEFW 0080H ; Read/Write Transfer Addr (char *dmaadr;) +dmaSav: DEFW 0 ; Temp storage of current DMA Address +srchFD: DEFW 0 ; File Descriptor for Searches +char: DEFB ' ' ; Byte storage for Conin/Conout +cnt: DEFW 0 ; Count of waiting keys +ttDat: DEFB 0,0,0,0,0,0 ; Working TTY Port Settings +ttDatO: DEFB 0,0,0,0,0,0 ; Initial TTY Port Settings + +dir: DEFS 128 ; Directory Buffer + +BIOSIZ EQU $-__bios +CPMSIZ EQU $-__bdos + + end diff --git a/src/kernel/uzi/extern.h b/src/kernel/uzi/extern.h new file mode 100755 index 00000000..649c4de3 --- /dev/null +++ b/src/kernel/uzi/extern.h @@ -0,0 +1,150 @@ +/************************************************** +UZI (Unix Z80 Implementation) Kernel: extern.h +***************************************************/ +/* These are the global data structures */ + +#ifdef MAIN +#define extern +#endif + +/* Nick #undef UTIL */ /* Change this to define UTIL if Not running kernel */ + +/* This is accessed by the macro udata which is really ub.u_d + * for the running system, _ub is defined in MACHASM.ASZ, but + * it needs to be here for the utilities that run under CP/M. + */ +/* Nick #ifndef UTIL */ +/* Nick #ifndef MAIN */ +#if defined(UTIL) || !defined(MAIN) /* Nick */ +#if 1 /* Nick */ +extern struct s_ublock ub; +#else +extern struct u_block ub; +#endif +#endif /* Nick */ +/* Nick #endif */ +/* Nick #endif */ + +#define udata ub.u_d + +#if 1 /* Nick UZIX compatible */ +extern struct s_ptab ptab[PTABSIZE]; +#else +extern struct p_tab ptab[PTABSIZE]; +#endif + +#if 1 /* Nick UZIX compatible */ +extern inoptr root_ino; /* Address of root dir in inode table */ +extern dev_t root_dev; /* Device number of root filesystem. */ +#else +extern inoptr root; /* Address of root dir in inode table */ +extern int16 ROOTDEV; /* Device number of root filesystem. */ +#endif + +#if 1 /* Nick UZIX compatible */ +extern struct s_cinode i_tab[ITABSIZE]; /* In-core inode table */ +#else +extern struct cinode i_tab[ITABSIZE]; /* In-core inode table */ +#endif +extern struct oft of_tab[OFTSIZE]; /* Open File Table */ + +#if 1 /* Nick UZIX compatible */ +extern struct s_filesys fs_tab[NFS]; /* Table entry for each + device with a filesystem. */ +#else +extern struct filesys fs_tab[NDEVS]; /* Table entry for each + device with a filesystem. */ +#endif +#if 1 /* Nick UZIX compatible */ +extern struct s_blkbuf bufpool[NBUFS]; +extern uchar dirty_mask; /* 1 if buffer writing delayed, else 0 */ +#else +extern struct blkbuf bufpool[NBUFS]; +#endif + +extern ptptr initproc; /* The process table address of the first process. */ +extern int16 inint; /* flag is set whenever interrupts are being serviced */ +extern char unix_locked_out; /* how many kernel ei() / di() blocks entered */ + +extern int16 sec; /* Tick counter for counting off one second */ +extern int16 runticks; /* Number of ticks current process has been + swapped in */ + +extern uzitime_t tod; /* Time of day */ +extern uzitime_t ticks; /* Cumulative tick counter, in minutes and ticks */ + +#if 1 /* Nick UZIX compatible */ +extern uchar total; /* Total available memory 16k pages */ +#endif + +extern char *swapbase; /* Used by device driver for swapping */ +extern unsigned swapcnt; +extern blkno_t swapblk; + +extern uint16 waitno; /* Serial number of processes entering wait state */ + +#ifdef DEBUG +extern char traceon; /* Nick flag to enable/disable tracing via keyboard */ +#endif + +#if 1 /* Nick UZIX compatible */ +/* release buffer */ +#define brelse(bp) bfree(bp, 0) + +/* free buffer and mark them dirty for eventually writing */ +#define bawrite(bp) bfree(bp, 1) + +/* do all buffers free without flushing */ +#define bufinit() bzero(bufpool, NBUFS*sizeof(blkbuf_t)) + +/* shortcuts for block device read/write */ +#define bdread(bp) bdreadwrite(bp, 0) +#define bdwrite(bp) bdreadwrite(bp, 1) + +/* shortcuts for character device read/write */ +#define cdread(dev) cdreadwrite(dev, 0) +#define cdwrite(dev) cdreadwrite(dev, 1) + +/* shortcuts for device open/close */ +#define d_open(dev) d_openclose(dev, 1) +#define d_close(dev) d_openclose(dev, 0) + +/* shortcuts for access to buffer pool by clients */ +#define tmpbuf() zerobuf(1); /* not allowed to return NULL */ + +/* shortcuts for access to file data via an open inode */ +#define readi(x) readwritei(0, x) +#define writei(x) readwritei(1, x) + +#define freefileentry(e) ((e) & 0x80) +#endif + +#ifdef MAIN +#undef extern +#endif + +#ifdef UTIL /* Nick */ +#define kprintf printf +#define kputchar putchar +#define _putc putchar +#define uput(sptr, uptr, nbytes) (bcopy((sptr), (uptr), (nbytes))) +#define uget(uptr, sptr, nbytes) (bcopy((uptr), (sptr), (nbytes))) +#define uputw(w, uptr) (*(int *)(uptr) = (w)) +#define ugetw(uptr) (*(int *)(uptr)) +#define uputc(c, uptr) (*(char *)(uptr) = (c)) +#define ugetc(uptr) (*(char *)(uptr)) +#define ugets(uptr, sptr, count) (strcpy((sptr), (uptr)), 0) /* success */ +#define ei() +#define di() +#define ei_absolute() +#define di_absolute() +#define abyte() +/* #define d_init() 0 */ /* pretends success (please look into this!!.. OK!) */ +#define lpout() +/* #define rdtod() */ +#define sys_execve() +#define swapout() +#define swapin() +#define dofork() +#endif + diff --git a/src/kernel/uzi/filesys.c b/src/kernel/uzi/filesys.c new file mode 100755 index 00000000..9cff2fe8 --- /dev/null +++ b/src/kernel/uzi/filesys.c @@ -0,0 +1,1599 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + Filesystem related routines +**********************************************************/ + +#define NEED__DEVIO +#define NEED__FILESYS +#define NEED__MACHDEP +#define NEED__PROCESS +#define NEED__SCALL + +#if 1 /* Nick */ +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include "devio.h" /* prototypes added by Nick */ +#include "filesys.h" /* prototypes added by Nick */ +#include "xip.h" /* prototypes added by Nick */ +#else /* Nick */ +#include "uzix.h" +#ifdef SEPH +#include "types.h" +#include "signal.h" +#include "errno.h" +#include "sys\stat.h" +#endif +#include "unix.h" +#include "extern.h" +#endif /* Nick */ + +#if 1 /* Nick */ +int int_min(int, int); +#endif + +inoptr _namei(uchar *name, uchar **rest, inoptr strt, inoptr *parent); +fsptr getfs(dev_t devno); + +/* Common messages. They are here to save memory */ +static char *badinomsg = "%s: bad inode number %u"; +char *baddevmsg = "%s: bad dev %u"; +static char *badfsmsg = "%s: fs of dev %u marked as bad"; +static char *refstoinode = "%s refs to inode %u"; +static char *gtinobadoft = "getinode: bad oft %u%s %u"; + +/* Returns true if the magic number of a superblock is ok ??? not used */ +#define gooddev(dev) ((dev)->s_mounted == SMOUNTED) + +#define blockinodes(blk) ((blk) << DINODESPERBLOCKLOG) +#define devinodes(dev) blockinodes((dev)->s_isize) +#define inodeblock(dev,ino) (((ino) >> DINODESPERBLOCKLOG) + (dev)->s_reserv) +#define inodeoffset(ino) ((ino) & DINODESPERBLOCKMASK) + +/* Check the given device number, and return its address in the mount table. + */ +fsptr findfs(dev_t devno) +{ + register fsptr dev = fs_tab; + + while (dev != fs_tab + NFS) { + if (dev->s_mounted != 0 && dev->s_dev == devno) + return dev; + ++dev; + } + return NULL; +} + +/* Check the given device number, and return its address in the mount table. + * Also time-stamp the superblock of dev, and mark it modified. + * Used when freeing and allocating blocks and inodes. + */ +fsptr getfs(dev_t devno) +{ + fsptr dev = findfs(devno); + + if (dev == NULL) + panic(baddevmsg, "getfs", devno); + rdtime(&dev->s_time); /* timestamp */ + dev->s_fmod = 1; /* mark modified */ + return dev; +} + +/* Wr_inode() writes out the given inode in the inode table out to disk, + * and resets its dirty bit. + * Attention! Immediate writing may be delayed by dirty_mask! + */ +int wr_inode(inoptr ino) +{ + dinode_t *buf; + +#if DEBUG > 1 + kprintf("wr_inode(%u) starting\n", ino - i_tab); +#endif + + magic(ino, "wr_inode"); + if (ino->c_dirty && !ino->c_ro) { + if ((buf = (dinode_t *)bread(ino->c_dev, + inodeblock(findfs(ino->c_dev), + ino->c_num), 0)) == NULL) + { +Err: +#if DEBUG > 1 + kprintf("wr_inode() returning -1, error %u\n", udata.u_error); +#endif + return -1; + } + bcopy(&ino->c_node, &buf[inodeoffset(ino->c_num)], + sizeof(dinode_t)); +#if 1 /* Nick */ + /* write immediately, unless dirty_mask set before call */ + if (bfree((bufptr)buf, dirty_mask ? 1 : 2) < 0) +#else + if (bfree((bufptr)buf, 2) < 0) /* write immediately ! */ +#endif + goto Err; + } + ino->c_dirty = 0; /* unmark modif flag */ +#if DEBUG > 1 + kprintf("wr_inode() returning 0, success\n", udata.u_error); +#endif + return 0; +} + +/* I_ref() increases the reference count of the given inode table entry. + */ +void i_ref(inoptr ino) +{ +#if DEBUG > 1 + kprintf("i_ref(%u) starting\n", ino - i_tab); +#endif + + magic(ino, "i_ref"); + if (++ino->c_refs >= 12 * ITABSIZE) /* Arbitrary limit */ + panic(refstoinode, "too many", ino - i_tab); +#if DEBUG > 1 + kprintf("i_ref() returning, refs %u\n", ino->c_refs); +#endif +} + +/* I_deref() decreases the reference count of an inode, and frees it + * from the table if there are no more references to it. If it also + * has no links, the inode itself and its blocks (if not a device) are freed. + */ +void i_deref(inoptr ino) +{ +#if DEBUG > 1 + kprintf("i_deref(%u) starting\n", ino - i_tab); +#endif + + magic(ino, "i_deref"); + if (ino->c_refs == 0) + panic(refstoinode, "no", ino); + if (getmode(ino) == S_IFPIPE) + wakeup(ino); + /* If the inode has no links and no refs, + * it must have its blocks freed. + */ + if (--ino->c_refs == 0) { + if (ino->c_node.i_nlink == 0) { + ino->c_node.i_size = 0; + f_trunc(ino); + /* and also freeing this inode */ + ino->c_node.i_mode = 0; + i_free(ino->c_dev, ino->c_num); + } + /* If the inode was modified, we must write it back to disk. */ + if (ino->c_dirty) + wr_inode(ino); + } +#if DEBUG > 1 + kprintf("i_deref() returning, refs %u\n", ino->c_refs); +#endif +} + +/* I_free() is given a device and inode number, and frees the inode. + * It is assumed that there are no references to the inode in the + * inode table or in the filesystem. + */ +void i_free(dev_t devno, ino_t ino) +{ + register fsptr dev = getfs(devno); + +#if DEBUG > 1 + kprintf("i_free(%u, %u) starting\n", devno, ino); +#endif + + if (ino <= ROOTINODE || ino >= devinodes(dev)) + panic(badinomsg, "i_free", ino); +#if 1 /* Nick free bitmap */ + if (dev->s_bitmap_inode < dev->s_bitmap_block) + { + if (bitmap_set(devno, ino, 0, dev->s_bitmap_inode, + dev->s_bitmap_block) != 1) + { +#if DEBUG > 1 + kprintf("i_free() returning, error\n"); +#endif + return; /* always an i/o error (or very bad !!) */ + } + + ++dev->s_tinode; +#if DEBUG > 1 + kprintf("i_free() returning, success\n"); +#endif + return; /* crude way to skip inode list processing */ + } +#endif + ++dev->s_tinode; /* total free inodes */ + /* account to free inodes list if it's possible */ + if (dev->s_ninode < FSFREEINODES) + dev->s_inode[dev->s_ninode++] = ino; +#if DEBUG > 1 + kprintf("i_free() returning, success\n"); +#endif +} + +/* _namei() is given a string containing a path name, + * and returns an inode table pointer. + * If it returns NULL, the file did not exist. + * If the parent existed, 'parent' will be filled in with the + * parents inoptr. Otherwise, 'parent' will be set to NULL. + */ +#if 0 /* Nick */ +inoptr _namei(uchar *uname, uchar **rest, inoptr strt, inoptr *parent) +#else +inoptr _namei(uchar *name, uchar **rest, inoptr strt, inoptr *parent) +#endif +{ + inoptr temp; + register inoptr ninode; /* next dir */ + register inoptr wd; /* the directory we are currently searching. */ +#if 0 /* Nick */ + char *tb; + char *name; /* Grab a block to copy the name from user space */ + + name = tb = (char *)tmpbuf(); +#if 0 + if (ugets (uname, name, 512)) + { + brelse((bufptr)tb); + return NULLINODE; /* Source String exceeded available length */ + } +#else + ugets (uname, name, 512); /*--*--*/ +#endif +#endif + + ninode = wd = strt; + i_ref(wd); + i_ref(ninode); + for (;;) { + if (ninode != NULL) { + magic(ninode, "_namei"); + /* See if we are at a mount point */ + ninode = srch_mt(ninode); + } + while (*name == '/') /* Skip (possibly repeated) slashes */ + ++name; + if (*name == 0) /* No more components of path? */ + break; + if (ninode == NULL) { /* path not found */ + udata.u_error = ENOENT; + goto Err; + } + if (getmode(ninode) == S_IFLNK) + break; /* symlinks processed separately */ + i_deref(wd); /* drop current dir */ + wd = ninode; /* switch to next inode */ + /* this node must be directory ... */ + if (getmode(wd) != S_IFDIR) { + udata.u_error = ENOTDIR; + goto Err; + } + /* ... enabled for searching */ + if ((getperm(wd) & S_IOEXEC) == 0) { + udata.u_error = EPERM; + goto Err; + } + /* See if we are going up through a mount point */ + if (wd->c_num == ROOTINODE && + wd->c_dev != root_dev && + name[1] == '.') { + /* switch to other fsys */ + temp = findfs(wd->c_dev)->s_mntpt; + i_deref(wd); + i_ref(wd = temp); + } + /* search for next part of path */ + if ((ninode = srch_dir(wd, (char *)name)) == (inoptr)-1) + goto Err; + while (*name != 0 && *name != '/') + ++name; /* skip this part */ + } + *parent = wd; /* store ref to parent */ +#if 0 /* Nick */ + *rest = uname + (name - tb); + brelse((bufptr)tb); +#else + *rest = name; +#endif + return ninode; + +Err: *parent = NULL; + i_deref(wd); +#if 0 /* Nick */ + brelse((bufptr)tb); +#endif + return NULL; +} + +/* namei() is given a string containing a path name, + * and returns an inode table pointer. + * If it returns NULL, the file did not exist. + * If the parent existed, and 'parent' is not null, 'parent' + * will be filled in with the parents inoptr. + * Otherwise, 'parent' will be set to NULL. + * If 'follow' is false then tail symlink is not opened + */ +#if 1 /* Nick */ +inoptr namei(char *uname, inoptr *parent, uchar follow) +#else +inoptr namei(char *name, inoptr *parent, uchar follow) +#endif +{ + register inoptr ino; + inoptr parent1, strt; + uchar *buf = NULL, *buf1 = NULL, *rest, *s; + uchar cnt = 0; +#if 1 /* Nick */ + char *tb; + char *name; /* Grab a block to copy the name from user space */ + +#if 0 + if (uname == NULL) { + udata.u_error = ENOENT; + return NULL; + } +#endif + name = tb = (char *)tmpbuf(); +#if 0 + if (ugets(uname, name, 512)) + { + brelse((bufptr)tb); + return NULLINODE; /* String exceeded available length */ + } +#else + ugets(uname, name, 512); +#endif +#endif + udata.u_error = 0; +#if 0 /* Nick */ + if (name == NULL) { + udata.u_error = ENOENT; + ino = NULL; + goto Ret; + } +#endif + strt = (*name == '/') ? udata.u_root : udata.u_cwd; + while ((ino = _namei((uchar *)name, &rest, strt, &parent1)) != NULL) { + if (getmode(ino) != S_IFLNK || (*rest == 0 && !follow)) { + if (parent != NULL) + *parent = parent1; + else i_deref(parent1); + goto Ret; + } + /* check symlink is readable */ + if (!(getperm(ino) & S_IOREAD)) { + udata.u_error = EPERM; +Err: i_deref(parent1); + i_deref(ino); + ino = NULL; + goto Ret; + } +#if 0 /* NICK TEMPORARY! PLEASE CHANGE THIS BACK! */ + if (!buf) if ((buf = (uchar *)zerobuf()) == NULL) goto Err1; +#else + if (!buf) if ((buf = (uchar *)zerobuf(1)) == NULL) goto Err1; +#endif + if (*rest) { /* need the temporary buffer */ +#if 0 /* NICK TEMPORARY! PLEASE CHANGE THIS BACK! */ + if (!buf1) buf1 = (uchar *)zerobuf(); +#else + if (!buf1) buf1 = (uchar *)zerobuf(0); +#endif + if (!buf1) { +Err1: udata.u_error = ENOMEM; + goto Ret; + } + s = buf1; + while ('\0' != (*s++ = *rest++)) + ; + rest = buf1; + } + else rest = (uchar *)""; /* ! It's important - really "" ! */ + /* readin symlink contents */ + udata.u_count = BUFSIZE; + udata.u_base = (uchar *)buf; + udata.u_offset = 0; +#if 1 /* Nick */ + udata.u_sysio = 1; +#endif + readi(ino); + /* check for buffer size */ + s = rest; + while (*s++ != '\0') + ; + if (udata.u_count + (s - rest) >= BUFSIZE-1) { + udata.u_error = ENOMEM; + goto Err; + } + /* create substituted name */ + s = buf+udata.u_count; + if (*rest) + *s++ = '/'; + while ((*s++ = *rest++) != '\0') + ; + name = (char *)buf; + strt = (*name == '/') ? root_ino : parent1; + if (++cnt == 13) { /* recursion too deep */ + udata.u_error = ELOOP; + goto Err; + } + i_deref(parent1); + i_deref(ino); + } + /* name not found (ino == NULL) */ + if (parent != NULL) + *parent = parent1; /* store ref to parent */ + else { /* we want existent file! */ + if (parent1) + i_deref(parent1); /* deref node */ + if (udata.u_error == 0) + udata.u_error = ENOENT; + } +Ret: if (buf) if (brelse((bufptr)buf) < 0) ino=NULL; + if (buf1) if (brelse((bufptr)buf1) < 0) ino=NULL; +#if 1 /* Nick */ + brelse((bufptr)tb); +#endif + return ino; +} + +/* Srch_dir() is given a inode pointer of an open directory and a string + * containing a filename, and searches the directory for the file. + * If it exists, it opens it and returns the inode pointer, otherwise NULL. + * If an error occur, Srch_dir() returns -1. + * + * This depends on the fact that bread will return unallocated blocks as + * zero-filled, and a partially allocated block will be padded with zeroes. + */ +inoptr srch_dir(inoptr wd, char *name) +{ + ino_t ino; + blkno_t db; + uint cb, ce, nblocks; + register direct_t *bp, *buf; + + nblocks = (uint)(wd->c_node.i_size >> BUFSIZELOG); /* # of full blocks */ + if ((uint)wd->c_node.i_size & (BUFSIZE-1)) + ++nblocks; /* and part of last block */ + cb = 0; + while (cb != nblocks) { + /* map file block to fs */ + if ((db = bmap(wd, cb, 1)) == NULLBLK) + break; + if ((buf = bp = (direct_t *)bread(wd->c_dev, db, 0)) == NULL) +Err1: return (inoptr)-1; + ce = 0; + while (ce < DIRECTPERBLOCK) { + if (namecomp((uchar *)name, bp->d_name)) { + /* file name found */ + ino = bp->d_ino; /* inode of file */ + if (brelse((bufptr)buf) < 0) goto Err1; + /* open the found file */ + return i_open(wd->c_dev, ino); + } + ++ce; + ++bp; + } + if (brelse((bufptr)buf) < 0) /* need next block */ + goto Err1; + ++cb; + } + /* file not found in this directory */ + return NULL; +} + +/* Srch_mt() sees if the given inode is a mount point. + * If so it dereferences it, and references and returns a pointer + * to the root of the mounted filesystem. + */ +inoptr srch_mt(inoptr ino) +{ + register fsptr dev = fs_tab; + + while (dev != fs_tab + NFS) { + if (dev->s_mounted != 0 && dev->s_mntpt == ino) { + i_deref(ino); + ino = i_open(dev->s_dev, ROOTINODE); + /* return replaced inode */ + break; + } + ++dev; + } + return ino; +} + +/* I_open() is given an inode number and a device number, and makes an entry + * in the inode table for them, or increases it reference count if it is + * already there. + * + * An inode == NULLINO means a newly allocated inode. + */ +inoptr i_open(dev_t devno, ino_t ino) +{ + fsptr dev; + dinode_t *buf; + inoptr ip, nindex; + uchar i, newn, mode0; + static inoptr nexti = i_tab; /* rover ptr */ + +#if DEBUG > 1 + kprintf("i_open(%u, %u) starting\n", devno, ino); +#endif + + if ((dev = findfs(devno)) == NULL) + panic(baddevmsg, "i_open", devno); + newn = 0; + if (ino == NULLINO) { /* Wanted a new one */ + if ((ino = i_alloc(devno)) == NULLINO) + goto Err; /* errno is already set by i_alloc */ + ++newn; + } +/* kprintf("ino = %u\n", ino); */ +/* kprintf("dev -> %u\n", dev - fs_tab); */ +/* kprintf("devinodes(dev) = %u\n", devinodes(dev)); */ + if (ino < ROOTINODE || ino >= devinodes(dev)) { + warning(badinomsg, "i_open", ino); + goto Err; + } + /* search inode table for available entry */ + nindex = NULL; + i = 0; + ip = nexti; +/* kprintf("{ "); */ + while (i != ITABSIZE) { + nexti = ip; + if (++ip >= i_tab + ITABSIZE) + ip = i_tab; +/* kprintf("%u ", ip - i_tab); */ + if (ip->c_refs == 0) + nindex = ip; /* candidate for discarding */ + if (ip->c_dev == devno && ip->c_num == ino) { + nindex = ip; +/* kprintf("} "); */ + goto found; /* really found */ + } + ++i; + } +/* kprintf("} "); */ + /* Not already in table - take last candidate */ + if (nindex == NULL) { /* No unrefed slots in inode table */ + udata.u_error = ENFILE; + goto Err; + } +/* kprintf("reading(%u, %u) ", inodeblock(dev, ino), inodeoffset(ino)); */ + /* discard oldest? inode from table and read the inode from disk */ + buf = (dinode_t *)bread(devno, inodeblock(dev, ino), 0); + if (buf == NULL) goto Err; + bcopy(&buf[inodeoffset(ino)], &nindex->c_node, sizeof(dinode_t)); + if (brelse((bufptr)buf) < 0) goto Err; + /* fill-in in-core parts of inode */ + nindex->c_magic = CMAGIC; + nindex->c_dev = devno; + nindex->c_num = ino; + nindex->c_ro = dev->s_ronly; +found: +/* kprintf("found(%u, 0%o) ", nindex->c_node.i_nlink, nindex->c_node.i_mode); */ + mode0 = (getmode(nindex) == 0); + if (newn) { /* RO fs can't do i_alloc()! */ + /* newly allocated disk inode must be clean */ + if (nindex->c_node.i_nlink || !mode0) + goto badino; + } /* and vice versa */ + else if (nindex->c_node.i_nlink == 0 || mode0) + goto badino; + i_ref(nindex); /* yet one ref */ +#if DEBUG > 1 + kprintf("i_open() returning %u, success\n", nindex - i_tab); +#endif + return nindex; + +badino: warning(badinomsg, "i_open (disk)", ino); /* nindex - i_tab); */ +Err: +#if DEBUG > 1 + kprintf("i_open() returning NULL, error %u\n", udata.u_error); +#endif + return NULL; +} + +/* Ch_link() modifies or makes a new entry in the directory for the name + * and inode pointer given. The directory is searched for oldname. + * When found, it is changed to newname, and it inode # is that of *nindex. + * + * An empty oldname ("") matches a unused slot. + * A nindex NULL means an inode #0. + * + * A return status of 0 means there was no space left in the filesystem, + * or a non-empty oldname was not found, or the user did not have write + * permission. + */ +int ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex) +{ + direct_t curentry; + int i; + +#if DEBUG > 1 + kprintf("ch_link(%u, \"%s\", \"%s\", %u) starting\n", + wd - i_tab, oldname, newname, nindex - i_tab); +#endif + + /* Need the write permissions */ + if ((getperm(wd) & S_IOWRITE) == 0) { + udata.u_error = EPERM; + goto Err; + } + /* Search the directory for the desired slot */ + udata.u_offset = 0; /* from beginning */ + for (;;) { + udata.u_base = (uchar *)&curentry; + udata.u_count = sizeof(curentry); +#if 1 /* Nick */ + udata.u_sysio = 1; +#endif + readi(wd); + /* Read until EOF or name is found */ + /* readi() advances udata.u_offset */ + if (udata.u_count == 0 || + namecomp((uchar *)oldname, curentry.d_name)) + break; + } + if (udata.u_count == 0 && *oldname) +#if 1 /* Nick's addition due to a newfile() path which didn't set u_error */ + { + udata.u_error = ENOENT; + goto Err; /* Rename and old entry not found */ + } +#else + goto Err; /* Rename and old entry not found */ +#endif + oldname = (char *)curentry.d_name; + i = sizeof(curentry.d_name); + while (--i >= 0) { + if ('\0' != (*oldname++ = *newname)) + ++newname; + } + curentry.d_ino = nindex ? nindex->c_num : 0; + /* If an existing slot is being used, + * we must back up the file offset + */ + if (udata.u_count > 0) + udata.u_offset -= udata.u_count; + udata.u_base = (uchar *)&curentry; + udata.u_count = sizeof(curentry); + udata.u_error = 0; +#if 1 /* Nick */ + udata.u_sysio = 1; +#endif + writei(wd); /* write back updated directory */ + if (udata.u_error) + { +Err: +#if DEBUG > 1 + kprintf("ch_link() returning 0, error %u\n", udata.u_error); +#endif + return 0; + } + /* Update directory length to next block - simple way to extend dir */ + if ((uint)wd->c_node.i_size & (BUFSIZE-1)) { + wd->c_node.i_size &= ~(BUFSIZE-1); + wd->c_node.i_size += BUFSIZE; + } + setftim(wd, A_TIME | M_TIME | C_TIME); /* And sets c_dirty */ +#if DEBUG > 1 + kprintf("ch_link() returning 1, success\n"); +#endif + return 1; +} + +#if 1 /* Nick */ +/* Filename is given a path name in user space, and copies + * the final component of it to name (in system space). + */ + +void filename(char *upath, char *name) +{ + char *buf; + register char *ptr; +/* Nick char *tmpbuf(); */ +/* Nick int ugets(); */ + + buf = (char *)tmpbuf(); + if (ugets(upath, buf, 512)) + { + brelse((bufptr)buf); + *name = '\0'; + return; /* An access violation reading the name */ + } + ptr = buf; + while (*ptr) + ++ptr; + /* Special case for "...name.../" */ + while (*ptr != '/' && ptr-- > buf) + ; + ptr++; + bcopy(ptr, name, DIRNAMELEN); + brelse((bufptr)buf); +} +#else +/* Filename() is given a path name, and returns a pointer + * to the final component of it. + */ +char *filename(char *path) +{ + register char *ptr = path; + + while (*ptr) /* find end of pathname */ + ++ptr; + while (*ptr != '/' && ptr >= path) + --ptr; /* traverse back */ + return (ptr + 1); +} +#endif + +/* Namecomp() compares two strings to see if they are the same file name. + * It stops at DIRNAMELEN chars or a null or a slash. + * It returns 0 for difference. + */ +int namecomp(uchar *n1, uchar *n2) +{ + uchar n = DIRNAMELEN; + +#if DEBUG > 2 + kprintf("namecomp(\"%s\", \"%s\") starting\n", n1, n2); +#endif + + while (*n1 && *n1 != '/') { + if (*n1++ != *n2++) + goto NotEq; + if (--n == 0) + { +#if DEBUG > 2 + kprintf("namecomp() returning -1, error\n"); +#endif + return (-1); /* first name too long - ignore this */ + } + } + if (*n2 == '\0' || *n2 == '/') + { +#if DEBUG > 2 + kprintf("namecomp() returning -1, match\n"); +#endif + return 1; /* names matched */ + } +NotEq: +#if DEBUG > 2 + kprintf("namecomp() returning 0, no match\n"); +#endif + return 0; +} + +/* Newfile() is given a pointer to a directory and a name, and + * creates an entry in the directory for the name, dereferences + * the parent, and returns a pointer to the new inode. + * + * It allocates an inode number, and creates a new entry in the inode + * table for the new file, and initializes the inode table entry for + * the new file. The new file will have one reference, and 0 links to it. + * + * Better make sure there isn't already an entry with the same name. + */ +inoptr newfile(inoptr pino, char *name) +{ + register inoptr nindex; + +#if DEBUG > 1 + kprintf("newfile(%u, \"%s\") starting\n", pino - i_tab, name); +#endif + + if ((getperm(pino) & S_IOWRITE) == 0) { + udata.u_error = EPERM; +#if DEBUG > 1 + kprintf("newfile() returning NULL, error %u\n", udata.u_error); +#endif + return 0; + } + if ((nindex = i_open(pino->c_dev, NULLINO)) == NULL) + { +#if DEBUG > 1 + kprintf("newfile() returning NULL, error %u\n", udata.u_error); +#endif + goto Ret; /* can't create new inode */ + } + /* fill-in new inode */ + bzero(&nindex->c_node,sizeof(dinode_t)); + nindex->c_node.i_mode = S_IFREG; /* For the time being */ + nindex->c_node.i_nlink = 1; + nindex->c_node.i_uid = udata.u_euid; /* File owner */ + nindex->c_node.i_gid = udata.u_egid; + nindex->c_dirty = 1; + wr_inode(nindex); +#if 1 /* Nick now done by caller */ + if (ch_link(pino, "", name, nindex) == 0) { +#else + if (ch_link(pino, "", filename(name), nindex) == 0) { +#endif + i_deref(nindex); /* can't enter new file to directory */ + nindex = NULL; +#if DEBUG > 1 + kprintf("newfile() returning NULL, error %u\n", udata.u_error); +#endif + } +#if DEBUG > 1 + else + { + kprintf("newfile() returning %u, success\n", nindex - i_tab); + } +#endif +Ret: i_deref(pino); + return nindex; +} + +/* doclose() given the file descriptor and close them */ +int doclose(uchar fd) +{ + register inoptr ino = getinode(fd); + uchar oftindex; + +#if DEBUG > 1 + kprintf("doclose(%u) starting\n", (unsigned int)fd); +#endif + + if (ino == NULL) + { +#if DEBUG > 1 + kprintf("doclose() returning -1, error\n"); +#endif + return (-1); + } + oftindex = udata.u_files[fd]; + if (isdevice(ino) + && ino->c_refs == 1 + && of_tab[oftindex].o_refs == 1) + d_close(DEVNUM(ino)); + udata.u_files[fd] = -1; + oft_deref(oftindex); +#if DEBUG > 1 + kprintf("doclose() returning 0, success\n"); +#endif + return 0; +} + +/* I_alloc() finds an unused inode number, and returns it, + * or NULLINO if there are no more inodes available. + */ +ino_t i_alloc(dev_t devno) +{ + ino_t ino; + blkno_t blk; + register uchar j, k; + dinode_t *buf, *bp; + fsptr dev = getfs(devno); + +#if DEBUG > 1 + kprintf("i_alloc(%u) starting\n", devno); +#endif + + if (dev->s_ronly) { + udata.u_error = EROFS; + goto Err1; + } +#if 1 /* Nick free bitmap */ + if (dev->s_bitmap_inode < dev->s_bitmap_block) + { + ino = bitmap_find(devno, 0, 0, 1, dev->s_bitmap_inode, + dev->s_bitmap_block); + if (ino <= ROOTINODE || ino >= devinodes(dev)) + { + goto Err; /* should distinguish disk i/o errors !! */ + } + + if (dev->s_tinode == 0) + { + goto Corrupt; /* fs is corrupt, not just full! */ + } + + goto found_inode; /* crude way to skip inode list processing */ + } +#endif +Again: if (dev->s_ninode) { /* there are available inodes in list */ + if (dev->s_tinode == 0) + goto Corrupt; /* fs is corrupt, not just full! */ + /* get free inode from list */ + ino = dev->s_inode[--dev->s_ninode]; +#if 1 /* Nick free bitmap */ +found_inode: +#endif + if (ino <= ROOTINODE || ino >= devinodes(dev)) + goto Corrupt; + --dev->s_tinode; +#if DEBUG > 1 + kprintf("i_alloc() returning %u, success\n", ino); +#endif + return ino; + } + /* There are no avilable inodes in list - we must scan the + * disk inodes, and fill up the table + */ + sys_sync(); /* Make on-disk inodes consistent */ + k = 0; + blk = 0; +/* kprintf("[ "); */ + while (blk != dev->s_isize) { + if ((bp = buf = (dinode_t *)bread(devno, blk+dev->s_reserv, 0)) == NULL) + goto Err; + j = 0; + while (j != DINODESPERBLOCK) { + if (bp->i_mode == 0 && bp->i_nlink == 0) +/* { */ +/* kprintf("%d ", blockinodes(blk) + j); */ + dev->s_inode[k++] = blockinodes(blk) + j; +/* } */ + if (k == FSFREEINODES) { + if (brelse((bufptr)buf) < 0) goto Err; + goto Done; + } + ++bp; + ++j; + } + ++blk; + if (brelse((bufptr)buf) < 0) goto Err; + if (k >= DINODESPERBLOCK-2) /* ??? */ + break; + } +Done: +/* kprintf("] "); */ + if (k == 0) { /* no free inodes on disk */ + if (dev->s_tinode) + goto Corrupt; + goto Err; /* not a fatal error, the table is full */ + } + dev->s_ninode = k; + goto Again; + +Corrupt:warning(badfsmsg, "i_alloc", devno); + dev->s_mounted = ~SMOUNTED; /* mark device as bad */ +Err: udata.u_error = ENOSPC; +Err1: +#if DEBUG > 1 + kprintf("i_alloc() returning NULLINO, error %u\n", udata.u_error); +#endif + return NULLINO; +} + +/* Blk_alloc() is given a device number, and allocates an unused block + * from it. A returned block number of zero means no more blocks. + */ +blkno_t blk_alloc(dev_t devno) +{ +#if 1 /* Nick, don't use nf variable unnecessarily */ + char *buf; + blkno_t newno; +#else + count_t nf; + blkno_t *buf, newno; +#endif + register fsptr dev = getfs(devno); +/* int i; */ + +#if DEBUG > 1 + kprintf("blk_alloc(%u) starting\n", devno); +#endif + + if (dev->s_ronly) { + udata.u_error = EROFS; + goto Err1; + } +#if 1 /* Nick free bitmap */ + if (dev->s_bitmap_block < dev->s_bitmap_immov) + { + newno = bitmap_find(devno, 0, 0, 1, dev->s_bitmap_block, + dev->s_bitmap_immov); + if (newno < (dev->s_reserv + dev->s_isize) || + newno >= dev->s_fsize) + { + goto Err; /* should distinguish disk i/o errors !! */ + } + + goto found_block; /* crude way to skip free list processing */ + } +#endif +#if 1 /* Nick, don't use nf variable unnecessarily */ + if (dev->s_nfree <= 0 || dev->s_nfree > FSFREEBLOCKS) + goto Corrupt; +#else + nf = dev->s_nfree; +/* kprintf("nf = %u\n", nf); */ + if (nf <= 0 || nf > FSFREEBLOCKS) +/* { */ +/* kprintf("nf out of range\n"); */ + goto Corrupt; +/* } */ +#endif + if (0 == (newno = dev->s_free[--dev->s_nfree])) { + if (dev->s_tfree != 0) +/* { */ +/* kprintf("dev->s_tfree != 0\n"); */ + goto Corrupt; +/* } */ + ++dev->s_nfree; + goto Err; + } + /* See if we must refill the s_free array */ + if (dev->s_nfree == 0) { + if ((buf = bread(devno, newno, 0)) == NULL) + goto Err; +/* kprintf("buf[0] = %u\n", ((blkno_t *)buf)[0]); */ + dev->s_nfree = ((blkno_t *)buf)[0]; + bcopy(((blkno_t *)buf)+1,dev->s_free,sizeof(dev->s_free)); +/* kprintf("< "); */ +/* for (i = 0; i < dev->s_nfree; i++) */ +/* { */ +/* kprintf("%u ", dev->s_free[i]); */ +/* } */ +/* kprintf("> "); */ + if (brelse((bufptr)buf) < 0) + goto Err; + } +#if 1 /* Nick free bitmap */ +found_block: +#endif + validblk(devno, newno); + if (dev->s_tfree == 0) +/* { */ +/* kprintf("dev->s_tfree == 0\n"); */ + goto Corrupt; +/* } */ + --dev->s_tfree; + /* Zero out the new block */ + if ((buf = bread(devno, newno, 2)) == NULL) /* 2 for zeroing */ + goto Err; + if (bawrite((bufptr)buf) < 0) /* write back */ + goto Err; +#if DEBUG > 1 + kprintf("blk_alloc() returning %u, success\n", newno); +#endif + return newno; + +Corrupt:warning(badfsmsg, "blk_alloc", devno); + dev->s_mounted = ~SMOUNTED; +Err: udata.u_error = ENOSPC; +Err1: +#if DEBUG > 1 + kprintf("blk_alloc() returning 0, error %u\n", udata.u_error); +#endif + return 0; +} + +/* Blk_free() is given a device number and a block number, + * and frees the block. + */ +void blk_free(dev_t devno, blkno_t blk) +{ +#if 1 /* Nick free bitmap */ + blkno_t j; + char *buf, *p; +#else + blkno_t *buf; +#endif + register fsptr dev = getfs(devno); + +#if DEBUG > 1 + kprintf("blk_free(%u, %u) starting\n", devno, blk); +#endif + + if (dev->s_ronly || blk == 0) + { +End: +#if DEBUG > 1 + kprintf("blk_free() returning, error\n"); +#endif + return; + } + validblk(devno, blk); +#if 1 /* Nick free bitmap */ + if (dev->s_bitmap_block < dev->s_bitmap_immov) + { + if (bitmap_set(devno, blk, 0, dev->s_bitmap_block, + dev->s_bitmap_immov) != 1) + { + goto End; /* always an i/o error (or very bad !!) */ + } + +#if 1 /* temporary only... also unreserve the block if it was reserved */ + if (bitmap_set(devno, blk, 0, dev->s_bitmap_immov, + dev->s_bitmap_final) == -1) + { + goto End; /* always an i/o error (or very bad !!) */ + } +#endif + + ++dev->s_tfree; +#if DEBUG > 1 + kprintf("blk_free() returning, success\n"); +#endif + return; /* crude way to skip free list processing */ + } +#endif + /* flushing overflowed free blocks list */ + if (dev->s_nfree == FSFREEBLOCKS) { + buf = bread(devno, blk, 1); + if (buf == NULL) + goto End; + ((blkno_t *)buf)[0] = dev->s_nfree; + bcopy(dev->s_free, ((blkno_t *)buf)+1, sizeof(dev->s_free)); + if (bawrite((bufptr)buf) < 0) + goto End; + dev->s_nfree = 0; + } + ++dev->s_tfree; + dev->s_free[dev->s_nfree++] = blk; +#if DEBUG > 1 + kprintf("blk_free() returning, success\n"); +#endif +} + +/* Oft_alloc() allocate entries in the open file table. + */ +uchar oft_alloc(void) +{ + register ofptr op = of_tab; + uchar j = 0; + +#if DEBUG > 1 + kprintf("oft_alloc() starting\n"); +#endif + + while (j != OFTSIZE) { + if (op->o_refs == 0) { + bzero(op, sizeof(oft_t)); /* zero out all fields */ + op->o_refs++; +#if DEBUG > 1 + kprintf("oft_alloc() returning %u, success\n", (unsigned int)j); +#endif + return j; + } + ++op; + ++j; + } + udata.u_error = ENFILE; +#if DEBUG > 1 + kprintf("oft_alloc() returning -1, error %u\n", udata.u_error); +#endif + return (-1); +} + +/* Oft_deref() dereference (and possibly free attached inode) + * entries in the open file table. + */ +void oft_deref(uchar of) +{ + register ofptr op = of_tab + of; + +#if DEBUG > 1 + kprintf("oft_deref(%u) starting\n", (unsigned int)of); +#endif + + if (--op->o_refs == 0 && op->o_inode != NULL) { + i_deref(op->o_inode); + op->o_inode = NULL; + } +#if DEBUG > 1 + kprintf("oft_deref() returning, refs %u\n", op->o_refs); +#endif +} + +/* Uf_alloc() finds an unused slot in the user file table. + */ +uchar uf_alloc(void) +{ + register uchar j = 0; + register uchar *p = udata.u_files; + +#if DEBUG > 1 + kprintf("uf_alloc() starting\n"); +#endif + + while (j != UFTSIZE) { + if (freefileentry(*p)) + { +#if DEBUG > 1 + kprintf("uf_alloc() returning %u, success\n", (unsigned int)j); +#endif + return j; + } + ++p; + ++j; + } + udata.u_error = ENFILE; +#if DEBUG > 1 + kprintf("uf_alloc() returning -1, error %u\n", udata.u_error); +#endif + return (-1); +} + +/* isdevice() returns true if ino points to a device + * old: !!! assume S_IFBLK == S_IFCHR|any + * new: checks for S_IFBLK and S_IFCHR separately + */ +uchar isdevice(inoptr ino) +{ +#if 1 /* Nick, to avoid conflict with S_IFALIGN and other new filetypes */ + return S_ISDEV(ino->c_node.i_mode); +#else + return (ino->c_node.i_mode & S_IFCHR) != 0; +#endif +} + +/* Freeblk() - free (possible recursive for (double)inderect) block + */ +void freeblk(dev_t dev, blkno_t blk, uchar level) +{ +#if DEBUG > 2 + kprintf("freeblk(%u, %u, %u) starting\n", dev, blk, (unsigned int)level); +#endif + + if (blk != 0) { + if (level != 0) { /* INDERECT/DINDERECT block */ + register blkno_t *buf = (blkno_t *)bread(dev, blk, 0); + uint j; + + --level; + if ((buf) != NULL) { + j = BUFSIZE/sizeof(blkno_t); + while (j != 0) + freeblk(dev, buf[--j], level); + brelse((bufptr)buf); + } + } + blk_free(dev, blk); +#if DEBUG > 2 + kprintf("freeblk() returning, success\n"); +#endif + } +#if DEBUG > 2 + else + { + kprintf("freeblk() returning, error\n"); + } +#endif +} + +/* F_trunc() frees all the blocks associated with the file, + * if it is a disk file. + * need enhancement for truncating to given size + */ +void f_trunc(inoptr ino) +{ + dinode_t *ip = &ino->c_node; + blkno_t *blk = ip->i_addr; + register uchar j; + +#if DEBUG > 1 + kprintf("f_trunc(%u) starting\n", ino - i_tab); +#endif + + /* First deallocate the double indirect blocks */ + freeblk(ino->c_dev, blk[TOTALREFBLOCKS-1], 2); + /* Also deallocate the indirect blocks */ + freeblk(ino->c_dev, blk[TOTALREFBLOCKS-1-DINDIRECTBLOCKS], 1); + /* Finally, free the direct blocks */ + j = 0; + while (j != DIRECTBLOCKS) { + freeblk(ino->c_dev, *blk++, 0); + ++j; + } + bzero(ip->i_addr, sizeof(blkno_t)*TOTALREFBLOCKS); + ino->c_dirty = 1; + ip->i_size = 0; +#if DEBUG > 1 + kprintf("f_trunc() returning\n"); +#endif +} + +/* Bmap() defines the structure of file system storage by returning the + * physical block number on a device given the inode and the logical + * block number in a file. + * + * The block is zeroed if created. + */ +blkno_t bmap(inoptr ip, blkno_t bn, uchar rdflg) +{ + dev_t dev; + register uint i, j, sh; + register blkno_t *bp, nb; + +#if DEBUG > 1 + kprintf("bmap(%u, %u, %u) starting\n", ip - i_tab, bn, (unsigned int)rdflg); +/* kprintf("xx %u %u\n", i_tab[38].c_node.i_addr[3], udata.u_page); */ +#endif + + if (isdevice(ip)) /* block devices */ + { +#if DEBUG > 1 + kprintf("bmap() returning %u, direct\n", bn); +#endif + return bn; /* map directly */ + } + dev = ip->c_dev; + /* blocks 0..DIRECTBLOCKS-1 are direct blocks */ + if (bn < DIRECTBLOCKS) { + bp = &ip->c_node.i_addr[bn]; + if (0 == (nb = *bp)) { + /* block not allocated yet */ + if (rdflg || (nb = blk_alloc(dev)) == 0) + goto Err; + *bp = nb; + ip->c_dirty = 1; + } + goto Ok; + } + /* addresses DIRECTBLOCKS and DIRECTBLOCKS+1 have single and double + * indirect blocks. + * The first step is to determine how many levels of indirection. + */ + bn -= DIRECTBLOCKS; + sh = 0; + j = INDIRECTBLOCKS+DINDIRECTBLOCKS; + if (bn >= BUFSIZE/sizeof(blkno_t)) { /* double indirect */ + sh = 8; /* shift by 8 */ + bn -= BUFSIZE/sizeof(blkno_t); + j -= INDIRECTBLOCKS; + } + /* fetch the address from the inode. + * Create the first indirect block if needed. + */ + bp = &ip->c_node.i_addr[TOTALREFBLOCKS - j]; + if ((nb = *bp) == 0) { + if (rdflg || 0 == (nb = blk_alloc(dev))) + goto Err; + *bp = nb; + ip->c_dirty = 1; + } + /* fetch through the indirect blocks */ + while (j <= INDIRECTBLOCKS+DINDIRECTBLOCKS) { + if ((bp = (blkno_t *)bread(dev, nb, 0)) == NULL) + { +Err: +#if DEBUG > 1 + kprintf("bmap() returning NULLBLK, error %u\n", udata.u_error); +#endif + return NULLBLK; + } + i = (bn >> sh) & (BUFSIZE/sizeof(blkno_t)-1); + if ((nb = bp[i]) != 0) { + if (brelse((bufptr)bp) < 0) + goto Err; + } else { + if (rdflg || 0 == (nb = blk_alloc(dev))) { + brelse((bufptr)bp); + goto Err; + } + bp[i] = nb; + if (bawrite((bufptr)bp) < 0) + goto Err; + } + sh -= 8; + ++j; + } +Ok: +#if DEBUG > 1 + kprintf("bmap() returning %u, success\n", nb); +#endif + return nb; +} + +/* Validblk() panics if the given block number is not a valid data block + * for the given device. + */ +void validblk(dev_t devno, blkno_t num) +{ + register fsptr dev = findfs(devno); + + if (dev == NULL) + panic("validblk: dev %p not mounted",dev); + if (num < dev->s_isize + dev->s_reserv || num >= dev->s_fsize) + panic("validblk: invalid block %u", num); +} + +/* Getinode() returns the inode pointer associated with a user's + * file descriptor, checking for valid data structures + */ +inoptr getinode(uchar uindex) +{ + register inoptr inoindex; + uchar oftindex = udata.u_files[uindex]; + + if (uindex >= UFTSIZE || freefileentry(oftindex)) { + udata.u_error = EBADF; + return (NULL); + } + if (oftindex >= OFTSIZE) + panic(gtinobadoft, oftindex, " for", uindex); + if ((inoindex = of_tab[oftindex].o_inode) < i_tab || + inoindex >= i_tab + ITABSIZE) + panic(gtinobadoft, oftindex, ", inode", inoindex); + magic(inoindex, "getinode"); + return inoindex; +} + +/* Getperm() looks at the given inode and the effective user/group ids, and + * returns the effective permissions in the low-order 3 bits. + */ +int getperm(inoptr ino) +{ + mode_t mode = ino->c_node.i_mode; + + if (super()) + mode |= S_ISDEV(mode) ? (mode >> 3) | (mode >> 6) : 07; + else { + if (ino->c_node.i_uid == udata.u_euid) mode >>= 6; /* owner */ + else if (ino->c_node.i_gid == udata.u_egid) mode >>= 3; /* group */ + } + return (mode & 07); +} + +/* Setftim() sets the times of the given inode, according to the flags + */ +void setftim(inoptr ino, uchar flag) +{ + static time_t t; + + rdtime(&t); + if (flag & A_TIME) ino->c_node.i_atime = t; + if (flag & M_TIME) ino->c_node.i_mtime = t; + if (flag & C_TIME) ino->c_node.i_ctime = t; + ino->c_dirty = 1; +} + +/* Fmount() places the given device in the mount table with mount point ino + */ +int fmount(dev_t dev, inoptr ino, bool_t roflag) +{ + char *buf; + register fsptr fp = fs_tab; + +#if 0 /* NICK TEMPORARY! PLEASE CHANGE THIS BACK! */ + if (!validdev(dev)) { +#else + if (!validdev(dev,NULL)) { +#endif + udata.u_error = ENODEV; + goto Err1; /* ENODEV */ + } + if (MAJOR(dev) >= BLK_DEVS) + goto Err; + /* Lookup free slot in mounted fs table */ + while (fp != fs_tab+NFS) { + if (fp->s_dev == dev && fp->s_mounted != 0) { + udata.u_error = EBUSY; + goto Err1; + } + ++fp; + } + while (fp != fs_tab) { + --fp; + if (fp->s_mounted == 0) + goto Ok; + } + udata.u_error = ENOMEM; + goto Err1; + /* temporarly lock the slot */ +Ok: fp->s_mounted = ~SMOUNTED; + fp->s_dev = dev; + if (d_open(dev) != 0) + panic("fmount: can't open fs on %p", dev); +#if 0 /* routine to search for the starting position within a FAT/FAT32 fs */ + { + register int i; + for (i = SUPERBLOCK; i < 0x400; ++i) + { + kprintf("reading sector 0x%x\n", i); + buf = bread(dev, i, 0); + if (*(int *)buf == SMOUNTED) + { + kprintf("formatted at sector 0x%x\n", i - SUPERBLOCK); + panic("stop"); + } + brelse((bufptr)buf); + } + } +#endif + /* read in superblock */ + buf = (char *)bread(dev, SUPERBLOCK, 0); + if (buf == NULL) goto Err1; + bcopy(buf, fp, sizeof(filesys_t)); + /* fill-in in-core fields */ + fp->s_ronly = roflag; + fp->s_dev = dev; + fp->s_fmod = 0; + if (brelse((bufptr)buf) < 0) goto Err1; + /* See if there really is a filesystem on the device */ + if (fp->s_mounted != SMOUNTED || fp->s_isize >= fp->s_fsize) { + fp->s_mounted = 0; /* free fs table entry */ +Err: udata.u_error = ENOTBLK; +Err1: return (-1); + } + if ((fp->s_mntpt = ino) != NULL) + i_ref(ino); +/* fp->s_reserv = 2; */ + return 0; +} + +/* magic() check inode against corruption + */ +void magic(inoptr ino, char *who) /* Nick added who */ +{ + if (ino->c_magic != CMAGIC) + panic("%s: corrupted inode %p", who, ino); /* Nick added who */ +} + +/* i_sync() syncing all inodes + */ +void i_sync(void) +{ + register inoptr ino = i_tab; + + /* Write out modified inodes */ + ++dirty_mask; + while (ino != i_tab + ITABSIZE) { + if (ino->c_magic == CMAGIC && + ino->c_dirty != 0 && + ino->c_refs > 0) + wr_inode(ino); + ++ino; + } +#if 1 /* Nick */ + --dirty_mask; +#endif + bufsync(); +} + +/* fs_sync() syncing all superblocks + */ +void fs_sync(void) +{ + register fsptr fp = fs_tab; + register bufptr buf; + + /* Write out modified super blocks + * old: This fills the rest of the super block with zeros + * new: This preserves the remaining bytes of the superblock + */ + while (fp != fs_tab+NFS) { + if (fp->s_mounted && fp->s_fmod) { +#if 1 /* Nick free bitmap */ + buf = (bufptr)bread(fp->s_dev, SUPERBLOCK, 0); +#else + buf = (bufptr)bread(fp->s_dev, SUPERBLOCK, 2); +#endif + if (buf != NULL) { + fp->s_fmod = 0; + bcopy(fp, buf, sizeof(*fp)); + if (bfree(buf, 1) < 0) + fp->s_fmod = 1; + } + } + ++fp; + } + bufsync(); +} + diff --git a/src/kernel/uzi/filesys.h b/src/kernel/uzi/filesys.h new file mode 100755 index 00000000..856fdbb3 --- /dev/null +++ b/src/kernel/uzi/filesys.h @@ -0,0 +1,42 @@ +/* filesys.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __FILESYS_H +#define __FILESYS_H + +fsptr findfs(dev_t devno); +fsptr getfs(dev_t devno); +int wr_inode(inoptr ino); +void i_ref(inoptr ino); +void i_deref(inoptr ino); +void i_free(dev_t devno, ino_t ino); +inoptr _namei(uchar *name, uchar **rest, inoptr strt, inoptr *parent); +inoptr namei(char *uname, inoptr *parent, uchar follow); +inoptr srch_dir(inoptr wd, char *name); +inoptr srch_mt(inoptr ino); +inoptr i_open(dev_t devno, ino_t ino); +int ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex); +void filename(char *upath, char *name); /* char *filename(char *path); */ +int namecomp(uchar *n1, uchar *n2); +inoptr newfile(inoptr pino, char *name); +int doclose(uchar fd); +ino_t i_alloc(dev_t devno); +blkno_t blk_alloc(dev_t devno); +void blk_free(dev_t devno, blkno_t blk); +uchar oft_alloc(void); +void oft_deref(uchar of); +uchar uf_alloc(void); +uchar isdevice(inoptr ino); +void freeblk(dev_t dev, blkno_t blk, uchar level); +void f_trunc(inoptr ino); +blkno_t bmap(inoptr ip, blkno_t bn, uchar rdflg); +void validblk(dev_t devno, blkno_t num); +inoptr getinode(uchar uindex); +int getperm(inoptr ino); +void setftim(inoptr ino, uchar flag); +int fmount(dev_t dev, inoptr ino, bool_t roflag); +void magic(inoptr ino, char *who); +void i_sync(void); +void fs_sync(void); + +#endif /* __FILESYS_H */ + diff --git a/src/kernel/uzi/flopasm.asm b/src/kernel/uzi/flopasm.asm new file mode 100755 index 00000000..66de08a4 --- /dev/null +++ b/src/kernel/uzi/flopasm.asm @@ -0,0 +1,714 @@ +;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +; YASBEC Floppy disk Routines for Modified DP8473 Controller +; Copyright (C) 1998 by Harold F. Bower +;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + public _fdInit, _dTbl, _FdcCk ; PUBlic + public _fdread0, _fdwrite0 ; " + public _ftrack, _fsector, _ferror, _fbuf ; " + + extern _ub ; in data.c + extern _ei ; in machasm.asz + + .if 1 ; IAR + extern ?BANK_CALL_DIRECT_L08 + .endif + +$ asmdef.inc + + rseg CODE +;------------------------------------------------------------ +; 9 May 1998 - Initial Version HFB +;------------------------------------------------------------ +; This module uses Polled IO with a National DP8473 grafted on a +; YASBEC in place of the Western Digital FD1772. If your system +; uses Interrupts, place the Interrupt handler in high memory +; within the COMMON base in MACHASM, and declare the label GLOBAL. +;------------------------------------------------------------ +; DESIGN NOTES: +; This module assumes that only MFM recorded disks will be +; used. Consequently, Single-Density is not supported although +; it could easily be added. Also, only sector sizes of 512 and +; 1024 bytes are accomodated to minimize deblocking code and +; further simplify the module. +; Formats and drive parameters are coded in a table, one for +; each drive attached to the system. They may be accessed and +; changed by the ioctl function for the desired device, just as +; TTY terminal characteristics. +;------------------------------------------------------------- +; The modified YASBEC Uses only one bit of Port 40H (FDCTRL) +; Control Port as: +; Bit 7 6 5 4 3 2 1 0 (Write Only) +; | | | | | | | | +; | | | +-+-+-+-+-- (unused) +; | | +------------ Speed/Density +; | | 3.5" - 1=Normal MFM, 0=Hi-Speed/Density +; | | 5.25" - Same if strapped as IBM PC "HD" +; +-+-------------- (unused) +; +; Floppy Units on the modified YASBEC using IO addresses derived +; from the original FD-1772 controller. The software uses Polled +; IO to access the National DP8473 Controller. I/O addresses used +; by the Controller are: +; +; 068, 069 - (Not Used, Tri-State) +; 06A - Drive Control Register (Write Only) +; 7 6 5 4 3 2 1 0 +; | | | | | | +-+-- Drive (00=0, 01=1, 10=2, 11=3) +; | | | | | +------ 1 = Normal Opn, 0 = Reset Controller +; | | | | +-------- 1 = Enable DMA Pins, 0 = Disable DRQ,DAK,INT pins +; | | | +---------- 1 = Enable Drive 0 Motor +; | | +------------ 1 = Enable Drive 1 Motor +; | +-------------- 1 = Enable Drive 2 Motor +; +---------------- 1 = Enable Drive 3 Motor +; 06B - (Not Used, Tri-State) +; 06C - Main Status Register (Read Only) +; 7 6 5 4 3 2 1 0 +; | | | | +-+-+-+-- Drives Seeking (0=B0 Set, 1=B1 Set,.. 3=B3 Set) +; | | | +---------- 1 = Command In Progress, 0 = Command Ended +; | | +------------ 1 = Non-DMA Execution, 0 = DMA Execution +; | +-------------- 1 = Read, 0 = Write +; +---------------- 1 = Request for Master, 0 = Interal Execution +; 06D - Data Register (Read/Write) +; 06E - (Not Used, Tri-State) +; 06F - Data Rate Register (Write) / Disk Changed Bit (Read) +; 7 6 5 4 3 2 1 0 (Write) +; | | | | | | +-+-- 00=500 kb/s, RPM/LC Hi, 01=250/300 kb/s (RPM/LC Lo) +; | | | | | | 10=250 kb/s, RPM/LC Lo, 11=1000 kb/s (RPM/LC Hi/Lo) +; +-+-+-+-+-+------ (Not Used) +; +; 7 6 5 4 3 2 1 0 (Read) +; | +-+-+-+-+-+-+-- (Tri-State, used for HD Controller) +; +---------------- 1 = Disk Changed (latched complement of DSKCHG inp) + +FDCTRL EQU 40H ; Floppy Drive Control Register. B5 sets + ; Pin 2 on Floppy (Hi/Reg Density) +FDCBAS EQU 68H ; 1772/DP8473 Controller Base Address +DCR EQU FDCBAS+2 ; Drive Control Register +MSR EQU FDCBAS+4 ; Main Status Register +DR EQU FDCBAS+5 ; Data Register +DRR EQU FDCBAS+7 ; Data Rate Register/Disk Changed Bit in B7 + +MONTIM EQU 10*20 ; Motor On time (Seconds * TICKSPERSEC) + +; Offsets in Drive Data Table (defined at end of this module) +oFLG EQU 0 ; 0 = Not Logged, 1 = Drive Logged +oPRM1 EQU 1 ; Step Rate (B7-4), HUT (3-0) +oPRM2 EQU 2 ; Hd Load in 4mS steps (0=infinite) +oGAP3 EQU 3 ; Gap 3 Length for Read +oSPT EQU 4 ; Sectors-per-Track +oSEC1 EQU 5 ; First Sector Number +oFMT EQU 6 ; Bit-mapped Format byte +oSPIN EQU 7 ; Spinup delay (1/20-secs) +oTRK EQU 8 ; Current Head Position (Track) + +;------------------------------------------------------------- +; Determine if the controller exists and a drive is attached +; fdInit (int minor); +; Enter: Drive Minor # is on Stack +; Exit : HL = 0 if All is Ok, Non-Zero if Error + +_fdInit: + LD A,(_ub+OSYS) ; Get Current System Flag + LD (sysSav),A ; (save) + LD A,1 ; Indicate we are in System Mode + LD (_ub+OSYS),A + + xor a + ld (motim),a ; Mark Motors as initially OFF + + POP HL ; Return Addr + POP BC ; minor + PUSH BC ; Keep on Stack for Exit + PUSH HL + LD A,C + LD (drive),A ; Save Desired Device + CP 4 ; Legal? + JR NC,NoDrv ; ..Exit if Error + CALL LWRD ActivA ; Else force Reset (B2=0) + LD B,0 + DJNZ $ ; (settle) + CALL LWRD Activ8 ; then bring out of Reset + DJNZ $ ; (settle, B already =0) + IN A,(MSR) + CP 80H ; Do we have correct Ready Status? + JR NZ,NoDrv ; ..exit Error if Not + + LD A,(drive) + CALL LWRD GetPrm ; Pt to this drive's table entry + PUSH HL + POP IY + LD (IY+oFLG),0 ; Insure drive is Unlogged + CALL LWRD Spec ; Set Controller Params + JR C,NoDrv ; ..Error if TimeOut, Else.. + CALL LWRD Recal ; Recalibrate (home) Drive + JR NZ,NoDrv ; ..Error if it failed + LD (IY+oFLG),01H ; Mark Drive as Active + LD HL,0 ; Load Ok Status +fdIEx: LD A,(sysSav) ; Get Entry Insys Flag + LD (_ub+OSYS),A ; Restore + RET + +NoDrv: LD HL,-1 ; Set Error Status + JR fdIEx ; ..Exit + +;------------------------------------------------------------- +; This routine Reads/Writes data from buffer trying up to 4 times +; before giving up. If an error occurs after the next-to-last +; try, the heads are homed to force a re-seek. +; +; Enter: None. Entry Point sets Read/Write Flag +; Exit : A = 0, Zero Set if Ok, A <> 0, Zero Reset if Errors +; Uses : AF,HL + +_fdread0: + LD A,1 + DEFB 21H ;..Trash HL, fall thru.. +_fdwrite0: + LD A,0 + LD (rdOp),A + + LD A,(_ub+OSYS) ; Get Current System Flag + LD (sysSav),A ; (save) + LD A,1 ; Indicate we are in System Mode + LD (_ub+OSYS),A + + CALL LWRD Setup ; Set up subsystem +;;-- LD HL,buffer ; Point to the host buffer +;;-- LD (actDma),HL ; and set Memory Pointer + + LD A,4 ; Get the maximum retry count +Rwf1: LD (rwRtry),A + LD D,0FFH ; (Verify needed) + CALL LWRD SEEK ; Try to seek to the desired track + JR NZ,Rwf2 ; ..jump if No Good + + LD A,(rdOp) + OR A ; Read operation? + JR Z,SWrite ; No, must be Write + + LD A,06H ; Load DP8473 Read Command + DEFB 21H ; Trash HL w/load of write comnd +SWrite: LD A,05H ; Load DP8473 Write Command + OR 01000000B ; Set MFM Mode Bit + PUSH BC ; Save Regs + LD C,A ; Save + LD B,9 ; Read/Write Comnds are 9 bytes + + LD A,(eot) ; Get Last Sctr # + PUSH AF ; (save for Exit) + LD A,(sect) ; Get Desired Sector # + LD (eot),A ; make last to Read only one Sector + +;;-- LD HL,(actDma) ; Get actual DMA Addr + ld hl,(_fbuf) ;;-- + CALL LWRD FdCmd ; Execute Read/Write + + POP AF ; Restore Last Sctr # + LD (eot),A ; to Comnd Blk + + LD A,(st1) ; Get Status Reg 1 + AND 34H ; Return Any Error Bits + POP BC ; Restore Regs + LD (_ferror),A ; (store Error bits) + JR Z,FhdrX ; ..jump to return if No Errors + +Rwf2: LD A,(rwRtry) ; Get retry count + CP 2 ; Are we on Next to last try? + CALL Z,LWRD Recal ; Return to Track 0 if so + LD A,(rwRtry) ; and re-fetch try count + DEC A ; Do we have more retries left? + JR NZ,Rwf1 ; ..jump to try again if more tries remain + + OR 0FFH ; Else show Error +FhdrX: PUSH AF ; Save Status + LD A,(sysSav) + LD (_ub+OSYS),A ; Reset Insys flag to entry + .if 1 ; IAR + ld hl,LWRD _ei + ld a,BYTE3 _ei + call ?BANK_CALL_DIRECT_L08 + .else + CALL _ei ; reset Ints to desired state + .endif + POP AF ; Get return status back + RET ; and Exit + +;------------------------------------------------------------- +; SPEC - Do a Specify Command, setting Step Rate and Head +; Load/Unload Time. Settings require tailoring to Drive. +; +; Enter: IY -> Drive Table entry for current drive +; Exit : Nothing +; Uses : AF,BC + +Spec: CALL LWRD WRdyT ; Wait for RQM (hope DIO is Low!), Disable Ints + RET C ; ..Error if Timed Out + LD A,03H ; Do an FDC Specify Command + OUT (DR),A + + CALL LWRD WRdyT + RET C ; ..Error if Timed Out + LD A,(IY+oPRM1) ; first Rate Byte (Step Rate, HUT) + OUT (DR),A + + CALL LWRD WRdyT + RET C ; ..Error if Timed Out + LD A,(IY+oPRM2) ; Get Head Load Time + ADD A,A ; Shift value left (doubles count) + INC A ; Set LSB for Non-DMA Operation + OUT (DR),A +;;;== CALL _ei ; Re-enable Ints if Not Insys + XOR A ; Return Ok Flag + RET + +;------------------------------------------------------------- +; RECAL Recalibrate Current "drive" (moves heads to track 0). +; Enter : IY -> Current Drive Table Entry +; Variable "drive" set to desired floppy unit +; Return: A = 0 if Ok, NZ if Error. Flags reflect A +; Uses : AF All other Registers Preserved/Not Affected +; +; NOTE: BC Must be preserved by this routine. + +Recal: LD A,(drive) ; Place drive + LD (hdr),A ; in Command Block + LD A,3 ; Give this 3 chances to Home +Recal1: LD (retrys),A + PUSH BC ; Save needed regs + LD BC,2*256+07H ; (2-byte Recalibrate Comnd = 07H) + CALL LWRD FdCmd ; execute Recalibrate + CALL LWRD FdcDn ; Clear Pending Ints, Wait for Seek Complete + POP BC ; (restore regs) + AND 00010000B ; Homed? (B4=1 if No Trk0 found) + JR Z,RecOk ; ..jump to Store if Ok + LD A,(retrys) + DEC A ; Any trys left? + JR NZ,Recal1 ; ..loop if So + DEC A ; Else set Error Flag (0-->FF) + RET + +RecOk: XOR A ; Get a Zero (track / flag) + LD (IY+oTRK),A ; Set in Table + RET ; and return + +;------------------------------------------------------------- +; READID - Read the first Valid Address Mark on a track. +; +; Enter : "hdr" byte set in Command Blk +; Return: A = 0 if Ok, NZ if Error. Flags reflect A +; Uses : AF All other Registers Preserved/Not Affected + +ReadID: LD A,01001010B ; Load ReadID Command + MFM Mode byte + ; ||||++++- 0AH = ReadID Command + ; ||++----- (unused) + ; |+------- 1 = MFM Mode, 0 = FM Mode + ; +-------- (unused) + PUSH BC ; Save regs + LD B,2 ; two bytes in ReadID Command + LD C,A ; move Command to C + CALL LWRD FdCmd ; Activate DP8473 FDC + + LD A,(st1) ; Get Status Reg 1 + AND 25H ; Return Any Error Bits + POP BC ; Restore regs + RET ; ..and quit + +;------------------------------------------------------------- +; SETUP - Set parameters necessary to Read/Write from Active Drive +; Enter: Variable "drive" set to current Drive (0..3) +; Variables _ftrack and _fsector set to desired block address +; Exit : IY -> Drive's Table entry +; Uses : AF,BC,HL + +Setup: LD A,(drive) + PUSH AF + CALL LWRD GetPrm ; Pt to Current Drive's Table + PUSH HL + POP IY + POP BC + LD A,(active) ; Get current Activation Byte + AND 11110000B ; keep only motors + OR B ; add drive bits + CALL LWRD Activ8 ; save new byte and activate FDC + LD A,(_ftrack) ; Get Host Track # + SRL A ; Div by 2 (LSB to Carry) + LD (trk),A ; Physical Track # to Comnd Blk + LD A,0 + ADC A,A ; LSB becomes Head # + LD (hd),A ; save in Comnd Blk + ADD A,A + ADD A,A ; Shift to B3 + LD HL,drive + OR (HL) ; add Drive bits + LD (hdr),A ; Save in Comnd Blk + LD A,(IY+oGAP3) + LD (gpl),A ; Set Gap3 Length + LD A,(IY+oSPT) + LD (eot),A ; Final Sector # on Trk + LD A,(IY+oFMT) + AND 0011B ; B0/1 of Format byte is Sector Size + LD (rsz),A ; save in Comnd Blk + LD A,0FFH + LD (dtl),A ; Set Data Length code + LD A,(_fsector) + ADD A,(IY+oSEC1) ; Offset Sector # (base 0) by 1st Sector # + LD (sect),A ; set in Comnd Blk + + LD A,(IY+oFMT) ; Get Format bits + AND 00001100B ; Save only Drive Size bits + BIT 7,(IY+oFMT) + JR Z,StSiz0 ; ..jump if Lo-Speed/Lo-Density (Drv Size in A) + + SUB 00001100B ; 3.5"? (prepare 00H for 3.5" HD) + JR Z,StSiz2 ; ..jump if Yes + LD A,00100000B ; Else make 5.25" HD + JR StSiz2 ; ..continue to Set + +StSiz0: CP 00001100B ; 3.5" (normal MFM)? + JR Z,StSiz1 ; ..jump if Yes to Set + + LD A,00100001B ; (Prepare for 5.25" HD MFM at 300 kbps) + BIT 4,(IY+oFMT) + JR NZ,StSiz2 ; ..jump if HD at Low rate +StSiz1: LD A,00100010B ; Load normal 250 kbps MFM Flags +StSiz2: OUT (FDCTRL),A ; Set Density Line (Bit 5, rest ignored) + AND 00000011B ; mask off control line + OUT (DRR),A ; and Set Rate in FDC Reg + RET + +;------------------------------------------------------------- +; SEEK - Set the Track for disk operations and seek to it. +; +; Enter : A = Desired Track Number +; D = Verify flag (0=No, FF=Yes) +; Return: A = 0, Zero Flag Set (Z) if Ok, A <> 0 Zero Clear (NZ) if Error +; Uses : AF All other Registers Preserved/Not Affected + +SEEK: PUSH HL ; Save Regs used here + PUSH DE + PUSH BC + + LD A,(trk) ; Get Track # + CP (IY+oTRK) ; Is desired Track same as last logged? + LD (IY+oTRK),A ; (set as if we made it there) + JR NZ,SEEKNV ; ..jump if Not Same + INC D ; Else Set to No Verify (FF->0) +SEEKNV: LD A,4 ; Get the maximum Retry Count +SEEK1: LD (retrys),A ; save remaining Retry Count + LD BC,3*256+0FH ; (3-byte Seek Command = 0FH) + CALL LWRD FdCmd ; Execute the Seek + CALL LWRD FdcDn ; Clear Pending Int, wait for Seek Complete + AND 01000000B ; Set NZ if Abnormal Termination + + INC D ; Are we Verifying (FF -> 0)? + CALL Z,LWRD ReadID ; Read next ID Mark if So + DEC D ; (Correct for Test, 0 -> FF) + + OR A ; Set Status (Seek Status if No ReadID) + JR Z,SEEKX ; ..exit if Ok + + LD A,(retrys) ; Else get trys remaining + DEC A ; Any left (80-track could need two)? + JR NZ,SEEK1 ; ..loop to try again if More + DEC A ; Else set Error Flag (0->FF) + +SEEKX: POP BC ; Restore Regs + POP DE + POP HL + RET + +;------------------------------------------------------------- +; FDCMD - Send Command to DP-8473 FDC +; Enter: B = # of Bytes in Command, C = Command Byte +; HL -> Buffer for Read/Write Data (If Needed) +; Exit : AF = Status byte +; Uses : AF. All other registers preserved/unused + +FdCmd: PUSH HL ; Save regs (for Exit) + PUSH BC + PUSH HL ; save pointer for possible Transfer + CALL LWRD Motor ; Insure motors are On + LD HL,comnd ; Point to Command Block + LD (HL),C ; command passed in C + LD C,DR ; DP8473 Data Port +OtLoop: CALL LWRD WRdy ; Wait for RQM (hoping DIO is Low) (No Ints) + OUTI ; Output Command bytes to FDC + JR NZ,OtLoop ; ..loop til all bytes sent + + POP HL ; Restore Possible Transfer Addr +FdCi1: CALL LWRD WRdy + BIT 5,A ; In Execution Phase? + JR Z,FdcRes ; ..jump if Not to check result + BIT 6,A ; Write? + JR NZ,FdCi2 ; ..jump if Not to Read + OUTI ; Else Write a Byte from (HL) to (C) + JR FdCi1 ; and check for next + +FdCi2: INI ; Read a byte from (C) to (HL) + JR FdCi1 ; and check for next + +FdcRes: LD HL,st0 ; Point to Status Result area +IsGo: CALL LWRD WRdy +;;; EI ; (Ints Ok now) + BIT 4,A ; End of Status/Result? + JR Z,FdcXit ; ..exit if So + BIT 6,A ; Another byte Ready? + JR Z,FdcXit ; ..exit if Not + INI ; Else Read Result/Status Byte + JR IsGo ; ..loop for next + +FdcXit: POP BC ; Restore Regs + POP HL + RET + +;------------------------------------------------------------- +; Check for Proper Termination of Seek/Recalibrate Actions by +; executing a Check Interrupt Command returning ST0 in A. +; Enter: None. Used after Seek/Recalibrate Commands +; Exit : AF = ST0 Result Byte +; Uses : AF. All other registers preserved/unused + +FdcDn: PUSH HL ; Don't alter regs +FdcDn0: CALL LWRD WRdy1 + LD A,8 ; Sense Interrupt Status Comnd + OUT (DR),A + CALL LWRD WRdy1 + IN A,(DR) ; Get first Result Byte (ST0) + LD L,A + CP 80H ; Invalid Command? + JR Z,FdcDn0 ; ..jump to exit if So + CALL LWRD WRdy1 + IN A,(DR) ; Read Second Result Byte (Trk #) + LD A,L + BIT 5,A ; Command Complete? + JR Z,FdcDn0 ; ..loop if Not + POP HL + RET + +;------------------------------------------------------------- +; MOTOR CONTROL. This routine performs final selection of +; the drive control latch and determines if the Motors are +; already spinning. If they are off, then the Motors are +; activated and the spinup delay time in tenths-of-seconds +; is performed before returning. +; +; Enter : None +; Return: None +; Uses : HL. Remaining Registers Preserved/Not Affected + +Motor: PUSH AF ; Save Regs + LD A,(motim) ; Get remaining Seconds + OR A ; Already On? + LD A,MONTIM ; (get On Time) + LD (motim),A ; always reset + JR NZ,MotorX ; ..exit if already running + PUSH BC + LD A,(hdr) ; Get current Drive + OR 11110100B ; Set All Motors On and Controller Active + CALL LWRD Activ8 ; Do It! + LD A,(drive) ; Get Current drive + CALL LWRD GetPrm ; Pt to Param table + LD BC,oSPIN + ADD HL,BC ; offset to Spinup Delay + LD A,(HL) ; Get value + LD (mtm),A ; to GP Counter + EI ; Insure Ints are ABSOLUTELY Active.. +MotoLp: LD A,(mtm) ; ..otherwise, loop never times out! + OR A ; Up to Speed? + JR NZ,MotoLp ; ..loop if Not + di ;;; + POP BC +MotorX: POP AF ; Restore Reg + RET + +;------------------------------------------------------------- +; Wait for FDC RQM to become Ready with Timeout indicator. +; Timeout Length is arbitrary and depends on CPU Clock Rate. + +WRdyT: DI ; No Ints while we are doing I/O + LD BC,25000 ; << Arbitrary >> +WRdyT0: DEC BC + LD A,B + OR C ; Timed Out? + SCF ; (set Error Flag in case) + RET Z ; ..return Error Flag if Yes + IN A,(MSR) ; Read Status Reg + AND 80H ; Interrupt Present (also kill Carry)? + RET NZ ; ..return Ok if Yes + JR WRdyT0 ; ..else loop to try again + +;------------------------------------------------------------- +; Wait for FDC RQM to become Ready, return DIO status in +; Zero Flag. Pause before reading status port (~12 mS +; specified, some assumed in code). + +WRdy: DI ; No Ints while we are doing I/O +WRdy1: ; (entry to avoid Disabling Ints) +;; LD A,(SPEED) ; Get Speed in MHz (Constant) +;; CP 12+1 ; Are we in Turbo Mode (probably)? +;; JR C,WRdyL ; ..jump if probably NOT +;; SRL A ; Else divide +;; SRL A ; by 4 +;;WRdy0: DEC A ; count down +;; JR NZ,WRdy0 ; for ~6 uS Delay +WRdyL: IN A,(MSR) ; Read Main Status Register + BIT 7,A ; Interrupt Present? + RET NZ ; Return if So + JR WRdyL ; Else Loop + +;------------------------------------------------------------- +; Return Pointer to Parameters of selected Drive +; Enter: A = Drive (0..3) +; Exit : HL -> Parameter entry of drive +; Uses : AF,HL + +GetPrm: PUSH DE + LD DE,TBLSIZ ; Entry Size + LD HL,_dTbl ; Init to table start + INC A +GetPr0: DEC A ; End? + JR Z,GetPrX ; ..quit if Yes, Ptr set + ADD HL,DE ; Else step to next + JR GetPr0 ; ..loop til found + +GetPrX: POP DE + RET + +;------------------------------------------------------------- +; This routine called at each Clock Interrupt. It is used +; to provide any necessary timer/timeout functions. +; Enter: None. +; Exit : HL -> mtm byte variable +; AF - destroyed +; Uses : AF,HL + +_FdcCk: LD HL,motim ; Point to FDC Motor-On timer + LD A,(HL) + OR A ; Already Timed out? + JR Z,TDone ; ..jump if Yes + DEC (HL) ; Else count down + CALL Z,LWRD MotOff ; stop motors if timed out +TDone: INC HL ; Advance ptr to watchdog/spinup timer (mtm) + LD A,(HL) + OR A ; Timed out? + RET Z ; ..quit if Yes + DEC (HL) ; Else count down + RET ; exit + +;------------------------------------------------------------- +; Motor Off routine. Force Off to delay on next select +; Enter: None. (Motoff) +; A = FDC Device Control Reg bits (Activ8/ActivA) +; Exit : A = Current DCR Register / "active" byte settings +; Uses : AF + +MotOff: XOR A + LD (motim),A ; Insure Motors Marked as OFF + LD A,(active) ; Get current settings + AND 00000111B ; strip off Motor bits +Activ8: OR 00000100B ; (insure FDC out of Reset) +ActivA: LD (active),A ; save + OUT (DCR),A ; and Command! + RET + +;------------------- Data Storage Area ----------------------- +; Disk and Drive parameters are dictated by table entries. While +; not all parameters are implemented in this module, they may be +; added as desired. A bit-mapped byte is used defined as: + +; D D D D D D D D Format Byte +; 7 6 5 4 3 2 1 0 +; | | | | | | +-+----- Sector Size: 000=128, 001=256, 010=512, 011=1024 bytes +; | | | | +-+--------- Disk Size: 00=fixed disk, 01=8", 10=5.25", 11=3.5" +; | | | +------------- 0 = Normal 300 RPM MFM, 1 = "High-Density" Drive +; | | +--------------- 0 = Single-Sided, 1 = Double-Sided +; | +----------------- 0 = Double-Density, 1 = Single-Density +; +------------------- 0 = 250 kbps (normal MFM), 1 = 500 kbps (Hi-Density) + +IBMPC3 EQU 10101110B ; HD, DD, DS, 3.5", 512-byte Sctrs (1.44 MB) +UZIHD3 EQU 10101111B ; HD, DD, DS, 3.5", 1024-byte Sctrs (1.76 MB) +IBMPC5 EQU 10101010B ; HD, DD, DS, 5.25", 512-byte Sctrs (1.2 MB) +UZIHD5 EQU 10101011B ; HD, DD, DS, 5.25", 1024-byte Sctrs (1.44 MB) +DSQD3 EQU 00101111B ; MFM, DD, DS, 3.5", 1024-byte Sctrs (800 KB) +DSDD3 EQU 00101110B ; MFM, DD, DS, 3.5", 512-byte Sctrs (800 KB) +DSQD5 EQU 00101011B ; MFM, DD, DS, 5.25", 1024-byte Sctrs (800 KB) +DSDD5 EQU 00101010B ; MFM, DD, DS, 5.25", 512-byte Sctrs (800 KB) + + rseg IDATA0 +_dTbl: defs TBLSIZ*4 ; Drive Param Table. 1 Entry Per Drive. + rseg CDATA0 +_dTbl_CDATA0: + DEFB 00H, 0DFH, 01H, 27, 18, 1, IBMPC3, 10, 0 + ; | | | | | | | | +- Current Track Number + ; | | | | | | | +- Spinup (1/20-secs) + ; | | | | | | +-- Format Byte (See above) + ; | | | | | +------- First Sector Number + ; | | | | +------- Physical Sectors-Per-Track + ; | | | +----------- Gap3 (Size 512=27, 1024=13) + ; | | +---------------- Hd Load in 4mS steps (0=inf) + ; | +--------------------- Step Rate (B7-4) = 3mS (2's Compl) + ; | (Div by 2 for 250 kbps MFM) + ; | HUT (B3-0) = 240 mS + ; +--------------------------- Drive Logged (FF), Unlogged (0) +TBLSIZ EQU $-_dTbl_CDATA0 + DEFB 00H, 0CFH, 01H, 27, 18, 1, IBMPC3, 10, 0 + DEFB 00H, 0CFH, 01H, 27, 18, 1, IBMPC3, 10, 0 + DEFB 00H, 0CFH, 01H, 27, 18, 1, IBMPC3, 10, 0 + +; -->>> NOTE: Do NOT move these next two variables out of sequence !!! <<<-- + rseg IDATA0 +motim: defs 1 + rseg CDATA0 + DEFB 0 ; Motor On Time Counter + rseg IDATA0 +mtm: defs 1 + rseg CDATA0 + DEFB 0 ; Floppy Spinup Time down-counter + + rseg UDATA0 +sysSav: DEFS 1 ; Entry "insys" process status flag +drive: DEFS 1 ; (minor) Currently Selected Drive +active: DEFS 1 ; Current bits written to Dev Contr Reg (DCR) +;;--block: DEFS 1 ; Index in Buffer for desired 512-byte block +;;--buffer: DEFS 1024 ; Physical Sector Buffer. Max Possible Size + + +comnd: DEFS 1 ; Storage for Command in execution +hdr: DEFS 1 ; Head (B2), Drive (B0,1) +trk: DEFS 1 ; Track (t) +hd: DEFS 1 ; Head # (h) +sect: DEFS 1 ; Physical Sector Number +rsz: DEFS 1 ; Bytes/Sector (n) +eot: DEFS 1 ; End-of-Track Sect # +gpl: DEFS 1 ; Gap Length +dtl: DEFS 1 ; Data Length + +; FDC Operation Result Storage Area + +st0: DEFS 1 ; Status Byte 0 +st1: DEFS 1 ; Status Byte 1 (can also be PCN) + DEFS 1 ; ST2 - Status Byte 2 + DEFS 1 ; RC - Track # + DEFS 1 ; RH - Head # (0/1) + DEFS 1 ; RR - Sector # + DEFS 1 ; RN - Sector Size + +actDma: DEFS 2 ; 16-bit DMA Address + +; DISK Subsystem Variable Storage + +rdOp: DEFS 1 ; Read/write flag +retrys: DEFS 1 ; Number of times to try Opns +rwRtry: DEFS 1 ; Number of read/write tries +DRVSPD: DEFS 1 ; Drive Speed +DRVSIZ: DEFS 1 ; Drive Size + +_fsector: defs 1 +_ftrack: defs 1 ; LSB used as Head # in DS formats +_ferror: defs 1 +_fbuf: defs 2 + +; rseg CODE + + end diff --git a/src/kernel/uzi/hdasm.asm b/src/kernel/uzi/hdasm.asm new file mode 100755 index 00000000..b5fee62d --- /dev/null +++ b/src/kernel/uzi/hdasm.asm @@ -0,0 +1,234 @@ + + public _scsiop ; PUBlic + + extern _dptr, _dlen, _cptr, _busid, _cmdblk, _hd_offset ; in devhd.c + .if 1 ; IAR + extern ?BANK_FAST_LEAVE_L08 + .endif + +;/* This SCSI driver code section is a polled-IO driver for the YASBEC */ + +; Equates for the National DP8490/NCR 5380 SCSI controller on YASBEC + +NCR EQU 058H ; Base of NCR 5380/DP5380/DP8490 in YASBEC + +; 5380 Chip Registers + +NCRDAT EQU NCR ; Current SCSI Data (Read) + ; Output Data Register (Write) +NCRCMD EQU NCR+1 ; Initiator Command Register (Read/Write) +NCRMOD EQU NCR+2 ; Mode Register (Read/Write) +NCRTGT EQU NCR+3 ; Target Command Register (Read/Write) +NCRBUS EQU NCR+4 ; Current SCSI Bus Status (Read) +NCRST EQU NCR+5 ; Bus & Status Register (Read) + ; Start DMA Send (Write) +NCRINT EQU NCR+7 ; Reset Parity/Interrupt (Read) + ; Start DMA Initiator Receive (Write) +DMAACK EQU NCR+8 ; SCSI Dack IO Port (Read/Write) + +; Bit Assignments for 5380 Ports as indicated + +B_AACK EQU 00010000B ; Assert *ACK (NCRCMD) +B_ASEL EQU 00000100B ; Assert *SEL (NCRCMD) +B_ABUS EQU 00000001B ; Assert *Data Bus (NCRCMD) + +B_BSY EQU 01000000B ; *Busy (NCRBUS) +B_MSG EQU 00010000B ; *Message (NCRBUS) +B_CD EQU 00001000B ; *Command/Data (NCRBUS) +B_IO EQU 00000100B ; *I/O (NCRBUS) + +B_PHAS EQU 00001000B ; Phase Match (NCRST) + + rseg CODE +;--------------------------------------------------------------------- +; Try the Command specified. If errors returned (e.g. Attn assertion), +; read the SCSI Sense status and try the command again. + +_scsiop: + .if 1 ; IAR + push bc + push de + call LWRD _scsiop_entry + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 +_scsiop_entry: + .endif + LD HL,(_cmdblk+2) ; Get low 16-bits of Block # + LD E,H ; in + LD D,L ; Little-Endian order + LD HL,(_hd_offset) ; Fetch Track offset for this Logical Unit + XOR A + LD B,4 +Mul16: ADD HL,HL ; Multiply by 16 + ADC A,A ; with 20-bit result + DJNZ Mul16 + ADD HL,DE ; Add desired relative block # + ADC A,0 ; to 20-bit resulting block Number + LD C,A + EX DE,HL + LD HL,_cmdblk+1 ; Pt to LUN/Hi-5 Block # + LD A,(HL) ; Get it + AND 0E0H ; strip block bits + OR C ; add in ours + LD (HL),A ; save + INC HL ; Advance to cmdblk+2 + LD (HL),D ; save middle 8-bits of block + INC HL + LD (HL),E ; save low 8-bits + + CALL LWRD HDRW0 ; Try the Command + RET Z ; ..exit if Ok + LD HL,SENSE ; Else set for Sense Command + LD DE,snsDat ; Pt to sense data + CALL LWRD HDRW1 ; and execute +HDRW0: LD DE,(_dptr) ; Get Ptr to Data Area + LD HL,_cmdblk ; and Command Area +HDRW1: LD (hdCmd),HL ; Save Comnd Blk Ptr + LD (hdDat),DE ; and Data Ptr + CALL LWRD SCSI ; Do the Work + AND 00000010B ; Any errors? + LD L,A + RET NZ ; return 0 if Ok, 02 if Errors + LD H,A + RET + +;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +; Raw SCSI Driver + +SCSI: XOR A + OUT (NCRCMD),A ; Clear any previous Controller junk + OUT (NCRMOD),A + OUT (NCRTGT),A + + LD A,(_busid) ; Get the Target Device address bit + OR 10000000B ; add Host initiator address bit + OUT (NCRDAT),A + IN A,(NCRCMD) ; Get Initiator Comnd Reg + OR B_ABUS ; Get the Data Bus + OUT (NCRCMD),A + LD A,B_ASEL+B_ABUS ; Now Claim both Select and Data Bus bits + OUT (NCRCMD),A + +; Wait for roughly 250 mS. We might not have a valid clock so we just use +; a loop counter. The specified SCSI duration is 250 mS. + + LD DE,25000 ; Set loop limit + LD HL,0FFFFH ; Preset Timeout Error Status + +BSYWT: DEC DE + LD A,D + OR E ; Have we timed out? + JR Z,TimOut ; ..exit to Error if So + IN A,(NCRBUS) ; Get the Current Bus Status + AND B_BSY ; Is it BSY? + JR Z,BSYWT ; ..loop if Not + ;..else fall thru.. + LD A,B_ABUS + OUT (NCRCMD),A ; Grab Bus w/o Select Command (or free) + XOR A ; get a Zero without affecting Zero Flag + OUT (NCRCMD),A ; then free the Data Bus + ;..fall thru to check for Phase Change.. +PHASE: IN A,(NCRBUS) ; Read the Bus Status + AND B_MSG+B_CD+B_IO ; keep the three phases we are interested in + RRCA ; Rotate Phase status bits + RRCA ; into B0-2 position for testing + OUT (NCRTGT),A ; Check for phase match + LD C,NCRDAT ; Data goes to/from this port + LD HL,messge ; (Ph 7 input goes here) + CP 7 ; Are we in Phase 7 ? + JR Z,HDIN ; ..jump if so to Message In Phase + LD HL,(hdDat) ; (Ph 0/1 IO From/To here) + OR A ; Are we in Phase 0 ? + JR Z,HDOUT ; ..jump to if so to Data Out Phase + DEC A ; Are we in Phase 1 ? + JR Z,HDIN ; ..jump to if so to Data In Phase + LD HL,(hdCmd) ; (Ph 2 output from here) + DEC A ; Are we in Phase 2 ? + JR Z,HDOUT ; ..jump to if so to Command Out Phase + LD HL,status ; (Ph 3 Input to here) + DEC A ; Are we in Phase 3 ? + JR Z,HDIN ; ..jump to if so to Status In Phase + ;..else fall thru +; Phases 4, 5 and 6 wind up here in an Error + + LD HL,0FEFFH ; Set Phase Error Return Value + JR TimOut ; ..continue to Exit + + +;..... +; SCSI Input routine. +; Polled-IO Input Routine +; Enter with HL pointing to Buffer, C Addressing 5380 Data Port + +HDIN: IN A,(NCRBUS) ; Check the Bus + BIT 5,A ; Do we have a REQuest? + JR NZ,HDIN1 ; ..jump if So to readint + AND B_BSY ; Is the Bus Busy? + JR NZ,HDIN ; ..loop if So + +HDEXIT: XOR A ; Else we are finished. Clean up & Quit + OUT (NCRCMD),A ; clear Initiator Command Register + OUT (NCRTGT),A ; and Target Command Register + LD HL,(status) ; Get Message (H) and Status (L) Bytes +TimOut: LD A,L ; Get Status Byte + OR A ; set Return Status Ok if Status Byte = 0 + RET + +HDIN1: IN A,(NCRST) ; Get SCSI Status + AND B_PHAS ; Do the Phases Match? + JR Z,PHASE ; ..quit here if Not and Clear + INI ; Else Get byte from Port (C) to Memory at (HL) + LD A,B_AACK + OUT (NCRCMD),A ; ACKnowledge the Byte + XOR A + OUT (NCRCMD),A ; clear *ACK bit + JR HDIN ; and back for More + +;..... +; SCSI Output Routine. +; Enter: HL = Address of Send Buffer start +; Polled-IO Output Routine +; Enter with HL pointing to Buffer, C Addressing 5380 Data Port + +HDOUT: LD A,B_ABUS ; Assert Data Bus + OUT (NCRCMD),A + IN A,(NCRBUS) ; Check the SCSI Bus + BIT 5,A ; Do we have a REQuest? + JR NZ,HDOUT1 ; ..jump if So to Send a Byte + AND B_BSY ; Else is the Bus Busy? + JR NZ,HDOUT ; ..loop if so because we have more to go + JR HDEXIT ; Else Quit + +HDOUT1: IN A,(NCRST) ; Get Current Status + AND B_PHAS ; Do we have a Phase Match? + JR Z,PHASE ; ..quit here if Not and clear + + OUTI ; Send a byte from (HL) to Port (C) + LD A,B_AACK+B_ABUS + OUT (NCRCMD),A ; Set ACKnowledge and BUS bits + XOR A + OUT (NCRCMD),A ; clear *ACK and *BUS + JR HDOUT ; ..and back for More + +;..... +; SCSI Read Sense Command Data Block + + rseg IDATA0 +SENSE: DEFS 6 + rseg CDATA0 + DEFB 03H ; SCSI Sense Command + DEFB 00,00,00,18,00 ; remainder of Sense Command Block + ; (data length set to available space) + + rseg UDATA0 +hdCmd: DEFS 2 ; Storage for Current Command Data Block +hdDat: DEFS 2 ; Storage for current Data Transfer Area +snsDat: DEFS 18 ; Storage for extended Sense Data Received + +;<<--- Do not re-order the following Two Bytes --->> +status: DEFS 1 ; Ending Status Byte +messge: DEFS 1 ; Ending Message Byte + rseg CODE + + end diff --git a/src/kernel/uzi/hdconf.h b/src/kernel/uzi/hdconf.h new file mode 100755 index 00000000..a1ff4931 --- /dev/null +++ b/src/kernel/uzi/hdconf.h @@ -0,0 +1,72 @@ +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: hdconf.h + Hard Disk Partitioning Physical and Logical data Definitions +---------------------------------------------------------------- + Copyright (C) 1998 by Harold F. Bower +****************************************************************/ +/* Revisions: + */ + +/* ! ! ! ! ! Define ONLY ONE of the following types: ! ! ! ! ! */ +/* ! ! ! ! ! UnDefine all others ! ! ! ! ! */ +#undef SCSI +#undef GIDE +#define APIBUS + +#define LUN 0 /* Only needed for SCSI, but no adverse effect on GIDE */ + +/* Set Read and Write Command Bytes for appropriate Disk System */ + +#ifdef SCSI +#define RDCMD 0x08 +#define WRCMD 0x0a +#endif + +#ifdef GIDE +#define RDCMD 0x20 +#define WRCMD 0x30 +#endif + +#ifdef APIBUS +#define RDCMD 'R' +#define WRCMD 'W' +#endif + +/* For GIDE and Unique data, Insert Drive geometry here (as an example). + * These values are used in the low-level driver to compute the + * physical CHS address for Read/Write operations. + */ +#ifdef GIDE +#define HD_Cyls 998 /* for Toshiba MK1422 2.5" 82 MB */ +#define HD_Heads 10 +#define HD_Sector 17 +#endif + +/* Initial Track Offsets, and Number of Tracks in each partition. */ +/*************************************************************************** + * NOTE: For Hard drives, each "track" equates to 16 512-byte blocks (8 KB). + * The Low-level assembly driver should multiply the offset by 16 + * before adding to the computed block number passed from devwd.c. + *************************************************************************** + */ + +#if 1 /* Nick, very temporary */ +#define HD0_Start 0 /* sentinel value indicating the ramdrive */ +#define HD0_Size 0x600 /* define a harddrive of size 768 kbytes */ + +#define HD1_Start 0x239 /*0x259 /*0x2bb /* just after HYTDISK.DAT finishes */ +#define HD1_Size 0x2000 /* define a harddrive of size 4 Mbytes */ +#else +#define HD0_Start 3000 /* 1st Drive Start. CP/M uses first 3000 "tracks" */ +#define HD0_Size 2000 /* Number of "tracks" in HD0 (2000 * 8 = 16.0 MB) */ + +#define HD1_Start 5100 /* 2nd Drive Start. */ +#define HD1_Size 1700 /* Number of "tracks" in HD1 (1700 * 8 = 13.6 MB) */ +#endif + +/* Swap space is needed for the original UZI system configuration. + * It needs to be defined until replaced or redefined. + */ +#define SWAP_Start 5000 /* Swap space Start. (until Swap not needed) */ +#define SWAP_Size 100 /* Number of "tracks" in Swap (100 * 8 = 800 KB) */ + diff --git a/src/kernel/uzi/machasm.asm b/src/kernel/uzi/machasm.asm new file mode 100755 index 00000000..703e4da6 --- /dev/null +++ b/src/kernel/uzi/machasm.asm @@ -0,0 +1,1590 @@ +;/*************************************************************** +; UZI (Unix Z80 Implementation) Kernel: machasm.asz +;---------------------------------------------------------------- +; Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke +; Copyright (C) 1998 by Harold F. Bower +; Portions Copyright (C) 1995 by Stefan Nitschke +;****************************************************************/ +;/* Revisions: +; * 22.12.97 - extracted from several modules. HFB +; */ + +; These routines reflect settings for the YASBEC SBC. +; Capabilities of the YASBEC are: + +; SCSI - National DP5380/8490 Controller with or +; without Interrupt-driven DMA transfer. +; Floppy - Western Digital FD1772. Modifications +; for National 8473 also available. +; Polled operation only. +; RTC - Dallas DS-1216E installed between ROM and socket. +; Printer- Octal latch with Interrupt *ACK (limited Centronics). +; Memory - 128k to 1 MB available. +; RS-232 - Two Channels w/partial handshaking. +; Channel 0 - Auxiliary +; Channel 1 - Console TTY + +; Resources used and chip set are: + +; Z180 ASCI0 - Aux Serial port (unused here) +; Z180 ASCI1 - TTY Console (ASCI1 Interrupt) +; Z180 Timer0 - 50/100 mS Interrupts (ASCI1 Int) +; Provides ticks for time slicing +; Z180 Int0 - SCSI (5380) (optional Interrupt) +; Z180 Int1 - Parallel printer ACK Latch +; Dallas DS-1216 Clock/Calendar (for TOD) +;****************************************************************/ + + public _initsys + .if 0 ; Nick + public _rdtod + public __putc + .endif + public _lpout, _ei, _di ; PUBlic + .if 1 ; Nick + public _di_absolute, _ei_absolute + .endif + public _IRET, _tempstack, _uget, _ugets, _uput ; " + public _ugetw, _uputw, _ugetc, _uputc, _doexec, _unix ; " + public _osBank + .if 0 ; Nick has temporarily removed CP/M support + public _uzicom + .endif + .if 0 ; Nick, not public anymore, now defined by extern.h (can be anywhere) + extern _ub + .else + public _ub + .endif + + extern _fs_init, _tty_inproc, _panic, _inint, _kprintf ; in machdep.c + extern _calltrap ; " + extern _FdcCk ; flopasm.asz + extern _clkint2, _unix2 ; in process.c + extern _tod ; in data.c + .if 0 ; IAR + extern __Lbss, __Hdata ; from linker + .endif + .if 0 ; Nick has temporarily removed CP/M support + extern __Lcpm22, __Hcpm22, __Bcpm22 ; from linker + extern EStart ; in emu.asz + .endif + .if 0 ; Nick + extern _bcopy ; runtime.lib + .endif + + extern copyr + extern abyte, ahexw, acrlf + .if 1 ; Nick + extern _unix_locked_out + .endif + extern _exit ; for trap errors + + .if 1 ; IAR + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + .endif + +;#include +;#include +;#include + +$ asmdef.inc ; Common Definitions, Ascii and CP/M +$ z180.inc ; Z180 Register Mnemonics + + rseg CODE +;/*---------------------------------------------------------------*/ +;/* Perform initial system setup from cold start. Begin by */ +;/* clearing all of the uninitialized RAM to 0, then Initialize */ +;/* the Z180 Interrupt Vector Table. Interrupt Handler addresses */ +;/* are installed at the appropriate locations in Init, and the */ +;/* base address of the table is set in Z180 registers. */ +;/* This interrupt table configuration is YASBEC-specific! */ +;/*---------------------------------------------------------------*/ + +;initsys() +;{ +;#asm + +_initsys: + .if 1 ; IAR + push bc + push de + + .if 0 + ld a,'!' + call abyte + .endif + .else + ld hl,__Hdata ; Pt to common image in low mem (Top of Data) + ld de,0F000H ; Common Area destination + ld bc,endcom-_ub ; and length + ldir ; ..move into position + + ; /* Initialize the internal Z180 interrupt table address */ + ; NOTE: Insure that it begins on an even 32-byte boundary! + + ld hl,itbl ; Get Address of Interrupt Table (Common Mem) + OUT0 (IL),L ; Set Z180 Low Int Adr + ld a,h ; Get Page + ld i,a ; to Interrupt Register + ld a,00010001B ; Turn Ints On and enable downcounting + OUT0 (TCR),A + ld a,00000111B ; Activate INT0 and Interrupts + OUT0 (ITC),A + di ; + + ld de,__Lbss ; Clear all bss Memory + ld hl,0F000H + or a + sbc hl,de ; Compute bss size + ld c,l + ld b,h ; Set count + ld l,e + ld h,d ; Copy to source Reg + inc de ; Dest = Source + 1 + dec bc ; deduct one from count for init byte + ld (hl),0 ; Zero the first Byte + ldir ; and move it along + .endif + +; /* Establish base of Common Memory which is always resident */ +; This *MUST* be done here since CBR might be different if read in high mem + + IN0 A,(CBR) ; Get Current Bank + LD (_osBank),A ; Save for later kernel use + + .if 1 ; IAR + ld hl,LWRD _fs_init + ld a,BYTE3 _fs_init + call ?BANK_CALL_DIRECT_L08 + + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + .else + jp _fs_init ; ..chain to more setup in MACHDEP.C + .endif + +;=============== Section relocated to Common Memory (F000H) ============= +; This portion of code is always in context in both User and System modes. +; Critical items are: +; User Data Block (udata) +; User Stack (from end of udata thru top of _ub) +; Z180 Interrupt Table (because we don't know where we are when interrupted) +; Interrupt Handlers (or at least vectors) which are "bank aware" if they +; chain to code in the system area +; Temporary Stack for use in process swapping or other temporary purposes + + .if 1 ; Nick, not needed anymore, now defined by extern.h (can be anywhere) + rseg RCODE + ; udata block padded up to 512 bytes (256 Wds). + ; Data is in the low part, with the Kernel (System) + ; Stack at _ub+512 and the Timer Interrupt Stack + ; 256 bytes above that. +_ub: + .if 1 + defs 1000h + .else + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; Kernel stack ends here + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + defw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + ; Timer Interrupt stack ends here + .endif + .endif + + .if 0 ; Nick +; NOTE: The interrupt table must start on a 32-byte boundary + +itbl: ; INT0 - Uncomment Only one of these first two + defw _badint ;;-- For Polled SCSI +;;-- defw _scsint ;;-- For Interrupt/DMA SCSI + + defw _intpio ; INT1 - Printer ACK + defw _timer ; Timer0 - Process Tick + defw _badint ; Timer1 - (unused) + defw _badint ; DMA Ch0 - (unused) + defw _badint ; DMA Ch1 - (unused) + defw _badint ; CSIO - (unused) + defw _badint ; ASCI0 - (unused) + defw _tty_int ; ASCI1 - Console TTY +itblen equ $-itbl +;#endasm +;} + .endif + + +;/*--------------- Interrupt Handler Routines --------------*/ + +TrapEr: ld hl,0 ; Get Addr where Trap Occured + add hl,sp + ld e,(hl) + inc hl + ld d,(hl) + ld a,(_osBank) + OUT0 (CBR),A ; Get System Bank into Context + ld sp,0000 + push de ; Trap Addr to stack + ld hl,trpmsg ; Print message + push hl + .if 1 ; IAR + ld hl,LWRD _kprintf + ld a,BYTE3 _kprintf + call ?BANK_CALL_DIRECT_L08 + .else + call _kprintf + .endif + .if 1 + ld de,1 + ld hl,LWRD _exit + ld a,BYTE3 _exit + jp ?BANK_CALL_DIRECT_L08 + .else +TrapL: di + jr TrapL ; ..should never get here..but... + .endif + +trpmsg: defm 'Trap @ %x!' + defb 0AH,0 + + .if 0 ; Nick +;..... +;badint() +;{ +; panic ("Bad Int"); + +_badint: ld a,(_osBank) + OUT0 (CBR),A ; Get System Bank into Context + ld sp,0000 ; Set Error Stk + ld hl,bimsg + push hl + .if 1 ; IAR + ld hl,LWRD _panic + ld a,BYTE3 _panic + call ?BANK_CALL_DIRECT_L08 + .else + call _panic + .endif + ret ; ..should never get here + +bimsg: defm 'Bad Int' + defb 0 +;} + + +;static char ptrrdy; /* Printer Ready Flag */ + + +;/*---- Parallel Printer Interrupt Handler ----*/ +;/* In the YASBEC, data is latched to an octal buffer, and the Printer +; strobe activated by writing to different addresses. When the +; printer acknowledged the character by toggling its *ACK line low, +; an interrupt in generated (INT 1) to indicate that the printer is +; ready for another character. This handler clears the flag and int. +; */ + +;intpio() +;{ +;#asm + +_intpio: di ; Clear Ints + push af + ld a,0ffh + ld (ptrrdy),a ; Set Ready Flag + out (42h),a ; ..and clear interrupt + pop af + ei ; Enable Ints + ret +;#endasm +;} + + +;/*--------------- Interrupt-Driven Console Handler ---------------*/ +;/* This tty interrupt routine is activated in response to a received +; character on ASCI1 of the Z180. It reads the character from the +; port then passed it to code in "devtty.c" to add it to the tty +; input queue, echoing and processing backspace and carriage return. +; If the queue contains a full line, it wakes up anything waiting +; on it. If it is totally full, it beeps at the user. +; */ + +;tty_int() +;{ +; register char c; +;#asm + +_tty_int: + di + push af ; Save machine state + push bc + push de + push hl + push ix + push iy + IN0 L,(RDR1) ; Read char from ASCI1 + ld h,0 ; make into word + push hl + ld l,1 ; Set for minor = 1 + push hl + .if 1 ; IAR + ld hl,LWRD _tty_inproc + ld a,BYTE3 _tty_inproc + call ?BANK_CALL_DIRECT_L08 + .else + call _tty_inproc ; massage character in C (devtty.c) + .endif + pop bc ; (clr stk on ret) + pop bc ; (both words) + pop iy + pop ix + pop hl + pop de + pop bc + pop af ; Restore state + ei ; Ints Ok now + ret +;} + + +;/*---------------------- Timer Interrupt Handler ----------------------*/ +;/* This is activated roughly every 50 mS (depending on the timer value +; set on initialization) to control timeouts. It only runs when +; interrupts are enabled, so is subject to some error. Set the correct +; value in "config.h" for the desired rate depending on processor clock +; speed for your configuration. + +; NOTE: This routine also provides a timer function to turn floppy disk +; motors off after a pre-determined time (for the P112 or DB8473 mod) +; and can also provide periodic sampling of the _tty routines for +; systems which do not have interrupts on the serial (tty) ports. +; */ +;timer() +;{ +;#asm + +_timer: di ; No ints here + ex af,af' + push af ; Save all regs + ex af,af' + exx + push bc + push de + push hl + exx + push af + push bc + push de + push hl + push ix + push iy + + IN0 A,(TCR) + IN0 A,(TMDR0L) + IN0 A,(TMDR0H) ; Clear the Interrupt + + LD (ISTACK-2),SP ; Save Entry Stack Ptr + LD SP,ISTACK-2 ; set New Stack + + IN0 A,(CBR) ; Read entry Bank Buffer Reg + push af ; (save for exit) + + ld a,(_osBank) + OUT0 (CBR),A ; Get System Bank into Context + + .if 1 ; IAR + ld hl,LWRD _FdcCk + ld a,BYTE3 _FdcCk + call ?BANK_CALL_DIRECT_L08 + .else + CALL _FdcCk ; Perform needed Floppy Timeout functions + .endif + + .if 0 ; Nick + call __cin ; Check polled tty ports + ; process any waiting chars + .endif + +; We call the tick service routine in "process.c" in lieu of a real int. + + .if 1 ; IAR + ld hl,LWRD _clkint2 + ld a,BYTE3 _clkint2 + call ?BANK_CALL_DIRECT_L08 + .else + call _clkint2; + .endif + +; Subroutine service() incorporated within this portion of the handler. +; It is sampled every 1/TICKSPERSECOND Secs, with calltrap() called as needed. + +; /* Deal with a pending caught signal, if any */ +; if (!udata.u_insys) + + ld a,(_ub+OSYS) + or a ; In Kernel Mode? + jr nz,tdone ; ..jump if Not..no trap check + +; { +; inint = 0; + + ld (_inint),a ; (A still 0 from above) + +; calltrap(); + + .if 1 ; IAR + ld hl,LWRD _calltrap + ld a,BYTE3 _calltrap + call ?BANK_CALL_DIRECT_L08 + .else + call _calltrap ; Handle signal + .endif +; } + +tdone: pop af ; Get entry Bank + OUT0 (CBR),A ; bring back into Context + LD SP,(ISTACK-2) ; restore Entry Stack Ptr + JP _IRET ; ..exit, restoring all regs, enable Ints +;#endasm +;} + .endif ; Nick + + +;/*----------------------------------------------------------*/ +;/* Send a single character to Console, waiting if not ready. +; This routine does not mask the MSB before sending, so it is +; possible to send 8-bit characters to the console. Output +; handshaking is also not provided which may result in over- +; driving the terminal at higher speeds. In the Z180, output +; flow control is automatic via rts/cts if so wired. +; */ + +; _putc (int minor, char c) + + .if 0 ; Nick +__putc: POP HL ; Return Address + POP DE ; minor + POP BC ; c + PUSH BC ; Keep Parms on stack + PUSH DE +; { +; if (minor == 2) { + + DEC E ; 2 + DEC E ; -> 0? + JR NZ,put0 ; ..jump if Not 2 (assume 1) + +; /* tty1 (minor = 2) is desired, which is ASCI0 */ +; while (!(in (0x04)&02)) ; + +put1: IN0 A,(STAT0) ; ASCI0 status (Aux) + AND 02H ; Ready? + JR Z,put1 ; ..loop til Ready + +; out (c, 0x06); + + OUT0 (TDR0),C ; Send Char + JP (HL) ; "Return" +; } + +; else { + +; /* tty0 (minor = 0) is desired, which is ASCI1 */ +; while (!(in (0x05)&02)) ; + +put0: IN0 A,(STAT1) ; ASCI1 Status (Con) + AND 02H ; Ready? + JR Z,put0 ; ..loop to wait if Not + +; out (c, 0x07); + + OUT0 (TDR1),C ; Send Char + JP (HL) ; jump to Return addr +; } + .endif + +;---------------------------------------------------------- +; Check for waiting input characters from tty1 (ASCI0). +; ASCI1 is interrupt-driven and handled elsewhere. +; First check tty1 (ASCI0) + + .if 0 ; Nick +__cin: IN0 A,(STAT0) ; Aux (Reader) Input Status + AND 80H ; keep only status bit + LD L,A + LD H,A ; (prepare C-style return status) + RET Z + + IN0 A,(RDR0) ; Read ASCI0 Input Port + LD L,A + LD H,0 ; make into word + PUSH HL + LD L,2 ; minor = 2 + PUSH HL + .if 1 ; IAR + ld hl,LWRD _tty_inproc + ld a,BYTE3 _tty_inproc + call ?BANK_CALL_DIRECT_L08 + .else + CALL _tty_inproc ; Process character + .endif + POP BC ; clean stack + POP BC + JR __cin ; ..loop to clean out waiting chars + .endif + +;/*---------------- Real Time Clock Interface -----------------*/ +;/* Dallas DS-1216E Real-Time Clock/Calendar (aka No-Slot-Clock) Interface. +; This functions by reading location 4 of the ROM after an initial setup +; sequence to obtain date/time one bit at a time. The bit appears in +; the LSB of the byte, and each byte is read in MSB..LSB fashion. The +; entire Date/Time String is eight bytes read as: +; 10/100Sec Sec Min Hour DOW Day Mon Year +; This implementation ignores the tenths/hundredths and the Day-Of-Week +; bytes (after using them to check validity) and converts the date/time +; to the correct UZI (MS-DOS) format. +;*/ + +;/* Read Hardware Clock/Calendar into: struct time_s */ +;/* uint16 t_time; */ +;/* uint16 t_date; */ +;/* Update global time of day */ +;rdtod() +;{ + + rseg CODE + + .if 1 ; Nick +;_rdtod: +; ld hl,0 +; ld (_tod),hl +; ld (_tod+2),hl +; jp ?BANK_FAST_LEAVE_L08 + .else +_rdtod: + di ; NO INTERRUPTS in this routine + ld (_timstk+12),sp ; Store entry SP + ld sp,_timstk+12 ; set ours + ; Set up chip for reading + IN0 A,(CBR) ; Read entry Bank Buffer Reg + push af ; save for exit + xor a ; Set banked area for physical 0 (ROM) + OUT0 (CBR),A + IN0 A,(DCNTL) ; Read entry wait states + push af ; save for exit + or 0c0h ; set to max memory waits + OUT0 (DCNTL),A + ld hl,cstrng ; Point to control activation string + ld d,8 ; 8 bytes + ld a,(0004h) ; read clock control addr + +nxbyt: ld b,8 ; Gather 8 bits + ld c,(hl) ; Get a control byte +nxbit: rr c ; Is LSB "1"? + jr c,onebit ; ..jump if Yes + ld a,(0002h) ; Else read "0" + jr zerbit ; ..continue + +onebit: ld a,(0003h) ; Read "1" +zerbit: djnz nxbit ; ..loop til all bits done + inc hl ; Advance to next byte + dec d ; more bytes to go? + jr nz,nxbyt ; ..loop if More + ; Else fall thru to Read Clock + ld hl,_lcltim+6 ; Pt to tenths field (tenths field) + ld d,8 ; Gather 8 bytes of info + +rdbyt: ld b,8 ; 8-bits per byte +rdbit: ld a,(0004h) ; Read a bit from the clock + rra ; put LSB in Carry + rr c ; then to MSB of accumulated byte + djnz rdbit ; ..loop til 8 bits read + ld a,d + cp 4 ; DOW field? + jr nz,rdbit0 ; ..jump if No + push af ; else save for later Error checks + jr rdbit1 ; ..bypass save/increment + +rdbit0: ld (hl),c ; Save the byte + dec hl ; backup to previous byte +rdbit1: dec d ; More bytes to read? + jr nz,rdbyt ; ..loop if Yes + + pop af ; Retrieve DOW for Error check + ld c,a ; save + pop af ; Restore wait settings + OUT0 (DCNTL),A + pop af ; Restore Memory Bank + OUT0 (CBR),A + ld a,c ; Get Error Flag + or a ; Error (0)? + jp z,noclock ; ..jump if Yes + inc a ; Error (FF)? + jp z,noclock ; ..jump if Yes + +; tod.t_date = tread(DAY) | (tread(MON)<<5) | (YEAR<<9); + + ld hl,_lcltim ; Pt to years field of day/date + ld a,(hl) ; fetch + inc hl ; (advance to month) + call bcd2bin + ADD A,A + LD D,A + LD E,0 ; (Year * 512) -or- (Year << 9) + ld a,(hl) ; Fetch month + inc hl ; (advance to day) + call bcd2bin + ld c,a + LD B,32 + MLT BC ; (Month * 32) -or- (Month << 5) + ex de,hl + add hl,bc ; add month to shifted year + LD A,(DE) ; Fetch day + INC DE ; (advance to hrs) + call bcd2bin + OR L ; Add Binary Day + LD L,A ; to Yr,Mo + ld (_tod+2),hl ; Save in _tod.t_date + ex de,hl ; restore ptr + +; tod.t_time = (tread(SECS)>>1) | (tread(MINS)<<5) | (tread(HRS)<<11); + + ld a,(hl) ; Fetch Hours + inc hl ; (advance to mins) + call bcd2bin + ADD A,A ; (Hrs * 8) + ADD A,A ; -or- + ADD A,A ; (Hrs << 11-8) + LD D,A + LD E,0 ; = Hrs << 11 -or- Hrs * 2048 + ld a,(hl) ; Fetch Minutes + inc hl ; (advance to secs) + call bcd2bin + ld c,a + LD B,32 + MLT BC ; (Mins * 32) -or- (Mins << 5) + ex de,hl + add hl,bc ; add mins to shifted hrs + LD A,(DE) ; Fetch Secs + call bcd2bin + srl a ; Shift right one to strip LSB + OR L ; Add Binary (shifted) Sec + LD L,A ; to Hr,Min + ld (_tod),hl ; save in _tod.t_time + +timex: ld sp,(_timstk+12) ; Restore entry Stack + .if 1 ; IAR + ld hl,LWRD _ei + ld a,BYTE3 _ei + call ?BANK_CALL_DIRECT_L08 + .else + call _ei ; Ints Ok now + .endif + ret ; return! + + +noclock: ld hl,0 + ld (_tod),hl + ld (_tod+2),hl + jr timex + +cstrng: defb 0c5h,3ah,0a3h,5ch,0c5h,3ah,0a3h,5ch +;} + +; Helper file for converting Time/Date in above routine +; return ( 10*((n>>4)&0x0f) + (n&0x0f); + +bcd2bin: push de + ld d,a + and 0f0h + ld e,a + ld a,d + and 0fh + srl e + add a,e + srl e + srl e + add a,e + pop de + ret + .endif + +;/*-----------------------------------------------------*/ +;/* Send a single character to the Printer port, waiting if +; it is not ready. The output characters are not masked +; by this routine so it is possible to send 8-bit data. +; */ + + rseg RCODE + +;lpout(c) +;char c; +;{ +; while (!ptrrdy) ; + +_lpout: ld a,(ptrrdy) ; get Parallel port status + or a ; Ready? + jr z,_lpout ; ..loop if Not + +; ptrrdy = 0; + + xor a ; Else set busy + ld (ptrrdy),a + +; out (c,0x42); + + pop hl ; Get Return Addr + pop de ; minor # + pop bc ; and character + push bc ; (keeping stack balanced) + push de + ld a,c + out (42h),a ; send to data latch + +; out (c,0x43); + + out (43h),a ; toggle strobe + +; out (c,0x42); + + out (42h),a ; clear strobe + jp (hl) ; ..return +;} + +;/************** Miscellaneous Support Routines ***************/ +;..... +; Set up Temporary System Stack to use during context switches +; (Area reserved at end of this module) + +_tempstack: + pop hl ; Fetch Return Address + ld sp,tstk+tmplen ; Set temp Stack to top of scratch area + jp (hl) ; .."return" + + +;------------------------------------------------------------- +; Unix System CALL Trap Routine. This entry point is reached when a +; process requests Unix Kernel services with a RST 30H instruction. + +_unix: di ; No Ints while we change Banks & Stack + ex af,af' + push af + .if 0 + ld a,'%' + call abyte + .endif + ex af,af' + exx + push bc + push de + push hl + exx + push af + push bc + push de + push hl + push ix + push iy + + .if 1 ; Nick + LD (_ub+ORVAL1),bc ; in case we are NOT returning long in bc:hl + .endif + +; udata.u_retloc = (char *)ugetw (udata.u_sp); /* uret */ + + ld (_ub+ORET),sp ; Save return Stack Ptr for Task + ld (_ub+OSP),sp ; Nick... allows _brk() to check for error + + .if 1 ; latest unix() calling convention for better UZIX compatibility + ld a,e ; a = callno (1st argument) + .else + .if 0 ; for Nick's version the syscall index is passed in a (how convenient) + LD HL,+22 ; (Fudged balue to index Formal Parms) + ADD HL,SP ; Pt to Return Address + 1 Word + LD A,(HL) ; fetch Function CALL Number + .endif + .endif + LD (_ub+OCALL),A ; save + +; /* Copy args from user data space */ +; udata.u_argn3 = ugetw (udata.u_sp+4); /* argn3 */ +; udata.u_argn2 = ugetw (udata.u_sp+3); /* argn2 */ +; udata.u_argn1 = ugetw (udata.u_sp+2); /* argn1 */ +; udata.u_argn = ugetw (udata.u_sp+1); /* argn */ + + .if 1 ; latest unix() calling convention for better UZIX compatibility + ld l,c + ld h,b ; hl -> stack frame (2nd argument) + .else + .if 1 + ld hl,24 ; points to return address + 2 word (pushed DE) + add hl,sp + .else + INC HL ; Advance to argn + INC HL + .endif + .endif + + LD BC,8 ; move 4 Words + LD DE,_ub+OARGN ; to _ub+u_argn + LDIR ; (from unix2 in process.c) + + LD SP,ISTACK ;KSTACK ; Set High Stack for Kernel Processing + + LD A,(_osBank) ; Get OS Bank Number + OUT0 (CBR),A ; Bring OS bank into Context + + .if 1 ; IAR + ld hl,LWRD _unix2 + ld a,BYTE3 _unix2 + call ?BANK_CALL_DIRECT_L08 + .else + call _unix2 ; Continue processing + .endif + + ; Shove return values where they will eventually get popped to regs + + DI ; No Ints while we change Banks & Stack + + LD A,(_ub+OPAGE) ; Get Process' Bank # + + ld sp,(_ub+ORET) ; Restore Stack Ptr value for User Return +; ld sp,(_ub+OSP) ; Nick... as ORET was removed to save space + + OUT0 (CBR),A ; Bring it into Context + .if 0 + ld a,'#' + call abyte + .endif + + POP IY ; Start to restore status + POP IX + INC SP ; Skip HL restore + INC SP ; (value already in HL) + POP DE + LD BC,(_ub+OERR) ; Get Error result + LD A,B + OR C ; Set NZ if Error + .if 1 ; Nick + INC SP + INC SP ; skip bc restoration (temporary !!) + LD BC,(_ub+ORVAL1) ; in case we are returning long in bc:hl + .else + POP BC + .endif + INC SP ; (skip AF restoration) + INC SP + JR Z,_IRet0 ; ..jump if No Error, Carry Clear + SCF ; Else set Carry for Error + LD HL,(_ub+OERR) ; Return Error # instead of RetVal + JR _IRet0 ; ..and jump to restore rest & Return + + ;..fall thru to exit.. +;----------------------------------------------------------- +; This is the common interrupt-scall-trap return routine. +; It restores all registers. + +_IRET: pop iy + pop ix + pop hl + pop de + pop bc + pop af +_IRet0: exx ; Enter here for Unix2 Return + pop hl + pop de + pop bc + exx + ex af,af' + pop af + ex af,af' +; ex (sp),hl +; push af +; ld a,'[' +; call abyte +; call ahexw +; ld a,']' +; call abyte +; pop af +; ex (sp),hl + ei ; ..Return to User allowing Ints Now + ret + + +;/*-----------------------------------------------------*/ +; extern int unix(); +; doexec ((int *)envp, int entry) +; { + + rseg CODE + +_doexec: di ; Stop Ints here + .if 1 ; IAR + ;push bc ; don't bother, we're throwing away our stack + ;push de ; don't bother, we're throwing away our stack + + ; careful - de and bc are used again below, don't corrupt them !! + .endif + + .if 0 ; Nick has temporarily removed CP/M support + LD A,(_uzicom) + OR A ; Is this an UZI App? + JR NZ,ExeUZI ; ..jump if Yes + + LD HL,__Hcpm22 ; Else position Emulator + LD DE,__Lcpm22 + OR A + SBC HL,DE ; Compute Length + INC HL ; (+1 for safety) + PUSH HL ; Pass + LD HL,EStart ; (EA00) + PUSH HL ; Dest in proc + LD HL,__Bcpm22+100H ; (correct for TPA offset) + PUSH HL ; Src in System + CALL _uput ; Get module + POP BC + POP BC + POP BC + +ExeUZI: + .endif + .if 1 ; IAR + ex de,hl ; hl = 1st parameter (passed in de) + .else + pop hl ; Remove Return Address + pop hl ; Ptr to Argv[] now on top-of-stack + .endif + + LD A,(_ub+OPAGE) ; Fetch Task bank # + OUT0 (CBR),A ; Bring task bank into Context + + LD SP,HL ; Initialize User Stack below params + + xor a ; show that we are in User Mode + ld (_ub+OSYS),a ; by clearing OS flag + + ld a,0c3h ; Set Restart Vector for SYStem Calls + ld (0030h),a ; (RST 30H is Unix Function call vector) + ld hl,_unix + ld (0031h),hl + ld (0000h),a ; Set vector for Illegal Instructions + ld hl,TrapEr ; to Our Trap Handler + ld (0001h),hl + + .if 0 ; Nick has temporarily removed CP/M support + ; At this point, we check on the type of executable loaded. If it + ; is a CP/M type (No "UZI" string detected), then load the CP/M + ; emulator module in the process' memory and execute there. + + LD A,(_uzicom) + OR A ; Uzi Executable? + JR Z,ExeCPM ; ..jump if No + .endif + + .if 1 ; Nick EXE format +; ld l,c +; ld h,b +; call ahexw + push bc + ei ; Allow Ints again + ret + .else + ei ; Allow Ints again + jp PROGBASE ;0100H ; ..begin UZI task execution + .endif + + .if 0 ; Nick has temporarily removed CP/M support +ExeCPM: EI + JP EStart ; Execute Bios Cold Boot + .endif +; } + +;/*-----------------------------------------------------*/ +; /* Get a string from User to kernel Space up to count chars +; * in length. Addresses > Common base fetch from Common. +; * This module MUST be in Common memory since it transfers +; * a character-at-a-time by switching banks in context. +; * Function called as: ugets (SourceAdr, DestAdr, MaxLength). +; * Exit: HL = 0 if Ok, <>0 (hopefully) if string too long. +; */ +; ugets (char *uptr, char *sptr, unsigned count); + +_ugets: + .if 1 ; IAR + ld hl,4 ; assumes banked memory model (bbr on stack) + add hl,sp + + push bc + push de + push iy + + push bc + pop iy ; destination to iy (2nd argument) + + ld c,(hl) + inc hl + ld b,(hl) ; count to bc (3rd argument) + + ex de,hl ; source to hl (1st argument) + .else + ld hl,+7 + add hl,sp ; Pt to Hi-byte of count + push iy + ld b,(hl) + dec hl + ld c,(hl) ; Get count to BC + dec hl + ld d,(hl) + dec hl + ld e,(hl) ; Destination to DE (always in kernel space) + push de + pop iy ; (transfer to iy) + dec hl + ld a,(hl) + dec hl + ld l,(hl) + ld h,a ; Source to HL + .endif + ld a,(_osBank) ; (assume Yes by loading kernel base) + ld e,a ; set dest bank to kernel + ld a,(_ub+OPAGE) ; Else load User Bank as source + ld d,a ; save source bank + LD A,R + PUSH AF ; (save Interrupt Flag as B2) + IN0 A,(CBR) ; Get Current Bank + push af ; save for exit + + di ; No Ints while we transfer the string +l0: OUT0 (CBR),D ; Switch to User Bank + ld a,(hl) ; Get a byte + inc hl ; bump ptr + OUT0 (CBR),E ; Switch to kernel Bank + ld (iy+0),a ; save byte + inc iy ; bump ptr + or a ; End? + jr z,l1 ;1f ; ..jump to exit if Yes + + dec bc ; Dec max count + ld a,b + or c ; Destination full? + jr nz,l0 ;0b ; .loop if Not + dec iy ; Else back up destination + ld (iy+0),0 ; Terminate dest string + jr l2 ;2f ; ..exit w/hl hopefully non-zero + +l1: ld hl,0 ; Return 0 if Ok +l2: pop af + OUT0 (CBR),A ; Bring Entry Bank back in context + POP AF ; Restore Int Flag in B2 + POP IY ; and Regs + AND 04H ; Were Ints ON at Entry? + .if 1 ; IAR + jr z,$+3 + ei +; push hl +; ld hl,LWRD _ei +; ld a,BYTE3 _ei +; call nz,?BANK_CALL_DIRECT_L08 +; pop hl + + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + .else + RET Z ; ..exit if No, Ints stay Off + EI ; Else Ints On + ret + .endif + + +;/*-----------------------------------------------------*/ +; Move block of data from System to User Space +; uput (char *sptr, char *uptr, unsigned nbytes) + +_uput: + .if 1 ; IAR + ld hl,4 ; assumes banked memory model (bbr on stack) + add hl,sp + + push bc + push de + push iy + + ld a,(hl) + inc hl + ld h,(hl) + ld l,a +; call ahexw + .else + pop hl ; Ret Addr + pop de ; Source (*sptr) + pop bc ; Dest (*uptr) + ex (sp),hl ; Count to HL (nbytes) + .endif + LD A,R + PUSH AF ; (Save Int Flag in B2) + push hl ; Save Count + ld a,(_ub+OPAGE) ; Get Dest Bank + ld l,a ; (dest = LBC) + ld a,(_osBank) ; System Bank (Source) + JR _uget0 ; ..continue in common code below + +;/*-----------------------------------------------------*/ +; Move block of data from User to System space. +; uget (char *uptr, char *sptr, unsigned nbytes); + +_uget: + .if 1 ; IAR + ld hl,4 ; assumes banked memory model (bbr on stack) + add hl,sp + + push bc + push de + push iy + + ld a,(hl) + inc hl + ld h,(hl) + ld l,a + .else + pop hl ; Ret Addr + pop de ; Source (*uptr) + pop bc ; Dest (*sptr) + ex (sp),hl ; Count to HL (nbytes) + .endif + LD A,R + PUSH AF ; (Save Int Flag in B2) + push hl ; Save Count + ld a,(_osBank) ; Get Dest Bank + ld l,a ; (dest = LBC) + ld a,(_ub+OPAGE) ; User's Bank (Source) +_uget0: ld h,a ; (source = HDE) +; call ahexw + .if 1 +; push hl +; ld l,c +; ld h,b +; call ahexw +; pop hl +; ld a,'x' +; call abyte + bit 7,b + jr nz,$+4 ; 0 <= bc < 8000h ? + ld l,0 ; yes, it's relative to CA0 (0), not CA1 (CBR) + +; ex de,hl +; call ahexw +; ex de,hl +; ld a,'y' +; call abyte + bit 7,d + jr nz,$+4 ; 0 <= de < 8000h ? + ld h,0 ; yes, it's relative to CA0 (0), not CA1 (CBR) +; call ahexw +; ld a,'z' +; call abyte + .endif + .if 1 + ld a,e + ld e,d ; Shuffle to deal with high 16-bits + ld d,0 ; and Addr to 16-bits + + push hl + ld l,h ; so that l = source bank # + + ld h,d ;0 ; Expand Source Bank + add hl,hl ; Source Bank # + add hl,hl ; * 16 + add hl,hl + add hl,hl + add hl,de ; + Hi 8-bits of addr + + ld d,l + ld e,a ; h:de -> source data + push de ; save value for iy + pop iy ; h:iy -> source data + ld d,h ; d:iy -> source data + + ld a,c + ld c,b ; Shuffle to deal with high 16-bits + ld b,0 ; and Addr to 16-bits + + pop hl ; so that l = source bank # + + ld h,b ;0 ; Expand Dest Bank + add hl,hl ; Dest Bank # + add hl,hl ; * 16 + add hl,hl + add hl,hl + add hl,bc ; + Hi 8-bits of Addr + + ld e,h + ld h,l + ld l,a ; e:hl -> destination spot + + pop bc ; bc = count + call copyr ; go and copy it, in small blocks !! + .else + di ; NO INTERRUPTS while we play around here! + OUT0 (SAR0L),E ; Set Source LSB + OUT0 (SAR0L+3),C ; and Dest LSB + PUSH HL ; Save both bank CBR values + LD H,0 + ADD HL,HL ; while we massage Dest Bank # + ADD HL,HL + ADD HL,HL + ADD HL,HL + LD C,B ; Position Dest (MSB) + LD B,0 + ADD HL,BC ; Add processed Bank to Dest Addr MSB + OUT0 (SAR0L+4),L ; Set Dest MSB + OUT0 (SAR0L+5),H ; and Bank + POP HL ; Restore Bank CBR values + LD L,H + LD H,0 ; position + ADD HL,HL ; and massage Source Bank # + ADD HL,HL + ADD HL,HL + ADD HL,HL + LD E,D ; Position Source (MSB) + LD D,0 + ADD HL,DE ; Add processed Bank to Source Addr MSB + OUT0 (SAR0L+1),L ; Set Source MSB + OUT0 (SAR0L+2),H ; and Bank + + POP HL ; Restore Count + ld a,h + or l ; Anything to move? + jr z,ugetX ; ..quit here if Not + + OUT0 (SAR0L+6),L ; Set Count LSB + OUT0 (SAR0L+7),H ; and MSB + + LD A,00000010B ; Set DMA Mode control to Burst Mode + OUT0 (DMODE),A + LD A,40H ; Enable DMA0 + OUT0 (DSTAT),A ; and move the block + +ugetX: + .endif + POP AF ; Restore Int Flag + .if 1 + pop iy + .endif + .if 0 ; IAR + EX (SP),HL ; Ret Addr to HL, junk to stack + PUSH HL ; param + PUSH HL ; space + .endif + AND 04H ; Were Ints ON at entry? + .if 1 ; IAR + jr z,$+3 + ei +; ld hl,LWRD _ei +; ld a,BYTE3 _ei +; call nz,?BANK_CALL_DIRECT_L08 + + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + .else + CALL NZ,_ei ; If so, activate if Not in intr svc + JP (HL) ; "return" + .endif + + +;/*-----------------------------------------------------*/ +; Get a Word (16-bits) of data from Address in User Space +; ugetw (char *uptr) { +; int w; +; +; uget (uptr, &w, sizeof (int)); +; return (w); +; } + +_ugetw: + .if 1 ; IAR + push bc + push de + + ex de,hl ; argument to hl + .else + pop de ; Ret Addr + pop hl ; *uptr + push hl ; (keep Stack constant) + push de + .endif + IN0 A,(CBR) ; Get Current Bank + ld e,a ; (save for exit) + LD A,R + LD D,A ; (save Int flag as B2) + di ; No INTS while we switch banks + ld a,(_ub+OPAGE) + OUT0 (CBR),A ; Bring User Bank in context + ld a,(hl) ; fetch Word (lo) + inc hl + ld h,(hl) ; fetch (hi) + ld l,a ; Position return value + jr gpXit ; ..exit thru common code + + +;/*-----------------------------------------------------*/ +; Put a Word (16-bits) of data to Address in User Space +; uputw (int w, char *uptr) { +; uput (&w, uptr, sizeof (int)); +; } + +_uputw: + .if 1 ; IAR +; ld a,'x' +; call abyte + push bc + push de + + ld l,c + ld h,b ; 2nd argument to hl (uptr) + ld c,e + ld b,d ; 1st argument to bc (w) + .else + pop de ; Ret Addr + pop bc ; w + pop hl ; *uptr + push hl ; (keep Stack constant) + push bc + push de + .endif + IN0 A,(CBR) ; Get Current Bank + ld e,a ; (save for exit) + LD A,R + LD D,A ; (save Int flag as B2) + di ; No INTS while we switch banks + ld a,(_ub+OPAGE) + OUT0 (CBR),A ; Bring User Bank in context + ld (hl),c + inc hl + ld (hl),b ; store the word +gpXit: OUT0 (CBR),E ; Restore Entry Bank to context + BIT 2,D ; Were Ints ON at entry? + .if 1 ; IAR +; ld a,'y' +; call abyte + jr z,$+3 + ei +; push hl +; ld hl,LWRD _ei +; ld a,BYTE3 _ei +; call nz,?BANK_CALL_DIRECT_L08 +; pop hl +; ld a,'z' +; call abyte + + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + .else + JR NZ,_ei ; ..activate Ints if On and Not in intr svc + ret ; quit + .endif + + +;/*-----------------------------------------------------*/ +; Get a Byte of data from Address in User Space +; ugetc (char *uptr) { +; char c; +; +; uget (uptr, &c, 1); +; return (c); +; } + +_ugetc: + .if 1 ; IAR + push bc + push de + + ex de,hl ; argument to hl + .else + pop de ; Ret Addr + pop hl ; &w + push hl ; (keep Stack constant) + push de + .endif + IN0 A,(CBR) ; Get Current Bank + ld e,a ; (save for exit) + LD A,R + LD D,A ; (save Int flag as B2) + di ; No INTS while we switch banks + ld a,(_ub+OPAGE) + OUT0 (CBR),A ; Bring User Bank in context + ld l,(hl) + ld h,0 + jr gpXit ; ..exit thru common code + + +;/*-----------------------------------------------------*/ +; Put a Byte of data to Address in User Space +; uputc (int c, char *uptr) { +; uput (&c, uptr, 1); +; } + +_uputc: + .if 1 ; IAR + push bc + push de + + ld l,c + ld h,b ; 2nd argument to hl (uptr) + ld c,e + ld b,d ; 1st argument to bc (w) + .else + pop de ; Ret Addr + pop bc ; c + pop hl ; *uptr + push hl ; (keep Stack constant) + push bc + push de + .endif + IN0 A,(CBR) ; Get Current Bank + ld e,a ; (save for exit) + LD A,R + LD D,A ; (save Int flag as B2) + di ; No INTS while we switch banks + ld a,(_ub+OPAGE) + OUT0 (CBR),A ; Bring User Bank in context + ld (hl),c ; store the byte + jr gpXit ; ..exit thru common code + + +;;/*-----------------------------------------------------*/ +;;/* Disable interrupts */ +;;di() +;;{ +;;#asm +;_di: +;; ld a,'-' +;; call abyte +; di +;;#endasm +; .if 1 ; IAR +; jp ?BANK_FAST_LEAVE_L08 +; .else +; ret +; .endif +;;} +; +;;/*-----------------------------------------------------*/ +;;/* Enable interrupts if we are not in service routine */ +;;ei() +;;{ +;; if (inint) +; +;_ei: +;; ld a,'+' +;; call abyte +; ld a,(_inint) +; or a +; +;; return; +; +; .if 1 ; IAR +; jp z,?BANK_FAST_LEAVE_L08 +; .else +; ret z ; ..in Service routine, leave disabled +; .endif +;_ei_absolute: ; another entry point to save space (see below) +; ei ; else enable ints +;;} +; .if 1 ; IAR +; jp ?BANK_FAST_LEAVE_L08 +; .else +; ret +; .endif + +;/*--------------------------------------------------------------------*/ +;/* Disable interrupts regardless of whether we are in service routine */ +;di_absolute() +;{ +;#asm +_di_absolute: + di +;#endasm + .if 1 ; IAR + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif +;} + +;/* Enable interrupts regardless of whether we are in service routine */ +;ei_absolute() +;{ +;#asm +_ei_absolute: + ei +;#endasm + .if 1 ; IAR + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif +;} + +;/* Placeholder routines to increment/decrement kernel locking count */ + +_di: + ld hl,_unix_locked_out + inc (hl) + .if 1 ; IAR + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +_ei: + ld hl,_unix_locked_out + dec (hl) + + ; if it's zero, do something (wake all tasks waiting on lock??) + + .if 1 ; IAR + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +;*************************************************************** +; D A T A A R E A +;*************************************************************** + + rseg RCODE + +_osBank: defb 0 ; CBR Register value for Kernel data + + .if 0 ; Nick has temporarily removed CP/M support +_uzicom: defw 1 ; Executable Type (0 = CP/M, 1 = UZI) + .endif + +ptrrdy: defb 0 ; Ptr Ready Flag (for Int Ack) + +_timstk: defs 14 ; static char *timstk[14]; + ; /* Clock stack */ +_lcltim: defs 7 ; static char *lcltim[7]; + ; /* Raw Clock buff */ + +tmplen equ 200h ; Nick ;100 ; Length of Temp Stack +tstk: defs tmplen ; Temp Stack Space in Hi-Memory + + .if 0 ; Nick +endcom: + .endif + +; ----------------------------------------------------------------------------- + + END diff --git a/src/kernel/uzi/machdep.c b/src/kernel/uzi/machdep.c new file mode 100755 index 00000000..1a327888 --- /dev/null +++ b/src/kernel/uzi/machdep.c @@ -0,0 +1,313 @@ +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: machdep.c +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + * 9.12.97 - modified _asm for only Z80, added include for + * config.h, deleted from unix.h. HFB + */ + +#undef MEMDEBUG + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#define __KERNEL__ /* Nick please look into this */ +void panic(char *s, void *a1, void *a2, void *a3); /* Nick */ +void warning(char *s, void *a1, void *a2, void *a3); /* Nick */ + +/* This is chained to from the initial hardware setup in MACHASM.ASZ which + * performs initial required actions such as clearing uninitialized RAM, + * setting up the interrupt vector table, and disabling interrupts. Unique + * hardware setups should also have been performed prior to entering here. + * This is the equivalent of main() + */ + +fs_init() +{ + /* abyte('@'); */ + +#if 1 /* Nick UZIX compatible */ + total = 16; /* total number of writeable 16 kbyte pages in system (256k) */ +#endif + + inint = 0; + udata.u_insys = 1; + ei_absolute(); /* Nick */ + init2(); /* in process.c, never returns here */ +} + + +/* This checks to see if a user-suppled address is legitimate */ + +valadr (base, size) +char *base; +uint16 size; +{ +#ifndef UTIL /* can't validate addresses under Windows */ + if (base < PROGBASE || base+size > PROGTOP) /* >= (char *)&udata) */ + { + udata.u_error = EFAULT; + return(0); + } +#endif + return(1); +} + + +/* This adds two tick counts together. The t_time field holds up to + * one second of ticks, while the t_date field counts minutes. + */ + +addtick (t1, t2) +time_t *t1, *t2; +{ + t1->t_time += t2->t_time; + t1->t_date += t2->t_date; + if (t1->t_time >= 60*TICKSPERSEC) + { + t1->t_time -= 60*TICKSPERSEC; + ++t1->t_date; + } +} + + +incrtick (t) +time_t *t; +{ + if (++t->t_time == 60*TICKSPERSEC) + { + t->t_time = 0; + ++t->t_date; + } +} + + +static int cursig; +static int (*curvec)(); + +/*----------------------------------------------------------*/ +calltrap() +{ + /* Deal with a pending caught signal, if any. */ + /* udata.u_insys should be false, and interrupts enabled. + * Remember, the user may never return from the trap routine. + */ + + if (udata.u_cursig) + { + cursig = udata.u_cursig; + curvec = udata.u_sigvec[cursig]; + udata.u_cursig = 0; + + /* reset to default */ + udata.u_sigvec[cursig] = (void (*)(signal_t))SIG_DFL; + + /* call the user space handler */ + ei_absolute(); /* Nick */ + kprintf("calling pid %d signal %d handler at 0x%08lx\n", + udata.u_ptab->p_pid, cursig, (long)curvec); + (*curvec)(cursig); + kprintf("done signal handler\n"); + di_absolute(); /* Nick */ + } +} + +/*-----------------------------------------------------------*/ +/* Read date/time to System location from global variable */ +#ifndef UTIL +rdtime (tloc) +time_t *tloc; +{ + di_absolute(); /* Nick */ + tloc->t_time = tod.t_time; + tloc->t_date = tod.t_date; + ei_absolute(); /* Nick */ +} +#endif + + +/*--------------------------------------------------------*/ +/* Set Clock Date/Time. Error exit since Not implemented */ + +#ifdef UTIL +sttime() +{ + panic ("Calling sttime\n", 0, 0, 0); /* Nick added 0, 0, 0 */ +} +#endif + + +#if 1 /* Nick UZIX compatible */ +void panic(char *s, void *a1, void *a2, void *a3) +{ + /* what's the point di_absolute(); */ + ++inint; + kprintf("\nPANIC: "); + kprintf(s,a1,a2,a3); + kputchar('\n'); +#if 0 + idump(); +#endif + abort(99); +} + +/* warning() prints warning message to console */ +void warning(char *s, void *a1, void *a2, void *a3) +{ + kprintf("\nWARNING: "); + kprintf(s,a1,a2,a3); + kputchar('\n'); +} + +#if 0 /* Nick see main.c */ +#ifdef __KERNEL__ +/* kputs() prints zero-terminated character string to console */ +void kputs(s) + register char *s; +{ + while (*s) + kputchar((uchar)*(s++)); +} +#endif +#endif + +#if DEBUG > 0 +/* _idump() dumps state of all inodes + */ +static void _idump(void) +{ + register inoptr ip = i_tab; + + kprintf("Inodes:\tMAGIC\tDEV\tNUM\tMODE\tNLINK\t(DEV)\tREFS\tDIRTY\n"); + while (ip < i_tab + ITABSIZE) { + kprintf("#%d\t%d\t%p\t%u\t%06o\t%d\t%p\t%d\t%d\n", + ip - i_tab, ip->c_magic, ip->c_dev, ip->c_num, + ip->c_node.i_mode, ip->c_node.i_nlink, + DEVNUM(ip), ip->c_refs, ip->c_dirty); + ++ip; + } +} + +/* _pdump() dumps state of all processes + */ +static void _pdump(void) +{ + register ptptr pp = ptab; + + kprintf("Proc:\tSTATUS\tWAIT\tPID\tPPTR\tALARM\tPENDING\tIGNORED\tBREAK\n"); /*\tSP\n");*/ + while (pp < ptab + PTABSIZE) { + kprintf("#%d\t%d\t%p\t%d\t%d\t%d\t%p\t%p\t%p\t%p\n", + pp - ptab, pp->p_status, pp->p_wait, pp->p_pid, + pp->p_pptr - ptab, pp->p_alarm, pp->p_pending, + pp->p_ignored, pp->p_break/*, pp->p_sp*/); + ++pp; + } +} + +/* idump() dumps state of all system datas + */ +void idump(void) +{ + kprintf("%s: Errno %d, root #%d, Insys=%d, ptab #%d, callno=%d, cwd #%d, usp %p\n", + udata.u_name, + udata.u_error, root_ino - i_tab, + udata.u_insys, udata.u_ptab - ptab, + udata.u_callno, udata.u_cwd - i_tab, + udata.u_sp /*udata.u_ptab->p_sp*/); + _idump(); + _pdump(); + bufdump(); +} +#endif + +#else +/* This prints an error message and dies. */ + +panic (s) +char *s; +{ + di(); + inint = 1; + ei_absolute(); /* added by Nick... has to come after the above */ +#if 1 /* Nick */ + kprintf("\nPANIC: %s\n",s); +#else + kprintf("PANIC: %s\n",s); +#endif + idump(); + abort(); +} + + +warning (char *s) +{ + kprintf("WARNING: %s\n",s); +} + + +idump() +{ + inoptr ip; + ptptr pp; +#if 1 /* Nick UZIX compatible */ + extern cinode_t i_tab[]; +#else + extern struct cinode i_tab[]; +#endif + +#if 1 /* Nick UZIX compatible */ + kprintf("Err %d root %d\n", udata.u_error, root_ino - i_tab); +#else + kprintf("Err %d root %d\n", udata.u_error, root - i_tab); +#endif + kprintf ("\tMAGIC\tDEV\tNUM\tMODE\tNLINK\t(DEV)\tREFS\tDIRTY\n"); + + for (ip=i_tab; ip < i_tab+ITABSIZE; ++ip) + { + kprintf ("%d\t%d\t%d\t%u\t0%o\t", + ip-i_tab, ip->c_magic,ip->c_dev, ip->c_num, + ip->c_node.i_mode); + kprintf ("%d\t%d\t%d\t%d\n", /* line split for compiler */ + ip->c_node.i_nlink,ip->c_node.i_addr[0], + ip->c_refs,ip->c_dirty); + ifnot (ip->c_magic) + break; + } + + kprintf ("\tSTAT\tWAIT\tPID\tPPTR\tALARM\tPENDING\tIGNORED\tCHILD\n"); + for (pp=ptab; pp < ptab+PTABSIZE; ++pp) + { + kprintf ("%d\t%d\t0x%x\t%d\t", + pp-ptab, pp->p_status, pp->p_wait, pp->p_pid); + kprintf ("%d\t%d\t0x%x\t0x%x\t%x\n", /* line split for compiler */ + pp->p_pptr-ptab, pp->p_alarm, pp->p_pending, + pp->p_ignored, pp->p_fork_inf); + ifnot (pp->p_pptr) + break; + } + + bufdump(); + + kprintf ("insys %d ptab %d call %d cwd %d sp 0x%x\n", + udata.u_insys,udata.u_ptab-ptab, udata.u_callno, udata.u_cwd-i_tab, + udata.u_sp); +} +#endif + + +#if 0 /* Nick UZIX compatible */ +/* Min() calculate minimal of two numbers + * Must be function not macro! + */ +int Min(int a, int b) +{ + return (b < a ? b : a); +} +#endif + + diff --git a/src/kernel/uzi/main.c b/src/kernel/uzi/main.c new file mode 100755 index 00000000..18b4207d --- /dev/null +++ b/src/kernel/uzi/main.c @@ -0,0 +1,803 @@ +/* main.c for uzi180 by Nick - initialises CMX and then starts UZI as a task */ + +#define POLLED /* causes console I/O to be output via abyte() */ + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include +#include +#include +#include "devtty.h" + +void asci0_setup(void); +void asci1_setup(void); +void escc0_setup(void); +void escc1_setup(void); +void apibus_setup(void); +void timer0_setup(void); /* initializes timer 3, for CMX tick */ + +extern char osBank; /* defined in machasm */ +/* extern int root_dev; /* should be dev_t */ /* defined in extern.h */ + +/* extern char silly; */ /* Nick, very silly !! */ +extern char rom_serial_no[]; /* 5 digits (leading space padded) plus null */ + +#if 1 /* Nick UZIX compatible */ +char UZIX[14]="UZI180"; /* Nick "UZIX"; should be 13 chars or fewer */ +char HOST[14]="sn00000"; /* Nick kdata.k_host should be 13 chars or fewer */ +#endif + +byte uzi_slot; /* UZI task global slot number */ +extern void initsys(void); /* start of the UZI task's code */ + +extern char cmdblk[8]; /* for scsiop(), defined in devhd.c */ +extern long hd_offset; +extern long hd_sector; +extern char *dptr; +extern int dlen; +extern char *cptr; +extern int busid; + +void main(int argc, char **argv); +void timer0_handler(void); +#if 0 /* Nick, see kprintf.c */ +void kprintf(char *fmt, ...); +#endif +void kputchar(char c); +void puts(char *s); +void _putc(int minor, char c); +void tty_inproc(int minor, char c); /* in devtty.c */ +void my_tty_inproc(SDEV *device, char c); +#if 0 +void my_tty_inproc5(SDEV *device, char c); +#endif +#if 0 /* Nick, see kprintf.c */ +char *itob(int n, char *s, int base); +#endif +void bzero(char *ptr, int count); +void bcopy(char *src, char *dest, int count); +int int_min(int a, int b); +int int_max(int a, int b); +int scsiop(void); +void my_compactflash_in(SDEV *device, char c); +void my_touchscreen_in(SDEV *device, char c); +void sttime(time_t *tvec); +void hostname_setup(void); + +#if 0 +tcbpointer compactflash_tcbptr; /* must be initialised to NULL by runtime!! */ +#else +char compactflash_enable; /* must be initialised to 0 by runtime!! */ +#endif + +#if 0 +byte t0_cnt; /* used by interrupt, for counter */ +byte go_ahead; /* used by interrupt, to determine when to send messages */ + +char int_mesg[] = {"interrupt mesg"}; /* message that interrupt will send */ +#endif + +#if 0 +void initsysx(void) + { + while (1) + { + abyte ('#'); + } + } +#endif + +void main(int argc, char **argv) + { +#if 1 + int i; +#endif + byte status; + + /* abyte('C'); */ + +#if 1 + amess("kernel: parameters:"); + if (argc < 2) + { + amess(" none"); + } + else + { + for (i = 1; i < argc; i++) + { + abyte(' '); + amess(argv[i]); + } + } + acrlf(); + + root_dev = -1; + for (i = 1; i < argc; i++) + { + if (strlen(argv[i]) == 8 && + strncmp(argv[i], "root=hd", 7) == 0 && + (status = argv[i][7]) >= '0' && status <= '9') + { + root_dev = status - '0'; + } + } +#endif + + K_OS_Init(); /* initialize ram and things */ + K_Init_Sdevs(); /* set up serial port buffers */ + /* abyte('D'); */ + + asci0_setup(); + asci1_setup(); + escc0_setup(); + escc1_setup(); + apibus_setup(); + /* abyte('E'); */ + + /* initialise compactflash card (and synchronise WPO chip tx count) */ + K_Put_Str(10, "\x1bI", 2); + +#if 1 + K_Put_Str(1, "\r\nWelcome to Hytech CMX version 1.0\r\n", 37); + /* abyte('F'); */ +#endif + + K_Task_Create(2, &uzi_slot, initsys, 128); /* create UZI task */ + K_Task_Start(uzi_slot); /* trigger UZI task */ + + timer0_setup(); /* initialize and start timer, to produce CMX TICK */ + /* abyte('0'); */ + +#if 0 + K_Put_Str(0, "\r\nHello from Hytech CMX, serial port 0\r\n", 40); +/* K_Put_Str(1, "\r\nHello from Hytech CMX, serial port 1\r\n", 40); */ + K_Put_Str(2, "\r\nHello from Hytech CMX, serial port 2\r\n", 40); + K_Put_Str(3, "\r\nHello from Hytech CMX, serial port 3\r\n", 40); + K_Put_Str(5, "\x1bKHello from Hytech CMX, apibus port 5\r\n", 40); + K_Put_Str(6, "\x1bKHello from Hytech CMX, apibus port 6\r\n", 40); +#endif + +#if 0 + K_Put_Str(1, "\r\nPress any key to start the scheduler... ", 42); + + while (!K_Get_Char(1, &status)) + /* abyte('.') */; /* can't use CMX task blocking functions just yet */ + /* abyte('>'); */ + + K_Put_Char(1, &status); + + K_Put_Str(1, "\r\nStarting the RTOS scheduler\r\n", 31); +#endif + +#if 1 + hostname_setup(); + + K_OS_Disable_Interrupts(); + + /* redirect incoming characters on SERIAL 0 to the uzi tty handler */ + sdevs[0].rx_vector = my_tty_inproc; + sdevs[1].rx_vector = my_tty_inproc; + sdevs[2].rx_vector = my_tty_inproc; + sdevs[3].rx_vector = my_tty_inproc; + sdevs[4].rx_vector = my_tty_inproc; + sdevs[5].rx_vector = my_touchscreen_in; + sdevs[6].rx_vector = my_tty_inproc; + sdevs[7].rx_vector = my_tty_inproc; + sdevs[8].rx_vector = my_tty_inproc; + + /* redirect incoming data from CompactFlash to the uzi scsi handler */ + sdevs[10].rx_vector = my_compactflash_in; + + K_OS_Enable_Interrupts(); +#endif + + K_OS_Start(); /* enter CMX RTOS */ + } + +void timer0_handler(void) + { +#if 0 /* Nick, very temporary */ + K_OS_Tick_Update(); +#endif +#if 0 + if (go_ahead) /* see if task has enable message sending */ + { + if (++t0_cnt == 2) /* see if count = 2. */ + { + t0_cnt = 0; /* reset count */ + + /* The following allows an interrupt to use a CMX function, but + it must use it indirectly. Thus the interrupt must call + the respective CMX function with a leading 'int_' to the + function. */ + K_Intrp_Mesg_Send(0,int_mesg); + } + } +#endif + } + +#if 0 /* Nick, see kprintf.c */ +void kprintf (char *fmt, ...) +{ + register char *arg; + register char c; + int base; + char s[7], *itob(); + +/* abyte('{'); */ + arg = (char *)(&fmt+1); /* NOTE: Assumes Pointer to 2-byte Word */ +#if 0 + while (c = *fmt++) + { + kputchar(c); + } + ahexw(*(int *)arg); + abyte('}'); + return; +#endif + while (c = *fmt++) { + if (c != '%') { + kputchar (c); + continue; + } + switch (c = *fmt++) { + case 'c': kputchar (*arg++); arg++; /* for IAR compiler */ + continue; + case 'd': base = -10; + goto prt; + case 'o': base = 8; + goto prt; + case 'u': base = 10; + goto prt; + case 'p': /* Nick */ + case 'x': base = 16; + prt: + puts (itob (*(int *)arg, s, base)); + arg++; arg++; /* NOTE: for Size of Word Ptr */ + continue; + case 's': puts (*(char **)arg); + arg++; arg++; /* NOTE: for Size of Word Ptr */ + continue; + default: kputchar (c); + continue; + } + } +/* abyte('}'); */ +} +#endif + +void kputchar(char c) + { + if (c == '\n') +#if 0 + { + abyte('\r'); + } + abyte(c); +#else + { + _putc(0, '\r'); /* Use default TTY, minor=0 */ + } + _putc(0, c); +#endif + } + +void puts(char *s) + { + while (*s) + { + kputchar(*s++); + } + } + +void _putc(int minor, char c) + { +#ifdef POLLED + if (minor == 0 || minor == 2) + { + abyte(c); +#else + if (minor == 0) + { + K_Put_Char_Wait(1, &c, 0x1000); +#endif + } + else + { + K_Put_Char_Wait(minor - 1, &c, 0x1000); + } + } + +void my_tty_inproc(SDEV *device, char c) + { +#if 1 + register int minor; + + minor = device->port + 1; + (*tty_vector[minor])(minor, c); +#else + tty_inproc(1, c); +#endif + } + +#if 0 +void my_tty_inproc5(SDEV *device, char c) + { + tty_inproc(2, c); + } +#endif + +#if 0 /* Nick, see kprintf.c */ +#define TRUE 1 +#define FALSE 0 + +/* convert an integer to a string in any base (2-36) */ +char *itob (int n, char *s, int base) + { + register unsigned int u; + register char *p, *q; + register negative, c; + if ((n < 0) && (base == -10)) { + negative = TRUE; + u = -n; + } + else { + negative = FALSE; + u = n; + } + if (base == -10) /* Signals signed conversion */ + base = 10; + p = q = s; + do { /* Generate digits in reverse order */ + if ((*p = u % base + '0') > '9') + *p += ('A' - ('9' + 1)); + ++p; + u = u / base; + } while (u > 0); + if (negative) + *p++ = '-'; + *p = '\0'; /* Terminate the string */ + while (q < --p) { /* Reverse the digits */ + c = *q; + *q++ = *p; + *p = c; + } + return s; + } +#endif + +void bzero(ptr, count) +char *ptr; +int count; + { + while (count--) + { + *ptr++ = 0; + } + } + +void bcopy(src, dest, count) +char *src, *dest; +int count; + { + while (count--) + { + *dest++ = *src++; + } + } + +int int_min(int a, int b) +{ + return (b < a ? b : a); +} + +int int_max(int a, int b) +{ + return (b > a ? b : a); +} + +int scsiop(void) + { + register char i, k; + register unsigned int j; /* counts up to n*0x200 */ + char checksum; /* can't be register */ + int timecnt = 0x1000; + +#if 0 + if (silly == 0) + while (1) + ; +#endif + +/** abyte(':'); **/ +#if 0 /* Nick very temporary */ + if (cmdblk[1] == 'W') + return 0; +#endif + +#if DEBUG > 1 + kprintf("scsiop: %c %u+%u,%u -> 0x%x\n", cmdblk[1], + (unsigned int)hd_sector, + (unsigned int)hd_offset, + (unsigned int)cmdblk[7], + (unsigned int)dptr); +#endif + + /* check for special hd_offset indicating the ramdrive is wanted */ + if (hd_offset == 0) + { + j = ((unsigned int)cmdblk[7]) << 9; + hd_sector = 0x40000L + (hd_sector << 9); + hd_offset = (((long)osBank) << 12) + (long)dptr; + + switch(cmdblk[1]) + { + case 'R': +/* kprintf("R %08lx -> %08lx, %04x\n", hd_sector, hd_offset, j); */ + copyr(hd_sector, hd_offset, j); + break; + case 'W': +/* kprintf("W %08lx -> %08lx, %04x\n", hd_offset, hd_sector, j); */ + copyr(hd_offset, hd_sector, j); + break; + } + + return 0; + } + + /* at this point partitioning doesn't matter, so clobber hd_sector */ + hd_sector += hd_offset; +/** abyte('a'); **/ + + + for (i = 0; i < cmdblk[7]; i++) + { +/** abyte('b'); **/ + cmdblk[2] = hd_sector; + cmdblk[3] = hd_sector >> 8; + cmdblk[4] = hd_sector >> 16; + cmdblk[5] = hd_sector >> 24; +/** abyte('c'); **/ + cmdblk[6] = 0xff - cmdblk[5] - cmdblk[4] + - cmdblk[3] - cmdblk[2]; +/** abyte('d'); **/ + +#if 0 + /* tell transmitter task waiting. */ + compactflash_tcbptr = activetcb; +#else + compactflash_enable = 1; /* prepare to receive esc sequence */ +#endif + +/* abyte('&'); */ + switch(cmdblk[1]) + { + + case 'R': +/** abyte('e'); **/ + if (K_Put_Str_Wait(10, cmdblk, 7, timecnt) != K_OK) + { +/** abyte('f'); **/ + return 1; + } +/** abyte('g'); **/ + break; + + case 'W': + if (K_Put_Str_Wait(10, cmdblk, 6, timecnt) != K_OK) + { + return 1; + } + + checksum = cmdblk[6]; + for (j = 0; j < 0x200; j += 0x20) + { + if (K_Put_Str_Wait(10, dptr + j, 0x20, timecnt) + != K_OK) + { + return 1; + } + for (k = 0; k < 0x20; k++) + { + checksum -= dptr[j + k]; + } +/* abyte('.'); */ + } + + if (K_Put_Char_Wait(10, &checksum, timecnt) != K_OK) + { + return 1; + } + break; + + } + +/* abyte('*'); */ +#if 0 + K_I_Disable_Sched(); /* set task block. */ + + /* see if still waiting for a response */ + K_OS_Disable_Interrupts(); /* DISABLE INTERRUPTS. */ + if (compactflash_tcbptr != NULL) + { + if (timecnt) /* wait on time too? */ + { + /* put task to sleep, indicating why */ + activetcb->tcbstate = WAIT | TIME; + } + else + { + /* put task to sleep, indicating why */ + activetcb->tcbstate = WAIT; + } + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + + K_I_Insert_Link(timecnt); /* insert it into time link. */ + compactflash_tcbptr = NULL; /* task will return to here. */ + + K_I_Disable_Sched(); /* set task block. */ + if(K_I_Remove_Link()) /* remove from link. */ + { + K_I_Func_Return(); /* time out occurred. */ + return(K_TIMEOUT); + } + } + else + { + K_OS_Enable_Interrupts(); /* RE-ENABLE INTERRUPTS */ + } + K_I_Func_Return(); +#else + while (compactflash_enable) + ; /* rather primitive for the moment */ +#endif + + dptr += 0x200; + hd_sector++; + } +/** abyte(';'); **/ + + return 0; + } + +void my_compactflash_in(SDEV *device, char c) + { + static char state = 0; + static char *dest; + static int count; + +#if 0 + if (compactflash_tcbptr == NULL) +#else + if (compactflash_enable == 0) +#endif + { +#if 0 + if (c == '0' || c == '1') + { + abyte(c + 6); + } +#endif + return; + } + + switch (state) + { + + case 0: + switch (c) + { + + case '0': + case '1': +#if 0 + abyte(c + 8); +#endif + break; + + case 0x1b: + state++; + break; + + } + break; + + case 1: + case 2: + case 3: + case 4: +#if 0 + if (state == 1) + { + abyte(c); + } +#endif + if (c == cmdblk[state]) + { + state++; + break; + } + state = 0; + break; + + case 5: + if (c == cmdblk[5]) + { + switch (cmdblk[1]) + { + + case 'R': + state = 6; /* reading, prepare for data xfer */ + dest = dptr; + count = 0x200; + break; + + case 'W': + state = 7; /* writing, skip data xfer step */ + break; + + default: + state = 0; /* should never get here */ + break; + + } + break; + } + state = 0; + break; + + case 6: + cmdblk[6] -= c; + *dest++ = c; +#if 0 + if ((count & 0x1f) == 0) + { + abyte('.'); + } +#endif + if (--count) + { + break; + } + state = 7; + break; + + case 7: + if (c == cmdblk[6]) + { +#if 0 + abyte('$'); +#endif +#if 0 + /* see if task waiting. */ + if (compactflash_tcbptr->tcbstate & WAIT) + { + /* yes, wake task. */ + device->xmit.tcbptr->tcbstate = RESUME; + if (compactflash_tcbptr->priority < + active_priority) + { + PREEMPTED; /*cmx_flag1 |= preempted;*/ /* yes, set preempted K_I_Scheduler flag */ + } + } + + compactflash_tcbptr = NULL; +#else + compactflash_enable = 0; /* command done ok */ +#endif + } +#if 0 + else { abyte('%'); } +#endif + /* we could also include retry stuff here */ + state = 0; + break; + + } + } + +void my_touchscreen_in(SDEV *device, char c) + { + static char state = 0; + static unsigned char message[8]; + + message[state] = c; + + switch (state) + { + + case 0: + switch (c) + { + + case 0x1b: + state++; + break; + + default: +#if 1 + (*tty_vector[6])(6, c); +#else + tty_inproc(2, c); +#endif + break; + + } + break; + + case 1: + if (c == 'T') + { + state++; + } + else + { + state = 0; + } + break; + + case 2: /* hour */ + case 3: /* mins */ + case 4: /* secs */ + case 5: /* month */ + case 6: /* day */ + state++; + break; + + case 7: /* year-1980 */ + tod.t_time = ((int)message[4] >> 1) | + ((int)message[3] << 5) | + ((int)message[2] << 11); + + tod.t_date = (int)message[6] | + ((int)message[5] << 5) | + ((int)message[7] << 9); + + state = 0; + break; + } + } + +void sttime(time_t *tvec) + { + char message[8]; + + message[0] = 0x1b; + message[1] = 'T'; + message[2] = (tvec->t_time >> 11) & 0x1f; /* hour */ + message[3] = (tvec->t_time >> 5) & 0x3f; /* mins */ + message[4] = (tvec->t_time << 1) & 0x3f; /* secs */ + message[5] = (tvec->t_date >> 5) & 0xf; /* month */ + message[6] = tvec->t_date & 0x1f; /* day */ + message[7] = (tvec->t_date >> 9) & 0x3f; /* year */ + + if (K_Put_Str_Wait(5, message, 8, 0x1000) != K_OK) + { + panic("can't sttime"); + } + } + +void hostname_setup(void) + { + register char i, j; + + for (i = 0; i < 5; i++) + { + if (rom_serial_no[i] != ' ') + { + break; + } + } + + j = 2; + while (i < 5 && rom_serial_no[i]) + { + HOST[j++] = rom_serial_no[i++]; + } + + HOST[j] = 0; + } + diff --git a/src/kernel/uzi/procasm.asm b/src/kernel/uzi/procasm.asm new file mode 100755 index 00000000..9eebc332 --- /dev/null +++ b/src/kernel/uzi/procasm.asm @@ -0,0 +1,770 @@ +;/*************************************************************** +; UZI (Unix Z80 Implementation) Kernel: procasm.asz +;---------------------------------------------------------------- +; Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke +; Copyright (C) 1998 by Harold F. Bower +; Portions Copyright (C) 1995 by Stefan Nitschke +;****************************************************************/ +;/* Revisions: +; */ + +; #include +; #include +; #include + + + public _swapout, _swapin, _dofork, _newid ; PUBlic + + extern _chksigs, _ptab_alloc, _getproc, _newproc ; in process.c + extern _panic ; in machdep.c + extern _tempstack, _ei, _osBank ; in machasm.asz + extern _ub, _runticks ; in data.c + + extern copyr + extern abyte + + .if 1 ; IAR + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + .endif + +$ asmdef.inc +$ z180.inc + + rseg UDATA0 +F199: defs 2 ; static ptptr newp (swapout) +F207: defs 2 ; static ptptr newp (swapin) +F218: defs 2 ; static ptptr p (dofork) + ; /* Temp storage for dofork */ +_newid: defs 2 ; int16 newid; + rseg CODE + +;--------------------------------------------------------------- +; /* Swapout swaps out the current process, finds another that is READY, +; * possibly the same process, and swaps it in. When a process is +; * restarted after calling swapout, it thinks it has just returned +; * from swapout(). +; */ +; /* This function can have no arguments or auto variables */ + +; swapout() +; { + +_swapout: + .if 1 ; IAR + push bc + push de + .endif +; this doesn't do anything - see chksigs +; DI ; Don't allow Ints while we do this + +; static ptptr newp; +; ptptr getproc(); + +; /* See if any signals are pending */ +; chksigs(); + + .if 1 ; IAR + ld hl,LWRD _chksigs + ld a,BYTE3 _chksigs + call ?BANK_CALL_DIRECT_L08 + .else + call _chksigs + .endif + +; /* Get a new process */ +; newp = getproc(); + + .if 1 ; IAR + ld hl,LWRD _getproc + ld a,BYTE3 _getproc + call ?BANK_CALL_DIRECT_L08 + .else + call _getproc + .endif + ld (F199),hl + +; added by Nick, see above + DI ; Don't allow Ints while we do this + +; /* If there is nothing else to run, just return */ +; if (newp == udata.u_ptab) + + LD DE,(_ub) + or a + sbc hl,de + JR nz,L19 + +; { +; udata.u_ptab->p_status = P_RUNNING; + + EX DE,HL + ld (hl),P_RUNNING ;1 + +; return (runticks = 0); + + ld hl,0 + ld (_runticks),hl + +; added by Nick, see above + EI + + .if 1 ; IAR + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +; } +; /* Save the stack pointer and critical registers */ +; /* Returns 1 if swapped */ +; #asm + +L19: +; added by Nick, see above + EI + + ld hl,01 ; This will return 1 if swapped + push hl ; will be return value + push ix + push iy + +; #endasm +; udata.u_sp = stkptr; + + ld (_ub+OSP),sp + +; Write the User Data Block to storage in the respective Memory Bank +; UZI180 - replaces "swrite();" with "uput (0xf000, 0xf000, 768);" +; swrite(); +; call _swrite + + LD HL,1000h ;768 ; Save all of ub, KStack and IStack + LD (dmaLen),HL ; Length + .if 1 ; new register convention + ; new: L:BC = destination address (L = CBR value, BC = offset) + ; H:DE = source address (H = CBR value, DE = offset) + + ld a,(_ub+OPAGE) + ld l,a + ld bc,7000h ; just before process data begins at 8000h + + sub a ;ld a,(_osBank) + ld h,a + ld de,_ub ; processing area in kernel data segment + .else + ; old: L = Destination Bank # + ; E = Source Bank # + ; BC = Start/Destination Address in Banks + + .if 1 ; Nick + LD BC,_ub ; Start Address in both Src and Dst + .else + LD BC,0F000H ; Start Address in both Src and Dst + .endif + LD A,(_osBank) + LD E,A ; Source Bank is Common1 + LD HL,(_ub+OPAGE) ; Dest Bank if that of Current Process + .endif + CALL LWRD MovDMA ; Save Common:udata to User:udata! + +; /* Read the new process in, and return into its context. */ +; swapin (newp); + + .if 1 ; IAR + ld de,(F199) ; 1st argument is passed in de + + ld hl,LWRD _swapin + ld a,BYTE3 _swapin + call ?BANK_CALL_DIRECT_L08 + .else + ld hl,(F199) + push hl + call _swapin + .endif + + +; /* We should never get here. */ +; panic ("swapin failed"); + + ld hl,msg19 + ex (sp),hl + .if 1 ; IAR + ld hl,LWRD _panic + ld a,BYTE3 _panic + call ?BANK_CALL_DIRECT_L08 + .else + call _panic + .endif + .if 0 ; should never get here, because panic() doesn't return + pop bc + ret + .endif +; } + + +;--------------------------------------------------------------- +; /* No automatics can be used past tempstack(); +; */ +; swapin (pp) +; ptptr pp; +; { + +_swapin: + .if 1 ; IAR +; push bc ; don't bother, we're throwing away our stack +; push de ; don't bother, we're throwing away our stack + .endif + +; static blkno_t blk; +; static ptptr newp; + +; di(); + + DI ; No Ints while we work here + + .if 1 ; IAR + ex de,hl ; hl = 1st argument (passed in de) + .else + pop de ; Ret Addr + pop hl ; newp + push hl + push de + .endif + ld (F207),hl ; local newp + +; /* See if process has ignored signals. If not ignored 0CH, +; * increase process priority (maybe an interactive task) +; */ +; if (newp->p_ignored != 0xC) + + ld de,0CH + ld iy,(F207) + ld l,(iy+20) + ld h,(iy+21) + or a + sbc hl,de + JR z,L1 + +; newp->p_priority = MAXINTER; + + ld (iy+16),5 + JR L22 + +; else +; newp->p_priority = MAXBACK2; + +L1: ld (iy+16),2 + +; tempstack(); + +L22: ld (iy+17),0 + .if 0 ; oopsy, don't do this IAR + ld hl,LWRD _tempstack + ld a,BYTE3 _tempstack + call ?BANK_CALL_DIRECT_L08 + .else + call _tempstack + .endif + +; /* Reload the user area */ +; UZI180 - User Data Area restored from Banked memory, and User Bank restored +; to context at exit. This replaces the reads/writes to/from swap device. + +; swapread (SWAPDEV, blk, 512, ((char *)(&udata+1))-512 ); + +; /* The user address space is read in two i/o operations, +; * one from 0x100 to the break, and then from the stack up. +; * Notice that this might also include part or all of the +; * user data, but never anything above it. +; */ +; swapread (SWAPDEV, +; blk+1, +; (((char *)(&udata+1))-PROGBASE) & ~511, +; PROGBASE); + +; udata.u_page = newp->p_page; /* Set u_page so uget works */ + + LD IY,(F207) + LD A,(IY+14) + ld (_ub+OPAGE),a + +; uget (0xf000, 0xf000, 768); + + LD HL,1000h ;768 ; Get all of ub, KStack and IStack + LD (dmaLen),HL ; Length + .if 1 ; new register convention + ; new: L:BC = destination address (L = CBR value, BC = offset) + ; H:DE = source address (H = CBR value, DE = offset) + + ld a,(_ub+OPAGE) + ld h,a + ld de,7000h ; just before process data begins at 8000h + + sub a ;ld a,(_osBank) + ld l,a + ld bc,_ub ; processing area in kernel data segment + .else + ; old: L = Destination Bank # + ; E = Source Bank # + ; BC = Start/Destination Address in Banks + + .if 1 ; Nick + LD BC,_ub ; Start Address in both Src and Dst + .else + LD BC,0F000H ; Start Address in both Src and Dst + .endif + LD A,(_ub+OPAGE) + LD E,A ; Source Bank is that of Current Process + LD HL,(_osBank) ; Dest Bank is Common1 + .endif + CALL LWRD MovDMA ; Move User:ubase to Common:ubase + +; if (newp != udata.u_ptab) + + ld de,(F207) + ld hl,(_ub) + or a + sbc hl,de + JR z,L23 + +; panic ("mangled swapin"); + + ld hl,msg29 + push hl + .if 1 ; IAR + ld hl,LWRD _panic + ld a,BYTE3 _panic + call ?BANK_CALL_DIRECT_L08 + .else + call _panic + .endif + pop bc + +; di(); + +L23: DI + +; newp->p_status = P_RUNNING; + + EX DE,HL + ld (hl),P_RUNNING ;1 + +; runticks = 0; + + ld hl,0 + ld (_runticks),hl + +; /* Restore the registers */ +; stkptr = udata.u_sp; + + ld sp,(_ub+OSP) + +; #asm + pop iy + pop ix + .if 1 + ld hl,LWRD _ei + ld a,BYTE3 _ei + call ?BANK_CALL_DIRECT_L08 + pop hl + + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + .else + pop hl + JP _ei ; ..Exit, possibly enabling Ints + .endif + +; #endasm /* return into the context of the swapped-in process */ +; } + +;--------------------------------------------------------------- +; /* Dofork implements forking. +; * This function can have no arguments or auto variables. +; */ +; dofork() +; { + +_dofork: + .if 1 ; IAR + push bc + push de + .endif + +; static ptptr p; +; ptptr ptab_alloc(); + +; ifnot (p = ptab_alloc()) + + .if 1 ; IAR + ld hl,LWRD _ptab_alloc + ld a,BYTE3 _ptab_alloc + call ?BANK_CALL_DIRECT_L08 + .else + call _ptab_alloc + .endif + ld (F218),hl + ld a,l + or h + JR nz,L26 + +; { +; udata.u_error = EAGAIN; + + ld hl,EAGAIN ;11 + ld (_ub+OERR),hl + +; return(-1); + + ld hl,-1 + .if 1 ; IAR + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + +; } +; di(); + +L26: DI + +; udata.u_ptab->p_status = P_READY; /* Parent is READY */ + + ld hl,(_ub) + ld (hl),P_READY ;2 + +; newid = p->p_pid; + + ld HL,(F218) + INC HL + INC HL + LD A,(HL) + INC HL + LD H,(HL) + LD L,A + ld (_newid),hl + +; /* Save the stack pointer and critical registers. +; * When the process is swapped back in, it will be as if +; * it returns with the value of the childs pid. +; */ +; #asm + push hl ; HL still has _newid from above + push ix + push iy +; #endasm + +; udata.u_sp = stkptr; + + ld (_ub+OSP),sp + +; uput (0xf000, 0xf000, 768); /* in lieu of call to swrite() */ + + LD HL,1000h ;768 ; Save all of ub, KStack and IStack + LD (dmaLen),HL ; Length + .if 1 ; new register convention + ; new: L:BC = destination address (L = CBR value, BC = offset) + ; H:DE = source address (H = CBR value, DE = offset) + + ld a,(_ub+OPAGE) + ld l,a + ld bc,7000h ; just before process data begins at 8000h + + sub a ;ld a,(_osBank) + ld h,a + ld de,_ub ; processing area in kernel data segment + .else + ; old: L = Destination Bank # + ; E = Source Bank # + ; BC = Start/Destination Address in Banks + + .if 1 ; Nick + LD BC,_ub ; Start Address in both Src and Dst + .else + LD BC,0F000H ; Start Address in both Src and Dst + .endif + LD A,(_osBank) + LD E,A ; Source Bank is Common1 + LD HL,(_ub+OPAGE) ; Dest Bank if that of Current Process + .endif + CALL LWRD MovDMA ; Save Common:ubase to User:ubase! + +; #asm + pop hl ; reg set flag not needed + pop hl ; repair stack pointer + pop hl +; #endasm + + LD A,(_ub+OPAGE) ; Get Parent's Page + PUSH AF ; save for execve use + +; /* Make a new process table entry, etc. */ +; newproc (p); + + .if 1 ; IAR + ld de,(F218) ; de = p = 1st argument to call + + ld hl,LWRD _newproc + ld a,BYTE3 _newproc + call ?BANK_CALL_DIRECT_L08 + .else + ld hl,(F218) + push hl + call _newproc + pop bc + .endif + +; di(); + + DI ; (in case newproc enabled ints) + +; runticks = 0; + + ld hl,0 + ld (_runticks),hl + +; p->p_status = P_RUNNING; + + ld hl,(F218) + ld (hl),P_RUNNING ;1 + +; /* Added for correct execve() operation */ +; p->p_fork_inf = Parent_udata.u_page; /* Mark with Parent's Page # */ + + LD DE,26 ; Offset to p_fork_inf + ADD HL,DE + POP AF ; Restore Parent's Page # + LD (HL),A ; save + INC HL + LD (HL),0 ; as Integer + ; a & hl will be used again below !! + +; Copy entire 60k process into Child's address space + + .if 1 ; new register convention + ; new: L:BC = destination address (L = CBR value, BC = offset) + ; H:DE = source address (H = CBR value, DE = offset) + + .if 1 ; banked EXE format + ; don't corrupt a in here !! + inc hl + ld e,(hl) + inc hl + ld d,(hl) + ex de,hl ; hl = process's break level + + ld de,8000h ; de = start of process, PROGBASE-100h + or a + sbc hl,de ; hl = bytes to copy from start + ld (dmaLen),hl + .else + ld hl,PROGTOP-PROGBASE + ld (dmaLen),hl ; length to move + + ld de,PROGBASE ; source address + .endif + ld h,a ; source bank + + ld a,(_ub+OPAGE) + ld l,a ; destination bank + ld c,e + ld b,d ; destination address is same as source + .else + ; old: L = Destination Bank # + ; E = Source Bank # + ; BC = Start/Destination Address in Banks + + LD E,A ; Source Bank is Parent's Bank (E) + .if 1 + ld hl,PROGTOP-PROGBASE + ld (dmaLen),hl ; length to move + ld bc,PROGBASE ; addr in both starts at PROGBASE + .else + LD HL,0F000H + LD (dmaLen),HL ; Length to move is 60k + LD C,L + LD B,L ; Addr in both starts at 0000H + .endif + LD HL,(_ub+OPAGE) ; Dest is Child's Bank (L) + .endif + CALL LWRD MovDMA ; Copy Parent's data to Child's Space + +; ei(); + + .if 1 ; IAR + ld hl,LWRD _ei + ld a,BYTE3 _ei + call ?BANK_CALL_DIRECT_L08 + .else + call _ei + .endif + +; return (0); /* Return to child */ + + ld hl,0 +; } + .if 1 ; IAR + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif + + +;================================================================ +; Tailored generic DMA Move routine for Process Swaps used instead +; of calls to _uget and _uput to avoid all C-Procedure overhead. +; This code uses direct register setup for DMA Channel 0 instead +; of setting a data block and using the OTIMR block output instruc- +; tion. This code is six bytes longer, but 74 T-states faster. +; Enter: Length to move in variable dmaLen +; new: L:BC = destination address (L = CBR value, BC = offset) +; H:DE = source address (H = CBR value, DE = offset) +; old: L = Destination Bank # +; E = Source Bank # +; BC = Start/Destination Address in Banks +; Exit : None +; Uses : AF,BC,DE,HL + +MovDMA: + .if 1 ; new register convention + ; new: L:BC = destination address (L = CBR value, BC = offset) + ; H:DE = source address (H = CBR value, DE = offset) + + ld a,e + ld e,d ; Shuffle to deal with high 16-bits + ld d,0 ; and Addr to 16-bits + + push hl + ld l,h ; so that l = source bank # + + ld h,d ;0 ; Expand Source Bank + add hl,hl ; Source Bank # + add hl,hl ; * 16 + add hl,hl + add hl,hl + add hl,de ; + Hi 8-bits of addr + + ld d,l + ld e,a ; h:de -> source data + push de ; save value for iy + pop iy ; h:iy -> source data + ld d,h ; d:iy -> source data + + ld a,c + ld c,b ; Shuffle to deal with high 16-bits + ld b,0 ; and Addr to 16-bits + + pop hl ; so that l = dest bank # + + ld h,b ;0 ; Expand Dest Bank + add hl,hl ; Dest Bank # + add hl,hl ; * 16 + add hl,hl + add hl,hl + add hl,bc ; + Hi 8-bits of Addr + + ld e,h + ld h,l + ld l,a ; e:hl -> destination spot + + ld bc,(dmaLen) ; bc = count + jp copyr ; go and copy it, in small blocks !! + .else + ; old: L = Destination Bank # + ; E = Source Bank # + ; BC = Start/Destination Address in Banks + + .if 1 ; Nick + ld a,c + ld c,b ; Shuffle to deal with high 16-bits + ld b,0 ; and Addr to 16-bits + + ex de,hl ; so that l = source bank # + + ld h,b ;0 ; Expand Source Bank + add hl,hl ; Source Bank # + add hl,hl ; * 16 + add hl,hl + add hl,hl + add hl,bc ; + Hi 8-bits of addr + + push hl ; h will be restored into d, later on + ld h,l + ld l,a ; e:hl -> source data + ex (sp),hl ; save value for iy, get h = value for d + pop iy ; h:iy -> source data + + ex de,hl ; so that l = destination bank # + ; d:iy -> source data + + ld h,b ;0 ; Expand Dest Bank + add hl,hl ; Dest Bank # + add hl,hl ; * 16 + add hl,hl + add hl,hl + add hl,bc ; + Hi 8-bits of Addr + + ld e,h + ld h,l + ld l,a ; e:hl -> destination spot + + ld bc,(dmaLen) ; bc = count + jp copyr ; go and copy it, in small blocks !! + .else + OUT0 (SAR0L),C ; LSB Source Addr + OUT0 (DAR0L),C ; LSB Dest Addr + LD C,B ; Shuffle to deal with high 16-bits + XOR A + LD H,A ; Expand Dest Bank + LD D,A ; Source Bank + LD B,A ; and Addr to 16-bits + ADD HL,HL ; Dest Bank # + ADD HL,HL ; * 16 + ADD HL,HL + ADD HL,HL + ADD HL,BC ; + Hi 8-bits of Addr + OUT0 (DAR0L+1),L ; Set Dest middle Byte + OUT0 (DAR0B),H ; and Dest Bank + EX DE,HL ; Place Source Bank for work + ADD HL,HL ; Source Bank # + ADD HL,HL ; * 16 + ADD HL,HL + ADD HL,HL + ADD HL,BC ; + Hi 8-bits of Addr + OUT0 (SAR0L+1),L ; Set Source middle Byte + OUT0 (SAR0B),H ; and Source Bank + LD HL,(dmaLen) ; Get Length of move + OUT0 (BCR0L),L ; Set Low + OUT0 (BCR0H),H ; Set High + LD A,00000010B ; Set DMA Mode control to Burst Mode + OUT0 (DMODE),A + LD A,40H ; Enable DMA0 + OUT0 (DSTAT),A ; move the block + RET ; done. + .endif + .endif + +;---------------------------------------------------------------- + rseg IDATA0 +msg19: defs 14 + rseg CDATA0 + DEFM 'swapin failed' + DEFB 0 + rseg IDATA0 +msg29: defs 15 + rseg CDATA0 + DEFM 'mangled swapin' + DEFB 0 + + rseg UDATA0 +dmaLen: DEFS 2 ; Length of DMA Move + + end diff --git a/src/kernel/uzi/process.c b/src/kernel/uzi/process.c new file mode 100755 index 00000000..5ed822ff --- /dev/null +++ b/src/kernel/uzi/process.c @@ -0,0 +1,701 @@ +/*************************************************************** + UZI (Unix Z80 Implementation) Kernel: process.c +---------------------------------------------------------------- + Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke + Copyright (C) 1998 by Harold F. Bower + Portions Copyright (C) 1995 by Stefan Nitschke +****************************************************************/ +/* Revisions: + */ + +#if 0 /* Nick */ +#undef DEBUG /* Define to activate Debug Code */ +#endif + +/* #include "io64180.h" /* silly silly */ +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include "devio.h" /* prototypes added by Nick */ +#include "devtty.h" /* prototypes added by Nick */ +#include "filesys.h" /* prototypes added by Nick */ + +/* start of prototypes added by Nick */ +void systrace_entry(void); +void systrace_exit(void); +int dowait(void); +/* end of prototypes added by Nick */ + +/* silly prototype added by Nick */ +/* char silly_pause(void); */ + +#define NO_ASM /* define this for pure c-coding */ + +extern char osBank; /* defined in machasm */ + +#if 1 /* Nick UZIX compatible */ +extern char UZIX[]; /* operating system name, defined in main.c */ +#endif + + +init2() +{ + register char *j; + static char bootline[2]; +#if 1 + static char arg[] = { '/', 'b', 'i', 'n', '/', 'i', 'n', 'i', 't', 0, 0, + (int16)PROGBASE & 0xff, (int16)PROGBASE >> 8, + 0, 0, 0, 0 }; +#else + static char arg[] = {'/','i','n','i','t',0,0,0x01,0x01,0,0,0,0}; +#endif + inoptr i_open(); + ptptr ptab_alloc(); +/* Nick int d_open(),fmount(); */ + +#if 1 /* Nick, as udata is defined by defs statement, pad value 0xff */ + bzero (&udata, sizeof(udata_t)); +#endif + + bufinit(); +/* abyte('a'); */ + + /* Create the context for the first process + */ + newproc (udata.u_ptab = initproc = ptab_alloc()); +/* ahexw(udata.u_page); */ +/* abyte('b'); */ + initproc->p_status = P_RUNNING; + initproc->p_fork_inf = udata.u_page; /* set for use in execve */ + + /* User's file table + */ + for (j=udata.u_files; j < (udata.u_files+UFTSIZE); ++j) + *j = -1; + +/* abyte('c'); */ + ei_absolute(); /* Nick */ +/* abyte('d'); */ + +#if 0 /* Nick */ + /* Set Time-Of-Day absolutely, instead of waiting for interrupt */ + rdtod(); +#endif +/* abyte('e'); */ + + /* Open the console tty device thereby establishing the init + * process' controlling tty + */ + if (d_open (TTYDEV) != 0) + panic ("no tty"); +#if 1 /* Nick */ + tty_data[MINOR(TTYDEV)].t_flags = XTABS | CRMOD | ECHO | COOKED; +#else + tty_data[dev_tab[TTYDEV].minor].t_flags = XTABS | CRMOD | ECHO | COOKED; +#endif +/* abyte('f'); */ + +#if 1 /* Nick UZIX compatibility */ + kprintf("Welcome to Hytech %s version %s release %s\n\n", + UZIX, VERSION, RELEASE); +#else + kprintf ("UZI180 (c) Copyright (1998) by H.F.Bower, D.Braun, S.Nitschke\n"); +#endif + if (root_dev == (dev_t)-1) + { +#if 1 /* Nick */ + kprintf("root device? "); +#else + kprintf ("boot: "); +#endif + udata.u_base = bootline; + udata.u_sysio = 1; + udata.u_count = 2; + udata.u_euid = 0; /* Always begin as superuser */ + + cdread (TTYDEV); +#if 1 /* Nick UZIX compatible */ + root_dev = *bootline - '0'; +#else + ROOTDEV = *bootline - '0'; +#endif + } + +#if 1 /* Nick UZIX compatible */ + if (root_dev < 0 || root_dev >= NFS) /* number of mountable devs */ + { + root_dev = 0; + } +#else + if (ROOTDEV < 0 || ROOTDEV > 1) + { + ROOTDEV = 0; + } +#endif + + /* Mount the root device */ +/* abyte('g'); */ +#if 1 /* Nick UZIX compatible */ + if (fmount (root_dev, NULLINODE, 0)) +#else + if (fmount (ROOTDEV, NULLINODE)) +#endif + panic ("no filesys"); +/* abyte('h'); */ +#if 1 /* Nick UZIX compatible */ + if ((root_ino = i_open (root_dev, ROOTINODE)) == NULL) +#else + ifnot (root = i_open (ROOTDEV, ROOTINODE)) +#endif + panic ("no root"); +/* abyte('i'); */ + +#if 1 /* Nick UZIX compatible */ + udata.u_root = root_ino; /* already referenced by i_open */ + i_ref (udata.u_cwd = root_ino); +#else + i_ref (udata.u_cwd = root); +#endif +/* abyte('j'); */ + + rdtime (&udata.u_time); +/* abyte('k'); */ + + /* Poke the execve arguments into user data space the UZI280 way */ + uput (arg, PROGBASE, sizeof (arg)); +/* abyte('l'); */ + +#if 1 + udata.u_argn0 = (int16)PROGBASE; + udata.u_argn1 = (int16)PROGBASE + 7 + 4; /* Arguments (just "/init") */ + udata.u_argn2 = (int16)PROGBASE + 0xb + 4; /* Environment (none) */ +#else + udata.u_argn = (int16)PROGBASE; + udata.u_argn1 = 0x107; /* Arguments (just "/init") */ + udata.u_argn2 = 0x10b; /* Environment (none) */ +#endif + + sys_execve(); + + panic ("no /bin/init, errno %d", udata.u_error); /* BIG Trouble */ +} + + + +/* psleep() puts a process to sleep on the given event. If another + * process is runnable, it swaps out the current one and starts the + * new one. Normally when psleep is called, the interrupts have + * already been disabled. An event of 0 means a pause(), while an + * event equal to the process's own ptab address is a wait(). + */ + +psleep (event) +char *event; +{ + di_absolute(); /* Nick */ + if (udata.u_ptab->p_status != P_RUNNING) + panic ("psleep: voodoo"); + if (!event) + udata.u_ptab->p_status = P_PAUSE; + else if (event == (char *)udata.u_ptab) + udata.u_ptab->p_status = P_WAIT; + else + udata.u_ptab->p_status = P_SLEEP; + + udata.u_ptab->p_wait = event; + udata.u_ptab->p_waitno = ++waitno; + + ei_absolute(); /* Nick */ + swapout(); /* Swap us out, and start another process */ + /* Swapout doesn't return until we have been swapped back in */ +} + + + +/* wakeup() looks for any process waiting on the event, + * and makes it runnable + */ + +wakeup (event) +char *event; +{ + register ptptr p; + + di_absolute(); /* Nick */ + for (p=ptab; p < ptab+PTABSIZE; ++p) + { + if (p->p_status > P_RUNNING && p->p_wait == event) + { + p->p_status = P_READY; + p->p_wait = (char *)NULL; + } + } + ei_absolute(); /* Nick */ +} + + + +/* Getproc returns the process table pointer of a runnable process. + * It is actually the scheduler. If there are none, it loops. + * This is the only time-wasting loop in the system. + */ + +ptptr +getproc() +{ + register status; + static ptptr pp = ptab; /* Pointer for round-robin scheduling */ + + for (;;) + { + if (++pp >= ptab + PTABSIZE) + pp = ptab; + di_absolute(); /* Nick */ + status = pp->p_status; +#ifdef NO_ASM + ei_absolute(); /* Interrupts ON absolutely! (instead of "ei()") */ +#else +_asm + ei ; Interrupts ON absolutely! (instead of "ei()") +_endasm +#endif + + if (status == P_RUNNING) + panic ("getproc: extra running"); + if (status == P_READY) + return (pp); + } +} + + + +/* Newproc fixes up the tables for the child of a fork + */ +newproc (p) /* Passed New process table entry */ +ptptr p; +{ + register char *j; + + /* Note that ptab_alloc clears most of the entry */ + di_absolute(); /* Nick */ + /* p_swap is replaced by p_page for UZI180 Banked memory access. It is + * the BBR value for the base of the process area in memory (Byte value). + * The same value is also set in udata.u_page for use by put/get routines. + */ +#if 1 + udata.u_page = p->p_page = osBank + (0x10-7) + (p-ptab) * 9; +#else + udata.u_page = p->p_page = (p-ptab) * 0x10 + 0x10 + osBank; +#endif + p->p_status = P_RUNNING; + + p->p_pptr = udata.u_ptab; + p->p_ignored = udata.u_ptab->p_ignored; + p->p_tty - udata.u_ptab->p_tty; + ifnot (p->p_tty) /* If no tty, try tty of parent's parent */ + p->p_tty = udata.u_ptab->p_pptr->p_tty; + p->p_uid = udata.u_ptab->p_uid; + udata.u_ptab = p; + + bzero (&udata.u_utime, 4 * sizeof (time_t)); /* Clear tick counters */ + + rdtime (&udata.u_time); +#if 1 /* Nick UZIX compatible */ + if (udata.u_root) + i_ref (udata.u_root); +#endif + if (udata.u_cwd) + i_ref (udata.u_cwd); + udata.u_cursig = udata.u_error = 0; + +#if 1 /* Nick UZIX compatible */ + /* Set default priority */ + p->p_cprio = MAXTICKS; +#else + /* Set default priority */ + p->p_priority = MAXTICKS; +#endif + + for (j=udata.u_files; j < (udata.u_files+UFTSIZE); ++j) + if (*j >= 0) + ++of_tab[*j].o_refs; + ei_absolute(); /* Nick */ +} + + + +/* This allocates a new process table slot, and fills in its + * p_pid field with a unique number. + */ +ptptr +ptab_alloc() +{ + register ptptr p; + register ptptr pp; + static int nextpid = 0; + + di_absolute(); /* Nick */ + for (p=ptab; p < ptab+PTABSIZE; ++p) + { + if (p->p_status == P_EMPTY) + goto found; + } + ei_absolute(); /* Nick */ + return (NULL); + +found: + /* See if next pid number is unique */ +nogood: + if (nextpid++ > 32000) + nextpid = 1; + for (pp=ptab; pp < ptab+PTABSIZE; ++pp) + { + if (pp->p_status != P_EMPTY && pp->p_pid == nextpid) + goto nogood; + } + +#if 1 /* Nick UZIX compatible */ + bzero (p, sizeof (struct s_ptab)); +#else + bzero (p, sizeof (struct p_tab)); +#endif + p->p_pid = nextpid; + p->p_status = P_FORKING; + + ei_absolute(); /* Nick */ + return (p); +} + + + +/* This is the clock interrupt routine. Its job is to increment the clock + * counters, increment the tick count of the running process, and either + * swap it out if it has been in long enough and is in user space or mark + * it to be swapped out if in system space. Also it decrements the alarm + * clock of processes. + * UZI180: This is CALLed from the actual Interrupting service + * routine (See MACHASM.ASZ). HFB + * This must have no automatic or register variables. + */ +clkint2() +{ + static ptptr p; + + inint = 1; /* We arrived from H/W Interrupt */ + + /* Increment processes and global tick counters */ + if (udata.u_ptab->p_status == P_RUNNING) + incrtick (udata.u_insys ? &udata.u_stime : &udata.u_utime); + + incrtick (&ticks); + + /* Do once-per-second things */ + if (++sec == TICKSPERSEC) + { + /* Update global time counters */ + sec = 0; +#if 0 /* Nick */ + rdtod(); /* Update time-of-day */ +#endif + + /* Update process alarm clocks */ + for (p=ptab; p < ptab+PTABSIZE; ++p) + { + if (p->p_alarm) + ifnot (--p->p_alarm) + ssig (p, SIGALRM); + } + } + /* Check run time of current process */ +#if 1 /* Nick UZIX compatible */ + if ((++runticks >= udata.u_ptab->p_cprio) +#else + if ((++runticks >= udata.u_ptab->p_priority) +#endif + && !udata.u_insys && (inint == 1)) /* Time to swap out */ + { + di_absolute(); /* Nick, formerly just di; must have been a mistake */ + udata.u_insys = 1; + inint = 0; + udata.u_ptab->p_status = P_READY; + swapout(); + udata.u_insys = 0; /* We have swapped back in */ + } + inint = 0; +} + + + +extern int (*disp_tab[])(); /* in data.c */ +extern int ncalls; + +/* Unix System Call Trap Routine secondary processing. The primary + * Interrupt trap is in PROCASM.ASZ which manages state saving, then + * vectors here for final activity. + * No auto vars here, so flags will be preserved. + */ +unix2() +{ +/* abyte('&'); */ +/* ahexw((int16)osBank); */ +/* abyte(' '); */ +/* ahexw((int16)CBR); */ +/* abyte(' '); */ +/* ahexw((int16)udata.u_ptab); */ +/* abyte(' '); */ +/* ahexw(udata.u_ptab->p_pending); */ + udata.u_insys = 1; + udata.u_error = 0; + + /* UZI180 saves the Stack Pointer and arguments in the + * Assembly Language Function handler in MACHASM.ASZ + */ + if (udata.u_callno >= ncalls) + udata.u_error = EINVAL; +/* abyte('0'); */ + ei_absolute(); /* Nick */ +/* abyte('1'); */ + +#if DEBUG > 0 && !defined(UTIL) + if (traceon) + { +#if 1 + systrace_entry(); +#else + kprintf ("\t\tcall %d (%x, %x, %x, %x)\n", udata.u_callno, /* Nick */ + udata.u_argn, udata.u_argn1, udata.u_argn2, udata.u_argn3); +#endif +/* silly_pause(); */ + } +#endif +/* abyte('2'); */ + + /* Branch to correct routine */ + ifnot (udata.u_error) /* Could be set by ugetw() */ + udata.u_retval = (*disp_tab[udata.u_callno])(); +/* abyte('3'); */ + +#if DEBUG > 0 && !defined(UTIL) + if (traceon) + { +#if 1 + systrace_exit(); +#else + kprintf ("\t\t\tcall %d, ret %x err %d\n", + udata.u_callno, udata.u_retval, udata.u_error); +#endif + } +#endif +/* abyte('4'); */ + + chksigs(); +/* abyte('5'); */ + + di_absolute(); /* Nick */ +#if 1 /* Nick UZIX compatible */ + if (runticks >= udata.u_ptab->p_cprio) /* Time to swap out */ +#else + if (runticks >= udata.u_ptab->p_priority) /* Time to swap out */ +#endif + { + udata.u_ptab->p_status = P_READY; + swapout(); + } + ei_absolute(); /* Nick */ + udata.u_insys = 0; +/*=== calltrap(); /* Call Trap Routine if necessary */ +/* abyte('*'); */ + + if (udata.u_error) + return (-1); + + return (udata.u_retval); +} + + + +/* This sees if the current process has any signals set, and handles them. + */ +chksigs() +{ + register j; + + di_absolute(); /* Nick */ + ifnot (udata.u_ptab->p_pending) + { + ei_absolute(); /* Nick */ + return; + } + + for (j=1; j < NSIGS; ++j) + { + ifnot (sigmask(j) & udata.u_ptab->p_pending) + continue; + if (udata.u_sigvec[j] == SIG_DFL) + { + ei_absolute(); /* Nick */ +#ifdef DEBUG + kprintf("process terminated by signal %d: ", j); /* Nick %d */ +#endif + doexit (0, j); + } + + if (((long)udata.u_sigvec[j]) != SIG_IGN) + { + /* Arrange to call the user routine at return */ + udata.u_ptab->p_pending &= ~sigmask(j); + udata.u_cursig = j; + } + } + ei_absolute(); /* Nick */ +} + + + +sgrpsig (tty, sig) +int tty; +int16 sig; +{ + register ptptr p; + + for (p=ptab; p < ptab+PTABSIZE; ++p) { + if (p->p_status && p->p_tty == tty) + ssig (p, sig); + } +} + + + +/*-- sendsig (ptptr proc, int16 sig) + *-- { + *-- register ptptr p; + + *-- if (proc) + *-- ssig (proc, sig); + *-- else + *-- for (p=ptab; p < ptab+PTABSIZE; ++p) + *-- if (p->p_status) + *-- ssig (p, sig); + *-- }--*/ + + + +ssig (proc, sig) +ptptr proc; +int16 sig; +{ + register stat; + + di_absolute(); + ifnot (proc->p_status) + goto done; /* Presumably was killed just now */ + + if (proc->p_ignored & sigmask (sig)) + goto done; + + stat = proc->p_status; + if (stat == P_PAUSE || stat == P_WAIT || stat == P_SLEEP) + proc->p_status = P_READY; + + proc->p_wait = (char *)NULL; + proc->p_pending |= sigmask (sig); +done: + ei_absolute(); +} + + + +#if 1 /* Nick UZIX compatible */ +/* Sendsig() send signal sig to process p + * (or to all processes if p == NULL) + */ +void sendsig(ptptr p, signal_t sig) +{ + if (p) + ssig(p, sig); + else { + p = ptab; + while (p < ptab+PTABSIZE) { + if ((uchar)(p->p_status) > P_ZOMBIE) + ssig(p, sig); + ++p; + } + } +} +#endif + + + +#if 1 /* Nick UZIX compatible */ +/* dowait() + */ +#define pid (int)udata.u_argn0 +#define statloc (int *)udata.u_argn1 +#define options (int)udata.u_argn2 + +int dowait(void) +{ + register ptptr p; + int retval; + + for (;;) { + /* Search for an exited child */ + di_absolute(); + p = ptab; + while (p < ptab+PTABSIZE) { + if (p->p_pptr == udata.u_ptab && /* my own child! */ + (uchar)(p->p_status) == P_ZOMBIE) { + retval = p->p_pid; + /* if (pid < -1)... + wait for any child whose group ID is equal + to the absolute value of PID + - NOT IMPLEMENTED - + + if (pid == 0)... + wait for any child whose group ID is equal + to the group of the calling process + - NOT IMPLEMENTED - + + if option == WUNTRACED... + - NOT IMPLEMENTED - + */ + if (pid > 0) if (retval != pid) continue; + if (statloc != NULL) +#if 1 /* Nick */ + uputw(p->p_exitval, statloc); +#else + *statloc = p->p_exitval; +#endif + p->p_status = P_EMPTY; /* free ptab now! */ + /* Add in child's time info. + * It was stored on top of p_alarm in the childs + * process table entry + */ + addtick(&udata.u_cutime, (time_t *)&(p->p_break)+0); + addtick(&udata.u_cstime, (time_t *)&(p->p_break)+1); + ei_absolute(); + return retval; + } + ++p; + } + if (options & WNOHANG != 0) { + udata.u_error = ECHILD; + return 0; + } + /* Nothing yet, so wait */ + psleep(udata.u_ptab); /* P_WAIT */ + if (udata.u_ptab->p_intr) { + udata.u_error = EINTR; + return -1; + } + } +} + +#undef options +#undef statloc +#undef pid +#endif + + + diff --git a/src/kernel/uzi/scall1.c b/src/kernel/uzi/scall1.c new file mode 100755 index 00000000..c6414fed --- /dev/null +++ b/src/kernel/uzi/scall1.c @@ -0,0 +1,1452 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + Implementation of system calls +**********************************************************/ + +#define NEED__DEVIO +#define NEED__FILESYS +#define NEED__MACHDEP +#define NEED__PROCESS +#define NEED__SCALL + +#if 1 /* Nick */ +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include "devio.h" /* prototypes added by Nick */ +#include "filesys.h" /* prototypes added by Nick */ +#include "scall1.h" /* prototypes added by Nick */ +#define __KERNEL__ /* temporary */ +static int chany(char *path, int val1, int val2, bool_t mode); +#else /* Nick */ +#include "uzix.h" +#ifdef SEPH +#include "types.h" +#include "signal.h" +#include "errno.h" +#include "fcntl.h" +#include "sys\stat.h" +#include "sys\ioctl.h" +#endif +#include "unix.h" +#include "extern.h" +#endif /* Nick */ + +#define ISIZE(ino) ((ino)->c_node.i_size) + +/* definitions for 'UDATA' access */ +#define UOFFS (udata.u_offset) +#define UBAS (udata.u_base) +#define UCNT (udata.u_count) +#define UERR (udata.u_error) + +inoptr rwsetup(uchar fd, void *base, uint cnt, uchar rwflag); +#define psize(x) (uint)ISIZE(x) +#define addoff(x,y) *(x)+=(y) +#define updoff(x) of_tab[udata.u_files[x]].o_ptr = UOFFS +void stcpy(inoptr ino, struct stat *buf); +inoptr n_creat(char *name, bool_t new, mode_t mode); + +#if 1 /* Nick UZIX compatible */ +extern char UZIX[]; /* operating system name, defined in main.c */ +extern char HOST[]; /* this terminal's hostname, defined in main.c */ +#endif + +#ifdef __KERNEL__ +/********************************************* + SYSCALL NONE(); +**********************************************/ +int sys_NONE(void) +{ + UERR = ENOSYS; + return -1; +} +#endif /* __KERNEL__ */ + +/**************************************** + SYSCALL sync(void); +***************************************/ +int sys_sync(void) +{ + i_sync(); /* flushing inodes */ + fs_sync(); /* flushing superblocks */ + /* flushing buffers is already done by i_sync/fs_sync */ + return 0; +} + +#ifdef NEED__SCALL + +/******************************** + SYSCALL utime(char *path, struct utimbuf *buf); +********************************/ +#define path (char *)udata.u_argn0 +#define buf ((struct utimbuf *)udata.u_argn1) +int sys_utime(void) +{ + struct utimbuf lcl, *bufp = buf; + register inoptr ino; + + if (path == NULL) { + UERR = EFAULT; +Err: return -1; + } + if (bufp == NULL) { + bufp = &lcl; + rdtime(&bufp->actime); + bcopy(&bufp->actime, &bufp->modtime, sizeof(time_t)); + } +#if 1 /* Nick */ + else + { + uget((char *)bufp, (char *)&lcl, sizeof(struct utimbuf)); + bufp = &lcl; + } +#endif + if ((ino = namei(path, NULL, 1)) == NULL) + goto Err; + if (ino->c_node.i_uid != udata.u_euid && !super()) { + UERR = EPERM; + goto Err1; + } + if (ino->c_ro) { + UERR = EROFS; +Err1: i_deref(ino); + goto Err; + } + bcopy(&bufp->actime, &ino->c_node.i_atime, sizeof(time_t)); + bcopy(&bufp->modtime, &ino->c_node.i_mtime, sizeof(time_t)); + ino->c_dirty=1; + i_deref(ino); + return 0; +} +#undef path +#undef buf + +/********************************************* + SYSCALL close(int uindex); +**********************************************/ +#define uindex (uint)udata.u_argn0 +int sys_close(void) +{ + return doclose(uindex); +} +#undef uindex + +/* truncate the file, if a regular one, to zero length */ +void truncateto0(inoptr ino) + { + oft_t *op; + +#if 1 + if (S_ISREGALIGN(ino->c_node.i_mode)) /* regular file or XIP aligned */ +#else + if (getmode(ino) == S_IFREG) /* regular file */ +#endif + { + /* Truncate the regular file to zero length */ + ISIZE(ino) = 0; /* for future use */ + f_trunc(ino); + /* Reset any oft pointers */ + op = of_tab; + while (op < of_tab+OFTSIZE) + { + if (op->o_inode == ino) + op->o_ptr = 0; + ++op; + } + } + } + +/******************************************* + SYSCALL open(char *name, int flag, mode_t mode); +********************************************/ +#define name (char *)udata.u_argn0 +#define flag (int)udata.u_argn1 +#define mode udata.u_argn2 +int sys_open(void) +{ + ofptr of; + off_t *op; + register inoptr ino; + register int spf = flag; + uchar perm, oftindex, uindex; + + if ((flag &= 0xFF) > O_RDWR) { /* special flags in high byte */ + UERR = EINVAL; + goto Err1; + } + if (spf & O_SYMLINK) + spf = O_SYMLINK; + if ((uindex = uf_alloc()) == (uchar)-1 || /* user file descriptor */ + (oftindex = oft_alloc()) == (uchar)-1) /* system file descriptor */ + goto Err1; + if ((spf & O_NEW) || + (ino = namei(name, NULL, !(spf & O_SYMLINK))) == NULL) { /* open inode for name */ + if (!(spf & O_CREAT)) + goto Err; + mode = (S_IFREG | (mode & S_UMASK & ~udata.u_mask)); + udata.u_error = 0; + if ((ino = n_creat(name, (spf & O_NEW) != 0, mode)) == NULL) +#if 0 /* Nick's experimental addition */ + { + UERR = 10000; + goto Err; + } +#else + goto Err; +#endif + } + of = &of_tab[oftindex]; + of->o_inode = ino; /* save inode ref */ + perm = getperm(ino); /* check for permissions */ + if (((((uchar)flag == O_RDONLY) || (uchar)flag == O_RDWR) && + !((uchar)perm & S_IOREAD)) || + (((uchar)flag == O_WRONLY || (uchar)flag == O_RDWR) && + !((uchar)perm & S_IOWRITE))) { + UERR = EPERM; + goto Err; + } + if (((uchar)flag == O_WRONLY || (uchar)flag == O_RDWR) && + (ino->c_ro)) { + UERR = EROFS; + goto Err; + } + if ((spf & O_SYMLINK) && getmode(ino) != S_IFLNK) { + UERR = ESRCH; + goto Err; + } + if (getmode(ino) == S_IFDIR && /* directories only for read */ + flag != O_RDONLY) { + UERR = EISDIR; + goto Err; + } + if (isdevice(ino) && +#if 1 /* Nick */ + ino->c_refs == 1 && + /*of_tab[oftindex].o_refs == 1 &&*/ /* always true */ +#endif + d_open(DEVNUM(ino)) != 0) { + UERR = ENXIO; /* can't access to device */ + goto Err; + } + udata.u_files[uindex] = oftindex; /* user fd */ + op = &(of->o_ptr); + if (spf & O_APPEND) /* posit to end of file */ + *op = ino->c_node.i_size; + else *op = 0; /* posit to start of file */ + /* creat must truncate file to 0 if it exists! */ + if ((spf & (O_CREAT|O_TRUNC)) == (O_CREAT|O_TRUNC)) truncateto0(ino); + of->o_access = flag; + if (getmode(ino) == S_IFPIPE && of->o_refs == 1) + psleep(ino); /* sleep process if no writer of reader */ + return uindex; + +Err: oft_deref(oftindex); /* This will call i_deref() */ +Err1: return (-1); +} +#undef name +#undef flag +#undef mode + +/******************************************** + SYSCALL link(char *oldname, char *newname); +*********************************************/ +#define oldname (char *)udata.u_argn0 +#define newname (char *)udata.u_argn1 +int sys_link(void) +{ + register inoptr ino, ino2; + inoptr parent2 = NULL; + int ret = -1; +#if 1 + char fname[15]; +#endif + + if ((ino = namei(oldname, NULL, 1)) == 0) + goto Err1; + if (!(getperm(ino) & S_IOWRITE)) { + UERR = EPERM; + goto Err; + } + /* Make sure newname doesn't exist, and get its parent */ + if ((ino2 = namei(newname, &parent2, 1)) != NULL) { + i_deref(ino2); + UERR = EEXIST; + goto Err; + } + if (parent2 == NULL) /* even no path */ + goto Err; + if (ino->c_dev != parent2->c_dev) { + UERR = EXDEV; /* inter-device link not allowed */ + goto Err; + } +#if 1 /* Nick */ + filename(newname, fname); + if (ch_link(parent2, "", fname, ino) == 0) +#else + if (ch_link(parent2, "", filename(newname), ino) == 0) +#endif + goto Err; + /* Update the link count */ + ++ino->c_node.i_nlink; + if (wr_inode(ino) < 0) goto Err; + setftim(ino, C_TIME); + ret = 0; +Err: if (parent2 != NULL) + i_deref(parent2); + i_deref(ino); +Err1: return ret; +} +#undef oldname +#undef newname + +/******************************************** + SYSCALL symlink(char *oldname, char *newname); +*********************************************/ +#define oldname (char *)udata.u_argn0 +#define newname (char *)udata.u_argn1 +int sys_symlink(void) +{ + register inoptr ino = NULL; + int ret = -1; + mode_t mode = S_IFREG | (0666 & ~udata.u_mask); +#if 1 /* Nick for IAR compiler */ + char *p; +#endif + + /* Create newname as new IFREG node */ + if ((ino = n_creat(newname, 1, mode)) == NULL) + goto Ret; + /* fill in new file */ + UOFFS = 0; /* don't use a = b = c = 0 ! HTC doesn't like this */ + UCNT = 0; + UBAS = (uchar *)oldname; /* buf */ +#if 1 /* Nick for IAR compiler */ + p = oldname; + while (ugetc(p)) /* (*p) */ + { + p++; + udata.u_count++; + } +#else + while (ugetc(oldname++)) /* (*oldname++ != 0) */ + UCNT = UCNT+1; /* nbytes */ +#endif +#if 1 /* Nick */ + udata.u_sysio = 0; /* target of symlink is passed in user space */ +#endif + writei(ino); /* write it */ + /* change mode to LNK */ + ino->c_node.i_mode = (mode & S_UMASK) | S_IFLNK; + if (wr_inode(ino) < 0) goto Ret; + ret = 0; +Ret: if (ino != NULL) i_deref(ino); + return ret; +} +#undef oldname +#undef newname + +/******************************************* + SYSCALL unlink(char *path); +********************************************/ +#define path (char *)udata.u_argn0 +int sys_unlink(void) +{ + auto inoptr pino; + register inoptr ino = namei(path, &pino, 0); + int ret = -1; +#if 1 + char fname[15]; +#endif + + if (pino == NULL || ino == NULL) { + UERR = ENOENT; + goto Ret; + } + if (!(getperm(ino) & S_IOWRITE)) { + UERR = EPERM; + goto Ret; + } + /* Remove the directory entry */ +#if 1 + filename(path, fname); + if (ch_link(pino, fname, "", NULL) == 0) +#else + if (ch_link(pino, filename(path), "", NULL) == 0) +#endif + goto Ret; + /* Decrease the link count of the inode */ + if (ino->c_node.i_nlink-- == 0) + warning("_unlink: bad nlink %d",ino->c_node.i_nlink += 2); + setftim(ino, C_TIME); + ret = 0; +Ret: if (pino) i_deref(pino); + if (ino) i_deref(ino); + return ret; +} +#undef path + +/********************************************** + SYSCALL read(int d, char *buf, uint nbytes); + SYSCALL write(int d, char *buf, uint nbytes); +**********************************************/ +#define d (uint)udata.u_argn0 +#define buf (void *)udata.u_argn1 +#define nbytes (uint)udata.u_argn2 +#define isread (udata.u_callno == 23) +int sys_readwrite(void) +{ + register inoptr ino; + + /* Set up u_base, u_offset, ino; check permissions, file num. */ + if ((ino = rwsetup(d, buf, nbytes, isread)) == NULL) + return (-1); /* bomb out if error */ + if (nbytes) + if (isread) readi(ino); else writei(ino); + updoff(d); + return UCNT; +} +#undef d +#undef buf +#undef nbytes + +/************************************************ + SYSCALL lseek(int file, long offset, int whence); +************************************************/ +#define file (uchar)udata.u_argn0 +#define offset *((long *)&udata.u_argn1) +#define flag (int)udata.u_argn3 +int sys_lseek(void) +{ + register off_t* offp; + register inoptr ino; + + if ((ino = getinode(file)) == NULL) { +Err1: udata.u_retval1 = (-1); + return (-1); + } + if (getmode(ino) == S_IFPIPE) { + UERR = ESPIPE; + goto Err1; + } + offp = &of_tab[udata.u_files[file]].o_ptr; + switch (flag) { + case SEEK_SET: *offp = offset; break; + case SEEK_CUR: *offp += offset; break; + case SEEK_END: *offp = ISIZE(ino) + offset; break; + default: + UERR = EINVAL; + goto Err1; + } + udata.u_retval1 = ((uint *)offp)[1]; + return *(uint *)offp; +} +#undef file +#undef offset +#undef flag + +/************************************ + SYSCALL chdir(char *dir); +************************************/ +#define dir (char *)udata.u_argn0 +int sys_chdir(void) +{ + register inoptr newcwd; + + if ((newcwd = namei(dir, NULL, 1)) == 0) +Err1: return (-1); + if (getmode(newcwd) != S_IFDIR) { + i_deref(newcwd); + UERR = ENOTDIR; + goto Err1; + } + if (!(getperm(newcwd) & S_IOEXEC)) { + UERR = EPERM; + goto Err1; + } + i_deref(udata.u_cwd); + udata.u_cwd = newcwd; + return 0; +} +#undef dir + +/************************************ + SYSCALL chroot(char *dir); +************************************/ +#define dir (char *)udata.u_argn0 +int sys_chroot(void) +{ + if (sys_chdir() == 0) { + i_deref(udata.u_root); + udata.u_root = udata.u_cwd; + i_ref(udata.u_root); + return 0; + } + return -1; +} +#undef dir + +/********************************************* + SYSCALL mknod(char *name, mode_t mode, int dev); +*********************************************/ +#define name (char *)udata.u_argn0 +#define mode (int)udata.u_argn1 +#define dev (dev_t)udata.u_argn2 +int sys_mknod(void) +{ + register inoptr ino; + + mode &= ((~udata.u_mask & S_UMASK) | S_IFMT); + if (S_ISDEV(mode) && !super()) { /* only super able to create devs */ + UERR = EPERM; +Err1: return -1; + } + if ((ino = n_creat(name, 1, mode)) == NULL) + goto Err1; + /* Initialize device node */ + if (isdevice(ino)) { + DEVNUM(ino) = dev; + ino->c_dirty = 1; + } + if (wr_inode(ino) < 0) { + i_deref(ino); + goto Err1; + } + i_deref(ino); + return 0; +} +#undef name +#undef mode +#undef dev + +/**************************************** + SYSCALL access(char *path, int mode); +****************************************/ +#define path (char *)udata.u_argn0 +#define mode (int)udata.u_argn1 +int sys_access(void) +{ + register inoptr ino; + register int retval = -1; + uchar euid, egid; +#if 1 /* Nick for IAR compiler */ + /* char *p; */ + + /* p = path; */ + if ((mode &= 07) != 0 && ugetc(path) == 0) { +#else + if ((mode &= 07) != 0 && *path == 0) { +#endif + UERR = ENOENT; + goto Err1; + } + /* Temporarily make eff. id real id. */ + euid = udata.u_euid; + egid = udata.u_egid; + udata.u_euid = udata.u_ptab->p_uid; + udata.u_egid = udata.u_gid; + + if ((ino = namei(path, NULL, 1)) == NULL) + goto Err; + retval = 0; + if ((~getperm(ino) & mode) != 0) { + UERR = EPERM; + retval = -1; + } + i_deref(ino); +Err: udata.u_euid = euid; + udata.u_egid = egid; +Err1: return retval; +} +#undef path +#undef mode + +static int chany(char *path, int val1, int val2, bool_t mode) +{ + register inoptr ino; + + if ((ino = namei(path, NULL, 1)) == NULL) + goto Err1; + if (ino->c_node.i_uid != udata.u_euid && !super()) { + i_deref(ino); + UERR = EPERM; +Err1: return (-1); + } + if (mode) { + /* file class can't be changed */ + ino->c_node.i_mode &= S_IFMT; + ino->c_node.i_mode = (ino->c_node.i_mode | + ((mode_t)val1 & S_UMASK)); + } + else { + ino->c_node.i_uid = val1; + ino->c_node.i_gid = val2; + } + setftim(ino, C_TIME); + i_deref(ino); + return 0; +} + +/******************************************* + SYSCALL chmod(char *path, mode_t mode); +*******************************************/ +#define path (char *)udata.u_argn0 +#define mode (mode_t)udata.u_argn1 +int sys_chmod(void) +{ + return chany(path, (int)mode, 0, 1); +} +#undef path +#undef mode + +/************************************************* + SYSCALL chown(char *path, int owner, int group); +*************************************************/ +#define path (char *)udata.u_argn0 +#define owner (uchar)udata.u_argn1 +#define group (uchar)udata.u_argn2 +int sys_chown(void) +{ + return chany(path, owner, group, 0); +} +#undef path +#undef owner +#undef group + +#if 1 /* Nick UZIX compatible */ +/* stcpy() Utility for stat and fstat + */ +void stcpy(inoptr ino, struct stat *buf) +{ + /* don't bother making stat() and fstat() available to the kernel */ + /* but do ensure fields are copied individually, cinode_t may change */ + uputw(ino->c_dev, &buf->st_dev); + uputw(ino->c_num, &buf->st_ino); + uputw(ino->c_node.i_mode, &buf->st_mode); + uputw(ino->c_node.i_nlink, &buf->st_nlink); + uputw(ino->c_node.i_uid, &buf->st_uid); + uputw(ino->c_node.i_gid, &buf->st_gid); + uputw(DEVNUM(ino), &buf->st_rdev); + uput(&ino->c_node.i_size, &buf->st_size, sizeof(off_t)); + uput(&ino->c_node.i_atime, &buf->st_atime, 3*sizeof(time_t)); +} +#else +/* stcpy() Utility for stat and fstat + */ +void stcpy(inoptr ino, struct stat *buf) +{ + buf->st_dev = ino->c_dev; + buf->st_ino = ino->c_num; + buf->st_mode = ino->c_node.i_mode; + buf->st_nlink = ino->c_node.i_nlink; + buf->st_uid = ino->c_node.i_uid; + buf->st_gid = ino->c_node.i_gid; + buf->st_rdev = DEVNUM(ino); + bcopy(&ino->c_node.i_size, &buf->st_size, sizeof(off_t)); + bcopy(&ino->c_node.i_atime, &buf->st_atime, 3*sizeof(time_t)); +} +#endif + +/************************************** + SYSCALL stat(char *path, char *buf); + SYSCALL fstat(int fd, char *buf); + **************************************/ +#define path (char *)udata.u_argn0 +#define fd (uchar)udata.u_argn0 +#define buf (char *)udata.u_argn1 +#define isstat (udata.u_callno == 27) +int sys_statfstat(void) +{ + register inoptr ino; + + if (!valadr(buf, sizeof(struct stat))) goto Err; + if ((ino = isstat ? namei(path, NULL, 1) : getinode(fd)) == 0) { +Err: return -1; + } + stcpy(ino, (struct stat *)buf); + if (isstat) i_deref(ino); + return (0); +} +#undef path +#undef buf + +#if 1 /* Nick free bitmap */ +/************************************** + SYSCALL falign(int fd, int parm); + **************************************/ +#define fd (uchar)udata.u_argn0 +#define parm (int)udata.u_argn1 +int sys_falign(void) +{ + inoptr ino; + + ino = getinode(fd); + if (ino == 0) + { + return -1; + } + + switch (parm) + { + case XIP_ALIGN: + return bitmap_align(ino, ino->c_node.i_size); + + case XIP_UALIGN: + return bitmap_ualign(ino, ino->c_node.i_size); + } + + return -1; +} +#undef path +#undef buf +#endif /* Nick free bitmap */ + +/************************************ + SYSCALL dup(int oldd); +************************************/ +#define oldd (uchar)udata.u_argn0 +int sys_dup(void) +{ + register uchar newd, oftindex; + + if (getinode(oldd) == NULL || + (newd = uf_alloc()) == (uchar)-1) + return (-1); + oftindex = udata.u_files[oldd]; + udata.u_files[newd] = oftindex; + ++of_tab[oftindex].o_refs; + return newd; +} +#undef oldd + +/**************************************** + SYSCALL dup2(int oldd, int newd); +****************************************/ +#define oldd (uchar)udata.u_argn0 +#define newd (uchar)udata.u_argn1 +int sys_dup2(void) +{ + if (getinode(oldd) == NULL) + goto Err1; + if (newd >= UFTSIZE) { + UERR = EBADF; +Err1: return (-1); + } + if (!freefileentry(udata.u_files[newd])) + doclose(newd); + udata.u_files[newd] = udata.u_files[oldd]; + ++of_tab[udata.u_files[oldd]].o_refs; + return 0; +} +#undef oldd +#undef newd + +#if 1 /* Nick, new getfsys() convention */ +/* Special system call returns copies of UZIX + * structures for system dependent utils like df, ps... + */ +/*********************************************** + SYSCALL getfsys(dev_t devno, char *ubuf); +***********************************************/ +#define devno ((dev_t)udata.u_argn0) +#define ubuf ((char *)udata.u_argn1) +int sys_getfsys(void) + { + info_t buf; + + if (getfsys(devno, &buf)) + { + return -1; + } + + if (!valadr(ubuf, buf.size)) + { + return -1; + } + + uput((char *)buf.ptr, ubuf, buf.size); + return 0; + } +#undef devno +#undef ubuf +#else +/* Special system call returns pointers to UZIX + * structures for system dependent utils like df, ps... + */ +/*********************************************** + SYSCALL getfsys(dev_t devno, char *buf); formerly info_t *buf); +***********************************************/ +#define devno ((dev_t)udata.u_argn0) +#define buf ((info_t *)udata.u_argn1) +int sys_getfsys(void) +{ + return getfsys(devno, buf); +} +#undef devno +#undef buf +#endif + +/********************************************** + SYSCALL ioctl(int fd,int request, void *data); +**********************************************/ +#define fd (uchar)udata.u_argn0 +#define request (int)udata.u_argn1 +#define data (void *)udata.u_argn2 +int sys_ioctl(void) +{ + register inoptr ino; + + if ((ino = getinode(fd)) == NULL) + UERR = EBADF; + else if (!isdevice(ino)) + UERR = ENODEV; + else if ((getperm(ino) & S_IOWRITE) == 0) + UERR = EPERM; + else if (!d_ioctl(DEVNUM(ino), request, data)) + return 0; + return -1; +} +#undef fd +#undef request +#undef data + +/************************************************** + SYSCALL mount(char *spec, char *dir, int rwflag); + SYSCALL umount(char *spec); +**************************************************/ +#define spec (char *)udata.u_argn0 +#define dir (char *)udata.u_argn1 +#define rwflag (int)udata.u_argn2 +#define ismount (udata.u_callno == 19) +int sys_mountumount(void) +{ + register inoptr sino, dino; + register dev_t dev; + int sts = -1; + fsptr fp; + + if (!super()) { + UERR = EPERM; + goto Err1; + } + if ((sino = namei(spec, NULL, 1)) == NULL) + goto Err1; + if (ismount) if ((dino = namei(dir, NULL, 1)) == 0) { + i_deref(sino); + goto Err1; + } + if (getmode(sino) != S_IFBLK) { + UERR = ENOTBLK; + goto Err; + } + if (!ismount) { +#if 0 /* FIX THIS!... now fixed */ + if (!validdev(dev = DEVNUM(sino))) goto ErrIO; +#else + if (!validdev(dev = DEVNUM(sino),NULL)) goto ErrIO; +#endif + } else { + if (getmode(dino) != S_IFDIR) { + UERR = ENOTDIR; + goto Err; + } + if (d_open(dev = DEVNUM(sino))) { +ErrIO: UERR = ENXIO; + goto Err; + } + d_close(dev); /* fmount will open the device */ + } + fp = findfs(dev); + if (!ismount) { + if (!fp || !fp->s_mounted) { + UERR = EINVAL; + goto Err; + } + dino = i_tab; + while (dino < i_tab + ITABSIZE) { + if (dino->c_refs > 0 && dino->c_dev == dev) { + goto ErrBusy; + } + ++dino; + } + } else { + if (fp || dino->c_refs != 1 || dino->c_num == ROOTINODE) { +ErrBusy: UERR = EBUSY; + goto Err; + } + } + sys_sync(); + if (!ismount) { + fp->s_mounted = 0; + i_deref(fp->s_mntpt); + sts = 0; + } else { + if (!fmount(dev, dino, rwflag)) + sts = 0; + else goto ErrBusy; + } +Err: if (ismount) i_deref(dino); + i_deref(sino); +Err1: return sts; +} +#undef spec +#undef dir +#undef rwflag + +/*********************************** + SYSCALL time(time_t *tvec); +***********************************/ +#define tvec (time_t *)udata.u_argn0 +int sys_time(void) +{ +#if 1 /* Nick */ + time_t buf; + + rdtime(&buf); + uputw(buf.t_time, &(tvec)->t_time); + uputw(buf.t_date, &(tvec)->t_date); +#else + rdtime(tvec); +#endif + return 0; +} +#undef tvec + +/*======================================================================*/ + +#ifdef __KERNEL__ +/* exit0() - do exit through vector 0 (erroneous jmp to address 0) + */ +void exit0(void) +{ + doexit(-1, -1); +} +#endif /* __KERNEL__ */ + +/* create any kind of node */ +inoptr n_creat(char *name, bool_t new, mode_t mode) +{ + register inoptr ino; + auto inoptr parent = NULL; +#if 1 + char fname[15]; +#endif +#if DEBUG > 1 + char *buf; + + buf = tmpbuf(); + ugets(name, buf, 512); + kprintf("n_creat(\"%s\", %d, 0%o)\n", buf, new, mode); + brelse((bufptr)buf); +#endif + + if ((ino = namei(name, &parent, 1)) != NULL) { + /* The file already exists */ + if (new) { + UERR = EEXIST; /* need new file! */ + goto Err1; + } + i_deref(parent); /* parent not needed */ + if (getmode(ino) == S_IFDIR) { /* can't rewrite directory */ + UERR = EISDIR; + goto Err; + } + /* must have the write access */ + if ((getperm(ino) & S_IOWRITE) == 0) { + UERR = EACCES; + goto Err; + } + truncateto0(ino); + } + else { /* must create the new file */ + if (parent == NULL) /* missing path to file */ +#if 0 /* Nick experimental */ + { + UERR = 10003; + goto Err; + } +#else + goto Err; +#endif +#if 1 /* Nick */ + filename(name, fname); + if ((ino = newfile(parent, fname)) == NULL) +#else + if ((ino = newfile(parent, name)) == NULL) +#endif + /* Parent was derefed in newfile! */ +#if 0 /* Nick experimental */ + { + UERR = 10002; + goto Err; + } +#else + goto Err; /* Doesn't exist and can't make it */ +#endif + ino->c_node.i_mode = mode; + setftim(ino, A_TIME | M_TIME | C_TIME); + /* The rest of the inode is initialized in newfile() */ + if (_getmode(mode) == S_IFDIR) { + if (ch_link(ino, "", ".", ino) == 0 || + ch_link(ino, "", "..", parent) == 0) + goto Err1; + ino->c_node.i_size = 2*sizeof(direct_t); + ino->c_node.i_nlink++; + parent->c_node.i_nlink++; + parent->c_dirty = 1; + } + } + if (wr_inode(ino) < 0) +#if 0 /* Nick experimental */ + { + UERR = 10001; + goto Err; + } +#else + goto Err; +#endif +#if DEBUG > 1 + kprintf("n_creat() returning %u, success\n", ino - i_tab); +#endif + return ino; + +Err1: i_deref(parent); +Err: if (ino) + i_deref(ino); +#if DEBUG > 1 + kprintf("n_creat() returning NULL, error %u\n", udata.u_error); +#endif + return NULL; +} + +/* readwritei() implements reading/writing from/to any kind of inode + * udata prepared with parameters + */ + +void readwritei(char write, inoptr ino) +{ + register uint amount, todo, ublk, uoff, tdo = 0; + register char *bp; + register blkno_t pblk; + dev_t dev = ino->c_dev; + bool_t ispipe = 0; + +#if DEBUG > 1 + kprintf("readwritei(%u, %u) starting\n", (unsigned int)write, ino - i_tab); +#endif + + if (write && ino->c_ro) { + UERR = EROFS; +#if DEBUG > 1 + kprintf("readwritei() returning, error %u\n", udata.u_error); +#endif + return; + } + switch (getmode(ino)) { + case S_IFCHR: /* character device */ + UCNT = write ? cdwrite(DEVNUM(ino)) : cdread(DEVNUM(ino)); + if ((int)UCNT != -1) + addoff(&UOFFS, UCNT); +#if DEBUG > 1 + kprintf("readwritei() returning, error %u\n", udata.u_error); +#endif + return; + case S_IFLNK: /* sym link */ + if (write) goto error; + case S_IFDIR: /* directory */ + case S_IFREG: /* regular file */ +#if 1 /* Nick */ + case S_IFALIGN: /* aligned regular file */ +#endif + todo = UCNT; + if (!write) { + /* See if offset is beyond end of file */ + if ((unsigned long)UOFFS >= (unsigned long)ISIZE(ino)) { + UCNT = 0; +#if DEBUG > 1 + kprintf("readwritei() returning, error %u\n", udata.u_error); +#endif + return; + } + /* See if end of file will limit read */ + if (UOFFS + todo > ISIZE(ino)) + todo = (uint)(ISIZE(ino) - UOFFS); + UCNT = todo; + } + goto loop; +#ifdef __KERNEL__ + case S_IFPIPE: /* interprocess pipe */ + ++ispipe; + if (write) { /* write side */ + while ((todo = UCNT) > + (DIRECTBLOCKS * BUFSIZE) - psize(ino)) { + if (ino->c_refs == 1) { /* No readers - broken pipe */ + UCNT = -1; + UERR = EPIPE; + ssig(udata.u_ptab, SIGPIPE); +#if DEBUG > 1 + kprintf("readwritei() returning, error %u\n", udata.u_error); +#endif + return; + } + /* Sleep if full pipe */ + psleep(ino); /* P_SLEEP */ + } + goto loop; + } else { /* read side */ + while (psize(ino) == 0) { + if (ino->c_refs == 1) /* No writers */ + break; + /* Sleep if empty pipe */ + psleep(ino); /* P_SLEEP */ + } +#if 1 /* Nick */ + /* this really should be revised to uint_min */ + todo = int_min(udata.u_count, psize(ino)); +#else + todo = Min(UCNT, psize(ino)); +#endif + UCNT = todo; + goto loop; + } +#endif /* __KERNEL__ */ + case S_IFBLK: /* block device */ + dev = DEVNUM(ino); + todo = UCNT; + /* blockdev/directory/regular/pipe */ +loop: while (todo) { + ublk = (uint)(UOFFS >> BUFSIZELOG); + uoff = (uint)UOFFS & (BUFSIZE - 1); + pblk = bmap(ino, ublk, write ? 0 : 1); + if (!write) { + /* Nick added isdevice(ino) to allow access */ + /* to block 0 via open handle to /dev/hdX */ +#if 0 /* FIX THIS!... now fixed */ + bp = (pblk == NULLBLK && isdevice(ino) == 0) ? + zerobuf() : bread(dev, pblk, 0); +#else + bp = (pblk == NULLBLK && isdevice(ino) == 0) ? + zerobuf(1): bread(dev, pblk, 0); +#endif + if (bp == NULL) { + /* EFAULT: for FD, means, out of disk bounds! + * it's not really an error. it just means EOF... */ + if (UERR == EFAULT) + UERR = 0; +#if DEBUG > 1 + kprintf("readwritei() returning, error %u\n", udata.u_error); +#endif + return; + } + } +#if 1 /* Nick */ + /* this really should be revised to uint_min */ + amount = int_min(todo, BUFSIZE - uoff); +#else + amount = Min(todo, BUFSIZE - uoff); +#endif + if (write) { + if (pblk == NULLBLK && isdevice(ino) == 0) + return; /* No space to make more blocks */ + /* If we are writing an entire block, we don't care + * about its previous contents + */ + bp = bread(dev, pblk, (amount == BUFSIZE)); + if (bp == NULL) + { +#if DEBUG > 1 + kprintf("readwritei() returning, error %u\n", udata.u_error); +#endif + return; + } +#if 1 /* Nick */ + /* if System is in context or destination is in Common memory + * (F000-FFFF is always in context), simply copy the data. + * Otherwise perform Interbank move (uput) to User bank. + */ + if (udata.u_sysio || (udata.u_base < (char *)0x8000)) /* Nick >= (char *) 0xf000)) */ + bcopy (udata.u_base, bp + uoff, amount); + else + uget (udata.u_base, bp + uoff, amount); +#else + bcopy(UBAS, bp + uoff, amount); +#endif + if (bfree((bufptr)bp, 2) < 0) + { +#if DEBUG > 1 + kprintf("readwritei() returning, error %u\n", udata.u_error); +#endif + return; + } + } else { +#if 1 /* Nick */ + /* if System is in context or destination is in Common memory + * (F000-FFFF is always in context), simply copy the data. + * Otherwise perform Interbank move (uput) to User bank. + */ + if (udata.u_sysio || (udata.u_base < (char *)0x8000)) /* Nick >= (char *)0xf000)) */ + bcopy (bp + uoff, udata.u_base, amount); + else + uput (bp + uoff, udata.u_base, amount); +#else + bcopy(bp+uoff, UBAS, amount); +#endif + if (brelse((bufptr)bp) < 0) + { +#if DEBUG > 1 + kprintf("readwritei() returning, error %u\n", udata.u_error); +#endif + return; + } + } + UBAS = UBAS + amount; /* HTC stuff */ + tdo = tdo + amount; + addoff(&UOFFS, amount); + todo = todo - amount; +#ifdef __KERNEL__ + if (ispipe) { + if (ublk >= DIRECTBLOCKS) + UOFFS &= (BUFSIZE - 1); + addoff(&(ino->c_node.i_size), + write ? amount : -amount); + /* Wake up any readers/writers */ + wakeup(ino); + } +#endif /* __KERNEL__ */ + } + UCNT = tdo; + /* Update size if file grew */ + if (write && !ispipe) { + if (UOFFS > ISIZE(ino)) { + ISIZE(ino) = UOFFS; + ino->c_dirty = 1; + } + } +#if DEBUG > 1 + kprintf("readwritei() returning, success\n"); +#endif + return; + default: +error: UERR = ENODEV; + if (!write) + UCNT = -1; +#if DEBUG > 1 + kprintf("readwritei() returning, error %u\n", udata.u_error); +#endif + return; + } +} + +/* rwsetup() prepare udata for read/write file */ +inoptr rwsetup(uchar fd, void *base, uint cnt, uchar rdflag) +{ + register inoptr ino; + register ofptr oftp; + +#if DEBUG > 1 + kprintf("rwsetup(%u, 0x%x, %u, %u) starting\n", + (unsigned int)fd, base, cnt, (unsigned int)rdflag); +#endif + + if ((ino = getinode(fd)) == NULL) /* check fd */ + { +Err1: +#if DEBUG > 1 + kprintf("rwsetup() returning NULL, error %u\n", udata.u_error); +#endif + return NULL; + } + oftp = of_tab + udata.u_files[fd]; + if (oftp->o_access == (rdflag ? O_WRONLY : O_RDONLY)) { + UERR = EACCES; + goto Err1; + } + setftim(ino, rdflag ? A_TIME : (A_TIME | M_TIME)); + /* Initialize u_offset from file pointer */ + UOFFS = oftp->o_ptr; + UBAS = (uchar *)base; /* buf */ + UCNT = cnt; /* nbytes */ +#if 1 /* Nick */ + udata.u_sysio = 0; /* transfer is to be done on behalf of user */ +#endif +#if DEBUG > 1 + kprintf("rwsetup() returning %u, success\n", ino - i_tab); +#endif + return ino; +} + +#if 0 /* FIX THIS! */ +#ifdef __KERNEL__ +#define tmpbuf ((udata_t *)TEMPDBUF) +int pdat(struct s_pdata *ubuf) { + struct swap_mmread pp; + register ptptr p = ptab; +#ifdef PC_HOSTED + udata_t TEMPDBUF[1]; +#endif + + while (p < ptab+PTABSIZE) { + if (p->p_pid == ubuf->u_pid && p->p_status != P_ZOMBIE) { + if (p->p_status == P_RUNNING) + bcopy(&ub, tmpbuf, sizeof(udata_t)); + else { + pp.mm[0] = p->p_swap[0]; + pp.mm[1] = p->p_swap[1]; + pp.buf = (void *)tmpbuf; + pp.size = sizeof(udata_t); + pp.offset = (uint)p->p_udata; + if (swap_mmread(&pp) < 0) { + UERR = EIO; + goto Err; + } + } + ubuf->u_ptab = tmpbuf->u_ptab; + bcopy(tmpbuf->u_name, ubuf->u_name, DIRNAMELEN); + ubuf->u_insys = tmpbuf->u_insys; + ubuf->u_callno = tmpbuf->u_callno; +#if DEBUG > 1 + ubuf->u_traceme = tmpbuf->u_traceme; +#else + ubuf->u_traceme = 0; +#endif + ubuf->u_cursig = tmpbuf->u_cursig; + ubuf->u_euid = tmpbuf->u_euid; + ubuf->u_egid = tmpbuf->u_egid; + ubuf->u_gid = tmpbuf->u_gid; + ubuf->u_uid = p->p_uid; + ubuf->u_time = tmpbuf->u_time; + ubuf->u_utime = tmpbuf->u_utime; + ubuf->u_stime = tmpbuf->u_stime; + return 0; + } + ++p; + } + UERR = ESRCH; +Err: return -1; +} +#endif /* __KERNEL__ */ +#endif + +/* This function is support for getfsys syscall and /dev/kmem */ +#define ubuf ((struct s_pdata *)buf) +#if 1 /* Nick, new getfsys() convention */ +info_t ibuf; +struct s_kdata kbuf; +int getfsys(dev_t devno, info_t *buf) +#else +#define kbuf ((struct s_kdata *)buf) +int getfsys(dev_t devno, void *buf) +#endif + { + fsptr dev = findfs(devno); + register void *ptr = dev; +#if 1 /* Nick, new getfsys() convention */ + int cnt = sizeof(filesys_t); +#else + uchar cnt = 1; +#endif + + if (dev == NULL) + { + switch (devno) + { + case GI_FTAB: cnt = NFS; ptr = fs_tab; break; + case GI_ITAB: cnt = ITABSIZE; ptr = i_tab; break; + case GI_BTAB: cnt = NBUFS; ptr = bufpool; break; +#ifdef __KERNEL__ + case GI_PTAB: cnt = PTABSIZE; ptr = ptab; break; + case GI_UDAT: cnt = 1; ptr = &ub; break; + case GI_UTAB: cnt = 1; ptr = udata.u_ptab; break; +#if 0 /* FIX THIS! */ + case GI_PDAT: return pdat(ubuf); +#endif + +#if 1 /* Nick, new getfsys() convention */ + case GI_KDAT: bcopy(UZIX, kbuf.k_name, 14); + bcopy(VERSION, kbuf.k_version, 8); + bcopy(RELEASE, kbuf.k_release, 8); + + bcopy(HOST, kbuf.k_host, 14); + bcopy(HOST_MACHINE, kbuf.k_machine, 8); + + kbuf.k_tmem = total * 16; + kbuf.k_kmem = 32; /* 32k kernel */ + + cnt = sizeof(kbuf); + ptr = &kbuf; + goto getfsys_done; +#else +#if 1 /* Nick */ + case GI_KDAT: uput(UZIX, kbuf->k_name, 14); + uput(VERSION, kbuf->k_version, 8); + uput(RELEASE, kbuf->k_release, 8); + + uput(HOST, kbuf->k_host, 14); + uput(HOST_MACHINE, kbuf->k_machine, 8); + + uputw(total * 16, &kbuf->k_tmem); + uputw(32, &kbuf->k_kmem); /* 32k kernel */ + goto Ok; +#else + case GI_KDAT: bcopy(UZIX, kbuf->k_name, 14); + bcopy(VERSION, kbuf->k_version, 8); + bcopy(RELEASE, kbuf->k_release, 8); + + bcopy(HOST, kbuf->k_host, 14); + bcopy(HOST_MACHINE, kbuf->k_machine, 8); + + kbuf->k_tmem = total * 16; + kbuf->k_kmem = 32; /* 32k kernel */ + goto Ok; +#endif +#endif +#endif /* __KERNEL__ */ + default: + UERR = ENXIO; + return (-1); + } + +#if 1 + ibuf.size = cnt; + ibuf.ptr = ptr; + cnt = sizeof(ibuf); + ptr = &ibuf; +#endif + } + +#if 1 /* Nick, new getfsys() convention */ +getfsys_done: + buf->size = cnt; + buf->ptr = ptr; +#else + ((info_t *)buf)->size = cnt; + ((info_t *)buf)->ptr = ptr; +Ok: +#endif + return 0; + } +#undef tmpbuf +#if 0 /* Nick, new getfsys() convention */ +#undef kbuf +#endif +#undef ubuf + +#endif /* NEED__SCALL */ diff --git a/src/kernel/uzi/scall1.h b/src/kernel/uzi/scall1.h new file mode 100755 index 00000000..5ccd8420 --- /dev/null +++ b/src/kernel/uzi/scall1.h @@ -0,0 +1,46 @@ +/* scall1.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __SCALL1_H +#define __SCALL1_H + +int sys_NONE(void); +int sys_sync(void); +int sys_utime(void); +int sys_close(void); +void truncateto0(inoptr ino); +int sys_open(void); +int sys_link(void); +int sys_symlink(void); +int sys_unlink(void); +int sys_readwrite(void); +int sys_lseek(void); +int sys_chdir(void); +int sys_chroot(void); +int sys_mknod(void); +int sys_access(void); +int sys_chmod(void); +int sys_chown(void); +void stcpy(inoptr ino, struct stat *buf); +int sys_statfstat(void); +#if 1 /* Nick free bitmap */ +int sys_falign(void); +#endif +int sys_dup(void); +int sys_dup2(void); +int sys_getfsys(void); +int sys_ioctl(void); +int sys_mountumount(void); +int sys_time(void); +void exit0(void); +inoptr n_creat(char *name, bool_t new, mode_t mode); +void readwritei(char write, inoptr ino); +inoptr rwsetup(uchar fd, void *base, uint cnt, uchar rdflag); +int pdat(struct s_pdata *ubuf); +#if 1 /* Nick, new getfsys() convention */ +int getfsys(dev_t devno, info_t *buf); +#else +int getfsys(dev_t devno, void *buf); +#endif + +#endif /* __SCALL1_H */ + diff --git a/src/kernel/uzi/scall2.c b/src/kernel/uzi/scall2.c new file mode 100755 index 00000000..3635a151 --- /dev/null +++ b/src/kernel/uzi/scall2.c @@ -0,0 +1,639 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + Implementation of system calls +**********************************************************/ + +#define NEED__FILESYS +#define NEED__MACHDEP +#define NEED__PROCESS +#define NEED__SCALL + +#if 1 /* Nick */ +#include "vendor.h" /* Nick, must come first */ +#ifndef UTIL /* Nick */ +#include /* because reboot() must wait on SERIAL 1 tx */ +#endif +#include +#include +#include +#include "devio.h" /* prototypes added by Nick */ +#include "filesys.h" /* prototypes added by Nick */ +#include "scall2.h" /* prototypes added by Nick */ +#define __KERNEL__ /* temporary */ +void sttime(time_t *tvec); /* temporary */ +#else +#include "uzix.h" +#ifdef SEPH +#include "types.h" +#include "signal.h" +#include "errno.h" +#include "fcntl.h" +#include "sys\stat.h" +#endif +#include "unix.h" +#include "extern.h" +#endif + +/* Implementation of system calls */ + +#define IBLK(ino) ((ino)->c_node.i_size.o_blkno) +#define IOFF(ino) ((ino)->c_node.i_size.o_offset) + +/* definitions for 'udata' access */ +#define UWHERE (udata.u_offset) +#define UBLK (UWHERE.o_blkno)) +#define UOFF (UWHERE.o_offset)) +#define UBAS (udata.u_base) +#define UCNT (udata.u_count) +#define UERR (udata.u_error) + +#ifdef __KERNEL__ + +#if 1 /* Nick */ +int uint_min(int, int); +#else +int Min(int, int); +#endif + +/* return a pointer to p_tab of process pid only */ +/* user must own process pid or be the superuser */ +ptptr findprocess(int pid) +{ + register ptptr p = ptab; + while (p < ptab + PTABSIZE) { + if (p->p_pid == pid) { + if (udata.u_ptab->p_uid == p->p_uid || super()) { + return p; + } + else { + UERR = EPERM; + goto Err; + } + } + ++p; + } + UERR = EINVAL; +Err: return NULL; +} + +/******************************************** + SYSCALL pipe(int fildes[2]); +*******************************************/ +#define fildes ((uint *)udata.u_argn0) + +void filldesc(uchar oft, uchar access, inoptr ino) +{ + oft_t *op; + + op = &of_tab[oft]; + op->o_ptr = 0; + op->o_inode = ino; + op->o_access = access; +} + +int sys_pipe(void) +{ + uchar u1, u2, oft1 = (uchar)-1, oft2 = (uchar)-1; + inoptr ino; + + /* uf_alloc doesn't alloc an entry in user file table, + just returns the first free entry. so you must set it + before allocating another, or you'll get the same entry + */ + + if ((ino = i_open(root_dev, NULLINO)) == NULL) { + UERR = ENOMEM; + goto Err; + } + if ((u1 = uf_alloc()) == (uchar)-1 || + (oft1 = oft_alloc()) == (uchar)-1) { + UERR = ENOENT; + goto Err1; + } + udata.u_files[u1] = oft1; /* read side */ + filldesc(oft1, O_RDONLY, ino); + + if ((u2 = uf_alloc()) == (uchar)-1 || + (oft2 = oft_alloc()) == (uchar)-1) { + udata.u_files[u1] = -1; /* free user file table entry */ + UERR = ENOENT; + goto Err2; + } + /* fill in pipe descriptors */ + udata.u_files[u2] = oft2; /* write side */ + filldesc(oft2, O_WRONLY, ino); + + /* No permissions necessary on pipes */ + ino->c_node.i_mode = S_IFPIPE | 0777; + ino->c_node.i_nlink = 0; /* a pipe is not in any directory */ + ++ino->c_refs; /* count two sides of pipe */ + +#if 1 /* Nick */ + uputw(u1, &fildes[0]); + uputw(u2, &fildes[1]); +#else + fildes[0] = u1; + fildes[1] = u2; +#endif + + return 0; + +Err2: if (oft2 != (uchar)-1) oft_deref(oft2); +Err1: if (oft1 != (uchar)-1) oft_deref(oft1); +Err: return (-1); +} +#undef fildes + +/********************************** + SYSCALL stime(time_t *tvec) +**********************************/ +#define tvec (time_t *)udata.u_argn0 +int sys_stime(void) +{ +#if 1 /* Nick */ + time_t buf; + + if (super() == 0) + { + udata.u_error = EPERM; + return -1; + } + + buf.t_time = ugetw(&(tvec)->t_time); + buf.t_date = ugetw(&(tvec)->t_date); + sttime(&buf); + return 0; +#else + if (super()) { + sttime(tvec); + return 0; + } + UERR = EPERM; + return (-1); +#endif +} +#undef tvec + +/********************************* + SYSCALL times(struct tms *buf); +*********************************/ +#define buf ((struct tms *)udata.u_argn0) +int sys_times(void) +{ + if (valadr(buf, sizeof(struct tms))) { +#if 1 /* Nick */ + uput(&udata.u_utime, buf, 4 * sizeof(time_t)); + uput(&ticks, &buf->tms_etime, sizeof(time_t)); +#else + di_absolute(); + bcopy(&udata.u_utime, buf, 4 * sizeof(time_t)); + bcopy(&ticks, &buf->tms_etime, sizeof(time_t)); + ei_absolute(); +#endif + return (0); + } + return (-1); +} +#undef buf + +/********************************** + SYSCALL brk(char *addr); +**********************************/ +#define addr ((char *)udata.u_argn0) +int sys_brk(void) +{ +#if 1 /* Nick */ + if (addr < PROGBASE /*|| (addr + 256) >= (char *)udata.u_sp*/) { +#else + auto char dummy; /* A thing to take address of */ + + /* A hack to get approx val of stack ptr. */ + if ((uint)addr < PROGBASE || (addr + 256) >= &dummy) { +#endif + UERR = ENOMEM; + return (-1); + } + udata.u_ptab->p_break = addr; + udata.u_break = (unsigned)addr; /* Nick added cast */ + return 0; +} +#undef addr + +/************************************ + SYSCALL sbrk(uint incr); +************************************/ +#define incr udata.u_argn0 +int sys_sbrk(void) +{ +#if 1 /* Nick */ + register char *oldbrk = udata.u_ptab->p_break; +#else + register char *oldbrk = (char *)udata.u_break; /* Nick added cast */ +#endif + + if (incr) { + incr = incr + (uint)oldbrk; + if ((uint)incr < (uint)oldbrk || sys_brk()) + /* argument already on place */ + return (-1); + } + return (int)oldbrk; +} +#undef incr + +/************************************** + SYSCALL waitpid(int pid, int *statloc, int options); +**************************************/ +#define pid (int)udata.u_argn0 +#define statloc (int *)udata.u_argn1 +#define options (int)udata.u_argn0 +int sys_waitpid(void) +{ + register ptptr p; + +#if 1 /* Nick */ + if (!valadr((char *)statloc, sizeof(int))) { +#else + if (statloc > (int *)UZIXBASE) { +#endif + UERR = EFAULT; + goto Err; + } + di_absolute(); + /* See if we have any children. */ + p = ptab; + while (p < ptab + PTABSIZE) { + if ((uchar)(p->p_status) != P_EMPTY && + p->p_pptr == udata.u_ptab && + p != udata.u_ptab) { + ei_absolute(); + return dowait(); + } + ++p; + } + UERR = ECHILD; + ei_absolute(); +Err: return -1; +} +#undef pid +#undef statloc +#undef options + +/************************************** + SYSCALL exit(int val); +**************************************/ +#define val (int)udata.u_argn0 +int sys__exit(void) +{ + doexit(val, 0); + return -1; +} +#undef val + + + +#if 1 /* Nick */ +/* Subject of change in version 1.3h */ +doexit (val, val2) +int16 val; +int16 val2; +{ + register int16 j; + register ptptr p; + +#if DEBUG > 1 + kprintf ("process %d exiting\n", udata.u_ptab->p_pid); +#endif + + di(); + + for (j=0; j < UFTSIZE; ++j) + { + if (udata.u_files[j] >= 0) /* Portable equivalent of == -1 */ + doclose (j); + } + + sys_sync(); /* Not necessary, but a good idea. */ + + udata.u_ptab->p_exitval = (val<<8) | (val2 & 0xff); + + i_deref (udata.u_root); + i_deref (udata.u_cwd); + + /* Stash away child's execution tick counts in process table, + * overlaying some no longer necessary stuff. + */ + addtick (&udata.u_utime, &udata.u_cutime); + addtick (&udata.u_stime, &udata.u_cstime); + bcopy (&udata.u_utime, &(udata.u_ptab->p_wait), 2 * sizeof(time_t)); + + /* See if we have any children. Set child's parents to our parent */ + for (p=ptab; p < ptab+PTABSIZE; ++p) + { + if (p->p_status && p->p_pptr == udata.u_ptab && p != udata.u_ptab) + p->p_pptr = udata.u_ptab->p_pptr; + } + ei(); + + /* Wake up a waiting parent, if any. */ + wakeup ((char *)udata.u_ptab->p_pptr); + + udata.u_ptab->p_status = P_ZOMBIE; + + swapin (getproc()); + panic ("doexit:won't exit"); +} +#endif + + + +/************************************** + SYSCALL fork(void); +**************************************/ +int sys_fork(void) +{ + return dofork(); +} + +/************************************** + SYSCALL pause(void); +**************************************/ +int sys_pause(void) +{ + psleep(NULL); /* P_PAUSE */ + UERR = EINTR; + return (-1); +} + +#if 1 /* Nick */ +/**************************************** + SYSCALL signal(int sig, void (*func)()); +****************************************/ +#define sig (signal_t)udata.u_argn0 +#define func *((long *)&udata.u_argn1) +int sys_signal(void) +{ + long retval = -1; + + di_absolute(); + /* SIGKILL & SIGSTOP can't be caught !!!*/ + if (sig == __NOTASIGNAL || + sig == SIGKILL || + ((unsigned)sig) > NSIGS) { + UERR = EINVAL; + goto Err; + } + if (func == SIG_IGN) + udata.u_ptab->p_ignored |= sigmask(sig); + else { +#if 0 /* Nick removed this for IAR compiler... now back in again... OUT!! */ + if ((sig_t)func != SIG_DFL && ((char *)func) < PROGBASE) { + UERR = EFAULT; + goto Err; + } +#endif + udata.u_ptab->p_ignored = udata.u_ptab->p_ignored & ~(sigmask(sig)); + } + retval = (long)udata.u_sigvec[sig-1]; + udata.u_sigvec[sig-1] = (void (*)(signal_t))func; +Err: ei_absolute(); + udata.u_retval1 = ((int *)&retval)[1]; + return ((int *)&retval)[0]; +} +#undef sig +#undef func +#else +/**************************************** + SYSCALL signal(int sig, void (*func)()); +****************************************/ +#define sig (signal_t)udata.u_argn0 +#define func (void (*)(signal_t))udata.u_argn1 +int sys_signal(void) +{ + register int retval = -1; +#if 1 /* Nick... totally temporary... due to internal error in IAR compiler */ + int (*p)(); +#endif + + di_absolute(); + /* SIGKILL & SIGSTOP can't be caught !!!*/ + if (sig == __NOTASIGNAL || + (uchar)sig == SIGKILL || + (uchar)sig > NSIGS) { + UERR = EINVAL; + goto Err; + } +#if 1 /* Nick... totally temporary... due to internal error in IAR compiler */ + p = func; + if (p == SIG_IGN) +#else + if (func == SIG_IGN) +#endif + udata.u_ptab->p_ignored |= sigmask(sig); + else { +#if 0 /* Nick removed this for IAR compiler... now back in again... OUT!! */ + if ((sig_t)func != SIG_DFL && ((char *)func) < PROGBASE) { + UERR = EFAULT; + goto Err; + } +#endif + udata.u_ptab->p_ignored = udata.u_ptab->p_ignored & ~(sigmask(sig)); + } + retval = (int)udata.u_sigvec[sig-1]; + udata.u_sigvec[sig-1] = func; +Err: ei_absolute(); + return (retval); +} +#undef sig +#undef func +#endif + +/************************************** + SYSCALL kill(int pid, int sig); +**************************************/ +#define pid (int)udata.u_argn0 +#define sig (int)udata.u_argn1 +int sys_kill(void) +{ + register ptptr p; + + if (sig == __NOTASIGNAL || (uchar)sig >= NSIGS || pid <= 1) { + UERR = EINVAL; +Err: return -1; + } + if ((p = findprocess(pid)) == NULL) goto Err; + sendsig(p, sig); + return 0; +} +#undef pid +#undef sig + +/******************************** + SYSCALL alarm(uint secs); +********************************/ +#define secs (uint)udata.u_argn0 +int sys_alarm(void) +{ + register int retval; + + di_absolute(); + retval = udata.u_ptab->p_alarm; + udata.u_ptab->p_alarm = secs; + ei_absolute(); + return retval; +} +#undef secs + +/******************************** + SYSCALL reboot(char p1, char p2); +********************************/ +#define p1 (char)udata.u_argn0 +#define p2 (char)udata.u_argn1 +int sys_reboot(void) +{ +#if 1 /* Nick */ + if (super() == 0) + { + udata.u_error = EPERM; + return -1; + } +#endif + + if (p1 == 'm' && p2 == 'e') + { +#ifndef UTIL /* Nick */ + while (sdevs[1].swr1 & 1) + ; /* wait for tx on SERIAL 1 to finish */ +#endif + abort(0); /* Nick _abort */ + } + +#if 1 /* Nick */ + udata.u_error = EFAULT; + return -1; +#else + return EFAULT; +#endif +} +#undef p1 +#undef p2 + +/*********************************** + SYSCALL getset(int what, int parm1 ...); +***********************************/ +#define what (int)udata.u_argn0 +#define parm1 (int)udata.u_argn1 +#define parm2 (int)udata.u_argn2 +int sys_getset(void) +{ + register int old; + register ptptr p; + register char nice; + + switch (what) { + case GET_PID: + return (udata.u_ptab->p_pid); + case GET_PPID: + return (udata.u_ptab->p_pptr->p_pid); + case GET_UID: + return (udata.u_ptab->p_uid); + case SET_UID: + if (super() || udata.u_ptab->p_uid == parm1) { + udata.u_ptab->p_uid = parm1; + udata.u_euid = parm1; + goto Ok; + } + break; + case GET_EUID: + return (udata.u_euid); + case GET_GID: + return (udata.u_gid); + case SET_PRIO: + /* parm1 = PID, parm2 = nice value */ + if ((p = findprocess(parm1)) == NULL) goto Err; +#if 1 /* Nick */ + nice = int_min((char)parm2, PRIO_MAX); +#else + nice = Min((char)parm2, PRIO_MAX); +#endif + if (nice < PRIO_MIN) nice = PRIO_MIN; + if (!super()) if (nice < 0) nice = 0; + p->p_nice = nice; + p->p_cprio = (nice < 1) ? + (((-nice)*(TICKSPERSEC - MAXTICKS)) / (- PRIO_MIN)) + MAXTICKS + : + 1 + (((PRIO_MAX - nice) * MAXTICKS) / PRIO_MAX); + goto Ok; + case GET_EGID: + return (udata.u_egid); + case GET_PRIO: + return (udata.u_ptab->p_cprio); /* must be p_prio */ + case SET_GID: + if (super() || udata.u_gid == parm1) { + udata.u_gid = parm1; + udata.u_egid = parm1; + goto Ok; + } + break; + case SET_UMASK: + old = udata.u_mask; + udata.u_mask = parm1 & S_UMASK; + return old; + case SET_TRACE: +#if DEBUG > 1 + if (parm1 < 0) traceon = 1; + else if (parm1 > 0) udata.u_traceme = 1; + else if (udata.u_traceme) udata.u_traceme = 0; + else traceon = 0; +#endif + goto Ok; + } + UERR = EPERM; +Err: return (-1); +Ok: return 0; +} +#undef what +#undef parm1 +#undef parm2 +#undef nice + +#else +/*********************************** + SYSCALL getset(int what, int parm); +***********************************/ +#define what (int)udata.u_argn0 +#define parm (int)udata.u_argn1 +int sys_getset(void) +{ + int old; + + switch (what) { + case SET_UMASK: + old = udata.u_mask; + udata.u_mask = parm & S_UMASK; + return old; + } + UERR = EPERM; + return (-1); +} +#undef what +#undef parm + +#endif /* __KERNEL__ */ diff --git a/src/kernel/uzi/scall2.h b/src/kernel/uzi/scall2.h new file mode 100755 index 00000000..20f1d8fd --- /dev/null +++ b/src/kernel/uzi/scall2.h @@ -0,0 +1,25 @@ +/* scall2.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __SCALL2_H +#define __SCALL2_H + +ptptr findprocess(int pid); +void filldesc(uchar oft, uchar access, inoptr ino); +int sys_pipe(void); +int sys_stime(void); +int sys_times(void); +int sys_brk(void); +int sys_sbrk(void); +int sys_waitpid(void); +int sys__exit(void); +int sys_fork(void); +int sys_pause(void); +int sys_signal(void); +int sys_kill(void); +int sys_alarm(void); +int sys_reboot(void); +int sys_getset(void); +int sys_getset(void); + +#endif /* __SCALL2_H */ + diff --git a/src/kernel/uzi/scall3.c b/src/kernel/uzi/scall3.c new file mode 100755 index 00000000..8f3e45f0 --- /dev/null +++ b/src/kernel/uzi/scall3.c @@ -0,0 +1,1047 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + Implementation of system calls +**********************************************************/ + +#define NEED__DEVIO +#define NEED__FILESYS +#define NEED__MACHDEP +#define NEED__SCALL + +#if 1 /* Nick */ +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include "devio.h" /* prototypes added by Nick */ +#include "filesys.h" /* prototypes added by Nick */ +#include "xip.h" /* prototypes added by Nick */ +#include "scall3.h" /* prototypes added by Nick */ +#define __KERNEL__ /* temporary */ +#else +#include "uzix.h" +#ifdef SEPH +#include "types.h" +#include "signal.h" +#include "errno.h" +#include "sys\stat.h" +#endif +#include "unix.h" +#include "extern.h" +#endif + +/* Implementation of system calls */ + +#define ISIZE(ino) ((ino)->c_node.i_size) + +/* shortcuts for 'udata' access */ +#define UWHERE (udata.u_offset) +#define UBAS (udata.u_base) +#define UCNT (udata.u_count) +#define UERR (udata.u_error) + +#ifdef __KERNEL__ + +#if 1 /* Nick please look into this */ +/* User's execve() call. All other flavors are library routines. */ +/******************************************* +execve (name, argv, envp) Function 23 +char *name; +char *argv[]; +char *envp[]; +********************************************/ +#define name (char *)udata.u_argn0 +#define argv (char **)udata.u_argn1 +#define envp (char **)udata.u_argn2 + +int sys_execve(void) + { + int argc; + register inoptr ino; + char *buf; + blkno_t bmap(); + blkno_t blk; + char **nargv, **nenvp; /* In user space */ + struct s_argblk *abuf, *ebuf; + int (**sigp)(); + char *progptr; /* Original UZI */ +#if 1 /* Nick EXE format */ + uint entry, count, remain, offset; +#if 1 /* Nick banked EXE format */ +#if 1 + fsptr dev; + dev_t devno; + blkno_t i, pos, *region = NULL, regions, blocks; +#else + blkno_t i, pos, regions; +#endif +#endif +#endif + + ino = namei(name, NULLINOPTR, 1); + if (ino == NULL) + { + return -1; + } + + if ((getperm(ino) & S_IOEXEC) == 0 || +#if 0 /* Nick */ + (ino->c_node.i_mode & S_IFREG) == 0 || +#endif + (ino->c_node.i_mode & + (S_IEXEC | S_IOEXEC | S_IGEXEC)) == 0) + { + udata.u_error = EACCES; + goto nogood; + } + +#if 1 /* Nick */ + if (S_ISREGALIGN(ino->c_node.i_mode) == 0) + { + udata.u_error = ENOREGALIGN; /* file not regular or aligned */ + goto nogood; + } +#endif + +/* abyte('a'); */ + + setftim (ino, A_TIME); +/* abyte('b'); */ + + /* Read in the first block of the new program */ + buf = bread(ino->c_dev, bmap(ino, 0, 1), 0); +/* abyte('c'); */ + +#if 1 /* Nick EXE format */ + switch (((exefile_t *)buf)->e_magic) + { + case E_MAGIC: + break; + case 0x2123: /* '#!' */ + udata.u_error = ESHELL; + goto nogood2; + default: + udata.u_error = ENOEXEC; + goto nogood2; + } + +#if 1 /* Nick banked EXE format */ + entry = ((exefile_t *)buf)->e_format; + switch (entry) /* temporary multiple use of variable */ + { + case E_FORMAT_LARGE: + break; + case E_FORMAT_BANKED: +#if 1 + /* prepare to access the given inode */ + devno = ino->c_dev; + dev = getfs(devno); + + /* construct region list using shared subroutine */ + region = bitmap_examine(dev, ino, ino->c_node.i_size, + ®ions, &blocks); + if (region == NULL) + { + goto nogood2; /* error code has been setup */ + } +#else + if (ino->c_dev) + { + udata.u_error = ENOLCKFS; + goto nogood2; + } + if (getmode(ino) != S_IFALIGN) + { + udata.u_error = ENOALIGN; + goto nogood2; + } +#endif + break; + default: + udata.u_error = ENOEXEC; + goto nogood2; + } +#endif + + /* check the file's reported length against header */ + /* note: holes in the executable will cause a crash!! */ + if (((exefile_t *)buf)->e_size > ino->c_node.i_size) + { + udata.u_error = ETOOSHORT; /* file is too short, or hole */ + goto nogood2; + } + + /* can't skip more than one block for header */ + if (((exefile_t *)buf)->e_hsize >= BUFSIZE) + { + udata.u_error = ENOEXEC; /* executable format error */ + goto nogood2; + } +#else + /**************************************** + * Get magic number into var magic + * C3 : executable file no C/D sep. + * 00FF : " " with C/D sep. (not supported in UZI180) + * other : maybe shell script (nogood2) + ****************************************/ + if ((*buf & 0xff) != EMAGIC) + { + if (((uchar *)buf)[0] == '#' && ((uchar *)buf)[1] == '!') + { + udata.u_error = ESHELL; + } + else + { + udata.u_error = ENOEXEC; + } + goto nogood2; + } +#endif + +#if 0 /* Nick has temporarily removed CP/M support */ + /* Set Flag to indicate type of Executable (UZI-CP/M) */ + if ((*(buf+3)=='U') && (*(buf+4)=='Z') && (*(buf+5)=='I')) + uzicom = 1; + else + uzicom = 0; +#endif +/* abyte('d'); */ + + /* Gather the arguments, and put them in temporary buffers. */ + /* Put environment in another buffer. */ + abuf = (struct s_argblk *)tmpbuf(); + ebuf = (struct s_argblk *)tmpbuf(); +/* abyte('e'); */ + + if (wargs(argv, abuf) || wargs(envp, ebuf)) + { + goto nogood3; /* SN */ + } +/* abyte('f'); */ + + di(); /* not sure if this is really necessary */ + + /* Check setuid stuff here. No other changes needed in user data */ + if (ino->c_node.i_mode & S_ISUID) + { + udata.u_euid = ino->c_node.i_uid; + } + + if (ino->c_node.i_mode & S_ISGID) + { + udata.u_egid = ino->c_node.i_gid; + } + + /* Reset child of fork */ + udata.u_ptab->p_fork_inf = 0; +/* abyte('g'); */ + + /* We are definitely going to succeed with the exec, + * so we can start writing over the old program + */ + +#if 1 /* Nick EXE format */ + /* get break for program (not including argument data) */ + nargv = (char **)((exefile_t *)buf)->e_break; + + /* read back arguments, determine position of environment */ + nenvp = (char **)rargs((char *)nargv, abuf, &argc); + brelse((bufptr)abuf); + + /* read back environment, determine initial break address */ + udata.u_ptab->p_break = (char **)rargs((char *)nenvp, ebuf, NULL); + udata.u_break = (uint)udata.u_ptab->p_break; /* phase this out */ + + /* zero out the program's udata and stack segments */ + progptr = (char *)((exefile_t *)buf)->e_udata; + remain = (uint)nargv - ((exefile_t *)buf)->e_udata; + +#if 1 /* Nick banked EXE format */ + bzero(ebuf, BUFSIZE); /* optimised for size, not speed */ + uput(ebuf, 0x8000, 0x100); /* zero out virtual memory table */ +#else + count = int_min(remain, BUFSIZE); + bzero(ebuf, count); /* optimised for speed, not size */ +#endif + + while (remain) + { + count = int_min(remain, BUFSIZE); + uput(ebuf, progptr, count); + + progptr += count; + remain -= count; + } + + brelse((bufptr)ebuf); + + /* push the arguments to main(), just below the argument data */ + uputw(argc, nargv - 3); + uputw(nargv, nargv - 2); + uputw(nenvp, nargv - 1); + + /* set initial stack for program, just below parameters pushed */ + udata.u_isp = (char *)(nargv - 3); + +#if 1 /* Nick banked EXE format */ + /* if executable is banked, map it into virtual memory space */ + if (entry == E_FORMAT_BANKED) /* entry = e_format field from header */ + { + /* find initial location of program, in virtual memory */ + progptr = (char *)0x8000; /* hard coded for now */ + +#if 1 + for (i = 0; i < regions; i++) + { + /* convert to page number, put in virt memory table */ + uputc(0x40 + (region[i] >> (PAGE_LOG-BUFSIZELOG)) - 4, + progptr++); + } + + if (brelse((bufptr)region) < 0) + { + /* udata.u_error = something; */ + } + /* region = NULL; */ /* don't bother, we can't fail now */ +#else + /* find count of regions, using the file's reported size */ + regions = (ino->c_node.i_size + + REGION_BYTES - 1) >> REGION_LOG; + + /* find each region's existing physical memory address */ + pos = 0; + for (i = 0; i < regions; i++) + { + /* first block must be aligned, find its position */ + blk = bmap(ino, pos, 1); + + /* convert to page number, put in virt memory table */ + uputc(0x40 + (blk >> (PAGE_LOG-BUFSIZELOG)) - 4, + progptr++); + + pos += REGION_BLOCKS; + } +#endif + } +#endif + + /* find out program's entry address, while buf is still valid */ + entry = ((exefile_t *)buf)->e_entry; +#else + /* Move 1st Block to user bank */ + uput(buf, PROGBASE, BUFSIZE); + brelse((bufptr)buf); +/* abyte('h'); */ +#endif + +#if 0 /* Nick redundant */ + /* At this point, we are committed to reading in and + * executing the program. We switch to a local stack, + * and pass to it the necessary parameter: ino + */ + + udata.u_ino = ino; /* Temporarily stash these here */ + +/* I think this must be a mistake... not necessary and can't use automatic */ +/* variables after this point, because SP needs a known relationship to IX */ +/* tempstack(); */ +/* abyte('i'); */ +#endif + +#if 1 /* Nick EXE format */ + /* Read in the rest of the program */ + /* we have already checked that offset is < BUFSIZE */ + progptr = (char *)((exefile_t *)buf)->e_idata; + offset = ((exefile_t *)buf)->e_hsize; + remain = ((exefile_t *)buf)->e_udata - (uint)progptr; + + if (remain) /* first block is treated specially */ + { + count = int_min(remain, BUFSIZE - offset); + uput(buf + offset, progptr, count); + + progptr += count; + remain -= count; + } + brelse((bufptr)buf); + + blk = 1; + while (remain) + { + buf = bread(ino->c_dev, bmap(ino, blk++, 1), 0); + + count = int_min(remain, BUFSIZE); + uput(buf, progptr, count); + + progptr += count; + remain -= count; + + brelse((bufptr)buf); + } +#else + /* Read in the rest of the program */ + progptr = PROGBASE + BUFSIZE; + for (blk = 1; blk <= (ino->c_node.i_size >> BUFSIZELOG); ++blk) + { + buf = bread(ino->c_dev, bmap(ino, blk, 1), 0); + uput(buf, progptr, BUFSIZE); + brelse((bufptr)buf); + progptr += BUFSIZE; + } +#endif +/* abyte('j'); */ + i_deref(ino); + +#if 0 /* Nick EXE format */ + /* Set Break for program */ + udata.u_ptab->p_break = (void *)progptr; + udata.u_break = (int)progptr; /* this needs to be phased out */ +/* abyte('k'); */ +#endif + + /* Turn off caught signals */ + for (sigp = udata.u_sigvec; sigp < (udata.u_sigvec + NSIGS); sigp++) + { + if (((long)*sigp) != SIG_IGN) + { + *sigp = (void (*)(signal_t))SIG_DFL; + } + } + +#if 0 /* Nick EXE format */ + /* Read back the arguments and the environment */ + nargv = (char **)rargs(PROGTOP-2, abuf, &argc); + nenvp = (char **)rargs((char *)nargv, ebuf, NULL); +#endif + + /* Fill in udata.u_name with Program invocation name */ + uget(ugetw(nargv), udata.u_name, 8); +/* abyte('l'); */ + +#if 0 /* Nick EXE format */ + brelse((bufptr)abuf); + brelse((bufptr)ebuf); +#endif + +#if 0 /* Nick */ + /* Shove argc and the address of argv just below envp */ + uputw(argc, nenvp - 3); + uputw(nargv, nenvp - 2); + uputw(nenvp, nenvp - 1); +#endif + + /* Jump into the program, first setting the stack + * and copying the udata block + */ + + ei(); /* not sure if this is really necessary */ +/* abyte('m'); */ +#if 0 /* Nick EXE format */ + udata.u_isp = (char *)(nenvp - 3); + doexec((int16 *)udata.u_isp); +#else + doexec((int *)udata.u_isp, entry); +#endif + +nogood3: + brelse((bufptr)abuf); + brelse((bufptr)ebuf); +nogood2: +#if 1 + if (region) + { + brelse((bufptr)region); + } +#endif + brelse((bufptr)buf); +nogood: + i_deref(ino); + return -1; + } + +#undef name +#undef argv +#undef envp + +/* SN TODO max (1024) 512 bytes for argv + and max 512 bytes for environ +*/ + + +int wargs(char **argv, struct s_argblk *argbuf) /* argv in user space */ +{ + register char *ptr; /* Address of base of arg strings in user space */ + int c; + register char *bufp; + /* Nick unsigned ugetw(); due to IAR stricter checking */ + char ugetc(); +/* kprintf("wargs 0x%x\n", argv); */ + + argbuf->a_argc = 0; /* Store argc in argbuf */ + bufp = argbuf->a_buf; + + while (ptr = (char *)ugetw (argv++)) + { +/* kprintf("0x%x\n", ptr); */ + ++(argbuf->a_argc); /* Store argc in argbuf. */ + do + { + *bufp++ = c = ugetc (ptr++); + if (bufp > argbuf->a_buf+500) + { + udata.u_error = E2BIG; + return (1); + } + } + while (c); + } + argbuf->a_arglen = bufp - argbuf->a_buf; /*Store total string size. */ + return (0); +} + + + +char *rargs(char *ptr, struct s_argblk *argbuf, int *cnt) +{ + int argc; + char **argv; /* Address of users argv[], just below ptr */ +#if 0 /* Nick EXE format */ + int arglen; + char *argbase; +#endif + char *sptr; + + sptr = argbuf->a_buf; + +#if 1 /* Nick EXE format */ + /* Move them into the users address space, from the bottom */ + argc = argbuf->a_argc; + argv = (char **)ptr; + ptr += (argc + 1) * sizeof(char *); + +/* abyte('a'); */ +/* ahexw((int)sptr); */ +/* abyte(' '); */ +/* ahexw((int)ptr); */ +/* abyte(' '); */ +/* ahexw((int)argbuf->a_arglen); */ + if (argbuf->a_arglen) + uput (sptr, ptr, argbuf->a_arglen); +/* abyte('b'); */ +#else + /* Move them into the users address space, at the very top */ + ptr -= (arglen = argbuf->a_arglen); + +/* abyte('a'); */ +/* ahexw((int)sptr); */ +/* abyte(' '); */ +/* ahexw((int)ptr); */ +/* abyte(' '); */ +/* ahexw((int)arglen); */ + if (arglen) + uput (sptr, ptr, arglen); +/* abyte('b'); */ + + /* Set argv to point below the argument strings */ + argc = argbuf->a_argc; + argbase = argv = (char **)ptr - (argc + 1); +#endif + + if (cnt) +/* { */ +/* kprintf("(argc = %d)\n", argc); */ + *cnt = argc; +/* } */ + + /* Set each element of argv[] to point to its argument string */ + while (argc--) + { +/* abyte('c'); */ +/* ahexw((int)ptr); */ +/* abyte(' '); */ +/* ahexw((int)argv); */ + uputw (ptr, argv++); +/* abyte('d'); */ +#if 1 /* Nick EXE format */ + do + ++ptr; + while (*sptr++); +#else + if (argc) + { + } +#endif + } +/* abyte('e'); */ +/* ahexw(0); */ +/* abyte(' '); */ +/* ahexw((int)argv); */ + /* add Null Pointer to end of array */ + uputw ((char *)0, argv); +/* abyte('f'); */ +#if 1 /* Nick EXE format */ + return ptr; +#else + return argbase; +#endif +} +#else +int repack(char **argp, char **envp, uchar check)); +void *scop(char **argv, uchar cnt, char *to, char *real); +uint ssiz(char **argv, uchar *cnt, char **smin); +void exec2(void); + +static uint __argc; +static char **__argv; +static char **__envp; + +/* check for arguments size */ +uint ssiz(char **argv, uchar *cnt, char **smin) +{ + char *p, *mi = *smin; + uint n = 0; + + *cnt = 1; + while ((p = *argv++) != NULL) { + if (p < mi) mi = p; + while (++n, *p++ != '\0') + ; + ++(*cnt); + } + *smin = mi; + return n; +} + +/* copy arguments vector */ +void *scop(char **argv, uchar cnt, char *to, char *real) +{ + char *s, **a = (char **)to, *q = to + sizeof(char *) * cnt; + + while ((s = *argv++) != NULL) { + *a++ = real; + while (++real, (*q++ = *s++) != '\0') + ; + } + *a = NULL; + return q; +} + +/* move all arguments to top of program memory or check their size */ +/* for move, stack can't be near the top of program memory and */ +/* PROGBASE area is used as draft area */ +int repack(char **argp, char **envp, uchar check) +{ + uint tot, et, asiz, esiz; + uchar acnt, ecnt; + register char *p = (void *)PROGBASE; + char *amin = (void *)UZIXBASE; + + asiz = ssiz(argp, &acnt, &amin); + esiz = ssiz(envp, &ecnt, &amin); + + tot = (asiz + sizeof(char *) * acnt) + + (et = esiz + sizeof(char *) * ecnt); + if ((uint)p + tot > (uint)amin) { /* p == PROGBASE! */ + UERR = ENOMEM; +Err: return 1; /* no room for args */ + } + if (check) { + if ((uint)UBAS > (uint)(UZIXBASE - 1 - tot)) { + UERR = E2BIG; + goto Err; /* no room for args */ + } + goto Ok; + } + p = scop(argp, acnt, p, (char *)(UZIXBASE - 1 - et - asiz)); + scop(envp, ecnt, p, (char *)(UZIXBASE - 1 - esiz)); + __envp = (char **)(UZIXBASE - 1 - et); + __argv = (char **)(UZIXBASE - 1 - tot); + __argc = acnt-1; + bcopy((void *)PROGBASE, __argv, tot); +Ok: return 0; +} + +/* exec2() second step of execve - executed on system stack! */ +void exec2(void) +{ + register char **p, *progptr; + register blkno_t pblk; + uchar blk = 0; + char *buf; + + /* Read in the rest of the program */ + progptr = (char *)PROGBASE; + while (blk <= UCNT) { + if ((pblk = bmap(udata.u_ino, blk, 1)) != NULLBLK) { + buf = bread(udata.u_ino->c_dev, pblk, 0); + if (buf != NULL) { + bcopy(buf, progptr, BUFSIZE); + brelse((bufptr)buf); + } + } + progptr += BUFSIZE; + ++blk; + } + i_deref(udata.u_ino); + /* Zero out the free memory */ + bzero(progptr, (uint) ((char *)__argv - progptr)); + udata.u_ptab->p_break = (void *)(((exeptr)PROGBASE)->e_bss); + udata.u_break = (void *)(((exeptr)PROGBASE)->e_bss); +#if DEBUG > 1 + udata.u_traceme = (DEBUG > 10); /* Nick 0; */ +#endif + /* Fill in udata.u_name */ + bcopy(*__argv, udata.u_name, DIRNAMELEN); + /* Shove argc and the address of argv just below argv */ + p = __argv; + *--__argv = (char *) __envp; + *--__argv = (char *) p; + *--__argv = (char *) __argc; +#ifdef UZIX_MODULE + RESET_MODULE(); +#endif + /* Machine dependant jump into the program, first setting the stack */ + doexec((uint)__argv); /* NORETURN */ +} + +/********************************************************* + SYSCALL execve(char *name, char *argv[], char *envp[]); +*********************************************************/ +#define name (char *)udata.u_argn0 +#define argv (char **)udata.u_argn1 +#define envp (char **)udata.u_argn2 +int sys_execve(void) +{ + register inoptr ino; + register uchar *buf; + register sig_t *sp; + uchar magic; + uint mblk; + + if ((ino = namei(name, NULL, 1)) == 0) { + UERR = ENOENT; + goto Err1; + } + mblk = (uint)ISIZE(ino); /* image length in bytes */ + if (PROGBASE + ISIZE(ino) >= UZIXBASE) { /* long operation! */ + UERR = ENOMEM; + goto Ret; + } + if ((getperm(ino) & S_IOEXEC) == 0 || + getmode(ino) != S_IFREG || + (ino->c_node.i_mode & (S_IEXEC | S_IGEXEC | S_IOEXEC)) == 0) { + UERR = EACCES; + goto Ret; + } + /* save information about program size in blocks/top */ + UCNT = (mblk + BUFSIZE - 1) >> BUFSIZELOG; + UBAS = (void *)(PROGBASE + mblk + 1024); /* min +1K stack */ + /* Read in the first block of the new program */ + buf = bread(ino->c_dev, bmap(ino, 0, 1), 0); + if (buf == NULL) goto Ret; + magic = ((exeptr)buf)->e_magic; + if (brelse((bufptr)buf) != 0) goto Ret; + if (magic != EMAGIC) { + if (((uchar *)buf)[0] == '#' && ((uchar *)buf)[1] == '!') + UERR = ESHELL; + else UERR = ENOEXEC; + goto Ret; + } + setftim(ino, A_TIME); /* set access time */ + /* Turn off caught signals */ + sp = udata.u_sigvec; + while (sp < (udata.u_sigvec + NSIGS)) { + if ((sig_t)(*sp) != SIG_IGN) + *(sig_t *)sp = SIG_DFL; + ++sp; + } + /* Here, check the setuid stuff. No other changes need be + * made in the user data + */ + if (ino->c_node.i_mode & S_ISUID) udata.u_euid = ino->c_node.i_uid; + if (ino->c_node.i_mode & S_ISGID) udata.u_egid = ino->c_node.i_gid; + /* + * at this point, we are committed to reading in and executing + * the program. We switch to a local stack, and pass to it the + * necessary parameter: ino + */ + udata.u_ino = ino; /* Temporarly stash these here */ + if (repack(argv, envp, 1)) /* Check args size */ + goto Ret; + tempstack(); + repack(argv, envp, 0); /* Move arguments */ + exec2(); + +Ret: i_deref(ino); +Err1: return (-1); +} +#undef name +#undef argv +#undef envp +#endif + +#if 0 /* def UZIX_MODULE */ + +#define proc_page0 udata.u_ptab->p_swap[0] +#define proc_page1 udata.u_ptab->p_swap[1] +static void *stkbkp = NULL; + +modtabptr searchmodule (int sig) { + modtabptr mtable=&modtab; + + while (mtable != modtab + MTABSIZE) { + if (mtable->sig==sig) + return mtable; + ++mtable; + } + UERR=ESRCH; + return NULL; +} + +/* call module handler */ +int callmodu2(uint sign, uint fcn, char *args, int argsize, int pid) { +#ifdef PC_UZIX_TARGET + uchar TEMPDBUF[512]; /* possible problem: stack too deep */ +#else +/* MSX already defines TEMPDBUF as a 512bytes buffer */ +#endif + static modtabptr mtable; + static uint _fcn; + static uint _argsiz; + static int _ppid; + static ptptr _p; + + if (sign == NULL) goto Err; + if ((mtable = searchmodule(sign)) == NULL) goto Err; + _di(); + _p = udata.u_ptab; + _ppid = pid == 0 ? _p->p_pid : pid; + _fcn=fcn; + _argsiz=argsize; + if (argsize > 0) bcopy(args, (uchar *)TEMPDBUF, argsize); + NOTUSED(fcn); /* this is a trick for HTC. if you remove this, + if the above IF is false, HTC will jump the + _asm below */ +#define __SAVESTACK callmodu2_SAVESTACK +#ifdef MSX_UZIX_TARGET +#include "process.msx" +#endif +#ifdef PC_UZIX_TARGET +#include "process.mtc" +#endif + tempstack(); + swap_read(mtable->page); /* swap_read can't do ei()! */ + _fcn=mtable->fcn_hnd(_fcn, _ppid, (uchar *)TEMPDBUF, _argsiz); + _di(); + swap_read(_p->p_swap); +#define __RESTSTACK callmodu2_RESTSTACK +#ifdef MSX_UZIX_TARGET +#include "process.msx" +#endif +#ifdef PC_UZIX_TARGET +#include "process.mtc" +#endif + _ei(); + if (_fcn!=0) { + UERR=_fcn; +Err: return -1; + } + return 0; +} + +/* clear waiting replies from module to the exited process */ +void clear_module_reqs(int pid) { + modreplyptr mreply; + modtabptr mtable=&modtab; + + for (mreply=modreply; mreply < modreply + RTABSIZE; ++mreply) { + if (mreply->pid==pid) mreply->sig = 0; + } + /* tell modules that the queries/replies for this + * process can be erased + */ + while (mtable != modtab + MTABSIZE) { + callmodu2(mtable->sig, 0, NULL, -1, pid); + if (mtable->page[0]==proc_page0 && mtable->page[1]==proc_page1) { + mtable->sig=0; + RESET_MODULE(); + } + ++mtable; + } +} + +/********************************************************* + SYSCALL reg(uint sig, int (*func)()); +*********************************************************/ +#define sign (uint)udata.u_argn0 +#define func (void (*))udata.u_argn1 +int sys_reg(void) +{ + modtabptr mtable=&modtab; + + while (mtable != modtab + MTABSIZE) { + if (mtable->sig==0) goto fnd; + ++mtable; + } + UERR=ENOMEM; + return -1; +fnd: mtable->sig = sign; + mtable->fcn_hnd = func; + mtable->page[0] = proc_page0; + mtable->page[1] = proc_page1; + SET_MODULE(); + return 0; +} +#undef func +#undef sign + +/********************************************************* + SYSCALL dereg(uint sig); +*********************************************************/ +#define sign (uint)udata.u_argn0 +int sys_dereg(void) +{ + modtabptr mtable; + + if ((mtable = searchmodule(sign)) == NULL) goto Err; + if (!super() && + (mtable->page[0]!=proc_page0 || mtable->page[1]!=proc_page1)) { + UERR=EPERM; +Err: return -1; + } + /* we should search for a waiting reply on reply table and return + EBUSY if the table is not clear... */ + mtable->sig=0; + RESET_MODULE(); + return 0; +} +#undef func +#undef sign + +/********************************************************* + SYSCALL callmodu(uint sig, uint fcn, char *args, int argsize); +*********************************************************/ +#define sign (uint)udata.u_argn0 +#define fcn (uint)udata.u_argn1 +#define args (char *)udata.u_argn2 +#define argsize (int)udata.u_argn3 +int sys_callmodu(void) +{ + if (argsize < 0 || argsize > BUFSIZE) { + UERR=EINVAL; + return -1; + } + return callmodu2(sign, fcn, args, argsize, 0); +} +#undef sign +#undef fcn +#undef args +#undef argsize + +/********************************************************* + SYSCALL modreply(int sig, int fcn, char *repladdr); +*********************************************************/ +#define sign (uint)udata.u_argn0 +#define fctn (uint)udata.u_argn1 +#define repladdr (uint)udata.u_argn2 +/* send module reply to the process that requested module function */ +int sys_modreply(void) +{ + modtabptr mtable; + modreplyptr mreply; + struct swap_mmread pp; + int p_id; + + if ((mtable = searchmodule(sign)) == NULL) { + goto Err; + } + p_id = (udata.u_ptab)->p_pid; + pp.mm[0]=mtable->page[0]; + pp.mm[1]=mtable->page[1]; + for (mreply=modreply; mreply < modreply + RTABSIZE; ++mreply) { + if (mreply->sig==sign && mreply->pid==p_id && mreply->fcn==fctn) { + pp.buf = (void *)repladdr; + pp.size = mreply->replysize; + pp.offset = (uint)(mreply->replyaddr); + if (swap_mmread(&pp) < 0) { +reperr: UERR=EIO; + goto Err1; + } + if (callmodu2(sign, fctn, NULL, -1, 0) < 0) goto reperr; /* clear module reply table */ + mreply->sig=0; + return 0; + } + } + /* since this syscall is called essentialy by a library, the common + structure is "while (modreply()<0)". so, the module must be executed + to answer the call. so, let's not waste CPU calling this syscall + over and over again and returning -1 until process timeslice expires. + let's give other processes their bit of CPU */ + /* no reply found for this query */ + UERR=ENXIO; +Err1: runticks = udata.u_ptab->p_cprio; +Err: return -1; +} +#undef sign +#undef fctn +#undef repladdr + +/********************************************************* + SYSCALL repfmodu(int pid, int fcn, char *repladdr, int replysize); +*********************************************************/ +#define p_id (uint)udata.u_argn0 +#define fcnt (uint)udata.u_argn1 +#define repladdr (char *)udata.u_argn2 +#define reply_size (uint)udata.u_argn3 +/* put module reply in the reply table to the waiting process */ +int sys_repfmodu(void) +{ + modtabptr mtable=&modtab; + modreplyptr mreply; + + while (mtable != modtab + MTABSIZE) { + if (mtable->page[0]==proc_page0 && mtable->page[1]==proc_page1) + goto fnd; + ++mtable; + } + UERR=ESRCH; + goto Err; +fnd: + for (mreply=modreply; mreply < modreply + RTABSIZE; ++mreply) { + if (mreply->sig==0) { + mreply->sig=mtable->sig; + mreply->fcn=fcnt; + mreply->pid=p_id; + mreply->replyaddr=repladdr; + mreply->replysize=reply_size; + return 0; + } + } + UERR=ENXIO; +Err: return -1; +} +#undef p_id +#undef fcnt +#undef repladdr +#undef reply_size + +#endif /* UZIX_MODULE */ + +#endif /* __KERNEL__ */ diff --git a/src/kernel/uzi/scall3.h b/src/kernel/uzi/scall3.h new file mode 100755 index 00000000..2b3122db --- /dev/null +++ b/src/kernel/uzi/scall3.h @@ -0,0 +1,26 @@ +/* scall3.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __SCALL3_H +#define __SCALL3_H + +#if 1 /* Nick please look into this */ +int sys_execve(void); +int wargs(char **argv, struct s_argblk *argbuf); +char *rargs(char *ptr, struct s_argblk *argbuf, int *cnt); +#else +uint ssiz(char **argv, uchar *cnt, char **smin); +void *scop(char **argv, uchar cnt, char *to, char *real); +int repack(char **argp, char **envp, uchar check); +void exec2(void); +int sys_execve(void); +#endif +#if 0 /* def UZIX_MODULE */ +int sys_reg(void); +int sys_dereg(void); +int sys_callmodu(void); +int sys_modreply(void); +int sys_repfmodu(void); +#endif + +#endif /* __SCALL3_H */ + diff --git a/src/kernel/uzi/startasm.asm b/src/kernel/uzi/startasm.asm new file mode 100755 index 00000000..d566a15f --- /dev/null +++ b/src/kernel/uzi/startasm.asm @@ -0,0 +1,71 @@ +; startasm.asm +; currently not in use for the Hytech kernel + +; /*************************************************************** +; UZI (Unix Z80 Implementation) Kernel: startasm.asz +; ---------------------------------------------------------------- +; Copyright (C) 1998 by Harold F. Bower +; ****************************************************************/ +; Revisions: + + rseg RCODE + public _init0 + extern _initsys + +$ asmdef.inc +$ z180.inc + +_init0: DI ; No Interrupts while we mess around here + XOR A ; Disable Interrupts and PRT downcounting + OUT0 (TCR),A ; until Int Vector Table initialized + + .if HISPEED + LD A,80H ; Set Hi-Speed flag, Normal Drive + OUT0 (CCR),A ; speed up if ZS8180 or Z80182 + .endif + .if HISPEED .eq. FALSE + XOR A ; Set Lo-Speed flag, Normal Drive + OUT0 (CCR),A + .endif + NOP ; let things settle + NOP + + LD A,0F0H ; Set New Common Base + OUT0 (CBAR),A ; for the high module + + LD SP,0 ; Set Initial Stack to Top. + + ; To reduce storage requirements of the executable image (and + ; avoid problems with the Hi-Tech linker) we link in the order: + ; text -> data -> common -> bss; with Bss at an absolute addr + ; of 8000H. This needs to be raised in the linkage script if + ; the combined image size exceeds 7F00H bytes. + + LD HL,0F000H ; Zero the top 4k of memory + LD E,L + LD D,H + INC DE + LD BC,0FFFH + LD (HL),0 + LDIR + +;;-- LD A,00001000B ; Set Interrupts (00H for Polled Mode) +;;-- OUT0 (STAT0),A ; for ASCI0 + LD A,00001100B ; Enable Interrupts & CTS1* (04H for No Ints) + OUT0 (STAT1),A ; for ASCI1 + + IN0 A,(DCNTL) ; Get current Wait State settings + AND 0FH ; (don't change DMA bits) + OR MWAIT .SHL. 6 + IOWAIT .SHL. 4 + OUT0 (DCNTL),A ; and send it + + LD HL,RELOAD ; Get the timer reload constant + OUT0 (RLDR0L),L ; send low byte + OUT0 (RLDR0H),H ; and hi byte + + LD A,00H ; Disable DRAM Refresh (83H to activate) + OUT0 (RCR),A ; Set Refresh timing specs + + jp _initsys + + end diff --git a/src/kernel/uzi/systrace.c b/src/kernel/uzi/systrace.c new file mode 100755 index 00000000..ffae234e --- /dev/null +++ b/src/kernel/uzi/systrace.c @@ -0,0 +1,362 @@ +/* systrace.c by Nick for UZI180 */ + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include "kprintf.h" + +void kputchar(char c); +#if 0 /* Nick, see kprintf.c */ +void kprintf(char *fmt, ...); +#endif +char ugetc(char *ptr); + +void systrace_entry(void); +void systrace_exit(void); +void systrace_dump(unsigned int value, unsigned int count, unsigned char type); + +#define TYPE_BIN 1 +#define TYPE_STR 2 +#define TYPE_OCT 3 +#define TYPE_DEC 4 +#define TYPE_HEX 5 + +struct systrace_entry + { + char return_type; + char *function_name; + char argument_type[4]; + }; + +struct systrace_entry systrace_table[] = + { +#if 1 /* Nick UZIX compatibility */ + { TYPE_DEC, "access", { TYPE_STR, TYPE_OCT, 0, 0 } }, + { TYPE_DEC, "alarm", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_HEX, "brk", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_DEC, "chdir", { TYPE_STR, 0, 0, 0 } }, + { TYPE_DEC, "chmod", { TYPE_STR, TYPE_OCT, 0, 0 } }, + { TYPE_DEC, "chown", { TYPE_STR, TYPE_DEC, TYPE_DEC, 0 } }, + { TYPE_DEC, "close", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_DEC, "getset", { TYPE_HEX, TYPE_HEX, TYPE_HEX, 0 } }, /* { TYPE_DEC, "creat", { TYPE_STR, TYPE_HEX, 0, 0 } }, */ + { TYPE_DEC, "dup", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_DEC, "dup2", { TYPE_DEC, TYPE_DEC, 0, 0 } }, + { TYPE_DEC, "execve", { TYPE_STR, TYPE_HEX, TYPE_HEX, 0 } }, + { TYPE_DEC, "_exit", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_DEC, "fork", { 0, 0, 0, 0 } }, + { TYPE_DEC, "fstat", { TYPE_DEC, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "getfsys", { TYPE_HEX, TYPE_HEX, 0, 0 } }, + { TYPE_HEX, "ioctl", { TYPE_DEC, TYPE_HEX, TYPE_HEX, 0 } }, + { TYPE_DEC, "kill", { TYPE_DEC, TYPE_DEC, 0, 0 } }, + { TYPE_DEC, "link", { TYPE_STR, TYPE_STR, 0, 0 } }, + { TYPE_DEC, "mknod", { TYPE_STR, TYPE_OCT, 0, 0 } }, + { TYPE_DEC, "mount", { TYPE_STR, TYPE_STR, 0, 0 } }, + { TYPE_DEC, "open", { TYPE_STR, TYPE_HEX, TYPE_OCT, 0 } }, + { TYPE_DEC, "pause", { 0, 0, 0, 0 } }, + { TYPE_DEC, "pipe", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_HEX, "read", { TYPE_DEC, TYPE_HEX, TYPE_HEX, 0 } }, + { TYPE_HEX, "sbrk", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_HEX, "lseek", { TYPE_DEC, TYPE_HEX, TYPE_HEX, TYPE_DEC } }, + { TYPE_DEC, "signal", { TYPE_DEC, TYPE_HEX, TYPE_HEX, 0 } }, + { TYPE_DEC, "stat", { TYPE_STR, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "stime", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_DEC, "sync", { 0, 0, 0, 0 } }, + { TYPE_DEC, "time", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_DEC, "times", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_DEC, "umount", { TYPE_STR, 0, 0, 0 } }, + { TYPE_DEC, "unlink", { TYPE_STR, 0, 0, 0 } }, + { TYPE_DEC, "utime", { TYPE_STR, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "waitpid", { TYPE_DEC, TYPE_HEX, TYPE_HEX, 0 } }, + { TYPE_HEX, "write", { TYPE_DEC, TYPE_BIN, TYPE_HEX, 0 } }, + { TYPE_DEC, "reboot", { TYPE_HEX, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "symlink", { TYPE_STR, TYPE_STR, 0, 0 } }, + { TYPE_DEC, "chroot", { TYPE_STR, 0, 0, 0 } }, + { TYPE_DEC, "falign", { TYPE_DEC, TYPE_DEC, 0, 0 } } +#else + { TYPE_DEC, "_exit", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_DEC, "open", { TYPE_STR, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "close", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_DEC, "creat", { TYPE_STR, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "mknod", { TYPE_STR, TYPE_OCT, 0, 0 } }, + { TYPE_DEC, "link", { TYPE_STR, TYPE_STR, 0, 0 } }, + { TYPE_DEC, "unlink", { TYPE_STR, 0, 0, 0 } }, + { TYPE_HEX, "read", { TYPE_DEC, TYPE_HEX, TYPE_HEX, 0 } }, + { TYPE_HEX, "write", { TYPE_DEC, TYPE_BIN, TYPE_HEX, 0 } }, + { TYPE_HEX, "seek", { TYPE_DEC, TYPE_HEX, TYPE_DEC, 0 } }, + { TYPE_DEC, "chdir", { TYPE_STR, 0, 0, 0 } }, + { TYPE_DEC, "sync", { 0, 0, 0, 0 } }, + { TYPE_DEC, "access", { TYPE_STR, 0, 0, 0 } }, + { TYPE_DEC, "chmod", { TYPE_STR, TYPE_OCT, 0, 0 } }, + { TYPE_DEC, "chown", { TYPE_STR, TYPE_DEC, TYPE_DEC, 0 } }, + { TYPE_DEC, "stat", { TYPE_STR, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "fstat", { TYPE_DEC, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "dup", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_DEC, "getpid", { 0, 0, 0, 0 } }, + { TYPE_DEC, "getppid", { 0, 0, 0, 0 } }, + { TYPE_DEC, "getuid", { 0, 0, 0, 0 } }, + { TYPE_DEC, "umask", { TYPE_OCT, 0, 0, 0 } }, + { TYPE_DEC, "getfsys", { TYPE_HEX, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "execve", { TYPE_STR, TYPE_HEX, TYPE_HEX, 0 } }, + { TYPE_DEC, "wait", { 0, 0, 0, 0 } }, + { TYPE_DEC, "setuid", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_DEC, "setgid", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_DEC, "time", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_DEC, "stime", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_HEX, "ioctl", { TYPE_DEC, TYPE_HEX, 0, 0 } }, + { TYPE_HEX, "brk", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_HEX, "sbrk", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_DEC, "fork", { 0, 0, 0, 0 } }, + { TYPE_DEC, "mount", { TYPE_STR, TYPE_STR, 0, 0 } }, + { TYPE_DEC, "umount", { TYPE_STR, 0, 0, 0 } }, + { TYPE_DEC, "signal", { TYPE_DEC, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "dup2", { TYPE_DEC, TYPE_DEC, 0, 0 } }, + { TYPE_DEC, "pause", { 0, 0, 0, 0 } }, + { TYPE_DEC, "alarm", { TYPE_DEC, 0, 0, 0 } }, + { TYPE_DEC, "kill", { TYPE_DEC, TYPE_DEC, 0, 0 } }, + { TYPE_DEC, "pipe", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_DEC, "getgid", { 0, 0, 0, 0 } }, + { TYPE_DEC, "times", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_DEC, "utime", { TYPE_HEX, 0, 0, 0 } }, + { TYPE_DEC, "reboot", { TYPE_HEX, TYPE_HEX, 0, 0 } }, + { TYPE_DEC, "mkfifo", { TYPE_STR, TYPE_OCT, 0, 0 } } +#endif + }; + +#define SYSTRACE_LIMIT (sizeof(systrace_table) / sizeof(struct systrace_entry)) + +char *syserror_table[] = + { + "", + "EPERM", + "ENOENT", + "ESRCH", + "EINTR", + "EIO", + "ENXIO", + "E2BIG", + "ENOEXEC", + "EBADF", + "ECHILD", + "EAGAIN", + "ENOMEM", + "EACCES", + "EFAULT", + "ENOTBLK", + "EBUSY", + "EEXIST", + "EXDEV", + "ENODEV", + "ENOTDIR", + "EISDIR", + "EINVAL", + "ENFILE", + "EMFILE", + "ENOTTY", + "ETXTBSY", + "EFBIG", + "ENOSPC", + "ESPIPE", + "EROFS", + "EMLINK", + "EPIPE", + "EDOM", + "ERANGE", + "EDEADLK", + "ENAMETOOLONG", + "ENOLCK", + "EINVFNC", + "ENOTEMPTY", + "ELOOP", + "ESHELL" + }; + +#define SYSERROR_LIMIT (sizeof(syserror_table) / sizeof(char *)) + +void systrace_entry(void) + { + int *u_argn_ptr; + register unsigned char i; + unsigned int value; + unsigned char type; + +/* kprintf("word at 0x83f8 = 0x%x\n", ugetw(0x83f8)); */ + + kprintf ("\tpid %d, call %d", + udata.u_ptab->p_pid, udata.u_callno); + + if (udata.u_callno < 0 || udata.u_callno >= SYSTRACE_LIMIT) + { + panic("can't trace invalid syscall index"); + } + + kprintf (", %s (", systrace_table[udata.u_callno].function_name); + + u_argn_ptr = &udata.u_argn0; + for (i = 0; i < 4; i++) + { + type = systrace_table[udata.u_callno].argument_type[i]; + if (type == 0) + { + break; + } + + if (i) + { + kputchar(','); + kputchar(' '); + } + + value = *u_argn_ptr++; + systrace_dump(value, udata.u_argn2, type); + } + + kputchar(')'); + kputchar('\n'); + } + +void systrace_exit(void) + { + register unsigned char type; + + kprintf ("\t\tpid %d, call %d, ret ", + udata.u_ptab->p_pid, udata.u_callno); + + if (udata.u_callno == 23 /*7*/ && udata.u_error == 0) /* read() */ + { + systrace_dump(udata.u_argn1, udata.u_retval, TYPE_BIN); + kputchar(','); + kputchar(' '); + } + + type = systrace_table[udata.u_callno].return_type; + systrace_dump(udata.u_retval, 0, type); + + if ((udata.u_callno == 25 || udata.u_callno == 26) && + udata.u_error == 0) /* lseek() or signal() */ + { + kputchar(','); + kputchar(' '); + systrace_dump(udata.u_retval1, 0, type); + } + + kprintf(", err %d", udata.u_error); + if (udata.u_error > 0 && udata.u_error <= SYSERROR_LIMIT) + { + kprintf(" (%s)", syserror_table[udata.u_error]); + } + + kputchar('\n'); +/* kprintf("word at 0x83f8 = 0x%x\n", ugetw(0x83f8)); */ + } + +void systrace_dump(unsigned int value, unsigned int count, unsigned char type) + { + register unsigned char j, c; + unsigned char max, flag, *data; + + max = 32; + flag = 1; + + switch (type) + { + + case TYPE_BIN: + max = 8; + if (count <= 8) + { + max = count; /* size of buffer at (char *)value */ + flag = 0; /* whether to show ellipsis */ + } + /* fall thru */ + + case TYPE_STR: + kputchar('"'); + + data = (unsigned char *)value; + for (j = 0; j < max; j++) + { + c = ugetc(data++); + if (c == 0 && max > 16) + { + flag = 0; /* whether to show ellipsis */ + break; + } + if (c < 0x20 || c >= 0x80) + { + kputchar('\\'); + switch (c) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + kputchar('0' + c); + break; + case 9: + kputchar('t'); + break; + case 0xa: + kputchar('n'); + break; + case 0xd: + kputchar('r'); + break; + default: + kprintf("x%x", (int)c); + break; + } + } + else + { + if (c == '\\' || c == '"') + { + kputchar('\\'); + } + kputchar(c); + } + } + + if (flag) + { + kputchar('.'); + kputchar('.'); + kputchar('.'); + } + + kputchar('"'); + break; + + case TYPE_OCT: + if (value < 8) + { + kputchar('0' + value); + } + else + { + kprintf("0%o", value); + } + break; + + case TYPE_DEC: + kprintf("%d", value); + break; + + case TYPE_HEX: + if (value < 10) + { + kputchar('0' + value); + } + else + { + kprintf("0x%x", value); + } + break; + } + } + diff --git a/src/kernel/uzi/unix.h b/src/kernel/uzi/unix.h new file mode 100755 index 00000000..b03a399a --- /dev/null +++ b/src/kernel/uzi/unix.h @@ -0,0 +1,1011 @@ +/**************************************************** +UZI (Unix Z80 Implementation) Kernel: unix.h +From UZI by Doug Braun and UZI280 by Stefan Nitschke. +*****************************************************/ +/* History: + * 21.12.97 - Removed leading ? from Per-Process equates. HFB + * 11.07.98 - Shortened Time Slices to 50 Ticks/Sec (20 mS). HFB + */ + +#ifndef __UNIX_H +#define __UNIX_H + +#ifndef VAX /* Nick UZIX compatible */ +#include /* for mode_t and others */ +#include /* for O_RDONLY and others */ +#include /* for signal_t and others */ +#include /* for info_t and others */ +#include /* for S_IFREG and others */ +#include /* for SEEK_END and others */ +#include /* for EACCES and others */ +#endif + +#ifndef VAX +#define CPM +#endif + +#define UFTSIZE 20 /*10*/ /* Number of user files */ /*280 = 22*/ +#define OFTSIZE 30 /*15*/ /* Open file table size */ /*280 = 45*/ +#define ITABSIZE 40 /*20*/ /* Inode table size */ /*280 = 45*/ +#define PTABSIZE 5 /*6*/ /* Process table size in UZI180. Size as: + * 1 MB RAM, 1st 32k Shadowed - 14 + * 512k RAM, No Shadow ROM - 7 + * 512k RAM, 1st 32k Shadowed - 6 + * 256k RAM, No Shadow ROM - 3 + */ +#define NSIGS 16 /* Number of signals <= 16 */ + +#if 1 /* Nick UZIX compatible */ +#define SUPERBLOCK 4 /*1*/ /* disk block of filesystem superblock */ +#endif +#define ROOTINODE 1 /* Inode # of / for all mounted filesystems. */ + +#define TICKSPERSEC 50 /* Ticks per second */ +#define MAXTICKS 4 /* Max ticks before swapping out (time slice) + default process time slice */ +#define MAXBACK 3 /* Process time slice for tasks not connected + to the current tty */ +#define MAXBACK2 2 /* Process time slice for background tasks */ +#define MAXINTER 5 /* Process time slice for interactive tasks */ + +#define ARGBLK 0 /* Block number on SWAPDEV for arguments */ +#define PROGBASE ((char *)(0x8100)) /* also data base (Nick, prev 0x100) */ +#define PROGTOP ((char *)(0xfffe)) /* Top of program, base of U_DATA */ +#define SYSCADDR 0x30 /* System call address, by Nick, UZIX compatible */ + +#define EMAGIC 0xc3 /* Header of executable */ +#define CMAGIC 24721 /* Random number for cinode c_magic */ +#define SMOUNTED 12742 /* Magic number to specify mounted filesystem */ +#define NULL 0 + +#define Hi_TECH_C + +#ifndef Hi_TECH_C +/* Speed and code length optimized for Q/C Compiler */ +#define ifnull(e) if(e){}else +#define ifnot(e) if(e){}else +#define ifzero(e) if(e){}else +#else /* Define for Hi-Tech Compiler */ +#define FALSE 0 +#define ifnull(e) if ((e)==0) +#define ifnot(e) if ((e)==FALSE) +#define ifzero(e) if ((e)==NULL) +#endif + + +#ifdef CPM + typedef unsigned uint16; + typedef int int16; +#else + typedef unsigned short uint16; + typedef short int16; +#endif + +/* USER! basic data types added by Nick, see ../include/types.h */ +/* ! uchar & uint is counterparts and must be declared simultaneously */ +#ifndef uchar_is_defined +#define uchar_is_defined +typedef unsigned char uchar; +typedef unsigned int uint; +#endif + + +typedef struct s_queue { + char *q_base; /* Pointer to data */ + char *q_head; /* Pointer to addr of next char to read. */ + char *q_tail; /* Pointer to where next char to insert goes. */ + int q_size; /* Max size of queue */ + int q_count; /* How many characters presently in queue */ + int q_wakeup; /* Threshold for waking up processes waiting on queue */ +} queue_t; + + +#ifdef __TYPES_H /* Nick */ +typedef time_t uzitime_t; +#else +typedef struct uzitime_s { + uint16 t_time; + uint16 t_date; +} uzitime_t; + +#ifndef SKIP_TIME_T /* for utils target, skip when compiling ucp.c, ucpsub.c */ +typedef uzitime_t time_t; +#endif + +/* User's structure for times() system call */ + +struct tms { + uzitime_t tms_utime; + uzitime_t tms_stime; + uzitime_t tms_cutime; + uzitime_t tms_cstime; + uzitime_t tms_etime; /* Elapsed real time */ +}; + +#ifndef utimbuf_is_defined +#define utimbuf_is_defined +/* User's structure for utime() system call */ +struct utimbuf { + uzitime_t actime; + uzitime_t modtime; +}; +#endif + +#endif /* Nick */ + +/* Flags for setftime() */ +#define A_TIME 1 +#define M_TIME 2 +#define C_TIME 4 + +#ifndef __TYPES_H /* Nick */ +/* extra typedefs added from types.h, needed for UTIL target */ +typedef long off_t; +typedef uchar bool_t; /* boolean value */ +typedef uint count_t; /* counter for anything */ +typedef unsigned int mode_t; + +#define BUFSIZE 512 /* uzix buffer/block size */ +#define BUFSIZELOG 9 /* uzix buffer/block size log2 */ +#endif /* __TYPES_H Nick */ + +#ifndef __SIGNAL_H /* Nick */ +/* extra typedefs added from signal.h, needed for UTIL target */ +typedef int signal_t; +#endif + +#if 1 /* file-system related data types added by Nick from uzix1.0 */ +typedef uint16 ino_t; /* Can have 65536 inodes in fs */ +typedef uint16 blkno_t; /* Can have 65536 BUFSIZE-byte blocks in fs */ +typedef uint16 dev_t; /* Device number */ + +#define MINOR(dev) ((uchar)(dev)) +#define MAJOR(dev) ((uchar)((dev) >> 8)) +#define MKDEV(major, minor) (((uint)(uchar)(major) << 8) | (uchar)(minor)) + +#define NULLINO ((ino_t)0) +#define NULLBLK ((blkno_t)-1) +#define NULLDEV ((dev_t)-1) +#else +typedef uint16 blkno_t; /* Can have 65536 512-byte blocks in filesystem */ +#define NULLBLK ((blkno_t)-1) +#endif + +#if 1 /* Nick UZIX compatible */ +typedef struct s_blkbuf { + uchar bf_data[BUFSIZE]; /* This MUST BE first ! */ + dev_t bf_dev; /* device of this block */ + blkno_t bf_blk; /* and block number on device */ + uchar bf_dirty; /* buffer changed flag */ + uchar bf_busy; /* buffer processing in progress */ + uchar bf_prio; /* buffer must be in memory (for wargs) */ + uint bf_time; /* LRU time stamp */ +/* struct s_blkbuf *bf_next; /* LRU free list pointer */ +} blkbuf_t, *bufptr; +#else +typedef struct s_blkbuf { + char bf_data[512]; /* This MUST be first ! */ + char bf_dev; + blkno_t bf_blk; + char bf_dirty; + char bf_busy; + uint16 bf_time; /* LRU time stamp */ +} blkbuf_t, *bufptr; +#endif + +#if 1 /* Nick UZIX compatible */ +#define DIRECTBLOCKS 18 +#define INDIRECTBLOCKS 1 /* MUST BE 1! */ +#define DINDIRECTBLOCKS 1 /* MUST BE 1! */ +#define TOTALREFBLOCKS (DIRECTBLOCKS+2) +#endif + +#if 1 /* Nick UZIX compatible */ +typedef struct s_dinode { +#else +typedef struct dinode { +#endif + uint16 i_mode; + uint16 i_nlink; + uint16 i_uid; + uint16 i_gid; + off_t i_size; /* Nick blkoff_t i_size; */ + uzitime_t i_atime; + uzitime_t i_mtime; + uzitime_t i_ctime; + blkno_t i_addr[20]; +#if 1 /* Nick UZIX compatible */ +} dinode_t; /* Exactly 64 bytes long! */ +#else +} dinode; /* Exactly 64 bytes long! */ +#endif + +#if 1 /* Nick UZIX compatible */ +#define DINODESPERBLOCK 8 /* # of dinode_t per logical block */ +#define DINODESPERBLOCKLOG 3 /* log2(DINODESPERBLOCK) */ +#define DINODESPERBLOCKMASK ((1<c_node.i_addr[0])) + +/* Getmode() returns the inode kind */ +#define _getmode(mode) ((mode) & S_IFMT) +#define getmode(ino) (_getmode((ino)->c_node.i_mode)) +/* Super() returns true if we are the superuser */ +#define super() (udata.u_euid == 0) +#endif + +#ifndef __TYPES_H /* Nick */ + +struct stat /* Really only used by users */ +{ + int16 st_dev; + uint16 st_ino; + uint16 st_mode; + uint16 st_nlink; + uint16 st_uid; + uint16 st_gid; + uint16 st_rdev; + off_t st_size; /* blkoff_t st_size; */ + uzitime_t st_atime; + uzitime_t st_mtime; + uzitime_t st_ctime; +}; + +#endif + +#if 1 /* Nick UZIX compatible */ +#ifndef _SYS_STAT_H + +#define S_IFMT 0170000 /* file type mask */ +#if 1 /* Nick */ +#define S_IFALIGN 0120000 /* regular file, XIP aligned */ +#endif +#define S_IFLNK 0110000 /* symbolic link */ +#define S_IFREG 0100000 /* or just 000000, regular */ +#define S_IFBLK 0060000 /* block special */ +#define S_IFDIR 0040000 /* directory */ +#define S_IFCHR 0020000 /* character special */ +#define S_IFPIPE 0010000 /* pipe */ + +#define S_UMASK 07777 /* bits modifiable by chmod */ + +#define S_ISUID 04000 /* set euid to file uid */ +#define S_ISGID 02000 /* set egid to file gid */ +#define S_ISVTX 01000 /* */ + +#define S_IREAD 0400 /* owner may read */ +#define S_IWRITE 0200 /* owner may write */ +#define S_IEXEC 0100 /* owner may execute */ + +#define S_IGREAD 0040 /* group may read */ +#define S_IGWRITE 0020 /* group may write */ +#define S_IGEXEC 0010 /* group may execute */ + +#define S_IOREAD 0004 /* other may read */ +#define S_IOWRITE 0002 /* other may write */ +#define S_IOEXEC 0001 /* other may execute */ + +#define S_IRWXU 00700 +#define S_IRUSR 00400 +#define S_IWUSR 00200 +#define S_IXUSR 00100 + +#define S_IRWXG 00070 +#define S_IRGRP 00040 +#define S_IWGRP 00020 +#define S_IXGRP 00010 + +#define S_IRWXO 00007 +#define S_IROTH 00004 +#define S_IWOTH 00002 +#define S_IXOTH 00001 + +#ifdef __KERNEL__ +#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO) +#define S_IALLUGO (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO) +#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH) +#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH) +#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH) +#endif + +#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +#define S_ISPIPE(m) (((m) & S_IFMT) == S_IFPIPE) + +#if 1 /* Nick */ +#define S_ISDEV(m) (S_ISCHR(m) || S_ISBLK(m)) +#else +#define S_ISDEV(m) (((m) & S_IFMT) & S_IFCHR) +#endif + +#if 1 /* Nick */ +#define S_ISALIGN(m) (((m) & S_IFMT) == S_IFALIGN) +#define S_ISREGALIGN(m) (S_ISREG(m) || S_ISALIGN(m)) +#endif + +#if 1 /* Nick free bitmap */ +#define XIP_ALIGN 0 +#define XIP_UALIGN 1 +#endif + +#endif +#else +/* Bit masks for i_mode and st_mode */ + +#define OTH_EX 0001 +#define OTH_WR 0002 +#define OTH_RD 0004 +#define GRP_EX 0010 +#define GRP_WR 0020 +#define GRP_RD 0040 +#define OWN_EX 0100 +#define OWN_WR 0200 +#define OWN_RD 0400 + +#define SAV_TXT 01000 +#define SET_GID 02000 +#define SET_UID 04000 + +#define MODE_MASK 07777 + +#define F_REG 0100000 +#define F_DIR 040000 +#define F_PIPE 010000 +#define F_BDEV 060000 +#define F_CDEV 020000 + +#define F_MASK 0170000 +#endif + +#if 1 /* Nick UZIX compatible */ +/* Getmode() returns the inode kind */ +#define _getmode(mode) ((mode) & S_IFMT) +/* temporary #define getmode(ino) (_getmode((ino)->c_node.i_mode)) */ +/* Super() returns true if we are the superuser */ +/* temporary #define super() (udata.u_euid == 0) */ +#endif + + +#if 1 /* Nick UZIX compatible */ +/* in-core inode structure */ +typedef struct s_cinode { + uint16 c_magic; /* Used to check for corruption */ + uchar c_dirty; /* Modified flag */ + dev_t c_dev; /* Inode's device */ + ino_t c_num; /* Inode's number */ + uint16 c_refs; /* In-core reference count */ + bool_t c_ro; /* Read-only filesystem flag */ + dinode_t c_node; /* disk inode copy */ +} cinode_t, *inoptr; +#else +typedef struct cinode { + int16 c_magic; /* Used to check for corruption. */ + int16 c_dev; /* Inode's device */ + uint16 c_num; /* Inode # */ + dinode c_node; + char c_refs; /* In-core reference count */ + char c_dirty; /* Modified flag. */ +} cinode, *inoptr; +#endif + +#define NULLINODE ((inoptr)NULL) +#define NULLINOPTR ((inoptr*)NULL) + + +#ifndef __TYPES_H /* Nick */ +#define DIRNAMELEN 14 + +/* device directory entry */ +typedef struct s_direct { + uint16 d_ino; /* file's inode */ + uchar d_name[DIRNAMELEN]; /* file name */ +} direct_t; + +#define BUFSIZE 512 /* uzix buffer/block size */ +#define BUFSIZELOG 9 /* uzix buffer/block size log2 */ + +#if 1 /* Nick free bitmap */ +#define REGION_LOG 14 +#define REGION_BYTES (1< +_asm +OSYS equ 2 ; byte offsets of elements of u_data +OCALL equ 3 +ORET equ 4 ; Return Location +ORVAL equ 6 ; Return Value +OERR equ 8 ; Error Number +OSP equ 10 ; User's Stack Pointer +OBC equ 12 ; User's Frame Pointer +OPAGE equ 121 + NSIGS ; Nick ; User's base BBR register value for Process +_endasm +------*/ + +#if 1 /* Nick UZIX compatible */ +typedef struct s_udata { +#else +typedef struct u_data { +#endif +#if 1 /* Nick UZIX compatible */ + ptab_t *u_ptab; /* Process table pointer */ +#else + struct p_tab *u_ptab; /* Process table pointer */ +#endif + char u_insys; /* True if in kernel */ + char u_callno; /* sys call being executed. */ + char *u_retloc; /* Return location from sys call */ + int u_retval; /* Return value from sys call */ + int u_retval1; /* Nick, for long return value from lseek() */ + int u_error; /* Last error number */ + int *u_sp; /* Used when process is swapped. */ + int *u_bc; /* Place for user's frame pointer */ + int u_cursig; /* Signal currently being caught */ +#if 1 /* Nick */ + int u_argn0; /* Last system call arg */ +#else + int u_argn; /* Last system call arg */ +#endif + int u_argn1; /* This way because args on stack backwards */ + int u_argn2; + int u_argn3; /* args n-3, n-2, n-1, and n */ + + char * u_base; /* Source or dest for I/O */ + unsigned u_count; /* Amount for I/O */ + off_t u_offset; /* Nick blkoff_t u_offset; /* Place in file for I/O */ +#if 1 /* Nick UZIX compatible */ + struct s_blkbuf *u_buf; +#else + struct blkbuf *u_buf; +#endif + char u_sysio; /* True if I/O to system space */ + + int u_gid; + int u_euid; + int u_egid; + int u_mask; /* umask: file creation mode mask */ + uzitime_t u_time; /* Start time */ +#if 0 + char u_files[UFTSIZE]; /* Process file table: + indices into open file table. */ +#endif + inoptr u_cwd; /* Index into inode table of cwd. */ + unsigned u_break; /* Top of data space */ + inoptr u_ino; /* Used during execve() */ + char *u_isp; /* Value of initial sp (argv) */ + int (*u_sigvec[NSIGS])(); /* Array of signal vectors */ + char u_name[8]; /* Name invoked with */ + uzitime_t u_utime; /* Elapsed ticks in user mode */ + uzitime_t u_stime; /* Ticks in system mode */ + uzitime_t u_cutime; /* Total childrens ticks */ + uzitime_t u_cstime; + char u_page; /* Process' MMU Base Address */ + inoptr u_root; /* Index into inode table of chroot target */ + char u_traceme; /* added by Nick, used only when DEBUG > 1 */ +#if 1 + char u_files[UFTSIZE]; /* Process file table: + indices into open file table. */ +#endif +#if 1 /* Nick UZIX compatible */ +} udata_t; +#else +} u_data; +#endif + + +/* This is the user data structure, padded out to 512 bytes with the + * System Stack. + */ +#if 1 /* Nick */ +typedef struct s_ublock { +#else +typedef struct u_block { +#endif +#if 1 /* Nick UZIX compatible */ + udata_t u_d; + char u_s [0x1000 /*512*/ - sizeof(struct s_udata)]; +#else + u_data u_d; + char u_s [512 - sizeof(struct u_data)]; +#endif +#if 1 /* Nick */ +} ublock_t; +#else +} u_block; +#endif + + +/* Struct to temporarily hold arguments in execve */ +struct s_argblk { + int a_argc; + int a_arglen; + int a_envc; + char a_buf[512-3*sizeof(int)]; +}; + + +/* The device driver switch table */ + +#if 1 /* Nick UZIX compatible */ +/* The device driver switch table */ +typedef struct s_devsw { + uchar minors; /* # of minor device numbers */ + int (*dev_init)(uchar minor); + int (*dev_open)(uchar minor); + int (*dev_close)(uchar minor); + int (*dev_read)(uchar minor, uchar rawflag); + int (*dev_write)(uchar minor, uchar rawflag); + int (*dev_ioctl)(uchar minor, int cmd, void *data); +} devsw_t; +#else +typedef struct devsw { + int minor; /* The minor device number (an argument to below) */ + int (*dev_open)(); /* The routines for reading, etc */ + int (*dev_close)(); /* Format: op(minor,blkno,offset,count,buf); */ + int (*dev_read)(); /* Offset would be ignored for block devices */ + int (*dev_write)(); /* Blkno and offset ignored for tty, etc. */ + int (*dev_ioctl)(); /* Count is rounded to 512 for block devices */ +} devsw; +#endif + +#if 1 /* Nick UZIX compatible */ +#ifndef NATIVE +#ifndef __FCNTL_H +/* extra definitions added by Nick from sys/fcntl.h, needed for UTIL target */ + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +/* Flag values for open only */ +#define O_CREAT 0x0100 /* create and open file */ +#define O_TRUNC 0x0200 /* open with truncation */ +#define O_NEW 0x0400 /* create only if not exist */ +#define O_SYMLINK 0x0800 /* open symlink as file */ + +/* a file in append mode may be written to only at its end. */ +#define O_APPEND 0x2000 /* to end of file */ +#define O_EXCL 0x4000 /* exclusive open */ +#define O_BINARY 0x8000 /* not used in unix */ + +#endif +#endif +#else +#ifndef _FCNTL_H +/* Open() parameters. */ + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#endif +#endif + +#if 1 /* Nick UZIX compatible */ +#ifndef __ERRNO_H +/* Error codes */ /*- if not used */ +#define EPERM 1 /* 1 Operation not permitted */ +#define ENOENT 2 /* 2 No such file or directory */ +#define ESRCH 3 /*-*/ /* 3 No such process */ +#define EINTR 4 /* 4 Interrupted system call */ +#define EIO 5 /* 5 I/O error */ +#define ENXIO 6 /* 6 No such device or address */ +#define E2BIG 7 /* 7 Arg list too long */ +#define ENOEXEC 8 /* 8 Exec format error */ +#define EBADF 9 /* 9 Bad file number */ +#define ECHILD 10 /* 10 No child processes */ +#define EAGAIN 11 /* 11 Try again */ +#define ENOMEM 12 /* 12 Out of memory */ +#define EACCES 13 /* 13 Permission denied */ +#define EFAULT 14 /* 14 Bad address */ +#define ENOTBLK 15 /* 15 Block device required */ +#define EBUSY 16 /* 16 Device or resource busy */ +#define EEXIST 17 /* 17 File exists */ +#define EXDEV 18 /* 18 Cross-device link */ +#define ENODEV 19 /* 19 No such device */ +#define ENOTDIR 20 /* 20 Not a directory */ +#define EISDIR 21 /* 21 Is a directory */ +#define EINVAL 22 /* 22 Invalid argument */ +#define ENFILE 23 /* 23 File table overflow */ +#define EMFILE 24 /*-*/ /* 24 Too many open files */ +#define ENOTTY 25 /*-*/ /* 25 Not a typewriter */ +#define ETXTBSY 26 /*-*/ /* 26 Text file busy */ +#define EFBIG 27 /*-*/ /* 27 File too large */ +#define ENOSPC 28 /* 28 No space left on device */ +#define ESPIPE 29 /* 29 Illegal seek */ +#define EROFS 30 /*-*/ /* 30 Read-only file system */ +#define EMLINK 31 /*-*/ /* 31 Too many links */ +#define EPIPE 32 /* 32 Broken pipe */ +#define EDOM 33 /*-*/ /* 33 Math argument out of domain of func */ +#define ERANGE 34 /*-*/ /* 34 Math result not representable */ +#define EDEADLK 35 /*-*/ /* 35 Resource deadlock would occur */ +#define ENAMETOOLONG 36 /*-*/ /* 36 File name too long */ +#define ENOLCK 37 /*-*/ /* 37 No record locks available */ +#define EINVFNC 38 /* 38 Function not implemented */ +#define ENOTEMPTY 39 /*-*/ /* 39 Directory not empty */ +#define ELOOP 40 /*-*/ /* 40 Too many symbolic links encountered */ +#define ESHELL 41 /*-*/ /* 41 It's a shell script */ +#define ENOSYS EINVFNC + +#define __ERRORS 40 +#endif +#else +#ifndef __ERRNO_H +/* + * Error codes + */ +#define EPERM 1 /* Not owner */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted System Call */ +#define EIO 5 /* I/O Error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No children */ +#define EAGAIN 11 /* No more processes */ +#define ENOMEM 12 /* Not enough core */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Mount device busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ + +/* math software */ +#define EDOM 33 /* Argument too large */ +#define ERANGE 34 /* Result too large */ + +#define ENAMETOOLONG 63 /* File name too long */ +#endif +#endif + +#if 1 /* Nick UZIX compatible */ + +/* Info about a specific process, returned by sys_getfsys */ +typedef struct s_pdata { + int u_pid; /* Process PID */ + ptab_t *u_ptab; /* Process table pointer */ + uchar u_name[DIRNAMELEN]; /* Name invoked with */ + + /* syscall's interface */ + uchar u_insys; /* True if in kernel now */ + uchar u_callno; /* syscall being executed */ + uchar u_traceme; /* Process tracing flag */ + + /* filesystem/user info */ + uchar u_uid; /* user id */ + uchar u_gid; /* group id */ + uchar u_euid; /* effective user id */ + uchar u_egid; /* group user id */ + uzitime_t u_time; /* Start time */ + + /* process flow info */ + signal_t u_cursig; /* Signal currently being caught */ + + /* time info */ + uzitime_t u_utime; /* Elapsed ticks in user mode */ + uzitime_t u_stime; /* Ticks in system mode */ +}; + +/* Info about kernel, returned by sys_getfsys */ +typedef struct s_kdata { + uchar k_name[14]; /* OS name */ + uchar k_version[8]; /* OS version */ + uchar k_release[8]; /* OS release */ + + uchar k_host[14]; /* Host name */ + uchar k_machine[8]; /* Host machine */ + + int k_tmem; /* System memory, in kbytes */ + int k_kmem; /* Kernel memory, in kbytes */ +}; + +#define PRIO_MAX 19 +#define PRIO_MIN -20 + +#define WNOHANG 1 +#define WUNTRACED 2 + +/* sys_getset() commands */ +#define GET_PID 0 /* get process id */ +#define GET_PPID 1 /* get parent process id */ +#define GET_UID 2 /* get user id */ +#define SET_UID 3 /* set user id */ +#define GET_EUID 4 /* get effective user id */ +#define GET_GID 5 /* get group id */ +#define SET_GID 6 /* set group id */ +#define GET_EGID 7 /* get effective group id */ +#define GET_PRIO 8 /* get process priority */ +#define SET_PRIO 9 /* set process priority */ +#define SET_UMASK 10 /* get/set umask */ +#define SET_TRACE 11 /* set trace flag */ + +#endif + +#ifndef SEEK_SET +/* extra definitions from sys/seek.h, it wasn't worth testing _SYS_SEEK_H */ +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef _SYS_IOCTL_H +/* extra definitions added by Nick from sys/ioctl.h, needed for UTIL target */ +typedef enum { + GI_PTAB = -1, /* processes table */ + GI_ITAB = -2, /* inodes table */ + GI_BTAB = -3, /* buffers table */ + GI_FTAB = -4, /* filesystems table */ + GI_UDAT = -5, /* process user data */ + GI_UTAB = -6, /* current process table */ + GI_PDAT = -7, /* process info */ + GI_KDAT = -8 /* kernel info */ +} getinfo_t; + +typedef struct { + getinfo_t req; + int size; /* Nick temporary size_t size; */ + void *ptr; +} info_t; +#endif + +#if 1 /* Nick EXE format */ +#define E_MAGIC 0xa6c9 + +#define E_FORMAT_LARGE 1 +#define E_FORMAT_BANKED 2 +#define E_FORMAT_KERNEL 3 + +typedef struct s_exefile + { + uint16 e_magic; + uint16 e_format; + off_t e_size; + uint16 e_hsize; + uint16 e_idata; + uint16 e_entry; + uint16 e_udata; + uint16 e_stack; + uint16 e_break; + } exefile_t; +#endif + +#endif /* __UNIX_H */ + diff --git a/src/kernel/uzi/utils.asm b/src/kernel/uzi/utils.asm new file mode 100755 index 00000000..08f42037 --- /dev/null +++ b/src/kernel/uzi/utils.asm @@ -0,0 +1,630 @@ +; utils.asm + +;/*************************************************************** +; UZI (Unix Z80 Implementation) Kernel: utils.asz +;---------------------------------------------------------------- +; Adapted from UZI By Doug Braun, and UZI280 by Stefan Nitschke +; Copyright (C) 1998 by Harold F. Bower +; Portions Copyright (C) 1995 by Stefan Nitschke +;****************************************************************/ +;/* Revisions: +; * 15.1.98 - Extracted from machdep.c and several of Stefan's +; * separate modules in UZI280. HFB +; */ + + public _shift8 + extern ?BANK_FAST_LEAVE_L08 + + .if 0 ; Nick + public _puts, _kprintf, _bcopy, _bzero ; PUBlic + public _itob, _abort, _strlen ; " + + extern __putc ; EXTern + + extern ?ENT_PARM_DIRECT_L09 ; formerly ncsv + extern ?ENT_AUTO_DIRECT_L09 ; formerly csv + extern ?BANK_LEAVE_DIRECT_L08 ; formerly cret + extern ?BANK_CALL_DIRECT_L08 ; Nick for IAR + + extern indir, lmod, wrelop, ldiv ; from Runtime (Nick uh oh) + .endif + + rseg CODE +;-------------------------------------- +; /* This shifts an unsigned int right 8 places. */ + +; shift8() +; { +; #asm + +_shift8: + .if 1 ; IAR + ld l,d + ld h,0 + .else + pop de + pop hl + ld l,h + ld h,0 + push hl + push de + .endif + +; #endasm + .if 1 + jp ?BANK_FAST_LEAVE_L08 + .else + ret + .endif +; } + + +;-------------------------------------- +; puts (char *s) +; { + + .if 0 ; Nick +_puts: + call ?ENT_PARM_DIRECT_L09 + +; while (*s) + +L34: ld l,(ix+6) + ld h,(ix+7) + ld a,(hl) + or a + jp z,?BANK_LEAVE_DIRECT_L08 + +; kputchar (*s++); + + inc hl + ld (ix+6),l + ld (ix+7),h + ld l,a + ld h,0 + push hl + .if 1 ; IAR + ld hl,LWRD _kputchar + ld a,BYTE3 _kputchar + call ?BANK_CALL_DIRECT_L08 + .else + call _kputchar + .endif + pop bc + JR L34 +; } + .endif + +;-------------------------------------- +; kputchar (c) +; char c; +; { + + .if 0 ; Nick +_kputchar: + pop de ; Ret Addr + pop hl ; c + push hl + push de + +; if (c == '\n') + + ld a,l + push hl ; Save Char for print in L37 + cp 10 + JR nz,L37 + +; _putc (0, '\r'); /* Use default TTY, minor=0 */ + + ld l,13 + push hl + LD L,1 ; Dev = default TTY + push hl + .if 1 ; IAR + ld hl,LWRD __putc + ld a,BYTE3 __putc + call ?BANK_CALL_DIRECT_L08 + .else + call __putc + .endif + pop bc + pop bc + +; _putc (0, c); + + ; Char already on Stack as 1st Param +L37: LD HL,1 ; Dev = default TTY + push hl + .if 1 ; IAR + ld hl,LWRD __putc + ld a,BYTE3 __putc + call ?BANK_CALL_DIRECT_L08 + .else + call __putc + .endif + pop bc + pop bc +; } + ret + .endif + +;-------------------------------------- +; /* Short version of printf to save space. +; * NOTE: This code may need to be rewritten for different compilers +; * since it makes assumptions about the parameter ordering and +; * sizing on the system stack. +; */ +; kprintf (nargs) +; char *nargs; +; { + + .if 0 ; Nick +_kprintf: + call ?ENT_AUTO_DIRECT_L09 + defw -10 + +; register char *fmt; +; register char c; +; int base; +; char s[7], *itob(); + +; fmt = &nargs+1; /* NOTE: Assumes Pointer to 2-byte Word */ + + push ix + pop de + ld hl,8 + add hl,de + push hl + pop iy + +; while (c = *nargs++) { + +L46: ld l,(ix+6) + ld h,(ix+7) + ld a,(hl) + inc hl + ld (ix+6),l + ld (ix+7),h + or a + jp z,?BANK_LEAVE_DIRECT_L08 + +; if (c != '%') { +; kputchar (c); +; continue; + + cp 37 + JR NZ,L6 + +; } +; switch (c = *nargs++) { + + ld a,(hl) + inc hl + ld (ix+6),l + ld (ix+7),h + cp 'd' ; 100 + JR z,L53 + cp 'o' ; 111 + JR z,L55 + cp 's' ; 115 + JR z,L58 + cp 'u' ; 117 + JR z,L56 + cp 'x' ; 120 + JR z,L57 + cp 'c' ; 99 + JR NZ,L6 + +L52: ld l,(ix+6) + ld h,(ix+7) + ld a,(hl) + inc hl + ld (ix+6),l + ld (ix+7),h + jp LWRD L6 + +; case 'c': kputchar (*nargs++); + +L6: ld l,a + LD H,0 + push hl + .if 1 ; IAR + ld hl,LWRD _kputchar + ld a,BYTE3 _kputchar + call ?BANK_CALL_DIRECT_L08 + .else + call _kputchar + .endif + pop bc +; continue; + JR L46 + +; case 'd': base = -10; +; goto prt; + +L53: ld (ix-3),246 + ld (ix-2),255 + jp LWRD L54 + +; case 'o': base = 8; +; goto prt; + +L55: ld (ix-3),8 + JR L59 + +; case 'u': base = 10; +; goto prt; + +L56: ld (ix-3),10 + JR L59 + +; case 'x': base = 16; + +L57: ld (ix-3),16 +L59: ld (ix-2),0 + +; prt: +; puts (itob (*(int *)fmt, s, base)); + +L54: ld l,(ix-3) + ld h,(ix-2) + push hl + push ix + pop de + ld hl,-10 + add hl,de + push hl + ld l,(iy+0) + ld h,(iy+1) + push hl + .if 1 ; IAR + ld hl,LWRD _itob + ld a,BYTE3 _itob + call ?BANK_CALL_DIRECT_L08 + .else + call _itob + .endif + pop bc + pop bc + ex (sp),hl + .if 1 ; IAR + ld hl,LWRD _puts + ld a,BYTE3 _puts + call ?BANK_CALL_DIRECT_L08 + .else + call _puts + .endif + pop bc + +; fmt++; fmt++; /* NOTE: for Size of Word Ptr */ + +L60: inc iy + inc iy + +; continue; + jp LWRD L46 + +; case 's': puts (*(char **)fmt); + +L58: ld l,(iy+0) + ld h,(iy+1) + push hl + .if 1 ; IAR + ld hl,LWRD _puts + ld a,BYTE3 _puts + call ?BANK_CALL_DIRECT_L08 + .else + call _puts + .endif + pop bc + +; fmt++; fmt++; /* NOTE: for Size of Word Ptr */ +; continue; + jp LWRD L60 + +; default: kputchar (c); +; continue; +; } +; } +; } + .endif + +;-------------------------------------- +; Lock up the system in response to a fatal error. +; (from UZI original EXTRAS.C module) + +; abort() +; { +_abort: di + halt + jr _abort ; If an interrupt hits anyway, loop.. +; } + + +;-------------------------------------- +; /* itob.c */ +; Moderately optimized version of UZI280 code from Hi-Tech C Compiler output. +; UZI280 is Copyright (1990-95) by Stefan Nitschke and Doug Braun. +; H.F.Bower, 3 Jan 1998 + +; #define TRUE 1 +; #define FALSE 0 + +; /* convert an integer to a string in any base (2-36) */ +; char *itob (int n, char *s, int base) +; { + + .if 0 ; Nick +_itob: call ?ENT_AUTO_DIRECT_L09 + defw -8 + +; register unsigned int u; +; register char *p, *q; +; register negative, c; + +; if ((n < 0) && (base == -10)) { + + bit 7,(ix+7) + jr z,L2 + ld de,-10 + ld l,(ix+10) + ld h,(ix+11) + or a + sbc hl,de + jr nz,L2 + +; negative = TRUE; + + set 0,(ix-6) + +; u = -n; + + ld e,(ix+6) + ld d,(ix+7) + ld hl,0 + or a + sbc hl,de + jr L3 + +; } +; else { +; negative = FALSE; + +L2: res 0,(ix-6) + +; u = n; + + ld l,(ix+6) + ld h,(ix+7) +L3: ld (ix-2),l + ld (ix-1),h + +; } +; if (base == -10) /* Signals signed conversion */ + + ld de,-10 + ld l,(ix+10) + ld h,(ix+11) + or a + sbc hl,de + jr nz,L4 + +; base = 10; + + ld (ix+10),10 + ld (ix+11),0 + +; p = q = s; + +L4: ld l,(ix+8) + ld h,(ix+9) + ld (ix-4),l + ld (ix-3),h + push hl + pop iy + +; do { /* Generate digits in reverse order */ +; if ((*p = u % base + '0') > '9') + +L7: ld e,(ix+10) + ld d,(ix+11) + ld l,(ix-2) + ld h,(ix-1) + .if 1 ; IAR + ld hl,LWRD lmod + ld a,BYTE3 lmod + call ?BANK_CALL_DIRECT_L08 + .else + call lmod + .endif + ld a,l + add a,'0' + ld (iy+0),a + cp '9'+1 ; > '9'? + jr c,L8 ; ..jump if Not + +; *p += ('A' - ('9' + 1)); + + add a,7 + ld (iy+0),a + +; ++p; + +L8: inc iy + +; u = u / base; + + ld e,(ix+10) + ld d,(ix+11) + ld l,(ix-2) + ld h,(ix-1) + .if 1 ; IAR + ld hl,LWRD ldiv + ld a,BYTE3 ldiv + call ?BANK_CALL_DIRECT_L08 + .else + call ldiv + .endif + ld (ix-2),l + ld (ix-1),h + +; } while (u > 0); + + ld a,l + or h + jr nz,L7 + +; if (negative) + + bit 0,(ix-6) + jr z,L9 + +; *p++ = '-'; + + ld (iy+0),'-' + inc iy + +; *p = '\0'; /* Terminate the string */ + +L9: ld (iy+0),0 + +; while (q < --p) { /* Reverse the digits */ + + jr L10 + +; c = *q; + +L11: ld l,(ix-4) + ld h,(ix-3) + ld a,(hl) + +; *q++ = *p; + + ld e,(iy+0) + ld (hl),e + inc hl + ld (ix-4),l + ld (ix-3),h + +; *p = c; + + ld (iy+0),a + +; } + +L10: dec iy + push iy + pop de + ld l,(ix-4) + ld h,(ix-3) + .if 1 ; IAR + ld hl,LWRD wrelop + ld a,BYTE3 wrelop + call ?BANK_CALL_DIRECT_L08 + .else + call wrelop + .endif + jr c,L11 + +; return s; + + ld l,(ix+8) + ld h,(ix+9) +; } + jp ?BANK_LEAVE_DIRECT_L08 + .endif + +;-------------------------------------- +; Return length of Null-terminated string +; Enter: Ptr to String on Stack Top +; Exit : HL = Number of chars from start to Null +; Uses : AF,DE,HL + +; int strlen (char *s) +; { +; int n; + + .if 0 ; Nick +_strlen: + pop hl ; Return addr + pop de ; Ptr to string + push de ; keep on stack + push hl ; ret addr back to stack + +; n = 0; + + ld hl,0 ; Initialize counter + +; while (*s++ != NULL) + +strl0: ld a,(de) ; Get a char + inc de ; advance ptr + or a ; End-of-string? + ret z ; ..exit if yes (Count in HL) + +; ++n; + + inc hl ; bump count to show we had a char + jr strl0 ; back for more + +; return (n); +; } + .endif + +;-------------------------------------- +; Clear the memory starting at the address at "ptr", for "count" bytes +; +; bzero(ptr,count) +; char *ptr; +; int count; +; { + + .if 0 ; Nick +_bzero: pop de ; Return Addr + pop hl ; Start of area to fill + pop bc ; count + push bc ; (keep stack loaded) + push hl + push de ; Save Ret Addr + ld a,b + or c ; Any count? + ret z ; ..exit here if nothing to clear + ld (hl),0 ; Zero the first byte + ld e,l + ld d,h ; copy the addr + inc de ; + 1 + dec bc ; count - 1 + ld a,b + or c + ret z ; ..exit here if only one byte to zero + ldir + ret + .endif + +;-------------------------------------- +; Copy "count" bytes from "src" to "dest". Block Move function. +; BCOPY (SRC, DEST, COUNT) + + .if 0 ; Nick +_bcopy: pop hl + ld (HOLDER),hl + pop hl + pop de + pop bc + push hl + push hl + push hl + ld a,b + or c ; Zero Length? + jr z,nocopy ; ..jump to avoid 64k move + ldir +nocopy: ld hl,(HOLDER) + jp (hl) + + rseg UDATA0 +HOLDER: defs 2 + rseg CODE + .endif + + + end diff --git a/src/kernel/uzi/vendor.h b/src/kernel/uzi/vendor.h new file mode 100755 index 00000000..1884199c --- /dev/null +++ b/src/kernel/uzi/vendor.h @@ -0,0 +1,87 @@ +/* vendor.h for uzi180 by Nick - essential defines for the IAR compiler */ + +#ifndef UTIL /* ensures we don't do anything when compiling utils under MSVC */ + +#define _putc __putc +#define abyte _abyte +#define acrlf _acrlf +#define ahexw _ahexw +#define amess _amess +#define bcopy _bcopy +#define busid _busid +#define bzero _bzero +#define calltrap _calltrap +#define chksigs _chksigs +#define clkint2 _clkint2 +#define cmdblk _cmdblk +#define di _di +#define di_absolute _di_absolute +#define doexec _doexec +#define dofork _dofork +#define dptr _dptr +#define dTbl _dTbl +#define ei _ei +#define ei_absolute _ei_absolute +#define fbuf _fbuf +#define fdInit _fdInit +#define fdread0 _fdread0 +#define fdwrite0 _fdwrite0 +#define ferror _ferror +#define fs_init _fs_init +#define fsector _fsector +#define ftrack _ftrack +#define getproc _getproc +#define hd_offset _hd_offset +#define hdhds _hdhds +#define hdspt _hdspt +#define inint _inint +#define initsys _initsys +#define kprintf _kprintf +#define lpout _lpout +#define newproc _newproc +#define osBank _osBank +#define panic _panic +#define ptab_alloc _ptab_alloc +/* #define rdtod _rdtod */ +#define rom_serial_no _rom_serial_no +#define runticks _runticks +#define scsiop _scsiop +#define swapin _swapin +#define swapout _swapout +#define tempstack _tempstack +#define tod _tod +#define tty_inproc _tty_inproc +#define ub _ub +#define uget _uget +#define ugetc _ugetc +#define ugets _ugets +#define ugetw _ugetw +#define unix_locked_out _unix_locked_out +#define unix2 _unix2 +#define uput _uput +#define uputc _uputc +#define uputw _uputw + +#if 1 /* Nick, see kprintf.c */ +int kprintf(char *, ...); /* ensures IAR won't try to pass register params */ +#else +void kprintf(char *, ...); /* ensures IAR won't try to pass register params */ +#endif + +/* diag.h for uzi180 by Nick - essential defines for the IAR compiler */ + +#pragma function = non_banked + +/* void exit(int exitcode); */ +/* void abort(int exitcode); */ + +void abyte(char data); +void acrlf(void); +void ahexw(int data); +void amess(char *ptr); +void tempstack(void); /* for machasm.s01 */ + +#pragma function = default + +#endif /* UTIL */ + diff --git a/src/kernel/uzi/xip.c b/src/kernel/uzi/xip.c new file mode 100755 index 00000000..1f4e3eff --- /dev/null +++ b/src/kernel/uzi/xip.c @@ -0,0 +1,1394 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + Filesystem related routines for XIP system +**********************************************************/ + +#define NEED__DEVIO +#define NEED__FILESYS +#define NEED__MACHDEP +#define NEED__PROCESS +#define NEED__SCALL + +#include "vendor.h" /* Nick, must come first */ +#include +#include +#include +#include "devio.h" /* prototypes added by Nick */ +#include "filesys.h" /* prototypes added by Nick */ +#include "xip.h" /* prototypes added by Nick */ + +#ifdef UTIL /* rather a hack indeed */ +#define EISALIGN 42 /* 42 File is already aligned */ +#define ENOALIGN 43 /* 43 File is not aligned */ +#define ETOOSHORT 44 /* 44 File is too short, or hole */ +#define ENOREGALIGN 45 /* 42 Not a regular or aligned file */ +#define ENOLCKFS 46 /* 45 Not a locking filesystem */ +#define ECORRUPTFS 47 /* 46 Filesystem is corrupt */ +#endif + +int int_min(int, int); + +/* Returns true if the magic number of a superblock is ok ??? not used */ +#define gooddev(dev) ((dev)->s_mounted == SMOUNTED) + +#define blockinodes(blk) ((blk) << DINODESPERBLOCKLOG) +#define devinodes(dev) blockinodes((dev)->s_isize) +#define inodeblock(dev,ino) (((ino) >> DINODESPERBLOCKLOG) + (dev)->s_reserv) +#define inodeoffset(ino) ((ino) & DINODESPERBLOCKMASK) + +int bitmap_align(inoptr ino, off_t size) + { + blkno_t i, j, k; + blkno_t blk, pos, /*inc,*/ newno; + blkno_t *region, regions, blocks; + fsptr dev; + dev_t devno; + inoptr other; + int flag, exclude, indirection; + +#if DEBUG > 2 + kprintf("bitmap_align(%u, %ld) starting\n", ino - i_tab, size); +#endif + +/* return 0; */ + + /* prepare to access the given inode */ + devno = ino->c_dev; + dev = getfs(devno); + if (dev->s_bitmap_immov >= dev->s_bitmap_final) + { + udata.u_error = ENOLCKFS; /* not a locking filesystem */ +#if DEBUG > 2 + kprintf("bitmap_align() returning -1 a\n"); +#endif + return -1; + } + + /* validate the filetype, it must be non-aligned */ + if ((ino->c_node.i_mode & S_IFMT) == S_IFALIGN) + { + udata.u_error = EISALIGN; /* file is already aligned */ + return -1; + } + if ((ino->c_node.i_mode & S_IFMT) != S_IFREG) + { + udata.u_error = ENOREGALIGN; /* file not regular or aligned */ +#if DEBUG > 2 + kprintf("bitmap_ualign() returning -1 b\n"); +#endif + return -1; + } + + /* ensure the region list will fit in 512 bytes */ + regions = (size + REGION_BYTES - 1) >> REGION_LOG; + if (regions > (BUFSIZE / sizeof(blkno_t))) + { + udata.u_error = ENOSPC; /* size specified is too large */ +#if DEBUG > 2 + kprintf("bitmap_align() returning -1 c\n"); +#endif + return -1; + } + + /* ready to allocate the region list */ + region = (blkno_t *)tmpbuf(); + + /* calculate size in blocks, to resolve size of last region */ + blocks = (size + BUFSIZE - 1) >> BUFSIZELOG; + + /* allocate each region its physical memory address */ + pos = 0; + for (i = 0; i < regions; i++) + { + /* is this a full region, or the last partial region? */ + k = int_min(blocks - pos, REGION_BLOCKS); + + /* try to find contiguous aligned non-reserved blocks */ + j = bitmap_search(devno, k, dev->s_bitmap_immov, + dev->s_bitmap_final); + if (j == (blkno_t)-1) + { + /* there was not enough aligned space available */ + udata.u_error = ENOSPC; + + regions = i; + goto bitmap_align_error; + } + + /* found a suitable spot for the region, snarf it */ + region[i] = j; + if (bitmap_reserve(devno, j, k, 1, dev->s_bitmap_immov, + dev->s_bitmap_final)) + { + /* disk i/o error, or corrupt filesystem */ + /* udata.u_error = ENXIO */; + + regions = i; + goto bitmap_align_error; + } + + /* calculate file position for start of next region */ + pos += REGION_BLOCKS; + } + +#if DEBUG > 1 + kprintf("processing my inode %d\n", ino->c_num); +#endif + + /* move the file's data into unoccupied blocks of each region */ + pos = 0; + for (i = 0; i < regions; i++) + { + /* is this a full region, or the last partial region? */ + k = int_min(blocks - pos, REGION_BLOCKS); + + /* loop through each block of the region individually */ + blk = region[i]; + for (j = 0; j < k; j++) + { + /* see if the target spot for this block is occupied */ + flag = bitmap_set(devno, blk, 1, dev->s_bitmap_block, + dev->s_bitmap_immov); + if (flag == -1) + { + /* disk i/o error, or corrupt filesystem */ + /* udata.u_error = ENXIO; */ + + goto bitmap_align_error; + } + + if (flag == 0) + { + /* no, move something in and possibly repeat */ + newno = bitmap_align_chase(dev, ino, blk, pos, + region, regions, blocks); + if (newno == (blkno_t)-1) + { + /* i/o error, or corrupt filesystem */ + /* udata.u_error = ENXIO; */ + + goto bitmap_align_error; + } + + /* eventually a non-target block was freed */ + if (bitmap_set(devno, newno, 0, + dev->s_bitmap_block, + dev->s_bitmap_immov) != 1) + { + /* disk error, or corrupt filesystem */ + /* udata.u_error = ENXIO; */ + + goto bitmap_align_error; + } + } + + blk++; + pos++; + } + } + + /* now, if any blocks remain to be swapped, traverse the entire */ + /* filesystem to find them, updating the filesystem as we move them */ + k = devinodes(dev); + for (j = ROOTINODE; j < k; j++) + { + /* scan inode bitmap via utility routine, looking for '1' */ + j = bitmap_find(devno, j, 1, 0, dev->s_bitmap_inode, + dev->s_bitmap_block); + if (j == (blkno_t)-1) + { + /* disk i/o error, or corrupt filesystem */ + /* udata.u_error = ENXIO; */ + + goto bitmap_align_error; + } + + if (j < ROOTINODE || j >= k) + { + break; /* not found, means no more inodes to search */ + } + + other = i_open(devno, j); + if (other == NULLINO) + { + /* disk i/o error, or corrupt filesystem */ + /* udata.u_error = ENXIO; */ + + goto bitmap_align_error; + } + +#if DEBUG > 1 + kprintf("processing other inode %d\n", other->c_num); +#endif + if (other->c_node.i_mode == 0) + { + i_deref(other); + continue; /* inode bitmap is bad, try to continue */ + } + + /* check mode */ + flag = other->c_node.i_mode & S_IFMT; + if (flag != S_IFALIGN && + flag != S_IFREG && + flag != S_IFDIR && + flag != S_IFLNK && + flag != S_IFBLK && + flag != S_IFCHR) + { + i_deref(other); + continue; /* inode's mode is bad, skip it, continue */ + } + + /* check blocks */ + if (flag == S_IFALIGN || flag == S_IFREG || + flag == S_IFDIR || flag == S_IFLNK) + { + /*pos = 0;*/ + /*inc = 1;*/ + indirection = 0; + exclude = (ino == other) ? 2 : (flag == S_IFALIGN); +#if 1 /* under construction */ + for (i = ((exclude == 1) ? DIRECTBLOCKS : 0); +#else + for (i = (exclude ? DIRECTBLOCKS : 0); +#endif + i <= DIRECTBLOCKS+INDIRECTBLOCKS; i++) + { + if (i == DIRECTBLOCKS) + { + /*inc = BUFSIZE / sizeof(blkno_t);*/ + indirection = 1; + } + else if (i == DIRECTBLOCKS+INDIRECTBLOCKS) + { + /* inc doesn't matter in this case */ + indirection = 2; + } + blk = other->c_node.i_addr[i]; + if (blk == 3840) kprintf("bad @ %d,%d 0x%04x\n", other->c_num, i, &other->c_node.i_addr[i]); + if (blk) + { + pos = bitmap_align_recurse(dev, /*pos,*/ + ino, exclude, + &other->c_node.i_addr[i], + &other->c_dirty, indirection, + region, regions, blocks); + + /* move something into the freed spot, and possibly repeat */ + if (pos != (blkno_t)-1) + { + blk = bitmap_align_chase( + dev, ino, + blk, pos, + region, regions, blocks); + + if (blk == (blkno_t)-1) + { + /* disk i/o error, or corrupt filesystem */ + /* udata.u_error = ENXIO; */ + + break; /*return (blkno_t)-1;*/ + } + + /* eventually a non-target block was freed, indicate this */ + if (bitmap_set(devno, blk, 0, + dev->s_bitmap_block, + dev->s_bitmap_immov) + != 1) + { + /* disk i/o error, or corrupt filesystem */ + /* udata.u_error = ENXIO; */ + + break; /*return (blkno_t)-1;*/ /* corrupt filesystem */ + } + } + } + /*pos += inc;*/ + } + } + + i_deref(other); + } + + if (brelse((bufptr)region) < 0) + { + /* udata.u_error = something */ + +bitmap_align_error: + /* politely unreserve all regions reserved so far */ + for (i = 0; i < regions; i++) + { + /* in this case always unreserve a full sized region */ + bitmap_reserve(devno, region[i], + REGION_BLOCKS, 0, + dev->s_bitmap_immov, + dev->s_bitmap_final); + } + +#if DEBUG > 2 + kprintf("bitmap_align() returning -1 d\n"); +#endif + return -1; + } + + ino->c_node.i_mode = (ino->c_node.i_mode & ~S_IFMT) | S_IFALIGN; + ino->c_dirty = 1; + i_sync(); /* flushing inodes */ + +#if DEBUG > 2 + kprintf("bitmap_align() returning 0, success\n"); +#endif + return 0; /* successfully aligned the file */ + } + +int bitmap_ualign(inoptr ino, off_t size) + { + blkno_t i, j, pos; + blkno_t *region, regions, blocks; + fsptr dev; + dev_t devno; + +#if DEBUG > 2 + kprintf("bitmap_ualign(%u, %ld) starting\n", ino - i_tab, size); +#endif + + /* prepare to access the given inode */ + devno = ino->c_dev; + dev = getfs(devno); + + /* construct region list using subroutine shared with execve() */ + region = bitmap_examine(dev, ino, size, ®ions, &blocks); + if (region == NULL) + { +#if DEBUG > 2 + kprintf("bitmap_ualign() returning -1 a\n"); +#endif + return -1; /* error code has been setup by bitmap_examine() */ + } + + /* unreserve all regions using the list */ + pos = 0; + for (i = 0; i < regions; i++) + { + /* is this a full region, or the last partial region? */ + j = int_min(blocks - pos, REGION_BLOCKS); + + /* unreserve the required number of blocks for region */ + if (bitmap_reserve(devno, region[i], j, 0, + dev->s_bitmap_immov, + dev->s_bitmap_final)) + { + /* disk i/o error, or corrupt filesystem */ + /* udata.u_error = ENXIO */; +#if DEBUG > 2 + kprintf("bitmap_ualign() returning -1 f\n"); +#endif + return -1; + } + + pos += REGION_BLOCKS; + } + + if (brelse((bufptr)region) < 0) + { + /* udata.u_error = something */ + } + + ino->c_node.i_mode = (ino->c_node.i_mode & ~S_IFMT) | S_IFREG; + ino->c_dirty = 1; + i_sync(); /* flushing inodes */ + +#if DEBUG > 2 + kprintf("bitmap_ualign() returning 0\n"); +#endif + return 0; + } + +blkno_t *bitmap_examine(fsptr dev, inoptr ino, off_t size, + blkno_t *regioncount, blkno_t *blockcount) + { + blkno_t i, j, k; + blkno_t blk, pos, /*inc,*/ newno; + blkno_t *region, regions, blocks; + + if (dev->s_bitmap_immov >= dev->s_bitmap_final) + { + udata.u_error = ENOLCKFS; /* not a locking filesystem */ +#if DEBUG > 2 + kprintf("bitmap_examine() returning NULL a\n"); +#endif + return NULL; + } + + /* validate the filetype, it must be aligned */ + if ((ino->c_node.i_mode & S_IFMT) == S_IFREG) + { + udata.u_error = ENOALIGN; /* file is not aligned */ +#if DEBUG > 2 + kprintf("bitmap_examine() returning NULL b\n"); +#endif + return NULL; + } + if ((ino->c_node.i_mode & S_IFMT) != S_IFALIGN) + { + udata.u_error = ENOREGALIGN; /* file not regular or aligned */ +#if DEBUG > 2 + kprintf("bitmap_examine() returning NULL c\n"); +#endif + return NULL; + } + + /* ensure the region list will fit in 512 bytes */ + regions = (size + REGION_BYTES - 1) >> REGION_LOG; + if (regions > (BUFSIZE / sizeof(blkno_t))) + { + udata.u_error = ENOSPC; /* size specified is too large */ +#if DEBUG > 2 + kprintf("bitmap_examine() returning NULL c\n"); +#endif + return NULL; + } + + /* ready to allocate the region list */ + region = (blkno_t *)tmpbuf(); + + /* calculate size in blocks, to resolve size of last region */ + blocks = (size + BUFSIZE - 1) >> BUFSIZELOG; + + /* find each region's existing physical memory address */ + pos = 0; + for (i = 0; i < regions; i++) + { + /* is this a full region, or the last partial region? */ + k = int_min(blocks - pos, REGION_BLOCKS); + + /* first block must be aligned, save its position in list */ + blk = bmap(ino, pos, 1); + if ((blk & (PAGE_BLOCKS-1)) || blk == NULLBLK) + { + udata.u_error = ENOALIGN; /* alignment bad */ +#if DEBUG > 2 + kprintf("bitmap_examine() returning NULL d\n"); +#endif + return NULL; + } + region[i] = blk; + pos++; + + /* try to find and skip contiguous aligned blocks */ + for (j = 1; j < k; j++) + { + blk++; + newno = bmap(ino, pos, 1); + if (newno != blk) /*|| newno == NULLBLK)*/ + { + udata.u_error = ENOALIGN; /* alignment bad */ +#if DEBUG > 2 + kprintf("bitmap_examine() returning NULL e\n"); +#endif + return NULL; + } + pos++; + } + } + + *regioncount = regions; + *blockcount = blocks; + return region; + } + +blkno_t bitmap_align_chase(fsptr dev, inoptr ino, blkno_t blk, blkno_t pos, + blkno_t *region, blkno_t regions, + blkno_t blocks) + { + int i, occupied; + bufptr buf, other; + + /* check we have been passed a valid block number */ + if (blk < (dev->s_reserv + dev->s_isize) || blk >= dev->s_fsize) + { + udata.u_error = ECORRUPTFS; +#if DEBUG > 0 + kprintf("bitmap_align_chase() 1 ino = %d, blk = %d, pos = %d\n", + ino->c_num, blk, pos); +#endif + return (blkno_t)-1; /* filesystem is corrupt */ + } + + /* infinite loop to chase the just-freed block around the file */ + while (1) + { + /* find corresponding block in allocation table for ino */ + blk = bitmap_align_bmap(ino, blk, pos); + if (blk == (blkno_t)-1) + { + /* udata.u_error = ETOOSHORT; */ + return (blkno_t)-1; /* file is too short, or hole */ + } + + /* check we have been passed a valid block number */ + if (blk < (dev->s_reserv + dev->s_isize) || + blk >= dev->s_fsize) + { + udata.u_error = ECORRUPTFS; +#if DEBUG > 0 + kprintf("bitmap_align_chase() 2 ino = %d, blk = %d, pos = %d\n", + ino->c_num, blk, pos); +#endif + return (blkno_t)-1; /* filesystem is corrupt */ + } + + /* see if the just-freed block was part of the target file */ + pos = bitmap_align_reverse(blk, region, regions, blocks); + if (pos == (blkno_t)-1) + { + return blk; /* success, return the just-freed block */ + } + + /* yes, we can move something into the just-freed block */ + } + } + +blkno_t bitmap_align_bmap(inoptr ino, blkno_t newno, blkno_t pos) + { + dev_t devno; + int i, j, sh; + blkno_t blk; + bufptr buf, other; + +#if DEBUG > 2 + kprintf("bitmap_align_bmap(%u, %u) starting\n", ino - i_tab, pos); +#endif + + devno = ino->c_dev; + /* blocks 0..DIRECTBLOCKS-1 are direct blocks */ + if (pos < DIRECTBLOCKS) + { + blk = ino->c_node.i_addr[pos]; + if (blk == 0) + { + goto Err; + } + ino->c_node.i_addr[pos] = newno; /* move the block! */ + ino->c_dirty = 1; + goto Ok; + } + /* addresses DIRECTBLOCKS and DIRECTBLOCKS+1 have single and double + * indirect blocks. + * The first step is to determine how many levels of indirection. + */ + pos -= DIRECTBLOCKS; + sh = 0; + j = INDIRECTBLOCKS+DINDIRECTBLOCKS; + if (pos >= BUFSIZE / sizeof(blkno_t)) /* double indirect */ + { + sh = 8; /* shift by 8 */ + pos -= BUFSIZE / sizeof(blkno_t); + j -= INDIRECTBLOCKS; + } + /* fetch the address from the inode. + * Create the first indirect block if needed. + */ + blk = ino->c_node.i_addr[TOTALREFBLOCKS - j]; + if (blk == 0) + { + udata.u_error = ETOOSHORT; /* hole in file */ + goto Err; + } + /* fetch through the indirect blocks */ + while (j < INDIRECTBLOCKS+DINDIRECTBLOCKS) /* Nick <= */ + { + buf = (bufptr)bread(devno, blk, 0); + if (buf == NULL) + { + goto Err; + } + i = (pos >> sh) & (BUFSIZE / sizeof(blkno_t) - 1); + blk = ((blkno_t *)buf)[i]; + if (brelse(buf) < 0) + { + goto Err; + } + if (blk == 0) + { + udata.u_error = ETOOSHORT; /* hole in file */ + goto Err; + } + sh -= 8; + ++j; + } + + buf = (bufptr)bread(devno, blk, 0); + if (buf == NULL) + { +Err: +#if DEBUG > 2 + kprintf("bitmap_align_bmap() returning -1, error %u\n", udata.u_error); +#endif + return (blkno_t)-1; + } + i = (pos >> sh) & (BUFSIZE / sizeof(blkno_t) - 1); + blk = ((blkno_t *)buf)[i]; + if (blk == 0) + { + udata.u_error = ETOOSHORT; /* hole in file */ + brelse(buf); + goto Err; + } + ((blkno_t *)buf)[i] = newno; /* move the block! */ + if (bawrite(buf) < 0) + { + goto Err; + } +Ok: + /* read the block, as we have to move the data also */ + buf = (bufptr)bread(devno, blk, 0); + if (buf == NULL) + { + goto Err; + } + +#if DEBUG > 2 + kprintf("getting block %d -> %d, errno = %d\n", blk, newno, udata.u_error); +#endif + + /* really move the block by manipulating cache entries */ + other = (bufptr)bfind(devno, newno); /* hanging around in cache? */ + if (other) + { +/* kprintf("bufpool entry %d = block %d, dirty 0\n", other - bufpool, blk); */ + other->bf_blk = blk; /* swap, for minimal overhead */ + other->bf_dirty = 0; /* try to avoid writing back */ + } + + /* revise the original cache entry to show the new block */ + buf->bf_blk = newno; /* original value is in variable blk */ +/* kprintf("bufpool entry %d = block %d, dirty 1\n", buf - bufpool, newno); */ + if (bawrite(buf) < 0) /* dirty, but delay writing for the moment */ + { + goto Err; + } + +#if DEBUG > 2 + kprintf("bitmap_align_bmap() returning %u, success\n", blk); +#endif + return blk; +} + +blkno_t bitmap_align_reverse(blkno_t blk, + blkno_t *region, blkno_t regions, blkno_t blocks) + { + blkno_t i, k; + blkno_t pos; + +#if DEBUG > 2 + kprintf("bitmap_align_reverse(%u) starting\n", blk); +#endif + + /* perform a reverse lookup of blk via the region list */ + pos = 0; + for (i = 0; i < regions; i++) + { + /* is this a full region, or the last partial region? */ + k = int_min(blocks - pos, REGION_BLOCKS); + + /* see if the given blk falls within this region */ + if (blk >= region[i] && blk < (region[i] + k)) + { + /* yes, return the computed logical pos in file */ + pos += blk - region[i]; +#if DEBUG > 2 + kprintf("bitmap_align_reverse() returning %u, found\n", pos); +#endif + return pos; + } + + /* calculate file position for start of next region */ + pos += REGION_BLOCKS; + } + + /* the given blk was not found in any region of the list */ +#if DEBUG > 2 + kprintf("bitmap_align_reverse() returning -1, not found\n"); +#endif + return -1; + } + +blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, + blkno_t *parent, char *dirty, + int indirection, blkno_t *region, + blkno_t regions, blkno_t blocks) + { + dev_t devno; + int i, reserved; + blkno_t blk, newno; + bufptr buf, other; + int moveable; + blkno_t tempblk; + char tempdirty; + blkno_t pos, chase; + + /* check we have been passed a valid block number */ + blk = *parent; + if (blk < (dev->s_reserv + dev->s_isize) || blk >= dev->s_fsize) + { + /* filesystem is corrupt, invalid block */ + udata.u_error = ECORRUPTFS; +#if DEBUG > 0 + kprintf("bitmap_align_recurse() ino = %d, blk = %d, ind = %d, par = 0x%04x\n", + ino->c_num, blk, indirection, parent); +#endif + return (blkno_t)-1; + } + + /* see if this block is intended for the target file */ +#if 0 /* not possible, see "exclude ? DIRECTBLOCKS : 0" above */ + if (exclude && indirection == 0) + { + /* it's some other aligned file on the drive */ + moveable = 0; + } + else +#endif +#if 0 /* under construction */ + if (exclude == 2 && indirection == 0) + { + /* it's the target file */ + chase = bitmap_align_reverse(blk, region, regions, blocks); + moveable = (chase != (blkno_t)-1); + } + else +#endif + { + chase = bitmap_align_reverse(blk, region, regions, blocks); + moveable = (chase != (blkno_t)-1); + } + + /* early out, if the block doesn't need to be accessed at all */ + if (moveable == 0 && indirection == 0) + { + /* no action is needed (no move and not indirect) */ + return (blkno_t)-1; + } + + /* need to read the block, we might modify it, and/or relocate it */ + devno = dev->s_dev; /* don't forget! */ + buf = (bufptr)bread(devno, blk, 0); + if (buf == NULL) + { + return (blkno_t)-1; /* disk i/o error reading the block itself */ + } + + /* if it's a single or double indirect block, traverse recursively */ +#if 1 /* under construction */ + if (indirection && (exclude != 1 || indirection > 1)) +#else + if (indirection && (exclude == 0 || indirection > 1)) +#endif + { +#if 0 /* silly silly */ + if (indirection > 1) + { + newno = BUFSIZE / sizeof(blkno_t); /* double ind. */ + } + else + { + newno = 1; /* single indirect */ + } +#endif + for (i = 0; i < BUFSIZE / sizeof(blkno_t); i++) + { + newno = ((blkno_t *)buf)[i]; + if (newno == 3840) kprintf("bad # %d,%d 0x%04x\n", buf->bf_blk, i, &((blkno_t *)buf)[i]); + if (newno) + { + if (exclude == 2) /* it's the target file */ + { + tempblk = newno; + tempdirty = 0; + + if (bfree(buf, buf->bf_dirty) < 0) + { + return (blkno_t)-1; /* disk i/o error */ + } + + pos = bitmap_align_recurse(dev, /*pos,*/ + ino, exclude, + &tempblk, &tempdirty, + indirection-1, + region, regions, blocks); + + buf = (bufptr)bread(devno, blk, 0); + if (buf == NULL) + { + return (blkno_t)-1; /* disk i/o error */ + } + + if (tempdirty) + { + ((blkno_t *)buf)[i] = tempblk; + buf->bf_dirty = tempdirty; + } + } + else + { + pos = bitmap_align_recurse(dev, /*pos,*/ + ino, exclude, + &((blkno_t *)buf)[i], + &buf->bf_dirty, indirection-1, + region, regions, blocks); + } + + /* move something into the freed spot, and possibly repeat */ + if (pos != (blkno_t)-1) + { + if (exclude == 2) + { + if (bfree(buf, buf->bf_dirty) < 0) + { + return (blkno_t)-1; /* disk i/o error */ + } + } + + newno = bitmap_align_chase(dev, ino, + newno, pos, + region, regions, blocks); + + if (exclude == 2) + { + buf = (bufptr)bread(devno, blk, 0); + if (buf == NULL) + { + return (blkno_t)-1; /* disk i/o error */ + } + } + + if (newno == (blkno_t)-1) + { + return (blkno_t)-1; + } + + /* eventually a non-target block was freed, indicate this */ + if (bitmap_set(devno, newno, 0, + dev->s_bitmap_block, + dev->s_bitmap_immov) != 1) + { + /* i/o error, or corrupt filesystem */ + return (blkno_t)-1; + } + } + } + /*pos += newno;*/ + } + } + + /* if this block is in the way of the target file, move it */ + if (moveable) + { + /* find an unoccupied block (fixme: can't be reserved) */ + newno = bitmap_find(devno, 0, 0, 1, dev->s_bitmap_block, + dev->s_bitmap_immov); + if (newno < (dev->s_reserv + dev->s_isize) || + newno >= dev->s_fsize) + { + udata.u_error = ENOSPC; /* may overwrite ENXIO !! */ + return (blkno_t)-1; + } + + /* revise parent's allocation entry to show the new block */ + *parent = newno; + + /* inform parent that its allocation entries were changed */ + *dirty = 1; + +#if DEBUG > 2 + kprintf("putting block %d -> %d, errno = %d\n", blk, newno, udata.u_error); +#endif + + /* really move the block by manipulating cache entries */ + other = (bufptr)bfind(devno, newno); /* hanging around in cache? */ + if (other) + { +/* kprintf("bufpool entry %d = block %d, dirty 0\n", other - bufpool, blk); */ + other->bf_blk = blk; /* swap, for minimal overhead */ + other->bf_dirty = 0; /* try to avoid writing back */ + } + + /* revise the original cache entry to show the new block */ +/* kprintf("bufpool entry %d = block %d, dirty 2\n", buf - bufpool, newno); */ + buf->bf_blk = newno; /* original value is in variable blk */ + if (bfree(buf, 2) < 0) /* very dirty, write back immediately */ + { + return (blkno_t)-1; /* disk i/o error writing back */ + } + + return chase; /* indicate which spot was just freed */ + } + else + { + if (bfree(buf, buf->bf_dirty) < 0) + { + return (blkno_t)-1; /* disk i/o error writing back */ + } + } + + return (blkno_t)-1; /* successfully traversed the block and its children */ + } + +blkno_t bitmap_search(dev_t devno, int size, blkno_t start, blkno_t final) + { + char *buf, *p; + blkno_t i, j, lm, blk; + unsigned long bits, mask; /* assumes REGION_BLOCKS <= 32 */ + +#if DEBUG > 2 + kprintf("bitmap_search(%u, %d, %u, %u) starting\n", + devno, size, start, final); +#endif + +#if REGION_BLOCKS < 32 + /* validate the size parameter for extra safety */ + if (size < 1 || size > REGION_BLOCKS) + { + return (blkno_t)-1; /* should indicate parameter error */ + } + + /* form a bitstring of the needed size, for testing bitmap */ + mask = (1L << size) - 1; +#else + /* validate the size parameter for extra safety */ + if (size < 1 || size > 32) /* REGION_BLOCKS > 32 bombs at runtime */ + { + return (blkno_t)-1; /* should indicate parameter error */ + } + + /* form a bitstring of the needed size, for testing bitmap */ + if (size < 32) + { + mask = (1L << size) - 1; + } + else + { + mask = (unsigned long)-1; /* size is maximum 32 */ + } +#endif + + /* initialise bitbuffer, we need it to span bitmap blocks */ + bits = (unsigned long)-1; + + /* read bitmap, skipping unused bytes of reserved blocks */ + j = start; + while (j < final) + { + /* calculate ending position after reading block */ + lm = int_min((j + BUFSIZE) & ~(BUFSIZE - 1), final); + + /* read block and calculate starting relevant byte */ + buf = bread(devno, j >> BUFSIZELOG, 0); + if (buf == NULL) + { +#if DEBUG > 2 + kprintf("bitmap_search() returning -1, i/o error\n"); +#endif + return (blkno_t)-1; /* should indicate i/o error */ + } + p = buf + (j & (BUFSIZE - 1)); + + /* ready to scan each byte looking for contiguous '0' bits */ + for (i = j; i < lm; i += (PAGE_BLOCKS >> 3)) /* can't be 0 ! */ + { + bits = (bits >> PAGE_BLOCKS) | + (((unsigned long)*p) << (32 - PAGE_BLOCKS)); + + if ((bits & mask) == 0) + { + /* all of the required blocks are unlocked */ + + /* calculate which disk block it refers to */ + blk = ((i - start) << 3) - (32 - PAGE_BLOCKS); + + /* don't write it back, our caller will */ + if (brelse((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_search() returning -1, i/o error\n"); +#endif + return (blkno_t)-1; + } + +#if DEBUG > 2 + kprintf("bitmap_search() returning %u, success\n", blk); +#endif + return blk; + } + + p += PAGE_BLOCKS >> 3; /* can't be 0 */ + } + + /* nothing found this time, release block and loop */ + if (brelse((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_search() returning -1, i/o error\n"); +#endif + return (blkno_t)-1; + } + + /* bump counter to continue after data just read */ + j = lm; + } + + /* no '0' string found within the bitmap limits */ +#if DEBUG > 2 + kprintf("bitmap_search() returning -1, bitmap full\n"); +#endif + return (blkno_t)-1; /* not an error, bitmap was really full */ + } + +int bitmap_reserve(dev_t devno, blkno_t blk, int size, int flag, + blkno_t start, blkno_t final) + { + blkno_t i, j, lm; + char *buf, *p, mask; + +#if DEBUG > 2 + kprintf("bitmap_reserve(%u, %u, %d, %d, %u, %u) starting\n", + devno, blk, size, flag, start, final); +#endif + + /* calculate byte position within bitmap for this block */ + j = start + (blk >> 3); + if (j >= final) + { +#if DEBUG > 2 + kprintf("bitmap_reserve() returning -1, out of range\n"); +#endif + return -1; /* block out of range, very bad */ + } + + /* read block and calculate starting relevant byte */ + buf = bread(devno, j >> BUFSIZELOG, 0); + if (buf == NULL) + { +#if DEBUG > 2 + kprintf("bitmap_reserve() returning -1, i/o error\n"); +#endif + return -1; /* should indicate i/o error */ + } + p = buf + (j & (BUFSIZE - 1)); + + /* calculate ending position after reading block */ + lm = int_min((j + BUFSIZE) & ~(BUFSIZE - 1), final); + + /* ready to modify the required bits and write back */ + mask = flag ? 0xff : 0; + while (size > 8) + { + *p++ = mask; + + j++; + if (j >= lm) + { + /* gone past the end of the current bitmap block */ + if (j >= final) + { +#if DEBUG > 2 + kprintf("bitmap_reserve() returning -1, out of range\n"); +#endif + return -1; /* out of range */ + } + + /* need to flush the modifications done so far */ + if (bawrite((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_reserve() returning -1, i/o error\n"); +#endif + return -1; /* i/o error */ + } + + /* read next block, we always start at the beginning */ + buf = bread(devno, j >> BUFSIZELOG, 0); + if (buf == NULL) + { +#if DEBUG > 2 + kprintf("bitmap_reserve() returning -1, i/o error\n"); +#endif + return -1; /* i/o error */ + } + p = buf; + + /* calculate ending position after reading block */ + lm = int_min((j + BUFSIZE) & ~(BUFSIZE - 1), final); + } + + size -= 8; + } + + /* done all bitmap bytes, except the last (maybe partial) byte */ + mask = (1 << size) - 1; + if (flag) + { + *p |= mask; + } + else + { + *p &= ~mask; + } + + /* ready to write back the modified bitmap block */ + if (bawrite((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_reserve() returning -1, i/o error\n"); +#endif + return -1; /* should indicate i/o error */ + } + +#if DEBUG > 2 + kprintf("bitmap_reserve() returning 0, success\n"); +#endif + return 0; + } + +blkno_t bitmap_find(dev_t devno, blkno_t blk, int flag, int toggle, + blkno_t start, blkno_t final) + { + char c, first; + char *buf, *p, mask; + blkno_t i, j, lm; + +#if DEBUG > 2 + kprintf("bitmap_find(%u, %u, %d, %d, %u, %u) starting\n", + devno, blk, flag, toggle, start, final); +#endif + + /* set up to skip byte sized groups having opposite value */ + mask = flag ? 0 : 0xff; + + /* prepare to handle the first byte of the bitmap specially */ + first = ~((1 << (blk & 7)) - 1); + + /* read bitmap, skipping unused bytes of reserved blocks */ + j = start + (blk >> 3); + while (j < final) + { + /* calculate ending position after reading block */ + lm = int_min((j + BUFSIZE) & ~(BUFSIZE - 1), final); + + /* read block and calculate starting relevant byte */ + buf = bread(devno, j >> BUFSIZELOG, 0); + if (buf == NULL) + { +#if DEBUG > 2 + kprintf("bitmap_find() returning -1, i/o error\n"); +#endif + return (blkno_t)-1; /* should indicate i/o error */ + } + p = buf + (j & (BUFSIZE - 1)); + + /* ready to scan each byte looking for a bit of 'flag' */ + for (i = j; i < lm; i++) + { + c = (*p ^ mask) & first; /* set bits being sought */ + first = 0xff; /* process full bytes from now on */ + + if (c) + { + /* at least one of the 8 blocks is available */ + + /* calculate which disk block it refers to */ + blk = (i - start) << 3; + for (i = 0; i < 7; i++) /* don't check bit 7 */ + { + if (c & (1 << i)) + { + break; + } + } + blk += i; + + if (toggle) + { + /* ready to toggle and write back */ + *p ^= 1 << i; + if (bawrite((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_find() returning -1, i/o error\n"); +#endif + return (blkno_t)-1; /* i/o */ + } + } + else + { + if (brelse((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_find() returning -1, i/o error\n"); +#endif + return (blkno_t)-1; /* i/o */ + } + } + +#if DEBUG > 2 + kprintf("bitmap_find() returning %u, success\n", blk); +#endif + return blk; + } + + p++; + } + + /* nothing found this time, release block and loop */ + if (brelse((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_find() returning -1, i/o error\n"); +#endif + return (blkno_t)-1; + } + + /* bump counter to continue after data just read */ + j = lm; + } + + /* no 'flag' bit found within the bitmap limits */ + blk = (j - start) << 3; +#if DEBUG > 2 + kprintf("bitmap_find() returning %u, bitmap full\n", blk); +#endif + return blk; /* not an error, bitmap was really full */ + } + +int bitmap_get(dev_t devno, blkno_t blk, blkno_t start, blkno_t final) + { + blkno_t i, j; + char *buf, *p; + +#if DEBUG > 2 + kprintf("bitmap_get(%u, %u, %u, %u) starting\n", devno, blk, start, final); +#endif + + /* calculate byte position within bitmap for this block */ + j = start + (blk >> 3); + if (j >= final) + { +#if DEBUG > 2 + kprintf("bitmap_get() returning -1, out of range\n"); +#endif + return -1; /* block out of range, very bad */ + } + i = 1 << (blk & 7); + + /* read block and calculate starting relevant byte */ + buf = bread(devno, j >> BUFSIZELOG, 0); + if (buf == NULL) + { +#if DEBUG > 2 + kprintf("bitmap_get() returning -1, i/o error\n"); +#endif + return -1; /* should indicate i/o error */ + } + p = buf + (j & (BUFSIZE - 1)); + + /* check if the block is free or used (value of 0 or 1) */ + i = ((*p & i) != 0); + + if (brelse((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_get() returning -1, i/o error\n"); +#endif + return -1; + } + +#if DEBUG > 2 + kprintf("bitmap_get() returning %d, success\n", i); +#endif + return i; + } + +int bitmap_set(dev_t devno, blkno_t blk, int flag, + blkno_t start, blkno_t final) + { + blkno_t i, j; + char *buf, *p, mask; + +#if DEBUG > 2 + kprintf("bitmap_set(%u, %u, %d, %u, %u) starting\n", + devno, blk, flag, start, final); +#endif + + /* calculate byte position within bitmap for this block */ + j = start + (blk >> 3); + if (j >= final) + { +#if DEBUG > 2 + kprintf("bitmap_set() returning -1, out of range\n"); +#endif + return -1; /* block out of range, very bad */ + } + mask = 1 << (blk & 7); + + /* read block and calculate starting relevant byte */ + buf = bread(devno, j >> BUFSIZELOG, 0); + if (buf == NULL) + { +#if DEBUG > 2 + kprintf("bitmap_set() returning -1, i/o error\n"); +#endif + return -1; /* should indicate i/o error */ + } + p = buf + (j & (BUFSIZE - 1)); + + /* find the desired and the original values of the bit */ + i = (flag != 0); + j = ((*p & mask) != 0); + + /* ready to modify the bit and write back (if necessary) */ + if (i != j) + { + *p ^= mask; + if (bawrite((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_set() returning -1, i/o error\n"); +#endif + return -1; /* should indicate i/o error */ + } + } + else + { + if (brelse((bufptr)buf) < 0) + { +#if DEBUG > 2 + kprintf("bitmap_set() returning -1, i/o error\n"); +#endif + return -1; /* should indicate i/o error */ + } + } + +#if DEBUG > 2 + kprintf("bitmap_set() returning %d, success\n", j); +#endif + return j; + } + diff --git a/src/kernel/uzi/xip.h b/src/kernel/uzi/xip.h new file mode 100755 index 00000000..75a49700 --- /dev/null +++ b/src/kernel/uzi/xip.h @@ -0,0 +1,30 @@ +/* xip.h for UZI180 by Nick (we are converting everything to ANSI C) */ + +#ifndef __XIP_H +#define __XIP_H + +int bitmap_align(inoptr ino, off_t size); +int bitmap_ualign(inoptr ino, off_t size); +blkno_t *bitmap_examine(fsptr dev, inoptr ino, off_t size, + blkno_t *regioncount, blkno_t *blockcount); +blkno_t bitmap_align_chase(fsptr dev, inoptr ino, blkno_t blk, blkno_t pos, + blkno_t *region, blkno_t regions, + blkno_t blocks); +blkno_t bitmap_align_bmap(inoptr ino, blkno_t newno, blkno_t pos); +blkno_t bitmap_align_reverse(blkno_t blk, + blkno_t *region, blkno_t regions, blkno_t blocks); +blkno_t bitmap_align_recurse(fsptr dev, inoptr ino, int exclude, + blkno_t *parent, char *dirty, + int indirection, blkno_t *region, + blkno_t regions, blkno_t blocks); +blkno_t bitmap_search(dev_t devno, int size, blkno_t start, blkno_t final); +int bitmap_reserve(dev_t devno, blkno_t blk, int size, int flag, + blkno_t start, blkno_t final); +blkno_t bitmap_find(dev_t devno, blkno_t blk, int flag, int toggle, + blkno_t start, blkno_t final); +int bitmap_get(dev_t devno, blkno_t blk, blkno_t start, blkno_t final); +int bitmap_set(dev_t devno, blkno_t blk, int flag, + blkno_t start, blkno_t final); + +#endif /* __XIP_H */ + diff --git a/src/kernel/uzi/z180.inc b/src/kernel/uzi/z180.inc new file mode 100755 index 00000000..29852d9c --- /dev/null +++ b/src/kernel/uzi/z180.inc @@ -0,0 +1,88 @@ +; Z180 Register Mnemonics + +CNTLA0 EQU 00H ; ASCI Control Reg A Ch 0 +CNTLA1 EQU 01H ; ASCI Control Reg A Ch 1 +CNTLB0 EQU 02H ; ASCI Control Reg B Ch 0 +CNTLB1 EQU 03H ; ASCI Control Reg B Ch 1 +STAT0 EQU 04H ; ASCI Status Reg Ch 0 +STAT1 EQU 05H ; ASCI Status Reg Ch 1 +TDR0 EQU 06H ; ASCI Tx Data Reg Ch 0 +TDR1 EQU 07H ; ASCI Tx Data Reg Ch 1 +RDR0 EQU 08H ; ASCI Rx Data Reg Ch 0 +RDR1 EQU 09H ; ASCI Rx Data Reg Ch 1 + +CNTR EQU 0AH ; CSI/O Control Reg +TRDR EQU 0DH ; CSI/O Tx/Rx Data Reg + +TMDR0L EQU 0CH ; Timer Data Reg Ch0-Low +TMDR0H EQU 0DH ; Timer Data Reg Ch0-High +RLDR0L EQU 0EH ; Timer Reload Reg Ch0-Low +RLDR0H EQU 0FH ; Timer Reload Reg Ch0-High +TCR EQU 10H ; Timer Control Reg +TMDR1L EQU 14H ; Timer Data Reg Ch1-Low +TMDR1H EQU 15H ; Timer Data Reg Ch1-High +RLDR1L EQU 16H ; Timer Reload Reg Ch1-Low +RLDR1H EQU 17H ; Timer Reload Reg Ch1-High +FRC EQU 18H ; Free-Running Counter + +CCR EQU 1FH ; CPU Control Reg (Z8S180 & higher Only) + +SAR0L EQU 20H ; DMA Source Addr Reg Ch0-Low +SAR0H EQU 21H ; DMA Source Addr Reg Ch0-High +SAR0B EQU 22H ; DMA Source Addr Reg Ch0-Bank +DAR0L EQU 23H ; DMA Dest Addr Reg Ch0-Low +DAR0H EQU 24H ; DMA Dest Addr Reg Ch0-High +DAR0B EQU 25H ; DMA Dest ADDR REG CH0-Bank +BCR0L EQU 26H ; DMA Byte Count Reg Ch0-Low +BCR0H EQU 27H ; DMA Byte Count Reg Ch0-High +MAR1L EQU 28H ; DMA Memory Addr Reg Ch1-Low +MAR1H EQU 29H ; DMA Memory Addr Reg Ch1-High +MAR1B EQU 2AH ; DMA Memory Addr Reg Ch1-Bank +IAR1L EQU 2BH ; DMA I/O Addr Reg Ch1-Low +IAR1H EQU 2CH ; DMA I/O Addr Reg Ch2-High +BCR1L EQU 2EH ; DMA Byte Count Reg Ch1-Low +BCR1H EQU 2FH ; DMA Byte Count Reg Ch1-High +DSTAT EQU 30H ; DMA Status Reg +DMODE EQU 31H ; DMA Mode Reg +DCNTL EQU 32H ; DMA/Wait Control Reg + +IL EQU 33H ; INT Vector Low Reg +ITC EQU 34H ; INT/TRAP Control Reg +RCR EQU 36H ; Refresh Control Reg +CBR EQU 38H ; MMU Common Base Reg +BBR EQU 39H ; MMU Bank Base Reg +CBAR EQU 3AH ; MMU COmmon/Bank Area Reg +OMCR EQU 3EH ; Operation Mode Control Reg +ICR EQU 3FH ; I/O Control Reg + +; Z182 Additional Registers (uncomment to define) + +;BRK0 EQU 12H ; Break Control Reg Ch 0 +;BRK1 EQU 13H ; Break Control Reg Ch 1 + +;INTTYPE EQU 0DFH ; Interrupt Edge/Pin MUX Reg +;WSGCS EQU 0D8H ; Wait-State Generator Chip Select +;ENH182 EQU 0D9H ; Z80182 Enhancements Reg +;PINMUX EQU 0DFH ; Interrupt Edge/Pin MUX Reg +;RAMUBR EQU 0E6H ; RAM End Boundary +;RAMLBR EQU 0E7H ; RAM Start Boundary +;ROMBR EQU 0E8H ; ROM Boundary +;FIFOCTL EQU 0E9H ; FIFO Control Reg +;RTOTC EQU 0EAH ; Rx Time-Out Time Constant +;TTOTC EQU 0EBH ; Tx Time-Out Time Constant +;FCR EQU 0ECH ; FIFO Register +;SCR EQU 0EFH ; System Pin Control +; (MIMIC Registers occupy 0F0-0FFH if used) + +;DDRA EQU 0EDH ; PIO Direction Reg Port A +;DRA EQU 0EEH ; PIO Data Port A +;DDRB EQU 0E4H ; PIO Direction Reg Port B +;DRB EQU 0E5H ; PIO Data Port B +;DDRC EQU 0DDH ; PIO Direction Reg Port C +;DRC EQU 0DEH ; PIO Data Port C + +;SCCACNT EQU 0E0H ; ESCC Control Channel A +;SCCAD EQU 0E1H ; ESCC Data Channel A +;SCCBCNT EQU 0E2H ; ESCC Control Channel B +;SCCBD EQU 0E3H ; ESCC Data Channel B + diff --git a/src/libc/!readme! b/src/libc/!readme! new file mode 100755 index 00000000..3bd82101 --- /dev/null +++ b/src/libc/!readme! @@ -0,0 +1,410 @@ +UZIX standard library + +The assembly sources standard library of the CPM Hitech-C compiler and adapted +to the UZIX operating system. All library sources from CPM Hitech-C compiler +(and also the compiler itself) were released into public domain by Hitech +Software (see below). + +regexp.c and regsub.c have their own license (see below). + +All the other files are released under GNU GPL license (see below). + +--------------------------------------------------------------------------- + +The HI-TECH Z80 CP/M C compiler V3.09 is provided free of charge for any +use, private or commercial, strictly as-is. No warranty or product +support is offered or implied. + +You may use this software for whatever you like, providing you acknowledge +that the copyright to this software remains with HI-TECH Software. + +The software is distributed in three archive files: + +Z80V309.EXE is a self-extracting lharc'ed archive containing the +entire compiler except for the library source code. + +LIBSRC.EXE is a self-extracting lharc'ed archive containg the library +source code. + +Z80DOC.EXE is a self-extracting lharc'ed archive containing a manual +for the Z80 CP/M compiler. + +To de-archive these files you will need to either run them on a DOS +system, in which case they will self-extract, or use the LHARC program +to extract. LHARC is available for unix as well as DOS. + +HI-TECH Software supplies a range of C cross compilers, as commercial +products, for several embedded microprocessors, including the Z80. + +For more information on our cross compilers, contact: + +HI-TECH Software +PO Box 103 ALDERLEY QLD 4051 AUSTRALIA +Ph. +61 7 300 5011 Fax +61 7 300 5246 +E-Mail: hitech@hitech.com.au + +--------------------------------------------------------------------------- + + Copyright (c) 1986 by University of Toronto. + Written by Henry Spencer. Not derived from licensed software. + + Permission is granted to anyone to use this software for any + purpose on any computer system, and to redistribute it freely, + subject to the following restrictions: + + 1. The author is not responsible for the consequences of use of + this software, no matter how awful, even if they arise + from defects in it. + + 2. The origin of this software must not be misrepresented, either + by explicit claim or by omission. + + 3. Altered versions must be plainly marked as such, and must not + be misrepresented as being the original software. + +------------------------------------------------------------------------------ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +------------------------------------------------------------------------------ + + \ No newline at end of file diff --git a/src/libc/N9.PMM b/src/libc/N9.PMM new file mode 100755 index 00000000..996cc66a --- /dev/null +++ b/src/libc/N9.PMM @@ -0,0 +1,9 @@ +; n9.pmm + +; converts n.bat files from tcc compilation to iar compilation + +ctcc -mt -O -Ziccz80 -S -w -mb -v1 -z -A -Ic:\iar\ew23\z80\inc\ +c-c  t l-m #bm bg i -l  bg -c.c -c.c l + +;ctlib libc +insert-modules libc.r01  c.obj.r01 + diff --git a/src/libc/T b/src/libc/T new file mode 100755 index 00000000..826490db --- /dev/null +++ b/src/libc/T @@ -0,0 +1 @@ +t 7l #bc bg -uc -ml  -mb  uc..\..\relcl..\..\relcb 2l diff --git a/src/libc/abort.c b/src/libc/abort.c new file mode 100755 index 00000000..7a6c8ac1 --- /dev/null +++ b/src/libc/abort.c @@ -0,0 +1,16 @@ +/* + */ +#include +#include +#include +#include + +void abort(void) { + signal(SIGABRT, SIG_DFL); + kill(SIGABRT, getpid()); /* Correct one */ + pause(); /* System may just schedule */ + signal(SIGKILL, SIG_DFL); + kill(SIGKILL, getpid()); /* Can't trap this! */ + _exit(255); /* WHAT!! */ +} + \ No newline at end of file diff --git a/src/libc/alloca-l.h b/src/libc/alloca-l.h new file mode 100755 index 00000000..6563f7bd --- /dev/null +++ b/src/libc/alloca-l.h @@ -0,0 +1,55 @@ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + * + * This is a combined alloca/malloc package. It uses a classic algorithm + * and so may be seen to be quite slow compared to more modern routines + * with 'nasty' distributions. + */ +#include +#include +#include +#include +#include + +#define __MINI_MALLOC__ + +#define MCHUNK 512 /* Allocation unit in 'mem' elements */ +/*#define LAZY_FREE /* If set frees can be infinitly defered */ +/*#define MINALLOC 32 /* Smallest chunk to alloc in 'mem's */ +#define VERBOSE /* Lots of noise, debuging ? */ + +#ifdef MAKE_ALL +#define L_malloc +#define L_free +#define L_alloca +#define L_calloc +#define L_realloc +#endif + +#undef malloc +#define MAX_INT ((int)(((unsigned)-1)>>1)) + +#ifdef VERBOSE +#define noise __noise +#else +#define noise(y,x) +#endif + +typedef struct mem_cell { + struct mem_cell *next; /* A pointer to the next mem */ + unsigned int size; /* An int >= sizeof pointer */ + char *depth; /* For the alloca hack */ +} mem; + +#define m_size(p) ((p)[0].size) /* For malloc */ +#define m_next(p) ((p)[0].next) /* For malloc and alloca */ +#define m_deep(p) ((p)[0].depth) /* For alloca */ +#define m_add(x,y) (mem *)((uchar *)x + y) /* Sum mem* with y bytes */ + +#if 0 /* Nick */ +extern void *__mini_malloc __P((size_t)); +extern void *(*__alloca_alloc) __P((size_t)); +extern mem *__freed_list; +#endif + diff --git a/src/libc/alloca.c b/src/libc/alloca.c new file mode 100755 index 00000000..d0d20130 --- /dev/null +++ b/src/libc/alloca.c @@ -0,0 +1,53 @@ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + * + * This is a combined alloca/malloc package. It uses a classic algorithm + * and so may be seen to be quite slow compared to more modern routines + * with 'nasty' distributions. + */ + +#if 1 /* Nick */ +#include "alloca-l.h" +#else +#include "malloc-l.h" +#endif + +#ifdef L_alloca +static mem *alloca_stack = 0; + +void *alloca(size) + size_t size; +{ + auto char probe; /* Probes stack depth: */ + register mem *hp, *np; + + /* Reclaim garbage, defined as all alloca'd storage that was allocated + * from deeper in the stack than currently. + */ + hp = alloca_stack; + while (hp != 0) { + if (m_deep(hp) < &probe) { + np = m_next(hp); + free(hp); /* Collect garbage */ + hp = np; /* -> next header */ + } + else break; /* Rest are not deeper */ + } + alloca_stack = hp; /* -> last valid storage */ + if (size == 0) + return 0; /* No allocation required */ +#if 1 /* Nick */ + if ((hp = (mem *) malloc(sizeof(mem) * 2 + size)) == 0) +#else + if ((hp = (mem *) (*__alloca_alloc) (sizeof(mem) * 2 + size)) == 0) +#endif + return hp; + m_next(hp) = alloca_stack; + m_deep(hp) = &probe; + alloca_stack = hp; + /* User storage begins just after header */ + return (void *) (hp + 2); +} +#endif /* L_alloca */ + diff --git a/src/libc/asctime.c b/src/libc/asctime.c new file mode 100755 index 00000000..941ad0e3 --- /dev/null +++ b/src/libc/asctime.c @@ -0,0 +1,59 @@ +/*************************** ASCTIME ************************************/ +#include "time-l.h" + +#ifdef L_asctime +/* + * Internal ascii conversion routine, avoid use of printf, it's a bit big! + */ +static void hit __P((char *, int)); + +static void hit(buf, val) + char *buf; + int val; +{ + *buf = '0' + val % 10; +} + +void __asctime(buffer, ptm) + register char *buffer; + struct tm *ptm; +{ + static char days[] = "SunMonTueWedThuFriSat"; + static char mons[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; + int year; + + strcpy(buffer, "Err Err .. ..:..:.. ....\n"); + if ((ptm->tm_wday >= 0) && (ptm->tm_wday <= 6)) + memcpy(buffer, days + 3 * (ptm->tm_wday), 3); + if ((ptm->tm_mon >= 0) && (ptm->tm_mon <= 11)) + memcpy(buffer + 4, mons + 3 * (ptm->tm_mon), 3); + year = ptm->tm_year + 1900; + hit(buffer + 8, ptm->tm_mday / 10); + hit(buffer + 9, ptm->tm_mday); + hit(buffer + 11, ptm->tm_hour / 10); + hit(buffer + 12, ptm->tm_hour); + hit(buffer + 14, ptm->tm_min / 10); + hit(buffer + 15, ptm->tm_min); + hit(buffer + 17, ptm->tm_sec / 10); + hit(buffer + 18, ptm->tm_sec); + hit(buffer + 20, year / 1000); + hit(buffer + 21, year / 100); + hit(buffer + 22, year / 10); + hit(buffer + 23, year); +} + +/* asctime - convert date and time to ascii. + * returns a pointer to the character string containing the date and time. + */ +char *asctime(timeptr) + struct tm *timeptr; +{ + static char timebuf[26]; + + if (timeptr == 0) + return 0; + __asctime(timebuf, timeptr); + return timebuf; +} +#endif + diff --git a/src/libc/assert.c b/src/libc/assert.c new file mode 100755 index 00000000..4d9b33a6 --- /dev/null +++ b/src/libc/assert.c @@ -0,0 +1,30 @@ +/* Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include +#include +#include +#include + +void __errput(str) + char * str; +{ + write(2, str, strlen(str)); +} + +void __assert(assertion, filename, linenumber) + char *assertion; + char *filename; + int linenumber; +{ + __errput("Failed '"); + __errput(assertion); + __errput("', file "); + __errput(filename); + __errput(", line "); + __errput(_itoa(linenumber)); + __errput(".\n"); + abort(); +} + \ No newline at end of file diff --git a/src/libc/atexit.c b/src/libc/atexit.c new file mode 100755 index 00000000..958c4548 --- /dev/null +++ b/src/libc/atexit.c @@ -0,0 +1,71 @@ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +/* + * This deals with both the atexit and on_exit function calls + * + * Note: calls installed with atexit are called with the same args as + * on_exit fuctions; the void* is given the NULL value. + */ +#include +#include + +/* ATEXIT.H */ +#define MAXONEXIT 10 /* AIUI Posix requires 10 */ + +typedef void (*vfuncp)(); + +extern struct exit_table { + onexit_t called; + void *argument; +} __on_exit_table[MAXONEXIT]; + +extern int __on_exit_count; + +/* End ATEXIT.H */ + +int __on_exit_count = 0; +struct exit_table __on_exit_table[MAXONEXIT]; + +static void __do_exit __P((int)); + +static void __do_exit(rv) + int rv; +{ + register int count = __on_exit_count - 1; + register vfuncp ptr; + + __on_exit_count = -1; /* ensure no more will be added */ + __cleanup = 0; /* Calling exit won't re-do this */ + /* In reverse order */ + while (count >= 0) { + ptr = (vfuncp)__on_exit_table[count].called; + (*ptr) (rv, __on_exit_table[count].argument); + --count; + } +} + +int on_exit(ptr, arg) + onexit_t ptr; + void *arg; +{ + if (__on_exit_count < 0 || __on_exit_count >= MAXONEXIT) { + errno = ENOMEM; + return -1; + } + __cleanup = (onexit_t)__do_exit; + if (ptr) { + __on_exit_table[__on_exit_count].called = ptr; + __on_exit_table[__on_exit_count].argument = arg; + __on_exit_count++; + } + return 0; +} + +int atexit(ptr) + atexit_t ptr; +{ + return on_exit((onexit_t)ptr,0); +} + diff --git a/src/libc/atoi.c b/src/libc/atoi.c new file mode 100755 index 00000000..2259e870 --- /dev/null +++ b/src/libc/atoi.c @@ -0,0 +1,14 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/**************************** atoi.c ****************************/ +#ifdef L_atoi +int atoi(str) + char *str; +{ + return (int)strtol(str,NULL,10); +} +#endif + diff --git a/src/libc/atol.c b/src/libc/atol.c new file mode 100755 index 00000000..57ecb708 --- /dev/null +++ b/src/libc/atol.c @@ -0,0 +1,14 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/**************************** atol.c ****************************/ +#ifdef L_atol +long atol(str) + char *str; +{ + return strtol(str,NULL,10); +} +#endif + diff --git a/src/libc/bsearch.c b/src/libc/bsearch.c new file mode 100755 index 00000000..b4d03a77 --- /dev/null +++ b/src/libc/bsearch.c @@ -0,0 +1,37 @@ +/* This file lifted in toto from 'Dlibs' on the atari ST (RdeBath) + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + */ +#include + +int _bsearch; /* index of element found, or where to insert */ + +void *bsearch(key, base, num, size, cmp) + void *key; /* item to search for */ + void *base; /* base address */ + size_t num; /* number of elements */ + size_t size; /* element size in bytes */ + cmp_func_t cmp; /* comparison function */ +{ + register int a, b, c, dir; + + a = 0; + b = num - 1; + while (a <= b) { + c = (a + b) >> 1; /* == ((a + b) / 2) */ + if (0 != (dir = (*cmp) (((char *)base + (c * size)), key))) { + if (dir > 0) + b = c - 1; + else a = c + 1; /* (dir < 0) */ + } + else { + _bsearch = c; + return ((char *)base + (c * size)); + } + } + _bsearch = b; + return (NULL); +} + \ No newline at end of file diff --git a/src/libc/build-b.ban b/src/libc/build-b.ban new file mode 100755 index 00000000..0a906cdc --- /dev/null +++ b/src/libc/build-b.ban @@ -0,0 +1,997 @@ +copy libcb.lib ..\..\..\lib + +copy ..\c0b.asm c0b.s01 +as-z80 -l -o c0b.s01 +@if errorlevel 1 goto failure +copy c0b.rel ..\..\..\lib +copy c0b.lst ..\..\..\lib + +copy ..\setjmpb.asm setjmpb.s01 +as-z80 -l -o setjmpb.s01 +@if errorlevel 1 goto failure +copy setjmpb.rel ..\..\..\lib\relcb + +copy ..\longjmpb.asm longjmpb.s01 +as-z80 -l -o longjmpb.s01 +@if errorlevel 1 goto failure +copy longjmpb.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_abort ..\abort +@if errorlevel 1 goto failure +del abort.r01 +as-z80 -l -o abort.s01 +@if errorlevel 1 goto failure +copy abort.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_alloca ..\alloca +@if errorlevel 1 goto failure +del alloca.r01 +as-z80 -l -o alloca.s01 +@if errorlevel 1 goto failure +copy alloca.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_asctime ..\asctime +@if errorlevel 1 goto failure +del asctime.r01 +as-z80 -l -o asctime.s01 +@if errorlevel 1 goto failure +copy asctime.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_assert ..\assert +@if errorlevel 1 goto failure +del assert.r01 +as-z80 -l -o assert.s01 +@if errorlevel 1 goto failure +copy assert.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_atexit ..\atexit +@if errorlevel 1 goto failure +del atexit.r01 +as-z80 -l -o atexit.s01 +@if errorlevel 1 goto failure +copy atexit.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_atoi ..\atoi +@if errorlevel 1 goto failure +del atoi.r01 +as-z80 -l -o atoi.s01 +@if errorlevel 1 goto failure +copy atoi.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_atol ..\atol +@if errorlevel 1 goto failure +del atol.r01 +as-z80 -l -o atol.s01 +@if errorlevel 1 goto failure +copy atol.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_bsearch ..\bsearch +@if errorlevel 1 goto failure +del bsearch.r01 +as-z80 -l -o bsearch.s01 +@if errorlevel 1 goto failure +copy bsearch.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_calloc ..\calloc +@if errorlevel 1 goto failure +del calloc.r01 +as-z80 -l -o calloc.s01 +@if errorlevel 1 goto failure +copy calloc.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_clock ..\clock +@if errorlevel 1 goto failure +del clock.r01 +as-z80 -l -o clock.s01 +@if errorlevel 1 goto failure +copy clock.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_closedir ..\closedir +@if errorlevel 1 goto failure +del closedir.r01 +as-z80 -l -o closedir.s01 +@if errorlevel 1 goto failure +copy closedir.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_convtime ..\convtime +@if errorlevel 1 goto failure +del convtime.r01 +as-z80 -l -o convtime.s01 +@if errorlevel 1 goto failure +copy convtime.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_crypt ..\crypt +@if errorlevel 1 goto failure +del crypt.r01 +as-z80 -l -o crypt.s01 +@if errorlevel 1 goto failure +copy crypt.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ctime ..\ctime +@if errorlevel 1 goto failure +del ctime.r01 +as-z80 -l -o ctime.s01 +@if errorlevel 1 goto failure +copy ctime.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ctype ..\ctype +@if errorlevel 1 goto failure +del ctype.r01 +as-z80 -l -o ctype.s01 +@if errorlevel 1 goto failure +copy ctype.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_difftime ..\difftime +@if errorlevel 1 goto failure +del difftime.r01 +as-z80 -l -o difftime.s01 +@if errorlevel 1 goto failure +copy difftime.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_error ..\error +@if errorlevel 1 goto failure +del error.r01 +as-z80 -l -o error.s01 +@if errorlevel 1 goto failure +copy error.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_etime ..\etime +@if errorlevel 1 goto failure +del etime.r01 +as-z80 -l -o etime.s01 +@if errorlevel 1 goto failure +copy etime.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execl ..\execl +@if errorlevel 1 goto failure +del execl.r01 +as-z80 -l -o execl.s01 +@if errorlevel 1 goto failure +copy execl.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execle ..\execle +@if errorlevel 1 goto failure +del execle.r01 +as-z80 -l -o execle.s01 +@if errorlevel 1 goto failure +copy execle.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execlp ..\execlp +@if errorlevel 1 goto failure +del execlp.r01 +as-z80 -l -o execlp.s01 +@if errorlevel 1 goto failure +copy execlp.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execlpe ..\execlpe +@if errorlevel 1 goto failure +del execlpe.r01 +as-z80 -l -o execlpe.s01 +@if errorlevel 1 goto failure +copy execlpe.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_exect ..\exect +@if errorlevel 1 goto failure +del exect.r01 +as-z80 -l -o exect.s01 +@if errorlevel 1 goto failure +copy exect.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execv ..\execv +@if errorlevel 1 goto failure +del execv.r01 +as-z80 -l -o execv.s01 +@if errorlevel 1 goto failure +copy execv.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execvp ..\execvp +@if errorlevel 1 goto failure +del execvp.r01 +as-z80 -l -o execvp.s01 +@if errorlevel 1 goto failure +copy execvp.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execvpe ..\execvpe +@if errorlevel 1 goto failure +del execvpe.r01 +as-z80 -l -o execvpe.s01 +@if errorlevel 1 goto failure +copy execvpe.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_exit ..\exit +@if errorlevel 1 goto failure +del exit.r01 +as-z80 -l -o exit.s01 +@if errorlevel 1 goto failure +copy exit.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fclose ..\fclose +@if errorlevel 1 goto failure +del fclose.r01 +as-z80 -l -o fclose.s01 +@if errorlevel 1 goto failure +copy fclose.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fflush ..\fflush +@if errorlevel 1 goto failure +del fflush.r01 +as-z80 -l -o fflush.s01 +@if errorlevel 1 goto failure +copy fflush.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fgetc ..\fgetc +@if errorlevel 1 goto failure +del fgetc.r01 +as-z80 -l -o fgetc.s01 +@if errorlevel 1 goto failure +copy fgetc.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fgetgren ..\fgetgren +@if errorlevel 1 goto failure +del fgetgren.r01 +as-z80 -l -o fgetgren.s01 +@if errorlevel 1 goto failure +copy fgetgren.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fgetpwen ..\fgetpwen +@if errorlevel 1 goto failure +del fgetpwen.r01 +as-z80 -l -o fgetpwen.s01 +@if errorlevel 1 goto failure +copy fgetpwen.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fgets ..\fgets +@if errorlevel 1 goto failure +del fgets.r01 +as-z80 -l -o fgets.s01 +@if errorlevel 1 goto failure +copy fgets.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fopen ..\fopen +@if errorlevel 1 goto failure +del fopen.r01 +as-z80 -l -o fopen.s01 +@if errorlevel 1 goto failure +copy fopen.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fprintf ..\fprintf +@if errorlevel 1 goto failure +del fprintf.r01 +as-z80 -l -o fprintf.s01 +@if errorlevel 1 goto failure +copy fprintf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fputc ..\fputc +@if errorlevel 1 goto failure +del fputc.r01 +as-z80 -l -o fputc.s01 +@if errorlevel 1 goto failure +copy fputc.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fputs ..\fputs +@if errorlevel 1 goto failure +del fputs.r01 +as-z80 -l -o fputs.s01 +@if errorlevel 1 goto failure +copy fputs.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fread ..\fread +@if errorlevel 1 goto failure +del fread.r01 +as-z80 -l -o fread.s01 +@if errorlevel 1 goto failure +copy fread.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_free ..\free +@if errorlevel 1 goto failure +del free.r01 +as-z80 -l -o free.s01 +@if errorlevel 1 goto failure +copy free.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fscanf ..\fscanf +@if errorlevel 1 goto failure +del fscanf.r01 +as-z80 -l -o fscanf.s01 +@if errorlevel 1 goto failure +copy fscanf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ftell ..\ftell +@if errorlevel 1 goto failure +del ftell.r01 +as-z80 -l -o ftell.s01 +@if errorlevel 1 goto failure +copy ftell.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fwrite ..\fwrite +@if errorlevel 1 goto failure +del fwrite.r01 +as-z80 -l -o fwrite.s01 +@if errorlevel 1 goto failure +copy fwrite.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getcwd ..\getcwd +@if errorlevel 1 goto failure +del getcwd.r01 +as-z80 -l -o getcwd.s01 +@if errorlevel 1 goto failure +copy getcwd.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getenv ..\getenv +@if errorlevel 1 goto failure +del getenv.r01 +as-z80 -l -o getenv.s01 +@if errorlevel 1 goto failure +copy getenv.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getgrent ..\getgrent +@if errorlevel 1 goto failure +del getgrent.r01 +as-z80 -l -o getgrent.s01 +@if errorlevel 1 goto failure +copy getgrent.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getgrgid ..\getgrgid +@if errorlevel 1 goto failure +del getgrgid.r01 +as-z80 -l -o getgrgid.s01 +@if errorlevel 1 goto failure +copy getgrgid.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getgrnam ..\getgrnam +@if errorlevel 1 goto failure +del getgrnam.r01 +as-z80 -l -o getgrnam.s01 +@if errorlevel 1 goto failure +copy getgrnam.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getopt ..\getopt +@if errorlevel 1 goto failure +del getopt.r01 +as-z80 -l -o getopt.s01 +@if errorlevel 1 goto failure +copy getopt.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpass ..\getpass +@if errorlevel 1 goto failure +del getpass.r01 +as-z80 -l -o getpass.s01 +@if errorlevel 1 goto failure +copy getpass.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpw ..\getpw +@if errorlevel 1 goto failure +del getpw.r01 +as-z80 -l -o getpw.s01 +@if errorlevel 1 goto failure +copy getpw.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpwent ..\getpwent +@if errorlevel 1 goto failure +del getpwent.r01 +as-z80 -l -o getpwent.s01 +@if errorlevel 1 goto failure +copy getpwent.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpwnam ..\getpwnam +@if errorlevel 1 goto failure +del getpwnam.r01 +as-z80 -l -o getpwnam.s01 +@if errorlevel 1 goto failure +copy getpwnam.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpwuid ..\getpwuid +@if errorlevel 1 goto failure +del getpwuid.r01 +as-z80 -l -o getpwuid.s01 +@if errorlevel 1 goto failure +copy getpwuid.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_gets ..\gets +@if errorlevel 1 goto failure +del gets.r01 +as-z80 -l -o gets.s01 +@if errorlevel 1 goto failure +copy gets.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_gmtime ..\gmtime +@if errorlevel 1 goto failure +del gmtime.r01 +as-z80 -l -o gmtime.s01 +@if errorlevel 1 goto failure +copy gmtime.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_initgrup ..\initgrup +@if errorlevel 1 goto failure +del initgrup.r01 +as-z80 -l -o initgrup.s01 +@if errorlevel 1 goto failure +copy initgrup.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_isatty ..\isatty +@if errorlevel 1 goto failure +del isatty.r01 +as-z80 -l -o isatty.s01 +@if errorlevel 1 goto failure +copy isatty.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_itoa ..\itoa +@if errorlevel 1 goto failure +del itoa.r01 +as-z80 -l -o itoa.s01 +@if errorlevel 1 goto failure +copy itoa.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_localtim ..\localtim +@if errorlevel 1 goto failure +del localtim.r01 +as-z80 -l -o localtim.s01 +@if errorlevel 1 goto failure +copy localtim.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_lsearch ..\lsearch +@if errorlevel 1 goto failure +del lsearch.r01 +as-z80 -l -o lsearch.s01 +@if errorlevel 1 goto failure +copy lsearch.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_lstat ..\lstat +@if errorlevel 1 goto failure +del lstat.r01 +as-z80 -l -o lstat.s01 +@if errorlevel 1 goto failure +copy lstat.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ltoa ..\ltoa +@if errorlevel 1 goto failure +del ltoa.r01 +as-z80 -l -o ltoa.s01 +@if errorlevel 1 goto failure +copy ltoa.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ltostr ..\ltostr +@if errorlevel 1 goto failure +del ltostr.r01 +as-z80 -l -o ltostr.s01 +@if errorlevel 1 goto failure +copy ltostr.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_malloc ..\malloc +@if errorlevel 1 goto failure +del malloc.r01 +as-z80 -l -o malloc.s01 +@if errorlevel 1 goto failure +copy malloc.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memccpy ..\memccpy +@if errorlevel 1 goto failure +del memccpy.r01 +as-z80 -l -o memccpy.s01 +@if errorlevel 1 goto failure +copy memccpy.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memchr ..\memchr +@if errorlevel 1 goto failure +del memchr.r01 +as-z80 -l -o memchr.s01 +@if errorlevel 1 goto failure +copy memchr.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memcmp ..\memcmp +@if errorlevel 1 goto failure +del memcmp.r01 +as-z80 -l -o memcmp.s01 +@if errorlevel 1 goto failure +copy memcmp.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memcpy ..\memcpy +@if errorlevel 1 goto failure +del memcpy.r01 +as-z80 -l -o memcpy.s01 +@if errorlevel 1 goto failure +copy memcpy.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memmove ..\memmove +@if errorlevel 1 goto failure +del memmove.r01 +as-z80 -l -o memmove.s01 +@if errorlevel 1 goto failure +copy memmove.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memset ..\memset +@if errorlevel 1 goto failure +del memset.r01 +as-z80 -l -o memset.s01 +@if errorlevel 1 goto failure +copy memset.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mkdir ..\mkdir +@if errorlevel 1 goto failure +del mkdir.r01 +as-z80 -l -o mkdir.s01 +@if errorlevel 1 goto failure +copy mkdir.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mktime ..\mktime +@if errorlevel 1 goto failure +del mktime.r01 +as-z80 -l -o mktime.s01 +@if errorlevel 1 goto failure +copy mktime.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_opendir ..\opendir +@if errorlevel 1 goto failure +del opendir.r01 +as-z80 -l -o opendir.s01 +@if errorlevel 1 goto failure +copy opendir.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_perror ..\perror +@if errorlevel 1 goto failure +del perror.r01 +as-z80 -l -o perror.s01 +@if errorlevel 1 goto failure +copy perror.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_popen ..\popen +@if errorlevel 1 goto failure +del popen.r01 +as-z80 -l -o popen.s01 +@if errorlevel 1 goto failure +copy popen.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_printf ..\printf +@if errorlevel 1 goto failure +del printf.r01 +as-z80 -l -o printf.s01 +@if errorlevel 1 goto failure +copy printf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_putenv ..\putenv +@if errorlevel 1 goto failure +del putenv.r01 +as-z80 -l -o putenv.s01 +@if errorlevel 1 goto failure +copy putenv.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_putgetch ..\putgetch +@if errorlevel 1 goto failure +del putgetch.r01 +as-z80 -l -o putgetch.s01 +@if errorlevel 1 goto failure +copy putgetch.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_putpwent ..\putpwent +@if errorlevel 1 goto failure +del putpwent.r01 +as-z80 -l -o putpwent.s01 +@if errorlevel 1 goto failure +copy putpwent.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_qsort ..\qsort +@if errorlevel 1 goto failure +del qsort.r01 +as-z80 -l -o qsort.s01 +@if errorlevel 1 goto failure +copy qsort.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rand ..\rand +@if errorlevel 1 goto failure +del rand.r01 +as-z80 -l -o rand.s01 +@if errorlevel 1 goto failure +copy rand.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_readdir ..\readdir +@if errorlevel 1 goto failure +del readdir.r01 +as-z80 -l -o readdir.s01 +@if errorlevel 1 goto failure +copy readdir.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_readlink ..\readlink +@if errorlevel 1 goto failure +del readlink.r01 +as-z80 -l -o readlink.s01 +@if errorlevel 1 goto failure +copy readlink.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_realloc ..\realloc +@if errorlevel 1 goto failure +del realloc.r01 +as-z80 -l -o realloc.s01 +@if errorlevel 1 goto failure +copy realloc.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_regerror ..\regerror +@if errorlevel 1 goto failure +del regerror.r01 +as-z80 -l -o regerror.s01 +@if errorlevel 1 goto failure +copy regerror.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_regexp ..\regexp +@if errorlevel 1 goto failure +del regexp.r01 +as-z80 -l -o regexp.s01 +@if errorlevel 1 goto failure +copy regexp.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_regsub ..\regsub +@if errorlevel 1 goto failure +del regsub.r01 +as-z80 -l -o regsub.s01 +@if errorlevel 1 goto failure +copy regsub.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rename ..\rename +@if errorlevel 1 goto failure +del rename.r01 +as-z80 -l -o rename.s01 +@if errorlevel 1 goto failure +copy rename.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rewind ..\rewind +@if errorlevel 1 goto failure +del rewind.r01 +as-z80 -l -o rewind.s01 +@if errorlevel 1 goto failure +copy rewind.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rewindir ..\rewindir +@if errorlevel 1 goto failure +del rewindir.r01 +as-z80 -l -o rewindir.s01 +@if errorlevel 1 goto failure +copy rewindir.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rmdir ..\rmdir +@if errorlevel 1 goto failure +del rmdir.r01 +as-z80 -l -o rmdir.s01 +@if errorlevel 1 goto failure +copy rmdir.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_scanf ..\scanf +@if errorlevel 1 goto failure +del scanf.r01 +as-z80 -l -o scanf.s01 +@if errorlevel 1 goto failure +copy scanf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setbuff ..\setbuff +@if errorlevel 1 goto failure +del setbuff.r01 +as-z80 -l -o setbuff.s01 +@if errorlevel 1 goto failure +copy setbuff.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setenv ..\setenv +@if errorlevel 1 goto failure +del setenv.r01 +as-z80 -l -o setenv.s01 +@if errorlevel 1 goto failure +copy setenv.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setgrent ..\setgrent +@if errorlevel 1 goto failure +del setgrent.r01 +as-z80 -l -o setgrent.s01 +@if errorlevel 1 goto failure +copy setgrent.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setpwent ..\setpwent +@if errorlevel 1 goto failure +del setpwent.r01 +as-z80 -l -o setpwent.s01 +@if errorlevel 1 goto failure +copy setpwent.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setvbuff ..\setvbuff +@if errorlevel 1 goto failure +del setvbuff.r01 +as-z80 -l -o setvbuff.s01 +@if errorlevel 1 goto failure +copy setvbuff.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sleep ..\sleep +@if errorlevel 1 goto failure +del sleep.r01 +as-z80 -l -o sleep.s01 +@if errorlevel 1 goto failure +copy sleep.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sprintf ..\sprintf +@if errorlevel 1 goto failure +del sprintf.r01 +as-z80 -l -o sprintf.s01 +@if errorlevel 1 goto failure +copy sprintf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sscanf ..\sscanf +@if errorlevel 1 goto failure +del sscanf.r01 +as-z80 -l -o sscanf.s01 +@if errorlevel 1 goto failure +copy sscanf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_stdio0 ..\stdio0 +@if errorlevel 1 goto failure +del stdio0.r01 +as-z80 -l -o stdio0.s01 +@if errorlevel 1 goto failure +copy stdio0.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strcat ..\strcat +@if errorlevel 1 goto failure +del strcat.r01 +as-z80 -l -o strcat.s01 +@if errorlevel 1 goto failure +copy strcat.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strchr ..\strchr +@if errorlevel 1 goto failure +del strchr.r01 +as-z80 -l -o strchr.s01 +@if errorlevel 1 goto failure +copy strchr.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strcmp ..\strcmp +@if errorlevel 1 goto failure +del strcmp.r01 +as-z80 -l -o strcmp.s01 +@if errorlevel 1 goto failure +copy strcmp.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strcpy ..\strcpy +@if errorlevel 1 goto failure +del strcpy.r01 +as-z80 -l -o strcpy.s01 +@if errorlevel 1 goto failure +copy strcpy.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strcspn ..\strcspn +@if errorlevel 1 goto failure +del strcspn.r01 +as-z80 -l -o strcspn.s01 +@if errorlevel 1 goto failure +copy strcspn.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strdup ..\strdup +@if errorlevel 1 goto failure +del strdup.r01 +as-z80 -l -o strdup.s01 +@if errorlevel 1 goto failure +copy strdup.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_stricmp ..\stricmp +@if errorlevel 1 goto failure +del stricmp.r01 +as-z80 -l -o stricmp.s01 +@if errorlevel 1 goto failure +copy stricmp.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strlen ..\strlen +@if errorlevel 1 goto failure +del strlen.r01 +as-z80 -l -o strlen.s01 +@if errorlevel 1 goto failure +copy strlen.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strncat ..\strncat +@if errorlevel 1 goto failure +del strncat.r01 +as-z80 -l -o strncat.s01 +@if errorlevel 1 goto failure +copy strncat.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strncmp ..\strncmp +@if errorlevel 1 goto failure +del strncmp.r01 +as-z80 -l -o strncmp.s01 +@if errorlevel 1 goto failure +copy strncmp.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strncpy ..\strncpy +@if errorlevel 1 goto failure +del strncpy.r01 +as-z80 -l -o strncpy.s01 +@if errorlevel 1 goto failure +copy strncpy.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strnicmp ..\strnicmp +@if errorlevel 1 goto failure +del strnicmp.r01 +as-z80 -l -o strnicmp.s01 +@if errorlevel 1 goto failure +copy strnicmp.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strpbrk ..\strpbrk +@if errorlevel 1 goto failure +del strpbrk.r01 +as-z80 -l -o strpbrk.s01 +@if errorlevel 1 goto failure +copy strpbrk.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strrchr ..\strrchr +@if errorlevel 1 goto failure +del strrchr.r01 +as-z80 -l -o strrchr.s01 +@if errorlevel 1 goto failure +copy strrchr.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strsep ..\strsep +@if errorlevel 1 goto failure +del strsep.r01 +as-z80 -l -o strsep.s01 +@if errorlevel 1 goto failure +copy strsep.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strspn ..\strspn +@if errorlevel 1 goto failure +del strspn.r01 +as-z80 -l -o strspn.s01 +@if errorlevel 1 goto failure +copy strspn.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strstr ..\strstr +@if errorlevel 1 goto failure +del strstr.r01 +as-z80 -l -o strstr.s01 +@if errorlevel 1 goto failure +copy strstr.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strtod ..\strtod +@if errorlevel 1 goto failure +del strtod.r01 +as-z80 -l -o strtod.s01 +@if errorlevel 1 goto failure +copy strtod.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strtok ..\strtok +@if errorlevel 1 goto failure +del strtok.r01 +as-z80 -l -o strtok.s01 +@if errorlevel 1 goto failure +copy strtok.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strtol ..\strtol +@if errorlevel 1 goto failure +del strtol.r01 +as-z80 -l -o strtol.s01 +@if errorlevel 1 goto failure +copy strtol.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strtoul ..\strtoul +@if errorlevel 1 goto failure +del strtoul.r01 +as-z80 -l -o strtoul.s01 +@if errorlevel 1 goto failure +copy strtoul.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_system ..\system +@if errorlevel 1 goto failure +del system.r01 +as-z80 -l -o system.s01 +@if errorlevel 1 goto failure +copy system.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_termcap ..\termcap +@if errorlevel 1 goto failure +del termcap.r01 +as-z80 -l -o termcap.s01 +@if errorlevel 1 goto failure +copy termcap.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_tmpnam ..\tmpnam +@if errorlevel 1 goto failure +del tmpnam.r01 +as-z80 -l -o tmpnam.s01 +@if errorlevel 1 goto failure +copy tmpnam.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_tparam ..\tparam +@if errorlevel 1 goto failure +del tparam.r01 +as-z80 -l -o tparam.s01 +@if errorlevel 1 goto failure +copy tparam.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ttyname ..\ttyname +@if errorlevel 1 goto failure +del ttyname.r01 +as-z80 -l -o ttyname.s01 +@if errorlevel 1 goto failure +copy ttyname.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_tzset ..\tzset +@if errorlevel 1 goto failure +del tzset.r01 +as-z80 -l -o tzset.s01 +@if errorlevel 1 goto failure +copy tzset.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ultoa ..\ultoa +@if errorlevel 1 goto failure +del ultoa.r01 +as-z80 -l -o ultoa.s01 +@if errorlevel 1 goto failure +copy ultoa.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ungetc ..\ungetc +@if errorlevel 1 goto failure +del ungetc.r01 +as-z80 -l -o ungetc.s01 +@if errorlevel 1 goto failure +copy ungetc.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_utsname ..\utsname +@if errorlevel 1 goto failure +del utsname.r01 +as-z80 -l -o utsname.s01 +@if errorlevel 1 goto failure +copy utsname.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vfprintf ..\vfprintf +@if errorlevel 1 goto failure +del vfprintf.r01 +as-z80 -l -o vfprintf.s01 +@if errorlevel 1 goto failure +copy vfprintf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vfscanf ..\vfscanf +@if errorlevel 1 goto failure +del vfscanf.r01 +as-z80 -l -o vfscanf.s01 +@if errorlevel 1 goto failure +copy vfscanf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vprintf ..\vprintf +@if errorlevel 1 goto failure +del vprintf.r01 +as-z80 -l -o vprintf.s01 +@if errorlevel 1 goto failure +copy vprintf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vscanf ..\vscanf +@if errorlevel 1 goto failure +del vscanf.r01 +as-z80 -l -o vscanf.s01 +@if errorlevel 1 goto failure +copy vscanf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vsprintf ..\vsprintf +@if errorlevel 1 goto failure +del vsprintf.r01 +as-z80 -l -o vsprintf.s01 +@if errorlevel 1 goto failure +copy vsprintf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vsscanf ..\vsscanf +@if errorlevel 1 goto failure +del vsscanf.r01 +as-z80 -l -o vsscanf.s01 +@if errorlevel 1 goto failure +copy vsscanf.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_xitoa ..\xitoa +@if errorlevel 1 goto failure +del xitoa.r01 +as-z80 -l -o xitoa.s01 +@if errorlevel 1 goto failure +copy xitoa.rel ..\..\..\lib\relcb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_xltoa ..\xltoa +@if errorlevel 1 goto failure +del xltoa.r01 +as-z80 -l -o xltoa.s01 +@if errorlevel 1 goto failure +copy xltoa.rel ..\..\..\lib\relcb + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/libc/build-l.ban b/src/libc/build-l.ban new file mode 100755 index 00000000..0ab34610 --- /dev/null +++ b/src/libc/build-l.ban @@ -0,0 +1,997 @@ +copy ..\libcl.lib ..\..\..\lib + +copy ..\c0l.asm c0l.s01 +as-z80 -l -o c0l.s01 +@if errorlevel 1 goto failure +copy c0l.rel ..\..\..\lib +copy c0l.lst ..\..\..\lib + +copy ..\setjmpl.asm setjmpl.s01 +as-z80 -l -o setjmpl.s01 +@if errorlevel 1 goto failure +copy setjmpl.rel ..\..\..\lib\relcl + +copy ..\longjmpl.asm longjmpl.s01 +as-z80 -l -o longjmpl.s01 +@if errorlevel 1 goto failure +copy longjmpl.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_abort ..\abort +@if errorlevel 1 goto failure +del abort.r01 +as-z80 -l -o abort.s01 +@if errorlevel 1 goto failure +copy abort.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_alloca ..\alloca +@if errorlevel 1 goto failure +del alloca.r01 +as-z80 -l -o alloca.s01 +@if errorlevel 1 goto failure +copy alloca.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_asctime ..\asctime +@if errorlevel 1 goto failure +del asctime.r01 +as-z80 -l -o asctime.s01 +@if errorlevel 1 goto failure +copy asctime.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_assert ..\assert +@if errorlevel 1 goto failure +del assert.r01 +as-z80 -l -o assert.s01 +@if errorlevel 1 goto failure +copy assert.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_atexit ..\atexit +@if errorlevel 1 goto failure +del atexit.r01 +as-z80 -l -o atexit.s01 +@if errorlevel 1 goto failure +copy atexit.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_atoi ..\atoi +@if errorlevel 1 goto failure +del atoi.r01 +as-z80 -l -o atoi.s01 +@if errorlevel 1 goto failure +copy atoi.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_atol ..\atol +@if errorlevel 1 goto failure +del atol.r01 +as-z80 -l -o atol.s01 +@if errorlevel 1 goto failure +copy atol.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_bsearch ..\bsearch +@if errorlevel 1 goto failure +del bsearch.r01 +as-z80 -l -o bsearch.s01 +@if errorlevel 1 goto failure +copy bsearch.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_calloc ..\calloc +@if errorlevel 1 goto failure +del calloc.r01 +as-z80 -l -o calloc.s01 +@if errorlevel 1 goto failure +copy calloc.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_clock ..\clock +@if errorlevel 1 goto failure +del clock.r01 +as-z80 -l -o clock.s01 +@if errorlevel 1 goto failure +copy clock.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_closedir ..\closedir +@if errorlevel 1 goto failure +del closedir.r01 +as-z80 -l -o closedir.s01 +@if errorlevel 1 goto failure +copy closedir.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_convtime ..\convtime +@if errorlevel 1 goto failure +del convtime.r01 +as-z80 -l -o convtime.s01 +@if errorlevel 1 goto failure +copy convtime.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_crypt ..\crypt +@if errorlevel 1 goto failure +del crypt.r01 +as-z80 -l -o crypt.s01 +@if errorlevel 1 goto failure +copy crypt.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ctime ..\ctime +@if errorlevel 1 goto failure +del ctime.r01 +as-z80 -l -o ctime.s01 +@if errorlevel 1 goto failure +copy ctime.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ctype ..\ctype +@if errorlevel 1 goto failure +del ctype.r01 +as-z80 -l -o ctype.s01 +@if errorlevel 1 goto failure +copy ctype.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_difftime ..\difftime +@if errorlevel 1 goto failure +del difftime.r01 +as-z80 -l -o difftime.s01 +@if errorlevel 1 goto failure +copy difftime.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_error ..\error +@if errorlevel 1 goto failure +del error.r01 +as-z80 -l -o error.s01 +@if errorlevel 1 goto failure +copy error.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_etime ..\etime +@if errorlevel 1 goto failure +del etime.r01 +as-z80 -l -o etime.s01 +@if errorlevel 1 goto failure +copy etime.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execl ..\execl +@if errorlevel 1 goto failure +del execl.r01 +as-z80 -l -o execl.s01 +@if errorlevel 1 goto failure +copy execl.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execle ..\execle +@if errorlevel 1 goto failure +del execle.r01 +as-z80 -l -o execle.s01 +@if errorlevel 1 goto failure +copy execle.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execlp ..\execlp +@if errorlevel 1 goto failure +del execlp.r01 +as-z80 -l -o execlp.s01 +@if errorlevel 1 goto failure +copy execlp.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execlpe ..\execlpe +@if errorlevel 1 goto failure +del execlpe.r01 +as-z80 -l -o execlpe.s01 +@if errorlevel 1 goto failure +copy execlpe.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_exect ..\exect +@if errorlevel 1 goto failure +del exect.r01 +as-z80 -l -o exect.s01 +@if errorlevel 1 goto failure +copy exect.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execv ..\execv +@if errorlevel 1 goto failure +del execv.r01 +as-z80 -l -o execv.s01 +@if errorlevel 1 goto failure +copy execv.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execvp ..\execvp +@if errorlevel 1 goto failure +del execvp.r01 +as-z80 -l -o execvp.s01 +@if errorlevel 1 goto failure +copy execvp.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execvpe ..\execvpe +@if errorlevel 1 goto failure +del execvpe.r01 +as-z80 -l -o execvpe.s01 +@if errorlevel 1 goto failure +copy execvpe.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_exit ..\exit +@if errorlevel 1 goto failure +del exit.r01 +as-z80 -l -o exit.s01 +@if errorlevel 1 goto failure +copy exit.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fclose ..\fclose +@if errorlevel 1 goto failure +del fclose.r01 +as-z80 -l -o fclose.s01 +@if errorlevel 1 goto failure +copy fclose.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fflush ..\fflush +@if errorlevel 1 goto failure +del fflush.r01 +as-z80 -l -o fflush.s01 +@if errorlevel 1 goto failure +copy fflush.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fgetc ..\fgetc +@if errorlevel 1 goto failure +del fgetc.r01 +as-z80 -l -o fgetc.s01 +@if errorlevel 1 goto failure +copy fgetc.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fgetgren ..\fgetgren +@if errorlevel 1 goto failure +del fgetgren.r01 +as-z80 -l -o fgetgren.s01 +@if errorlevel 1 goto failure +copy fgetgren.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fgetpwen ..\fgetpwen +@if errorlevel 1 goto failure +del fgetpwen.r01 +as-z80 -l -o fgetpwen.s01 +@if errorlevel 1 goto failure +copy fgetpwen.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fgets ..\fgets +@if errorlevel 1 goto failure +del fgets.r01 +as-z80 -l -o fgets.s01 +@if errorlevel 1 goto failure +copy fgets.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fopen ..\fopen +@if errorlevel 1 goto failure +del fopen.r01 +as-z80 -l -o fopen.s01 +@if errorlevel 1 goto failure +copy fopen.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fprintf ..\fprintf +@if errorlevel 1 goto failure +del fprintf.r01 +as-z80 -l -o fprintf.s01 +@if errorlevel 1 goto failure +copy fprintf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fputc ..\fputc +@if errorlevel 1 goto failure +del fputc.r01 +as-z80 -l -o fputc.s01 +@if errorlevel 1 goto failure +copy fputc.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fputs ..\fputs +@if errorlevel 1 goto failure +del fputs.r01 +as-z80 -l -o fputs.s01 +@if errorlevel 1 goto failure +copy fputs.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fread ..\fread +@if errorlevel 1 goto failure +del fread.r01 +as-z80 -l -o fread.s01 +@if errorlevel 1 goto failure +copy fread.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_free ..\free +@if errorlevel 1 goto failure +del free.r01 +as-z80 -l -o free.s01 +@if errorlevel 1 goto failure +copy free.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fscanf ..\fscanf +@if errorlevel 1 goto failure +del fscanf.r01 +as-z80 -l -o fscanf.s01 +@if errorlevel 1 goto failure +copy fscanf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ftell ..\ftell +@if errorlevel 1 goto failure +del ftell.r01 +as-z80 -l -o ftell.s01 +@if errorlevel 1 goto failure +copy ftell.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fwrite ..\fwrite +@if errorlevel 1 goto failure +del fwrite.r01 +as-z80 -l -o fwrite.s01 +@if errorlevel 1 goto failure +copy fwrite.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getcwd ..\getcwd +@if errorlevel 1 goto failure +del getcwd.r01 +as-z80 -l -o getcwd.s01 +@if errorlevel 1 goto failure +copy getcwd.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getenv ..\getenv +@if errorlevel 1 goto failure +del getenv.r01 +as-z80 -l -o getenv.s01 +@if errorlevel 1 goto failure +copy getenv.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getgrent ..\getgrent +@if errorlevel 1 goto failure +del getgrent.r01 +as-z80 -l -o getgrent.s01 +@if errorlevel 1 goto failure +copy getgrent.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getgrgid ..\getgrgid +@if errorlevel 1 goto failure +del getgrgid.r01 +as-z80 -l -o getgrgid.s01 +@if errorlevel 1 goto failure +copy getgrgid.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getgrnam ..\getgrnam +@if errorlevel 1 goto failure +del getgrnam.r01 +as-z80 -l -o getgrnam.s01 +@if errorlevel 1 goto failure +copy getgrnam.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getopt ..\getopt +@if errorlevel 1 goto failure +del getopt.r01 +as-z80 -l -o getopt.s01 +@if errorlevel 1 goto failure +copy getopt.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpass ..\getpass +@if errorlevel 1 goto failure +del getpass.r01 +as-z80 -l -o getpass.s01 +@if errorlevel 1 goto failure +copy getpass.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpw ..\getpw +@if errorlevel 1 goto failure +del getpw.r01 +as-z80 -l -o getpw.s01 +@if errorlevel 1 goto failure +copy getpw.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpwent ..\getpwent +@if errorlevel 1 goto failure +del getpwent.r01 +as-z80 -l -o getpwent.s01 +@if errorlevel 1 goto failure +copy getpwent.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpwnam ..\getpwnam +@if errorlevel 1 goto failure +del getpwnam.r01 +as-z80 -l -o getpwnam.s01 +@if errorlevel 1 goto failure +copy getpwnam.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpwuid ..\getpwuid +@if errorlevel 1 goto failure +del getpwuid.r01 +as-z80 -l -o getpwuid.s01 +@if errorlevel 1 goto failure +copy getpwuid.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_gets ..\gets +@if errorlevel 1 goto failure +del gets.r01 +as-z80 -l -o gets.s01 +@if errorlevel 1 goto failure +copy gets.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_gmtime ..\gmtime +@if errorlevel 1 goto failure +del gmtime.r01 +as-z80 -l -o gmtime.s01 +@if errorlevel 1 goto failure +copy gmtime.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_initgrup ..\initgrup +@if errorlevel 1 goto failure +del initgrup.r01 +as-z80 -l -o initgrup.s01 +@if errorlevel 1 goto failure +copy initgrup.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_isatty ..\isatty +@if errorlevel 1 goto failure +del isatty.r01 +as-z80 -l -o isatty.s01 +@if errorlevel 1 goto failure +copy isatty.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_itoa ..\itoa +@if errorlevel 1 goto failure +del itoa.r01 +as-z80 -l -o itoa.s01 +@if errorlevel 1 goto failure +copy itoa.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_localtim ..\localtim +@if errorlevel 1 goto failure +del localtim.r01 +as-z80 -l -o localtim.s01 +@if errorlevel 1 goto failure +copy localtim.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_lsearch ..\lsearch +@if errorlevel 1 goto failure +del lsearch.r01 +as-z80 -l -o lsearch.s01 +@if errorlevel 1 goto failure +copy lsearch.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_lstat ..\lstat +@if errorlevel 1 goto failure +del lstat.r01 +as-z80 -l -o lstat.s01 +@if errorlevel 1 goto failure +copy lstat.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ltoa ..\ltoa +@if errorlevel 1 goto failure +del ltoa.r01 +as-z80 -l -o ltoa.s01 +@if errorlevel 1 goto failure +copy ltoa.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ltostr ..\ltostr +@if errorlevel 1 goto failure +del ltostr.r01 +as-z80 -l -o ltostr.s01 +@if errorlevel 1 goto failure +copy ltostr.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_malloc ..\malloc +@if errorlevel 1 goto failure +del malloc.r01 +as-z80 -l -o malloc.s01 +@if errorlevel 1 goto failure +copy malloc.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memccpy ..\memccpy +@if errorlevel 1 goto failure +del memccpy.r01 +as-z80 -l -o memccpy.s01 +@if errorlevel 1 goto failure +copy memccpy.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memchr ..\memchr +@if errorlevel 1 goto failure +del memchr.r01 +as-z80 -l -o memchr.s01 +@if errorlevel 1 goto failure +copy memchr.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memcmp ..\memcmp +@if errorlevel 1 goto failure +del memcmp.r01 +as-z80 -l -o memcmp.s01 +@if errorlevel 1 goto failure +copy memcmp.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memcpy ..\memcpy +@if errorlevel 1 goto failure +del memcpy.r01 +as-z80 -l -o memcpy.s01 +@if errorlevel 1 goto failure +copy memcpy.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memmove ..\memmove +@if errorlevel 1 goto failure +del memmove.r01 +as-z80 -l -o memmove.s01 +@if errorlevel 1 goto failure +copy memmove.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_memset ..\memset +@if errorlevel 1 goto failure +del memset.r01 +as-z80 -l -o memset.s01 +@if errorlevel 1 goto failure +copy memset.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mkdir ..\mkdir +@if errorlevel 1 goto failure +del mkdir.r01 +as-z80 -l -o mkdir.s01 +@if errorlevel 1 goto failure +copy mkdir.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mktime ..\mktime +@if errorlevel 1 goto failure +del mktime.r01 +as-z80 -l -o mktime.s01 +@if errorlevel 1 goto failure +copy mktime.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_opendir ..\opendir +@if errorlevel 1 goto failure +del opendir.r01 +as-z80 -l -o opendir.s01 +@if errorlevel 1 goto failure +copy opendir.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_perror ..\perror +@if errorlevel 1 goto failure +del perror.r01 +as-z80 -l -o perror.s01 +@if errorlevel 1 goto failure +copy perror.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_popen ..\popen +@if errorlevel 1 goto failure +del popen.r01 +as-z80 -l -o popen.s01 +@if errorlevel 1 goto failure +copy popen.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_printf ..\printf +@if errorlevel 1 goto failure +del printf.r01 +as-z80 -l -o printf.s01 +@if errorlevel 1 goto failure +copy printf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_putenv ..\putenv +@if errorlevel 1 goto failure +del putenv.r01 +as-z80 -l -o putenv.s01 +@if errorlevel 1 goto failure +copy putenv.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_putgetch ..\putgetch +@if errorlevel 1 goto failure +del putgetch.r01 +as-z80 -l -o putgetch.s01 +@if errorlevel 1 goto failure +copy putgetch.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_putpwent ..\putpwent +@if errorlevel 1 goto failure +del putpwent.r01 +as-z80 -l -o putpwent.s01 +@if errorlevel 1 goto failure +copy putpwent.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_qsort ..\qsort +@if errorlevel 1 goto failure +del qsort.r01 +as-z80 -l -o qsort.s01 +@if errorlevel 1 goto failure +copy qsort.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rand ..\rand +@if errorlevel 1 goto failure +del rand.r01 +as-z80 -l -o rand.s01 +@if errorlevel 1 goto failure +copy rand.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_readdir ..\readdir +@if errorlevel 1 goto failure +del readdir.r01 +as-z80 -l -o readdir.s01 +@if errorlevel 1 goto failure +copy readdir.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_readlink ..\readlink +@if errorlevel 1 goto failure +del readlink.r01 +as-z80 -l -o readlink.s01 +@if errorlevel 1 goto failure +copy readlink.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_realloc ..\realloc +@if errorlevel 1 goto failure +del realloc.r01 +as-z80 -l -o realloc.s01 +@if errorlevel 1 goto failure +copy realloc.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_regerror ..\regerror +@if errorlevel 1 goto failure +del regerror.r01 +as-z80 -l -o regerror.s01 +@if errorlevel 1 goto failure +copy regerror.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_regexp ..\regexp +@if errorlevel 1 goto failure +del regexp.r01 +as-z80 -l -o regexp.s01 +@if errorlevel 1 goto failure +copy regexp.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_regsub ..\regsub +@if errorlevel 1 goto failure +del regsub.r01 +as-z80 -l -o regsub.s01 +@if errorlevel 1 goto failure +copy regsub.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rename ..\rename +@if errorlevel 1 goto failure +del rename.r01 +as-z80 -l -o rename.s01 +@if errorlevel 1 goto failure +copy rename.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rewind ..\rewind +@if errorlevel 1 goto failure +del rewind.r01 +as-z80 -l -o rewind.s01 +@if errorlevel 1 goto failure +copy rewind.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rewindir ..\rewindir +@if errorlevel 1 goto failure +del rewindir.r01 +as-z80 -l -o rewindir.s01 +@if errorlevel 1 goto failure +copy rewindir.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_rmdir ..\rmdir +@if errorlevel 1 goto failure +del rmdir.r01 +as-z80 -l -o rmdir.s01 +@if errorlevel 1 goto failure +copy rmdir.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_scanf ..\scanf +@if errorlevel 1 goto failure +del scanf.r01 +as-z80 -l -o scanf.s01 +@if errorlevel 1 goto failure +copy scanf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setbuff ..\setbuff +@if errorlevel 1 goto failure +del setbuff.r01 +as-z80 -l -o setbuff.s01 +@if errorlevel 1 goto failure +copy setbuff.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setenv ..\setenv +@if errorlevel 1 goto failure +del setenv.r01 +as-z80 -l -o setenv.s01 +@if errorlevel 1 goto failure +copy setenv.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setgrent ..\setgrent +@if errorlevel 1 goto failure +del setgrent.r01 +as-z80 -l -o setgrent.s01 +@if errorlevel 1 goto failure +copy setgrent.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setpwent ..\setpwent +@if errorlevel 1 goto failure +del setpwent.r01 +as-z80 -l -o setpwent.s01 +@if errorlevel 1 goto failure +copy setpwent.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setvbuff ..\setvbuff +@if errorlevel 1 goto failure +del setvbuff.r01 +as-z80 -l -o setvbuff.s01 +@if errorlevel 1 goto failure +copy setvbuff.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sleep ..\sleep +@if errorlevel 1 goto failure +del sleep.r01 +as-z80 -l -o sleep.s01 +@if errorlevel 1 goto failure +copy sleep.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sprintf ..\sprintf +@if errorlevel 1 goto failure +del sprintf.r01 +as-z80 -l -o sprintf.s01 +@if errorlevel 1 goto failure +copy sprintf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sscanf ..\sscanf +@if errorlevel 1 goto failure +del sscanf.r01 +as-z80 -l -o sscanf.s01 +@if errorlevel 1 goto failure +copy sscanf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_stdio0 ..\stdio0 +@if errorlevel 1 goto failure +del stdio0.r01 +as-z80 -l -o stdio0.s01 +@if errorlevel 1 goto failure +copy stdio0.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strcat ..\strcat +@if errorlevel 1 goto failure +del strcat.r01 +as-z80 -l -o strcat.s01 +@if errorlevel 1 goto failure +copy strcat.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strchr ..\strchr +@if errorlevel 1 goto failure +del strchr.r01 +as-z80 -l -o strchr.s01 +@if errorlevel 1 goto failure +copy strchr.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strcmp ..\strcmp +@if errorlevel 1 goto failure +del strcmp.r01 +as-z80 -l -o strcmp.s01 +@if errorlevel 1 goto failure +copy strcmp.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strcpy ..\strcpy +@if errorlevel 1 goto failure +del strcpy.r01 +as-z80 -l -o strcpy.s01 +@if errorlevel 1 goto failure +copy strcpy.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strcspn ..\strcspn +@if errorlevel 1 goto failure +del strcspn.r01 +as-z80 -l -o strcspn.s01 +@if errorlevel 1 goto failure +copy strcspn.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strdup ..\strdup +@if errorlevel 1 goto failure +del strdup.r01 +as-z80 -l -o strdup.s01 +@if errorlevel 1 goto failure +copy strdup.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_stricmp ..\stricmp +@if errorlevel 1 goto failure +del stricmp.r01 +as-z80 -l -o stricmp.s01 +@if errorlevel 1 goto failure +copy stricmp.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strlen ..\strlen +@if errorlevel 1 goto failure +del strlen.r01 +as-z80 -l -o strlen.s01 +@if errorlevel 1 goto failure +copy strlen.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strncat ..\strncat +@if errorlevel 1 goto failure +del strncat.r01 +as-z80 -l -o strncat.s01 +@if errorlevel 1 goto failure +copy strncat.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strncmp ..\strncmp +@if errorlevel 1 goto failure +del strncmp.r01 +as-z80 -l -o strncmp.s01 +@if errorlevel 1 goto failure +copy strncmp.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strncpy ..\strncpy +@if errorlevel 1 goto failure +del strncpy.r01 +as-z80 -l -o strncpy.s01 +@if errorlevel 1 goto failure +copy strncpy.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strnicmp ..\strnicmp +@if errorlevel 1 goto failure +del strnicmp.r01 +as-z80 -l -o strnicmp.s01 +@if errorlevel 1 goto failure +copy strnicmp.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strpbrk ..\strpbrk +@if errorlevel 1 goto failure +del strpbrk.r01 +as-z80 -l -o strpbrk.s01 +@if errorlevel 1 goto failure +copy strpbrk.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strrchr ..\strrchr +@if errorlevel 1 goto failure +del strrchr.r01 +as-z80 -l -o strrchr.s01 +@if errorlevel 1 goto failure +copy strrchr.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strsep ..\strsep +@if errorlevel 1 goto failure +del strsep.r01 +as-z80 -l -o strsep.s01 +@if errorlevel 1 goto failure +copy strsep.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strspn ..\strspn +@if errorlevel 1 goto failure +del strspn.r01 +as-z80 -l -o strspn.s01 +@if errorlevel 1 goto failure +copy strspn.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strstr ..\strstr +@if errorlevel 1 goto failure +del strstr.r01 +as-z80 -l -o strstr.s01 +@if errorlevel 1 goto failure +copy strstr.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strtod ..\strtod +@if errorlevel 1 goto failure +del strtod.r01 +as-z80 -l -o strtod.s01 +@if errorlevel 1 goto failure +copy strtod.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strtok ..\strtok +@if errorlevel 1 goto failure +del strtok.r01 +as-z80 -l -o strtok.s01 +@if errorlevel 1 goto failure +copy strtok.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strtol ..\strtol +@if errorlevel 1 goto failure +del strtol.r01 +as-z80 -l -o strtol.s01 +@if errorlevel 1 goto failure +copy strtol.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_strtoul ..\strtoul +@if errorlevel 1 goto failure +del strtoul.r01 +as-z80 -l -o strtoul.s01 +@if errorlevel 1 goto failure +copy strtoul.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_system ..\system +@if errorlevel 1 goto failure +del system.r01 +as-z80 -l -o system.s01 +@if errorlevel 1 goto failure +copy system.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_termcap ..\termcap +@if errorlevel 1 goto failure +del termcap.r01 +as-z80 -l -o termcap.s01 +@if errorlevel 1 goto failure +copy termcap.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_tmpnam ..\tmpnam +@if errorlevel 1 goto failure +del tmpnam.r01 +as-z80 -l -o tmpnam.s01 +@if errorlevel 1 goto failure +copy tmpnam.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_tparam ..\tparam +@if errorlevel 1 goto failure +del tparam.r01 +as-z80 -l -o tparam.s01 +@if errorlevel 1 goto failure +copy tparam.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ttyname ..\ttyname +@if errorlevel 1 goto failure +del ttyname.r01 +as-z80 -l -o ttyname.s01 +@if errorlevel 1 goto failure +copy ttyname.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_tzset ..\tzset +@if errorlevel 1 goto failure +del tzset.r01 +as-z80 -l -o tzset.s01 +@if errorlevel 1 goto failure +copy tzset.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ultoa ..\ultoa +@if errorlevel 1 goto failure +del ultoa.r01 +as-z80 -l -o ultoa.s01 +@if errorlevel 1 goto failure +copy ultoa.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ungetc ..\ungetc +@if errorlevel 1 goto failure +del ungetc.r01 +as-z80 -l -o ungetc.s01 +@if errorlevel 1 goto failure +copy ungetc.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_utsname ..\utsname +@if errorlevel 1 goto failure +del utsname.r01 +as-z80 -l -o utsname.s01 +@if errorlevel 1 goto failure +copy utsname.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vfprintf ..\vfprintf +@if errorlevel 1 goto failure +del vfprintf.r01 +as-z80 -l -o vfprintf.s01 +@if errorlevel 1 goto failure +copy vfprintf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vfscanf ..\vfscanf +@if errorlevel 1 goto failure +del vfscanf.r01 +as-z80 -l -o vfscanf.s01 +@if errorlevel 1 goto failure +copy vfscanf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vprintf ..\vprintf +@if errorlevel 1 goto failure +del vprintf.r01 +as-z80 -l -o vprintf.s01 +@if errorlevel 1 goto failure +copy vprintf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vscanf ..\vscanf +@if errorlevel 1 goto failure +del vscanf.r01 +as-z80 -l -o vscanf.s01 +@if errorlevel 1 goto failure +copy vscanf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vsprintf ..\vsprintf +@if errorlevel 1 goto failure +del vsprintf.r01 +as-z80 -l -o vsprintf.s01 +@if errorlevel 1 goto failure +copy vsprintf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_vsscanf ..\vsscanf +@if errorlevel 1 goto failure +del vsscanf.r01 +as-z80 -l -o vsscanf.s01 +@if errorlevel 1 goto failure +copy vsscanf.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_xitoa ..\xitoa +@if errorlevel 1 goto failure +del xitoa.r01 +as-z80 -l -o xitoa.s01 +@if errorlevel 1 goto failure +copy xitoa.rel ..\..\..\lib\relcl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_xltoa ..\xltoa +@if errorlevel 1 goto failure +del xltoa.r01 +as-z80 -l -o xltoa.s01 +@if errorlevel 1 goto failure +copy xltoa.rel ..\..\..\lib\relcl + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/libc/c0b.asm b/src/libc/c0b.asm new file mode 100755 index 00000000..9e55b758 --- /dev/null +++ b/src/libc/c0b.asm @@ -0,0 +1,305 @@ +; c0b.asm by Nick for UZI180 banked memory model + +; ----------------------------------------------------------------------------- + + .if 0 +$ io64180.s01 + .endif + + module _c0b + + public __init ; vendor _init + .if 0 + extern brk ; vendor _brk + .endif + extern main ; vendor _main + extern exit ; vendor _exit + + extern l__DEFAULT ; e_hsize + extern s_RCODE ; e_idata + extern s_UDATA0 ; e_udata + extern s_CSTACK ; e_stack + extern e_CSTACK ; e_break + + .if 1 + extern ?BANK_CALL_DIRECT_L08 + .endif + +E_MAGIC equ 0a6c9h +E_FORMAT_BANKED equ 2 +E_STACK_SIZE equ 1000h + +; ----------------------------------------------------------------------------- +; forward definitions of segments, to set the linkage order (c0l must be first) + + rseg RCODE +; rseg TEMP +; rseg DATA0 +; rseg WCSTR + rseg CONST + rseg CSTR + rseg IDATA0(NUL) + rseg CDATA0 + rseg ECSTR(NUL) + rseg CCSTR + rseg CODE(NUL) ; needs to be at end for banked model + rseg UDATA0 + rseg CSTACK + +; ----------------------------------------------------------------------------- + + .if 1 + rseg _DEFAULT ; means header is discarded at loading + .else + rseg RCODE ; means header is visible to loaded pgm + .endif + + .if 1 + defw E_MAGIC ; e_magic + defw E_FORMAT_BANKED ; e_format + defd 12345678h ; e_size + defw l__DEFAULT ; e_hsize + defw s_RCODE ; e_idata + defw __init ; e_entry + defw s_UDATA0 ; e_udata + defw s_CSTACK ; e_stack + defw e_CSTACK ; e_break + .else + jp __init + .endif + +; ----------------------------------------------------------------------------- + + rseg RCODE + +__init:: + .if 0 + ld a,'A' + call abyte + .endif + + .if 0 + ld de,.sfb.CSTACK ; 1st argument to brk() + + .if 0 + ld hl,LWRD brk + ld a,BYTE3 brk + call ?BANK_CALL_DIRECT_L08 + .else + call brk + .endif + + call seg_init + .endif + +; now there are the next stack structure: +; +4 envp +; +2 argv +; sp-> +0 argc + .if 1 + pop de + ld (_argc),de ; vendor __argc (2nd argument to main) + pop bc + ld (_argv),bc ; vendor __argv (1st argument to main) + pop hl + ld (environ),hl ; vendor _environ + .else + ld ix,0 + add ix,sp + ld l,(ix+4) + ld h,(ix+5) + ld (environ),hl ; vendor _environ + ld c,(ix+2) + ld b,(ix+3) + ld (_argv),bc ; vendor __argv (1st argument to main) + ld e,(ix+0) + ld d,(ix+1) + ld (_argc),de ; vendor __argc (2nd argument to main) + .endif + + .if 1 + ld HL,LWRD main ; banked call to _main() + ld A,BYTE3 main + call ?BANK_CALL_DIRECT_L08 + .else + call main ; vendor _main ; non-banked call to _main() + .endif + + ex de,hl ; de = exitcode (1st argument to exit) + + .if 1 + ld HL,LWRD exit ; banked call to _exit() + ld A,BYTE3 exit + jp ?BANK_CALL_DIRECT_L08 + .else + jp exit ; vendor _exit ; non-banked call to _exit() + .endif + +; ----------------------------------------------------------------------------- + + .if 0 +seg_init: + ld HL,.sfe.UDATA0 + ld DE,.sfb.UDATA0 + call zero_mem + + ld DE,.sfb.IDATA0 ; destination address + ld HL,.sfe.CDATA0 ;+4000h ; really 8:0000 + .sfe.CDATA0 + ld BC,.sfb.CDATA0 ;+4000h ; really 8:0000 + .sfb.CDATA0 + call copy_mem + + ld DE,.sfb.ECSTR ; destination address + ld HL,.sfe.CCSTR ;+4000h ; really 8:0000 + .sfe.CCSTR + ld BC,.sfb.CCSTR ;+4000h ; really 8:0000 + .sfb.CCSTR + + ; Just fall in to the copy_mem function + +copy_mem: + XOR A + SBC HL,BC + PUSH BC + LD C,L + LD B,H ; BC - that many bytes + POP HL ; source address + RET Z ; If block size = 0 return now + LDIR + RET + +zero_mem: + XOR A +again: PUSH HL + SBC HL,DE + POP HL + RET Z + LD (DE),A + INC DE + JR again + .endif + +; ----------------------------------------------------------------------------- + + .if 0 + public _abyte + +_abyte:: + .if 0 ; SDCC + ld hl,2 + add hl,sp + ld a,(hl) + .else ; IAR + ld a,e + .endif + + public abyte + +abyte:: + .if 0 + ret + .else + push af + .endif + +L1$: in0 a,(STAT1) + and 10b + jr z,L1$ + + pop af + out0 (TDR1),a + + .if 0 + di + .endif + .if 0 + ei + .endif + ret + + public _acrlf + +_acrlf:: + + public acrlf + +acrlf:: + ld a,0dh + call abyte + ld a,0ah + jr abyte + + public _ahexw + +_ahexw:: + .if 0 ; SDCC + ld hl,2 + add hl,sp + ld e,(hl) + inc hl + ld d,(hl) + .endif + ex de,hl + + public ahexw + +ahexw:: + ld a,h + call ahexb + ld a,l + + public ahexb + +ahexb:: + push af + rrca + rrca + rrca + rrca + call ahexn + pop af + + public ahexn + +ahexn:: + and 0fh + add a,90h + daa + adc a,40h + daa + jr abyte + + public amess + +amess:: + ex (sp),hl + push af + +L01$: ld a,(hl) + inc hl + or a + jr z,L02$ + + call abyte + jr L01$ + +L02$: pop af + ex (sp),hl + ret + .endif + +; ----------------------------------------------------------------------------- + + public _argc, _argv, environ, errno, __cleanup + ;public __argc, __argv, _environ, _errno, ___cleanup + + rseg UDATA0 +_argc: defs 2 ; vendor __argc +_argv: defs 2 ; vendor __argv +environ: defs 2 ; vendor _environ +errno: defs 2 ; vendor _errno +__cleanup: defs 3 ; oopsy 2 ; vendor ___cleanup + + rseg CSTACK + defs E_STACK_SIZE + +; ----------------------------------------------------------------------------- + + END diff --git a/src/libc/c0l.asm b/src/libc/c0l.asm new file mode 100755 index 00000000..bc69b550 --- /dev/null +++ b/src/libc/c0l.asm @@ -0,0 +1,305 @@ +; c0l.asm by Nick for UZI180 large memory model + +; ----------------------------------------------------------------------------- + + .if 0 +$ io64180.s01 + .endif + + module _c0l + + public __init ; vendor _init + .if 0 + extern brk ; vendor _brk + .endif + extern main ; vendor _main + extern exit ; vendor _exit + + extern l__DEFAULT ; e_hsize + extern s_RCODE ; e_idata + extern s_UDATA0 ; e_udata + extern s_CSTACK ; e_stack + extern e_CSTACK ; e_break + + .if 0 + extern ?BANK_CALL_DIRECT_L08 + .endif + +E_MAGIC equ 0a6c9h +E_FORMAT_LARGE equ 1 +E_STACK_SIZE equ 1000h + +; ----------------------------------------------------------------------------- +; forward definitions of segments, to set the linkage order (c0l must be first) + + rseg RCODE + rseg CODE ; needs to be at start for large model +; rseg TEMP +; rseg DATA0 +; rseg WCSTR + rseg CONST + rseg CSTR + rseg IDATA0(NUL) + rseg CDATA0 + rseg ECSTR(NUL) + rseg CCSTR + rseg UDATA0 + rseg CSTACK + +; ----------------------------------------------------------------------------- + + .if 1 + rseg _DEFAULT ; means header is discarded at loading + .else + rseg RCODE ; means header is visible to loaded pgm + .endif + + .if 1 + defw E_MAGIC ; e_magic + defw E_FORMAT_LARGE ; e_format + defd 12345678h ; e_size + defw l__DEFAULT ; e_hsize + defw s_RCODE ; e_idata + defw __init ; e_entry + defw s_UDATA0 ; e_udata + defw s_CSTACK ; e_stack + defw e_CSTACK ; e_break + .else + jp __init + .endif + +; ----------------------------------------------------------------------------- + + rseg RCODE + +__init:: + .if 0 + ld a,'A' + call abyte + .endif + + .if 0 + ld de,.sfb.CSTACK ; 1st argument to brk() + + .if 0 + ld hl,LWRD brk + ld a,BYTE3 brk + call ?BANK_CALL_DIRECT_L08 + .else + call brk + .endif + + call seg_init + .endif + +; now there are the next stack structure: +; +4 envp +; +2 argv +; sp-> +0 argc + .if 1 + pop de + ld (_argc),de ; vendor __argc (2nd argument to main) + pop bc + ld (_argv),bc ; vendor __argv (1st argument to main) + pop hl + ld (environ),hl ; vendor _environ + .else + ld ix,0 + add ix,sp + ld l,(ix+4) + ld h,(ix+5) + ld (environ),hl ; vendor _environ + ld c,(ix+2) + ld b,(ix+3) + ld (_argv),bc ; vendor __argv (1st argument to main) + ld e,(ix+0) + ld d,(ix+1) + ld (_argc),de ; vendor __argc (2nd argument to main) + .endif + + .if 0 + ld HL,LWRD main ; banked call to _main() + ld A,BYTE3 main + call ?BANK_CALL_DIRECT_L08 + .else + call main ; vendor _main ; non-banked call to _main() + .endif + + ex de,hl ; de = exitcode (1st argument to exit) + + .if 0 + ld HL,LWRD exit ; banked call to _exit() + ld A,BYTE3 exit + jp ?BANK_CALL_DIRECT_L08 + .else + jp exit ; vendor _exit ; non-banked call to _exit() + .endif + +; ----------------------------------------------------------------------------- + + .if 0 +seg_init: + ld HL,.sfe.UDATA0 + ld DE,.sfb.UDATA0 + call zero_mem + + ld DE,.sfb.IDATA0 ; destination address + ld HL,.sfe.CDATA0 ;+4000h ; really 8:0000 + .sfe.CDATA0 + ld BC,.sfb.CDATA0 ;+4000h ; really 8:0000 + .sfb.CDATA0 + call copy_mem + + ld DE,.sfb.ECSTR ; destination address + ld HL,.sfe.CCSTR ;+4000h ; really 8:0000 + .sfe.CCSTR + ld BC,.sfb.CCSTR ;+4000h ; really 8:0000 + .sfb.CCSTR + + ; Just fall in to the copy_mem function + +copy_mem: + XOR A + SBC HL,BC + PUSH BC + LD C,L + LD B,H ; BC - that many bytes + POP HL ; source address + RET Z ; If block size = 0 return now + LDIR + RET + +zero_mem: + XOR A +again: PUSH HL + SBC HL,DE + POP HL + RET Z + LD (DE),A + INC DE + JR again + .endif + +; ----------------------------------------------------------------------------- + + .if 0 + public _abyte + +_abyte:: + .if 0 ; SDCC + ld hl,2 + add hl,sp + ld a,(hl) + .else ; IAR + ld a,e + .endif + + public abyte + +abyte:: + .if 0 + ret + .else + push af + .endif + +L1$: in0 a,(STAT1) + and 10b + jr z,L1$ + + pop af + out0 (TDR1),a + + .if 0 + di + .endif + .if 0 + ei + .endif + ret + + public _acrlf + +_acrlf:: + + public acrlf + +acrlf:: + ld a,0dh + call abyte + ld a,0ah + jr abyte + + public _ahexw + +_ahexw:: + .if 0 ; SDCC + ld hl,2 + add hl,sp + ld e,(hl) + inc hl + ld d,(hl) + .endif + ex de,hl + + public ahexw + +ahexw:: + ld a,h + call ahexb + ld a,l + + public ahexb + +ahexb:: + push af + rrca + rrca + rrca + rrca + call ahexn + pop af + + public ahexn + +ahexn:: + and 0fh + add a,90h + daa + adc a,40h + daa + jr abyte + + public amess + +amess:: + ex (sp),hl + push af + +L01$: ld a,(hl) + inc hl + or a + jr z,L02$ + + call abyte + jr L01$ + +L02$: pop af + ex (sp),hl + ret + .endif + +; ----------------------------------------------------------------------------- + + public _argc, _argv, environ, errno, __cleanup + ;public __argc, __argv, _environ, _errno, ___cleanup + + rseg UDATA0 +_argc: defs 2 ; vendor __argc +_argv: defs 2 ; vendor __argv +environ: defs 2 ; vendor _environ +errno: defs 2 ; vendor _errno +__cleanup: defs 2 ; vendor ___cleanup + + rseg CSTACK + defs E_STACK_SIZE + +; ----------------------------------------------------------------------------- + + END diff --git a/src/libc/c0u.asm b/src/libc/c0u.asm new file mode 100755 index 00000000..016163a6 --- /dev/null +++ b/src/libc/c0u.asm @@ -0,0 +1,172 @@ +;[]------------------------------------------------------------[] +;| C0.ASM -- TC UZIX Start Up Code | +;| MSX/HTC/UZIX Run Time Library version 1.0 | +;[]------------------------------------------------------------[] + + public small_model +small_model equ 1 + +; psect text,class=CODE +; psect strings,class=CODE +; psect const,class=CODE +; psect data,class=DATA +; psect bss,class=DATA +; psect _bssend,class=DATA + + extrn _main:near, __exit:near + public start, _exit + +; ----------------------------------------------------------------------------- + +; signat _exit,4152 ; arg in DE +; signat __exit,4152 ; arg in DE +; psect text +_TEXT segment byte public 'CODE' + +DGROUP group _TEXT, _DATA, _BSS, _BSSEND + assume cs:DGROUP, ds:DGROUP + +; At the start, SP points to user stack. + org 100h +;;; executable header layout +start: db 0E9h ;0C3h ; for ??? + dw start0-($+2) ;start0 + + org 103h +e_flags db 0 ; bit 7: 1-not refresh system vectors on swapin() +e_text dw offset DGROUP:etext +e_data dw offset DGROUP:edata +e_bss dw offset DGROUP:ebss +e_heap dw 0 +e_stack dw 0 +e_env dw offset DGROUP:__argc +;;; total size of header == 16 bytes + +; org 110h ; not necessary, we're already at exactly 110h +start0: +; int 3 + mov [___stktop], sp + +; Clear BSS +; mov bx, (e_data) +; xchg dx, bx +; mov bx, (e_bss) +; or a ; CLC +; sbc bx, dx +; mov cl, bl +; mov ch, bh +; dec cx ; cx = counter-1 +; mov bl, dl +; mov bh, dh ; bx = e_data +; inc dx ; dx = e_data+1 +; mov byte ptr [bx], 0 +; ldir ; clear bss - always >= 10 bytes + mov di, [e_data] + mov cx, [e_bss] + sub cx, di + sub al, al + rep stosb ; assumes es set up on entry (done by kernel) + + pop cx ; drop retaddr (required for stack consistency) +; now there are the next stack structure: +; +4 envp +; +2 argv +; sp-> +0 argc +; mov bp, 0 +; add bp, sp +; mov bl, [bp+4] +; mov bh, [bp+5] +; mov [_environ],bx +; mov bl, [bp+2] +; mov bh, [bp+3] +; mov [__argv],bx +; mov bl, [bp+0] +; mov bh, [bp+1] +; mov [__argc],bx + push bp + mov bp,sp + mov ax,[bp+6] + mov [_environ],ax + mov ax,[bp+4] + mov [__argv],ax + mov ax,[bp+2] + mov [__argc],ax + pop bp + +start1: + call _main + pop cx + pop cx + pop cx + +; xchg dx, ax ; exit arg in dx + push ax ; push first (and only) argument to exit() + +_exit: +; push dx + mov bx, [___cleanup] + +; mov al, bl +; or al, bh +; call nz, indirect ; (*__cleanup)(exitcode, ???) + test bx,bx + jz skip_call + call bx +skip_call: + +; pop dx +; jp __exit ; to kernel - arg in dx (no, it's on stack) + call __exit + jmp $ ; dynamic halt if kernel returns (extra safe) + +;indirect: +; jp (bx) + +_TEXT ends + +;[]------------------------------------------------------------[] +;| Start Up Data Area | +;| | +;| WARNING Do not move any variables in the data | +;| segment unless you're absolutely sure | +;| that it does not matter. | +;| | +;[]------------------------------------------------------------[] + +; psect data +_DATA segment byte public 'DATA' + +etext label word + +; Memory management variables + public ___heapbase, ___brklvl, ___heaptop, ___stktop + +___heapbase dw ebss +___brklvl dw ebss +___heaptop dw ebss +___stktop dw 0 + +_DATA ends + +; psect bss +_BSS segment byte public 'BSS' + + public __argc, __argv, _environ, _errno, ___cleanup + +edata label word +__argc dw ? +__argv dw ? +_environ dw ? +_errno dw ? +___cleanup dw ? + +_BSS ends + +; psect _bssend +_BSSEND segment byte public 'BSSEND' ;'STACK' + +ebss label word + +_BSSEND ends + + end start diff --git a/src/libc/c9.pmm b/src/libc/c9.pmm new file mode 100755 index 00000000..8a316d4f --- /dev/null +++ b/src/libc/c9.pmm @@ -0,0 +1,7 @@ +; c9.pmm + +; search and replace in files, run in buffer 9 + +ua [qr e uc#asm_asm] +ua [qr e uc#endasm_endasm] + diff --git a/src/libc/calloc.c b/src/libc/calloc.c new file mode 100755 index 00000000..0327131d --- /dev/null +++ b/src/libc/calloc.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + * + * This is a combined alloca/malloc package. It uses a classic algorithm + * and so may be seen to be quite slow compared to more modern routines + * with 'nasty' distributions. + */ + +#if 1 /* Nick */ +#include "alloca-l.h" +#else +#include "malloc-l.h" +#endif + +#ifdef L_calloc +void *calloc(elm, sz) + unsigned elm, sz; +{ + register unsigned v = elm*sz; + register void *ptr = malloc(v); + + if (ptr) + memset(ptr, 0, v); + return ptr; +} +#endif /* L_calloc */ + diff --git a/src/libc/clock.c b/src/libc/clock.c new file mode 100755 index 00000000..4cd621ba --- /dev/null +++ b/src/libc/clock.c @@ -0,0 +1,15 @@ +/*************************** CLOCK ************************************/ +#include "time-l.h" + +#ifdef L_clock +#include +#include + +long clock(VOID) { + struct tms __tms; + + times(&__tms); + return (__tms.tms_utime.t_time+__tms.tms_utime.t_date*CLOCKS_PER_SEC*60); +} +#endif + diff --git a/src/libc/closedir.c b/src/libc/closedir.c new file mode 100755 index 00000000..d07507b9 --- /dev/null +++ b/src/libc/closedir.c @@ -0,0 +1,26 @@ +/* close.c closedir implementation + * + */ +#include +#include +#include +#include +#include +#include +#include + +int closedir(dir) + register DIR *dir; +{ + if (dir == NULL || dir->dd_buf == NULL || dir->dd_fd == 0) { + errno = EFAULT; + return -1; + } + close(dir->dd_fd); + free(dir->dd_buf); + dir->dd_fd = 0; + dir->dd_buf = NULL; + free(dir); + return 0; +} + diff --git a/src/libc/convtime.c b/src/libc/convtime.c new file mode 100755 index 00000000..e8704eb9 --- /dev/null +++ b/src/libc/convtime.c @@ -0,0 +1,64 @@ +/* UZIX time format (very simular to msdos) + * + * time_t.data: + * + * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0| + * | | | | | | | | | | | | | | | | | + * \ 7 bits /\4 bits/\ 5 bits / + * year+1980 month day + * + * time_t.time: + * + * |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0| + * | | | | | | | | | | | | | | | | | + * \ 5 bits /\ 6 bits /\ 5 bits / + * hour minutes sec*2 + */ + +/* + * Convert a UZIX time & date to the Unix time() format. + * (adapted from mtools convdate) + * + * Adapted from UZI280 by Stefan Nitchske + */ + +#include "time-l.h" +#include + +unsigned long +convtime(time_field) +time_t *time_field; +{ + unsigned year, mon, mday, hour, min, sec, old_leaps; + unsigned long answer, sec_year, sec_mon, sec_mday, + sec_hour, sec_min, sec_leap; + static unsigned month[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, + 334}; + /* disect the parts */ + year = ( (time_field->t_date&0xfe00) >> 9) + 1980; + if (year<1972) + year += 100; + mon = (time_field->t_date&0x01e0) >> 5; + mday = time_field->t_date&0x1f; + hour = (time_field->t_time&0xf800) >> 11; + min = (time_field->t_time&0x07e0) >> 5; + sec = (time_field->t_time&0x001f) * 2; + /* how many previous leap years */ + year = year - 1970; + old_leaps = year / 4; + sec_leap = old_leaps * 24L * 60L * 60L; + /* back off 1 day if before 29 Feb */ + if (!(year % 4) && mon < 3) + sec_leap -= 24L * 60L * 60L; + + sec_year = year * 365L * 24L * 60L * 60L; + mon = month[mon -1]; + sec_mon = mon * 24L * 60L * 60L; + sec_mday = mday * 24L * 60L * 60L; + sec_hour = hour * 60L * 60L; + sec_min = min * 60L; + + answer = sec_leap + sec_year + sec_mon + sec_mday + sec_hour + + sec_min + (long)sec + (long)timezone; + return(answer); +} diff --git a/src/libc/crypt.c b/src/libc/crypt.c new file mode 100755 index 00000000..44f53356 --- /dev/null +++ b/src/libc/crypt.c @@ -0,0 +1,64 @@ +/* TEA based crypt(), version 0.0 + * It looks like there are problems with key bits carrying through + * to the encrypted data, and I want to get rid of that libc call.. + */ +/* #include Nick */ +#include +#include +#include + +char *crypt(key, salt) + char *key, *salt; +{ + /* n is the number of rounds, + * delta is a golden # derivative, + * k is the key, + * v is the data to be encrypted. + */ + static char rkey[4*sizeof(long)]; + unsigned long v[2], k[4], sum, delta = 0x9e3779b9L, *p; + unsigned char i, n; + + /* Our constant string will be a string of zeros .. */ + memset(rkey,0,sizeof(rkey)); + memcpy(rkey, salt, 2); + i = 0; + while (i < sizeof(rkey)-2 && key[i]) { + rkey[i+2] = key[i]; + ++i; + } + while (key[i]) { + rkey[2] += key[i]; + ++i; + } + memcpy(k, rkey, sizeof(k)); + v[0] = v[1] = sum = 0; + for (i = 64; i != 0; --i) { + sum += delta; + v[0] += (v[1] << 4) + k[0] ^ v[1] + sum ^ (v[1] >> 5) + k[1]; + v[1] += (v[0] << 4) + k[2] ^ v[0] + sum ^ (v[0] >> 5) + k[3]; + } + /* Now we need to unpack the bits and map it to "A-Za-z0-9./" + * for printing in /etc/passwd + */ + p = v; + for (i = 2; i < 13; i++) { + /* This unpacks the 6 bit data, each cluster into its own byte */ + if (i == 8) { + v[0] |= v[1] >> 28; + ++p; + } + n = *p & 0x3F; + *p >>= 6; + /* Now we map to the proper chars */ + if (n < 12) n += '.'; + else if (n < 38) n += 'A'-12; + else n += 'a'-38; + rkey[i] = n; + } + rkey[13] = '\0'; +/* printf("crypt(\"%s\", 0x%x) yielded \"%s\"\n", key, salt, rkey); */ +/* fflush(stdout); */ + return rkey; +} + diff --git a/src/libc/cstartup.r01 b/src/libc/cstartup.r01 new file mode 100755 index 0000000000000000000000000000000000000000..1028bd7fa99a8911ff9d01a358d6565243442ea6 GIT binary patch literal 1537 zcmaJ<&rcIU6rOH(wo8dYB}R^mnrJ*IQS&Nkg4VVs@;hyT1EK4-E+cy*9Vb-cl=*es@ zk;x4WW?3kA@$3a7;W+k8p=4K#;X5}vAaQf#_N{LA!OD0kt+H zafE}Kjhg19ZOs)d$Lr5!72P!P8%y)0z^OI~XLWWiAT=~P)#+o7=D|&?GEo#Jmr#h9 z4+u44m*=M{vtDDaN8@&-Ql1SwI&N1i*;e_fyImaLW28;uRGCmE)ChILXq>){P$5(a zH9|cerfMo7ooQU7IO3w^!eeo?#nJy|F>Fb9-SH;ED4~007;NV0?u4CseHrt5eKb~c z^33f^3phAO^-W~)DN4fjnBZheluS$1F0^A4unV2|mO(`v2M(9=)V|u_><0zqhY*g{ zl0sJ+^gOtQh9MNIWrfZp9s6-7E>j2a6|M`XE;*Or9efb2rX+d?Hpl4m{1NaDi zkb*tvK_>LKj4F z=}$O-7rwkE$xB$V#rt`y*CqK7H)?@TunJe<3*1L+gB{q%MK9qpyvG)}Usc|;4UVw0 Leb~CU_qzTU)% + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include +#include + +#undef toupper +#undef tolower + +unsigned char __ctype[256] = { + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x00..0x03 */ + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x04..0x07 */ + __CT_c, __CT_c|__CT_s, __CT_c|__CT_s, __CT_c|__CT_s, /* 0x08..0x0B */ + __CT_c|__CT_s, __CT_c|__CT_s, __CT_c, __CT_c, /* 0x0C..0x0F */ + + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x10..0x13 */ + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x14..0x17 */ + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x18..0x1B */ + __CT_c, __CT_c, __CT_c, __CT_c, /* 0x1C..0x1F */ + + __CT_s, __CT_p, __CT_p, __CT_p, /* 0x20..0x23 */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x24..0x27 */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x28..0x2B */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x2C..0x2F */ + + __CT_d|__CT_x, __CT_d|__CT_x, __CT_d|__CT_x, __CT_d|__CT_x, /* 0x30..0x33 */ + __CT_d|__CT_x, __CT_d|__CT_x, __CT_d|__CT_x, __CT_d|__CT_x, /* 0x34..0x37 */ + __CT_d|__CT_x, __CT_d|__CT_x, __CT_p, __CT_p, /* 0x38..0x3B */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x3C..0x3F */ + + __CT_p, __CT_u|__CT_x, __CT_u|__CT_x, __CT_u|__CT_x, /* 0x40..0x43 */ + __CT_u|__CT_x, __CT_u|__CT_x, __CT_u|__CT_x, __CT_u, /* 0x44..0x47 */ + __CT_u, __CT_u, __CT_u, __CT_u, /* 0x48..0x4B */ + __CT_u, __CT_u, __CT_u, __CT_u, /* 0x4C..0x4F */ + + __CT_u, __CT_u, __CT_u, __CT_u, /* 0x50..0x53 */ + __CT_u, __CT_u, __CT_u, __CT_u, /* 0x54..0x57 */ + __CT_u, __CT_u, __CT_u, __CT_p, /* 0x58..0x5B */ + __CT_p, __CT_p, __CT_p, __CT_p, /* 0x5C..0x5F */ + + __CT_p, __CT_l|__CT_x, __CT_l|__CT_x, __CT_l|__CT_x, /* 0x60..0x63 */ + __CT_l|__CT_x, __CT_l|__CT_x, __CT_l|__CT_x, __CT_l, /* 0x64..0x67 */ + __CT_l, __CT_l, __CT_l, __CT_l, /* 0x68..0x6B */ + __CT_l, __CT_l, __CT_l, __CT_l, /* 0x6C..0x6F */ + + __CT_l, __CT_l, __CT_l, __CT_l, /* 0x70..0x73 */ + __CT_l, __CT_l, __CT_l, __CT_l, /* 0x74..0x77 */ + __CT_l, __CT_l, __CT_l, __CT_p, /* 0x78..0x7B */ + __CT_p, __CT_p, __CT_p, __CT_c /* 0x7C..0x7F */ +}; + +int toupper(c) + register int c; +{ + return (islower(c) ? (c ^ 0x20) : (c)); +} + +int tolower(c) + register int c; +{ + return (isupper(c) ? (c ^ 0x20) : (c)); +} + diff --git a/src/libc/cvt.h b/src/libc/cvt.h new file mode 100755 index 00000000..c4951d4d --- /dev/null +++ b/src/libc/cvt.h @@ -0,0 +1,21 @@ +/* numeric/string conversions package + */ +#include + +#ifdef MAKE_ALL +#define L_atoi +#define L_atol +#define L_itoa +#define L_ultoa +#define L_ltoa +#define L_ltostr +#define L_strtod +#define L_strtoul +#define L_strtol +#define L_xitoa +#define L_xltoa +#ifdef __TURBOC__ +#define FLOAT +#endif +#endif + diff --git a/src/libc/difftime.c b/src/libc/difftime.c new file mode 100755 index 00000000..37327f09 --- /dev/null +++ b/src/libc/difftime.c @@ -0,0 +1,22 @@ +/*************************** DIFFTIME **********************************/ +#include "time-l.h" + +#ifdef L_difftime +long difftime (__time2,__time1) + time_t *__time2; + time_t *__time1; +{ + struct tm tma, tmb; + unsigned long tm1,tm2; + + __tm_conv(&tma, __time1, 0); + __tm_conv(&tmb, __time2, 0); + /* each year is 365 days plus 8 hours = 365.25 days */ + tm1 = tma.tm_year*32227200L+tma.tm_yday*86400L+tma.tm_hour*3600+ + tma.tm_min*60+tma.tm_sec; + tm2 = tmb.tm_year*32227200L+tmb.tm_yday*86400L+tmb.tm_hour*3600+ + tmb.tm_min*60+tmb.tm_sec; + return (tm2-tm1); +} +#endif + diff --git a/src/libc/environ.h b/src/libc/environ.h new file mode 100755 index 00000000..8aea5593 --- /dev/null +++ b/src/libc/environ.h @@ -0,0 +1,12 @@ +/* Environment processing package + */ +#define const +#include +#include + +#ifdef MAKE_ALL +#define L_getenv +#define L_putenv +#define L_setenv +#endif + \ No newline at end of file diff --git a/src/libc/error.c b/src/libc/error.c new file mode 100755 index 00000000..52d83587 --- /dev/null +++ b/src/libc/error.c @@ -0,0 +1,57 @@ +/* Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include +#include +#include +#include +#include + +char **__sys_errlist =0; +int __sys_nerr = 0; + +char *strerror(err) + int err; +{ + static char retbuf[80]; + char *p, inbuf[128]; + int cc, fd; + uint i, bufoff = 0; + + if (__sys_nerr) { /* sys_errlist preloaded */ + if (err < 0 || err >= __sys_nerr) + goto UErr; + return __sys_errlist[err]; + } + if (err <= 0) + goto UErr; /* NB the <= allows comments in the file */ + if ((fd = open(_PATH_LIBERR, 0)) < 0) + goto UErr; + while ((cc = read(fd, inbuf, sizeof(inbuf))) > 0) { + i = 0; + while (i < cc) { + if (inbuf[i] == '\n') { + retbuf[bufoff] = '\0'; + if (err == atoi(retbuf)) { + if ((p = strchr(retbuf, ' ')) == NULL) { + close(fd); + goto UErr; + } + while (*p == ' ') + p++; + close(fd); + return p; + } + bufoff = 0; + } + else if (bufoff < sizeof(retbuf)-1) + retbuf[bufoff++] = inbuf[i]; + ++i; + } + } +UErr: strcpy(retbuf, "Unknown error "); + itoa(err,retbuf+strlen(retbuf),10); + return retbuf; +} + diff --git a/src/libc/etime.c b/src/libc/etime.c new file mode 100755 index 00000000..ba8ad9de --- /dev/null +++ b/src/libc/etime.c @@ -0,0 +1,83 @@ +/* etime.c added by Nick from UZI280 clib, since not included in UZIX1.0 */ + +#include /* also types.h */ +#include /* for the HZ definition */ +#define HZ TICKSPERSEC /* due to change in nomenclature */ + +/* Convert date to string */ + +static char *s; + +#if 0 /* Nick... see ctime.c, it is more advanced and has GMT conversion */ +char * +ctime(t) +register time_t *t; +{ + static char str[24]; + + s = str; + + dout((t->t_time&0xf800)>>11); + *s++ = ':'; + dout((t->t_time&0x07e0)>>5); + *s++ = ':'; + dout(t->t_time&0x001f * 2); + *s++ = ' '; + dout((t->t_date&0x01e0)>>5); + *s++ = '/'; + dout(t->t_date&0x001f); + *s++ = '/'; + dout((t->t_date&0xfe00)>>9); + *s = '\0'; + + return(str); +} +#endif + + +/* Convert elapsed time to string as: hh:mm:ss.t */ + +char * +etime(t) +register time_t *t; +{ + static char str[24]; + + s = str; + + dout(t->t_date / 60); + *s++ = ':'; + dout(t->t_date % 60); + *s++ = ':'; + dout(t->t_time / HZ); + *s++ = '.'; + *s++ = (((t->t_time % HZ) * 10) / HZ) + '0'; + *s = '\0'; + + return(str); +} + + +static dout(n) +register int n; +{ + n %= 100; + *s++ = n/10 + '0'; + *s++ = n%10 + '0'; +} + + +/* This decrements t1 by t2 */ + +ediff(t1, t2) +register time_t *t1, *t2; +{ + if (t1->t_time < t2->t_time) + { + --t1->t_date; + t1->t_time += (60 * HZ); + } + t1->t_date -= t2->t_date; + t1->t_time -= t2->t_time; +} + diff --git a/src/libc/exec.h b/src/libc/exec.h new file mode 100755 index 00000000..ae7899ad --- /dev/null +++ b/src/libc/exec.h @@ -0,0 +1,112 @@ +/* exec.h + * + * function(s) + * execl - load and run a program + * execle - load and execute a program + * execlp - load and execute a program + * execlpe - load and execute a program + * execv - load and execute a program + * exect - load and execute a program + * execvp - load and execute a program + * execvpe - load and execute a program + */ +#include +#include + +#ifdef MAKE_ALL +#define L_execl +#define L_execle +#define L_execlp +#define L_execlpe +#define L_execv +#define L_exect +#define L_execvp +#define L_execvpe +#endif + +/*--------------------------------------------------------------------------* +Name exec... - functions that load and run other programs + +Usage int execl(char *pathname, char *arg0, char *arg1, ..., + char *argn, NULL); + int execle(char *pathname, char *arg0, char *arg1, ..., + char *argn, NULL, char *envp[]); + int execlp(char *pathname, char *arg0, char *arg1, ..., + char *argn, NULL); + int execlpe(char *pathname, char *arg0, char *arg1, ..., + char *argn, NULL, char *envp[]); + int execv(char *pathname, char *argv[]); + int exect(char *pathname, char *argv[], char *envp[]); + int execvp(char *pathname, char *argv[]); + int execvpe(char *pathname, char *argv[], char *envp[]); + +Prototype in unistd.h + +Description The functions in the exec... family load and run (execute) + other programs, known as child processes. When an exec... + call is successful, the child process running concurently + with the parent process. There must be sufficient memory + available for loading and executing the child process. + + The suffixes l, v, p and e added to exec... "family name" + specify that the named function will operate with certain + capabilities. + + p specifies that the function will search for the + child in those directories specified by the + PATH environment variable. If pathname does not + contain an explicit directory the function will + search first the current directory then in the + directory specified by the path. Without the p + suffix, the function only searches the current + working directory. + + l specifies that the argument pointers (arg0, arg1, + ..., argn) are passed as separate arguments. + Typically, the l suffix is used when you know in + advance the number of arguments to be passed. A + mandatory NULL following argn marks the end of + the list. + + v specifies that the argument pointers (argv[0], + argv[1], ..., argv[n]) are passed as an array of + pointers. Typically, the v suffix is used a + variable number of arguments is to be passed. + + e specifies that the argument envp maybe passed to + the child process, allowing you to alter the + environment for the child process. Without the e + suffix, child process inherits the environment of + the parent process. This environment argument is + an array of char *. Each element points to a + null-terminated character string of the form: + + envar=value + + where envar is the name of an environment + variable, and value is the string value to which + envar is set. The last element of envp[] is NULL. + When envp[0] is NULL, the child inherits the + parent's environment settings. + + The exec... functions must at least one argument to the + child process. This argument is, by convention, a copy of + pathname. Under MS-DOS 3.x, path name is available for the + child process; under earlier versions, the child cannot use + the passed value of arg0 (or argv[0]). + + When an exec... function call is made, any open files + remain open in the child process. + +Return value If successful, the exec... functions do not return. On + error, the exec... functions return -1, and errno is set to + one of the following: + E2BIG Argument list too long + EACCES Permission denied + EMFILE Too many open files + ENOENT Path or file name not found + ENOEXEC Exec format error + ENOMEM Not enough core + ESHELL File is shell script??? +*/ + diff --git a/src/libc/execl.c b/src/libc/execl.c new file mode 100755 index 00000000..99c8cc99 --- /dev/null +++ b/src/libc/execl.c @@ -0,0 +1,65 @@ +/* execl.c + * + * function(s) + * execl - load and run a program + */ + +#include "exec.h" + +#ifdef L_execl +#include +#include + +/* Find file in pathes: + * 1. /name or ./name or ../name is already qualified names + * 2. else search in all pathes described in env var PATH (if this + * var is not exist, _PATH_DEFPATH is used) + * 3. else search in current directory + * 4. else return NULL (execve() interpretes NULL as non existent file!) + */ +char *_findPath(path) + char *path; +{ + char *p, *envp; + static char name[PATHLEN+1]; + + if (*path == '/' || /* qualified name */ + *path == '.') + return path; + /* search for pathes list */ + if ((envp = getenv("PATH")) == NULL) + envp = _PATH_DEFPATH; + /* lookup all pathes */ + while (*envp) { + p = name; + while (*envp && (*p = *envp++) != ':') { + if ((uint)(p - name) >= sizeof(name)) + break; + ++p; + } + if (*--p != '/') + *++p = '/'; + ++p; + if ((p - name) + strlen(path) >= sizeof(name)) + break; + strcpy(p, path); + if (access(name, 0) == 0) + return name; + } + if (access(path,0) == 0) /* file exist in current dir */ + return name; + return NULL; +} + +#if 1 /* Nick */ +int execl(char *pathP, char *arg0, ...) +#else +int execl(pathP, arg0, ...) + char *pathP; + char *arg0; +#endif +{ + return execve(pathP, &arg0, environ); +} +#endif + diff --git a/src/libc/execle.c b/src/libc/execle.c new file mode 100755 index 00000000..ae4f46ef --- /dev/null +++ b/src/libc/execle.c @@ -0,0 +1,26 @@ +/* execle.c + * + * function(s) + * execle - load and execute a program + */ + +#include "exec.h" + +#ifdef L_execle +#if 1 /* Nick */ +int execle(char *pathP, char *arg0, ...) +#else +int execle(pathP, arg0) + char *pathP; + char *arg0; +#endif +{ + register char **p = &arg0; + + /* Find the end of the argument list */ + while (*p++) + ; + return execve(pathP, &arg0, (char **)*p); +} +#endif + diff --git a/src/libc/execlp.c b/src/libc/execlp.c new file mode 100755 index 00000000..5aa7ff5b --- /dev/null +++ b/src/libc/execlp.c @@ -0,0 +1,21 @@ +/* execlp.c + * + * function(s) + * execlp - load and execute a program + */ + +#include "exec.h" + +#ifdef L_execlp +#if 1 /* Nick */ +int execlp(char *pathP, char *arg0, ...) +#else +int execlp(pathP, arg0) + char *pathP; + char *arg0; +#endif +{ + return execve(_findPath(pathP), &arg0, environ); +} +#endif + diff --git a/src/libc/execlpe.c b/src/libc/execlpe.c new file mode 100755 index 00000000..d48c4d65 --- /dev/null +++ b/src/libc/execlpe.c @@ -0,0 +1,26 @@ +/* execlpe.c + * + * function(s) + * execlpe - load and execute a program + */ + +#include "exec.h" + +#ifdef L_execlpe +#if 1 /* Nick */ +int execlpe(char *pathP, char *arg0, ...) +#else +int execlpe(pathP, arg0) + char *pathP; + char *arg0; +#endif +{ + register char **p = &arg0; + + /* Find the end of the argument list */ + while (*p++) + ; + return execve(_findPath(pathP), &arg0, (char **)*p); +} +#endif + diff --git a/src/libc/exect.c b/src/libc/exect.c new file mode 100755 index 00000000..afc5ad33 --- /dev/null +++ b/src/libc/exect.c @@ -0,0 +1,18 @@ +/* exect.c + * + * function(s) + * exect - load and execute a program + */ + +#include "exec.h" + +#ifdef L_exect +int exect(pathP, argv, envV) + char *pathP; + char *argv[]; + char *envV[]; +{ + return execve(pathP, argv, envV); +} +#endif + diff --git a/src/libc/execv.c b/src/libc/execv.c new file mode 100755 index 00000000..69cbde79 --- /dev/null +++ b/src/libc/execv.c @@ -0,0 +1,17 @@ +/* execv.c + * + * function(s) + * execv - load and execute a program + */ + +#include "exec.h" + +#ifdef L_execv +int execv(pathP, argv) + char *pathP; + char *argv[]; +{ + return execve(pathP, argv, environ); +} +#endif + diff --git a/src/libc/execvp.c b/src/libc/execvp.c new file mode 100755 index 00000000..8779494d --- /dev/null +++ b/src/libc/execvp.c @@ -0,0 +1,17 @@ +/* execvp.c + * + * function(s) + * execvp - load and execute a program + */ + +#include "exec.h" + +#ifdef L_execvp +int execvp(pathP, argv) + char *pathP; + char *argv[]; +{ + return execve(_findPath(pathP), argv, environ); +} +#endif + diff --git a/src/libc/execvpe.c b/src/libc/execvpe.c new file mode 100755 index 00000000..8d291fe4 --- /dev/null +++ b/src/libc/execvpe.c @@ -0,0 +1,18 @@ +/* execvpe.c + * + * function(s) + * execvpe - load and execute a program + */ + +#include "exec.h" + +#ifdef L_execvpe +int execvpe(pathP, argv, envV) + char *pathP; + char *argv[]; + char *envV[]; +{ + return execve(_findPath(pathP), argv, envV); +} +#endif + diff --git a/src/libc/exit.c b/src/libc/exit.c new file mode 100755 index 00000000..9435599f --- /dev/null +++ b/src/libc/exit.c @@ -0,0 +1,14 @@ +/* exit.c for UZI180 by Nick */ + +#include /* for exit() prototype */ +#include /* for _exit() prototype */ + +void exit(int val) + { + if (__cleanup != NULL) + { + (*__cleanup)(val, NULL); + } + _exit(val); + } + diff --git a/src/libc/fclose.c b/src/libc/fclose.c new file mode 100755 index 00000000..f16c5abf --- /dev/null +++ b/src/libc/fclose.c @@ -0,0 +1,48 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_fclose +int fclose(fp) + FILE *fp; +{ + int rv = 0; + + if (fp == 0) { + errno = EINVAL; + return EOF; + } + if (fflush(fp)) + return EOF; + if (close(fp->fd)) + rv = EOF; + fp->fd = -1; + if (fp->mode & __MODE_FREEBUF) { + free(fp->bufstart); + fp->mode &= ~__MODE_FREEBUF; + fp->bufstart = fp->bufend = 0; + } + if (fp->mode & __MODE_FREEFIL) { + FILE *ptr = __IO_list, *prev = 0; + + fp->mode = 0; + while (ptr && ptr != fp) + ptr = ptr->next; + if (ptr == fp) { + if (prev == 0) + __IO_list = fp->next; + else prev->next = fp->next; + } + free(fp); + } + else fp->mode = 0; + return rv; +} +#endif + diff --git a/src/libc/fflush.c b/src/libc/fflush.c new file mode 100755 index 00000000..72572270 --- /dev/null +++ b/src/libc/fflush.c @@ -0,0 +1,71 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_fflush +int fflush(fp) + FILE *fp; +{ + unsigned char *bstart; + int len, cc, rv = 0; + + if (fp == NULL) { /* On NULL flush the lot. */ + if (fflush(stdin) || fflush(stdout) || fflush(stderr)) + return EOF; + fp = __IO_list; + while (fp) { + if (fflush(fp)) + return EOF; + fp = fp->next; + } + return 0; + } + /* If there's output data pending */ + if (fp->mode & __MODE_WRITING) { + if ((len = fp->bufpos - fp->bufstart) != 0) { + bstart = fp->bufstart; + /* The loop is so we don't get upset by signals + * or partial writes. + */ + do { + if ((cc = write(fp->fd, bstart, len)) > 0) { + bstart += cc; + len -= cc; + } + } while (cc > 0 || (cc == -1 && errno == EINTR)); + /* If we get here with len != 0 there was an error, + * exactly what to do about it is another matter ... + * + * I'll just clear the buffer. */ + if (len) { + fp->mode |= __MODE_ERR; + rv = EOF; + } + } + } + /* If there's data in the buffer sychronise the file positions */ + else if (fp->mode & __MODE_READING) { + /* Humm, I think this means sync the file like fpurge() ... + * Anyway the user isn't supposed to call this function + * when reading + */ + len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */ + /* If it's a file, make it good */ + if (len > 0 && lseek(fp->fd, (long) -len, SEEK_CUR) < 0) { + /* Hummm - Not certain here, I don't think this is reported */ + /* fp->mode |= __MODE_ERR; return EOF; */ + } + } + /* All done, no problem */ + fp->mode &= (~(__MODE_READING | __MODE_WRITING | __MODE_EOF | __MODE_UNGOT)); + fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart; + return rv; +} +#endif + diff --git a/src/libc/fgetc.c b/src/libc/fgetc.c new file mode 100755 index 00000000..bc8d825f --- /dev/null +++ b/src/libc/fgetc.c @@ -0,0 +1,44 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_fgetc +int fgetc(fp) + FILE *fp; +{ + int ch; + + if (fp->mode & __MODE_WRITING) + fflush(fp); +#if __MODE_IOTRAN +try_again: +#endif + /* Can't read or there's been an EOF or error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return EOF; + /* Nothing in the buffer - fill it up */ + if (fp->bufpos >= fp->bufread) { + fp->bufpos = fp->bufread = fp->bufstart; + ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp); + if (ch == 0) + return EOF; + fp->bufread += ch; + fp->mode |= __MODE_READING; + fp->mode &= ~__MODE_UNGOT; + } + ch = *(fp->bufpos++); +#if __MODE_IOTRAN + /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */ + if (ch == '\r' && (fp->mode & __MODE_IOTRAN)) + goto try_again; +#endif + return ch; +} +#endif + diff --git a/src/libc/fgetgren.c b/src/libc/fgetgren.c new file mode 100755 index 00000000..0bb6e195 --- /dev/null +++ b/src/libc/fgetgren.c @@ -0,0 +1,17 @@ +/* fgetgren.c groups implementation + */ + +#include "grp-l.h" + +#ifdef L_fgetgren +struct group *fgetgrent(file) + FILE *file; +{ + if (file == NULL) { + errno = EINTR; + return NULL; + } + return __getgrent(fileno(file)); +} +#endif + \ No newline at end of file diff --git a/src/libc/fgetpwen.c b/src/libc/fgetpwen.c new file mode 100755 index 00000000..447f8d51 --- /dev/null +++ b/src/libc/fgetpwen.c @@ -0,0 +1,17 @@ +/* fgetpwen.c + */ + +#include "passwd.h" + +#ifdef L_fgetpwen +struct passwd *fgetpwent(file) + FILE *file; +{ + if (file == NULL) { + errno = EINTR; + return NULL; + } + return __getpwent(fileno(file)); +} +#endif + diff --git a/src/libc/fgets.c b/src/libc/fgets.c new file mode 100755 index 00000000..ef975a80 --- /dev/null +++ b/src/libc/fgets.c @@ -0,0 +1,36 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_fgets +/* Nothing special here ... */ +char *fgets(s, count, f) + char *s; + size_t count; + FILE *f; +{ + register size_t i = count; + register int ch; + char *ret = s; + + while (i-- != 0) { + if ((ch = getc(f)) == EOF) { + if (s == ret) + return NULL; + break; + } + *s++ = (char) ch; + if (ch == '\n') + break; + } + *s = 0; + return ferror(f) ? NULL : ret; +} +#endif + diff --git a/src/libc/fopen.c b/src/libc/fopen.c new file mode 100755 index 00000000..b89f3081 --- /dev/null +++ b/src/libc/fopen.c @@ -0,0 +1,131 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_fopen +/* + * This Fopen is all three of fopen, fdopen and freopen. The macros in + * stdio.h show the other names. + */ +FILE *__fopen(fname, fd, fp, mode) + char *fname; + int fd; + FILE *fp; + char *mode; +{ + uint open_mode = 0; +#if __MODE_IOTRAN + int do_iosense = 1; +#endif + int fopen_mode = 0; + FILE *nfp = 0; + + /* If we've got an fp close the old one (freopen) */ + if (fp) { + /* Careful, don't de-allocate it */ + fopen_mode |= (fp->mode & (__MODE_BUF | + __MODE_FREEFIL | + __MODE_FREEBUF)); + fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF); + fclose(fp); + } + /* decode the new open mode */ + while (*mode) { + switch (*mode++) { + case 'r': + fopen_mode |= __MODE_READ; + break; + case 'w': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_TRUNC); + break; + case 'a': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_APPEND); + break; + case '+': + fopen_mode |= __MODE_RDWR; + break; +#if __MODE_IOTRAN + case 'b': /* Binary */ + fopen_mode &= ~__MODE_IOTRAN; + do_iosense = 0; + break; + case 't': /* Text */ + fopen_mode |= __MODE_IOTRAN; + do_iosense = 0; + break; +#endif + } + } + /* Add in the read/write options to mode for open() */ + switch (fopen_mode & (__MODE_READ | __MODE_WRITE)) { + case 0: + return NULL; + case __MODE_READ: +#if O_RDONLY + open_mode |= O_RDONLY; +#endif + break; + case __MODE_WRITE: + open_mode |= O_WRONLY; + break; + default: + open_mode |= O_RDWR; + break; + } + /* Allocate the (FILE) before we do anything irreversable */ + if (fp == NULL && (nfp = calloc(1,sizeof(FILE))) == NULL) + return NULL; + /* Open the file itself */ + if (fname) + fd = open(fname, open_mode, 0666); + if (fd < 0) { /* Grrrr */ + open_mode = errno; /* Nick */ + if (nfp) + free(nfp); + errno = open_mode; /* Nick */ + return 0; + } + /* If this isn't freopen create a (FILE) and buffer for it */ + if (fp == NULL) { + fp = nfp; + fp->next = __IO_list; + __IO_list = fp; /* add to list */ + fp->mode = __MODE_FREEFIL; + if (isatty(fd)) { + fp->mode |= _IOLBF; +#if __MODE_IOTRAN + if (do_iosense) + fopen_mode |= __MODE_IOTRAN; +#endif + } +#if _IOFBF + else fp->mode |= _IOFBF; +#endif + if ((fp->bufstart = calloc(1,BUFSIZ)) == NULL) { + /* Oops, no mem + * Humm, full buffering with a eight(!) byte buffer. + */ + fp->bufstart = (uchar *)fp->unbuf; + fp->bufend = (uchar *)fp->unbuf + sizeof(fp->unbuf); + } + else { + fp->bufend = fp->bufstart + BUFSIZ; + fp->mode |= __MODE_FREEBUF; + } + } + /* Ok, file's ready clear the buffer and save important bits */ + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + fp->mode |= fopen_mode; + fp->fd = fd; + return fp; +} +#endif + diff --git a/src/libc/fprintf.c b/src/libc/fprintf.c new file mode 100755 index 00000000..8cbe825a --- /dev/null +++ b/src/libc/fprintf.c @@ -0,0 +1,36 @@ +/* printf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +#include "printf.h" + +#ifdef L_fprintf +#if 1 +int fprintf(FILE * fp, char *fmt,...) +#else +int fprintf(fp, fmt, va_alist) + FILE *fp; + char *fmt; + va_dcl +#endif +{ + va_list ptr; + int rv; + + va_strt(ptr, fmt); + rv = vfprintf(fp, fmt, ptr); + va_end(ptr); + return rv; +} +#endif + diff --git a/src/libc/fputc.c b/src/libc/fputc.c new file mode 100755 index 00000000..388abcd1 --- /dev/null +++ b/src/libc/fputc.c @@ -0,0 +1,49 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_fputc +int fputc(ch, fp) + int ch; + FILE *fp; +{ + register int v; + + Inline_init; + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return EOF; + /* Can't write or there's been an EOF or error then return EOF */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return EOF; +#if __MODE_IOTRAN + /* In MSDOS translation mode */ + if (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF) + return EOF; +#endif + /* Buffer is full */ + if (fp->bufpos >= fp->bufend && fflush(fp)) + return EOF; + /* Right! Do it! */ + *(fp->bufpos++) = ch; + fp->mode |= __MODE_WRITING; + + /* Unbuffered or Line buffered and end of line */ + if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF)) && fflush(fp)) + return EOF; + /* Can the macro handle this by itself ? */ + if (v & (__MODE_IOTRAN | _IOLBF | _IONBF)) + fp->bufwrite = fp->bufstart; /* Nope */ + else fp->bufwrite = fp->bufend; /* Yup */ + /* Correct return val */ + return (unsigned char) ch; +} +#endif + diff --git a/src/libc/fputs.c b/src/libc/fputs.c new file mode 100755 index 00000000..c4e35022 --- /dev/null +++ b/src/libc/fputs.c @@ -0,0 +1,27 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_fputs +int fputs(str, fp) + void *str; + FILE *fp; +{ + register int n = 0; + char *s = str; + + while (*s) { + if (putc(*s++, fp) == EOF) + return (EOF); + ++n; + } + return (n); +} +#endif + diff --git a/src/libc/fread.c b/src/libc/fread.c new file mode 100755 index 00000000..e41eec71 --- /dev/null +++ b/src/libc/fread.c @@ -0,0 +1,62 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_fread +/* + * fread will often be used to read in large chunks of data calling read() + * directly can be a big win in this case. Beware also fgetc calls this + * function to fill the buffer. + * + * This ignores __MODE__IOTRAN; probably exactly what you want. + * (It _is_ what fgetc wants) + */ +int fread(buf, size, nelm, fp) + void *buf; + size_t size, nelm; + FILE *fp; +{ + register int len, v; + unsigned bytes, got = 0; + + Inline_init; + if (!buf || !size || !nelm || !fp) + return 0; + v = fp->mode; + /* Want to do this to bring the file pointer up to date */ + if (v & __MODE_WRITING) + fflush(fp); + /* Can't read or there's been an EOF or error then return zero */ + if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return 0; + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + len = fp->bufread - fp->bufpos; + if (len >= bytes) { /* Enough buffered */ + memcpy(buf, fp->bufpos, bytes); + fp->bufpos += bytes; + return bytes; + } + else if (len > 0) { /* Some buffered */ + memcpy(buf, fp->bufpos, len); + got = len; + } + /* Need more; do it with a direct read */ + len = read(fp->fd, (char *)buf + got, bytes - got); + /* Possibly for now _or_ later */ + if (len < 0) { + fp->mode |= __MODE_ERR; + len = 0; + } + else if (len == 0) + fp->mode |= __MODE_EOF; + return (got + len) / size; +} +#endif + diff --git a/src/libc/free.c b/src/libc/free.c new file mode 100755 index 00000000..7547fd4b --- /dev/null +++ b/src/libc/free.c @@ -0,0 +1,37 @@ +/* free.c */ +/* Copyright (C) 1984 by Manx Software Systems */ + +#include "malloc-l.h" + +int free(void *area) + { + register FREE *tp, *hole; + +#ifdef MALLOC_DEBUG + printf("free(0x%x) starting\n"); + fflush(stdout); +#endif + + hole = (FREE *)area - 1; + if (hole->f_chain != NULL) + { +#ifdef MALLOC_DEBUG + printf("free() returning -1\n"); + fflush(stdout); +#endif + return -1; + } + for (tp = last ; tp > hole || hole > tp->f_chain ; tp = tp->f_chain) + if (tp >= tp->f_chain && (hole > tp || hole < tp->f_chain)) + break; + + hole->f_chain = tp->f_chain; + tp->f_chain = hole; + last = tp; +#ifdef MALLOC_DEBUG + printf("free() returning 0\n"); + fflush(stdout); +#endif + return 0; + } + diff --git a/src/libc/free.c$ b/src/libc/free.c$ new file mode 100755 index 00000000..44fb4e59 --- /dev/null +++ b/src/libc/free.c$ @@ -0,0 +1,148 @@ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + * + * This is a combined alloca/malloc package. It uses a classic algorithm + * and so may be seen to be quite slow compared to more modern routines + * with 'nasty' distributions. + */ + +#include "malloc-l.h" + +#ifdef L_free +/* Start the alloca with just the dumb version of malloc */ +void *(*__alloca_alloc) __P((size_t)) = __mini_malloc; +/* the free list is a single list of free blocks. __freed_list points to + the highest block (highest address) and each block points to the lower + block (lower address). last block points to 0 (initial value of + _freed_list) +*/ +mem *__freed_list = 0; + +#ifdef VERBOSE +/* NB: Careful here, stdio may use malloc - so we can't */ +#include +#include +#include + +static void pstr __P((char *)); +static void phex __P((unsigned)); +static void noise __P((char *, mem *)); + +static void pstr(str) + char *str; +{ + write(2, str, strlen(str)); +} + +static void phex(val) + unsigned val; +{ + char buf[8]; + + strcpy(buf,"000"); + ltoa((long)val,buf+3,16); + pstr(buf+strlen(buf+4)); +} + +void __noise(y, x) + char *y; + mem *x; +{ + pstr("Malloc "); phex((unsigned)x); + pstr(" sz "); phex(x ? (unsigned)m_size(x) : 0); + pstr(" nxt "); phex(x ? (unsigned)m_next(x) : 0); + pstr(" is "); pstr(y); pstr("\n"); +} +#endif + +void free(ptr) + void *ptr; +{ + register mem *top, *chk = (mem *)ptr; + + if (chk == 0) + return; /* free(NULL) - be nice */ + chk--; +try_this:; + top = (mem *) sbrk(0); + if (m_add(chk, m_size(chk)) >= top) { + noise("FREE brk", chk); + brk((void *)((uchar *)top - m_size(chk))); + /* Adding this code allow free to release blocks in any order; + * they can still only be allocated from the top of the heap + * tho. + */ +#ifdef __MINI_MALLOC__ + if (__alloca_alloc == __mini_malloc && __freed_list) { + chk = __freed_list; + __freed_list = m_next(__freed_list); + goto try_this; + } +#endif + } + else { /* Nope, not sure where this goes, leave it for malloc to deal with */ +#ifdef __MINI_MALLOC__ + /* check if block is already on free list. + if it is, return without doing nothing */ + top = __freed_list; + while (top) { + if (top == chk) return; + top = m_next(top); + } + /* else add it to free list */ + if (!__freed_list || chk > __freed_list) { + /* null free list or block above free list */ + m_next(chk) = __freed_list; + __freed_list = chk; + } + else { + /* insert block in free list, ordered by address */ + register mem *prev = __freed_list; + + top = __freed_list; + while (top && top > chk) { + prev = top; + top = m_next(top); + } + m_next(chk) = top; + m_next(prev) = chk; + } +#else + m_next(chk) = __freed_list; + __freed_list = chk; +#endif + noise("ADD LIST", chk); + } +} + +void *__mini_malloc(size) + size_t size; +{ + register mem *ptr; + register unsigned int sz; + + /* First time round this _might_ be odd, But we won't do that! */ +#if 0 + sz = (unsigned int) sbrk(0); + if (sz & (sizeof(struct mem_cell) - 1)) { + if (sbrk(sizeof(struct mem_cell) - (sz & (sizeof(struct mem_cell) - 1))) < 0) goto nomem; + } +#endif + if (size == 0) + return 0; + /* Minor oops here, sbrk has a signed argument */ + if (size > (((unsigned) -1) >> 1) - sizeof(struct mem_cell) * 3) { +nomem: errno = ENOMEM; + return 0; + } + size += sizeof(struct mem_cell); /* Round up and leave space for size field */ + ptr = (mem *) sbrk(size); + if ((int) ptr == -1) + return 0; + m_size(ptr) = size; + noise("CREATE", ptr); + return ptr + 1; +} +#endif /* L_free */ + diff --git a/src/libc/fscanf.c b/src/libc/fscanf.c new file mode 100755 index 00000000..76340ba9 --- /dev/null +++ b/src/libc/fscanf.c @@ -0,0 +1,25 @@ +/* scanf.c + */ + +#include "scanf.h" + +#ifdef L_fscanf +#if 1 +int fscanf(FILE * fp, char *fmt,...) +#else +int fscanf(fp, fmt, va_alist) + FILE *fp; + char *fmt; + va_dcl +#endif +{ + va_list ptr; + int rv; + + va_strt(ptr, fmt); + rv = vfscanf(fp, fmt, ptr); + va_end(ptr); + return rv; +} +#endif + \ No newline at end of file diff --git a/src/libc/ftell.c b/src/libc/ftell.c new file mode 100755 index 00000000..c4edb878 --- /dev/null +++ b/src/libc/ftell.c @@ -0,0 +1,20 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_ftell +long ftell(fp) + FILE *fp; +{ + if (fflush(fp) == EOF) + return EOF; + return lseek(fp->fd, 0L, SEEK_CUR); +} +#endif + diff --git a/src/libc/fwrite.c b/src/libc/fwrite.c new file mode 100755 index 00000000..0c5c9be4 --- /dev/null +++ b/src/libc/fwrite.c @@ -0,0 +1,70 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_fwrite +/* + * Like fread, fwrite will often be used to write out large chunks of + * data; calling write() directly can be a big win in this case. + * + * But first we check to see if there's space in the buffer. + * + * Again this ignores __MODE__IOTRAN. + */ +int fwrite(buf, size, nelm, fp) + void *buf; + size_t size, nelm; + FILE *fp; +{ + int len; + register int v; + unsigned int bytes, put; + + Inline_init; + if (!buf || !size || !nelm || !fp) + return 0; + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return 0; + /* Can't write or there's been an EOF or error then return 0 */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return 0; + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + len = fp->bufend - fp->bufpos; + /* Flush the buffer if not enough room */ + if (bytes > len && fflush(fp)) + return 0; + len = fp->bufend - fp->bufpos; + if (bytes <= len) { /* It'll fit in the buffer ? */ + fp->mode |= __MODE_WRITING; + memcpy(fp->bufpos, buf, bytes); + fp->bufpos += bytes; + /* If we're not fully buffered */ + if (v & (_IOLBF | _IONBF)) + fflush(fp); + return nelm; + } + /* Too big for the buffer */ + /* ??? May be leave the rest of data in buffer ? */ + put = bytes; + do { + if ((len = write(fp->fd, buf, bytes)) > 0) { + buf = (char *)buf + len; + bytes -= len; + } + } while (len > 0 || (len == -1 && errno == EINTR)); + if (len < 0) + fp->mode |= __MODE_ERR; + put -= bytes; + return put / size; +} +#endif + diff --git a/src/libc/getcwd.c b/src/libc/getcwd.c new file mode 100755 index 00000000..1025f2fb --- /dev/null +++ b/src/libc/getcwd.c @@ -0,0 +1,103 @@ +/* These functions find the absolute path to the current working directory. + * + * They don't use malloc or large amounts of stack space. + */ +#include +#include +#include +#include + +static char *search_dir __P((uint, uint)); /* Routine to find the step back down */ +static char *recurser __P((void)); /* Routine to go up tree */ +static char *path_buf; +static int path_size; + +static uint root_dev; +static uint root_ino; +static struct stat st; + +static char *search_dir(this_dev, this_ino) + uint this_dev; + uint this_ino; +{ + struct dirent *d; + char *ptr; + int slen; + DIR *dp; + unsigned char slow_search = 0; + + if (stat(path_buf, &st) < 0) + return NULL; + if (this_dev != st.st_dev) + ++slow_search; + slen = strlen(path_buf); + ptr = path_buf + slen - 1; + if (*ptr != '/') { + if (slen + 2 > path_size) { + errno = ERANGE; + return NULL; + } + strcpy(++ptr, "/"); + ++slen; + } + ++slen; + if ((dp = opendir(path_buf)) == 0) + return NULL; + while ((d = readdir(dp)) != 0) { + if (slow_search || this_ino == d->d_ino) { + if (slen + strlen(d->d_name) > path_size) { + errno = ERANGE; + return NULL; + } + strcpy(ptr + 1, d->d_name); + if (stat(path_buf, &st) < 0) + continue; + if (st.st_ino == this_ino && + st.st_dev == this_dev) { + closedir(dp); + return path_buf; + } + } + /* else ??? */ + } + closedir(dp); + errno = ENOENT; + return NULL; +} + +static char *recurser() { + uint this_dev; + uint this_ino; + + if (stat(path_buf, &st) < 0) + return NULL; + this_dev = st.st_dev; + this_ino = st.st_ino; + if (this_dev == root_dev && this_ino == root_ino) { + strcpy(path_buf, "/"); + return path_buf; + } + if (strlen(path_buf) + 4 > path_size) { + errno = ERANGE; + return NULL; + } + strcat(path_buf, "/.."); + return recurser() ? search_dir(this_dev, this_ino) : NULL; +} + +char *getcwd(buf, size) + char *buf; + int size; +{ + if ((path_size = size) < 3) { + errno = ERANGE; + return 0; + } + strcpy(path_buf = buf, "."); + if (stat("/", &st) < 0) + return NULL; /* no root */ + root_dev = st.st_dev; + root_ino = st.st_ino; + return recurser(); +} + \ No newline at end of file diff --git a/src/libc/getenv.c b/src/libc/getenv.c new file mode 100755 index 00000000..7b0279db --- /dev/null +++ b/src/libc/getenv.c @@ -0,0 +1,27 @@ +/*********************** getenv.c *************************** +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "environ.h" + +#ifdef L_getenv +char *getenv(name) + char *name; +{ + register char *p, **ep = environ; + register int l = strlen(name); + + if (ep == 0 || l == 0) + return 0; + while ((p = *ep++) != NULL) { + if (p[0] == name[0] && + p[l] == '=' && + memcmp(name, p, l) == 0) + return p + l + 1; + } + return NULL; +} +#endif + \ No newline at end of file diff --git a/src/libc/getgrent.c b/src/libc/getgrent.c new file mode 100755 index 00000000..bad15f1b --- /dev/null +++ b/src/libc/getgrent.c @@ -0,0 +1,87 @@ +/* getgrent.c groups implementation + */ + +#include "grp-l.h" + +#ifdef L_getgrent +#define GR_MAX_LINE_LEN 200 +/* This is the core group-file read function. It behaves exactly like + * getgrent() except that it is passed a file descriptor. getgrent() + * is just a wrapper for this function. + */ +struct group *__getgrent(grp_fd) + int grp_fd; +{ + static char line_buff[GR_MAX_LINE_LEN]; + static char *members[GR_MAX_MEMBERS+1]; + static struct group group; + + char *field_begin, *endptr; + int member_num, line_len; + register char *ptr; + + /* We use the restart label to handle malformatted lines */ +restart: + /* Read the line into the static buffer */ + if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) + return NULL; + if ((field_begin = strchr(line_buff, '\n')) != NULL) { + *field_begin++ = '\0'; + lseek(grp_fd, (long) ((field_begin - line_buff) - line_len), SEEK_CUR); + if (field_begin[-2] == '\r') + field_begin[-2] = '\0'; + } + else { /* The line is too long - skip it :-\ */ + do { + if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) + return NULL; + } while (0 == (field_begin = strchr(line_buff, '\n'))); + lseek(grp_fd, (long) ((field_begin - line_buff) - line_len + 1), SEEK_CUR); + goto restart; + } + if (*line_buff == '#' || + *line_buff == ' ' || + *line_buff == '\n' || + *line_buff == '\t') + goto restart; + /* Now parse the line */ + group.gr_name = line_buff; + if ((ptr = strchr(line_buff, ':')) == NULL) + goto restart; + *ptr++ = '\0'; + + group.gr_passwd = ptr; + if ((ptr = strchr(ptr, ':')) == NULL) + goto restart; + *ptr++ = '\0'; + + field_begin = ptr; + if ((ptr = strchr(ptr, ':')) == NULL) + goto restart; + *ptr++ = '\0'; + + group.gr_gid = (int)strtol(field_begin, &endptr, 10); + if (*endptr != '\0') + goto restart; + + field_begin = ptr; + member_num = 0; + while ((ptr = strchr(ptr, ',')) != NULL) { + *ptr = '\0'; + ptr++; + members[member_num] = field_begin; + field_begin = ptr; + if (member_num < GR_MAX_MEMBERS) + member_num++; + } + if (*field_begin == '\0') + members[member_num] = NULL; + else { + members[member_num] = field_begin; + members[member_num + 1] = NULL; + } + group.gr_mem = members; + return &group; +} +#endif + \ No newline at end of file diff --git a/src/libc/getgrgid.c b/src/libc/getgrgid.c new file mode 100755 index 00000000..6f6764d6 --- /dev/null +++ b/src/libc/getgrgid.c @@ -0,0 +1,21 @@ +/* getgrgid.c groups implementation + */ + +#include "grp-l.h" + +#ifdef L_getgrgid +struct group *getgrgid(gid) + int gid; +{ + struct group *group; + + setgrent(); + while ((group = getgrent()) != NULL) { + if (group->gr_gid == gid) + break; + } + endgrent(); + return group; +} +#endif + \ No newline at end of file diff --git a/src/libc/getgrnam.c b/src/libc/getgrnam.c new file mode 100755 index 00000000..a47a8608 --- /dev/null +++ b/src/libc/getgrnam.c @@ -0,0 +1,25 @@ +/* getgrnam.c groups implementation + */ + +#include "grp-l.h" + +#ifdef L_getgrnam +struct group *getgrnam(name) + char *name; +{ + struct group *group; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + setgrent(); + while ((group = getgrent()) != NULL) { + if (!strcmp(group->gr_name, name)) + break; + } + endgrent(); + return group; +} +#endif + \ No newline at end of file diff --git a/src/libc/getopt.c b/src/libc/getopt.c new file mode 100755 index 00000000..f27fcfce --- /dev/null +++ b/src/libc/getopt.c @@ -0,0 +1,66 @@ +/* + * getopt - parse command-line options + */ +/* $Header: getopt.c,v 1.1 89/12/18 14:39:31 eck Exp $ */ + +#include +#include +#include + +#define ERR(s, c) if(opterr){\ + fputs(argv[0], stderr);\ + fputs(s, stderr);\ + fputc(c, stderr);\ + fputc('\n', stderr);} + +int opterr = 1; +int optind = 1; +int optopt; +char *optarg; + +int +getopt(argc, argv, opts) +int argc; +char **argv; +char *opts; +{ + static int sp = 1; + register int c; + register char *cp; + + if (sp == 1) + if (optind >= argc || + argv[optind][0] != '-' || argv[optind][1] == '\0') + return EOF; + else if (!strcmp(argv[optind], "--")) { + optind++; + return EOF; + } + optopt = c = argv[optind][sp]; + if (c == ':' || (cp=strchr(opts, c)) == NULL) { + ERR (": illegal option -- ", c); + if (argv[optind][++sp] == '\0') { + optind++; + sp = 1; + } + return '?'; + } + if (*++cp == ':') { + if (argv[optind][sp+1] != '\0') + optarg = &argv[optind++][sp+1]; + else if (++optind >= argc) { + ERR (": option requires an argument -- ", c); + sp = 1; + return '?'; + } else + optarg = argv[optind++]; + sp = 1; + } else { + if (argv[optind][++sp] == '\0') { + sp = 1; + optind++; + } + optarg = NULL; + } + return c; +} diff --git a/src/libc/getpass.c b/src/libc/getpass.c new file mode 100755 index 00000000..c7692301 --- /dev/null +++ b/src/libc/getpass.c @@ -0,0 +1,70 @@ +/* getpass.c + */ +#include +#include +#include +/* Nick #include */ +#include /* Nick */ + +static char *_gets(buf, len) + char *buf; + int len; +{ + int ch, i = 0; + + while (i < len) { + if ((ch = _getchar()) == EOF && i == 0) + return NULL; +#if 0 + if (ch >= ' ') + _putchar(ch); + else { + _putchar('^'); + _putchar(ch + '@'); + } +#endif + if ((ch == 'C' & 037) || (ch == 'Z' & 037)) + return NULL; + if (ch == '\n' || ch == '\r') + break; + buf[i++] = ch; + } + buf[i] = 0; + return buf; +} + +char *getpass(prompt) + char *prompt; +{ + static char result[128]; +#if 1 /* Nick */ + struct sgttyb state; +#endif + int raw; + + /* display the prompt */ + fputs(prompt, stdout); + fflush(stdout); +#if 1 /* Nick */ + gtty(STDIN_FILENO, &state); + raw = state.sg_flags; + state.sg_flags &= ~ECHO; + stty(STDIN_FILENO, &state); +#else + raw = ioctl(STDIN_FILENO, TTY_RAW); +#endif + /* read the input */ + if (_gets(result, sizeof(result) - 1) == NULL) + result[0] = 0; +#if 1 /* Nick */ + state.sg_flags = raw; + stty(STDIN_FILENO, &state); +#else + if (!raw) + ioctl(STDIN_FILENO, TTY_COOKED); +#endif +/* printf("getpass(\"%s\") yielded \"%s\"\n", prompt, result); */ +/* fflush(stdout); */ + return result; +} + \ No newline at end of file diff --git a/src/libc/getpw.c b/src/libc/getpw.c new file mode 100755 index 00000000..b98aa2a5 --- /dev/null +++ b/src/libc/getpw.c @@ -0,0 +1,29 @@ +/* getpw.c + */ + +#include "passwd.h" + +#ifdef L_getpw +int getpw(uid, buf) + int uid; + char *buf; +{ + struct passwd *pwd; + + if (buf == NULL) { + errno = EINVAL; + return -1; + } + if ((pwd = getpwuid(uid)) == NULL) + return -1; + sprintf(buf, "%s:%s:%u:%u:%s:%s:%s", + pwd->pw_name, + pwd->pw_passwd, + pwd->pw_uid, pwd->pw_gid, + pwd->pw_gecos, + pwd->pw_dir, + pwd->pw_shell); + return 0; +} +#endif + diff --git a/src/libc/getpwent.c b/src/libc/getpwent.c new file mode 100755 index 00000000..9d4c177f --- /dev/null +++ b/src/libc/getpwent.c @@ -0,0 +1,70 @@ +/* getpwent.c + */ + +#include "passwd.h" + +#ifdef L_getpwent +#define PWD_BUFFER_SIZE 256 + +struct passwd *__getpwent(pwd_fd) + int pwd_fd; +{ + static char line_buff[PWD_BUFFER_SIZE]; + static struct passwd passwd; + + char *field_begin, *endptr, *gid_ptr, *uid_ptr; + int i, line_len; + + /* We use the restart label to handle malformatted lines */ +restart: + /* Read the passwd line into the static buffer using a minimal of syscalls. */ + if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0) + return NULL; + if ((field_begin = strchr(line_buff, '\n')) != NULL) { + *field_begin++ = '\0'; + lseek(pwd_fd, (long) ((field_begin - line_buff) - line_len), SEEK_CUR); + if (field_begin[-2] == '\r') + field_begin[-2] = '\0'; + } + else { /* The line is too long - skip it. :-\ */ + do { + if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0) + return NULL; + } while (0 == (field_begin = strchr(line_buff, '\n'))); + lseek(pwd_fd, (long) (field_begin - line_buff) - line_len + 1, SEEK_CUR); + goto restart; + } + if (*line_buff == '#' || + *line_buff == ' ' || + *line_buff == '\n' || + *line_buff == '\t') + goto restart; + /* We've read the line; now parse it. */ + field_begin = line_buff; + for (i = 0; i < 7; i++) { + switch (i) { + case 0: passwd.pw_name = field_begin; break; + case 1: passwd.pw_passwd = field_begin; break; + case 2: uid_ptr = field_begin; break; + case 3: gid_ptr = field_begin; break; + case 4: passwd.pw_gecos = field_begin; break; + case 5: passwd.pw_dir = field_begin; break; + case 6: passwd.pw_shell = field_begin; break; + } + if (i < 6) { + field_begin = strchr(field_begin, ':'); + if (field_begin == NULL) + goto restart; + *field_begin++ = '\0'; + } + } + passwd.pw_gid = (int)strtoul(gid_ptr, &endptr, 10); + if (*endptr != '\0') + goto restart; + passwd.pw_uid = (int)strtoul(uid_ptr, &endptr, 10); + if (*endptr != '\0') + goto restart; + return &passwd; +} +#endif + \ No newline at end of file diff --git a/src/libc/getpwnam.c b/src/libc/getpwnam.c new file mode 100755 index 00000000..f9fc683c --- /dev/null +++ b/src/libc/getpwnam.c @@ -0,0 +1,27 @@ +/* getpwnam.c + */ + +/* #include Nick */ +#include "passwd.h" + +#ifdef L_getpwnam +struct passwd *getpwnam(name) + char *name; +{ + struct passwd *pwd; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + setpwent(); + while ((pwd = getpwent()) != NULL) { +/* printf("getpwent() returned pw_name = \"%s\"\n", pwd->pw_name); */ + if (!strcmp(pwd->pw_name, name)) + break; + } + endpwent(); + return pwd; +} +#endif + diff --git a/src/libc/getpwuid.c b/src/libc/getpwuid.c new file mode 100755 index 00000000..0a83461b --- /dev/null +++ b/src/libc/getpwuid.c @@ -0,0 +1,21 @@ +/* getpwuid.c + */ + +#include "passwd.h" + +#ifdef L_getpwuid +struct passwd *getpwuid(uid) + int uid; +{ + struct passwd *pwd; + + setpwent(); + while ((pwd = getpwent()) != NULL) { + if (pwd->pw_uid == uid) + break; + } + endpwent(); + return pwd; +} +#endif + diff --git a/src/libc/gets.c b/src/libc/gets.c new file mode 100755 index 00000000..a147959f --- /dev/null +++ b/src/libc/gets.c @@ -0,0 +1,39 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_gets +char *gets(str) /* BAD function; DON'T use it! */ + char *str; +{ + /* Auwlright it will work but of course _your_ program will crash */ + /* if it's given a too long line */ + register int c; + register char *p = str; + + while (((c = getc(stdin)) != EOF) && (c != '\n')) + *p++ = c; + *p = '\0'; + return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */ +} +#endif + +#ifdef L_puts +int puts(str) + void *str; +{ + register int n; + + if (((n = fputs(str, stdout)) == EOF) + || (putc('\n', stdout) == EOF)) + return (EOF); + return (++n); +} +#endif + diff --git a/src/libc/gmtime.c b/src/libc/gmtime.c new file mode 100755 index 00000000..e961b06d --- /dev/null +++ b/src/libc/gmtime.c @@ -0,0 +1,141 @@ +/*************************** GMTIME ************************************/ +#include "time-l.h" + +#ifdef L_gmtime + +static unsigned int __mon_days[12] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +void __tm_conv(tmbuf, pt, offset) + struct tm *tmbuf; + time_t *pt; + int offset; +{ + register int y, i, wday, yday; + + tmbuf->tm_sec = (pt->t_time & 31) * 2; + tmbuf->tm_min = ((pt->t_time >> 5) & 63) + offset; + tmbuf->tm_hour = ((pt->t_time >> 11) & 31); + + tmbuf->tm_mday = (pt->t_date & 31); + tmbuf->tm_mon = ((pt->t_date >> 5) & 15) - 1; + y = ((pt->t_date >> 9) & 127) + 1980; + + while (tmbuf->tm_min < 0) { + tmbuf->tm_min += 60; + tmbuf->tm_hour--; + while (tmbuf->tm_hour < 0) { + tmbuf->tm_hour += 24; + i = __mon_days[tmbuf->tm_mon]; + if (tmbuf->tm_mon == 1 && __isleap(y)) + ++i; + tmbuf->tm_mday--; + while (tmbuf->tm_mday < 0) { + tmbuf->tm_mday += i; + tmbuf->tm_mon--; + while (tmbuf->tm_mon <= 0) { + tmbuf->tm_mon += 12; + --y; + } + } + } + } + while (tmbuf->tm_min >= 60) { + tmbuf->tm_min -= 60; + tmbuf->tm_hour++; + while (tmbuf->tm_hour >= 24) { + tmbuf->tm_hour -= 24; + i = __mon_days[tmbuf->tm_mon]; + if (tmbuf->tm_mon == 1 && __isleap(y)) + ++i; + tmbuf->tm_mday++; + while (tmbuf->tm_mday > i) { + tmbuf->tm_mday -= i; + tmbuf->tm_mon++; + while (tmbuf->tm_mon >= 12) { + tmbuf->tm_mon -= 12; + ++y; + } + } + } + } + tmbuf->tm_year = y - 1900; + if (y > 1996) { + /* Jan 1, 1997 was Wen */ + i = 1997; + wday = 2; + } + else { + /* Jan 1, 1970 was Thu */ + i = 1970; + wday = 3; + } + while (i < y) { + wday += __isleap(i) ? 2 : 1; + ++i; + } + i = 0; + yday = tmbuf->tm_mday; + while (i < tmbuf->tm_mon) { + yday += __mon_days[i]; + if (i == 1 && __isleap(i)) + ++yday; + ++i; + } + tmbuf->tm_wday = (wday + yday) % 7; + tmbuf->tm_yday = yday + 1; + tmbuf->tm_isdst = -1; +#if TIME_T_IS_JUST_A_LONG_NUMBER + long t = unixtime(pt); + + days = t / SECS_PER_DAY; + rem = t % SECS_PER_DAY; + rem += offset; + while (rem < 0) { + rem += SECS_PER_DAY; + --days; + } + while (rem >= SECS_PER_DAY) { + rem -= SECS_PER_DAY; + ++days; + } + tmbuf->tm_hour = rem / SECS_PER_HOUR; + rem %= SECS_PER_HOUR; + tmbuf->tm_min = rem / 60; + tmbuf->tm_sec = rem % 60; + /* January 1, 1970 was a Thursday. */ + tmbuf->tm_wday = (4 + days) % 7; + if (tmbuf->tm_wday < 0) + tmbuf->tm_wday += 7; + y = 1970; + while (days >= (rem = __isleap(y) ? 366 : 365)) { + ++y; + days -= rem; + } + while (days < 0) { + --y; + days += __isleap(y) ? 366 : 365; + } + tmbuf->tm_year = y - 1900; + tmbuf->tm_yday = days; + ip = __mon_lengths[__isleap(y)]; + y = 0; + while (days >= ip[y]) + days -= ip[y++]; + tmbuf->tm_mon = y; + tmbuf->tm_mday = days + 1; + tmbuf->tm_isdst = -1; +#endif +} + +struct tm *gmtime(timep) + time_t *timep; +{ + static struct tm tmb; + + __tm_conv(&tmb, timep, (int)(timezone/60)); + return &tmb; +} +#endif + diff --git a/src/libc/grp-l.h b/src/libc/grp-l.h new file mode 100755 index 00000000..3cc83329 --- /dev/null +++ b/src/libc/grp-l.h @@ -0,0 +1,21 @@ +/* grp-l.h groups implementation + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef MAKE_ALL +#define L_fgetgren +#define L_getgrgid +#define L_getgrnam +#define L_setgrent +#define L_initgroup +#define L_getgrent +#endif + \ No newline at end of file diff --git a/src/libc/initgrup.c b/src/libc/initgrup.c new file mode 100755 index 00000000..d4351768 --- /dev/null +++ b/src/libc/initgrup.c @@ -0,0 +1,35 @@ +/* initgrup.c groups implementation + */ + +#include "grp-l.h" + +#ifdef L_initgrou +int initgroups(user, gid) + char *user; + int gid; +{ + register struct group *group; + int group_list[GR_MAX_GROUPS]; + register char **tmp_mem; + int num_groups; + + num_groups = 0; + group_list[num_groups] = gid; + setgrent(); + while (num_groups < GR_MAX_GROUPS && (group = getgrent()) != NULL) { + if (group->gr_gid != gid) { + tmp_mem = group->gr_mem; + while (*tmp_mem != NULL) { + if (!strcmp(*tmp_mem, user)) { + num_groups++; + group_list[num_groups] = group->gr_gid; + } + tmp_mem++; + } + } + } + endgrent(); + return setgroups(num_groups, group_list); +} +#endif + \ No newline at end of file diff --git a/src/libc/isatty.c b/src/libc/isatty.c new file mode 100755 index 00000000..b4b5fabb --- /dev/null +++ b/src/libc/isatty.c @@ -0,0 +1,13 @@ +/* isatty.c + */ +#include +#include + +int isatty(int fd) { + struct stat stat; + + if (fstat(fd,&stat) == -1 || (stat.st_mode & S_IFMT) != S_IFCHR) + return 0; + return 1; +} + \ No newline at end of file diff --git a/src/libc/itoa.c b/src/libc/itoa.c new file mode 100755 index 00000000..18848aeb --- /dev/null +++ b/src/libc/itoa.c @@ -0,0 +1,199 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/**************************** ltoa.c ****************************/ +#ifdef L_itoa +/* + * filename - ltoa.c + * + * function(s) + * itoa - converts an integer to a string + * ltoa - converts a long to a string + * ultoa - converts an unsigned long to a string + * __longtoa - converts a long to a character string + */ + +/* +Name __longtoa - converts a long to a character string +Usage char *__longtoa (unsigned long value, char *strP, int radix, + char maybeSigned, char hexStyle); +Prototype in stdlib.h + +Description converts a long to a character string. see itoa below. + +Return value pointer to the string +*/ +/*#pragma warn -use*/ +char *__longtoa(unsigned long value, char *strP, int radix, + char maybeSigned, char hexStyle) { + char buf[34]; + register char *di = strP, *si = buf; +#ifdef __TURBOC__ + int *p = (int *)&value; + + hexStyle -= 10; + /* If the request is invalid, generate an empty result */ + if (radix > 36 || radix < 2) + goto lta_end; + if (((int *)&value)[1] < 0 && maybeSigned) { + *di++ = '-'; + value = -value; + } + /* Now loop, taking each digit as modulo radix, and reducing the value + * by dividing by radix, until the value is zeroed. Note that + * at least one loop occurs even if the value begins as 0, + * since we want "0" to be generated rather than "". + */ + /* BX = radix, CX:AX = value */ + _CX = radix; + if (((int *)&value)[1] == 0) + goto lta_shortLoop; + +lta_longLoop: + do { + _AX = ((int *)&value)[1]; + __emit__(0x33,0xD2); /* xor dx,dx */ + __emit__(0xF7,0xF1); /* div cx */ + p[1] = _AX; + _AX = ((int *)&value)[0]; + __emit__(0xF7,0xF1); /* div cx */ + p[0] = _AX; + *si++ = _DL; + } while (p[1] != 0); /* value does not fit in 16 bits */ + goto lta_shortTest; + +lta_shortLoop: + do { + _AX = ((int *)&value)[0]; + __emit__(0x33,0xD2); /* xor dx,dx */ + __emit__(0xF7,0xF1); /* div cx */ + p[0] = _AX; + *si++ = _DL; +lta_shortTest: ; + } while (p[0] != 0); + /* The value has now been reduced to zero and the + * digits are in the buffer. + */ + _CX = si-buf; /* CX = length of numeral */ + /* The digits in the buffer must now be copied in reverse order into + * the target string, translating to ASCII as they are moved. + */ + while ((int)--_CX >= 0) { + _AL = *--si; + if (_AL < 10) + _AL += '0'; + else _AL += hexStyle; + *di++ = _AL; + } +#else + uint *p = (uint *)&value; + uchar al, cx; + + hexStyle -= 10; + /* If the request is invalid, generate an empty result */ + if (radix > 36 || radix < 2) + goto lta_end; + if (p[1] & 0x8000 && maybeSigned) { + *di++ = '-'; + value = -value; + } + /* Now loop, taking each digit as modulo radix, and reducing the value + * by dividing by radix, until the value is zeroed. Note that + * at least one loop occurs even if the value begins as 0, + * since we want "0" to be generated rather than "". + */ + if (p[1] == 0) + goto lta_shortLoop; + do { + *si++ = (uchar)(value % radix); + value /= radix; + } while (p[1] != 0); /* value does not fit in 16 bits */ + goto lta_shortTest; + +lta_shortLoop: + do { + *si++ = (uchar)((uint)value % radix); + p[0] = ((uint)value / radix); +lta_shortTest: ; + } while (p[0] != 0); + /* The value has now been reduced to zero and the + * digits are in the buffer. + */ + cx = (uchar)(si-buf); /* length of numeral */ + /* The digits in the buffer must now be copied in reverse order into + * the target string, translating to ASCII as they are moved. + */ + while (cx != 0) { + al = *--si; + if (al < 10) + al += '0'; + else al += hexStyle; + *di++ = al; + --cx; + } +#endif + /* terminate the output string with a zero. */ +lta_end: + *di = 0; + return strP; /* return a pointer to the string */ +} +/*#pragma warn .use*/ + +/* +Name itoa - converts an integer to a string + ltoa - converts a long to a string + ultoa - converts an unsigned long to a string + +Usage char *itoa(int value, char *strP, int radix); + char *ltoa(long value, char *strP, int radix); + char *ultoa(unsigned long value, char *strP, int radix); + +Prototype in stdlib.h + +Description These functions convert value to a null-terminated string + and store the result in string. With itoa, value is an + integer; with ltoa it is a long; with ultoa it is an + unsigned long. __longtoa is the internal routine used for + all these conversions to ASCII. + + radix specifies the base to be used in converting value. it + must be between 2 and 36 (inclusive). With itoa and ltoa, + if value is negative, and radix is 10, the first character + of string is the minus sign (-). This does not occur with + ultoa. Also, ultoa performs no overflow checking. + + maybeSigned is treated as a boolean. If false then value is + treated as unsigned long and no sign will be placed in + *strP. + + hexStyle may take the values 'a' or 'A' and determines + whether lower or upper case alphabetics are used when the + radix is 11 or greater. + + Note: The space allocated for string must be large enough + to hold the returned string including the terminating null + character (\0). itoa can return up to 17 bytes; ltoa and + ultoa, up to 33 bytes. + +Return value All these functions return a pointer to string. There is no + error return. +*/ +char *itoa(value, strP, radix) + int value; + char *strP; + int radix; +{ + char hex = 'A'; + + if (radix < 0) { + hex = 'a'; + radix = -radix; + } + return __longtoa ((radix == 10) ? (long) value : + (unsigned long)((unsigned)value), + strP, radix, 1, hex); +} +#endif + diff --git a/src/libc/libcb.lib b/src/libc/libcb.lib new file mode 100755 index 00000000..83adbbd2 --- /dev/null +++ b/src/libc/libcb.lib @@ -0,0 +1,142 @@ +relcb\abort.rel +relcb\alloca.rel +relcb\asctime.rel +relcb\assert.rel +relcb\atexit.rel +relcb\atoi.rel +relcb\atol.rel +relcb\bsearch.rel +relcb\c0l.rel +relcb\calloc.rel +relcb\clock.rel +relcb\closedir.rel +relcb\convtime.rel +relcb\crypt.rel +relcb\ctime.rel +relcb\ctype.rel +relcb\difftime.rel +relcb\error.rel +relcb\etime.rel +relcb\execl.rel +relcb\execle.rel +relcb\execlp.rel +relcb\execlpe.rel +relcb\exect.rel +relcb\execv.rel +relcb\execvp.rel +relcb\execvpe.rel +relcb\exit.rel +relcb\fclose.rel +relcb\fflush.rel +relcb\fgetc.rel +relcb\fgetgren.rel +relcb\fgetpwen.rel +relcb\fgets.rel +relcb\fopen.rel +relcb\fprintf.rel +relcb\fputc.rel +relcb\fputs.rel +relcb\fread.rel +relcb\free.rel +relcb\fscanf.rel +relcb\ftell.rel +relcb\fwrite.rel +relcb\getcwd.rel +relcb\getenv.rel +relcb\getgrent.rel +relcb\getgrgid.rel +relcb\getgrnam.rel +relcb\getopt.rel +relcb\getpass.rel +relcb\getpw.rel +relcb\getpwent.rel +relcb\getpwnam.rel +relcb\getpwuid.rel +relcb\gets.rel +relcb\gmtime.rel +relcb\initgrup.rel +relcb\isatty.rel +relcb\itoa.rel +relcb\localtim.rel +relcb\longjmpb.rel +relcb\lsearch.rel +relcb\lstat.rel +relcb\ltoa.rel +relcb\ltostr.rel +relcb\malloc.rel +relcb\memccpy.rel +relcb\memchr.rel +relcb\memcmp.rel +relcb\memcpy.rel +relcb\memmove.rel +relcb\memset.rel +relcb\mkdir.rel +relcb\mktime.rel +relcb\opendir.rel +relcb\perror.rel +relcb\popen.rel +relcb\printf.rel +relcb\putenv.rel +relcb\putgetch.rel +relcb\putpwent.rel +relcb\qsort.rel +relcb\rand.rel +relcb\readdir.rel +relcb\readlink.rel +relcb\realloc.rel +relcb\regerror.rel +relcb\regexp.rel +relcb\regsub.rel +relcb\rename.rel +relcb\rewind.rel +relcb\rewindir.rel +relcb\rmdir.rel +relcb\scanf.rel +relcb\setbuff.rel +relcb\setenv.rel +relcb\setgrent.rel +relcb\setjmpb.rel +relcb\setpwent.rel +relcb\setvbuff.rel +relcb\sleep.rel +relcb\sprintf.rel +relcb\sscanf.rel +relcb\stdio0.rel +relcb\strcat.rel +relcb\strchr.rel +relcb\strcmp.rel +relcb\strcpy.rel +relcb\strcspn.rel +relcb\strdup.rel +relcb\stricmp.rel +relcb\strlen.rel +relcb\strncat.rel +relcb\strncmp.rel +relcb\strncpy.rel +relcb\strnicmp.rel +relcb\strpbrk.rel +relcb\strrchr.rel +relcb\strsep.rel +relcb\strspn.rel +relcb\strstr.rel +relcb\strtod.rel +relcb\strtok.rel +relcb\strtol.rel +relcb\strtoul.rel +relcb\system.rel +relcb\termcap.rel +relcb\tmpnam.rel +relcb\tparam.rel +relcb\ttyname.rel +relcb\tzset.rel +relcb\ultoa.rel +relcb\ungetc.rel +relcb\utsname.rel +relcb\vfprintf.rel +relcb\vfscanf.rel +relcb\vprintf.rel +relcb\vscanf.rel +relcb\vsprintf.rel +relcb\vsscanf.rel +relcb\xitoa.rel +relcb\xltoa.rel diff --git a/src/libc/libcl.lib b/src/libc/libcl.lib new file mode 100755 index 00000000..8f2ff799 --- /dev/null +++ b/src/libc/libcl.lib @@ -0,0 +1,142 @@ +relcl\abort.rel +relcl\alloca.rel +relcl\asctime.rel +relcl\assert.rel +relcl\atexit.rel +relcl\atoi.rel +relcl\atol.rel +relcl\bsearch.rel +relcl\c0l.rel +relcl\calloc.rel +relcl\clock.rel +relcl\closedir.rel +relcl\convtime.rel +relcl\crypt.rel +relcl\ctime.rel +relcl\ctype.rel +relcl\difftime.rel +relcl\error.rel +relcl\etime.rel +relcl\execl.rel +relcl\execle.rel +relcl\execlp.rel +relcl\execlpe.rel +relcl\exect.rel +relcl\execv.rel +relcl\execvp.rel +relcl\execvpe.rel +relcl\exit.rel +relcl\fclose.rel +relcl\fflush.rel +relcl\fgetc.rel +relcl\fgetgren.rel +relcl\fgetpwen.rel +relcl\fgets.rel +relcl\fopen.rel +relcl\fprintf.rel +relcl\fputc.rel +relcl\fputs.rel +relcl\fread.rel +relcl\free.rel +relcl\fscanf.rel +relcl\ftell.rel +relcl\fwrite.rel +relcl\getcwd.rel +relcl\getenv.rel +relcl\getgrent.rel +relcl\getgrgid.rel +relcl\getgrnam.rel +relcl\getopt.rel +relcl\getpass.rel +relcl\getpw.rel +relcl\getpwent.rel +relcl\getpwnam.rel +relcl\getpwuid.rel +relcl\gets.rel +relcl\gmtime.rel +relcl\initgrup.rel +relcl\isatty.rel +relcl\itoa.rel +relcl\localtim.rel +relcl\longjmpl.rel +relcl\lsearch.rel +relcl\lstat.rel +relcl\ltoa.rel +relcl\ltostr.rel +relcl\malloc.rel +relcl\memccpy.rel +relcl\memchr.rel +relcl\memcmp.rel +relcl\memcpy.rel +relcl\memmove.rel +relcl\memset.rel +relcl\mkdir.rel +relcl\mktime.rel +relcl\opendir.rel +relcl\perror.rel +relcl\popen.rel +relcl\printf.rel +relcl\putenv.rel +relcl\putgetch.rel +relcl\putpwent.rel +relcl\qsort.rel +relcl\rand.rel +relcl\readdir.rel +relcl\readlink.rel +relcl\realloc.rel +relcl\regerror.rel +relcl\regexp.rel +relcl\regsub.rel +relcl\rename.rel +relcl\rewind.rel +relcl\rewindir.rel +relcl\rmdir.rel +relcl\scanf.rel +relcl\setbuff.rel +relcl\setenv.rel +relcl\setgrent.rel +relcl\setjmpl.rel +relcl\setpwent.rel +relcl\setvbuff.rel +relcl\sleep.rel +relcl\sprintf.rel +relcl\sscanf.rel +relcl\stdio0.rel +relcl\strcat.rel +relcl\strchr.rel +relcl\strcmp.rel +relcl\strcpy.rel +relcl\strcspn.rel +relcl\strdup.rel +relcl\stricmp.rel +relcl\strlen.rel +relcl\strncat.rel +relcl\strncmp.rel +relcl\strncpy.rel +relcl\strnicmp.rel +relcl\strpbrk.rel +relcl\strrchr.rel +relcl\strsep.rel +relcl\strspn.rel +relcl\strstr.rel +relcl\strtod.rel +relcl\strtok.rel +relcl\strtol.rel +relcl\strtoul.rel +relcl\system.rel +relcl\termcap.rel +relcl\tmpnam.rel +relcl\tparam.rel +relcl\ttyname.rel +relcl\tzset.rel +relcl\ultoa.rel +relcl\ungetc.rel +relcl\utsname.rel +relcl\vfprintf.rel +relcl\vfscanf.rel +relcl\vprintf.rel +relcl\vscanf.rel +relcl\vsprintf.rel +relcl\vsscanf.rel +relcl\xitoa.rel +relcl\xltoa.rel diff --git a/src/libc/liberror.src b/src/libc/liberror.src new file mode 100755 index 00000000..15f7460b --- /dev/null +++ b/src/libc/liberror.src @@ -0,0 +1,42 @@ +1 Operation not permitted +2 No such file or directory +3 No such process +4 Interrupted system call +5 I/O error +6 No such device or address +7 Arg list too long +8 Exec format error +9 Bad file number +10 No child processes +11 Try again +12 Out of memory +13 Permission denied +14 Bad address +15 Block device required +16 Device or resource busy +17 File exists +18 Cross-device link +19 No such device +20 Not a directory +21 Is a directory +22 Invalid argument +23 File table overflow +24 Too many open files +25 Not a typewriter +26 Text file busy +27 File too large +28 No space left on device +29 Illegal seek +30 Read-only file system +31 Too many links +32 Broken pipe +33 Math argument out of domain of func +34 Math result not representable +35 Resource deadlock would occur +36 File name too long +37 No record locks available +38 Function not implemented +39 Directory not empty +40 Too many symbolic links encountered +41 It's a shell script + \ No newline at end of file diff --git a/src/libc/localtim.c b/src/libc/localtim.c new file mode 100755 index 00000000..10736c29 --- /dev/null +++ b/src/libc/localtim.c @@ -0,0 +1,14 @@ +/*************************** LOCALTIME ************************************/ +#include "time-l.h" + +#ifdef L_localtim +struct tm *localtime(timep) + time_t *timep; +{ + static struct tm tmb; + + __tm_conv(&tmb, timep, 0); + return &tmb; +} +#endif + diff --git a/src/libc/longjmpb.asm b/src/libc/longjmpb.asm new file mode 100755 index 00000000..abf0a0e7 --- /dev/null +++ b/src/libc/longjmpb.asm @@ -0,0 +1,69 @@ +; longjmpb.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module _longjmpb + + rseg CODE + + extern ?BANK_FAST_LEAVE_L08 + + public longjmp + +longjmp: + .if 1 + ld a,b + or c + jr nz,ok_return + inc bc +ok_return: + ex de,hl + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ex de,hl + ld sp,hl + ex de,hl + push bc + ld c,(hl) + inc hl + ld b,(hl) + inc hl + ld e,(hl) + inc hl + ld d,(hl) + inc hl + push de + pop ix + ld e,(hl) + inc hl + ld d,(hl) + inc hl + push de + pop iy + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld a,(hl) + pop hl + push de + push af + jp ?BANK_FAST_LEAVE_L08 + .else + defb 078h,0B1h,020h,001h,003h,0EBh,05Eh + defb 023h,056h,023h,0EBh,0F9h,0EBh,0C5h + defb 04Eh,023h,046h,023h,05Eh,023h,056h + defb 023h,0D5h,0DDh,0E1h,05Eh,023h,056h + defb 023h,0D5h,0FDh,0E1h,05Eh,023h,056h + defb 023h,07Eh,0E1h,0D5h,0F5h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + .endif + + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libc/longjmpl.asm b/src/libc/longjmpl.asm new file mode 100755 index 00000000..938af048 --- /dev/null +++ b/src/libc/longjmpl.asm @@ -0,0 +1,21 @@ +; longjmpl.asm +; Nick's reverse engineered subset of the IAR large 'C' library + +; ----------------------------------------------------------------------------- + + module _longjmpl + rseg CODE +code_base: + public longjmp +longjmp equ code_base+00000000h + defb 078h,0B1h,020h,001h,003h,0EBh,05Eh + defb 023h,056h,023h,0EBh,0F9h,0EBh,0C5h + defb 04Eh,023h,046h,023h,05Eh,023h,056h + defb 023h,0D5h,0DDh,0E1h,05Eh,023h,056h + defb 023h,0D5h,0FDh,0E1h,05Eh,023h,056h + defb 0E1h,0D5h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + END diff --git a/src/libc/lsearch.c b/src/libc/lsearch.c new file mode 100755 index 00000000..520e399e --- /dev/null +++ b/src/libc/lsearch.c @@ -0,0 +1,39 @@ +/* lsearch.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + */ +#include +#include + +void *lfind(key, base, num, size, cmp) + register void *key, *base; + size_t *num; + register size_t size; + register cmp_func_t cmp; +{ + register int n = *num; + + while (n--) { + if ((*cmp) (base, key) == 0) + return (base); + base = (char *)base + size; + } + return (NULL); +} + +void *lsearch(key, base, num, size, cmp) + void *key, *base; + register size_t *num; + register size_t size; + cmp_func_t cmp; +{ + register void *p; + + if ((p = lfind(key, base, num, size, cmp)) == NULL) { + p = memcpy(((char *)base + (size * (*num))), key, size); + ++(*num); + } + return (p); +} + diff --git a/src/libc/lseek.c$ b/src/libc/lseek.c$ new file mode 100755 index 00000000..1e1f4236 --- /dev/null +++ b/src/libc/lseek.c$ @@ -0,0 +1,32 @@ +/* lseek.c added by Nick from UZI280 libc, as we only have seek() in UZI180 */ + +#include + +long +lseek(f, offset, mode) +FILE *f; +long offset; +int mode; +{ + unsigned pos1,pos2; + +/* the following test must be done because the kernel + can't handle negative offsets */ + if (offset < 0L) + return -1L; + +/** + pos2 = offset / 512L; + pos1 = offset % 512L; + we use a faster version +**/ + pos2 = offset >> 9L; + pos1 = offset & 511L; + +/* CAUTION the seek calls must be in this order */ + pos1 = seek(f , pos1 , mode); /* byte seek */ + pos2 = seek(f , pos2, mode + 3); /* block seek */ + + return( ((long)pos2 << 9L) + (long)pos1); +} + diff --git a/src/libc/lstat.c b/src/libc/lstat.c new file mode 100755 index 00000000..85be0528 --- /dev/null +++ b/src/libc/lstat.c @@ -0,0 +1,21 @@ +/* lstat.c lstat implementation for UZIX + */ +#include +#include +#include + +int lstat(name, buf) + char *name; + void *buf; +{ + int sts, fd = open(name, O_SYMLINK); + + if (fd < 0) + sts = stat(name, buf); + else { + sts = fstat(fd, buf); + close(fd); + } + return sts; +} + \ No newline at end of file diff --git a/src/libc/ltoa.c b/src/libc/ltoa.c new file mode 100755 index 00000000..11c5527e --- /dev/null +++ b/src/libc/ltoa.c @@ -0,0 +1,22 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/**************************** ltoa.c ****************************/ +#ifdef L_ltoa +char *ltoa(value, strP, radix) + long value; + char *strP; + int radix; +{ + char hex = 'A'; + + if (radix < 0) { + hex = 'a'; + radix = -radix; + } + return __longtoa (value, strP, radix, (radix == 10), hex); +} +#endif + diff --git a/src/libc/ltostr.c b/src/libc/ltostr.c new file mode 100755 index 00000000..db430c5c --- /dev/null +++ b/src/libc/ltostr.c @@ -0,0 +1,24 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/**************************** ltostr.c ****************************/ +#ifdef L_ltostr +static char buf[34]; /* max len for radix == 2 */ + +char *ultostr(val, radix) + unsigned long val; + int radix; +{ + return ultoa(val,buf,radix); +} + +char *ltostr(val, radix) + long val; + int radix; +{ + return ltoa(val,buf,radix); +} +#endif + diff --git a/src/libc/malloc-l.h b/src/libc/malloc-l.h new file mode 100755 index 00000000..640362c1 --- /dev/null +++ b/src/libc/malloc-l.h @@ -0,0 +1,29 @@ +/* malloc-l.h */ +/* Copyright (C) 1984 by Manx Software Systems */ + +/* #define MALLOC_DEBUG */ + +#ifdef MALLOC_DEBUG +#include +#endif +#include /* Nick, for size_t */ +#include /* Nick, for sbrk() */ + +typedef struct freelist { + size_t f_size; + struct freelist *f_chain; +} FREE; + +#define NULL (FREE *)0 +#define GRAIN 1024 + +void *realloc(void *area, size_t size); +void *malloc(size_t size); +int free(void *area); + +extern FREE __malloc_head, *__malloc_last; + +/* trick to get the effect of "static FREE head, *last" over multiple files */ +#define head __malloc_head +#define last __malloc_last + diff --git a/src/libc/malloc-l.h$ b/src/libc/malloc-l.h$ new file mode 100755 index 00000000..b4535d8a --- /dev/null +++ b/src/libc/malloc-l.h$ @@ -0,0 +1,53 @@ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + * + * This is a combined alloca/malloc package. It uses a classic algorithm + * and so may be seen to be quite slow compared to more modern routines + * with 'nasty' distributions. + */ +#include +#include +#include +#include +#include + +#define __MINI_MALLOC__ + +#define MCHUNK 512 /* Allocation unit in 'mem' elements */ +/*#define LAZY_FREE /* If set frees can be infinitly defered */ +/*#define MINALLOC 32 /* Smallest chunk to alloc in 'mem's */ +#define VERBOSE /* Lots of noise, debuging ? */ + +#ifdef MAKE_ALL +#define L_malloc +#define L_free +#define L_alloca +#define L_calloc +#define L_realloc +#endif + +#undef malloc +#define MAX_INT ((int)(((unsigned)-1)>>1)) + +#ifdef VERBOSE +#define noise __noise +#else +#define noise(y,x) +#endif + +typedef struct mem_cell { + struct mem_cell *next; /* A pointer to the next mem */ + unsigned int size; /* An int >= sizeof pointer */ + char *depth; /* For the alloca hack */ +} mem; + +#define m_size(p) ((p)[0].size) /* For malloc */ +#define m_next(p) ((p)[0].next) /* For malloc and alloca */ +#define m_deep(p) ((p)[0].depth) /* For alloca */ +#define m_add(x,y) (mem *)((uchar *)x + y) /* Sum mem* with y bytes */ + +extern void *__mini_malloc __P((size_t)); +extern void *(*__alloca_alloc) __P((size_t)); +extern mem *__freed_list; + diff --git a/src/libc/malloc.c b/src/libc/malloc.c new file mode 100755 index 00000000..8bd5ab08 --- /dev/null +++ b/src/libc/malloc.c @@ -0,0 +1,64 @@ +/* malloc.c */ +/* Copyright (C) 1984 by Manx Software Systems */ + +#include "malloc-l.h" + +/*static*/ FREE head, *last; /* see #defines in malloc-l.h */ + +void *malloc(size_t size) +{ + register FREE *tp, *prev; + size_t units; + +#ifdef MALLOC_DEBUG + printf("malloc(0x%x) starting\n", size); + fflush(stdout); +#endif + + units = (size+sizeof(FREE)-1)/sizeof(FREE) + 1; + if ((prev = last) == NULL) + last = head.f_chain = prev = &head; + + for (tp = prev->f_chain ; ; prev = tp, tp = tp->f_chain) { + while (tp != tp->f_chain && tp+tp->f_size == tp->f_chain) { + if (last == tp->f_chain) + last = tp->f_chain->f_chain; + tp->f_size += tp->f_chain->f_size; + tp->f_chain = tp->f_chain->f_chain; + } + + if (tp->f_size >= units) { + if (tp->f_size == units) + prev->f_chain = tp->f_chain; + else { + last = tp + units; + prev->f_chain = last; + last->f_chain = tp->f_chain; + last->f_size = tp->f_size - units; + tp->f_size = units; + } + last = prev; + tp->f_chain = NULL; +#ifdef MALLOC_DEBUG + printf("malloc() returning 0x%x\n", tp+1); + fflush(stdout); +#endif + return (char *)(tp+1); + } + if (tp == last) { + if ((tp = (FREE *)sbrk(GRAIN)) == (FREE *)-1) + { +#ifdef MALLOC_DEBUG + printf("malloc() returning NULL\n"); + fflush(stdout); +#endif + return (char *)NULL; + } + tp->f_size = GRAIN/sizeof(FREE); + tp->f_chain = NULL; + free(tp+1); + tp = last; + } + } +} + diff --git a/src/libc/malloc.c$ b/src/libc/malloc.c$ new file mode 100755 index 00000000..9e4cf0b8 --- /dev/null +++ b/src/libc/malloc.c$ @@ -0,0 +1,305 @@ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + * + * This is a combined alloca/malloc package. It uses a classic algorithm + * and so may be seen to be quite slow compared to more modern routines + * with 'nasty' distributions. + */ + +#include "malloc-l.h" + +#if 0 /* Nick, see free.c */ +#undef noise +#define noise __noise +#define VERBOSE /* Nick silly */ +#endif + +#ifdef VERBOSE /* Nick, see free.c */ +/* NB: Careful here, stdio may use malloc - so we can't */ +#include +#include +#include + +static void pstr __P((char *)); +static void phex __P((unsigned)); +static void noise __P((char *, mem *)); + +static void pstr(str) + char *str; +{ + write(2, str, strlen(str)); +} + +static void phex(val) + unsigned val; +{ + char buf[8]; + + strcpy(buf,"000"); + ltoa((long)val,buf+3,16); + pstr(buf+strlen(buf+4)); +} + +void __noise(y, x) + char *y; + mem *x; +{ + pstr("Malloc "); phex((unsigned)x); + pstr(" sz "); phex(x ? (unsigned)m_size(x) : 0); + pstr(" nxt "); phex(x ? (unsigned)m_next(x) : 0); + pstr(" is "); pstr(y); pstr("\n"); +} +#endif + +#ifdef L_malloc +/* The chunk_list pointer is either NULL or points to a chunk in a + * circular list of all the free blocks in memory + */ + +#define Static static + +static mem *chunk_list = 0; +Static mem *__search_chunk __P((unsigned)); +Static void __insert_chunk __P((mem *)); + +void *malloc(size) + size_t size; +{ + register unsigned sz; + register mem *ptr = 0; + + if (size == 0) + return 0; /* ANSI STD */ + sz = size + sizeof(struct mem_cell); +#ifdef MINALLOC + if (sz < MINALLOC) + sz = MINALLOC; +#endif +#ifdef VERBOSE + { + static mem arr[2]; + + m_size(arr) = sz; + noise("WANTED", arr); + } +#endif + __alloca_alloc = malloc;/* We'll be messing with the heap now TVM */ +#ifdef LAZY_FREE + ptr = __search_chunk(sz); + if (ptr == 0) { +#endif + /* First deal with the freed list */ + if (__freed_list) { + while (__freed_list) { + ptr = __freed_list; + __freed_list = m_next(__freed_list); + if (m_size(ptr) == sz) { + /* Oh! Well that's lucky ain't it :-) */ + noise("LUCKY MALLOC", ptr); + return ptr + 1; + } + __insert_chunk(ptr); + } + ptr = m_next(chunk_list); + if (ptr + m_size(ptr) >= (void *) sbrk(0)) { + /* Time to free for real */ + m_next(chunk_list) = m_next(ptr); + if (ptr == m_next(ptr)) + chunk_list = 0; + free(ptr + 1); + } +#ifdef LAZY_FREE + ptr = __search_chunk(sz); +#endif + } +#ifndef LAZY_FREE + ptr = __search_chunk(sz); +#endif + if (ptr == 0) { +#ifdef MCHUNK + unsigned int alloc = + (MCHUNK * ((sz + MCHUNK - 1) / MCHUNK) - 1); + + if ((ptr = __mini_malloc(alloc)) != NULL) + __insert_chunk(ptr - 1); + else { /* Oooo, near end of RAM */ + unsigned int needed = alloc; + alloc /= 2; + while (alloc > 256 && needed) { + ptr = __mini_malloc(alloc); + if (ptr) { + if (alloc > needed) + needed = 0; + else needed -= alloc; + __insert_chunk(ptr - 1); + } + else alloc /= 2; + } + } + ptr = __search_chunk(sz); + if (ptr == 0) +#endif + { +#ifndef MCHUNK + ptr = __mini_malloc(size); +#endif +#ifdef VERBOSE + if (ptr == 0) + noise("MALLOC FAIL", 0); + else noise("MALLOC NOW", ptr - 1); +#endif + return ptr; + } + } +#ifdef LAZY_FREE + } +#endif +#ifdef VERBOSE + ptr[1].size = 0x5555; +#endif + noise("MALLOC RET\n", ptr); + return ptr + 1; +} + +/* This function takes a pointer to a block of memory and inserts it into + * the chain of memory chunks + */ +Static void __insert_chunk(mem_chunk) + mem *mem_chunk; +{ + register mem *p1, *p2; + + if (chunk_list == 0) { /* Simple case first */ + m_next(mem_chunk) = chunk_list = mem_chunk; + noise("FIRST CHUNK", mem_chunk); + return; + } + p1 = mem_chunk; + p2 = chunk_list; + do { + if (p1 > p2) { + /* We're at the top of the chain, p1 is higher */ + if (m_next(p2) <= p2) { + if (m_add(p2, m_size(p2)) == p1) { + /* Good, stick 'em together */ + noise("INSERT CHUNK", mem_chunk); + m_size(p2) += m_size(p1); + noise("JOIN 1", p2); + } + else { + m_next(p1) = m_next(p2); + m_next(p2) = p1; + noise("INSERT CHUNK", mem_chunk); + noise("FROM", p2); + } + return; + } + if (m_next(p2) > p1) { + /* In chain, p1 between p2 and next */ + m_next(p1) = m_next(p2); + m_next(p2) = p1; + noise("INSERT CHUNK", mem_chunk); + noise("FROM", p2); + + /* Try to join above */ + if (m_add(p1, m_size(p1)) == m_next(p1)) { + m_size(p1) += m_size(m_next(p1)); + m_next(p1) = m_next(m_next(p1)); + noise("JOIN 2", p1); + } + /* Try to join below */ + if (m_add(p2, m_size(p2)) == p1) { + m_size(p2) += m_size(p1); + m_next(p2) = m_next(p1); + noise("JOIN 3", p2); + } + chunk_list = p2; /* Make sure it's valid */ + return; + } + } + else if (p1 < p2) { + if (m_next(p2) <= p2 && p1 < m_next(p2)) { + /* At top of chain, next is bottom of chain, + * p1 is below next + */ + m_next(p1) = m_next(p2); + m_next(p2) = p1; + noise("INSERT CHUNK", mem_chunk); + noise("FROM", p2); + chunk_list = p2; + if (m_add(p1, m_size(p1)) == m_next(p1)) { + if (p2 == m_next(p1)) + chunk_list = p1; + m_size(p1) += m_size(m_next(p1)); + m_next(p1) = m_next(m_next(p1)); + noise("JOIN 4", p1); + } + return; + } + } + chunk_list = p2; /* Save for search */ + p2 = m_next(p2); + } while (p2 != chunk_list); + /* If we get here we have a problem, ignore it, maybe it'll go away */ + noise("DROPPED CHUNK", mem_chunk); +} + +/* This function will search for a chunk in memory of at least 'mem_size' + * when found, if the chunk is too big it'll be split, and pointer to the + * chunk returned. If none is found NULL is returned. + */ +Static mem *__search_chunk(mem_size) + unsigned mem_size; +{ + register mem *p1, *p2; + + if (chunk_list == 0) /* Simple case first */ + return 0; + /* Search for a block >= the size we want */ + p1 = m_next(chunk_list); + p2 = chunk_list; + do { + noise("CHECKED", p1); + _abyte('a'); + if (m_size(p1) >= mem_size) + break; + _abyte('b'); + p2 = p1; + p1 = m_next(p1); + } while (p2 != chunk_list); + _abyte('c'); + /* None found, exit */ + if (m_size(p1) < mem_size) + return 0; + _abyte('d'); + /* If it's exactly right remove it */ + if (m_size(p1) < mem_size + 2) { + _abyte('e'); + noise("FOUND RIGHT", p1); + chunk_list = m_next(p2) = m_next(p1); + if (chunk_list == p1) + chunk_list = 0; + return p1; + } + _abyte('f'); + noise("SPLIT", p1); + /* Otherwise split it */ + m_next(p2) = m_add(p1, mem_size); + chunk_list = p2; + p2 = m_next(p2); + m_size(p2) = m_size(p1) - mem_size; + m_next(p2) = m_next(p1); + m_size(p1) = mem_size; + if (chunk_list == p1) + chunk_list = p2; +#ifdef VERBOSE + p1[1].size = 0xAAAA; +#endif + noise("INSERT CHUNK", p2); + noise("FOUND CHUNK", p1); + noise("LIST IS", chunk_list); + return p1; +} +#endif /* L_malloc */ + diff --git a/src/libc/mem-l.h b/src/libc/mem-l.h new file mode 100755 index 00000000..e895f133 --- /dev/null +++ b/src/libc/mem-l.h @@ -0,0 +1,16 @@ +/* mem.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include + +#ifdef MAKE_ALL +#define L_memcpy +#define L_memccpy +#define L_memchr +#define L_memset +#define L_memcmp +#define L_memmove +#endif + \ No newline at end of file diff --git a/src/libc/memccpy.c b/src/libc/memccpy.c new file mode 100755 index 00000000..3ce801a6 --- /dev/null +++ b/src/libc/memccpy.c @@ -0,0 +1,25 @@ +/* memccpy.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "mem-l.h" + +/********************** Function memccpy ************************************/ +#ifdef L_memccpy +void *memccpy(d, s, c, l) /* Do we need a fast one ? */ + void *s, *d; + int c; + size_t l; +{ + register char *s1 = d, *s2 = s; + + while (l-- != 0) { + if ((*s1++ = *s2++) == c) + return s1; + } + return NULL; +} +#endif + \ No newline at end of file diff --git a/src/libc/memchr.c b/src/libc/memchr.c new file mode 100755 index 00000000..a404742f --- /dev/null +++ b/src/libc/memchr.c @@ -0,0 +1,26 @@ +/* memchr.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "mem-l.h" + +/********************** Function memchr ************************************/ +#ifdef L_memchr +void *memchr(str, c, l) + void *str; + int c; + size_t l; +{ + register char *p = (char *) str; + + while (l-- != 0) { + if (*p == c) + return p; + p++; + } + return NULL; +} +#endif + \ No newline at end of file diff --git a/src/libc/memcmp.c b/src/libc/memcmp.c new file mode 100755 index 00000000..a0aa7a06 --- /dev/null +++ b/src/libc/memcmp.c @@ -0,0 +1,66 @@ +/* memcmp.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "mem-l.h" + +/********************** Function memcmp ************************************/ +#ifdef L_memcmp +int memcmp(s, d, l) + void *s; + void *d; + size_t l; +{ +#ifdef HI_TECH_C +_asm + ; d = BC, s=DE, l=(ix+4, ix+5) + ld ix,0 + add ix,sp + push iy + ld l,(ix+4) + ld h,(ix+5) + ex de,hl ; HL=s, DE=l + push bc + pop iy ; IY=d + ld bc,0 ; char1, char2 +1: ld a,(hl) + ld b,a + ld a,(iy) ; char1 != char 2 ? + ld c,a + cp b + jr nz,2f + inc hl ; s++ + inc iy ; d++ + dec de ; l-- + ld a,d + or e + jp nz,1b ; l != 0, continue +2: ld a,c ; char1 - char2 + ld e,a + rla + sbc a,a + ld d,a + ld a,b + ld l,b + rla + sbc a,a + ld h,a + or a + sbc hl,de + pop iy +_endasm +#else + register char *s1 = d, *s2 = s; + register char c1 = 0, c2 = 0; + + while (l-- != 0) { + if ((c1 = *s1++) != (c2 = *s2++)) + break; + } + return c1 - c2; +#endif +} +#endif + diff --git a/src/libc/memcpy.c b/src/libc/memcpy.c new file mode 100755 index 00000000..c9970198 --- /dev/null +++ b/src/libc/memcpy.c @@ -0,0 +1,43 @@ +/* memcpy.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "mem-l.h" + +/********************** Function memcpy ************************************/ +#ifdef L_memcpy +void *memcpy(d, s, l) + void *d; + void *s; + size_t l; +{ +#ifndef HI_TECH_C + register char *s1 = d, *s2 = (char *) s; + + while (l-- != 0) + *((unsigned char *) s1++) = *((unsigned char *) s2++); + return d; +#else +_asm + ; HTC puts a "push ix" here + ld ix,0 + add ix,sp + ld h,b + ld l,c + ld c,(ix+4) + ld b,(ix+5) + push de + ld a,b + or c + jr z,_skip + ldir +_skip: + pop hl + ; HTC puts a "pop ix" here +_endasm +#endif +} +#endif + diff --git a/src/libc/memmove.c b/src/libc/memmove.c new file mode 100755 index 00000000..5c44bbdb --- /dev/null +++ b/src/libc/memmove.c @@ -0,0 +1,76 @@ +/* memmove.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "mem-l.h" + +/********************** Function memmove ************************************/ +#ifdef L_memmove +void *memmove(d, s, l) + void *d, *s; + size_t l; +{ +#ifdef HI_TECH_C +_asm + global _memcpy +;_s stored from bc +;_d stored from de + ld ix,0 + add ix,sp + push de ; saves d + push bc + push de + push de + pop hl ; HL = d + or a + sbc hl,bc ; d = d - s + ld e,(ix+4) + ld d,(ix+5) + or a + sbc hl,de ; d = d -l + jr c, 2f + ; d-s >=l -> memcpy + pop de ; d + pop bc ; s + ld l,(ix+4) ; l + ld h,(ix+5) + push hl + call _memcpy + jr 1f +2: ; s=s+l, d=d+l, lddr + xor a + pop hl + dec hl + add hl,de ; d=d+l + pop bc + push hl + ld h,b ; HL=s + ld l,c + dec hl + add hl,de ; s=s+l + ld b,d + ld c,e ; BC=l + pop de ; DE=d + lddr +1: pop hl ; d +_endasm +#else + register char *s1 = d, *s2 = s; + + /* This bit of sneakyness c/o Glibc, + * it assumes the test is unsigned + */ + if (s1 - s2 >= l) + return memcpy(d, s, l); + /* This reverse copy only used if we absolutly have to */ + s1 += l; + s2 += l; + while (l-- != 0) + *(--s1) = *(--s2); + return d; +#endif +} +#endif + diff --git a/src/libc/memset.c b/src/libc/memset.c new file mode 100755 index 00000000..536089a1 --- /dev/null +++ b/src/libc/memset.c @@ -0,0 +1,51 @@ +/* memset.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "mem-l.h" + +/********************** Function memset ************************************/ +#ifdef L_memset +void *memset(str, c, l) + void *str; + int c; + size_t l; +{ +#ifndef HI_TECH_C + register char *s1 = str; + + while (l-- != 0) + *s1++ = c; + return str; +#else +_asm + ld ix,0 + add ix,sp + ld h,d + ld l,e ; HL=str + ld d,c ; D=c + ld c,(ix+4) + ld b,(ix+5); BC=l + ld a,b + or c ; l=0? so return + jr z,_retw + ld a,d + ld (hl),a ; fill first byte + ld d,h + ld e,l + inc de ; DE=str+1 + dec bc + ld a,b ; l=1? so return + or c + jr z,_retw + push hl + ldir + pop hl +_retw: +_endasm +#endif +} +#endif + \ No newline at end of file diff --git a/src/libc/mkdir.c b/src/libc/mkdir.c new file mode 100755 index 00000000..12c6ac13 --- /dev/null +++ b/src/libc/mkdir.c @@ -0,0 +1,12 @@ +/* mkdir.c + */ +#include +#include + +int mkdir(path, mode) + char *path; + mode_t mode; +{ + return mknod(path, S_IFDIR | (mode & S_UMASK), 0); +} + diff --git a/src/libc/mktime.c b/src/libc/mktime.c new file mode 100755 index 00000000..8dbfd5e4 --- /dev/null +++ b/src/libc/mktime.c @@ -0,0 +1,18 @@ +/*************************** MKTIME ************************************/ +#include "time-l.h" + +#ifdef L_mktime +time_t mktime (__tp) + struct tm *__tp; +{ + time_t tt; + + tt.t_time = (((int)__tp->tm_hour << 8) << 3) | + ((int)__tp->tm_min << 5) | + ((int)__tp->tm_sec >> 1); + tt.t_date = (((int)(__tp->tm_year - 80) << 8) << 1) | + ((int)(__tp->tm_mon+1) << 5) | __tp->tm_mday; + return tt; +} +#endif + diff --git a/src/libc/n.bat b/src/libc/n.bat new file mode 100755 index 00000000..fda184d3 --- /dev/null +++ b/src/libc/n.bat @@ -0,0 +1,12 @@ +md build-l +cd build-l +copy ..\build-l.ban n.bat +call n +cd .. + +md build-b +cd build-b +copy ..\build-b.ban n.bat +call n +cd .. + diff --git a/src/libc/n.xlb b/src/libc/n.xlb new file mode 100755 index 00000000..5c5c9cc4 --- /dev/null +++ b/src/libc/n.xlb @@ -0,0 +1,142 @@ +on-error-exit +fetch-modules abort.r01 libc.r01 +fetch-modules alloca.r01 libc.r01 +fetch-modules asctime.r01 libc.r01 +fetch-modules assert.r01 libc.r01 +fetch-modules atexit.r01 libc.r01 +fetch-modules atoi.r01 libc.r01 +fetch-modules atol.r01 libc.r01 +fetch-modules bsearch.r01 libc.r01 +fetch-modules calloc.r01 libc.r01 +fetch-modules clock.r01 libc.r01 +fetch-modules closedir.r01 libc.r01 +fetch-modules convtime.r01 libc.r01 +fetch-modules crypt.r01 libc.r01 +fetch-modules ctime.r01 libc.r01 +fetch-modules ctype.r01 libc.r01 +fetch-modules difftime.r01 libc.r01 +fetch-modules error.r01 libc.r01 +fetch-modules etime.r01 libc.r01 +fetch-modules execl.r01 libc.r01 +fetch-modules execle.r01 libc.r01 +fetch-modules execlp.r01 libc.r01 +fetch-modules execlpe.r01 libc.r01 +fetch-modules exect.r01 libc.r01 +fetch-modules execv.r01 libc.r01 +fetch-modules execvp.r01 libc.r01 +fetch-modules execvpe.r01 libc.r01 +fetch-modules fclose.r01 libc.r01 +fetch-modules fflush.r01 libc.r01 +fetch-modules fgetc.r01 libc.r01 +fetch-modules fgetgren.r01 libc.r01 +fetch-modules fgetpwen.r01 libc.r01 +fetch-modules fgets.r01 libc.r01 +fetch-modules fopen.r01 libc.r01 +fetch-modules fprintf.r01 libc.r01 +fetch-modules fputc.r01 libc.r01 +fetch-modules fputs.r01 libc.r01 +fetch-modules fread.r01 libc.r01 +fetch-modules free.r01 libc.r01 +fetch-modules fscanf.r01 libc.r01 +fetch-modules ftell.r01 libc.r01 +fetch-modules fwrite.r01 libc.r01 +fetch-modules getcwd.r01 libc.r01 +fetch-modules getenv.r01 libc.r01 +fetch-modules getgrent.r01 libc.r01 +fetch-modules getgrgid.r01 libc.r01 +fetch-modules getgrnam.r01 libc.r01 +fetch-modules getopt.r01 libc.r01 +fetch-modules getpass.r01 libc.r01 +fetch-modules getpw.r01 libc.r01 +fetch-modules getpwent.r01 libc.r01 +fetch-modules getpwnam.r01 libc.r01 +fetch-modules getpwuid.r01 libc.r01 +fetch-modules gets.r01 libc.r01 +fetch-modules gmtime.r01 libc.r01 +fetch-modules initgrup.r01 libc.r01 +fetch-modules isatty.r01 libc.r01 +fetch-modules itoa.r01 libc.r01 +fetch-modules localtim.r01 libc.r01 +fetch-modules lsearch.r01 libc.r01 +fetch-modules lstat.r01 libc.r01 +fetch-modules ltoa.r01 libc.r01 +fetch-modules ltostr.r01 libc.r01 +fetch-modules malloc.r01 libc.r01 +fetch-modules memccpy.r01 libc.r01 +fetch-modules memchr.r01 libc.r01 +fetch-modules memcmp.r01 libc.r01 +fetch-modules memcpy.r01 libc.r01 +fetch-modules memmove.r01 libc.r01 +fetch-modules memset.r01 libc.r01 +fetch-modules mkdir.r01 libc.r01 +fetch-modules mktime.r01 libc.r01 +fetch-modules opendir.r01 libc.r01 +fetch-modules perror.r01 libc.r01 +fetch-modules popen.r01 libc.r01 +fetch-modules printf.r01 libc.r01 +fetch-modules putenv.r01 libc.r01 +fetch-modules putgetch.r01 libc.r01 +fetch-modules putpwent.r01 libc.r01 +fetch-modules qsort.r01 libc.r01 +fetch-modules rand.r01 libc.r01 +fetch-modules readdir.r01 libc.r01 +fetch-modules readlink.r01 libc.r01 +fetch-modules realloc.r01 libc.r01 +fetch-modules regerror.r01 libc.r01 +fetch-modules regexp.r01 libc.r01 +fetch-modules regsub.r01 libc.r01 +fetch-modules rename.r01 libc.r01 +fetch-modules rewind.r01 libc.r01 +fetch-modules rewindir.r01 libc.r01 +fetch-modules rmdir.r01 libc.r01 +fetch-modules scanf.r01 libc.r01 +fetch-modules setbuff.r01 libc.r01 +fetch-modules setenv.r01 libc.r01 +fetch-modules setgrent.r01 libc.r01 +fetch-modules setjmp.r01 libc.r01 +fetch-modules setpwent.r01 libc.r01 +fetch-modules setvbuff.r01 libc.r01 +fetch-modules sleep.r01 libc.r01 +fetch-modules sprintf.r01 libc.r01 +fetch-modules sscanf.r01 libc.r01 +fetch-modules stdio0.r01 libc.r01 +fetch-modules strcat.r01 libc.r01 +fetch-modules strchr.r01 libc.r01 +fetch-modules strcmp.r01 libc.r01 +fetch-modules strcpy.r01 libc.r01 +fetch-modules strcspn.r01 libc.r01 +fetch-modules strdup.r01 libc.r01 +fetch-modules stricmp.r01 libc.r01 +fetch-modules strlen.r01 libc.r01 +fetch-modules strncat.r01 libc.r01 +fetch-modules strncmp.r01 libc.r01 +fetch-modules strncpy.r01 libc.r01 +fetch-modules strnicmp.r01 libc.r01 +fetch-modules strpbrk.r01 libc.r01 +fetch-modules strrchr.r01 libc.r01 +fetch-modules strsep.r01 libc.r01 +fetch-modules strspn.r01 libc.r01 +fetch-modules strstr.r01 libc.r01 +fetch-modules strtod.r01 libc.r01 +fetch-modules strtok.r01 libc.r01 +fetch-modules strtol.r01 libc.r01 +fetch-modules strtoul.r01 libc.r01 +fetch-modules system.r01 libc.r01 +fetch-modules termcap.r01 libc.r01 +fetch-modules tmpnam.r01 libc.r01 +fetch-modules tparam.r01 libc.r01 +fetch-modules ttyname.r01 libc.r01 +fetch-modules tzset.r01 libc.r01 +fetch-modules ultoa.r01 libc.r01 +fetch-modules ungetc.r01 libc.r01 +fetch-modules utsname.r01 libc.r01 +fetch-modules vfprintf.r01 libc.r01 +fetch-modules vfscanf.r01 libc.r01 +fetch-modules vprintf.r01 libc.r01 +fetch-modules vscanf.r01 libc.r01 +fetch-modules vsprintf.r01 libc.r01 +fetch-modules vsscanf.r01 libc.r01 +fetch-modules xitoa.r01 libc.r01 +fetch-modules xltoa.r01 libc.r01 +make-library libc.r01 _abort _xltoa +exit diff --git a/src/libc/opendir.c b/src/libc/opendir.c new file mode 100755 index 00000000..12d482df --- /dev/null +++ b/src/libc/opendir.c @@ -0,0 +1,40 @@ +/* opendir.c opendir implementation + * + */ +#include +#include +#include +#include +#include +#include +#include + +DIR *opendir(path) + char *path; +{ + struct stat statbuf; + register DIR *dir; + + if (stat(path, &statbuf) != 0) + goto Err; + if ((statbuf.st_mode & S_IFDIR) == 0) { + errno = ENOTDIR; + goto Err; + } + if ((dir = (DIR *)calloc(1,sizeof(DIR))) == NULL) { + errno = ENOMEM; + goto Err; + } + if ((dir->dd_buf = calloc(1,sizeof(struct dirent))) == NULL) { + free(dir); + errno = ENOMEM; + goto Err; + } + if ((dir->dd_fd = open(path, O_BINARY)) < 0) { + free(dir->dd_buf); + free(dir); +Err: return NULL; + } + return dir; +} + diff --git a/src/libc/passwd.h b/src/libc/passwd.h new file mode 100755 index 00000000..0704c90d --- /dev/null +++ b/src/libc/passwd.h @@ -0,0 +1,28 @@ +/* passwd.h + */ + +/* OBS.: getpwuid gets the first password entry that has the given UID. + it DOESN'T look for GID, so entries with different GIDs and + equal UID will be treated as equal +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef MAKE_ALL +#define L_fgetpwen +#define L_getpw +#define L_getpwnam +#define L_getpwuid +#define L_putpwent +#define L_setpwent +#define L_getpwent +#endif + diff --git a/src/libc/perror.asm b/src/libc/perror.asm new file mode 100755 index 00000000..a4460527 --- /dev/null +++ b/src/libc/perror.asm @@ -0,0 +1,132 @@ + ifndef ??version +?debug macro + endm + endif + ?debug S "perror.c" +_TEXT segment byte public 'CODE' +DGROUP group _DATA,_BSS + assume cs:_TEXT,ds:DGROUP,ss:DGROUP +_TEXT ends +_DATA segment word public 'DATA' +d@ label byte +d@w label word +_DATA ends +_BSS segment word public 'BSS' +b@ label byte +b@w label word + ?debug C E9C0137E2D08706572726F722E63 + ?debug C E9CA367E2D122E2E5C696E636C7564655C737464696F2E68 + ?debug C E9CA367E2D122E2E5C696E636C7564655C74797065732E68 + ?debug C E9CA367E2D152E2E5C696E636C7564655C66656174757265732E68 + ?debug C E9E8367E2D162E2E5C696E636C7564655C7379732F63646566732E+ + ?debug C 68 + ?debug C E9CA367E2D132E2E5C696E636C7564655C7374646172672E68 + ?debug C E9CA367E2D132E2E5C696E636C7564655C756E697374642E68 + ?debug C E90832812D152E2E5C696E636C7564655C73797363616C6C732E68 + ?debug C E9CA367E2D132E2E5C696E636C7564655C7369676E616C2E68 + ?debug C E9CA367E2D132E2E5C696E636C7564655C737472696E672E68 + ?debug C E9CA367E2D132E2E5C696E636C7564655C7374646465662E68 + ?debug C E9CA367E2D122E2E5C696E636C7564655C6572726E6F2E68 +_BSS ends +_TEXT segment byte public 'CODE' +; ?debug L 8 +wr2 proc near + push bp + mov bp,sp + push si + push di + mov di,word ptr [bp+4] +; ?debug L 11 + mov si,di + jmp short @2 +@4: +; ?debug L 14 + inc si +@2: +; ?debug L 13 + cmp byte ptr [si],0 + jne @4 +; ?debug L 15 + mov ax,si + sub ax,di + push ax + push di + mov ax,2 + push ax + call near ptr _write + add sp,6 +; ?debug L 16 + pop di + pop si + pop bp + ret +wr2 endp +_TEXT ends +_DATA segment word public 'DATA' +_DATA ends +_TEXT segment byte public 'CODE' +; ?debug L 18 +_perror proc near + push bp + mov bp,sp + push si + mov si,word ptr [bp+4] +; ?debug L 21 + or si,si + jne @6 +; ?debug L 22 + mov si,offset DGROUP:s@ +@6: +; ?debug L 23 + push si + call near ptr wr2 + pop cx +; ?debug L 24 + mov ax,offset DGROUP:s@+6 + push ax + call near ptr wr2 + pop cx +; ?debug L 25 + push word ptr DGROUP:_errno + call near ptr _strerror + pop cx + mov si,ax +; ?debug L 26 + push si + call near ptr wr2 + pop cx +; ?debug L 27 + mov ax,offset DGROUP:s@+9 + push ax + call near ptr wr2 + pop cx +; ?debug L 28 + pop si + pop bp + ret +_perror endp +_TEXT ends + ?debug C E9 +_DATA segment word public 'DATA' +s@ label byte + db 101 + db 114 + db 114 + db 111 + db 114 + db 0 + db 58 + db 32 + db 0 + db 10 + db 0 +_DATA ends + extrn _errno:word +_TEXT segment byte public 'CODE' + extrn _strerror:near + extrn _write:near +_TEXT ends + public _perror +_wr2 equ wr2 + end + \ No newline at end of file diff --git a/src/libc/perror.c b/src/libc/perror.c new file mode 100755 index 00000000..a912374b --- /dev/null +++ b/src/libc/perror.c @@ -0,0 +1,29 @@ +/* perror.c + */ +#include +#include +#include +#include + +static void wr2(str) + char *str; +{ + char *p = str; + + while (*p) + ++p; + write(2, str, (unsigned int)(p-str)); +} + +void perror(str) + register char *str; +{ + if (!str) + str = "error"; + wr2(str); + wr2(": "); + str = strerror(errno); + wr2(str); + wr2("\n"); +} + \ No newline at end of file diff --git a/src/libc/popen.c b/src/libc/popen.c new file mode 100755 index 00000000..55761cec --- /dev/null +++ b/src/libc/popen.c @@ -0,0 +1,52 @@ +/* popen.c pipes implemetation + */ +#include +#include +#include +#include +#include + +FILE *popen(command, rw) + char *command; + char *rw; +{ + int pipe_fd[2]; /* 0=reading, 1=writing */ + int pid, reading, notreading; + static char *argv[4] = { "sh", "-c", 0, 0 }; + + if (pipe(pipe_fd) < 0) + return NULL; + reading = (rw[0] == 'r'); /* 0 or 1 only! */ + notreading = !reading; /* 1 or 0 */ + if ((pid = fork()) < 0) { + close(pipe_fd[0]); + close(pipe_fd[1]); + return NULL; + } + if (pid == 0) { /* child */ + close(pipe_fd[notreading]); + close(reading); /* 0/1 -- stdin/stdout */ + if (pipe_fd[reading] != reading) { + dup2(pipe_fd[reading], reading); + close(pipe_fd[reading]); + } + argv[2] = command; + execve(_PATH_BSHELL, argv, environ); + abort(); + } + /* parent */ + close(pipe_fd[reading]); + return fdopen(pipe_fd[notreading], rw); +} + +int pclose(fd) + FILE *fd; +{ + int waitstat; + + if (fclose(fd) != 0) + return EOF; + wait(&waitstat); + return waitstat; +} + diff --git a/src/libc/printf.c b/src/libc/printf.c new file mode 100755 index 00000000..caf94a12 --- /dev/null +++ b/src/libc/printf.c @@ -0,0 +1,36 @@ +/* printf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +#include "printf.h" + +#ifdef L_printf + +#if 1 +int printf(char *fmt,...) +#else +int printf(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ptr; + int rv; + + va_strt(ptr, fmt); + rv = vfprintf(stdout, fmt, ptr); + va_end(ptr); + return rv; +} +#endif + diff --git a/src/libc/printf.h b/src/libc/printf.h new file mode 100755 index 00000000..82ecfad8 --- /dev/null +++ b/src/libc/printf.h @@ -0,0 +1,39 @@ +/* printf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ +#ifdef MAKE_ALL +#define L_printf +#define L_sprintf +#define L_fprintf +#define L_vprintf +#define L_vsprintf +#define L_vfprintf +#ifndef HI_TECH_C +/* #define FLOATS Nick */ +#endif +#endif + +#include +#include +#if 1 +#include +#define va_strt va_start +#else +#include +#define va_strt(p,i) va_start(p) +#endif + +#include +#include +#include + diff --git a/src/libc/putenv.c b/src/libc/putenv.c new file mode 100755 index 00000000..816f00f1 --- /dev/null +++ b/src/libc/putenv.c @@ -0,0 +1,55 @@ +/************************** putenv.c ***************************/ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "environ.h" + +#ifdef L_putenv +#include + +#define ADD_NUM 4 + +int putenv(var) + register char *var; +{ + static char **mall_env = 0; + static int extras = 0; + char **p, **d, *r, *q; + register int len; + + if ((r = strchr(var, '=')) == 0) + len = strlen(var); + else len = (int)(r - var); + p = environ; + while ((q = *p) != NULL) { + if (q[0] == var[0] && + q[len] == '=' && + memcmp(var, q, len) == 0) { + while ((p[0] = p[1]) != NULL) + p++; + extras++; + break; + } + ++p; + } + if (r == 0) + return 0; /* want removing */ + if (extras <= 0) { /* Need more space */ + if ((d = malloc((p-environ+1+ADD_NUM)*sizeof(char *))) == 0) + return -1; + memcpy(d, environ, (p-environ+1)*sizeof(char *)); + p = d + (p - environ); + extras = ADD_NUM; + if (mall_env) + free(mall_env); + mall_env = environ = d; + } + *p++ = var; + *p = NULL; + extras--; + return 0; +} +#endif + \ No newline at end of file diff --git a/src/libc/putgetch.c b/src/libc/putgetch.c new file mode 100755 index 00000000..5fd60951 --- /dev/null +++ b/src/libc/putgetch.c @@ -0,0 +1,28 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_putchar +int _putchar(ch) + int ch; +{ + return write(STDOUT_FILENO, &ch, 1); +} +#endif + +#ifdef L_getchar +int _getchar(void) { + unsigned char ch; + + if (read(STDIN_FILENO, &ch, 1) == 1) + return ch; + return EOF; +} +#endif + \ No newline at end of file diff --git a/src/libc/putpwent.c b/src/libc/putpwent.c new file mode 100755 index 00000000..ff629397 --- /dev/null +++ b/src/libc/putpwent.c @@ -0,0 +1,23 @@ +/* putpwent.c + */ + +#include "passwd.h" + +#ifdef L_putpwent +int putpwent(pwd, f) + struct passwd *pwd; + FILE * f; +{ + if (pwd == NULL || f == NULL) { + errno = EINVAL; + return -1; + } + if (fprintf(f, "%s:%s:%u:%u:%s:%s:%s\n", + pwd->pw_name, pwd->pw_passwd, + pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, + pwd->pw_dir, pwd->pw_shell) < 0) + return -1; + return 0; +} +#endif + diff --git a/src/libc/qsort.c b/src/libc/qsort.c new file mode 100755 index 00000000..1ddff4d6 --- /dev/null +++ b/src/libc/qsort.c @@ -0,0 +1,141 @@ +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + */ +/* $Header: qsort.c,v 1.3 90/08/28 14:03:24 eck Exp $ */ + +#include + +static void qsort1(char *, char *, size_t); +/*static int (*qcompar)(const char *, const char *);*/ +static cmp_func_t qcompar; +static void qexchange(char *, char *, size_t); +static void q3exchange(char *, char *, char *, size_t); + +static void +qsort1(char *a1, char *a2, register size_t width) +{ + register char *left, *right; + register char *lefteq, *righteq; + int cmp; + + for (;;) { + if (a2 <= a1) return; + left = a1; + right = a2; + lefteq = righteq = a1 + width * (((a2-a1)+width)/(2*width)); + /* + Pick an element in the middle of the array. + We will collect the equals around it. + "lefteq" and "righteq" indicate the left and right + bounds of the equals respectively. + Smaller elements end up left of it, larger elements end + up right of it. + */ +again: + while (left < lefteq && (cmp = (*qcompar)(left, lefteq)) <= 0) { + if (cmp < 0) { + /* leave it where it is */ + left += width; + } + else { + /* equal, so exchange with the element to + the left of the "equal"-interval. + */ + lefteq -= width; + qexchange(left, lefteq, width); + } + } + while (right > righteq) { + if ((cmp = (*qcompar)(right, righteq)) < 0) { + /* smaller, should go to left part + */ + if (left < lefteq) { + /* yes, we had a larger one at the + left, so we can just exchange + */ + qexchange(left, right, width); + left += width; + right -= width; + goto again; + } + /* no more room at the left part, so we + move the "equal-interval" one place to the + right, and the smaller element to the + left of it. + This is best expressed as a three-way + exchange. + */ + righteq += width; + q3exchange(left, righteq, right, width); + lefteq += width; + left = lefteq; + } + else if (cmp == 0) { + /* equal, so exchange with the element to + the right of the "equal-interval" + */ + righteq += width; + qexchange(right, righteq, width); + } + else /* just leave it */ right -= width; + } + if (left < lefteq) { + /* larger element to the left, but no more room, + so move the "equal-interval" one place to the + left, and the larger element to the right + of it. + */ + lefteq -= width; + q3exchange(right, lefteq, left, width); + righteq -= width; + right = righteq; + goto again; + } + /* now sort the "smaller" part */ + qsort1(a1, lefteq - width, width); + /* and now the larger, saving a subroutine call + because of the for(;;) + */ + a1 = righteq + width; + } + /*NOTREACHED*/ +} + +static void +qexchange(register char *p, register char *q, + register size_t n) +{ + register int c; + + while (n-- > 0) { + c = *p; + *p++ = *q; + *q++ = c; + } +} + +static void +q3exchange(register char *p, register char *q, register char *r, + register size_t n) +{ + register int c; + + while (n-- > 0) { + c = *p; + *p++ = *r; + *r++ = *q; + *q++ = c; + } +} + +void +qsort(void *base, size_t nel, size_t width, + cmp_func_t compar) +{ + /* when nel is 0, the expression '(nel - 1) * width' is wrong */ + if (!nel) return; + qcompar = compar; + qsort1(base, (char *)base + (nel - 1) * width, width); +} + diff --git a/src/libc/rand.c b/src/libc/rand.c new file mode 100755 index 00000000..0757ac25 --- /dev/null +++ b/src/libc/rand.c @@ -0,0 +1,70 @@ +/* rand.c + */ +#include + +#ifdef ZX81_RNG +/* This is my favorite tiny RNG, If you had a ZX81 you may recognise it :-) + * (RdeBath) + */ + +#define MAXINT (((unsigned)-1)>>1) + +static unsigned sseed = 0; + +int rand(void) { + sseed = (unsigned)(((sseed + 1L) * 75L) % 65537L) - 1; + return sseed; +} + +void srand(seed) + unsigned seed; +{ + sseed = seed; +} +#else +/* This generator is a combination of three linear congruential generators + * with periods or 2^15-405, 2^15-1041 and 2^15-1111. It has a period that + * is the product of these three numbers. + */ +static int seed1 = 1; +static int seed2 = 1; +static int seed3 = 1; +#define MAXINT (((unsigned)-1)>>1) + +#define CRANK(a,b,c,m,s) \ + q = s/a; \ + s = b*(s-a*q) - c*q; \ + if (s < 0) s += m; + +int rand(void) { + register int q; +#if 1 + q = seed1/206; + seed1 = 157*(seed1-206*q) - 31*q; + if (seed1 < 0) seed1 += 32363; + + q = seed2/217; + seed2 = 146*(seed2-217*q) - 45*q; + if (seed2 < 0) seed2 += 31727; + + q = seed3/222; + seed3 = 142*(seed3-222*q) - 133*q; + if (seed3 < 0) seed3 += 31657; +#else + CRANK(206, 157, 31, 32363, seed1); + CRANK(217, 146, 45, 31727, seed2); + CRANK(222, 142, 133, 31657, seed3); +#endif + return seed1 ^ seed2 ^ seed3; +} + +void srand(seed) + unsigned int seed; +{ + seed &= MAXINT; + seed1 = seed % 32362 + 1; + seed2 = seed % 31726 + 1; + seed3 = seed % 31656 + 1; +} +#endif + diff --git a/src/libc/readdir.c b/src/libc/readdir.c new file mode 100755 index 00000000..1fdc2008 --- /dev/null +++ b/src/libc/readdir.c @@ -0,0 +1,34 @@ +/* readdir.c readdir implementation + * + */ +#include +#include +#include +#include +#include +#include +#include + +struct dirent *readdir(dir) + register DIR *dir; +{ + direct_t direntry; + register struct dirent *buf; + + if (dir == NULL || dir->dd_buf == NULL || dir->dd_fd == 0) { + errno = EFAULT; +Err: return NULL; + } + direntry.d_name[0] = 0; + while (direntry.d_name[0] == 0) + if (read(dir->dd_fd, &direntry, sizeof(direntry)) != sizeof(direntry)) + goto Err; + buf = dir->dd_buf; + buf->d_ino = direntry.d_ino; + buf->d_off = dir->dd_loc++; + strncpy(buf->d_name, (char *)direntry.d_name, DIRNAMELEN); + buf->d_name[DIRNAMELEN] = 0; + buf->d_reclen = strlen(buf->d_name); + return buf; +} + \ No newline at end of file diff --git a/src/libc/readlink.c b/src/libc/readlink.c new file mode 100755 index 00000000..40de52f7 --- /dev/null +++ b/src/libc/readlink.c @@ -0,0 +1,20 @@ +/* readlink.c readlink implementation for UZIX + */ +#include +#include +#include + +int readlink(name, buf, size) + char *name; + char *buf; + int size; +{ + int sts, fd = open(name, O_SYMLINK); + + if (fd < 0) + return -1; + sts = read(fd, buf, size); + close(fd); + return sts; +} + \ No newline at end of file diff --git a/src/libc/realloc.c b/src/libc/realloc.c new file mode 100755 index 00000000..07240fd3 --- /dev/null +++ b/src/libc/realloc.c @@ -0,0 +1,30 @@ +/* realloc.c */ +/* Copyright (C) 1984 by Manx Software Systems */ + +#include "malloc-l.h" + +void *realloc(void *area, size_t size) + { + register void *cp; + size_t osize; + +#ifdef MALLOC_DEBUG + printf("realloc(0x%x, 0x%x) starting\n", area, size); + fflush(stdout); +#endif + + osize = (((FREE *)area-1)->f_size - 1) * sizeof(FREE); + free(area); + if ((cp = malloc(size)) != 0 && cp != area) +#if 1 /* Nick */ + memcpy(cp, area, size>osize ? osize : size); +#else + movmem(area, cp, size>osize ? osize : size); +#endif +#ifdef MALLOC_DEBUG + printf("realloc() returning 0x%x\n", cp); + fflush(stdout); +#endif + return cp; + } + diff --git a/src/libc/realloc.c$ b/src/libc/realloc.c$ new file mode 100755 index 00000000..65c453e3 --- /dev/null +++ b/src/libc/realloc.c$ @@ -0,0 +1,32 @@ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + * + * This is a combined alloca/malloc package. It uses a classic algorithm + * and so may be seen to be quite slow compared to more modern routines + * with 'nasty' distributions. + */ + +#include "malloc-l.h" + +#ifdef L_realloc +void *realloc(ptr, size) + void *ptr; + size_t size; +{ + void *nptr; + unsigned int osize; + + if (ptr == 0) + return malloc(size); + /* ??? what if I really want to free rest of block ? */ + if (size <= (osize = (m_size(((mem *) ptr) - 1) - 1) * sizeof(mem))) + return ptr; + if ((nptr = malloc(size)) == NULL) + return 0; + memcpy(nptr, ptr, osize); + free(ptr); + return nptr; +} +#endif /* L_realloc */ + \ No newline at end of file diff --git a/src/libc/regerror.c b/src/libc/regerror.c new file mode 100755 index 00000000..ab93e28a --- /dev/null +++ b/src/libc/regerror.c @@ -0,0 +1,18 @@ +/* regerror.c + */ +#include +#include +#include +#include + +void regerror(s) + char *s; +{ +#ifdef ERRAVAIL + error("regexp: %s", s); +#else + fprintf(stderr, "regexp(3): %s", s); + exit(1); +#endif +} + \ No newline at end of file diff --git a/src/libc/regexp.c b/src/libc/regexp.c new file mode 100755 index 00000000..01f3bdeb --- /dev/null +++ b/src/libc/regexp.c @@ -0,0 +1,1086 @@ +/* regexp.c regcomp and regexec -- regsub and regerror are elsewhere + * + * Copyright (c) 1986 by University of Toronto. + * Written by Henry Spencer. Not derived from licensed software. + * + * Permission is granted to anyone to use this software for any + * purpose on any computer system, and to redistribute it freely, + * subject to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of + * this software, no matter how awful, even if they arise + * from defects in it. + * + * 2. The origin of this software must not be misrepresented, either + * by explicit claim or by omission. + * + * 3. Altered versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + * + * Beware that some of this code is subtly aware of the way operator + * precedence is structured in regular expressions. Serious changes in + * regular-expression syntax might require a total rethink. + */ +#include +#include +#include +#include +#include "regmagic.h" + +/* The "internal use only" fields in regexp.h are present to pass info from + * compile to execute that permits the execute phase to run lots faster on + * simple cases. They are: + * + * regstart char that must begin a match; '\0' if none obvious + * reganch is the match anchored (at beginning-of-line only)? + * regmust string (pointer into program) that match must include, or NULL + * regmlen length of regmust string + * + * Regstart and reganch permit very fast decisions on suitable starting points + * for a match, cutting down the work a lot. Regmust permits fast rejection + * of lines that cannot possibly match. The regmust tests are costly enough + * that regcomp() supplies a regmust only if the r.e. contains something + * potentially expensive (at present, the only such thing detected is * or + + * at the start of the r.e., which can involve a lot of backup). Regmlen is + * supplied because the test in regexec() needs it and regcomp() is computing + * it anyway. + */ + +/* Structure for regexp "program". This is essentially a linear encoding + * of a nondeterministic finite-state machine (aka syntax charts or + * "railroad normal form" in parsing technology). Each node is an opcode + * plus a "next" pointer, possibly plus an operand. "Next" pointers of + * all nodes except BRANCH implement concatenation; a "next" pointer with + * a BRANCH on both ends of it is connecting two alternatives. (Here we + * have one of the subtle syntax dependencies: an individual BRANCH (as + * opposed to a collection of them) is never concatenated with anything + * because of operator precedence.) The operand of some types of node is + * a literal string; for others, it is a node leading into a sub-FSM. In + * particular, the operand of a BRANCH node is the first node of the branch. + * (NB this is *not* a tree structure: the tail of the branch connects + * to the thing following the set of BRANCHes.) The opcodes are: + */ + +/* definition number opnd? meaning */ +#define END 0 /* no End of program. */ +#define BOL 1 /* no Match "" at beginning of line. */ +#define EOL 2 /* no Match "" at end of line. */ +#define ANY 3 /* no Match any one character. */ +#define ANYOF 4 /* str Match any character in this string. */ +#define ANYBUT 5 /* str Match any character not in this string. */ +#define BRANCH 6 /* node Match this alternative, or the next... */ +#define BACK 7 /* no Match "", "next" ptr points backward. */ +#define EXACTLY 8 /* str Match this string. */ +#define NOTHING 9 /* no Match empty string. */ +#define STAR 10 /* node Match this (simple) thing 0 or more times. */ +#define PLUS 11 /* node Match this (simple) thing 1 or more times. */ +#define OPEN 20 /* no Mark this point in input as start of #n. */ + /* OPEN+1 is number 1, etc. */ +#define CLOSE 30 /* no Analogous to OPEN. */ + +/* + * Opcode notes: + * + * BRANCH The set of branches constituting a single choice are hooked + * together with their "next" pointers, since precedence prevents + * anything being concatenated to any individual branch. The + * "next" pointer of the last BRANCH in a choice points to the + * thing following the whole choice. This is also where the + * final "next" pointer of each individual branch points; each + * branch starts with the operand node of a BRANCH node. + * + * BACK Normal "next" pointers all implicitly point forward; BACK + * exists to make loop structures possible. + * + * STAR,PLUS '?', and complex '*' and '+', are implemented as circular + * BRANCH structures using BACK. Simple cases (one character + * per match) are implemented with STAR and PLUS for speed + * and to minimize recursive plunges. + * + * OPEN,CLOSE ...are numbered at compile time. + */ + +/* + * A node is one char of opcode followed by two chars of "next" pointer. + * "Next" pointers are stored as two 8-bit pieces, high order first. The + * value is a positive offset from the opcode of the node containing it. + * An operand, if any, simply follows the node. (Note that much of the + * code generation knows about this implicit relationship.) + * + * Using two bytes for the "next" pointer is vast overkill for most things, + * but allows patterns to get big without disasters. + */ +#define OP(p) (*(p)) +#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) +#define OPERAND(p) ((p) + 3) + +/* + * See regmagic.h for one further detail of program structure. + */ + +/* + * Utility definitions. + */ +#ifndef CHARBITS +#define UCHARAT(p) ((int)*(unsigned char *)(p)) +#else +#define UCHARAT(p) ((int)*(p)&CHARBITS) +#endif + +extern void regerror __P((char *)); + +#define FAIL(m) { regerror(m); return(NULL); } +#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') +#define META "^$.[()|?+*\\" + +/* + * Flags to be passed up and down. + */ +#define HASWIDTH 01 /* Known never to match null string. */ +#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ +#define SPSTART 04 /* Starts with * or +. */ +#define WORST 0 /* Worst case. */ + +/* + * Global work variables for regcomp(). + */ +static char *regparse; /* Input-scan pointer. */ +static int regnpar; /* () count. */ +static char regdummy; +static char *regcode; /* Code-emit pointer; ®dummy = don't. */ +static long regsize; /* Code size. */ + +/* + * Forward declarations for regcomp()'s friends. + */ +static char *reg __P((int paren, int *flagp)); +static char *regbranch __P((int *flagp)); +static char *regpiece __P((int *flagp)); +static char *regatom __P((int *flagp)); +static char *regnode __P((char op)); +static void regc __P((uint b)); +static void reginsert __P((char op, char *opnd)); +static void regtail __P((char *p, char *val)); +static void regoptail __P((char *p, char *val)); +static int regtry __P((regexp *prog, char *string)); +static int regmatch __P((char *prog)); +static int regrepeat __P((char *p)); +static char *regnext __P((char *p)); +static char *regprop __P((char *op)); +#ifdef STRCSPN +static int strcspn __P((char *, char *)); +#endif + +/* regcomp - compile a regular expression into internal code + * + * We can't allocate space until we know how big the compiled form will be, + * but we can't compile it (and thus know how big it is) until we've got a + * place to put the code. So we cheat: we compile it twice, once with code + * generation turned off and size counting turned on, and once "for real". + * This also means that we don't allocate space until we are sure that the + * thing really will compile successfully, and we never have to move the + * code and thus invalidate pointers into it. (Note that it has to be in + * one piece because free() must be able to free it all.) + * + * Beware that the optimization-preparation code in here knows about some + * of the structure of the compiled regexp. + */ +regexp *regcomp(exp) + char *exp; +{ + register regexp *r; + register char *scan; + register char *longest; + register int len; + int flags; + + if (exp == NULL) + FAIL("NULL argument"); + /* First pass: determine size, legality. */ + regparse = exp; + regnpar = 1; + regsize = 0L; + regcode = ®dummy; + regc(MAGIC); + if (reg(0, &flags) == NULL) + return(NULL); + /* Small enough for pointer-storage convention? */ + if (regsize >= 32767L) /* Probably could be 65535L. */ + FAIL("regexp too big"); + /* Allocate space. */ + r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize); + if (r == NULL) + FAIL("out of space"); + /* Second pass: emit code. */ + regparse = exp; + regnpar = 1; + regcode = r->program; + regc(MAGIC); + if (reg(0, &flags) == NULL) + return(NULL); + /* Dig out information for optimizations. */ + r->regstart = '\0'; /* Worst-case defaults. */ + r->reganch = 0; + r->regmust = NULL; + r->regmlen = 0; + scan = r->program+1; /* First BRANCH. */ + if (OP(regnext(scan)) == END) { /* Only one top-level choice. */ + scan = OPERAND(scan); + /* Starting-point info. */ + if (OP(scan) == EXACTLY) + r->regstart = *OPERAND(scan); + else if (OP(scan) == BOL) + r->reganch++; + /* + * If there's something expensive in the r.e., find the + * longest literal string that must appear and make it the + * regmust. Resolve ties in favor of later strings, since + * the regstart check works with the beginning of the r.e. + * and avoiding duplication strengthens checking. Not a + * strong reason, but sufficient in the absence of others. + */ + if (flags&SPSTART) { + longest = NULL; + len = 0; + while (scan != NULL) { + if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { + longest = OPERAND(scan); + len = strlen(OPERAND(scan)); + } + scan = regnext(scan); + } + r->regmust = longest; + r->regmlen = len; + } + } + return r; +} + +/* reg - regular expression, i.e. main body or parenthesized thing + * + * Caller must absorb opening parenthesis. + * + * Combining parenthesis handling with the base level of regular expression + * is a trifle forced, but the need to tie the tails of the branches to what + * follows makes it hard to avoid. + */ +static char *reg(paren, flagp) + int paren; /* Parenthesized? */ + int *flagp; +{ + register char *ret; + register char *br; + register char *ender; + register int parno; + int flags; + + *flagp = HASWIDTH; /* Tentatively. */ + /* Make an OPEN node, if parenthesized. */ + if (paren) { + if (regnpar >= NSUBEXP) + FAIL("too many ()"); + parno = regnpar; + regnpar++; + ret = regnode(OPEN+parno); + } + else ret = NULL; + /* Pick up the branches, linking them together. */ + br = regbranch(&flags); + if (br == NULL) + return NULL; + if (ret != NULL) + regtail(ret, br); /* OPEN -> first. */ + else ret = br; + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + while (*regparse == '|') { + regparse++; + br = regbranch(&flags); + if (br == NULL) + return NULL; + regtail(ret, br); /* BRANCH -> BRANCH. */ + if (!(flags&HASWIDTH)) + *flagp &= ~HASWIDTH; + *flagp |= flags&SPSTART; + } + /* Make a closing node, and hook it on the end. */ + ender = regnode((paren) ? CLOSE+parno : END); + regtail(ret, ender); + /* Hook the tails of the branches to the closing node. */ + br = ret; + while (br != NULL) { + regoptail(br, ender); + br = regnext(br); + } + /* Check for proper termination. */ + if (paren && *regparse++ != ')') { + FAIL("unmatched ()"); + } + else if (!paren && *regparse != '\0') { + if (*regparse == ')') { + FAIL("unmatched ()"); + } + else FAIL("junk on end"); /* "Can't happen". */ + /* NOTREACHED */ + } + return ret; +} + +/* regbranch - one alternative of an | operator + * + * Implements the concatenation operator. + */ +static char *regbranch(flagp) + int *flagp; +{ + register char *ret; + register char *chain; + register char *latest; + int flags; + + *flagp = WORST; /* Tentatively. */ + ret = regnode(BRANCH); + chain = NULL; + while (*regparse != '\0' && *regparse != '|' && *regparse != ')') { + latest = regpiece(&flags); + if (latest == NULL) + return(NULL); + *flagp |= flags&HASWIDTH; + if (chain == NULL) /* First piece. */ + *flagp |= flags&SPSTART; + else regtail(chain, latest); + chain = latest; + } + if (chain == NULL) /* Loop ran zero times. */ + regnode(NOTHING); + return ret; +} + +/* regpiece - something followed by possible [*+?] + * + * Note that the branching code sequences used for ? and the general cases + * of * and + are somewhat optimized: they use the same NOTHING node as + * both the endmarker for their branch list and the body of the last branch. + * It might seem that this node could be dispensed with entirely, but the + * endmarker role is not redundant. + */ +static char *regpiece(flagp) + int *flagp; +{ + register char *ret; + register char op; + register char *next; + int flags; + + ret = regatom(&flags); + if (ret == NULL) + return(NULL); + op = *regparse; + if (!ISMULT(op)) { + *flagp = flags; + return(ret); + } + if (!(flags&HASWIDTH) && op != '?') + FAIL("*+ operand could be empty"); + *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); + if (op == '*' && (flags&SIMPLE)) + reginsert(STAR, ret); + else if (op == '*') { + /* Emit x* as (x&|), where & means "self". */ + reginsert(BRANCH, ret); /* Either x */ + regoptail(ret, regnode(BACK)); /* and loop */ + regoptail(ret, ret); /* back */ + regtail(ret, regnode(BRANCH)); /* or */ + regtail(ret, regnode(NOTHING)); /* null. */ + } + else if (op == '+' && (flags&SIMPLE)) + reginsert(PLUS, ret); + else if (op == '+') { + /* Emit x+ as x(&|), where & means "self". */ + next = regnode(BRANCH); /* Either */ + regtail(ret, next); + regtail(regnode(BACK), ret); /* loop back */ + regtail(next, regnode(BRANCH)); /* or */ + regtail(ret, regnode(NOTHING)); /* null. */ + } + else if (op == '?') { + /* Emit x? as (x|) */ + reginsert(BRANCH, ret); /* Either x */ + regtail(ret, regnode(BRANCH)); /* or */ + next = regnode(NOTHING); /* null. */ + regtail(ret, next); + regoptail(ret, next); + } + regparse++; + if (ISMULT(*regparse)) + FAIL("nested *?+"); + return(ret); +} + +/* regatom - the lowest level + * + * Optimization: gobbles an entire sequence of ordinary characters so that + * it can turn them into a single node, which is smaller to store and + * faster to run. Backslashed characters are exceptions, each becoming a + * separate node; the code is simpler that way and it's not worth fixing. + */ +static char *regatom(flagp) + int *flagp; +{ + register char *ret; + int flags; + + *flagp = WORST; /* Tentatively. */ + switch (*regparse++) { + case '^': + ret = regnode(BOL); + break; + case '$': + ret = regnode(EOL); + break; + case '.': + ret = regnode(ANY); + *flagp |= HASWIDTH|SIMPLE; + break; + case '[': { + register int class; + register int classend; + + if (*regparse == '^') { /* Complement of range. */ + ret = regnode(ANYBUT); + regparse++; + } + else ret = regnode(ANYOF); + if (*regparse == ']' || *regparse == '-') + regc(*regparse++); + while (*regparse != '\0' && *regparse != ']') { + if (*regparse == '-') { + regparse++; + if (*regparse == ']' || *regparse == '\0') + regc('-'); + else { + class = UCHARAT(regparse-2)+1; + classend = UCHARAT(regparse); + if (class > classend+1) + FAIL("invalid [] range"); + while (class <= classend) + regc(class++); + regparse++; + } + } + else regc(*regparse++); + } + regc('\0'); + if (*regparse != ']') + FAIL("unmatched []"); + regparse++; + *flagp |= HASWIDTH|SIMPLE; + } + break; + case '(': + ret = reg(1, &flags); + if (ret == NULL) + return(NULL); + *flagp |= flags&(HASWIDTH|SPSTART); + break; + case '\0': + case '|': + case ')': + FAIL("internal urp"); /* Supposed to be caught earlier. */ + case '?': + case '+': + case '*': + FAIL("?+* follows nothing"); + case '\\': + if (*regparse == '\0') + FAIL("trailing \\"); + ret = regnode(EXACTLY); + regc(*regparse++); + regc('\0'); + *flagp |= HASWIDTH|SIMPLE; + break; + default: { + register int len; + register char ender; + + len = strcspn(--regparse, META); + if (len <= 0) + FAIL("internal disaster"); + ender = *(regparse+len); + if (len > 1 && ISMULT(ender)) + len--; /* Back off clear of ?+* operand. */ + *flagp |= HASWIDTH; + if (len == 1) + *flagp |= SIMPLE; + ret = regnode(EXACTLY); + while (len > 0) { + regc(*regparse++); + len--; + } + regc('\0'); + } + break; + } + return ret; +} + +/* regnode - emit a node + */ +static char *regnode(op) + char op; +{ + register char *ret; + register char *ptr; + + ret = regcode; + if (ret == ®dummy) { + regsize += 3; + return ret; + } + ptr = ret; + *ptr++ = op; + *ptr++ = '\0'; /* Null "next" pointer. */ + *ptr++ = '\0'; + regcode = ptr; + return ret; +} + +/* regc - emit (if appropriate) a byte of code + */ +static void regc(b) + uint b; +{ + if (regcode != ®dummy) + *regcode++ = (char)b; + else regsize++; +} + +/* reginsert - insert an operator in front of already-emitted operand + * + * Means relocating the operand. + */ +static void reginsert(op, opnd) + char op; + char *opnd; +{ + register char *src; + register char *dst; + register char *place; + + if (regcode == ®dummy) { + regsize += 3; + return; + } + src = regcode; + regcode += 3; + dst = regcode; + while (src > opnd) + *--dst = *--src; + place = opnd; /* Op node, where operand used to be. */ + *place++ = op; + *place++ = '\0'; + *place++ = '\0'; +} + +/* regtail - set the next-pointer at the end of a node chain + */ +static void regtail(p, val) + char *p; + char *val; +{ + register char *scan; + register char *temp; + register int offset; + + if (p == ®dummy) + return; + /* Find last node. */ + scan = p; + for (;;) { + temp = regnext(scan); + if (temp == NULL) + break; + scan = temp; + } + if (OP(scan) == BACK) + offset = scan - val; + else offset = val - scan; + *(scan+1) = (offset>>8)&0377; + *(scan+2) = offset&0377; +} + +/* regoptail - regtail on operand of first argument; nop if operandless + */ +static void regoptail(p, val) + char *p; + char *val; +{ + /* "Operandless" and "op != BRANCH" are synonymous in practice. */ + if (p == NULL || p == ®dummy || OP(p) != BRANCH) + return; + regtail(OPERAND(p), val); +} + +/* + * regexec and friends + */ + +/* + * Global work variables for regexec(). + */ +static char *reginput; /* String-input pointer. */ +static char *regbol; /* Beginning of input, for ^ check. */ +static char **regstartp; /* Pointer to startp array. */ +static char **regendp; /* Ditto for endp. */ + +/* + * Forwards. + */ +#ifdef DEBUG +int regnarrate = 0; +#endif + +/* regexec - match a regexp against a string + */ +int regexec(prog, string) + regexp *prog; + char *string; +{ + register char *s; + + /* Be paranoid... */ + if (prog == NULL || string == NULL) { + regerror("NULL parameter"); + return(0); + } + /* Check validity of program. */ + if (UCHARAT(prog->program) != MAGIC) { + regerror("corrupted program"); + return(0); + } + /* If there is a "must appear" string, look for it. */ + if (prog->regmust != NULL) { + s = string; + while ((s = strchr(s, prog->regmust[0])) != NULL) { + if (strncmp(s, prog->regmust, prog->regmlen) == 0) + break; /* Found it. */ + s++; + } + if (s == NULL) /* Not present. */ + return(0); + } + /* Mark beginning of line for ^ . */ + regbol = string; + /* Simplest case: anchored match need be tried only once. */ + if (prog->reganch) + return(regtry(prog, string)); + /* Messy cases: unanchored match. */ + s = string; + if (prog->regstart != '\0') { + /* We know what char it must start with. */ + while ((s = strchr(s, prog->regstart)) != NULL) { + if (regtry(prog, s)) + return(1); + s++; + } + } + else { /* We don't -- general case. */ + do { + if (regtry(prog, s)) + return(1); + } while (*s++ != '\0'); + } + /* Failure. */ + return(0); +} + +/* regtry - try match at specific point + * 0 failure, 1 success + */ +static int regtry(prog, string) + regexp *prog; + char *string; +{ + register int i; + register char **sp; + register char **ep; + + reginput = string; + regstartp = prog->startp; + regendp = prog->endp; + sp = prog->startp; + ep = prog->endp; + i = NSUBEXP; + while (i-- != 0) { + *sp++ = NULL; + *ep++ = NULL; + } + if (regmatch(prog->program + 1)) { + prog->startp[0] = string; + prog->endp[0] = reginput; + return(1); + } + return(0); +} + +/* regmatch - main matching routine + * + * Conceptually the strategy is simple: check to see whether the current + * node matches, call self recursively to see whether the rest matches, + * and then act accordingly. In practice we make some effort to avoid + * recursion, in particular by going through "ordinary" nodes (that don't + * need to know whether the rest of the match failed) by a loop instead of + * by recursion. + */ +static int regmatch(prog) + char *prog; +{ + register char *scan; /* Current node. */ + char *next; /* Next node. */ + + scan = prog; +#ifdef DEBUG + if (scan != NULL && regnarrate) + fprintf(stderr, "%s(\n", regprop(scan)); +#endif + while (scan != NULL) { +#ifdef DEBUG + if (regnarrate) + fprintf(stderr, "%s...\n", regprop(scan)); +#endif + next = regnext(scan); + + switch (OP(scan)) { + case BOL: + if (reginput != regbol) + return(0); + break; + case EOL: + if (*reginput != '\0') + return(0); + break; + case ANY: + if (*reginput == '\0') + return(0); + reginput++; + break; + case EXACTLY: { + register int len; + register char *opnd; + + opnd = OPERAND(scan); + /* Inline the first character, for speed. */ + if (*opnd != *reginput) + return(0); + len = strlen(opnd); + if (len > 1 && strncmp(opnd, reginput, len) != 0) + return(0); + reginput += len; + } + break; + case ANYOF: + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL) + return(0); + reginput++; + break; + case ANYBUT: + if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL) + return(0); + reginput++; + break; + case NOTHING: + break; + case BACK: + break; + case OPEN+1: + case OPEN+2: + case OPEN+3: + case OPEN+4: + case OPEN+5: + case OPEN+6: + case OPEN+7: + case OPEN+8: + case OPEN+9: { + register int no; + register char *save; + + no = OP(scan) - OPEN; + save = reginput; + + if (regmatch(next)) { + /* + * Don't set startp if some later + * invocation of the same parentheses + * already has. + */ + if (regstartp[no] == NULL) + regstartp[no] = save; + return(1); + } + return(0); + } + case CLOSE+1: + case CLOSE+2: + case CLOSE+3: + case CLOSE+4: + case CLOSE+5: + case CLOSE+6: + case CLOSE+7: + case CLOSE+8: + case CLOSE+9: { + register int no; + register char *save; + + no = OP(scan) - CLOSE; + save = reginput; + + if (regmatch(next)) { + /* + * Don't set endp if some later + * invocation of the same parentheses + * already has. + */ + if (regendp[no] == NULL) + regendp[no] = save; + return(1); + } + return(0); + } + case BRANCH: { + register char *save; + + if (OP(next) != BRANCH) /* No choice. */ + next = OPERAND(scan); /* Avoid recursion. */ + else { + do { + save = reginput; + if (regmatch(OPERAND(scan))) + return(1); + reginput = save; + scan = regnext(scan); + } while (scan != NULL && OP(scan) == BRANCH); + return(0); + } + } + break; /* ??? */ + case STAR: + case PLUS: { + register char nextch; + register int no; + register char *save; + register int min; + + /* + * Lookahead to avoid useless match attempts + * when we know what character comes next. + */ + nextch = '\0'; + if (OP(next) == EXACTLY) + nextch = *OPERAND(next); + min = (OP(scan) == STAR) ? 0 : 1; + save = reginput; + no = regrepeat(OPERAND(scan)); + while (no >= min) { + /* If it could work, try it. */ + if (nextch == '\0' || *reginput == nextch) + if (regmatch(next)) + return(1); + /* Couldn't or didn't -- back up. */ + no--; + reginput = save + no; + } + return(0); + } + case END: + return(1); /* Success! */ + default: + regerror("memory corruption"); + return(0); + } + scan = next; + } + /* + * We get here only if there's trouble -- normally "case END" is + * the terminating point. + */ + regerror("corrupted pointers"); + return(0); +} + +/* regrepeat - repeatedly match something simple, report how many + */ +static int regrepeat(p) + char *p; +{ + register int count = 0; + register char *scan; + register char *opnd; + + scan = reginput; + opnd = OPERAND(p); + switch (OP(p)) { + case ANY: + count = strlen(scan); + scan += count; + break; + case EXACTLY: + while (*opnd == *scan) { + count++; + scan++; + } + break; + case ANYOF: + while (*scan != '\0' && strchr(opnd, *scan) != NULL) { + count++; + scan++; + } + break; + case ANYBUT: + while (*scan != '\0' && strchr(opnd, *scan) == NULL) { + count++; + scan++; + } + break; + default: /* Oh dear. Called inappropriately. */ + regerror("internal foulup"); + count = 0; /* Best compromise. */ + break; + } + reginput = scan; + + return(count); +} + +/* regnext - dig the "next" pointer out of a node + */ +static char *regnext(p) + register char *p; +{ + register int offset; + + if (p == ®dummy) + return(NULL); + + offset = NEXT(p); + if (offset == 0) + return(NULL); + + if (OP(p) == BACK) + return p-offset; + return p+offset; +} + +#ifdef DEBUG + +/* regdump - dump a regexp onto stdout in vaguely comprehensible form + */ +void regdump(r) + regexp *r; +{ + register char *s, *next; + register char op = EXACTLY; /* Arbitrary non-END op. */ + + s = r->program + 1; + while (op != END) { /* While that wasn't END last time... */ + op = OP(s); + printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ + next = regnext(s); + if (next == NULL) /* Next ptr. */ + printf("(0)"); + else printf("(%d)", (s-r->program)+(next-s)); + s += 3; + if (op == ANYOF || op == ANYBUT || op == EXACTLY) { + /* Literal string, where present. */ + while (*s != '\0') { + putchar(*s); + s++; + } + s++; + } + putchar('\n'); + } + /* Header fields of interest. */ + if (r->regstart != '\0') + printf("start `%c' ", r->regstart); + if (r->reganch) + printf("anchored "); + if (r->regmust != NULL) + printf("must have \"%s\"", r->regmust); + printf("\n"); +} + +/* regprop - printable representation of opcode + */ +static char *regprop(op) + char *op; +{ + register char *p; + static char buf[50]; + + (void) strcpy(buf, ":"); + + switch (OP(op)) { + case BOL: p = "BOL"; break; + case EOL: p = "EOL"; break; + case ANY: p = "ANY"; break; + case ANYOF: p = "ANYOF"; break; + case ANYBUT: p = "ANYBUT"; break; + case BRANCH: p = "BRANCH"; break; + case EXACTLY: p = "EXACTLY"; break; + case NOTHING: p = "NOTHING"; break; + case BACK: p = "BACK"; break; + case END: p = "END"; break; + case STAR: p = "STAR"; break; + case PLUS: p = "PLUS"; break; + case OPEN+1: case OPEN+2: case OPEN+3: case OPEN+4: case OPEN+5: + case OPEN+6: case OPEN+7: case OPEN+8:case OPEN+9: + sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN); + p = NULL; + break; + case CLOSE+1: case CLOSE+2: case CLOSE+3: case CLOSE+4: case CLOSE+5: + case CLOSE+6: case CLOSE+7: case CLOSE+8: case CLOSE+9: + sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE); + p = NULL; + break; + default: + regerror("corrupted opcode"); + break; + } + if (p != NULL) + strcat(buf, p); + return buf; +} +#endif + +/* The following is provided for those people who do not have strcspn() in + * their C libraries. They should get off their butts and do something + * about it; at least one public-domain implementation of those (highly + * useful) string routines has been published on Usenet. + */ +#ifdef STRCSPN +/* strcspn - find length of initial segment of s1 consisting entirely + * of characters not from s2 + */ +static int strcspn(s1, s2) + char *s1; + char *s2; +{ + register char *scan1; + register char *scan2; + register int count; + + count = 0; + scan1 = s1; + while (*scan1 != '\0') { + for (scan2 = s2; *scan2 != '\0';) { /* ++ moved down. */ + if (*scan1 == *scan2++) + return(count); + } + scan1++; + count++; + } + return count; +} +#endif + diff --git a/src/libc/regsub.c b/src/libc/regsub.c new file mode 100755 index 00000000..a5c37cc9 --- /dev/null +++ b/src/libc/regsub.c @@ -0,0 +1,80 @@ +/* regsub.c + * + * Copyright (c) 1986 by University of Toronto. + * Written by Henry Spencer. Not derived from licensed software. + * + * Permission is granted to anyone to use this software for any + * purpose on any computer system, and to redistribute it freely, + * subject to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of + * this software, no matter how awful, even if they arise + * from defects in it. + * + * 2. The origin of this software must not be misrepresented, either + * by explicit claim or by omission. + * + * 3. Altered versions must be plainly marked as such, and must not + * be misrepresented as being the original software. + */ +#include +#include +#include +#include "regmagic.h" + +#ifndef CHARBITS +#define UCHARAT(p) ((int)*(unsigned char *)(p)) +#else +#define UCHARAT(p) ((int)*(p)&CHARBITS) +#endif + +extern void regerror __P((char *)); + +/* regsub - perform substitutions after a regexp match + */ +void regsub(prog, source, dest) + regexp *prog; + char *source; + char *dest; +{ + register char *src; + register char *dst; + register char c; + register int no; + register int len; + + if (prog == NULL || source == NULL || dest == NULL) { + regerror("NULL parm to regsub"); + return; + } + if (UCHARAT(prog->program) != MAGIC) { + regerror("damaged regexp fed to regsub"); + return; + } + src = source; + dst = dest; + while ((c = *src++) != '\0') { + if (c == '&') + no = 0; + else if (c == '\\' && '0' <= *src && *src <= '9') + no = *src++ - '0'; + else no = -1; + if (no < 0) { /* Ordinary character. */ + if (c == '\\' && (*src == '\\' || *src == '&')) + c = *src++; + *dst++ = c; + } + else if (prog->startp[no] != NULL && prog->endp[no] != NULL) { + len = prog->endp[no] - prog->startp[no]; + strncpy(dst, prog->startp[no], len); + dst += len; + if (len != 0 && *(dst-1) == '\0') { + /* strncpy hit NUL. */ + regerror("damaged match string"); + return; + } + } + } + *dst++ = '\0'; +} + \ No newline at end of file diff --git a/src/libc/rename.c b/src/libc/rename.c new file mode 100755 index 00000000..41c1b746 --- /dev/null +++ b/src/libc/rename.c @@ -0,0 +1,16 @@ +/* rename.c + */ +#include +#include + +int rename(oldname, newname) + char *oldname; + char *newname; +{ + int error = link(oldname, newname); + + if (error) + return error; + return unlink(oldname); +} + \ No newline at end of file diff --git a/src/libc/rewind.c b/src/libc/rewind.c new file mode 100755 index 00000000..0f7a5193 --- /dev/null +++ b/src/libc/rewind.c @@ -0,0 +1,54 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_rewind +void rewind(fp) + FILE *fp; +{ + fseek(fp, 0L, SEEK_SET); + clearerr(fp); +} +#endif + +#ifdef L_fseek +int fseek(fp, offset, ref) + FILE *fp; + long offset; + int ref; +{ +#if 1 + /* if __MODE_READING and no ungetc ever done can just move pointer */ + /* This needs testing! */ + if ((fp->mode & (__MODE_READING | __MODE_UNGOT)) == __MODE_READING && + (ref == SEEK_SET || ref == SEEK_CUR)) { + long fpos = lseek(fp->fd, 0L, SEEK_CUR); + + if (fpos == -1L) + return EOF; + if (ref == SEEK_CUR) { + ref = SEEK_SET; + offset += fpos + (fp->bufpos - fp->bufread); + } + if (ref == SEEK_SET) { + if (offset < fpos && /* ??? */ + offset >= fpos + (fp->bufstart - fp->bufread)) { + fp->bufpos = (int)(offset - fpos) + fp->bufread; + return 0; + } + } + } +#endif + /* Use fflush to sync the pointers */ + if (fflush(fp) == EOF || lseek(fp->fd, offset, ref) < 0) + return EOF; + return 0; +} +#endif + diff --git a/src/libc/rewindir.c b/src/libc/rewindir.c new file mode 100755 index 00000000..08bdf8f0 --- /dev/null +++ b/src/libc/rewindir.c @@ -0,0 +1,22 @@ +/* rewindir.c rewinddir implementation + * + */ +#include +#include +#include +#include +#include +#include +#include + +void rewinddir(dir) + register DIR *dir; +{ + if (dir == NULL || dir->dd_buf == NULL || dir->dd_fd == 0) { + errno = EFAULT; + return; + } + dir->dd_loc = 0; + lseek(dir->dd_fd, 0L, SEEK_SET); +} + diff --git a/src/libc/rmdir.c b/src/libc/rmdir.c new file mode 100755 index 00000000..ed506d27 --- /dev/null +++ b/src/libc/rmdir.c @@ -0,0 +1,51 @@ +/* rmdir.c + */ +#include +#include +#include +#include +#include +#include + +int rmdir(path) + char *path; +{ + struct stat statbuf; + char newpath[PATHLEN]; + direct_t dir; + int fd; + + if (strlen(path)+3+1 > sizeof(newpath)) { + errno = ENAMETOOLONG; + goto Err; + } + if (stat(path, &statbuf) != 0) + goto Err; + if ((statbuf.st_mode & S_IFDIR) == 0) { + errno = ENOTDIR; + goto Err; + } + if ((fd = open(path, 0)) < 0) + goto Err; + while (read(fd, (char *) &dir, sizeof(dir)) == sizeof(dir)) { + if (dir.d_ino == 0 || + 0 == strcmp((char *)dir.d_name, ".") || + 0 == strcmp((char *)dir.d_name, "..")) + continue; + close(fd); + errno = ENOTEMPTY; + goto Err; + } + close(fd); + strcpy(newpath, path); + strcat(newpath, "/."); + if (unlink(newpath) != 0) /* remove path/. */ + goto Err; + strcat(newpath, "."); + if (unlink(newpath) != 0) /* remove path/.. */ + goto Err; + if (unlink(path) != 0) /* remove path */ +Err: return -1; + return 0; +} + diff --git a/src/libc/scanf.c b/src/libc/scanf.c new file mode 100755 index 00000000..5e831766 --- /dev/null +++ b/src/libc/scanf.c @@ -0,0 +1,24 @@ +/* scanf1.c + */ + +#include "scanf.h" + +#ifdef L_scanf +#if 1 +int scanf(char *fmt,...) +#else +int scanf(fmt, va_alist) + char *fmt; + va_dcl +#endif +{ + va_list ptr; + int rv; + + va_strt(ptr, fmt); + rv = vfscanf(stdin, fmt, ptr); + va_end(ptr); + return rv; +} +#endif + \ No newline at end of file diff --git a/src/libc/scanf.h b/src/libc/scanf.h new file mode 100755 index 00000000..06f3ddaa --- /dev/null +++ b/src/libc/scanf.h @@ -0,0 +1,27 @@ +/* scanf.c + */ +#include +#include +#include + +#ifdef MAKE_ALL +#define L_scanf +#define L_sscanf +#define L_fscanf +#define L_vscanf +#define L_vsscanf +#define L_vfscanf +#ifndef HI_TECH_C +/* #define FLOATS Nick */ +#endif +#endif + +#if 1 +#include +#define va_strt va_start +#else +#include +#define va_strt(p,i) va_start(p) +#endif + + \ No newline at end of file diff --git a/src/libc/setbuff.c b/src/libc/setbuff.c new file mode 100755 index 00000000..6feab35d --- /dev/null +++ b/src/libc/setbuff.c @@ -0,0 +1,36 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_setbuff +void setbuffer(fp, buf, size) + FILE *fp; + char *buf; + size_t size; +{ + fflush(fp); + if (fp->mode & __MODE_FREEBUF) + free(fp->bufstart); + fp->mode &= ~(__MODE_FREEBUF | __MODE_BUF); + if (buf == NULL) { + fp->bufstart = (uchar *)fp->unbuf; + fp->bufend = (uchar *)fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + } + else { + fp->bufstart = (uchar *)buf; + fp->bufend = (uchar *)buf + size; +#if _IOFBF + fp->mode |= _IOFBF; +#endif + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; +} +#endif + diff --git a/src/libc/setenv.c b/src/libc/setenv.c new file mode 100755 index 00000000..5f50ad85 --- /dev/null +++ b/src/libc/setenv.c @@ -0,0 +1,88 @@ +/**************************** setenv.c ****************************/ +/* Copyright (C) 1992, 1995 Free Software Foundation, Inc. + This file is part of the GNU C Library. + */ + +#include "environ.h" + +#ifdef L_setenv +#include +#include + +int setenv(name, value, replace) + char *name; + char *value; + int replace; +{ + register char **ep; + register size_t size = 0; + size_t namelen = strlen(name); + size_t vallen = strlen(value); + char *p; + + ep = environ; + while ((p = *ep++) != NULL) { + if (!memcmp(p, name, namelen) && p[namelen] == '=') + break; + ++size; + } + if (p == NULL) { + static char **last_environ = NULL; + char **new_environ = (char **) malloc((size + 2) * sizeof(char *)); + if (new_environ == NULL) { +Err: errno = ENOMEM; + return -1; + } + memcpy(new_environ, environ, size * sizeof(char *)); + if ((p = malloc(namelen + 1 + vallen + 1)) == NULL) { + free(new_environ); + goto Err; + } + memcpy(p, name, namelen); + p[namelen] = '='; + memcpy(&p[namelen + 1], value, vallen + 1); + new_environ[size] = p; + new_environ[size + 1] = NULL; + if (last_environ != NULL) + free((void *) last_environ); + last_environ = new_environ; + environ = new_environ; + } + else if (replace) { + /* var exists and replaceing it contents is desired */ + size_t len = strlen(p); + + /* no room for new var and its contents. alloc space + for name and new content and copy them */ + if (len < namelen + 1 + vallen) { + char *new = malloc(namelen + 1 + vallen + 1); + + if (new == NULL) + goto Err; + memcpy(new, name, namelen); /* name */ + new[namelen] = '='; + *--ep = p = new; + /* next step: put new content */ + } + /* if len(old_value)>len(new_value), so we can just + copy the new value over the old one */ + memcpy(&p[namelen + 1], value, vallen + 1); + } + return 0; +} + +void unsetenv(name) + char *name; +{ + register char **ep, **dp, *p; + size_t namelen = strlen(name); + + dp = ep = environ; + while ((p = *ep++) != NULL) { + if (memcmp(p, name, namelen) || p[namelen] != '=') + *dp++ = p; + } + *dp = NULL; +} +#endif + \ No newline at end of file diff --git a/src/libc/setgrent.c b/src/libc/setgrent.c new file mode 100755 index 00000000..6feeedef --- /dev/null +++ b/src/libc/setgrent.c @@ -0,0 +1,33 @@ +/* setgrent.c groups implementation + */ + +#include "grp-l.h" + +#ifdef L_setgrent +/* + * setgrent(), endgrent(), and getgrent() are mutually-dependent functions, + * so they are all included in the same object file, and thus all linked + * in together. + */ +static int grp_fd = -1; +char *_path_group = _PATH_GROUP; + +void setgrent() { + if (grp_fd != -1) + close(grp_fd); + grp_fd = open(_path_group, O_RDONLY | O_BINARY); +} + +void endgrent() { + if (grp_fd != -1) + close(grp_fd); + grp_fd = -1; +} + +struct group *getgrent() { + if (grp_fd == -1) + return NULL; + return __getgrent(grp_fd); +} +#endif + \ No newline at end of file diff --git a/src/libc/setjmp.c$ b/src/libc/setjmp.c$ new file mode 100755 index 00000000..ea41a8c7 --- /dev/null +++ b/src/libc/setjmp.c$ @@ -0,0 +1,48 @@ +/* + * setjmp.c for UZIX + * by A&L Software, 08/07/99 + */ +#include + +static int _lngjmprv = 1; + +#ifdef __TURBOC__ + +int setjmp (env) + jmp_buf env; +{ + env[0].di = _DI; + env[0].si = _SI; + env[0].bp = _BP; + env[0].sp = _SP; + __emit__(0x58); /* pop ax */ + __emit__(0x50); /* push ax */ + env[0].pc = _AX; + return 0; +} + +#if 1 +int longjmp(env, rv) /* Nick */ +#else +void longjmp(env, rv) +#endif + jmp_buf env; + int rv; +{ + _SP = env[0].sp; + _DI = env[0].di; + _SI = env[0].si; + _BP = env[0].bp; + __emit__(0x58); /* pop ax */ /* discards return from longjmp */ + _AX = env[0].pc; + __emit__(0x50); /* push ax */ /* now return is as it was from setjmp */ + if (rv) + return rv; + return 1; +} +#endif + +#ifdef HI_TECH_C +#include "setjmp.msx" +#endif + \ No newline at end of file diff --git a/src/libc/setjmp.msx b/src/libc/setjmp.msx new file mode 100755 index 00000000..a842354b --- /dev/null +++ b/src/libc/setjmp.msx @@ -0,0 +1,126 @@ +/* + * setjmp.msx for UZIX + * by A&L Software, 08/07/99 + */ +#ifdef HI_TECH_C + +int setjmp (env) + jmp_buf env; /* int jmp_buf[7] */ +{ +#asm + ; DE = env + ; don't use stack here! + + defb 0FDh,07Dh ; LD A,IYl - saves IY + ld (de),a + inc de + defb 0FDh,07Ch ; LD A,IYh + ld (de),a + inc de + defb 0DDh,07Dh ; LD A,IXl - saves IX + ld (de),a + inc de + defb 0DDh,07Ch ; LD A,IXh + ld (de),a + inc de + ld a,c ; - saves BC + ld (de),a + inc de + ld a,b + ld (de),a + inc de + ld a,e ; - saves DE + ld (de),a + inc de + ld a,d + ld (de),a + inc de + ld a,l ; - saves HL + ld (de),a + inc de + ld a,h + ld (de),a + inc de + ld hl,0 + add hl,sp ; HL = SP + inc hl ; skip return address to after setjmp call + inc hl ; (it is saved below) + ld a,l ; - saves SP + ld (de),a + inc de + ld a,h + ld (de),a + inc de + pop hl ; HL = return address after setjmp call + push hl + ld a,l ; - saves PC + ld (de),a + inc de + ld a,h + ld (de),a + ld hl,0 + ret +#endasm +} + +void longjmp (env, rv) + jmp_buf env; + int rv; +{ +#asm + ; BC = rv, DE = env + ; don't use stack here! + global __lngjmprv + + ld (__lngjmprv),bc + ld hl,12 + add hl,de + ld b,(hl) + dec hl + ld c,(hl) ; BC = return address after setjmp call + dec hl + ld a,(hl) + dec hl + ld l,(hl) + ld h,a ; HL = saved SP in env + ld sp,hl ; - restores SP + push bc ; put return address in stack + ld a,(de) + defb 0FDh,06Fh ; LD IYl,A - restores IY + inc de + ld a,(de) + defb 0FDh,067h ; LD IYh,A + inc de + ld a,(de) + defb 0DDh,06Fh ; LD IXl,A - restores IX + inc de + ld a,(de) + defb 0DDh,067h ; LD IXh,A + inc de + ld a,(de) + ld c,a ; - restores BC + inc de + ld a,(de) + ld b,a + inc de + ld a,(de) + ;ld e,a ; - restores DE + inc de + ;ld a,(de) + ;ld d,a ; DE is the pointer, it can't be restored. + inc de ; anyway, it doesn't matter for lonjmp/setjmp + ;ld a,(de) + ;ld l,a ; - restores HL + inc de + ;ld a,(de) ; HL is the return value, it don't need to be + ;ld h,a ; restored, because it will be overwritten. + ld hl,(__lngjmprv) ; return value + ld a,h ; zero? + or l + ret nz ; return it if not + ld hl,1 + ret ; else return 1 +#endasm +} +#endif + diff --git a/src/libc/setjmp.r01 b/src/libc/setjmp.r01 new file mode 100755 index 0000000000000000000000000000000000000000..5c1117834e80bf39db1ca9263440ffc9e10b6191 GIT binary patch literal 513 zcmZQzWo8g&O6Q2r$6u&%1JF!2s6<$Fmu!oH#YKONKs*6 zXkcJq^kPVbu$a9V(jY8$Zw3Yi1r}$27grx9AQK4Kp=JV^P$3O2d*^r`e?NCG-vE#( zBS;wo1Dm~zlY6`okmbV)7GMyucXIUej(2km4vF`1bqsTj_c5>lN?C)Y%___`nkkqu znlYQbHj6V;HVXsd*JeL~_^6p5knIMVWL4W?#)1!0>P^#PV6u z_KRmRKmvw6zBsjn%HhHWF%oDQk=|7_V*xtQ66n2RpvQ`UxDbd7fcUQ2Q?rY3(Z49X Uk3boa=U{ru%@onSnOgK808K%4^8f$< literal 0 HcmV?d00001 diff --git a/src/libc/setjmpb.asm b/src/libc/setjmpb.asm new file mode 100755 index 00000000..c3d723cf --- /dev/null +++ b/src/libc/setjmpb.asm @@ -0,0 +1,64 @@ +; setjmpb.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module _setjmpb + + rseg CODE + + extern ?BANK_FAST_LEAVE_L08 + + public setjmp + +setjmp: + .if 1 + ld hl,4 + add hl,sp + ex de,hl + ld (hl),e + inc hl + ld (hl),d + inc hl + ld (hl),c + inc hl + ld (hl),b + inc hl + push ix + pop de + ld (hl),e + inc hl + ld (hl),d + inc hl + push iy + pop de + ld (hl),e + inc hl + ld (hl),d + inc hl + pop af + pop de + push de + push af + ld (hl),e + inc hl + ld (hl),d + inc hl + ld (hl),a + ld hl,0 + jp ?BANK_FAST_LEAVE_L08 + .else + defb 021h,004h,000h,039h,0EBh,073h,023h + defb 072h,023h,071h,023h,070h,023h,0DDh + defb 0E5h,0D1h,073h,023h,072h,023h,0FDh + defb 0E5h,0D1h,073h,023h,072h,023h,0F1h + defb 0D1h,0D5h,0F5h,073h,023h,072h,023h + defb 077h,021h,000h,000h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + .endif + + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libc/setjmpl.asm b/src/libc/setjmpl.asm new file mode 100755 index 00000000..fb394d92 --- /dev/null +++ b/src/libc/setjmpl.asm @@ -0,0 +1,21 @@ +; setjmpl.asm +; Nick's reverse engineered subset of the IAR large 'C' library + +; ----------------------------------------------------------------------------- + + module _setjmpl + rseg CODE +code_base: + public setjmp +setjmp equ code_base+00000000h + defb 021h,002h,000h,039h,0EBh,073h,023h + defb 072h,023h,071h,023h,070h,023h,0DDh + defb 0E5h,0D1h,073h,023h,072h,023h,0FDh + defb 0E5h,0D1h,073h,023h,072h,023h,0D1h + defb 0D5h,073h,023h,072h,021h,000h,000h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + END diff --git a/src/libc/setpwent.c b/src/libc/setpwent.c new file mode 100755 index 00000000..f569f230 --- /dev/null +++ b/src/libc/setpwent.c @@ -0,0 +1,35 @@ +/* setpwent.c + */ + +#include "passwd.h" + +#ifdef L_setpwent +/* + * setpwent(), endpwent(), and getpwent() are included in the same object + * file, since one cannot be used without the other two, so it makes sense to + * link them all in together. + */ +/* file descriptor for the password file currently open */ +static int pw_fd = -1; +char *_path_passwd = _PATH_PASSWD; + +void setpwent() { + if (pw_fd != -1) + close(pw_fd); + pw_fd = open(_path_passwd, O_RDONLY | O_BINARY); + if (pw_fd==-1) printf("ERRNO %d opening password\n",errno); +} + +void endpwent(void) { + if (pw_fd != -1) + close(pw_fd); + pw_fd = -1; +} + +struct passwd *getpwent(void) { + if (pw_fd != -1) + return __getpwent(pw_fd); + return NULL; +} +#endif + diff --git a/src/libc/setvbuff.c b/src/libc/setvbuff.c new file mode 100755 index 00000000..733bf469 --- /dev/null +++ b/src/libc/setvbuff.c @@ -0,0 +1,38 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_setvbuf +int setvbuf(fp, buf, mode, size) + FILE *fp; + char *buf; + int mode; + size_t size; +{ + fflush(fp); + if (fp->mode & __MODE_FREEBUF) + free(fp->bufstart); + fp->mode &= ~(__MODE_FREEBUF | __MODE_BUF); + fp->bufstart = (uchar *)fp->unbuf; + fp->bufend = (uchar *)fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + if (mode == _IOFBF || mode == _IOLBF) { + if (size == 0) + size = BUFSIZ; + if (buf == NULL && (buf = calloc(1,size)) == NULL) + return EOF; + fp->bufstart = (uchar *)buf; + fp->bufend = (uchar *)buf + size; + fp->mode |= mode; + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + return 0; +} +#endif + diff --git a/src/libc/sleep.c b/src/libc/sleep.c new file mode 100755 index 00000000..67ae83f2 --- /dev/null +++ b/src/libc/sleep.c @@ -0,0 +1,26 @@ +/* sleep.c + */ +#include +#include +#include + +/* This uses SIGALRM, it does keep the previous alarm call but will lose + * any alarms that go off during the sleep + */ +static void alrm() { } + +unsigned int sleep(seconds) + unsigned int seconds; +{ + unsigned int prev_sec = alarm(0); + sig_t last_alarm = signal(SIGALRM, (sig_t)alrm); /* Nick cast */ + + if (prev_sec) + prev_sec = (prev_sec <= seconds ? 1 : prev_sec - seconds); + alarm(seconds); + pause(); + seconds = alarm(prev_sec); + signal(SIGALRM, last_alarm); + return seconds; +} + diff --git a/src/libc/sprintf.c b/src/libc/sprintf.c new file mode 100755 index 00000000..a5a03045 --- /dev/null +++ b/src/libc/sprintf.c @@ -0,0 +1,43 @@ +/* printf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +#include "printf.h" + +#ifdef L_sprintf +#if 1 +int sprintf(char *sp, char *fmt,...) +#else +int sprintf(sp, fmt, va_alist) + char *sp; + char *fmt; + va_dcl +#endif +{ + static FILE string[1] = { + { 0, 0, (unsigned char *)-1, 0, (unsigned char *)-1, -1, + _IOFBF | __MODE_WRITE + } + }; + va_list ptr; + int rv; + + va_strt(ptr, fmt); + string->bufpos = (unsigned char *)sp; + rv = vfprintf(string, fmt, ptr); + va_end(ptr); + *(string->bufpos) = 0; + return rv; +} +#endif + diff --git a/src/libc/sscanf.c b/src/libc/sscanf.c new file mode 100755 index 00000000..19b228c6 --- /dev/null +++ b/src/libc/sscanf.c @@ -0,0 +1,31 @@ +/* scanf.c + */ + +#include "scanf.h" + +#ifdef L_sscanf +#if 1 +int sscanf(char *sp, char *fmt,...) +#else +int sscanf(sp, fmt, va_alist) + char *sp; + char *fmt; + va_dcl +#endif +{ + static FILE string[1] = { + { 0, (unsigned char *)-1, 0, 0, (unsigned char *)-1, -1, + _IOFBF | __MODE_READ + } + }; + va_list ptr; + int rv; + + va_strt(ptr, fmt); + string->bufpos = (unsigned char *)sp; + rv = vfscanf(string, fmt, ptr); + va_end(ptr); + return rv; +} +#endif + \ No newline at end of file diff --git a/src/libc/stdio-l.h b/src/libc/stdio-l.h new file mode 100755 index 00000000..a4f8e82d --- /dev/null +++ b/src/libc/stdio-l.h @@ -0,0 +1,50 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#ifdef MAKE_ALL +#define L_stdio +#define L_fputc +#define L_fgetc +#define L_putchar +#define L_getchar +#define L_fflush +#define L_fgets +#define L_gets +#define L_fputs +#define L_puts +#define L_fread +#define L_fwrite +#define L_rewind +#define L_fseek +#define L_ftell +#define L_fopen +#define L_fclose +#define L_setbuff +#define L_setvbuf +#define L_ungetc +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef STATIC +#define STATIC +#endif + +extern FILE *__IO_list; /* For fflush at exit */ +#ifndef Inline_init +#define Inline_init __stdio_init_vars() +STATIC void __stdio_init_vars __P((void)); +#endif + diff --git a/src/libc/stdio0.c b/src/libc/stdio0.c new file mode 100755 index 00000000..a7dd9dcd --- /dev/null +++ b/src/libc/stdio0.c @@ -0,0 +1,69 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_stdio + +#if 1 /* Nick */ +#define buferr (unsigned char *)(stderr[0].unbuf) /* Stderr is unbuffered */ +#else +#define buferr (unsigned char *)(stderr->unbuf) /* Stderr is unbuffered */ +#endif + +FILE *__IO_list = NULL; /* For fflush at exit */ + +static unsigned char bufin[BUFSIZ]; +static unsigned char bufout[BUFSIZ]; +#ifndef buferr +static unsigned char buferr[BUFSIZ]; +#endif + +FILE stdin[1] = { + {bufin, bufin, bufin, bufin, bufin + sizeof(bufin), + 0, _IOFBF | __MODE_READ | __MODE_IOTRAN} +}; + +FILE stdout[1] = { + {bufout, bufout, bufout, bufout, bufout + sizeof(bufout), + 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +FILE stderr[1] = { + {buferr, buferr, buferr, buferr, buferr + sizeof(buferr), + 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +/* Call the stdio initialiser; it's main job it to call atexit */ +STATIC void __stdio_close_all(VOID) { + FILE *fp = __IO_list; + + fflush(stdout); + fflush(stderr); + while (fp) { + fflush(fp); + close(fp->fd); + /* Note we're not de-allocating the memory */ + /* There doesn't seem to be much point :-) */ + fp->fd = -1; + fp = fp->next; + } +} + +STATIC void __stdio_init_vars() { + static int first_time = 1; + + if (!first_time) + return; + first_time = 0; + if (isatty(1)) + stdout->mode |= _IOLBF; + atexit((atexit_t)__stdio_close_all); +} +#endif + diff --git a/src/libc/strcat.c b/src/libc/strcat.c new file mode 100755 index 00000000..505f0193 --- /dev/null +++ b/src/libc/strcat.c @@ -0,0 +1,19 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strcat ************************************/ +#ifdef L_strcat +char *strcat(d, s) + char *d; + char *s; +{ + strcpy(d + strlen(d), s); + return d; +} +#endif + \ No newline at end of file diff --git a/src/libc/strchr.c b/src/libc/strchr.c new file mode 100755 index 00000000..f57323c5 --- /dev/null +++ b/src/libc/strchr.c @@ -0,0 +1,26 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strchr ************************************/ +#ifdef L_strchr +char *strchr(s, c) + char *s; + int c; +{ + register char ch; + + for (;;) { + if ((ch = *s) == c) + return s; + if (ch == 0) + return 0; + s++; + } +} +#endif + \ No newline at end of file diff --git a/src/libc/strcmp.c b/src/libc/strcmp.c new file mode 100755 index 00000000..c2d0d857 --- /dev/null +++ b/src/libc/strcmp.c @@ -0,0 +1,22 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strcmp ************************************/ +#ifdef L_strcmp +int strcmp(d, s) + char *d; + char *s; +{ + register char *s1 = (char *)d, *s2 = (char *)s, c1, c2; + + while ((c1 = *s1++) == (c2 = *s2++) && c1) + ; + return c1 - c2; +} +#endif + \ No newline at end of file diff --git a/src/libc/strcpy.c b/src/libc/strcpy.c new file mode 100755 index 00000000..a91a79ac --- /dev/null +++ b/src/libc/strcpy.c @@ -0,0 +1,18 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strcpy ************************************/ +#ifdef L_strcpy +char *strcpy(d, s) + char *d; + char *s; +{ + return memcpy(d, s, strlen(s) + 1); +} +#endif + \ No newline at end of file diff --git a/src/libc/strcspn.c b/src/libc/strcspn.c new file mode 100755 index 00000000..d348616c --- /dev/null +++ b/src/libc/strcspn.c @@ -0,0 +1,29 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strcspn ************************************/ +#ifdef L_strcspn +/* + * Return the length of the sub-string of that consists + * entirely of characters not found in . The terminating '\0' + * in is not considered part of the match set. If the first + * character in is in , 0 is returned. + */ +/* This uses strchr, strchr should be in assembler */ +size_t strcspn(string, set) + register char *string; + char *set; +{ + char *start = string; + + while (*string && strchr(set, *string++) == 0) + ; + return (size_t)(string - start); +} +#endif + \ No newline at end of file diff --git a/src/libc/strdup.c b/src/libc/strdup.c new file mode 100755 index 00000000..fea6918d --- /dev/null +++ b/src/libc/strdup.c @@ -0,0 +1,23 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strdup ************************************/ +#ifdef L_strdup +#include +char *strdup(s) + char *s; +{ + register size_t len = strlen(s) + 1; + register char *p = (char *) malloc(len); + + if (p) + memcpy(p, s, len); /* Faster than strcpy */ + return p; +} +#endif + \ No newline at end of file diff --git a/src/libc/stricmp.c b/src/libc/stricmp.c new file mode 100755 index 00000000..6c02e8a2 --- /dev/null +++ b/src/libc/stricmp.c @@ -0,0 +1,29 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function stricmp ************************************/ +#ifdef L_stricmp +#include +int stricmp(s, d) + char *s; + char *d; +{ + for (;;) { + unsigned char sc = *(uchar *)s++, dc = *(uchar *)d++; + + if (sc != dc) { + if (_tolower(sc) != _tolower(dc)) + return (int)(char)(sc - dc); + } + else if (sc == '\0') + break; + } + return 0; +} +#endif + \ No newline at end of file diff --git a/src/libc/string-l.h b/src/libc/string-l.h new file mode 100755 index 00000000..d1c2a79e --- /dev/null +++ b/src/libc/string-l.h @@ -0,0 +1,34 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include + +#ifdef MAKE_ALL +#define L_strlen +#define L_strcat +#define L_strcpy +#define L_strcmp +#define L_strncat +#define L_strncpy +#define L_strncmp +#define L_strchr +#define L_strrchr +#define L_strdup +#define L_strcspn +#define L_stricmp +#define L_strnicmp +#define L_strpbrk +#define L_strsep +#define L_strspn +#define L_strstr +#define L_strtok +#endif + +/* This is a basic string package; it includes the most used functions: + * + * strlen strcat strcpy strcmp strncat strncpy strncmp strchr strrchr strdup + * strcspn stricmp strnicmp strpbrk strspn strstr strtok + */ + \ No newline at end of file diff --git a/src/libc/strlen.c b/src/libc/strlen.c new file mode 100755 index 00000000..2fb26449 --- /dev/null +++ b/src/libc/strlen.c @@ -0,0 +1,33 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strlen ************************************/ +#ifdef L_strlen +size_t strlen(str) + register char *str; +{ +#ifndef HI_TECH_C + register char *p = str; + + while (*p != 0) + ++p; + return (size_t)(p-str); +#else +_asm + ld h,d + ld l,e + ld bc,0ffffh + xor a + cpir + sbc hl,de + dec hl +_endasm +#endif +} +#endif + \ No newline at end of file diff --git a/src/libc/strncat.c b/src/libc/strncat.c new file mode 100755 index 00000000..c35dbfd7 --- /dev/null +++ b/src/libc/strncat.c @@ -0,0 +1,26 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strncat ************************************/ +#ifdef L_strncat +char *strncat(d, s, l) + char *d, *s; + size_t l; +{ + register char *s1 = d + strlen(d), *s2 = memchr(s, 0, l); + + if (s2) + memcpy(s1, s, s2 - s + 1); + else { + memcpy(s1, s, l); + s1[l] = '\0'; + } + return d; +} +#endif + \ No newline at end of file diff --git a/src/libc/strncmp.c b/src/libc/strncmp.c new file mode 100755 index 00000000..0e7e5257 --- /dev/null +++ b/src/libc/strncmp.c @@ -0,0 +1,24 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strncmp ************************************/ +#ifdef L_strncmp +int strncmp(d, s, l) + char *d, *s; + size_t l; +{ + register char c1 = 0, c2 = 0; + + while (l-- != 0) { + if ((c1 = *d++) != (c2 = *s++) || c1 == '\0') + break; + } + return c1 - c2; +} +#endif + \ No newline at end of file diff --git a/src/libc/strncpy.c b/src/libc/strncpy.c new file mode 100755 index 00000000..a478f3d9 --- /dev/null +++ b/src/libc/strncpy.c @@ -0,0 +1,28 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strncpy ************************************/ +#ifdef L_strncpy +char *strncpy(d, s, l) + char *d, *s; + size_t l; +{ + register char *s1 = d, *s2 = s; + + while (l) { + l--; + if ((*s1++ = *s2++) == '\0') + break; + } + /* This _is_ correct strncpy is supposed to zap */ + while (l-- != 0) + *s1++ = '\0'; + return d; +} +#endif + \ No newline at end of file diff --git a/src/libc/strnicmp.c b/src/libc/strnicmp.c new file mode 100755 index 00000000..332f6b2d --- /dev/null +++ b/src/libc/strnicmp.c @@ -0,0 +1,31 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strnicmp ************************************/ +#ifdef L_strnicmp +#include + +int strnicmp(s, d, l) + char *s; + char *d; + size_t l; +{ + while (l-- != 0) { + unsigned char sc = *(uchar *)s++, dc = *(uchar *)d++; + + if (sc != dc) { + if (_tolower(sc) != _tolower(dc)) + return (int)(char)(sc - dc); + } + else if (sc == '\0') + break; + } + return 0; +} +#endif + \ No newline at end of file diff --git a/src/libc/strpbrk.c b/src/libc/strpbrk.c new file mode 100755 index 00000000..cbc17642 --- /dev/null +++ b/src/libc/strpbrk.c @@ -0,0 +1,24 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strpbrk ************************************/ +#ifdef L_strpbrk +/* This uses strchr, strchr should be in assembler */ +char *strpbrk(str, set) + register char *str; + register char *set; +{ + while (*str != '\0') { + if (strchr(set, *str)) + return str; + ++str; + } + return 0; +} +#endif + \ No newline at end of file diff --git a/src/libc/strrchr.c b/src/libc/strrchr.c new file mode 100755 index 00000000..3ed24bd5 --- /dev/null +++ b/src/libc/strrchr.c @@ -0,0 +1,27 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strrchr ************************************/ +#ifdef L_strrchr +char *strrchr(s, c) + char *s; + int c; +{ + register char *p = s + strlen(s); + + /* For null it's just like strlen */ + if (c == '\0') + return p; + while (p != s) { + if (*--p == c) + return p; + } + return NULL; +} +#endif + \ No newline at end of file diff --git a/src/libc/strsep.c b/src/libc/strsep.c new file mode 100755 index 00000000..5389c5ab --- /dev/null +++ b/src/libc/strsep.c @@ -0,0 +1,27 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strsep ************************************/ +#ifdef L_strsep +char *strsep(pp, delim) + char **pp; + char *delim; +{ + char *p, *q; + + if (0 == (p = *pp)) + return 0; + if ((q = strpbrk(p, delim)) != 0) { + *pp = q + 1; + *q = '\0'; + } + else *pp = 0; + return p; +} +#endif + \ No newline at end of file diff --git a/src/libc/strspn.c b/src/libc/strspn.c new file mode 100755 index 00000000..842fdd04 --- /dev/null +++ b/src/libc/strspn.c @@ -0,0 +1,33 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strspn ************************************/ +#ifdef L_strspn +/* Return the length of the maximum initial segment + of S which contains only characters in ACCEPT. + */ +size_t strspn(s, accept) + char *s; + char *accept; +{ + register char *p = s, *a; + register size_t count = 0; + + while (*p != '\0') { + a = accept; + while (*a != '\0' && *p != *a) + ++a; + if (*a == '\0') + break; + ++p; + ++count; + } + return count; +} +#endif + \ No newline at end of file diff --git a/src/libc/strstr.c b/src/libc/strstr.c new file mode 100755 index 00000000..28e1532c --- /dev/null +++ b/src/libc/strstr.c @@ -0,0 +1,57 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strstr ************************************/ +#ifdef L_strstr +#if 1 +/* We've now got a nice fast strchr and memcmp use them */ +char *strstr(s1, s2) + char *s1; + char *s2; +{ + register int l = strlen(s2); + register char *p = s1; + + if (l == 0) + return p; + while ((p = strchr(p, *s2)) != 0) { + if (memcmp(p, s2, l) == 0) + return p; + ++p; + } + return NULL; +} +#else +/* This is a nice simple self contained strstr, + now go and work out why the GNU one is faster :-) + */ +char *strstr(str1, str2) + char *str1, *str2; +{ + register char *Sptr, *Tptr; + int len = strlen(str1) - strlen(str2) + 1; + + if (*str2) { + while (len > 0) { + if (*str1 != *str2) + continue; + for (Sptr = str1, Tptr = str2; *Tptr != '\0'; Sptr++, Tptr++) { + if (*Sptr != *Tptr) + break; + } + if (*Tptr == '\0') + return str1; + --len; + ++str1; + } + } + return NULL; +} +#endif +#endif + \ No newline at end of file diff --git a/src/libc/strtod.c b/src/libc/strtod.c new file mode 100755 index 00000000..15d3d7e5 --- /dev/null +++ b/src/libc/strtod.c @@ -0,0 +1,96 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +#ifdef FLOAT +/**************************** strtod.c ****************************/ +#ifdef L_strtod +#include + +double strtod(nptr, endptr) + register char *nptr, **endptr; +{ + double number, mult; + int digits, negative, exp, exp_negative, exponent; + + /* advance beyond any leading whitespace */ + while (isspace(*nptr)) + nptr++; + /* check for optional '+' or '-' */ + negative = 0; + if (*nptr == '-') { + ++negative; + ++nptr; + } + else if (*nptr == '+') + ++nptr; + while (*nptr == '0') + nptr++; + exponent = digits = 0; + number = 0; + while (isdigit(*nptr)) { + if (digits > 33) + ++exponent; + else { + number *= 10; + number += (*nptr - '0'); + } + ++nptr; + ++digits; + } + if (*nptr == '.') { + ++nptr; + if (digits == 0) { + while (*nptr == '0') { + --exponent; + ++nptr; + } + } + while (isdigit(*nptr)) { + if (digits > 33) + ; + else { + number *= 10; + number += (*nptr - '0'); + --exponent; + } + ++nptr; + ++digits; + } + } + if (*nptr == 'e' || *nptr == 'E') { + nptr++; + exp_negative = 0; + if (*nptr == '-') { + ++exp_negative; + ++nptr; + } + else if (*nptr == '+') + ++nptr; + exp = 0; + while (isdigit(*nptr)) { + exp *= 10; + exp += (*nptr++ - '0'); + } + if (number != 0) { + if (exp_negative) + exp = -exp; + mult = 10; + if ((exp += exponent) < 0) { + exp = -exp; + mult = 0.1; + } + while (exp-- != 0) + number *= mult; + } + } + if (negative) + number = -number; + if (endptr != NULL) + *endptr = nptr; + return number; +} +#endif +#endif + diff --git a/src/libc/strtok.c b/src/libc/strtok.c new file mode 100755 index 00000000..df2362d9 --- /dev/null +++ b/src/libc/strtok.c @@ -0,0 +1,54 @@ +/* string.c + * Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include "string-l.h" + +/********************** Function strtok ************************************/ +#ifdef L_strtok +static char *olds = 0; + +/* Parse S into tokens separated by characters in DELIM. + If S is NULL, the last string strtok() was called with is + used. For example: + char s[] = "-abc=-def"; + + x = strtok(s, "-"); // x = "abc" + x = strtok(NULL, "=-"); // x = "def" + x = strtok(NULL, "="); // x = NULL + // s = "abc\0-def\0" +*/ +char *strtok(s, delim) + register char *s; + register char *delim; +{ + char *token; + + if (s == 0) { + if (olds == 0) + return 0; + s = olds; + } + /* Scan leading delimiters. */ + s += strspn(s, delim); + if (*s == '\0') { + olds = 0; + return 0; + } + /* Find the end of the token. */ + token = s; + s = strpbrk(token, delim); + if (s == 0) + /* This token finishes the string. */ + olds = 0; + else { + /* Terminate the token and make OLDS point past it. */ + *s = '\0'; + olds = s + 1; + } + return token; +} +#endif + \ No newline at end of file diff --git a/src/libc/strtol.c b/src/libc/strtol.c new file mode 100755 index 00000000..42b0f915 --- /dev/null +++ b/src/libc/strtol.c @@ -0,0 +1,30 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/**************************** strtol.c ****************************/ +#ifdef L_strtol +#include + +long strtol(nptr, endptr, base) + char *nptr, **endptr; + int base; +{ + long number; + int negative = 0; + char *ptr = nptr; + + while (isspace(*ptr)) + ptr++; + if (*ptr == '-') { + ++negative; + ++ptr; + } + else if (*ptr == '+') + ++ptr; + number = (long)strtoul(ptr, endptr, base); + return (negative ? -number : number); +} +#endif + diff --git a/src/libc/strtoul.c b/src/libc/strtoul.c new file mode 100755 index 00000000..0c8b8478 --- /dev/null +++ b/src/libc/strtoul.c @@ -0,0 +1,74 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/**************************** strtoul.c ****************************/ +#ifdef L_strtoul +#include + +static int digit __P((unsigned char , int)); + +static int digit(unsigned char c, int base) { + int val = -1; + + if (isdigit(c)) val = c - '0'; + if (islower(c)) val = c - 'a' + 10; + if (isupper(c)) val = c - 'Z' + 10; + if (val >= base) val = -1; + return val; +} + +unsigned long strtoul(nptr, endptr, base) + char *nptr, **endptr; + int base; +{ + unsigned long number; + int dig; + + /* Sanity check the arguments */ + if (base < 2 || base > 36) + base = 0; + /* advance beyond any leading whitespace */ + while (isspace(*nptr)) + nptr++; + /* check for optional '+' ??? */ + if (*nptr == '+') + nptr++; + /* If base==0 and the string begins with + * "0x" then we're supposed to assume that it's hexadecimal + * "0b" then we're supposed to assume that it's binary + * "0" then we're supposed to assume that it's octal + */ + else if (base == 0 && *nptr == '0') { + if (__toupper(*(nptr + 1)) == 'X') { + base = 16; + nptr += 2; + } + else if (__toupper(*(nptr + 1)) == 'B') { + base = 2; + nptr += 2; + } + else { + base = 8; + nptr++; + } + } + /* If base is still 0 (it was 0 to begin with and the string didn't + * begin with "0"), then we are supposed to assume that it's base 10 + */ + if (base == 0) + base = 10; + number = 0; + while ((dig = digit(*nptr,base)) != -1) { + number *= base; + number += dig; + ++nptr; + } + if (endptr != NULL) + *endptr = nptr; + /* All done */ + return number; +} +#endif + diff --git a/src/libc/system.c b/src/libc/system.c new file mode 100755 index 00000000..fcbeab9a --- /dev/null +++ b/src/libc/system.c @@ -0,0 +1,42 @@ +/* system.c + */ +#include +#include +#include +#include +#include + +int system(command) + char *command; +{ + sig_t save_quit, save_int; + int wait_ret, pid, wait_val = -1; + static char *argv[4] = { "sh", "-c", 0, 0 }; + + if (command == NULL) + return 1; + save_quit = (sig_t)signal(SIGQUIT, SIG_IGN); + save_int = (sig_t)signal(SIGINT, SIG_IGN); + if ((pid = fork()) < 0) + goto Ret; /* return -1 */ + if (pid == 0) { /* child */ + signal(SIGQUIT, SIG_DFL); + signal(SIGINT, SIG_DFL); + argv[2] = command; + execve(_PATH_BSHELL, argv, environ); + abort(); + } + /* Signals are not absolutly guaranteed with vfork */ + signal(SIGQUIT, SIG_IGN); + signal(SIGINT, SIG_IGN); + do { + if ((wait_ret = wait(&wait_val)) == -1) { + wait_val = -1; + break; + } + } while (wait_ret != pid); +Ret: signal(SIGQUIT, save_quit); + signal(SIGINT, save_int); + return wait_val; +} + \ No newline at end of file diff --git a/src/libc/termcap.c b/src/libc/termcap.c new file mode 100755 index 00000000..bc437e90 --- /dev/null +++ b/src/libc/termcap.c @@ -0,0 +1,651 @@ +/* termcap.c + * Work-alike for termcap, plus extra features. + * Copyright (C) 1985, 1986, 1993 Free Software Foundation, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define bcopy(s, d, n) memcpy ((d), (s), (n)) + +/* TCBUFSIZ is the initial size allocated for the buffer + for reading the termcap file. The original name, BUFSIZ, + was changed to avoid conflict with stdio BUFSIZ (types.h). + It is not a limit. + Make it large normally for speed. + Make it variable when debugging, so can exercise + increasing the space dynamically. + */ + +#ifndef TCBUFSIZ +#ifdef DEBUG +#define TCBUFSIZ bufsize + +int bufsize = 128; +#else +#ifdef MSX +#define TCBUFSIZ 128 +#else +#define TCBUFSIZ 2048 +#endif +#endif +#endif + +#ifdef TIOCGWINSZ +#define ADJUST_WIN_EXTENT +#endif + +static void memory_out __P((void)); +static char *xmalloc __P((unsigned size)); +static char *xrealloc __P((char *ptr, unsigned size)); +static char *find_capability __P((char *bp, char *cap)); +static char *tgetst1 __P((char *ptr, char **area)); +static int scan_file __P((char *str, int fd, struct buffer *bufp)); +static int name_match __P((char *line, char *name)); +static int compare_contin __P((char *str1, char *str2)); +static char *gobble_line __P((int fd, struct buffer *bufp, char *append_end)); + + +static void memory_out() { + write(2, "virtual memory exhausted\n", 25); + exit(1); +} + +static char *xmalloc(size) + unsigned size; +{ + register char *tem = malloc(size); + + if (!tem) + memory_out(); + return tem; +} + +static char *xrealloc(ptr, size) + char *ptr; + unsigned size; +{ + register char *tem = realloc(ptr, size); + + if (!tem) + memory_out(); + return tem; +} + +/* Looking up capabilities in the entry already found. */ + +/* The pointer to the data made by tgetent is left here + for tgetnum, tgetflag and tgetstr to find. */ +static char *term_entry; + +/* Search entry BP for capability CAP. + * Return a pointer to the capability (in BP) if found, + * 0 if not found. + */ +static char *find_capability(bp, cap) + register char *bp, *cap; +{ + while (*bp) { + if (bp[0] == ':' + && bp[1] == cap[0] + && bp[2] == cap[1]) + return &bp[4]; + ++bp; + } + return NULL; +} + +int tgetnum(cap) + char *cap; +{ + register char *ptr = find_capability(term_entry, cap); + + if (!ptr || ptr[-1] != '#') + return -1; + return atoi(ptr); +} + +int tgetflag(cap) + char *cap; +{ + register char *ptr = find_capability(term_entry, cap); + + return ptr && ptr[-1] == ':'; +} + +/* Look up a string-valued capability CAP. + If AREA is non-null, it points to a pointer to a block in which + to store the string. That pointer is advanced over the space used. + If AREA is null, space is allocated with `malloc'. + */ +char *tgetstr(cap, area) + char *cap; + char **area; +{ + register char *ptr = find_capability(term_entry, cap); + + if (!ptr || (ptr[-1] != '=' && ptr[-1] != '~')) + return NULL; + return tgetst1(ptr, area); +} + +/* Table, indexed by a character in range 0100 to 0140 with 0100 subtracted, + gives meaning of character following \, or a space if no special meaning. + */ +static char esctab[] = +/* @ a b c d e f g h i j k l m n o p q r s t u v w x y z */ + "\ \a\b\ \ \033\f\ \ \ \ \ \ \ \n\ \ \ \r\ \ \ \v\ \ \ \ "; + +/* PTR points to a string value inside a termcap entry. + Copy that value, processing \ and ^ abbreviations, + into the block that *AREA points to, + or to newly allocated storage if AREA is NULL. + Return the address to which we copied the value, + or NULL if PTR is NULL + */ +static char *tgetst1(ptr, area) + char *ptr; + char **area; +{ + register char *p, *r; + register int c, size, c1; + char *ret; + + if (!ptr) + return NULL; + /* `ret' gets address of where to store the string. */ + if (!area) { + /* Compute size of block needed (may overestimate). */ + p = ptr; + while ((c = *p++) != 0 && c != ':' && c != '\n') + ; + ret = (char *) xmalloc(p - ptr + 1); + } + else ret = *area; + /* Copy the string value, stopping at null or colon. + * Also process ^ and \ abbreviations. + */ + p = ptr; + r = ret; + while ((c = *p++) != 0 && c != ':' && c != '\n') { + if (c == '^') /* control char ^X */ + c = *p++ & 037; + else if (c == '\\') { /* escaped char \X */ + c = *p++; + if (c >= '0' && c <= '7') { + c -= '0'; + size = 0; + + while (++size < 3 && + (c1 = *p) >= '0' && + c1 <= '7') { + c <<= 3; + c += c1 - '0'; + p++; + } + } + else if (c >= 0100 && c < 0200) { + c1 = esctab[(c & ~040) - 0100]; + if (c1 != ' ') + c = c1; + } + } + *r++ = c; + } + *r = '\0'; + if (area) + *area = r + 1; + return ret; +} + +/* Outputting a string with padding. */ + +int ospeed; +/* If OSPEED is 0, we use this as the actual baud rate. */ +int tputs_baud_rate; +char PC; +/* Actual baud rate if positive; + - baud rate / 100 if negative. + */ + +static short speeds[] = { + 0, 50, 75, 110, 135, 150, -2, -3, -6, -12, + -18, -24, -48, -96, -192, -384 +}; + +void tputs(str, nlines, outfun) + char *str; + int nlines; + int (*outfun) (int); +{ + register int padcount = 0; + + if (!str) + return; + while (*str >= '0' && *str <= '9') { + padcount += *str++ - '0'; + padcount *= 10; + } + if (*str == '.') { + str++; + padcount += *str++ - '0'; + } + if (*str == '*') { + str++; + padcount *= nlines; + } + while (*str) + (*outfun) (*str++); + /* padcount is now in units of tenths of msec. */ + padcount *= speeds[ospeed]; + padcount += 500; + padcount /= 1000; + if (speeds[ospeed] < 0) + padcount = -padcount; + else { + padcount += 50; + padcount /= 100; + } + while (padcount-- > 0) + (*outfun) (PC); +} + +/* Finding the termcap entry in the termcap data base. */ +struct buffer { + char *beg; + int size; + char *ptr; + int ateof; + int full; +}; + +/* Forward declarations of static functions. */ + +#ifdef ADJUST_WIN_EXTENT +#ifdef TIOCGWINSZ +static int get_win_extent(li, co) + int *li, *co; +{ + struct winsize ws; + + /* Some TIOCGWINSZ may be broken. + * Make sure ws.ws_row and ws.ws_col are not zero. + */ + if (ioctl(0, TIOCGWINSZ, &ws) != 0 || !ws.ws_row || !ws.ws_col) + return -1; + *li = ws.ws_row; + *co = ws.ws_col; + return 0; +} +#endif /* TIOCGWINSZ */ + +static int adjust_win_extent(bpp, howalloc, li, co) + char **bpp; + int howalloc; /* 0 must do in place, + * 1 must use malloc, + * 2 must use realloc */ + int li, co; +{ + int licolen, o_len, t, colon; + char *licobuf, *s; + + if (li < 0 || co < 0) + return 0; + s = *bpp; + colon = -1; + while (*s) { + if (*s == ':' && colon < 0) + colon = s - *bpp; + ++s; + } + o_len = s - *bpp; + licolen = 11; + t = li; + while ((t /= 10) > 0) + ++licolen; + t = co; + while ((t /= 10) > 0) + ++licolen; + licobuf = xmalloc(licolen + 1); + sprintf(licobuf, ":li#%d:co#%d:", li, co); + if (howalloc == 0) { + bcopy(*bpp + colon, *bpp + colon + licolen, o_len - colon + 1); + bcopy(licobuf, *bpp + colon, licolen); + } + else if (howalloc == 1) { + char *newbp = xmalloc(o_len + licolen + 1); + + bcopy(*bpp, newbp, colon); + bcopy(licobuf, newbp + colon, licolen); + strcpy(newbp + colon + licolen, *bpp + colon); + *bpp = newbp; + } + else { /* (howalloc == 2) */ + char *newbp = xrealloc(*bpp, o_len + licolen + 1); + + bcopy(newbp + colon, newbp + colon + licolen, o_len - colon + 1); + bcopy(licobuf, newbp + colon, licolen); + *bpp = newbp; + } + free(licobuf); + return 1; +} +#endif /* ADJUST_WIN_EXTENT */ + +#define valid_filename_p(fn) (*(fn) == '/') + +/* Find the termcap entry data for terminal type NAME + and store it in the block that BP points to. + Record its address for future use. + + If BP is null, space is dynamically allocated. + + Return -1 if there is some difficulty accessing the data base + of terminal types, + 0 if the data base is accessible but the type NAME is not defined + in it, and some other value otherwise. + */ +int tgetent(bp, name) + char *bp, *name; +{ + register char *termcap_name; + register int fd; + struct buffer buf; + register char *bp1; + char *bp2, *term; + register int c; + char *tcenv; /* TERMCAP value, if it contains :tc=. */ + char *indirect = NULL; /* Terminal type in :tc= in TERMCAP value. */ + char *termvar = getenv("TERM"); + int malloc_size = 0; + int filep; +#ifdef ADJUST_WIN_EXTENT + int li, co; /* #lines and columns on this tty */ + + if (get_win_extent(&li, &co) != 0) + li = co = -1; +#endif /* ADJUST_WIN_EXTENT */ + if (termvar == NULL) + return -1; /* missing env variable TERM */ + termcap_name = getenv("TERMCAP"); + if (termcap_name && *termcap_name == '\0') + termcap_name = NULL; + filep = termcap_name && valid_filename_p(termcap_name); + /* If termcap_name is non-null and starts with / (in the un*x case, + * that is), it is a file name to use instead of /etc/termcap. If it + * is non-null and does not start with /, it is the entry itself, + * but only if the name the caller requested matches the TERM + * variable. + */ + if (termcap_name && !filep && !strcmp(name, termvar)) { + indirect = tgetst1(find_capability(termcap_name, "tc"), (char **) 0); + if (!indirect) { + if (!bp) { + bp = termcap_name; +#ifdef ADJUST_WIN_EXTENT + if (adjust_win_extent(&bp, 1, li, co)) + malloc_size = 1; /* force return of bp */ +#endif /* ADJUST_WIN_EXTENT */ + } + else { + strcpy(bp, termcap_name); +#ifdef ADJUST_WIN_EXTENT + adjust_win_extent(&bp, 0, li, co); +#endif /* ADJUST_WIN_EXTENT */ + } + goto ret; + } + else { /* It has tc=. Need to read /etc/termcap. */ + tcenv = termcap_name; + termcap_name = NULL; + } + } + if (!termcap_name || !filep) + termcap_name = _PATH_TERMCAP; + /* Here we know we must search a file and termcap_name has its name. */ + if ((fd = open(termcap_name, 0)) < 0) + return -1; + buf.size = TCBUFSIZ; + /* Add 1 to size to ensure room for terminating null. */ + buf.beg = (char *) xmalloc(buf.size + 1); + term = indirect ? indirect : name; + if (!bp) { + malloc_size = indirect ? strlen(tcenv) + 1 : buf.size; + bp = (char *) xmalloc(malloc_size); + } + bp1 = bp; + if (indirect) { /* Copy the data from the environment variable. */ + strcpy(bp, tcenv); + bp1 += strlen(tcenv); + } + while (term) { + /* Scan the file, reading it via buf, + * till find start of main entry. + */ + if (scan_file(term, fd, &buf) == 0) { + close(fd); + free(buf.beg); + if (malloc_size) + free(bp); + return 0; + } + /* Free old `term' if appropriate. */ + if (term != name) + free(term); + /* If BP is malloc'd by us, make sure it is big enough. */ + if (malloc_size) { + malloc_size = bp1 - bp + buf.size; + termcap_name = (char *) xrealloc(bp, malloc_size); + bp1 += termcap_name - bp; + bp = termcap_name; + } + bp2 = bp1; + /* Copy the line of the entry from buf into bp. */ + termcap_name = buf.ptr; + while ((*bp1++ = c = *termcap_name++) != 0 && c != '\n') { + /* Drop out any \ newline sequence. */ + if (c == '\\' && *termcap_name == '\n') { + bp1--; + termcap_name++; + } + } + *bp1 = '\0'; + /* Does this entry refer to another terminal type's entry? + * If something is found, copy it into heap and + * null-terminate it. + */ + term = tgetst1(find_capability(bp2, "tc"), (char **) 0); + } + close(fd); + free(buf.beg); + if (malloc_size) + bp = (char *) xrealloc(bp, bp1 - bp + 1); +#ifdef ADJUST_WIN_EXTENT + adjust_win_extent(&bp, malloc_size ? 2 : 0, li, co); +#endif /* ADJUST_WIN_EXTENT */ + +ret: term_entry = bp; + if (malloc_size) + return (int) bp; + return 1; +} + +/* Given file open on FD and buffer BUFP, + scan the file from the beginning until a line is found + that starts the entry for terminal type STR. + Return 1 if successful, with that line in BUFP, + or 0 if no entry is found in the file. + */ +static int scan_file(str, fd, bufp) + char *str; + int fd; + register struct buffer *bufp; +{ + register char *end; + + bufp->ptr = bufp->beg; + bufp->full = 0; + bufp->ateof = 0; + *bufp->ptr = '\0'; + lseek(fd, 0L, SEEK_SET); + while (!bufp->ateof) { + /* Read a line into the buffer. */ + end = NULL; + do { + /* if it is continued, append another line to it, until a + * non-continued line ends. */ + end = gobble_line(fd, bufp, end); + } while (!bufp->ateof && end[-2] == '\\'); + if (*bufp->ptr != '#' && name_match(bufp->ptr, str)) + return 1; + /* Discard the line just processed. */ + bufp->ptr = end; + } + return 0; +} + +/* Return nonzero if NAME is one of the names specified + by termcap entry LINE. + */ +static int name_match(line, name) + char *line, *name; +{ + register char *tem; + + if (!compare_contin(line, name)) + return 1; + /* This line starts an entry. Is it the right one? */ + tem = line; + while (*tem && *tem != '\n' && *tem != ':') { + if (*tem++ == '|' && !compare_contin(tem, name)) + return 1; + } + return 0; +} + +static int compare_contin(str1, str2) + register char *str1, *str2; +{ + register int c1, c2; + + while (1) { + c1 = *str1++; + c2 = *str2++; + while (c1 == '\\' && *str1 == '\n') { + str1++; + while ((c1 = *str1++) == ' ' || c1 == '\t') + ; + } + if (c2 == '\0') { + /* End of type being looked up. */ + if (c1 == '|' || c1 == ':') + /* If end of name in data base, we win. */ + return 0; + break; + } + else if (c1 != c2) + break; + } + return 1; +} + +/* Make sure that the buffer <- BUFP contains a full line + of the file open on FD, starting at the place BUFP->ptr + points to. Can read more of the file, discard stuff before + BUFP->ptr, or make the buffer bigger. + + Return the pointer to after the newline ending the line, + or to the end of the file, if there is no newline to end it. + + Can also merge on continuation lines. If APPEND_END is + non-null, it points past the newline of a line that is + continued; we add another line onto it and regard the whole + thing as one line. The caller decides when a line is continued. + */ +static char *gobble_line(fd, bufp, append_end) + int fd; + register struct buffer *bufp; + char *append_end; +{ + register int nread; + register char *end, *tem, *buf = bufp->beg; + + if (!append_end) + append_end = bufp->ptr; + while (1) { + end = append_end; + while (*end && *end != '\n') + end++; + if (*end) + break; + if (bufp->ateof) + return buf + bufp->full; + if (bufp->ptr == buf) { + if (bufp->full == bufp->size) { + bufp->size *= 2; + /* Add 1 to size to ensure room for terminating + * null. */ + tem = (char *) xrealloc(buf, bufp->size + 1); + bufp->ptr = (bufp->ptr - buf) + tem; + append_end = (append_end - buf) + tem; + bufp->beg = buf = tem; + } + } + else { + append_end -= bufp->ptr - buf; + bcopy(bufp->ptr, buf, bufp->full -= bufp->ptr - buf); + bufp->ptr = buf; + } + if (0 == (nread = read(fd, buf + bufp->full, bufp->size - bufp->full))) + bufp->ateof = 1; + bufp->full += nread; + buf[bufp->full] = '\0'; + } + return end + 1; +} + +#ifdef TEST + +#include + +void tprint(char *cap) { + register char *y, *x = tgetstr(cap, 0); + + printf("%s: ", cap); + if (x) { + y = x; + while (*y) { + if (*y <= ' ' || *y == 0177) + printf("\\%0o", *y); + else putchar(*y); + ++y; + } + free(x); + } + else printf("none"); + putchar('\n'); +} + +void main(int argc, char *argv[]) { + char *buf, *term = argv[1]; + + putenv("TERMCAP=/UNIX/UZIX/LIB/SOURCES/termcap"); + printf("TERM: %s\n", term); + buf = (char *) tgetent(0, term); + if ((int) buf == 0 || (int)buf == -1) { + printf("No entry.\n"); + return; + } + printf("Entry: %s\n", buf); + tprint("cm"); + tprint("AL"); + printf("co: %d\n", tgetnum("co")); + printf("am: %d\n", tgetflag("am")); +} +#endif /* TEST */ + diff --git a/src/libc/termcap.src b/src/libc/termcap.src new file mode 100755 index 00000000..39acefcd --- /dev/null +++ b/src/libc/termcap.src @@ -0,0 +1,225 @@ +# From: miquels@drinkel.ow.org (Miquel van Smoorenburg) +# +# Okay guys, here is a shorter termcap that does have most +# capabilities and is ncurses compatible. If it works for you +# I'd like to hear about it. +# +# Some entries in termcap 2.0.7 are too long and your programs +# may complain "tgetent: warning: termcap entry too long". Here is +# a smaller termcap. But it may not cover as many terminals as the one +# in termcap 2.0.7. You can install it as /etc/termcap. +# +# termcap Termcap entries for the VT family. +# All termcap entries have been freed of the 'ks' and +# 'ke' entries, that put the keypad into applications +# mode. This is a generally misused entry, not ment +# for the vt100 "applications" mode. Now cursor and +# function keys will work in all programs. +# +# Also, there is a "generic" vt entry with common +# entries for all terminals, on which all other entries +# are built. +# +# Version: @(#) vt-termcap 1.37 12-Mar-1996 MvS +# + +# VT-52 entry. +vt52|dec vt52:\ + :co#80:it#8:li#24:\ + :bl=^G:cd=\EJ:ce=\EK:cl=\EH\EJ:cm=\EY%+ %+ :cr=^M:\ + :do=\EB:ho=\EH:kb=^H:kd=\EB:kl=\ED:kr=\EC:ku=\EA:\ + :le=\ED:nd=\EC:nw=^M^J:sf=^J:sr=\EI:ta=^I:up=\EA:\ + :dl=\EI:ve=\Ex5:vi=\Ey5: + +# Generic VT entry. +vg|vt-generic|Generic VT entries:\ + :bs:mi:ms:pt:xn:xo:it#8:\ + :RA=\E[?7l:SA=\E?7h:\ + :bl=^G:cr=^M:ta=^I:\ + :cm=\E[%i%d;%dH:\ + :le=^H:up=\E[A:do=\E[B:nd=\E[C:\ + :LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:DO=\E[%dB:\ + :ho=\E[H:cl=\E[H\E[2J:ce=\E[K:cb=\E[1K:cd=\E[J:sf=\ED:sr=\EM:\ + :ct=\E[3g:st=\EH:\ + :cs=\E[%i%d;%dr:sc=\E7:rc=\E8:\ + :ei=\E[4l:ic=\E[@:IC=\E[%d@:al=\E[L:AL=\E[%dL:\ + :dc=\E[P:DC=\E[%dP:dl=\E[M:DL=\E[%dM:\ + :so=\E[7m:se=\E[m:us=\E[4m:ue=\E[m:\ + :mb=\E[5m:mh=\E[2m:md=\E[1m:mr=\E[7m:me=\E[m:\ + :sc=\E7:rc=\E8:kb=\177:\ + :ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D: + +## Linux console. One should really set TERM=linux instead of TERM=console. +#lx|linux|console|con80x25|LINUX System Console:\ +# :co#80:li#25:am:\ +# :is=\E[m\E[?1l\E>\E[10m:\ +# :rs=\E[m\E[?1l\E>\E[10m:\ +# :ch=\E[%i%dG:cv=\E[%i%dd:\ +# :eA=\E)0:as=^N:ae=^O:ac=aaffggjjkkllmmnnooqqssttuuvvwwxx:\ +# :ve=\E[?25h:vi=\E[?25l:\ +# :se=\E[27m:ue=\E[24m:mh=\E[2m:\ +# :ks=:ke=:\ +# :kh=\E[1~:kH=\E[4~:kI=\E[2~:kD=\E[3~:kP=\E[5~:kN=\E[6~:\ +# :k1=\E[[A:k2=\E[[B:k3=\E[[C:k4=\E[[D:k5=\E[[E:\ +# :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k0=\E[21~:\ +# :F1=\E[23~:F2=\E[24~:\ +# :tc=vt-generic: + +# Slackware 3.1 linux termcap entry (Sat Apr 27 23:03:58 CDT 1996): +lx|linux|console|con80x25|LINUX System Console:\ + :do=^J:co#80:li#25:cl=\E[H\E[J:sf=\ED:sb=\EM:\ + :le=^H:bs:am:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:\ + :ce=\E[K:cd=\E[J:so=\E[7m:se=\E[27m:us=\E[36m:ue=\E[m:\ + :md=\E[1m:mr=\E[7m:mb=\E[5m:me=\E[m:is=\E[1;25r\E[25;1H:\ + :ll=\E[1;25r\E[25;1H:al=\E[L:dc=\E[P:dl=\E[M:\ + :it#8:ku=\E[A:kd=\E[B:kr=\E[C:kl=\E[D:kb=^H:ti=\E[r\E[H:\ + :ho=\E[H:kP=\E[5~:kN=\E[6~:kH=\E[4~:kh=\E[1~:kD=\E[3~:kI=\E[2~:\ + :k1=\E[[A:k2=\E[[B:k3=\E[[C:k4=\E[[D:k5=\E[[E:k6=\E[17~:\ + :k7=\E[18~:k8=\E[19~:k9=\E[20~:k0=\E[21~:K1=\E[1~:K2=\E[5~:\ + :K4=\E[4~:K5=\E[6~:\ + :pt:sr=\EM:vt#3:xn:km:bl=^G:vi=\E[?25l:ve=\E[?25h:vs=\E[?25h:\ + :sc=\E7:rc=\E8:cs=\E[%i%d;%dr:\ + :r1=\Ec:r2=\Ec:r3=\Ec: + +# Some other, commonly used linux console entries. +lx|con80x25:co#80:li#25:tc=linux: +lx|con80x28:co#80:li#25:tc=linux: +lx|con80x43:co#80:li#43:tc=linux: +lx|con80x50:co#80:li#50:tc=linux: +lx|con100x37:co#100:li#37:tc=linux: +lx|con100x40:co#100:li#40:tc=linux: +lx|con132x43:co#132:li#43:tc=linux: + +# vt102 - vt100 + insert line etc. VT102 does not have insert character. +v2|vt102|DEC vt102 compatible:\ + :co#80:li#24:\ + :ic@:IC@:\ + :is=\E[m\E[?1l\E>:\ + :rs=\E[m\E[?1l\E>:\ + :eA=\E)0:as=^N:ae=^O:ac=aaffggjjkkllmmnnooqqssttuuvvwwxx:\ + :ks=:ke=:\ + :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ + :tc=vt-generic: + +# vt100 - really vt102 without insert line, insert char etc. +vt|vt100|DEC vt100 compatible:\ + :im@:mi@:al@:dl@:ic@:dc@:AL@:DL@:IC@:DC@:\ + :tc=vt102: + +# Standard vt320 (based on my own digital vt320) +v3|vt320|DEC vt320:\ + :co#80:li#24:hs:es:\ + :is=\E[m\E[2$~\E[?1l\E>:\ + :rs=\E[m\E[?1l\E>:\ + :ve=\E[?25h:vi=\E[?25l:\ + :se=\E[27m:ue=\E[24m:mh=\E[2m:\ + :eA=\E)0:as=^N:ae=^O:ac=aaffggjjkkllmmnnooqqssttuuvvwwxx:\ + :ts=\E[1$}\E[1;%i%dH:fs=\E[0$}:ds=\E[1$}\r\E[m\E[K\E[0$}:\ + :ks=:ke=:\ + :kI=\E[2~:kD=\E[3~:kP=\E[5~:kN=\E[6~:\ + :@4=\E[29~:@0=\E[1~:*6=\E[4~:\ + :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[16~\ + :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k0=\E[21~:\ + :F1=\E[23~:F2=\E[24~:F3=\E[25~:F4=\E[26~:F5=\E[28~:\ + :F6=\E[29~:F7=\E[31~:F8=\E[32~:\ + :tc=vt-generic: + +v8|vt320-8|DEC vt320 in 8-bit mode:\ + :kI=\2332~:kD=\2333~:kP=\2335~:kN=\2336~:\ + :@4=\23329~:@0=\2331~:*6=\2334~:\ + :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\23316~\ + :k6=\23317~:k7=\23318~:k8=\23319~:k9=\23320~:k0=\23321~:\ + :F1=\23323~:F2=\23324~:F3=\23325~:F4=\23326~:F5=\23328~:\ + :F6=\23329~:F7=\23331~:F8=\23332~:\ + :ku=\233A:kd=\233B:kr=\233C:kl=\233D:\ + :tc=vt320: + +# Entry for minicom so it uses the PC (IBM) character set. +# If this doesn't work for kernels between 1.1.18 and 1.1.80, +# change \E(U -> \E[11m (enter ANSI mode) +# and \E(B -> \E[10m (leave ANSI mode) +mc|minicom|ansi-mc|termcap entry for minicom on the console:\ + :is=\E[m\E>\E(U:\ + :rs=\E[m\E>\E(B:\ + :as@:ae@:eA@:ac@:\ + :bl=\E(B\007\E(U:\ + :vb=\E(B\007\E(U:\ + :tc=linux: + +# Entry for an xterm. Insert mode has been disabled. +vs|xterm|vs100|xterm terminal emulator (X Window System):\ + :am:bs:mi@:km:co#80:li#55:\ + :im@:ei@:\ + :ct=\E[3k:ue=\E[m:\ + :is=\E[m\E[?1l\E>:\ + :rs=\E[m\E[?1l\E>:\ + :eA=\E)0:as=^N:ae=^O:ac=aaffggjjkkllmmnnooqqssttuuvvwwxx:\ + :kI=\E[2~:kD=\177:kP=\E[5~:kN=\E[6~:\ + :k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~:k5=\E[15~:\ + :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k0=\E[21~:\ + :F1=\E[23~:F2=\E[24~:\ + :kh=\E[H:kH=\EOw:\ + :ks=:ke=:\ + :te=\E[2J\E[?47l\E8:ti=\E7\E[?47h:\ + :tc=vt-generic: + +# Some other entries for the same xterm. +v2|xterms|vs100s|xterm small window:\ + :co#80:li#24:tc=xterm: +vb|xterm-bold|xterm with bold instead of underline:\ + :us=\E[1m:tc=xterm: +vi|xterm-ins|xterm with insert mode:\ + :mi:im=\E[4h:ei=\E[4l:tc=xterm: + +# DOS terminal emulator such as Telix or TeleMate. +# This probably also works for the SCO console, though it's incomplete. +an|ansi|ansi-bbs|ANSI terminals (emulators):\ + :co#80:li#24:am:\ + :is=:rs=\Ec:kb=^H:\ + :as=\E[m:ae=:eA=:\ + :ac=0\333+\257,\256.\031-\030a\261f\370g\361j\331k\277l\332m\300n\305q\304t\264u\303v\301w\302x\263~\025:\ + :kD=\177:kH=\E[Y:kN=\E[U:kP=\E[V:kh=\E[H:\ + :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOT:\ + :k6=\EOU:k7=\EOV:k8=\EOW:k9=\EOX:k0=\EOY:\ + :tc=vt-generic: + +# This seems to be an entry for other x86 based unices. +at|at386-m|386AT-M|386at-m|at/386 console:\ + :am:bw:eo:xt:co#80:li#25:\ + :ae=\E[10m:as=\E[12m:\ + :is=\E[0;10;38m:\ + :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOT:\ + :k6=\EOU:k7=\EOV:k8=\EOW:k9=\EOX:\ + :kh=\E[H:us=\E[4m:vb=^G:nl=\E[B:kb=^H:\ + :tc=vt-generic: + +# Yeah - Minix still lives :) +ma|minix|minix-am|minix-vcam|MINIX 1.5 Virtual Console:\ + :am:bs:co#80:li#25:km:ms:\ + :is=\E[0m\EPlinewrap.on\E\\:\ + :rs=\Ec\EPlinewrap.on\E\\:\ + :as=:ae=:eA=:\ + :ac=0\333+\257,\256.\031-\030a\261f\370g\361j\331k\277l\332m\300n\305q\304t\264u\303v\301w\302x\263~\025:\ + :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOT:\ + :k6=\EOU:k7=\EOV:k8=\EOW:k9=\EOX:k0=\EOY:\ + :kD=\177:kH=\E[Y:kN=\E[U:kP=\E[V:kh=\E[H:kb=^H:\ + :ve=\EPcursor.on\E\\:vi=\EPcursor.off\E\\:\ + :tc=vt-generic: + +# Some obligatory historic entries. +sa|network|ethernet|arpanet:co#80:os:am: +su|dumb|un|unknown:co#80:os:am: +sd|du|dialup:co#80:os:am: +t7|37|tty37|model 37 teletype:\ + :cr=^M:do=^J:nl=^J:bl=^G:le=^H:bs:hc:hu=\E8:hd=\E9:up=\E7:os: + +# Yes, there really are people that login from a Sun Console. +mu|sun|Sun Microsystems Workstation console:\ + :am:bs:km:mi:ms:pt:\ + :li#34:co#80:cl=^L:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:\ + :ce=\E[K:cd=\E[J:so=\E[7m:se=\E[m:\ + :kd=\E[B:kl=\E[D:ku=\E[A:kr=\E[C:kh=\E[H:\ + :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:\ + :al=\E[L:dl=\E[M:im=:ei=:ic=\E[@:dc=\E[P:\ + :rs=\E[s: + \ No newline at end of file diff --git a/src/libc/time-l.h b/src/libc/time-l.h new file mode 100755 index 00000000..c0c35ec3 --- /dev/null +++ b/src/libc/time-l.h @@ -0,0 +1,24 @@ +/* TIME-L.H Time conversion and time related package + * + */ +#include +#include + +#ifndef TZ_MOSCOW +#ifndef TZ_BRAZIL +#define TZ_BRAZIL +#endif +#endif + +#ifdef MAKE_ALL +#define L_asctime +#define L_ctime +#define L_gmtime +#define L_localtim +#define L_tzset +#define L_clock +#define L_mktime +#define L_difftime +#define L_convtime +#endif + \ No newline at end of file diff --git a/src/libc/tmpnam.c b/src/libc/tmpnam.c new file mode 100755 index 00000000..eedf57ec --- /dev/null +++ b/src/libc/tmpnam.c @@ -0,0 +1,48 @@ +/* tmpnam.c + * + * function(s) + * __mkname - builds a file name of the form TMPXXXXX.$$$ + * tmpnam - builds a unique file name + */ +#include +#include +#include +#include +#include + +static char template[64]; +unsigned long _tmpnum; + +static char *__mkname __P((char *s, unsigned long num)); + +/* +Name __mkname - builds a file name of the form /tmp/NNNNNNN +Usage char * __mkname(char *s, unsigned long num); +Return value a file name of the form /tmp/NNNNNNN +*/ +static char *__mkname(s, num) + char *s; + unsigned long num; +{ + /* If no buffer provided, use internal template */ + if (s == NULL) + s = template; + strcpy(s, _PATH_TMP); + ultoa(num, s + strlen(s), 10); + return s; +} + +/* tmpnam - builds a unique file name + * Usage char *tmpnam(char *s); + * Prototype in stdio.h + * Return value a unique temporary file name + */ +char *tmpnam(s) + char *s; +{ + do { + s = __mkname(s, _tmpnum += 13); + } while (access(s, 0) != -1); + return s; +} + diff --git a/src/libc/tparam.c b/src/libc/tparam.c new file mode 100755 index 00000000..f724861f --- /dev/null +++ b/src/libc/tparam.c @@ -0,0 +1,286 @@ +/* tparam.c + * Merge parameters into a termcap entry string. + * Copyright (C) 1985, 1987, 1993 Free Software Foundation, Inc. + */ +#include +#include +#include +#include +#include + +static void memory_out __P((void)); +static char *xmalloc __P((unsigned size)); +static char *xrealloc __P((char *ptr, unsigned size)); +static char *tparam1 __P((char *string, char *outstring, int len, char *up, char *left, int *argp)); + +static void memory_out() { + write(2, "virtual memory exhausted\n", 25); + exit(1); +} + +static char *xmalloc(size) + unsigned size; +{ + register char *tem = malloc(size); + + if (!tem) + memory_out(); + return tem; +} + +static char *xrealloc(ptr, size) + char *ptr; + unsigned size; +{ + register char *tem = realloc(ptr, size); + + if (!tem) + memory_out(); + return tem; +} + +/* Assuming STRING is the value of a termcap string entry + containing `%' constructs to expand parameters, + merge in parameter values and store result in block OUTSTRING points to. + LEN is the length of OUTSTRING. If more space is needed, + a block is allocated with `malloc'. + + The value returned is the address of the resulting string. + This may be OUTSTRING or may be the address of a block got with `malloc'. + In the latter case, the caller must free the block. + + The fourth and following args to tparam serve as the parameter values. + */ +/* VARARGS 2 */ +char *tparam(string, outstring, len, arg0, arg1, arg2, arg3) + char *string; + char *outstring; + int len; + int arg0, arg1, arg2, arg3; +{ +#ifdef NO_ARG_ARRAY + int arg[4]; + arg[0] = arg0; + arg[1] = arg1; + arg[2] = arg2; + arg[3] = arg3; + return tparam1(string, outstring, len, NULL, NULL, arg); +#else + (void)arg1; (void)arg2; (void)arg3; + return tparam1(string, outstring, len, NULL, NULL, &arg0); +#endif +} + +char *_BC; +char *_UP; + +static char tgoto_buf[50]; + +char *tgoto(cm, hpos, vpos) + char *cm; + int hpos, vpos; +{ + int args[2]; + + if (!cm) + return NULL; + args[0] = vpos; + args[1] = hpos; + return tparam1(cm, tgoto_buf, 50, _UP, _BC, args); +} + +static char *tparam1(string, outstring, len, up, left, argp) + char *string; + char *outstring; + int len; + char *up, *left; + register int *argp; +{ + register int c, tem; + register char *p = string; + register char *op = outstring; + int *old_argp = argp; + int outlen = 0; + int doleft = 0; + int doup = 0; + char *outend = outstring + len; + + while (1) { + /* If the buffer might be too short, make it bigger. */ + if (op + 5 >= outend) { + register char *new; + if (outlen == 0) { + outlen = len + 40; + new = (char *) xmalloc(outlen); + outend += 40; + memcpy(new, outstring, op - outstring); + } + else { + outend += outlen; + outlen *= 2; + new = (char *) xrealloc(outstring, outlen); + } + op += new -outstring; + outend += new -outstring; + outstring = new; + } + c = *p++; + if (!c) + break; + if (c == '%') { + c = *p++; + tem = *argp; + switch (c) { + case 'd': /* %d means output in decimal. */ + if (tem < 10) + goto onedigit; + if (tem < 100) + goto twodigit; + case '3': /* %3 means output in decimal, 3 digits. */ + if (tem > 999) { + *op++ = tem / 1000 + '0'; + tem %= 1000; + } + *op++ = tem / 100 + '0'; + case '2': /* %2 means output in decimal, 2 digits. */ +twodigit: + tem %= 100; + *op++ = tem / 10 + '0'; +onedigit: + *op++ = tem % 10 + '0'; + argp++; + break; + + case 'C': + /* For c-100: print quotient of value by 96, if + * nonzero, then do like %+. */ + if (tem >= 96) { + *op++ = tem / 96; + tem %= 96; + } + case '+': /* %+x means add character code of char x. */ + tem += *p++; + case '.': /* %. means output as character. */ + if (left) { + /* If want to forbid output of 0 and \n and + * \t, and this is one of them, increment + * it. */ + while (tem == 0 || tem == '\n' || tem == '\t') { + tem++; + if (argp == old_argp) + doup++, outend -= strlen(up); + else + doleft++, outend -= strlen(left); + } + } + *op++ = tem ? tem : 0200; + case 'f': /* %f means discard next arg. */ + argp++; + break; + + case 'b': /* %b means back up one arg (and re-use + * it). */ + argp--; + break; + + case 'r': /* %r means interchange following two args. */ + argp[0] = argp[1]; + argp[1] = tem; + old_argp++; + break; + + case '>': /* %>xy means if arg is > char code of x, */ + if (argp[0] > *p++) /* then add char code of y + * to the arg, */ + argp[0] += *p; /* and in any case don't + * output. */ + p++; /* Leave the arg to be output later. */ + break; + + case 'a': /* %a means arithmetic. */ + /* Next character says what operation. Add or + * subtract either a constant or some other arg. */ + /* First following character is + to add or - to + * subtract or = to assign. */ + /* Next following char is 'p' and an arg spec (0100 + * plus position of that arg relative to this one) + * or 'c' and a constant stored in a character. */ + tem = p[2] & 0177; + if (p[1] == 'p') + tem = argp[tem - 0100]; + if (p[0] == '-') + argp[0] -= tem; + else if (p[0] == '+') + argp[0] += tem; + else if (p[0] == '*') + argp[0] *= tem; + else if (p[0] == '/') + argp[0] /= tem; + else + argp[0] = tem; + + p += 3; + break; + + case 'i': /* %i means add one to arg, */ + argp[0]++; /* and leave it to be output later. */ + argp[1]++; /* Increment the following arg, + * too! */ + break; + + case '%': /* %% means output %; no arg. */ + goto ordinary; + + case 'n': /* %n means xor each of next two args with + * 140. */ + argp[0] ^= 0140; + argp[1] ^= 0140; + break; + + case 'm': /* %m means xor each of next two args with + * 177. */ + argp[0] ^= 0177; + argp[1] ^= 0177; + break; + + case 'B': /* %B means express arg as _BCD char code. */ + argp[0] += 6 * (tem / 10); + break; + + case 'D': /* %D means weird Delta Data + * transformation. */ + argp[0] -= 2 * (tem % 16); + break; + } + } + else + /* Ordinary character in the argument string. */ +ordinary: + *op++ = c; + } + *op = 0; + while (doup-- > 0) + strcat(op, up); + while (doleft-- > 0) + strcat(op, left); + return outstring; +} + +#ifdef TEST + +int main(argc, argv) + int argc; + char **argv; +{ + char buf[50]; + int args[3]; + + args[0] = atoi(argv[2]); + args[1] = atoi(argv[3]); + args[2] = atoi(argv[4]); + tparam1(argv[1], buf, 50, "LEFT", "UP", args); + printf("%s\n", buf); + return 0; +} +#endif /* DEBUG */ + diff --git a/src/libc/ttyname.c b/src/libc/ttyname.c new file mode 100755 index 00000000..c33a4d57 --- /dev/null +++ b/src/libc/ttyname.c @@ -0,0 +1,45 @@ +/* ttyname.c + */ +#include +#include +#include +#include + +char *ttyname(fd) + int fd; +{ + static char name[MAXNAMLEN]; + static char dev[] = "/dev"; + struct stat st, dst; + struct dirent *d; + char *ret = NULL; + DIR *fp; + int noerr = errno; + + if (fstat(fd, &st) < 0) + return 0; + if (!isatty(fd)) { + errno = ENOTTY; + return 0; + } + fp = opendir(dev); + if (fp == 0) + return 0; + strcpy(name, dev); + strcat(name, "/"); + while ((d = readdir(fp)) != 0) { + if (strlen(d->d_name) > sizeof(name) - sizeof(dev) - 1) + continue; + strcpy(name + sizeof(dev), d->d_name); + if (stat(name, &dst) == 0 && + st.st_dev == dst.st_dev && + st.st_ino == dst.st_ino) { + ret = name; + break; + } + } + closedir(fp); + errno = noerr; + return ret; +} + \ No newline at end of file diff --git a/src/libc/tzset.c b/src/libc/tzset.c new file mode 100755 index 00000000..f69425f9 --- /dev/null +++ b/src/libc/tzset.c @@ -0,0 +1,35 @@ +/*************************** TZSET ************************************/ +#include "time-l.h" + +#ifdef L_tzset +#include + +char *tzname[2] = { "GMT", "\0\0\0" }; +int daylight; +long timezone; + +/* tzset expects fo find a environment string of the form TZ=... + * ??? need to correct! + */ +void tzset(VOID) { + char *tz = getenv("TZ"); + + if (tz == NULL) { + memcpy(tzname[1],"GMT",3); +#ifdef TZ_MOSCOW + timezone = -3*60*60L; /* Moscow region */ +#endif +#ifdef TZ_BRAZIL + timezone = +3*60*60L; /* Brazil */ +#endif + } + else { + int v; + + memcpy(tzname[1],tz,3); + v = atoi(tz+3); + timezone = -((v / 100) * 60 + (v % 100) ) *60L; + } +} +#endif + diff --git a/src/libc/ultoa.c b/src/libc/ultoa.c new file mode 100755 index 00000000..70350a01 --- /dev/null +++ b/src/libc/ultoa.c @@ -0,0 +1,22 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/**************************** ultoa.c ****************************/ +#ifdef L_ultoa +char *ultoa(value, strP, radix) + unsigned long value; + char *strP; + int radix; +{ + char hex = 'A'; + + if (radix < 0) { + hex = 'a'; + radix = -radix; + } + return __longtoa (value, strP, radix, 0, hex); +} +#endif + diff --git a/src/libc/ungetc.c b/src/libc/ungetc.c new file mode 100755 index 00000000..7716a1ac --- /dev/null +++ b/src/libc/ungetc.c @@ -0,0 +1,30 @@ +/* stdio.c + * Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. */ + +#include "stdio-l.h" + +#ifdef L_ungetc +int ungetc(c, fp) + int c; + FILE *fp; +{ + if (fp->mode & __MODE_WRITING) + fflush(fp); + /* Can't read or there's been an error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ) + return EOF; + /* Can't do fast fseeks */ + fp->mode |= __MODE_UNGOT; + if (fp->bufpos > fp->bufstart) + return *--fp->bufpos = (unsigned char) c; + if (fp->bufread == fp->bufstart) + return *fp->bufread++ = (unsigned char) c; + return EOF; +} +#endif + \ No newline at end of file diff --git a/src/libc/unix.h$ b/src/libc/unix.h$ new file mode 100755 index 00000000..9a43feba --- /dev/null +++ b/src/libc/unix.h$ @@ -0,0 +1,440 @@ +/* + * UZIX - UNIX Implementation for MSX + * (c) 1997-2001 Arcady Schekochikhin + * Adriano C. R. da Cunha + * + * UZIX is based on UZI (UNIX Zilog Implementation) + * UZI is a UNIX kernel clone written for Z-80 systems. + * All code is public domain, not being based on any AT&T code. + * + * The author, Douglas Braun, can be reached at: + * 7696 West Zayante Rd. + * Felton, CA 95018 + * oliveb!intelca!mipos3!cadev4!dbraun + * + * This program is under GNU GPL, read COPYING for details + * + */ + +/********************************************************** + UZIX structure and main definitions +**********************************************************/ + +#ifndef __UNIX_H +#define __UNIX_H + +#ifndef SEPH +#include "types.h" +#include "signal.h" +#include "errno.h" +#include "fcntl.h" +#include "sys/stat.h" +#include "sys/ioctl.h" +#endif + +#ifndef DEBUG +#define DEBUG 0 +#endif + +#define UZIXBASE (unsigned)0x8000 /* start of UZIX code */ +#define _UZIXBASE 8000h /* start of UZIX code for ASM */ +#define PROGBASE 0x100 /* Executable's load base */ +#define SYSCADDR 8 /* System call routine */ + /* Changed to 0008h to allow BDOSEMU */ +#define EXITADDR 0 /* System exit routine */ + +#define MAXSWAP 1024 /* maximal memory to use for swap */ +#ifdef MSX_HOSTED +#define MEMBANKING /* MSX has memory banking hardware */ +#else +#undef MEMBANKING /* i86 has no memory banking hardware */ +#endif + +#define MEM_DEV + +/* ITABSIZE should be at least 7 to allow piping. A lower value causes + piping to block. */ + +#if DEBUG > 1 +#define UFTSIZE 5 /* Number of per user files */ +#define OFTSIZE 10 /* Open file table size */ +#define ITABSIZE 8 /* Inode table size */ +#define PTABSIZE 5 /* Process table size */ +#define NBUFS (4-1) /* Number of block buffers */ +#else /* DEBUG > 1 */ +#ifdef MSX_HOSTED +#ifdef UZIX_MODULE +#define UFTSIZE 9 /* Number of per user files */ +#define OFTSIZE (14-4) /* Open file table size */ +#define ITABSIZE 7 /* Inode table size */ +#define PTABSIZE 7 /* Process table size */ +#define MTABSIZE 2 /* Module table size */ +#define RTABSIZE 3 /* Module reply table size */ +#define NBUFS 2 /* Number of block buffers */ +#else /* UZIX_MODULE */ +#define UFTSIZE 10 /* Number of per user files */ +#define OFTSIZE 15 /* Open file table size */ +#define ITABSIZE 8 /* Inode table size */ +#define PTABSIZE 6 /* Process table size */ +#define NBUFS 2 /* Number of block buffers */ +#endif /* UZIX_MODULE */ +#undef MEM_DEV +#else /* MSX_HOSTED */ +#ifdef NEED__SCALL +#define UFTSIZE 10 /*20 /* Number of per user files */ +#define OFTSIZE 20 /*40 /* Open file table size */ +#define ITABSIZE 10 /*20 /* Inode table size */ +#define PTABSIZE 5 /*10 /* Process table size (Nick, formerly 0) */ +#define NBUFS 5 /*10 /* Number of block buffers */ +#else /* NEED__SCALL */ +#define UFTSIZE 10 /*20 /* Number of per user files */ +#define OFTSIZE 0 /* Open file table size */ +#define ITABSIZE 10 /*20 /* Inode table size */ +#define PTABSIZE 0 /* Process table size */ +#define NBUFS 5 /*10 /* Number of block buffers */ +#endif /* NEED_SCALL */ +#endif /* MSX_HOSTED */ +#endif /* DEBUG > 1 */ + +#define NSIGS 16 /* Number of signals <= 16 */ + +#ifdef PC_HOSTED +#define TMPSTK 400 /* size of tmp stack. the bigger, the better. */ +#else +#if DEBUG > 1 +#define TMPSTK 300-50 /* for MSX */ +#endif +#endif + +#define SUPERBLOCK 1 /* disk block of filesystem superblock */ +#define ROOTINODE 1 /* Inode # of / for all mounted filesystems */ + +#ifdef PC_HOSTED +#define EMAGIC 0xE9 /* Header of executable - jmp near ptr ... */ +#else +#define EMAGIC 0xC3 /* Header of Z80-executable: jp ... */ +#endif +#define CMAGIC 31415 /* Random number for cinode c_magic */ +#define SMOUNTED 19638 /* Magic number to specify mounted filesystem */ + +typedef uchar page_t; /* swap page definition */ + +/* file-system related data types */ +typedef uint ino_t; /* Can have 65536 inodes in fs */ +typedef uint blkno_t; /* Can have 65536 BUFSIZE-byte blocks in fs */ +typedef uint dev_t; /* Device number */ + +#define MINOR(dev) ((uchar)(dev)) +#define MAJOR(dev) ((uchar)((dev) >> 8)) +#define MKDEV(major, minor) (((uint)(uchar)(major) << 8) | (uchar)(minor)) + +#define NULLINO ((ino_t)0) +#define NULLBLK ((blkno_t)-1) +#define NULLDEV ((dev_t)-1) + +/* executable file header */ +typedef struct s_exec { + uchar e_magic; /* magic value (jmp near ptr ) */ + int e_jump; /* */ + uchar e_flags; /* executable flags */ + /* bit 7: 1-not refresh system vectors on swapin() */ + /* bit 6: 1-process is a module */ + uint e_text; /* end of text */ + uint e_data; /* end of data */ + uint e_bss; /* end of bss */ + uint e_heap; /* needed heap len */ + uint e_stack; /* needed stack len */ + uint e_dummy; /* undefined now */ +} exec_t, *exeptr; + +/* input/output queue for character devices */ +typedef struct s_queue { + uchar *q_base; /* Pointer to data buffer */ + uchar *q_head; /* Pointer to addr of next char to read. */ + uchar *q_tail; /* Pointer to where next char to insert goes. */ + uint q_size; /* Max size of queue */ + uint q_count; /* How many characters presently in queue */ + uint q_wakeup; /* Threshold for waking up procs waiting on queue */ +} queue_t; + +/* Flags for setftime() */ +#define A_TIME 1 /* set access time */ +#define M_TIME 2 /* set modify time */ +#define C_TIME 4 /* set creation time */ + +typedef struct s_blkbuf { + uchar bf_data[BUFSIZE]; /* This MUST BE first ! */ + dev_t bf_dev; /* device of this block */ + blkno_t bf_blk; /* and block number on device */ + uchar bf_dirty; /* buffer changed flag */ + uchar bf_busy; /* buffer processing in progress */ + uchar bf_prio; /* buffer must be in memory (for wargs) */ + uint bf_time; /* LRU time stamp */ +/* struct s_blkbuf *bf_next; /* LRU free list pointer */ +} blkbuf_t, *bufptr; + +#define DIRECTBLOCKS 18 +#define INDIRECTBLOCKS 1 /* MUST BE 1! */ +#define DINDIRECTBLOCKS 1 /* MUST BE 1! */ +#define TOTALREFBLOCKS (DIRECTBLOCKS+2) + +/* Device-resident inode structure */ +typedef struct s_dinode { + mode_t i_mode; /* file mode */ + uint i_nlink; /* number of links to file */ + uchar i_uid, i_gid; /* file owner */ + off_t i_size; /* file size */ + time_t i_atime; /* last access time */ + time_t i_mtime; /* last modification time */ + time_t i_ctime; /* file creation time */ + blkno_t i_addr[DIRECTBLOCKS+INDIRECTBLOCKS+DINDIRECTBLOCKS]; +#if TOTALREFBLOCKS < 21 + blkno_t i_dummy[21-TOTALREFBLOCKS]; +#endif +} dinode_t; /* Exactly 64 bytes long! See DINODESPERBLOCK below */ + +#define DINODESPERBLOCK 8 /* # of dinode_t per logical block */ +#define DINODESPERBLOCKLOG 3 /* log2(DINODESPERBLOCK) */ +#define DINODESPERBLOCKMASK ((1<c_node.i_addr[0])) + +/* Getmode() returns the inode kind */ +#define _getmode(mode) ((mode) & S_IFMT) +#define getmode(ino) (_getmode((ino)->c_node.i_mode)) +/* Super() returns true if we are the superuser */ +#define super() (UDATA(u_euid) == 0) + +/* in-core inode structure */ +typedef struct s_cinode { + uint c_magic; /* Used to check for corruption */ + uchar c_dirty; /* Modified flag */ + dev_t c_dev; /* Inode's device */ + ino_t c_num; /* Inode's number */ + uint c_refs; /* In-core reference count */ + bool_t c_ro; /* Read-only filesystem flag */ + dinode_t c_node; /* disk inode copy */ +} cinode_t, *inoptr; + +#define DIRECTPERBLOCK (BUFSIZE/sizeof(direct_t)) + +#define FSFREEBLOCKS 50 +#define FSFREEINODES 50 + +/* device-resident super-block */ +typedef struct s_filesys { + uint s_mounted; /* signature */ + uint s_reserv; /* # of first block of inodes */ + uint s_isize; /* # of inode's blocks */ + uint s_fsize; /* # of data's blocks */ + + blkno_t s_tfree; /* total free blocks */ + uint s_nfree; /* # of free blocks in s_free */ + blkno_t s_free[FSFREEBLOCKS]; /* #s of free block's */ + + ino_t s_tinode; /* total free inodes */ + uint s_ninode; /* # of free inodes in s_inode */ + ino_t s_inode[FSFREEINODES]; /* #s of free inodes */ + + time_t s_time; /* last modification timestamp */ + +/* Core-resident part */ + bool_t s_fmod; /* filesystem modified */ + bool_t s_ronly; /* readonly filesystem */ + inoptr s_mntpt; /* Mount point inode */ + dev_t s_dev; /* Fs device */ +} filesys_t, *fsptr; + +/* open file descriptor */ +typedef struct oft { + off_t o_ptr; /* File position pointer */ + inoptr o_inode; /* Pointer into in-core inode table */ + uchar o_access; /* O_RDONLY, O_WRONLY, or O_RDWR */ + uchar o_refs; /* Ref count: depends on # of active children */ +} oft_t, *ofptr; + +#ifndef _PSTATE_T +#define _PSTATE_T +/* Process table p_status values */ +typedef enum { + P_EMPTY = 0, /* Unused slot */ + P_ZOMBIE, /* 1. Exited. */ + P_FORKING, /* 2. In process of forking; do not mess with */ + P_RUNNING, /* 3. Currently running process */ + P_READY, /* 4. Runnable process */ + P_SLEEP, /* 5. Sleeping; can be awakened by signal */ + P_XSLEEP, /* 6. Sleeping, don't wake up for signal */ + P_PAUSE, /* 7. Sleeping for pause(); can wakeup for signal */ + P_WAIT, /* 8. Executed a wait() */ + P_STOPED /* 9. Process is stoped */ +} pstate_t; +#endif + +#define PRIO_MAX 19 +#define PRIO_MIN -20 + +#define WNOHANG 1 +#define WUNTRACED 2 + +/* Process table entry */ +typedef struct s_ptab { + pstate_t p_status; /* Process status */ + int p_pid; /* Process ID */ + uchar p_uid; /* User ID */ + uchar p_cprio; /* Process current priority */ +/* uchar p_prio; /* Process base priority - NOT IMPLEMENTED */ + signed char p_nice; /* Process nice value (-20 to 19) */ +/* uchar p_mapped; /* Process not in UZIX kernel - NOT USED */ +/* page_t p_map[3]; /* Process memory map - NOT USED */ + page_t p_swap[2]; /* Swapping parameters */ + struct s_ptab *p_pptr; /* Process's parent table entry */ + int p_exitval; /* Exit value */ + /* Everything below here is overlaid by time info at exit */ + void *p_break; /* process break level */ + void *p_sp; /* saved stack pointer when swapped out */ + void *p_udata; /* back pointer to saved udata */ + uint p_alarm; /* Seconds until alarm goes off */ + void *p_wait; /* Address of thing waited for */ + sigset_t p_pending; /* Pending signals */ + sigset_t p_ignored; /* Ignored signals */ + uchar p_intr; /* !0 if awakened by signal */ +} ptab_t, *ptptr; + +#define FORALLPROCS(p) for ((p) = ptab; (p) < ptab + PTABSIZE; ++(p)) + +/* Per-process data (Swapped with process) */ +typedef struct s_udata { + ptab_t *u_ptab; /* Process table pointer */ + uchar u_name[DIRNAMELEN]; /* Name invoked with */ + + /* syscall's interface */ + uchar u_insys; /* True if in kernel now */ + uchar u_callno; /* syscall being executed */ + uchar u_error; /* Last error number */ + uchar u_traceme; /* Process tracing flag */ + int u_argn1; /* First arg */ + int u_argn2; /* Second arg */ + int u_argn3; /* Third arg */ + int u_argn4; /* Fourth arg (only for lseek) */ + int u_retval; /* Return value from syscall */ + int u_retval1; /* for long return value */ + + /* I/O interface */ + uchar *u_base; /* Source or dest for I/O */ + count_t u_count; /* Amount for I/O */ + off_t u_offset; /* Place in file for I/O */ + bufptr u_buf; + + /* filesystem info */ + uchar u_gid; /* process group id */ + uchar u_euid; /* effective user id */ + uchar u_egid; /* effective group id */ + mode_t u_mask; /* umask: file creation mode mask */ + time_t u_time; /* Start time */ + uchar u_files[UFTSIZE]; /* Proc file table: cont indexes into oft */ + inoptr u_root; /* Pointer into inode table for root */ + inoptr u_cwd; /* Pointer into inode table for cwd */ + + /* processes flow info */ + void *u_break; /* Top of data space */ + inoptr u_ino; /* Used during execve() */ + uchar u_inint; /* Inint value right before swapping */ + + void (*u_sigvec[NSIGS]) __P((signal_t)); /* Array of signal vectors */ + signal_t u_cursig; /* Signal currently being caught (1..NSIGS) */ + time_t u_utime; /* Elapsed ticks in user mode */ + time_t u_stime; /* Ticks in system mode */ + time_t u_cutime; /* Total children's ticks */ + time_t u_cstime; /* Total system children's ticks */ +} udata_t; + +/* The device driver switch table */ +typedef struct s_devsw { + uchar minors; /* # of minor device numbers */ + int (*dev_init) __P((uchar minor)); + int (*dev_open) __P((uchar minor)); + int (*dev_close) __P((uchar minor)); + int (*dev_read) __P((uchar minor, uchar rawflag)); + int (*dev_write) __P((uchar minor, uchar rawflag)); + int (*dev_ioctl) __P((uchar minor, int cmd, void *data)); +} devsw_t; + +/* Info about a specific process, returned by sys_getfsys */ +typedef struct s_pdata { + int u_pid; /* Process PID */ + ptab_t *u_ptab; /* Process table pointer */ + uchar u_name[DIRNAMELEN]; /* Name invoked with */ + + /* syscall's interface */ + uchar u_insys; /* True if in kernel now */ + uchar u_callno; /* syscall being executed */ + uchar u_traceme; /* Process tracing flag */ + + /* filesystem/user info */ + uchar u_uid; /* user id */ + uchar u_gid; /* group id */ + uchar u_euid; /* effective user id */ + uchar u_egid; /* group user id */ + time_t u_time; /* Start time */ + + /* process flow info */ + signal_t u_cursig; /* Signal currently being caught */ + + /* time info */ + time_t u_utime; /* Elapsed ticks in user mode */ + time_t u_stime; /* Ticks in system mode */ +}; + +/* Info about kernel, returned by sys_getfsys */ +typedef struct s_kdata { + uchar k_name[14]; /* OS name */ + uchar k_version[8]; /* OS version */ + uchar k_release[8]; /* OS release */ + uchar k_machine[8]; /* Host machine */ + int k_tmem; /* System memory, in kbytes */ + int k_kmem; /* Kernel memory, in kbytes */ +}; + +#define REFRESH_VECTORS() (!(((exeptr)PROGBASE)->e_flags & 0x80)) + +#ifdef UZIX_MODULE + +#define RESET_MODULE() (((exeptr)PROGBASE)->e_flags &= ~0x40) +#define SET_MODULE() (((exeptr)PROGBASE)->e_flags |= 0x40) +#define IS_MODULE() ((((exeptr)PROGBASE)->e_flags & 0x40) != 0) + +typedef int (*fcnhnd_t) (); /* Function call handler typedef */ + +/* Module table */ +typedef struct s_mtable { + int sig; /* Module signature */ + fcnhnd_t fcn_hnd;/* Module function call handler */ + page_t page[2];/* Module process pages */ +} modtab_t, *modtabptr; + +/* Module reply table */ +typedef struct s_mreply { + int sig; /* Module signature */ + int fcn; /* Function called */ + int pid; /* Requester PID */ + char *replyaddr; /* Reply data address */ + int replysize; /* Reply data size */ +} modreply_t, *modreplyptr; + +#endif + +/* sys_getset() commands */ +#define GET_PID 0 /* get process id */ +#define GET_PPID 1 /* get parent process id */ +#define GET_UID 2 /* get user id */ +#define SET_UID 3 /* set user id */ +#define GET_EUID 4 /* get effective user id */ +#define GET_GID 5 /* get group id */ +#define SET_GID 6 /* set group id */ +#define GET_EGID 7 /* get effective group id */ +#define GET_PRIO 8 /* get process priority */ +#define SET_PRIO 9 /* set process priority */ +#define SET_UMASK 10 /* get/set umask */ +#define SET_TRACE 11 /* set trace flag */ + +#endif diff --git a/src/libc/utsname.c b/src/libc/utsname.c new file mode 100755 index 00000000..1c1fb9aa --- /dev/null +++ b/src/libc/utsname.c @@ -0,0 +1,39 @@ +/* + * utsname.c for UZIX + * by A&L Software 1999 + * + */ + +#include +#include +#include +#include +#ifdef __TURBOC__ +#include <..\kernel\unix.h> +/* Nick #endif */ +#else /* Nick #ifdef HI_TECH_C */ +#include +#endif + +int uname (__utsbuf) + struct utsname *__utsbuf; +{ + struct s_kdata kdata; + int i; + + getfsys(GI_KDAT, &kdata); + strcpy(__utsbuf->sysname,kdata.k_name); +#if 1 /* Nick */ + strcpy(__utsbuf->nodename,kdata.k_host); +#else + strcpy(__utsbuf->nodename,kdata.k_name); + for (i=0;inodename);i++) + __utsbuf->nodename[i]=tolower(__utsbuf->nodename[i]); +#endif + strcpy(__utsbuf->release,kdata.k_release); + strcpy(__utsbuf->version,kdata.k_version); + strcpy(__utsbuf->machine,kdata.k_machine); + strcpy(__utsbuf->domainname,"(localhost)"); + return 0; +} + \ No newline at end of file diff --git a/src/libc/vfprintf.c b/src/libc/vfprintf.c new file mode 100755 index 00000000..675081b1 --- /dev/null +++ b/src/libc/vfprintf.c @@ -0,0 +1,285 @@ +/* printf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +#include "printf.h" + +#ifdef L_vfprintf + +#ifdef FLOATS +extern void _fnum(double val, char fmt, int prec, char *ptmp); +#endif + +/* + * Output the given field in the manner specified by the arguments. Return + * the number of characters output. + */ +static int prtfld __P((FILE *op, unsigned char *buf, + int ljustf, char sign, char pad, + int width, int preci, int buffer_mode)); + +static int prtfld(op, buf, ljustf, sign, pad, width, preci, buffer_mode) + register FILE *op; + register unsigned char *buf; + int ljustf; + register char sign; + char pad; + register int width; + int preci; + int buffer_mode; +{ + register unsigned char ch; + register int cnt = 0, len = strlen(buf); + + if (*buf == '-') + sign = *buf++; + else if (sign) + len++; + if ((preci != -1) && (len > preci)) /* limit max data width */ + len = preci; + if (width < len) /* flexible field width or width overflow */ + width = len; + /* at this point: width = total field width, len = actual data width + * (including possible sign character) + */ + cnt = width; + width -= len; + while (width || len) { + if (!ljustf && width) { /* left padding */ + if (len && sign && (pad == '0')) + goto showsign; + ch = pad; + --width; + } + else if (len) { + if (sign) { +showsign: ch = sign; /* sign */ + sign = '\0'; + } + else ch = *buf++; /* main field */ + --len; + } + else { + ch = pad; /* right padding */ + --width; + } + putc(ch, op); + if (ch == '\n' && buffer_mode == _IOLBF) + fflush(op); + } + return (cnt); +} + +#if 1 +int vfprintf(op, fmt, ap) /* Nick */ +#else +static int vfprintf(op, fmt, ap) +#endif + FILE *op; + register char *fmt; + register va_list ap; +{ + register int i, ljustf, lval, preci, dpoint, width, radix, cnt = 0; + char pad, sign, hash; + register char *ptmp, *add; + unsigned long val; + char tmp[64]; + int buffer_mode; + + /* This speeds things up a bit for unbuffered */ + buffer_mode = (op->mode & __MODE_BUF); + op->mode &= (~__MODE_BUF); + while (*fmt) { + if (*fmt == '%') { + if (buffer_mode == _IONBF) + fflush(op); + ljustf = 0; /* left justify flag */ + sign = '\0'; /* sign char & status */ + pad = ' '; /* justification padding char */ + width = -1; /* min field width */ + dpoint = 0; /* found decimal point */ + preci = -1; /* max data width */ + radix = 10; /* number base */ + ptmp = tmp; /* pointer to area to print */ + hash = 0; + lval = (sizeof(int) == sizeof(long)); /* long value flaged */ +fmtnxt: for (i = 0, ++fmt; ; ++fmt) { + if (*fmt < '0' || *fmt > '9') + break; + i *= 10; + i += (*fmt - '0'); + if (dpoint) + preci = i; + else if (!i && (pad == ' ')) { + pad = '0'; + goto fmtnxt; + } + else width = i; + } + switch (*fmt) { + case '\0': /* early EOS */ + --fmt; + goto charout; + + case '-': /* left justification */ + ljustf = 1; + goto fmtnxt; + + case ' ': + case '+': /* leading sign flag */ + sign = *fmt; + goto fmtnxt; + + case '#': + hash = 1; + goto fmtnxt; + + case '*': /* parameter width value */ + i = va_arg(ap, int); + if (dpoint) + preci = i; + else if ((width = i) < 0) { + ljustf = 1; + width = -i; + } + goto fmtnxt; + + case '.': /* secondary width field */ + dpoint = 1; + goto fmtnxt; + + case 'l': /* long data */ + lval = 1; + goto fmtnxt; + + case 'h': /* short data */ + lval = 0; + goto fmtnxt; + + case 'd': /* Signed decimal */ + case 'i': + ptmp = ltoa((long) ((lval) ? + va_arg(ap, long) : + va_arg(ap, short)), + tmp, 10); + goto printit; + + case 'b': /* Unsigned binary */ + radix = 2; + goto usproc; + + case 'o': /* Unsigned octal */ + radix = 8; + goto usproc; + + case 'p': /* Pointer */ + lval = (sizeof(char *) == sizeof(long)); + pad = '0'; + width = 5; + preci = 8; + /* fall thru */ + + case 'X': /* Unsigned hexadecimal 'ABC' */ + radix = 16; + goto usproc; + + case 'x': /* Unsigned hexadecimal 'abc' */ + radix = -16; + /* fall thru */ + + case 'u': /* Unsigned decimal */ +usproc: val = lval ? va_arg(ap, unsigned long) : + va_arg(ap, unsigned short); + ptmp = ultoa(val, tmp+4, radix); + add = ""; + if (hash) { + if (radix == 2) + add = "0b"; + else if (radix == 8) { + if (val != 0) + add = "0"; + } + else if (radix == 16) + add = "0x"; + else if (radix == -16) + add = "0X"; + if (*add) { + pad = '\0'; + strcpy(tmp,add); + ptmp = strcat(tmp,ptmp); + } + } + goto printit; + + case '!': /* inline Character */ + if ((i = fmt[1]) != 0) + ++fmt; + goto Chr; + + case 'c': /* Character */ + i = va_arg(ap, int); +Chr: ptmp[0] = i; + ptmp[1] = '\0'; + if (hash) { + pad = *ptmp; + goto chrpad; + } + goto nopad; + + case 's': /* String */ + ptmp = va_arg(ap, char *); +nopad: pad = ' '; +chrpad: sign = '\0'; +printit: cnt += prtfld(op, (unsigned char *)ptmp, + ljustf, sign, pad, width, preci, + buffer_mode); + break; + +#ifdef FLOATS + case 'e': /* float */ + case 'f': + case 'g': + case 'E': + case 'G': + _fnum (va_arg(ap, double), + *fmt, preci, ptmp); + /* double arg; + char fmt; (e/f/g/E/G) + int preci; (width, -1 if no) + char *ptmp; (where to print) + */ + preci = -1; + goto printit; + /* FALLTHROUGH if no floating printf available */ +#endif + default: /* unknown character */ + goto charout; + } + } + else { +charout: putc(*fmt, op); /* normal char out */ + ++cnt; + if (*fmt == '\n' && buffer_mode == _IOLBF) + fflush(op); + } + ++fmt; + } + op->mode |= buffer_mode; + if (buffer_mode == _IONBF) + fflush(op); + if (buffer_mode == _IOLBF) + op->bufwrite = op->bufstart; + return (cnt); +} +#endif + diff --git a/src/libc/vfscanf.c b/src/libc/vfscanf.c new file mode 100755 index 00000000..cd513dbd --- /dev/null +++ b/src/libc/vfscanf.c @@ -0,0 +1,375 @@ +/* scanf.c + */ + +#include "scanf.h" + +#ifdef L_vfscanf +/* #define skip() do{c=getc(fp); if (c<1) goto done;}while(isspace(c)) */ + +#define skip() while(isspace(c)) { if ((c = getc(fp)) <= 0) goto done; } + +#ifdef FLOATS +/* fp scan actions */ +#define F_NADA 0 /* just change state */ +#define F_SIGN 1 /* set sign */ +#define F_ESIGN 2 /* set exponent's sign */ +#define F_INT 3 /* adjust integer part */ +#define F_FRAC 4 /* adjust fraction part */ +#define F_EXP 5 /* adjust exponent part */ +#define F_QUIT 6 + +#define NSTATE 8 +#define FS_INIT 0 /* initial state */ +#define FS_SIGNED 1 /* saw sign */ +#define FS_DIGS 2 /* saw digits, no . */ +#define FS_DOT 3 /* saw ., no digits */ +#define FS_DD 4 /* saw digits and . */ +#define FS_E 5 /* saw 'e' */ +#define FS_ESIGN 6 /* saw exp's sign */ +#define FS_EDIGS 7 /* saw exp's digits */ + +#define FC_DIG 0 +#define FC_DOT 1 +#define FC_E 2 +#define FC_SIGN 3 + +/* given transition,state do what action? */ +int fp_do[][NSTATE] = { + {F_INT, F_INT, F_INT, F_FRAC, F_FRAC, F_EXP, F_EXP, F_EXP}, /* see digit */ + {F_NADA, F_NADA, F_NADA, F_QUIT, F_QUIT, F_QUIT, F_QUIT, F_QUIT}, /* see '.' */ + {F_QUIT, F_QUIT, F_NADA, F_QUIT, F_NADA, F_QUIT, F_QUIT, F_QUIT}, /* see e/E */ + {F_SIGN, F_QUIT, F_QUIT, F_QUIT, F_QUIT, F_ESIGN, F_QUIT, F_QUIT}, /* see sign */ +}; + +/* given transition,state what is new state? */ +int fp_ns[][NSTATE] = { + {FS_DIGS, FS_DIGS, FS_DIGS, FS_DD, FS_DD, FS_EDIGS, FS_EDIGS, FS_EDIGS}, /* see digit */ + {FS_DOT, FS_DOT, FS_DD,}, /* see '.' */ + {0, 0, FS_E, 0, FS_E,}, /* see e/E */ + {FS_SIGNED, 0, 0, 0, 0, FS_ESIGN, 0, 0}, /* see sign */ +}; + +/* which states are valid terminators? */ +int fp_sval[NSTATE] = { + 0, 0, 1, 0, 1, 0, 0, 1 +}; + +double fp_scan(neg, eneg, n, frac, expo, fraclen) +int neg, eneg, fraclen; +long n, frac, expo; +{ + double l; + long exp; + int i; + + l = (double)n; + exp = expo; + if (eneg) exp = -exp; + for (i = 1; i <= fraclen; i++) l *= 10; + l += (double)frac; + exp -= fraclen; + while (exp < 0) { + l /= 10; + exp++; + } + while (exp > 0) { + l *= 10; + exp--; + } + if (neg) return -l; + return l; +} + +#endif + +#if 1 +int vfscanf(fp, fmt, ap) /* Nick */ +#else +static int vfscanf(fp, fmt, ap) +#endif + register FILE *fp; + register char *fmt; + va_list ap; +{ + register long n; + register /*unsigned*/ char *p; + /*unsigned*/ char delim[128], digits[17]; + unsigned char *q; + int store, neg, base, wide1, endnull, rngflag, c2; + register int c, width, lval, cnt = 0; +#ifdef FLOATS + long frac, expo; + int eneg, fraclen, fstate, trans; + double fx, fp_scan(); +#endif + + if (fmt == NULL || *fmt == 0) + return (0); + c = getc(fp); + while (c > 0) { + store = 0; + if (*fmt == '%') { + n = 0; + width = -1; + wide1 = 1; + base = 10; + lval = (sizeof(long) == sizeof(int)); + store = 1; + endnull = 1; + neg = -1; + strcpy(delim, "\011\012\013\014\015 "); + strcpy(digits, "0123456789ABCDEF"); + if (fmt[1] == '*') { + endnull = store = 0; + ++fmt; + } + while (isdigit(*++fmt)) { /* width digit(s) */ + if (width == -1) + width = 0; + wide1 = width = (width * 10) + (*fmt - '0'); + } + --fmt; +fmtnxt: ++fmt; + switch (_tolower(*fmt)) { /* _tolower() is a MACRO! */ + case '*': + endnull = store = 0; + goto fmtnxt; + case 'l': /* long data */ + lval = 1; + goto fmtnxt; + case 'h': /* short data */ + lval = 0; + goto fmtnxt; + + case 'i': /* any-base numeric */ + base = 0; + goto numfmt; + case 'b': /* unsigned binary */ + base = 2; + goto numfmt; + case 'o': /* unsigned octal */ + base = 8; + goto numfmt; + case 'x': /* unsigned hexadecimal */ + base = 16; + goto numfmt; + case 'd': /* SIGNED decimal */ + neg = 0; + /* FALL-THRU */ + case 'u': /* unsigned decimal */ +numfmt: skip(); + if (isupper(*fmt)) + lval = 1; + if (!base) { + base = 10; + neg = 0; + if (c == '%') { + base = 2; + goto skip1; + } + else if (c == '0') { + if ((c = getc(fp)) <= 0) + goto savnum; + if ((c == 'b') || (c == 'B')) { + base = 2; + digits[2] = '\0'; + goto zeroin; + } + if ((c != 'x') && (c != 'X')) { + base = 8; + digits[8] = '\0'; + goto zeroin; + } + base = 16; + goto skip1; + } + } + if ((neg == 0) && + (base == 10) && + ((neg = (c == '-')) != 0 || (c == '+'))) { +skip1: if ((c = getc(fp)) <= 0) + goto done; + } + digits[base] = '\0'; + p = strchr(digits, _toupper(c)); + if ((!c || !p) && width) + goto done; + while (p && width-- && c) { + n = (n * base) + (p - digits); + c = getc(fp); +zeroin: p = strchr(digits, _toupper(c)); + } +savnum: if (store) { + if (neg == 1) + n = -n; + if (lval) + *va_arg(ap, long *) = n; + else *va_arg(ap, short *) = n; + ++cnt; + } + break; +#ifdef FLOATS + case 'e': /* float */ + case 'f': + case 'g': + skip(); + if (isupper(*fmt)) + lval = 1; + fstate = FS_INIT; + neg = 0; + eneg = 0; + n = 0; + frac = 0; + expo = 0; + fraclen = 0; + while (c && width--) { + if (c >= '0' && c <= '9') + trans = FC_DIG; + else if (c == '.') + trans = FC_DOT; + else if (c == '+' || c == '-') + trans = FC_SIGN; + else if (_toupper(c) == 'E') + trans = FC_E; + else goto fdone; + switch (fp_do[trans][fstate]) { + case F_SIGN: + neg = (c == '-'); + break; + case F_ESIGN: + eneg = (c == '-'); + break; + case F_INT: + n *= 10; + n += (c - '0'); + break; + case F_FRAC: + frac *= 10; + frac += (c - '0'); + fraclen++; + break; + case F_EXP: + expo *= 10; + expo += (c - '0'); + break; + case F_QUIT: + goto fdone; + } + fstate = fp_ns[trans][fstate]; + c = getc(fp); + } +fdone: if (!fp_sval[fstate]) + goto done; + if (store) { + fx = fp_scan(neg, eneg, n, frac, expo, fraclen); + if (lval) + *va_arg(ap, double *) = fx; + else *va_arg(ap, float *) = fx; + ++cnt; + } + break; +#endif + case 'c': /* character data */ + width = wide1; + lval = endnull = 0; + delim[0] = '\0'; + goto strproc; + case '[': /* string w/ delimiter set */ + /* get delimiters */ + p = delim; + if (*++fmt == '^') { + fmt++; + lval = 0; + } + else lval = 1; + rngflag = 2; + if ((*fmt == ']') || (*fmt == '-')) { + *p++ = *fmt++; + rngflag = 0; + } + while (*fmt != ']') { + if (*fmt == '\0') + goto done; + switch (rngflag) { + case 1: + c2 = *(p - 2); + if (c2 <= *fmt) { + p -= 2; + while (c2 < *fmt) + *p++ = c2++; + rngflag = 2; + break; + } + /* fall thru intentional */ + case 0: + rngflag = (*fmt == '-'); + break; + case 2: + rngflag = 0; + } + *p++ = *fmt++; + } + *p = '\0'; + goto strproc; + + case 's': /* string data */ + lval = 0; + skip(); +strproc: /* process string */ + p = va_arg(ap, char *); + /* if the 1st char fails, match fails */ + if (width) { + q = ((unsigned char *) + strchr(delim, c)); + if ((c <= 0) || lval == (q == 0)) { + if (endnull) + *p = '\0'; + goto done; + } + } + for (;;) { /* FOREVER */ + if (store) + *p++ = c; + if (((c = getc(fp)) <= 0) || + (--width == 0)) + break; + + q = ((unsigned char *) + strchr(delim, c)); + if (lval == (q == 0)) + break; + } + if (store) { + if (endnull) + *p = '\0'; + ++cnt; + } + break; + case '\0': /* early EOS */ + --fmt; + /* FALL THRU */ + default: + goto cmatch; + } + } + else if (isspace(*fmt)) { /* skip whitespace */ + skip(); + } + else { /* normal match char */ +cmatch: if (c != *fmt) + break; + c = getc(fp); + } + if (!*++fmt) + break; + } +done: /* end of scan */ + if ((c == EOF) && (cnt == 0)) + return (EOF); + if (c != EOF) + ungetc(c, fp); + return (cnt); +} + +#endif + \ No newline at end of file diff --git a/src/libc/vprintf.c b/src/libc/vprintf.c new file mode 100755 index 00000000..c5dc0f68 --- /dev/null +++ b/src/libc/vprintf.c @@ -0,0 +1,25 @@ +/* printf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +#include "printf.h" + +#ifdef L_vprintf +int vprintf(fmt, ap) + char *fmt; + va_list ap; +{ + return vfprintf(stdout, fmt, ap); +} +#endif + diff --git a/src/libc/vscanf.c b/src/libc/vscanf.c new file mode 100755 index 00000000..701d660c --- /dev/null +++ b/src/libc/vscanf.c @@ -0,0 +1,14 @@ +/* scanf.c + */ + +#include "scanf.h" + +#ifdef L_vscanf +int vscanf(fmt, ap) + char *fmt; + va_list ap; +{ + return vfscanf(stdin, fmt, ap); +} +#endif + \ No newline at end of file diff --git a/src/libc/vsprintf.c b/src/libc/vsprintf.c new file mode 100755 index 00000000..d7b7cae1 --- /dev/null +++ b/src/libc/vsprintf.c @@ -0,0 +1,36 @@ +/* printf.c + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * + * Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +#include "printf.h" + +#ifdef L_vsprintf +int vsprintf(sp, fmt, ap) + char *sp; + char *fmt; + va_list ap; +{ + static FILE string[1] = { + { 0, 0, (unsigned char *)-1, 0, (unsigned char *)-1, -1, + _IOFBF | __MODE_WRITE + } + }; + int rv; + + string->bufpos = (unsigned char *)sp; + rv = vfprintf(string, fmt, ap); + *(string->bufpos) = 0; + return rv; +} +#endif + diff --git a/src/libc/vsscanf.c b/src/libc/vsscanf.c new file mode 100755 index 00000000..53952296 --- /dev/null +++ b/src/libc/vsscanf.c @@ -0,0 +1,21 @@ +/* scanf.c + */ + +#include "scanf.h" + +#ifdef L_vsscanf +int vsscanf(sp, fmt, ap) + char *sp; + char *fmt; + va_list ap; +{ + static FILE string[1] = { + { 0, (unsigned char *)-1, 0, 0, (unsigned char *)-1, -1, + _IOFBF | __MODE_READ + } + }; + string->bufpos = (unsigned char *)sp; + return vfscanf(string, fmt, ap); +} +#endif + \ No newline at end of file diff --git a/src/libc/x.bat b/src/libc/x.bat new file mode 100755 index 00000000..fda184d3 --- /dev/null +++ b/src/libc/x.bat @@ -0,0 +1,12 @@ +md build-l +cd build-l +copy ..\build-l.ban n.bat +call n +cd .. + +md build-b +cd build-b +copy ..\build-b.ban n.bat +call n +cd .. + diff --git a/src/libc/xitoa.c b/src/libc/xitoa.c new file mode 100755 index 00000000..63a5ae52 --- /dev/null +++ b/src/libc/xitoa.c @@ -0,0 +1,14 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/*********************** xitoa.c ***************************/ +#ifdef L_xitoa +char *_itoa(i) + int i; +{ + return ltostr((long)i,10); +} +#endif + \ No newline at end of file diff --git a/src/libc/xltoa.c b/src/libc/xltoa.c new file mode 100755 index 00000000..64e98bde --- /dev/null +++ b/src/libc/xltoa.c @@ -0,0 +1,20 @@ +/* numeric/string conversions package + */ + +#include "cvt.h" + +/*************************** xltoa.c ***************************/ +#ifdef L_xltoa +char *_ultoa(val) + unsigned long val; +{ + return ultostr(val,10); +} + +char *_ltoa(val) + long val; +{ + return ltostr(val,10); +} +#endif + \ No newline at end of file diff --git a/src/libiar/BANKCALL.asm b/src/libiar/BANKCALL.asm new file mode 100755 index 00000000..76693674 --- /dev/null +++ b/src/libiar/BANKCALL.asm @@ -0,0 +1,18 @@ +; BANKCALL.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BANK_CALL_L08 + public ?BANK_CALL_L08 +?BANK_CALL_L08 equ 00000028h + extern ?BANK_CALL_DIRECT_L08 + t_org_abs S86=0000 00000000 + t_org_abs S86=0000 00000028 + defb 0C3h + defw LWRD ?BANK_CALL_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BANKCALLDIRECT.asm b/src/libiar/BANKCALLDIRECT.asm new file mode 100755 index 00000000..05a84ebd --- /dev/null +++ b/src/libiar/BANKCALLDIRECT.asm @@ -0,0 +1,43 @@ +; BANKCALLDIRECT.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BANK_CALL_DIRECT_L08 + + .if 1 +BBR equ 39h + .endif + + rseg RCODE + + public ?BANK_CALL_DIRECT_L08 + +?BANK_CALL_DIRECT_L08: + .if 1 ; virtual memory + push hl + ld h,80h + ld l,a ; hl -> 8000h + entry a value + ld a,(hl) ; translate bbr via virt memory table +; pop hl +; +; or a ; check for unused virt memory pages +; ret z ; just to be extra paranoid + .endif + + .if 1 +; push hl + in0 h,(BBR) + out0 (BBR),a + ex (sp),hl + jp (hl) + .else + defb 0E5h,0EDh,020h,039h,0EDh,039h,039h + defb 0E3h,0E9h + .endif + + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BANKCALLDIRECTEXAF.asm b/src/libiar/BANKCALLDIRECTEXAF.asm new file mode 100755 index 00000000..3928961e --- /dev/null +++ b/src/libiar/BANKCALLDIRECTEXAF.asm @@ -0,0 +1,17 @@ +; BANKCALLDIRECTEXAF.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BANK_CALL_DIRECT_EXAF_L08 + rseg RCODE +rcode_base: + public ?BANK_CALL_DIRECT_EXAF_L08 +?BANK_CALL_DIRECT_EXAF_L08 equ rcode_base+00000000h + defb 008h,0EDh,038h,039h,0F5h,008h,0EDh + defb 039h,039h,0E9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BANKCALLEXAF.asm b/src/libiar/BANKCALLEXAF.asm new file mode 100755 index 00000000..e7fdf4be --- /dev/null +++ b/src/libiar/BANKCALLEXAF.asm @@ -0,0 +1,18 @@ +; BANKCALLEXAF.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BANK_CALL_EXAF_L08 + public ?BANK_CALL_EXAF_L08 +?BANK_CALL_EXAF_L08 equ 00000028h + extern ?BANK_CALL_DIRECT_EXAF_L08 + t_org_abs S86=0000 00000000 + t_org_abs S86=0000 00000028 + defb 0C3h + defw LWRD ?BANK_CALL_DIRECT_EXAF_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BANKLEAVE.asm b/src/libiar/BANKLEAVE.asm new file mode 100755 index 00000000..fbf8c75a --- /dev/null +++ b/src/libiar/BANKLEAVE.asm @@ -0,0 +1,18 @@ +; BANKLEAVE.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BANK_LEAVE_L08 + public ?BANK_LEAVE_L08 +?BANK_LEAVE_L08 equ 00000018h + extern ?BANK_LEAVE_DIRECT_L08 + t_org_abs S86=0000 00000000 + t_org_abs S86=0000 00000018 + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BANKLEAVE32.asm b/src/libiar/BANKLEAVE32.asm new file mode 100755 index 00000000..966a330f --- /dev/null +++ b/src/libiar/BANKLEAVE32.asm @@ -0,0 +1,17 @@ +; BANKLEAVE32.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BANK_LEAVE_32_L08 + rseg RCODE +rcode_base: + public ?BANK_LEAVE_32_L08 +?BANK_LEAVE_32_L08 equ rcode_base+00000000h + defb 0DDh,0F9h,0DDh,0E1h,0D1h,033h,033h + defb 0F1h,0EDh,039h,039h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BANKLEAVEDIRECT.asm b/src/libiar/BANKLEAVEDIRECT.asm new file mode 100755 index 00000000..e519f762 --- /dev/null +++ b/src/libiar/BANKLEAVEDIRECT.asm @@ -0,0 +1,41 @@ +; BANKLEAVEDIRECT.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BANK_LEAVE_DIRECT_L08 + + .if 1 +BBR equ 39h + .endif + + rseg RCODE + + public ?BANK_LEAVE_DIRECT_L08 + +?BANK_LEAVE_DIRECT_L08: + .if 1 + ld sp,ix + pop ix + pop de + pop bc + .else + defb 0DDh,0F9h,0DDh,0E1h,0D1h,0C1h + .endif + + public ?BANK_FAST_LEAVE_L08 + +?BANK_FAST_LEAVE_L08: + .if 1 + pop af + out0 (BBR),a + ret + .else + defb 0F1h,0EDh,039h,039h,0C9h + .endif + + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFCANDASG.asm b/src/libiar/BFCANDASG.asm new file mode 100755 index 00000000..fe64afc3 --- /dev/null +++ b/src/libiar/BFCANDASG.asm @@ -0,0 +1,22 @@ +; BFCANDASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_C_ANDASG_L10 + rseg RCODE +rcode_base: + public ?BF_C_ANDASG_L10 +?BF_C_ANDASG_L10 equ rcode_base+00000000h + extern ?BF_C_SHIFT_UP_L10 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,0CDh + defw LWRD ?BF_C_SHIFT_UP_L10 + defb 047h,07Eh,0A0h,0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFCLSHASG.asm b/src/libiar/BFCLSHASG.asm new file mode 100755 index 00000000..a13f2107 --- /dev/null +++ b/src/libiar/BFCLSHASG.asm @@ -0,0 +1,22 @@ +; BFCLSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_C_LSHASG_L10 + rseg RCODE +rcode_base: + public ?BF_C_LSHASG_L10 +?BF_C_LSHASG_L10 equ rcode_base+00000000h + extern ?C_LSH_L01 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,07Eh,0A2h,0CDh + defw LWRD ?C_LSH_L01 + defb 0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFCMULASG.asm b/src/libiar/BFCMULASG.asm new file mode 100755 index 00000000..58059dfd --- /dev/null +++ b/src/libiar/BFCMULASG.asm @@ -0,0 +1,22 @@ +; BFCMULASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_C_MULASG_L10 + rseg RCODE +rcode_base: + public ?BF_C_MULASG_L10 +?BF_C_MULASG_L10 equ rcode_base+00000000h + extern ?C_MUL_L01 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,047h,07Eh,0A2h,0CDh + defw LWRD ?C_MUL_L01 + defb 0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFCORASG.asm b/src/libiar/BFCORASG.asm new file mode 100755 index 00000000..744565e6 --- /dev/null +++ b/src/libiar/BFCORASG.asm @@ -0,0 +1,22 @@ +; BFCORASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_C_ORASG_L10 + rseg RCODE +rcode_base: + public ?BF_C_ORASG_L10 +?BF_C_ORASG_L10 equ rcode_base+00000000h + extern ?BF_C_SHIFT_UP_L10 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,0CDh + defw LWRD ?BF_C_SHIFT_UP_L10 + defb 047h,07Eh,0B0h,0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFCRETVAL.asm b/src/libiar/BFCRETVAL.asm new file mode 100755 index 00000000..835eb31f --- /dev/null +++ b/src/libiar/BFCRETVAL.asm @@ -0,0 +1,31 @@ +; BFCRETVAL.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_C_RET_VAL_L10 + rseg RCODE +rcode_base: + public ?BF_C_RET_VAL_L10 +?BF_C_RET_VAL_L10 equ rcode_base+00000000h + extern ?BF_SC_EXT_L10 + extern ?SC_RSH_L01 + extern ?UC_RSH_L01 + defb 0A2h,04Fh,07Ah,02Fh,0A6h,0B1h,077h + defb 0CBh,07Bh,028h,01Ch,0CBh,073h,0C4h + defw LWRD ?BF_SC_EXT_L10 + defb 07Bh,0E6h,007h,047h,079h,0CBh,073h + defb 028h,007h,0CDh + defw LWRD ?SC_RSH_L01 + defb 0D1h,0C3h + defw rcode_base+28h ; t_push_rel (0000) 00000028 + defb 0CDh + defw LWRD ?UC_RSH_L01 + defb 0D1h,0C3h + defw rcode_base+28h ; t_push_rel (0000) 00000028 + defb 0F1h,0D1h,0C1h,0EBh,0E3h,0EBh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFCSHIFTUP.asm b/src/libiar/BFCSHIFTUP.asm new file mode 100755 index 00000000..b46fd027 --- /dev/null +++ b/src/libiar/BFCSHIFTUP.asm @@ -0,0 +1,18 @@ +; BFCSHIFTUP.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_C_SHIFT_UP_L10 + rseg RCODE +rcode_base: + public ?BF_C_SHIFT_UP_L10 +?BF_C_SHIFT_UP_L10 equ rcode_base+00000000h + extern ?C_LSH_L01 + defb 04Fh,07Bh,0E6h,007h,047h,079h,0C3h + defw LWRD ?C_LSH_L01 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFCXORASG.asm b/src/libiar/BFCXORASG.asm new file mode 100755 index 00000000..1f1ef0ca --- /dev/null +++ b/src/libiar/BFCXORASG.asm @@ -0,0 +1,22 @@ +; BFCXORASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_C_XORASG_L10 + rseg RCODE +rcode_base: + public ?BF_C_XORASG_L10 +?BF_C_XORASG_L10 equ rcode_base+00000000h + extern ?BF_C_SHIFT_UP_L10 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,0CDh + defw LWRD ?BF_C_SHIFT_UP_L10 + defb 047h,07Eh,0A8h,0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFMASKEDLD.asm b/src/libiar/BFMASKEDLD.asm new file mode 100755 index 00000000..c8b91bb8 --- /dev/null +++ b/src/libiar/BFMASKEDLD.asm @@ -0,0 +1,17 @@ +; BFMASKEDLD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_MASKED_LD_L10 + rseg RCODE +rcode_base: + public ?BF_MASKED_LD_L10 +?BF_MASKED_LD_L10 equ rcode_base+00000000h + defb 07Eh,0DDh,0A6h,001h,05Fh,023h,07Eh + defb 0DDh,0A6h,002h,057h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFMASKEDST.asm b/src/libiar/BFMASKEDST.asm new file mode 100755 index 00000000..85adac2c --- /dev/null +++ b/src/libiar/BFMASKEDST.asm @@ -0,0 +1,19 @@ +; BFMASKEDST.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_MASKED_ST_L10 + rseg RCODE +rcode_base: + public ?BF_MASKED_ST_L10 +?BF_MASKED_ST_L10 equ rcode_base+00000000h + defb 0DDh,04Eh,001h,0DDh,046h,002h,07Bh + defb 0A1h,05Fh,07Ah,0A0h,057h,078h,02Fh + defb 0A6h,0B2h,077h,02Bh,079h,02Fh,0A6h + defb 0B3h,077h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSADDASG.asm b/src/libiar/BFSADDASG.asm new file mode 100755 index 00000000..d3adfbef --- /dev/null +++ b/src/libiar/BFSADDASG.asm @@ -0,0 +1,24 @@ +; BFSADDASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_ADDASG_L10 + rseg RCODE +rcode_base: + public ?BF_S_ADDASG_L10 +?BF_S_ADDASG_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,050h,059h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 07Eh,083h,05Fh,023h,07Eh,08Ah,057h + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSANDASG.asm b/src/libiar/BFSANDASG.asm new file mode 100755 index 00000000..06758107 --- /dev/null +++ b/src/libiar/BFSANDASG.asm @@ -0,0 +1,24 @@ +; BFSANDASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_ANDASG_L10 + rseg RCODE +rcode_base: + public ?BF_S_ANDASG_L10 +?BF_S_ANDASG_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,050h,059h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 07Eh,0A3h,05Fh,023h,07Eh,0A2h,057h + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSCDIVASG.asm b/src/libiar/BFSCDIVASG.asm new file mode 100755 index 00000000..2abc5dc8 --- /dev/null +++ b/src/libiar/BFSCDIVASG.asm @@ -0,0 +1,28 @@ +; BFSCDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SC_DIVASG_L10 + rseg RCODE +rcode_base: + public ?BF_SC_DIVASG_L10 +?BF_SC_DIVASG_L10 equ rcode_base+00000000h + extern ?BF_SC_LD_SHIFT_DOWN_L10 + extern ?SC_DIV_L01 + extern ?BF_C_SHIFT_UP_L10 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,0CDh + defw LWRD ?BF_SC_LD_SHIFT_DOWN_L10 + defb 0CDh + defw LWRD ?SC_DIV_L01 + defb 0CDh + defw LWRD ?BF_C_SHIFT_UP_L10 + defb 0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSCEXT.asm b/src/libiar/BFSCEXT.asm new file mode 100755 index 00000000..eeaf9f5a --- /dev/null +++ b/src/libiar/BFSCEXT.asm @@ -0,0 +1,18 @@ +; BFSCEXT.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SC_EXT_L10 + rseg RCODE +rcode_base: + public ?BF_SC_EXT_L10 +?BF_SC_EXT_L10 equ rcode_base+00000000h + defb 006h,080h,07Ah,0A0h,020h,004h,0CBh + defb 028h,018h,0F8h,079h,0A0h,0C8h,079h + defb 0B0h,04Fh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSCLDSHIFTDOWN.asm b/src/libiar/BFSCLDSHIFTDOWN.asm new file mode 100755 index 00000000..0fa8da56 --- /dev/null +++ b/src/libiar/BFSCLDSHIFTDOWN.asm @@ -0,0 +1,22 @@ +; BFSCLDSHIFTDOWN.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SC_LD_SHIFT_DOWN_L10 + rseg RCODE +rcode_base: + public ?BF_SC_LD_SHIFT_DOWN_L10 +?BF_SC_LD_SHIFT_DOWN_L10 equ rcode_base+00000000h + extern ?BF_SC_EXT_L10 + extern ?SC_RSH_L01 + defb 047h,0C5h,07Eh,0A2h,04Fh,0CDh + defw LWRD ?BF_SC_EXT_L10 + defb 07Bh,0E6h,007h,047h,079h,0CDh + defw LWRD ?SC_RSH_L01 + defb 0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSCMODASG.asm b/src/libiar/BFSCMODASG.asm new file mode 100755 index 00000000..d0cb848d --- /dev/null +++ b/src/libiar/BFSCMODASG.asm @@ -0,0 +1,28 @@ +; BFSCMODASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SC_MODASG_L10 + rseg RCODE +rcode_base: + public ?BF_SC_MODASG_L10 +?BF_SC_MODASG_L10 equ rcode_base+00000000h + extern ?BF_SC_LD_SHIFT_DOWN_L10 + extern ?SC_MOD_L01 + extern ?BF_C_SHIFT_UP_L10 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,0CDh + defw LWRD ?BF_SC_LD_SHIFT_DOWN_L10 + defb 0CDh + defw LWRD ?SC_MOD_L01 + defb 0CDh + defw LWRD ?BF_C_SHIFT_UP_L10 + defb 0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSCRSHASG.asm b/src/libiar/BFSCRSHASG.asm new file mode 100755 index 00000000..4ed8f93f --- /dev/null +++ b/src/libiar/BFSCRSHASG.asm @@ -0,0 +1,26 @@ +; BFSCRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SC_RSHASG_L10 + rseg RCODE +rcode_base: + public ?BF_SC_RSHASG_L10 +?BF_SC_RSHASG_L10 equ rcode_base+00000000h + extern ?BF_SC_EXT_L10 + extern ?SC_RSH_L01 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,0C5h,07Eh,0A2h,04Fh + defb 0CDh + defw LWRD ?BF_SC_EXT_L10 + defb 0C1h,0CDh + defw LWRD ?SC_RSH_L01 + defb 0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSLSHASG.asm b/src/libiar/BFSLSHASG.asm new file mode 100755 index 00000000..6d89383f --- /dev/null +++ b/src/libiar/BFSLSHASG.asm @@ -0,0 +1,26 @@ +; BFSLSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_LSHASG_L10 + rseg RCODE +rcode_base: + public ?BF_S_LSHASG_L10 +?BF_S_LSHASG_L10 equ rcode_base+00000000h + extern ?BF_MASKED_LD_L10 + extern ?S_LSH_L02 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,0CDh + defw LWRD ?BF_MASKED_LD_L10 + defb 0CDh + defw LWRD ?S_LSH_L02 + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSMULASG.asm b/src/libiar/BFSMULASG.asm new file mode 100755 index 00000000..17013fbc --- /dev/null +++ b/src/libiar/BFSMULASG.asm @@ -0,0 +1,24 @@ +; BFSMULASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_MULASG_L10 + rseg RCODE +rcode_base: + public ?BF_S_MULASG_L10 +?BF_S_MULASG_L10 equ rcode_base+00000000h + extern ?S_MUL_L02 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,07Eh,0DDh,0A6h,001h,05Fh,023h + defb 07Eh,0DDh,0A6h,002h,057h,0CDh + defw LWRD ?S_MUL_L02 + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSNEGASG.asm b/src/libiar/BFSNEGASG.asm new file mode 100755 index 00000000..725f3189 --- /dev/null +++ b/src/libiar/BFSNEGASG.asm @@ -0,0 +1,24 @@ +; BFSNEGASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_NEGASG_L10 + rseg RCODE +rcode_base: + public ?BF_S_NEGASG_L10 +?BF_S_NEGASG_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,011h,001h,000h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 07Eh,02Fh,083h,05Fh,023h,07Eh,02Fh + defb 08Ah,057h,0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSORASG.asm b/src/libiar/BFSORASG.asm new file mode 100755 index 00000000..31060124 --- /dev/null +++ b/src/libiar/BFSORASG.asm @@ -0,0 +1,24 @@ +; BFSORASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_ORASG_L10 + rseg RCODE +rcode_base: + public ?BF_S_ORASG_L10 +?BF_S_ORASG_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,050h,059h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 07Eh,0B3h,05Fh,023h,07Eh,0B2h,057h + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSPOSTDEC.asm b/src/libiar/BFSPOSTDEC.asm new file mode 100755 index 00000000..06b63eed --- /dev/null +++ b/src/libiar/BFSPOSTDEC.asm @@ -0,0 +1,24 @@ +; BFSPOSTDEC.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_POST_DEC_L10 + rseg RCODE +rcode_base: + public ?BF_S_POST_DEC_L10 +?BF_S_POST_DEC_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL2_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,011h,001h,000h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 04Eh,023h,046h,0C5h,079h,093h,05Fh + defb 078h,09Ah,057h,0C3h + defw LWRD ?BF_S_RET_VAL2_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSPOSTINC.asm b/src/libiar/BFSPOSTINC.asm new file mode 100755 index 00000000..ce4f824b --- /dev/null +++ b/src/libiar/BFSPOSTINC.asm @@ -0,0 +1,24 @@ +; BFSPOSTINC.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_POST_INC_L10 + rseg RCODE +rcode_base: + public ?BF_S_POST_INC_L10 +?BF_S_POST_INC_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL2_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,011h,001h,000h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 04Eh,023h,046h,0C5h,079h,083h,05Fh + defb 078h,08Ah,057h,0C3h + defw LWRD ?BF_S_RET_VAL2_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSPREDEC.asm b/src/libiar/BFSPREDEC.asm new file mode 100755 index 00000000..1ee854a7 --- /dev/null +++ b/src/libiar/BFSPREDEC.asm @@ -0,0 +1,24 @@ +; BFSPREDEC.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_PRE_DEC_L10 + rseg RCODE +rcode_base: + public ?BF_S_PRE_DEC_L10 +?BF_S_PRE_DEC_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,011h,001h,000h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 07Eh,093h,05Fh,023h,07Eh,09Ah,057h + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSPREINC.asm b/src/libiar/BFSPREINC.asm new file mode 100755 index 00000000..03ab13ba --- /dev/null +++ b/src/libiar/BFSPREINC.asm @@ -0,0 +1,24 @@ +; BFSPREINC.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_PRE_INC_L10 + rseg RCODE +rcode_base: + public ?BF_S_PRE_INC_L10 +?BF_S_PRE_INC_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,011h,001h,000h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 07Eh,083h,05Fh,023h,07Eh,08Ah,057h + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSRETVAL.asm b/src/libiar/BFSRETVAL.asm new file mode 100755 index 00000000..a79e3518 --- /dev/null +++ b/src/libiar/BFSRETVAL.asm @@ -0,0 +1,40 @@ +; BFSRETVAL.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_RET_VAL_L10 + rseg RCODE +rcode_base: + public ?BF_S_RET_VAL_L10 +?BF_S_RET_VAL_L10 equ rcode_base+0000000Ch + public ?BF_S_RET_VAL2_L10 +?BF_S_RET_VAL2_L10 equ rcode_base+00000000h + extern ?BF_MASKED_ST_L10 + extern ?BF_SS_EXT_L10 + extern ?SS_RSH_L02 + extern ?US_RSH_L02 + defb 0CDh + defw LWRD ?BF_MASKED_ST_L10 + defb 0D1h,07Bh,0A1h,05Fh,07Ah,0A0h,057h + defb 018h,003h,0CDh + defw LWRD ?BF_MASKED_ST_L10 + defb 0DDh,04Eh,000h,0CBh,079h,028h,01Dh + defb 079h,0E6h,00Fh,047h,0CBh,071h,028h + defb 00Ch,0CDh + defw LWRD ?BF_SS_EXT_L10 + defb 0CDh + defw LWRD ?SS_RSH_L02 + defb 042h,04Bh,0E1h,0C3h + defw rcode_base+34h ; t_push_rel (0000) 00000034 + defb 0CDh + defw LWRD ?US_RSH_L02 + defb 042h,04Bh,0E1h,0C3h + defw rcode_base+34h ; t_push_rel (0000) 00000034 + defb 0C1h,0F1h,0E1h,0D1h,0DDh,0E1h,0EBh + defb 0E3h,0EBh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSSDIVASG.asm b/src/libiar/BFSSDIVASG.asm new file mode 100755 index 00000000..77091cdd --- /dev/null +++ b/src/libiar/BFSSDIVASG.asm @@ -0,0 +1,29 @@ +; BFSSDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SS_DIVASG_L10 + rseg RCODE +rcode_base: + public ?BF_SS_DIVASG_L10 +?BF_SS_DIVASG_L10 equ rcode_base+00000000h + extern ?BF_SS_LD_SHIFT_DOWN_L10 + extern ?SS_DIV_L02 + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,0CDh + defw LWRD ?BF_SS_LD_SHIFT_DOWN_L10 + defb 0CDh + defw LWRD ?SS_DIV_L02 + defb 0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSSEXT.asm b/src/libiar/BFSSEXT.asm new file mode 100755 index 00000000..93c672aa --- /dev/null +++ b/src/libiar/BFSSEXT.asm @@ -0,0 +1,22 @@ +; BFSSEXT.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SS_EXT_L10 + rseg RCODE +rcode_base: + public ?BF_SS_EXT_L10 +?BF_SS_EXT_L10 equ rcode_base+00000000h + defb 0E5h,0C5h,0DDh,06Eh,001h,0DDh,066h + defb 002h,006h,080h,00Eh,000h,07Ch,0A0h + defb 020h,00Ah,07Dh,0A1h,020h,006h,0CBh + defb 028h,0CBh,019h,018h,0F2h,07Ah,0A4h + defb 0A0h,020h,008h,07Bh,0A5h,0A1h,028h + defb 006h,07Bh,0B1h,05Fh,07Ah,0B0h,057h + defb 0C1h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSSHIFTUP.asm b/src/libiar/BFSSHIFTUP.asm new file mode 100755 index 00000000..b513ea25 --- /dev/null +++ b/src/libiar/BFSSHIFTUP.asm @@ -0,0 +1,18 @@ +; BFSSHIFTUP.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_SHIFT_UP_L10 + rseg RCODE +rcode_base: + public ?BF_S_SHIFT_UP_L10 +?BF_S_SHIFT_UP_L10 equ rcode_base+00000000h + extern ?S_LSH_L02 + defb 0DDh,07Eh,000h,0E6h,00Fh,047h,0C3h + defw LWRD ?S_LSH_L02 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSSLDSHIFTDOWN.asm b/src/libiar/BFSSLDSHIFTDOWN.asm new file mode 100755 index 00000000..0ea7a5d2 --- /dev/null +++ b/src/libiar/BFSSLDSHIFTDOWN.asm @@ -0,0 +1,25 @@ +; BFSSLDSHIFTDOWN.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SS_LD_SHIFT_DOWN_L10 + rseg RCODE +rcode_base: + public ?BF_SS_LD_SHIFT_DOWN_L10 +?BF_SS_LD_SHIFT_DOWN_L10 equ rcode_base+00000000h + extern ?BF_MASKED_LD_L10 + extern ?BF_SS_EXT_L10 + extern ?SS_RSH_L02 + defb 0C5h,0CDh + defw LWRD ?BF_MASKED_LD_L10 + defb 0CDh + defw LWRD ?BF_SS_EXT_L10 + defb 0DDh,07Eh,000h,0E6h,00Fh,047h,0CDh + defw LWRD ?SS_RSH_L02 + defb 0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSSMODASG.asm b/src/libiar/BFSSMODASG.asm new file mode 100755 index 00000000..e067701a --- /dev/null +++ b/src/libiar/BFSSMODASG.asm @@ -0,0 +1,29 @@ +; BFSSMODASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SS_MODASG_L10 + rseg RCODE +rcode_base: + public ?BF_SS_MODASG_L10 +?BF_SS_MODASG_L10 equ rcode_base+00000000h + extern ?BF_SS_LD_SHIFT_DOWN_L10 + extern ?SS_MOD_L02 + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,0CDh + defw LWRD ?BF_SS_LD_SHIFT_DOWN_L10 + defb 0CDh + defw LWRD ?SS_MOD_L02 + defb 0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSSRSHASG.asm b/src/libiar/BFSSRSHASG.asm new file mode 100755 index 00000000..522e5dbd --- /dev/null +++ b/src/libiar/BFSSRSHASG.asm @@ -0,0 +1,29 @@ +; BFSSRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_SS_RSHASG_L10 + rseg RCODE +rcode_base: + public ?BF_SS_RSHASG_L10 +?BF_SS_RSHASG_L10 equ rcode_base+00000000h + extern ?BF_MASKED_LD_L10 + extern ?BF_SS_EXT_L10 + extern ?SS_RSH_L02 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,0CDh + defw LWRD ?BF_MASKED_LD_L10 + defb 0CDh + defw LWRD ?BF_SS_EXT_L10 + defb 0CDh + defw LWRD ?SS_RSH_L02 + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSSUBASG.asm b/src/libiar/BFSSUBASG.asm new file mode 100755 index 00000000..be1216af --- /dev/null +++ b/src/libiar/BFSSUBASG.asm @@ -0,0 +1,24 @@ +; BFSSUBASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_SUBASG_L10 + rseg RCODE +rcode_base: + public ?BF_S_SUBASG_L10 +?BF_S_SUBASG_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,050h,059h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 07Eh,093h,05Fh,023h,07Eh,09Ah,057h + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFSXORASG.asm b/src/libiar/BFSXORASG.asm new file mode 100755 index 00000000..85db9b58 --- /dev/null +++ b/src/libiar/BFSXORASG.asm @@ -0,0 +1,24 @@ +; BFSXORASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_S_XORASG_L10 + rseg RCODE +rcode_base: + public ?BF_S_XORASG_L10 +?BF_S_XORASG_L10 equ rcode_base+00000000h + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,050h,059h,0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 07Eh,0ABh,05Fh,023h,07Eh,0AAh,057h + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFUCDIVASG.asm b/src/libiar/BFUCDIVASG.asm new file mode 100755 index 00000000..2957484d --- /dev/null +++ b/src/libiar/BFUCDIVASG.asm @@ -0,0 +1,28 @@ +; BFUCDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_UC_DIVASG_L10 + rseg RCODE +rcode_base: + public ?BF_UC_DIVASG_L10 +?BF_UC_DIVASG_L10 equ rcode_base+00000000h + extern ?BF_UC_LD_SHIFT_DOWN_L10 + extern ?UC_DIV_L01 + extern ?BF_C_SHIFT_UP_L10 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,0CDh + defw LWRD ?BF_UC_LD_SHIFT_DOWN_L10 + defb 0CDh + defw LWRD ?UC_DIV_L01 + defb 0CDh + defw LWRD ?BF_C_SHIFT_UP_L10 + defb 0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFUCLDSHIFTDOWN.asm b/src/libiar/BFUCLDSHIFTDOWN.asm new file mode 100755 index 00000000..6c444df0 --- /dev/null +++ b/src/libiar/BFUCLDSHIFTDOWN.asm @@ -0,0 +1,20 @@ +; BFUCLDSHIFTDOWN.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_UC_LD_SHIFT_DOWN_L10 + rseg RCODE +rcode_base: + public ?BF_UC_LD_SHIFT_DOWN_L10 +?BF_UC_LD_SHIFT_DOWN_L10 equ rcode_base+00000000h + extern ?UC_RSH_L01 + defb 047h,0C5h,07Eh,0A2h,04Fh,07Bh,0E6h + defb 007h,047h,079h,0CDh + defw LWRD ?UC_RSH_L01 + defb 0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFUCMODASG.asm b/src/libiar/BFUCMODASG.asm new file mode 100755 index 00000000..d4834555 --- /dev/null +++ b/src/libiar/BFUCMODASG.asm @@ -0,0 +1,28 @@ +; BFUCMODASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_UC_MODASG_L10 + rseg RCODE +rcode_base: + public ?BF_UC_MODASG_L10 +?BF_UC_MODASG_L10 equ rcode_base+00000000h + extern ?BF_UC_LD_SHIFT_DOWN_L10 + extern ?UC_MOD_L01 + extern ?BF_C_SHIFT_UP_L10 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,0CDh + defw LWRD ?BF_UC_LD_SHIFT_DOWN_L10 + defb 0CDh + defw LWRD ?UC_MOD_L01 + defb 0CDh + defw LWRD ?BF_C_SHIFT_UP_L10 + defb 0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFUCRSHASG.asm b/src/libiar/BFUCRSHASG.asm new file mode 100755 index 00000000..09de5522 --- /dev/null +++ b/src/libiar/BFUCRSHASG.asm @@ -0,0 +1,22 @@ +; BFUCRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_UC_RSHASG_L10 + rseg RCODE +rcode_base: + public ?BF_UC_RSHASG_L10 +?BF_UC_RSHASG_L10 equ rcode_base+00000000h + extern ?UC_RSH_L01 + extern ?BF_C_RET_VAL_L10 + defb 0EBh,0E3h,0C5h,0D5h,05Eh,023h,056h + defb 023h,0E3h,0F5h,07Eh,0A2h,0CDh + defw LWRD ?UC_RSH_L01 + defb 0C3h + defw LWRD ?BF_C_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFUSDIVASG.asm b/src/libiar/BFUSDIVASG.asm new file mode 100755 index 00000000..0246f8e7 --- /dev/null +++ b/src/libiar/BFUSDIVASG.asm @@ -0,0 +1,29 @@ +; BFUSDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_US_DIVASG_L10 + rseg RCODE +rcode_base: + public ?BF_US_DIVASG_L10 +?BF_US_DIVASG_L10 equ rcode_base+00000000h + extern ?BF_US_LD_SHIFT_DOWN_L10 + extern ?US_DIV_L02 + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,0CDh + defw LWRD ?BF_US_LD_SHIFT_DOWN_L10 + defb 0CDh + defw LWRD ?US_DIV_L02 + defb 0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFUSLDSHIFTDOWN.asm b/src/libiar/BFUSLDSHIFTDOWN.asm new file mode 100755 index 00000000..54fade43 --- /dev/null +++ b/src/libiar/BFUSLDSHIFTDOWN.asm @@ -0,0 +1,22 @@ +; BFUSLDSHIFTDOWN.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_US_LD_SHIFT_DOWN_L10 + rseg RCODE +rcode_base: + public ?BF_US_LD_SHIFT_DOWN_L10 +?BF_US_LD_SHIFT_DOWN_L10 equ rcode_base+00000000h + extern ?BF_MASKED_LD_L10 + extern ?US_RSH_L02 + defb 0C5h,0CDh + defw LWRD ?BF_MASKED_LD_L10 + defb 0DDh,07Eh,000h,0E6h,00Fh,047h,0CDh + defw LWRD ?US_RSH_L02 + defb 0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFUSMODASG.asm b/src/libiar/BFUSMODASG.asm new file mode 100755 index 00000000..8dd625ee --- /dev/null +++ b/src/libiar/BFUSMODASG.asm @@ -0,0 +1,29 @@ +; BFUSMODASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_US_MODASG_L10 + rseg RCODE +rcode_base: + public ?BF_US_MODASG_L10 +?BF_US_MODASG_L10 equ rcode_base+00000000h + extern ?BF_US_LD_SHIFT_DOWN_L10 + extern ?US_MOD_L02 + extern ?BF_S_SHIFT_UP_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,0CDh + defw LWRD ?BF_US_LD_SHIFT_DOWN_L10 + defb 0CDh + defw LWRD ?US_MOD_L02 + defb 0CDh + defw LWRD ?BF_S_SHIFT_UP_L10 + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/BFUSRSHASG.asm b/src/libiar/BFUSRSHASG.asm new file mode 100755 index 00000000..42326744 --- /dev/null +++ b/src/libiar/BFUSRSHASG.asm @@ -0,0 +1,26 @@ +; BFUSRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?BF_US_RSHASG_L10 + rseg RCODE +rcode_base: + public ?BF_US_RSHASG_L10 +?BF_US_RSHASG_L10 equ rcode_base+00000000h + extern ?US_RSH_L02 + extern ?BF_MASKED_LD_L10 + extern ?BF_S_RET_VAL_L10 + defb 0EBh,0E3h,0DDh,0E5h,0D5h,0E5h,0DDh + defb 0E1h,023h,023h,023h,0E3h,0E5h,0F5h + defb 0C5h,0CDh + defw LWRD ?BF_MASKED_LD_L10 + defb 0CDh + defw LWRD ?US_RSH_L02 + defb 0C3h + defw LWRD ?BF_S_RET_VAL_L10 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/CALLIND.asm b/src/libiar/CALLIND.asm new file mode 100755 index 00000000..ae805f7a --- /dev/null +++ b/src/libiar/CALLIND.asm @@ -0,0 +1,16 @@ +; CALLIND.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?CALL_IND_L09 + rseg RCODE +rcode_base: + public ?CALL_IND_L09 +?CALL_IND_L09 equ rcode_base+00000000h + defb 0E9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/CDIVMOD.asm b/src/libiar/CDIVMOD.asm new file mode 100755 index 00000000..32c299e0 --- /dev/null +++ b/src/libiar/CDIVMOD.asm @@ -0,0 +1,18 @@ +; CDIVMOD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?C_DIVMOD_L01 + rseg RCODE +rcode_base: + public ?C_DIVMOD_L01 +?C_DIVMOD_L01 equ rcode_base+00000000h + defb 011h,009h,000h,0CBh,011h,01Dh,0C8h + defb 0CBh,012h,07Ah,090h,038h,0F6h,057h + defb 018h,0F3h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/CFINDSIGN.asm b/src/libiar/CFINDSIGN.asm new file mode 100755 index 00000000..5a7402ac --- /dev/null +++ b/src/libiar/CFINDSIGN.asm @@ -0,0 +1,18 @@ +; CFINDSIGN.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?C_FIND_SIGN_L01 + rseg RCODE +rcode_base: + public ?C_FIND_SIGN_L01 +?C_FIND_SIGN_L01 equ rcode_base+00000000h + defb 0CBh,078h,028h,005h,0AFh,090h,047h + defb 03Eh,001h,0CBh,079h,0C8h,0F5h,0AFh + defb 091h,04Fh,0F1h,0EEh,001h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/CLSH.asm b/src/libiar/CLSH.asm new file mode 100755 index 00000000..34905e2b --- /dev/null +++ b/src/libiar/CLSH.asm @@ -0,0 +1,16 @@ +; CLSH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?C_LSH_L01 + rseg RCODE +rcode_base: + public ?C_LSH_L01 +?C_LSH_L01 equ rcode_base+00000000h + defb 004h,005h,0C8h,087h,010h,0FDh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/CLSHASG.asm b/src/libiar/CLSHASG.asm new file mode 100755 index 00000000..e38f7e6e --- /dev/null +++ b/src/libiar/CLSHASG.asm @@ -0,0 +1,19 @@ +; CLSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?C_LSHASG_L01 + rseg RCODE +rcode_base: + public ?C_LSHASG_L01 +?C_LSHASG_L01 equ rcode_base+00000000h + extern ?C_LSH_L01 + defb 07Eh,0CDh + defw LWRD ?C_LSH_L01 + defb 077h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/CMUL.asm b/src/libiar/CMUL.asm new file mode 100755 index 00000000..f0dde678 --- /dev/null +++ b/src/libiar/CMUL.asm @@ -0,0 +1,16 @@ +; CMUL.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?C_MUL_L01 + rseg RCODE +rcode_base: + public ?C_MUL_L01 +?C_MUL_L01 equ rcode_base+00000000h + defb 0C5h,04Fh,0EDh,04Ch,079h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/CMULASG.asm b/src/libiar/CMULASG.asm new file mode 100755 index 00000000..7308472a --- /dev/null +++ b/src/libiar/CMULASG.asm @@ -0,0 +1,19 @@ +; CMULASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?C_MULASG_L01 + rseg RCODE +rcode_base: + public ?C_MULASG_L01 +?C_MULASG_L01 equ rcode_base+00000000h + extern ?C_MUL_L01 + defb 0C5h,047h,07Eh,0CDh + defw LWRD ?C_MUL_L01 + defb 077h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/CSSWITCH.asm b/src/libiar/CSSWITCH.asm new file mode 100755 index 00000000..4465fd6c --- /dev/null +++ b/src/libiar/CSSWITCH.asm @@ -0,0 +1,19 @@ +; CSSWITCH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?C_S_SWITCH_L06 + rseg RCODE +rcode_base: + public ?C_S_SWITCH_L06 +?C_S_SWITCH_L06 equ rcode_base+00000000h + defb 0E3h,0F5h,0D5h,016h,000h,07Bh,096h + defb 023h,05Fh,096h,023h,07Ah,09Eh,023h + defb 030h,004h,0EBh,023h,029h,019h,05Eh + defb 023h,056h,0EBh,0D1h,0F1h,0E3h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/CVSWITCH.asm b/src/libiar/CVSWITCH.asm new file mode 100755 index 00000000..a5509f54 --- /dev/null +++ b/src/libiar/CVSWITCH.asm @@ -0,0 +1,20 @@ +; CVSWITCH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?C_V_SWITCH_L06 + rseg RCODE +rcode_base: + public ?C_V_SWITCH_L06 +?C_V_SWITCH_L06 equ rcode_base+00000000h + extern ?V_SWITCH_END_L06 + defb 0E3h,0F5h,0C5h,04Eh,023h,046h,023h + defb 07Bh,0EDh,0B1h,020h,002h,023h,023h + defb 009h,0C3h + defw LWRD ?V_SWITCH_END_L06 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ENTAUTO.asm b/src/libiar/ENTAUTO.asm new file mode 100755 index 00000000..c120e126 --- /dev/null +++ b/src/libiar/ENTAUTO.asm @@ -0,0 +1,18 @@ +; ENTAUTO.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?ENT_AUTO_L09 + public ?ENT_AUTO_L09 +?ENT_AUTO_L09 equ 00000010h + extern ?ENT_AUTO_DIRECT_L09 + t_org_abs S86=0000 00000000 + t_org_abs S86=0000 00000010 + defb 0C3h + defw LWRD ?ENT_AUTO_DIRECT_L09 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ENTAUTODIRECT.asm b/src/libiar/ENTAUTODIRECT.asm new file mode 100755 index 00000000..3f875a4b --- /dev/null +++ b/src/libiar/ENTAUTODIRECT.asm @@ -0,0 +1,18 @@ +; ENTAUTODIRECT.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?ENT_AUTO_DIRECT_L09 + rseg RCODE +rcode_base: + public ?ENT_AUTO_DIRECT_L09 +?ENT_AUTO_DIRECT_L09 equ rcode_base+00000000h + defb 0E1h,0C5h,0D5h,0DDh,0E5h,0DDh,021h + defb 000h,000h,0DDh,039h,05Eh,023h,056h + defb 023h,0EBh,039h,0F9h,0EBh,0E9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ENTPARM.asm b/src/libiar/ENTPARM.asm new file mode 100755 index 00000000..5330d31f --- /dev/null +++ b/src/libiar/ENTPARM.asm @@ -0,0 +1,18 @@ +; ENTPARM.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?ENT_PARM_L09 + public ?ENT_PARM_L09 +?ENT_PARM_L09 equ 00000008h + extern ?ENT_PARM_DIRECT_L09 + t_org_abs S86=0000 00000000 + t_org_abs S86=0000 00000008 + defb 0C3h + defw LWRD ?ENT_PARM_DIRECT_L09 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ENTPARMDIRECT.asm b/src/libiar/ENTPARMDIRECT.asm new file mode 100755 index 00000000..acc08c69 --- /dev/null +++ b/src/libiar/ENTPARMDIRECT.asm @@ -0,0 +1,17 @@ +; ENTPARMDIRECT.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?ENT_PARM_DIRECT_L09 + rseg RCODE +rcode_base: + public ?ENT_PARM_DIRECT_L09 +?ENT_PARM_DIRECT_L09 equ rcode_base+00000000h + defb 0E1h,0C5h,0D5h,0DDh,0E5h,0DDh,021h + defb 000h,000h,0DDh,039h,0E9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FADDASG.asm b/src/libiar/FADDASG.asm new file mode 100755 index 00000000..1320fcfd --- /dev/null +++ b/src/libiar/FADDASG.asm @@ -0,0 +1,22 @@ +; FADDASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_ADDASG_L04 + rseg RCODE +rcode_base: + public ?F_ADDASG_L04 +?F_ADDASG_L04 equ rcode_base+00000000h + extern ?F_END_ASG2_L04 + extern ?F_ADD_L04 + defb 0C5h,0D5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0CDh + defw LWRD ?F_ADD_L04 + defb 0C3h + defw LWRD ?F_END_ASG2_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FADDSUB.asm b/src/libiar/FADDSUB.asm new file mode 100755 index 00000000..6503f5d2 --- /dev/null +++ b/src/libiar/FADDSUB.asm @@ -0,0 +1,75 @@ +; FADDSUB.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_ADD_SUB_L04 + rseg RCODE +rcode_base: + public ?F_SUB_L04 +?F_SUB_L04 equ rcode_base+00000000h + public ?F_ADD_L04 +?F_ADD_L04 equ rcode_base+00000014h + extern ?F_OVERFLOW_L04 + extern ?F_UNDERFLOW_L04 + extern ?F_ROUND_L04 + extern ?F_NO_PACK_L04 + extern ?F_PACK_L04 + extern ?F_UNPACK_L04 + defb 0EBh,0E3h,0DDh,0E5h,0DDh,021h,002h + defb 000h,0DDh,039h,0E5h,0F5h,0DDh,07Eh + defb 005h,0EEh,080h,06Fh,018h,00Fh,0EBh + defb 0E3h,0DDh,0E5h,0DDh,021h,002h,000h + defb 0DDh,039h,0E5h,0F5h,0DDh,06Eh,005h + defb 078h,0E6h,07Fh,0B1h,020h,015h,045h + defb 0DDh,04Eh,004h,0DDh,056h,003h,0DDh + defb 05Eh,002h,07Dh,0E6h + defb 07Fh,06Fh,0B1h,020h,001h,045h,0C3h + defw LWRD ?F_NO_PACK_L04 + defb 07Dh,0E6h,07Fh,0DDh,0B6h,004h,0CAh + defw LWRD ?F_NO_PACK_L04 + defb 0C5h,0D5h,078h,0E6h,07Fh,067h,0DDh + defb 075h,005h,07Dh,0E6h,07Fh,047h,069h + defb 0DDh,04Eh,004h,0EDh,042h,020h,009h + defb 0EBh,0DDh,046h,003h,0DDh,04Eh,002h + defb 0EDh,042h,0D1h,038h,01Dh,0E1h,0DDh + defb 07Eh,003h,0DDh,072h,003h,057h,0DDh + defb 07Eh,002h,0DDh,073h,002h,05Fh,0DDh + defb 046h,005h,0DDh,074h + defb 005h,0DDh,04Eh,004h,0DDh,075h,004h + defb 018h,001h,0C1h,0CDh + defw LWRD ?F_UNPACK_L04 + defb 0F5h,07Ch,095h,0FEh,01Ah,038h,00Fh + defb 0DDh,046h,005h,0DDh,04Eh,004h,0DDh + defb 056h,003h,0DDh,05Eh,002h,0C3h + defw LWRD ?F_PACK_L04 + defb 0FEh,008h,038h,010h,0D6h,008h,06Fh + defb 0AFh,0BBh,05Ah,028h,002h,0CBh,0C3h + defb 051h,048h,047h,07Dh,018h,0ECh,0B7h + defb 028h,00Fh,0CBh,038h,0CBh,019h,0CBh + defb 01Ah,0CBh,01Bh,030h,002h,0CBh,0C3h + defb 03Dh,020h,0F1h,0DDh,0CBh,0F9h,056h + defb 020h,029h,0DDh,07Eh,002h,083h,05Fh + defb 0DDh,07Eh,003h,08Ah + defb 057h,0DDh,07Eh,004h,089h,04Fh,0DDh + defb 07Eh,005h,088h,047h,030h,010h,0CBh + defb 018h,0CBh,019h,0CBh,01Ah,0CBh,01Bh + defb 030h,002h,0CBh,0C3h,024h,0CAh + defw LWRD ?F_OVERFLOW_L04 + defb 0C3h + defw LWRD ?F_ROUND_L04 + defb 0DDh,07Eh,002h,093h,05Fh,0DDh,07Eh + defb 003h,09Ah,057h,0DDh,07Eh,004h,099h + defb 04Fh,0DDh,07Eh,005h,098h,047h,0B1h + defb 0B2h,0B3h,0CAh + defw LWRD ?F_UNDERFLOW_L04 + defb 0CBh,078h,020h,00Eh,025h,0CAh + defw LWRD ?F_UNDERFLOW_L04 + defb 0CBh,023h,0CBh,012h,0CBh,011h,0CBh + defb 010h,018h,0EEh,0C3h + defw LWRD ?F_ROUND_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FCMP.asm b/src/libiar/FCMP.asm new file mode 100755 index 00000000..7eabf575 --- /dev/null +++ b/src/libiar/FCMP.asm @@ -0,0 +1,28 @@ +; FCMP.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_CMP_L04 + rseg RCODE +rcode_base: + public ?F_CMP_L04 +?F_CMP_L04 equ rcode_base+00000000h + defb 0EBh,0E3h,0DDh,0E5h,0DDh,021h,002h + defb 000h,0DDh,039h,0E5h,067h,0DDh,07Eh + defb 005h,0CBh,078h,028h,019h,0CBh,07Fh + defb 028h,015h,090h,020h,02Bh,0DDh,07Eh + defb 004h,091h,020h,025h,0DDh,07Eh,003h + defb 092h,020h,01Fh,0DDh,07Eh,002h,093h + defb 018h,019h,0EEh,080h,06Fh,078h,0EEh + defb 080h,095h,020h,010h + defb 079h,0DDh,096h,004h,020h,00Ah,07Ah + defb 0DDh,096h,003h,020h,004h,07Bh,0DDh + defb 096h,002h,07Ch,0E1h,0DDh,075h,004h + defb 0DDh,074h,005h,0DDh,0E1h,0E1h,0EBh + defb 033h,033h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FDEC.asm b/src/libiar/FDEC.asm new file mode 100755 index 00000000..80bd2045 --- /dev/null +++ b/src/libiar/FDEC.asm @@ -0,0 +1,20 @@ +; FDEC.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_DEC_L04 + rseg RCODE +rcode_base: + public ?F_DEC_L04 +?F_DEC_L04 equ rcode_base+00000000h + extern ?F_ADD_L04 + defb 0C5h,0E5h,001h,080h,0BFh,021h,000h + defb 000h,0CDh + defw LWRD ?F_ADD_L04 + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FDECASG.asm b/src/libiar/FDECASG.asm new file mode 100755 index 00000000..ebbfa1d4 --- /dev/null +++ b/src/libiar/FDECASG.asm @@ -0,0 +1,21 @@ +; FDECASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_DECASG_L04 + rseg RCODE +rcode_base: + public ?F_DECASG_L04 +?F_DECASG_L04 equ rcode_base+00000000h + extern ?F_DEC_L04 + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0EBh,0CDh + defw LWRD ?F_DEC_L04 + defb 0EBh,070h,02Bh,071h,02Bh,072h,02Bh + defb 073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FDIV.asm b/src/libiar/FDIV.asm new file mode 100755 index 00000000..02849632 --- /dev/null +++ b/src/libiar/FDIV.asm @@ -0,0 +1,59 @@ +; FDIV.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_DIV_L04 + rseg RCODE +rcode_base: + public ?F_DIV_L04 +?F_DIV_L04 equ rcode_base+00000000h + extern ?F_UNPACK_L04 + extern ?F_PACK_L04 + extern ?F_OVERFLOW_L04 + extern ?F_UNDERFLOW2_L04 + extern ?F_UNDERFLOW_L04 + extern ?F_UP_ROUND_L04 + defb 0EBh,0E3h,0DDh,0E5h,0DDh,021h,002h + defb 000h,0DDh,039h,0E5h,0F5h,0CDh + defw LWRD ?F_UNPACK_L04 + defb 01Fh,01Fh,0F5h,0AFh,0BDh,0CAh + defw LWRD ?F_UNDERFLOW_L04 + defb 0B4h,0CAh + defw LWRD ?F_OVERFLOW_L04 + defb 0D6h,07Fh,0D2h + defw rcode_base+28h ; t_push_rel (0000) 00000028 + defb 0EDh,044h,085h,0DAh + defw LWRD ?F_OVERFLOW_L04 + defb 018h,009h,067h,07Dh,094h,0DAh + defw LWRD ?F_UNDERFLOW_L04 + defb 0CAh + defw LWRD ?F_UNDERFLOW_L04 + defb 0F5h,06Ah,061h,048h,006h,000h,0DDh + defb 056h,004h,0DDh,05Eh,003h,0A7h,0EDh + defb 052h,079h,0DDh,09Eh,005h,030h,00Fh + defb 0DDh,035h,0F7h,0CAh + defw LWRD ?F_UNDERFLOW2_L04 + defb 0CBh,025h,0CBh,014h,017h,019h,0DDh + defb 08Eh,005h,04Fh,0DDh,036h,0F6h,017h + defb 0CBh,025h,0CBh,014h,0CBh,011h,0CBh + defb 010h,0EDh,052h,079h,0DDh,09Eh,005h + defb 04Fh,078h,0DEh,000h,047h,030h,008h + defb 019h,079h,0DDh,08Eh,005h,04Fh,006h + defb 000h,0DDh,0CBh,002h,016h,0DDh,0CBh + defb 003h,016h,0DDh,0CBh + defb 004h,016h,0DDh,035h,0F6h,020h,0D2h + defb 079h,0CBh,025h,0CBh,014h,017h,0CBh + defb 010h,020h,007h,0DDh,096h,005h,020h + defb 002h,0EDh,052h,0DDh,07Eh,004h,02Fh + defb 047h,0DDh,07Eh,003h,02Fh,04Fh,0DDh + defb 07Eh,002h,02Fh,057h,01Eh,000h,0E1h + defb 038h,007h,020h,002h,0CBh,042h,0C2h + defw LWRD ?F_UP_ROUND_L04 + defb 0C3h + defw LWRD ?F_PACK_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FDIVASG.asm b/src/libiar/FDIVASG.asm new file mode 100755 index 00000000..a0824b66 --- /dev/null +++ b/src/libiar/FDIVASG.asm @@ -0,0 +1,22 @@ +; FDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_DIVASG_L04 + rseg RCODE +rcode_base: + public ?F_DIVASG_L04 +?F_DIVASG_L04 equ rcode_base+00000000h + extern ?F_END_ASG2_L04 + extern ?F_DIV_L04 + defb 0C5h,0D5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0CDh + defw LWRD ?F_DIV_L04 + defb 0C3h + defw LWRD ?F_END_ASG2_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FENDASG2.asm b/src/libiar/FENDASG2.asm new file mode 100755 index 00000000..9118ac48 --- /dev/null +++ b/src/libiar/FENDASG2.asm @@ -0,0 +1,17 @@ +; FENDASG2.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_END_ASG2_L04 + rseg RCODE +rcode_base: + public ?F_END_ASG2_L04 +?F_END_ASG2_L04 equ rcode_base+00000000h + defb 0EBh,070h,02Bh,071h,02Bh,072h,02Bh + defb 073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FINC.asm b/src/libiar/FINC.asm new file mode 100755 index 00000000..2f920f00 --- /dev/null +++ b/src/libiar/FINC.asm @@ -0,0 +1,20 @@ +; FINC.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_INC_L04 + rseg RCODE +rcode_base: + public ?F_INC_L04 +?F_INC_L04 equ rcode_base+00000000h + extern ?F_ADD_L04 + defb 0C5h,0E5h,001h,080h,03Fh,021h,000h + defb 000h,0CDh + defw LWRD ?F_ADD_L04 + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FINCASG.asm b/src/libiar/FINCASG.asm new file mode 100755 index 00000000..773a10f8 --- /dev/null +++ b/src/libiar/FINCASG.asm @@ -0,0 +1,21 @@ +; FINCASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_INCASG_L04 + rseg RCODE +rcode_base: + public ?F_INCASG_L04 +?F_INCASG_L04 equ rcode_base+00000000h + extern ?F_INC_L04 + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0EBh,0CDh + defw LWRD ?F_INC_L04 + defb 0EBh,070h,02Bh,071h,02Bh,072h,02Bh + defb 073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FMUL.asm b/src/libiar/FMUL.asm new file mode 100755 index 00000000..c7600f1d --- /dev/null +++ b/src/libiar/FMUL.asm @@ -0,0 +1,64 @@ +; FMUL.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_MUL_L04 + rseg RCODE +rcode_base: + public ?F_MUL_L04 +?F_MUL_L04 equ rcode_base+00000000h + extern ?F_UNPACK_L04 + extern ?F_OVERFLOW_L04 + extern ?F_UNDERFLOW_L04 + extern ?F_ROUND_L04 + defb 0EBh,0E3h,0DDh,0E5h,0DDh,021h,002h + defb 000h,0DDh,039h,0E5h,0F5h,0CDh + defw LWRD ?F_UNPACK_L04 + defb 0CBh,03Fh,0CBh,03Fh,0F5h,0AFh,0BDh + defb 0CAh + defw LWRD ?F_UNDERFLOW_L04 + defb 0B4h,0CAh + defw LWRD ?F_UNDERFLOW_L04 + defb 0D6h,07Fh,038h,006h,085h,0DAh + defw LWRD ?F_OVERFLOW_L04 + defb 018h,004h,085h,0D2h + defw LWRD ?F_UNDERFLOW_L04 + defb 067h,03Eh,080h,0A8h,0B1h,0B2h,020h + defb 00Bh,0DDh,046h,005h,0DDh,04Eh,004h + defb 0DDh,056h,003h,018h,029h,03Eh,080h + defb 0DDh,0AEh,005h,0DDh,0B6h,004h,0DDh + defb 0B6h,003h,028h,01Ch,07Ch,0C5h,0D5h + defb 0CDh + defw rcode_base+6ah ; t_push_rel (0000) 0000006A + defb 0F1h,0F1h,0CBh,03Dh,030h,010h,024h + defb 0CAh + defw LWRD ?F_OVERFLOW_L04 + defb 0CBh,018h,0CBh,019h,0CBh,01Ah,0CBh + defb 01Bh,030h,002h,0CBh,0C3h,0C3h + defw LWRD ?F_ROUND_L04 + defb 0F5h,060h,0DDh,056h,005h,06Ah,0EDh + defb 06Ch,0E5h,060h,0DDh,06Eh,004h,0EDh + defb 06Ch,059h,0EDh,05Ch,0AFh,019h,0CEh + defb 000h,0F5h,0E5h,060h,0DDh,06Eh,003h + defb 0EDh,06Ch,059h,0DDh,056h,004h,0EDh + defb 05Ch,0AFh,019h,0CEh,000h,0DDh,046h + defb 0F5h,050h,0DDh,05Eh,005h,0EDh,05Ch + defb 019h,0CEh,000h,0F5h + defb 0E5h,069h,0DDh,066h,003h,0EDh,06Ch + defb 050h,0DDh,05Eh,004h,0EDh,05Ch,0AFh + defb 019h,0CEh,000h,0DDh,04Eh,003h,0EDh + defb 04Ch,0DDh,071h,002h,048h,006h,000h + defb 009h,0DDh,075h,0F4h,04Ch,0CEh,000h + defb 047h,0E1h,009h,04Dh,0D1h,07Ah,0CEh + defb 000h,057h,05Ch,0E1h,019h,045h,0D1h + defb 07Ah,0CEh,000h,057h + defb 05Ch,0E1h,019h,0E5h,0C5h,0D1h,0C1h + defb 0E1h,0CBh,013h,0CBh,012h,0CBh,011h + defb 0CBh,010h,0CBh,015h,0DDh,07Eh,0F4h + defb 0DDh,0B6h,002h,0C8h,0CBh,0C3h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FMULASG.asm b/src/libiar/FMULASG.asm new file mode 100755 index 00000000..e3db9e51 --- /dev/null +++ b/src/libiar/FMULASG.asm @@ -0,0 +1,22 @@ +; FMULASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_MULASG_L04 + rseg RCODE +rcode_base: + public ?F_MULASG_L04 +?F_MULASG_L04 equ rcode_base+00000000h + extern ?F_END_ASG2_L04 + extern ?F_MUL_L04 + defb 0C5h,0D5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0CDh + defw LWRD ?F_MUL_L04 + defb 0C3h + defw LWRD ?F_END_ASG2_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FNEGASG.asm b/src/libiar/FNEGASG.asm new file mode 100755 index 00000000..72e368c9 --- /dev/null +++ b/src/libiar/FNEGASG.asm @@ -0,0 +1,19 @@ +; FNEGASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_NEGASG_L04 + rseg RCODE +rcode_base: + public ?F_NEGASG_L04 +?F_NEGASG_L04 equ rcode_base+00000000h + defb 0F5h,05Eh,023h,056h,023h,04Eh,023h + defb 046h,079h,0B0h,028h,005h,078h,0EEh + defb 080h,047h,070h,02Bh,02Bh,02Bh,0F1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FPACK.asm b/src/libiar/FPACK.asm new file mode 100755 index 00000000..76fd0850 --- /dev/null +++ b/src/libiar/FPACK.asm @@ -0,0 +1,32 @@ +; FPACK.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_PACK_L04 + rseg RCODE +rcode_base: + public ?F_PACK_L04 +?F_PACK_L04 equ rcode_base+00000015h + public ?F_OVERFLOW_L04 +?F_OVERFLOW_L04 equ rcode_base+00000000h + public ?F_UNDERFLOW2_L04 +?F_UNDERFLOW2_L04 equ rcode_base+0000000Dh + public ?F_UNDERFLOW_L04 +?F_UNDERFLOW_L04 equ rcode_base+0000000Eh + public ?F_NO_PACK_L04 +?F_NO_PACK_L04 equ rcode_base+0000002Bh + defb 006h,0FFh,048h,050h,058h,0DDh,0CBh + defb 0F9h,01Eh,0CBh,018h,018h,01Dh,0C1h + defb 006h,000h,048h,050h,058h,018h,015h + defb 07Ch,0B7h,028h,0F5h,03Ch,028h,0E4h + defb 05Ah,051h,048h,044h,0DDh,0CBh,0F9h + defb 01Eh,0CBh,018h,038h,002h,0CBh,0B9h + defb 0F1h,0F1h,0E1h,0DDh,075h,004h,0DDh + defb 074h,005h,0DDh,0E1h + defb 0E1h,0EBh,033h,033h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FROUND.asm b/src/libiar/FROUND.asm new file mode 100755 index 00000000..521bf286 --- /dev/null +++ b/src/libiar/FROUND.asm @@ -0,0 +1,30 @@ +; FROUND.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_ROUND_L04 + rseg RCODE +rcode_base: + public ?F_ROUND_L04 +?F_ROUND_L04 equ rcode_base+00000000h + public ?F_UP_ROUND_L04 +?F_UP_ROUND_L04 equ rcode_base+00000010h + extern ?F_PACK_L04 + extern ?F_OVERFLOW_L04 + extern ?F_UNDERFLOW_L04 + defb 07Ch,0B7h,0CAh + defw LWRD ?F_UNDERFLOW_L04 + defb 07Bh,017h,030h,01Bh,0B7h,020h,004h + defb 0CBh,042h,028h,014h,07Ah,0C6h,001h + defb 057h,079h,0CEh,000h,04Fh,078h,0CEh + defb 000h,047h,030h,006h,0CBh,018h,024h + defb 0CAh + defw LWRD ?F_OVERFLOW_L04 + defb 0C3h + defw LWRD ?F_PACK_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FSUBASG.asm b/src/libiar/FSUBASG.asm new file mode 100755 index 00000000..c150d159 --- /dev/null +++ b/src/libiar/FSUBASG.asm @@ -0,0 +1,22 @@ +; FSUBASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_SUBASG_L04 + rseg RCODE +rcode_base: + public ?F_SUBASG_L04 +?F_SUBASG_L04 equ rcode_base+00000000h + extern ?F_END_ASG2_L04 + extern ?F_SUB_L04 + defb 0C5h,0D5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0CDh + defw LWRD ?F_SUB_L04 + defb 0C3h + defw LWRD ?F_END_ASG2_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FTOL.asm b/src/libiar/FTOL.asm new file mode 100755 index 00000000..688af051 --- /dev/null +++ b/src/libiar/FTOL.asm @@ -0,0 +1,34 @@ +; FTOL.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_TO_L_L04 + rseg RCODE +rcode_base: + public ?F_TO_L_L04 +?F_TO_L_L04 equ rcode_base+00000000h + extern ?L_NOT_L03 + extern ?L_INC_L03 + defb 0F5h,0D5h,0CBh,020h,0CBh,013h,0CBh + defb 079h,028h,002h,0CBh,0C0h,0CBh,0F9h + defb 078h,0D6h,07Fh,030h,007h,001h,000h + defb 000h,060h,069h,018h,041h,0FEh,020h + defb 038h,00Dh,001h,000h,080h,061h,069h + defb 0CBh,043h,020h,034h,00Bh,02Bh,018h + defb 030h,047h,03Eh,01Fh,090h,051h,04Ch + defb 065h,02Eh,000h,028h + defb 01Ah,0D6h,008h,038h,007h,06Ch,061h + defb 04Ah,016h,000h,018h,0F5h,0C6h,008h + defb 028h,00Bh,047h,0CBh,03Ah,0CBh,019h + defb 0CBh,01Ch,0CBh,01Dh,010h,0F6h,042h + defb 0CBh,043h,028h,006h,0CDh + defw LWRD ?L_NOT_L03 + defb 0CDh + defw LWRD ?L_INC_L03 + defb 0D1h,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/FUNPACK.asm b/src/libiar/FUNPACK.asm new file mode 100755 index 00000000..7c3f4cf7 --- /dev/null +++ b/src/libiar/FUNPACK.asm @@ -0,0 +1,25 @@ +; FUNPACK.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?F_UNPACK_L04 + rseg RCODE +rcode_base: + public ?F_UNPACK_L04 +?F_UNPACK_L04 equ rcode_base+00000000h + defb 0AFh,067h,0CBh,021h,0CBh,010h,017h + defb 037h,0CBh,019h,068h,041h,04Ah,053h + defb 01Eh,000h,0C5h,0D5h,0DDh,05Eh,002h + defb 0DDh,056h,003h,0DDh,04Eh,004h,0DDh + defb 046h,005h,0CBh,021h,0CBh,010h,0CBh + defb 014h,037h,0CBh,019h,0DDh,071h,005h + defb 0DDh,072h,004h,0DDh,073h,003h,0DDh + defb 036h,002h,000h,04Fh + defb 0ACh,0CBh,019h,017h,0CBh,01Ch,017h + defb 060h,0D1h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LADDASG.asm b/src/libiar/LADDASG.asm new file mode 100755 index 00000000..c990d5a1 --- /dev/null +++ b/src/libiar/LADDASG.asm @@ -0,0 +1,19 @@ +; LADDASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_ADDASG_L03 + rseg RCODE +rcode_base: + public ?L_ADDASG_L03 +?L_ADDASG_L03 equ rcode_base+00000000h + defb 0F5h,07Eh,083h,077h,05Fh,023h,07Eh + defb 08Ah,077h,057h,023h,07Eh,089h,077h + defb 04Fh,023h,07Eh,088h,077h,047h,02Bh + defb 02Bh,02Bh,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LAND.asm b/src/libiar/LAND.asm new file mode 100755 index 00000000..74b422bf --- /dev/null +++ b/src/libiar/LAND.asm @@ -0,0 +1,20 @@ +; LAND.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_AND_L03 + rseg RCODE +rcode_base: + public ?L_AND_L03 +?L_AND_L03 equ rcode_base+00000000h + defb 0EBh,0E3h,0F5h,0E5h,021h,006h,000h + defb 039h,07Eh,0A3h,077h,023h,07Eh,0A2h + defb 077h,0D1h,023h,07Eh,073h,0A1h,04Fh + defb 023h,07Eh,072h,0A0h,047h,0F1h,0D1h + defb 0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LANDASG.asm b/src/libiar/LANDASG.asm new file mode 100755 index 00000000..dde8774e --- /dev/null +++ b/src/libiar/LANDASG.asm @@ -0,0 +1,19 @@ +; LANDASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_ANDASG_L03 + rseg RCODE +rcode_base: + public ?L_ANDASG_L03 +?L_ANDASG_L03 equ rcode_base+00000000h + defb 0F5h,07Eh,0A3h,077h,05Fh,023h,07Eh + defb 0A2h,077h,057h,023h,07Eh,0A1h,077h + defb 04Fh,023h,07Eh,0A0h,077h,047h,02Bh + defb 02Bh,02Bh,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LDEC.asm b/src/libiar/LDEC.asm new file mode 100755 index 00000000..b32f28dd --- /dev/null +++ b/src/libiar/LDEC.asm @@ -0,0 +1,17 @@ +; LDEC.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_DEC_L03 + rseg RCODE +rcode_base: + public ?L_DEC_L03 +?L_DEC_L03 equ rcode_base+00000000h + defb 0F5h,07Dh,0B4h,02Bh,020h,001h,00Bh + defb 0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LDECASG.asm b/src/libiar/LDECASG.asm new file mode 100755 index 00000000..6355a318 --- /dev/null +++ b/src/libiar/LDECASG.asm @@ -0,0 +1,22 @@ +; LDECASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_DECASG_L03 + rseg RCODE +rcode_base: + public ?L_DECASG_L03 +?L_DECASG_L03 equ rcode_base+00000000h + extern ?L_DEC_L03 + extern ?L_END_ASG_L03 + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0EBh,0CDh + defw LWRD ?L_DEC_L03 + defb 0C3h + defw LWRD ?L_END_ASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LDIVMOD.asm b/src/libiar/LDIVMOD.asm new file mode 100755 index 00000000..21ba6ea1 --- /dev/null +++ b/src/libiar/LDIVMOD.asm @@ -0,0 +1,28 @@ +; LDIVMOD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_DIVMOD_L03 + rseg RCODE +rcode_base: + public ?L_DIVMOD_L03 +?L_DIVMOD_L03 equ rcode_base+00000000h + defb 0F5h,021h,000h,000h,001h,000h,000h + defb 0DDh,036h,0F8h,021h,018h,002h,019h + defb 037h,0DDh,0CBh,0FCh,016h,0DDh,0CBh + defb 0FDh,016h,0DDh,0CBh,0FEh,016h,0DDh + defb 0CBh,0FFh,016h,0DDh,035h,0F8h,028h + defb 02Eh,0CBh,011h,0CBh,010h,0CBh,015h + defb 0CBh,014h,0EDh,052h,038h,0DDh,020h + defb 010h,078h,0DDh,096h + defb 007h,038h,0D5h,020h,008h,079h,0DDh + defb 096h,006h,038h,0CDh,018h,004h,079h + defb 0DDh,096h,006h,04Fh,078h,0DDh,09Eh + defb 007h,047h,030h,0C1h,02Bh,0A7h,018h + defb 0BDh,0F1h,0E5h,060h,069h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LEAVE.asm b/src/libiar/LEAVE.asm new file mode 100755 index 00000000..255331fa --- /dev/null +++ b/src/libiar/LEAVE.asm @@ -0,0 +1,16 @@ +; LEAVE.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?LEAVE_L09 + public ?LEAVE_L09 +?LEAVE_L09 equ 00000020h + t_org_abs S86=0000 00000000 + t_org_abs S86=0000 00000020 + defb 0DDh,0F9h,0DDh,0E1h,0D1h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LEAVE32.asm b/src/libiar/LEAVE32.asm new file mode 100755 index 00000000..1eabf459 --- /dev/null +++ b/src/libiar/LEAVE32.asm @@ -0,0 +1,17 @@ +; LEAVE32.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?LEAVE_32_L09 + rseg RCODE +rcode_base: + public ?LEAVE_32_L09 +?LEAVE_32_L09 equ rcode_base+00000000h + defb 0DDh,0F9h,0DDh,0E1h,0D1h,033h,033h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LEAVEDIRECT.asm b/src/libiar/LEAVEDIRECT.asm new file mode 100755 index 00000000..9e2cbb5a --- /dev/null +++ b/src/libiar/LEAVEDIRECT.asm @@ -0,0 +1,16 @@ +; LEAVEDIRECT.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?LEAVE_DIRECT_L09 + rseg RCODE +rcode_base: + public ?LEAVE_DIRECT_L09 +?LEAVE_DIRECT_L09 equ rcode_base+00000000h + defb 0DDh,0F9h,0DDh,0E1h,0D1h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LENDASG.asm b/src/libiar/LENDASG.asm new file mode 100755 index 00000000..3f7f7e84 --- /dev/null +++ b/src/libiar/LENDASG.asm @@ -0,0 +1,17 @@ +; LENDASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_END_ASG_L03 + rseg RCODE +rcode_base: + public ?L_END_ASG_L03 +?L_END_ASG_L03 equ rcode_base+00000000h + defb 0EBh,070h,02Bh,071h,02Bh,072h,02Bh + defb 073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LENDMULDIVASG.asm b/src/libiar/LENDMULDIVASG.asm new file mode 100755 index 00000000..556feafc --- /dev/null +++ b/src/libiar/LENDMULDIVASG.asm @@ -0,0 +1,17 @@ +; LENDMULDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_END_MULDIVASG_L03 + rseg RCODE +rcode_base: + public ?L_END_MULDIVASG_L03 +?L_END_MULDIVASG_L03 equ rcode_base+00000000h + defb 0EBh,070h,02Bh,071h,02Bh,072h,02Bh + defb 073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LFINDSIGN.asm b/src/libiar/LFINDSIGN.asm new file mode 100755 index 00000000..5e796207 --- /dev/null +++ b/src/libiar/LFINDSIGN.asm @@ -0,0 +1,33 @@ +; LFINDSIGN.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_FIND_SIGN_L03 + rseg RCODE +rcode_base: + public ?L_FIND_SIGN_L03 +?L_FIND_SIGN_L03 equ rcode_base+00000000h + extern ?L_NOT_L03 + extern ?L_INC_L03 + defb 0CBh,07Ah,028h,018h,042h,04Bh,0DDh + defb 066h,007h,0DDh,06Eh,006h,0CDh + defw LWRD ?L_NOT_L03 + defb 0CDh + defw LWRD ?L_INC_L03 + defb 050h,059h,0DDh,074h,007h,0DDh,075h + defb 006h,03Eh,001h,0DDh,0CBh,0FFh,07Eh + defb 0C8h,0F5h,0DDh,046h,0FFh,0DDh,04Eh + defb 0FEh,0DDh,066h,0FDh,0DDh,06Eh,0FCh + defb 0CDh + defw LWRD ?L_NOT_L03 + defb 0CDh + defw LWRD ?L_INC_L03 + defb 0DDh,070h,0FFh,0DDh,071h,0FEh,0DDh + defb 074h,0FDh,0DDh,075h,0FCh,0F1h,0EEh + defb 001h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LIBVERSION.asm b/src/libiar/LIBVERSION.asm new file mode 100755 index 00000000..ec22fe86 --- /dev/null +++ b/src/libiar/LIBVERSION.asm @@ -0,0 +1,15 @@ +; LIBVERSION.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?LIB_VERSION_L00 + public ?CL64180B_4_06_L00 +?CL64180B_4_06_L00 equ 00000000h + public ?CL64180L_4_06_L00 ; Nick +?CL64180L_4_06_L00 equ 00000000h ; Nick + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LINC.asm b/src/libiar/LINC.asm new file mode 100755 index 00000000..0fb5806e --- /dev/null +++ b/src/libiar/LINC.asm @@ -0,0 +1,17 @@ +; LINC.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_INC_L03 + rseg RCODE +rcode_base: + public ?L_INC_L03 +?L_INC_L03 equ rcode_base+00000000h + defb 02Ch,0C0h,024h,0C0h,00Ch,0C0h,004h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LINCASG.asm b/src/libiar/LINCASG.asm new file mode 100755 index 00000000..3e6dfd05 --- /dev/null +++ b/src/libiar/LINCASG.asm @@ -0,0 +1,22 @@ +; LINCASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_INCASG_L03 + rseg RCODE +rcode_base: + public ?L_INCASG_L03 +?L_INCASG_L03 equ rcode_base+00000000h + extern ?L_INC_L03 + extern ?L_END_ASG_L03 + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0EBh,0CDh + defw LWRD ?L_INC_L03 + defb 0C3h + defw LWRD ?L_END_ASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LLSH.asm b/src/libiar/LLSH.asm new file mode 100755 index 00000000..b840b35d --- /dev/null +++ b/src/libiar/LLSH.asm @@ -0,0 +1,19 @@ +; LLSH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_LSH_L03 + rseg RCODE +rcode_base: + public ?L_LSH_L03 +?L_LSH_L03 equ rcode_base+00000000h + defb 0B7h,0C8h,0FEh,008h,038h,009h,041h + defb 04Ch,065h,02Eh,000h,0D6h,008h,018h + defb 0F2h,029h,0CBh,011h,0CBh,010h,03Dh + defb 020h,0F8h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LLSHASG.asm b/src/libiar/LLSHASG.asm new file mode 100755 index 00000000..109a3672 --- /dev/null +++ b/src/libiar/LLSHASG.asm @@ -0,0 +1,22 @@ +; LLSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_LSHASG_L03 + rseg RCODE +rcode_base: + public ?L_LSHASG_L03 +?L_LSHASG_L03 equ rcode_base+00000000h + extern ?L_LSH_L03 + extern ?L_END_ASG_L03 + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0EBh,0CDh + defw LWRD ?L_LSH_L03 + defb 0C3h + defw LWRD ?L_END_ASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LMUL.asm b/src/libiar/LMUL.asm new file mode 100755 index 00000000..529b1c77 --- /dev/null +++ b/src/libiar/LMUL.asm @@ -0,0 +1,35 @@ +; LMUL.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_MUL_L03 + rseg RCODE +rcode_base: + public ?L_MUL_L03 +?L_MUL_L03 equ rcode_base+00000000h + defb 0E3h,0D5h,0DDh,0E5h,0DDh,021h,000h + defb 000h,0DDh,039h,0DDh,056h,009h,0DDh + defb 074h,009h,0DDh,05Eh,008h,0DDh,075h + defb 008h,0D5h,0C5h,0F5h,0DDh,06Eh,004h + defb 062h,0EDh,06Ch,0DDh,056h,005h,0EDh + defb 05Ch,019h,059h,0DDh,056h,007h,0EDh + defb 05Ch,019h,0DDh,05Eh,006h,050h,0EDh + defb 05Ch,019h,0E5h,0DDh + defb 05Eh,004h,0DDh,056h,0FEh,0EDh,05Ch + defb 0DDh,06Eh,005h,0DDh,066h,007h,0EDh + defb 06Ch,019h,0DDh,046h,006h,0EDh,04Ch + defb 009h,0E5h,0DDh,05Eh,004h,0DDh,056h + defb 007h,0EDh,05Ch,0DDh,06Eh,005h,0DDh + defb 066h,006h,0EDh,06Ch,0AFh,019h,017h + defb 0F5h,0DDh,05Eh,004h,0DDh,056h,006h + defb 0EDh,05Ch,04Ah,006h + defb 000h,0AFh,009h,017h,055h,0C1h,04Ch + defb 0E1h,009h,084h,0C1h,081h,04Dh,047h + defb 0EBh,0F1h,0D1h,0D1h,0DDh,0E1h,0D1h + defb 033h,033h,033h,033h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LMULASG.asm b/src/libiar/LMULASG.asm new file mode 100755 index 00000000..7de5b686 --- /dev/null +++ b/src/libiar/LMULASG.asm @@ -0,0 +1,22 @@ +; LMULASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_MULASG_L03 + rseg RCODE +rcode_base: + public ?L_MULASG_L03 +?L_MULASG_L03 equ rcode_base+00000000h + extern ?L_MUL_L03 + extern ?L_END_MULDIVASG_L03 + defb 0C5h,0D5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0CDh + defw LWRD ?L_MUL_L03 + defb 0C3h + defw LWRD ?L_END_MULDIVASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LNEG.asm b/src/libiar/LNEG.asm new file mode 100755 index 00000000..7067e401 --- /dev/null +++ b/src/libiar/LNEG.asm @@ -0,0 +1,18 @@ +; LNEG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_NEG_L03 + rseg RCODE +rcode_base: + public ?L_NEG_L03 +?L_NEG_L03 equ rcode_base+00000000h + defb 0F5h,0AFh,095h,06Fh,03Eh,000h,09Ch + defb 067h,03Eh,000h,099h,04Fh,03Eh,000h + defb 098h,047h,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LNEGASG.asm b/src/libiar/LNEGASG.asm new file mode 100755 index 00000000..951ffb75 --- /dev/null +++ b/src/libiar/LNEGASG.asm @@ -0,0 +1,22 @@ +; LNEGASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_NEGASG_L03 + rseg RCODE +rcode_base: + public ?L_NEGASG_L03 +?L_NEGASG_L03 equ rcode_base+00000000h + extern ?L_NEG_L03 + extern ?L_END_ASG_L03 + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0EBh,0CDh + defw LWRD ?L_NEG_L03 + defb 0C3h + defw LWRD ?L_END_ASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LNOT.asm b/src/libiar/LNOT.asm new file mode 100755 index 00000000..f779a98c --- /dev/null +++ b/src/libiar/LNOT.asm @@ -0,0 +1,18 @@ +; LNOT.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_NOT_L03 + rseg RCODE +rcode_base: + public ?L_NOT_L03 +?L_NOT_L03 equ rcode_base+00000000h + defb 0F5h,07Dh,02Fh,06Fh,07Ch,02Fh,067h + defb 079h,02Fh,04Fh,078h,02Fh,047h,0F1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LNOTASG.asm b/src/libiar/LNOTASG.asm new file mode 100755 index 00000000..1ee3c69d --- /dev/null +++ b/src/libiar/LNOTASG.asm @@ -0,0 +1,22 @@ +; LNOTASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_NOTASG_L03 + rseg RCODE +rcode_base: + public ?L_NOTASG_L03 +?L_NOTASG_L03 equ rcode_base+00000000h + extern ?L_NOT_L03 + extern ?L_END_ASG_L03 + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0EBh,0CDh + defw LWRD ?L_NOT_L03 + defb 0C3h + defw LWRD ?L_END_ASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LOR.asm b/src/libiar/LOR.asm new file mode 100755 index 00000000..377f5fa7 --- /dev/null +++ b/src/libiar/LOR.asm @@ -0,0 +1,20 @@ +; LOR.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_OR_L03 + rseg RCODE +rcode_base: + public ?L_OR_L03 +?L_OR_L03 equ rcode_base+00000000h + defb 0EBh,0E3h,0F5h,0E5h,021h,006h,000h + defb 039h,07Eh,0B3h,077h,023h,07Eh,0B2h + defb 077h,0D1h,023h,07Eh,073h,0B1h,04Fh + defb 023h,07Eh,072h,0B0h,047h,0F1h,0D1h + defb 0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LORASG.asm b/src/libiar/LORASG.asm new file mode 100755 index 00000000..ffd40d78 --- /dev/null +++ b/src/libiar/LORASG.asm @@ -0,0 +1,19 @@ +; LORASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_ORASG_L03 + rseg RCODE +rcode_base: + public ?L_ORASG_L03 +?L_ORASG_L03 equ rcode_base+00000000h + defb 0F5h,07Eh,0B3h,077h,05Fh,023h,07Eh + defb 0B2h,077h,057h,023h,07Eh,0B1h,077h + defb 04Fh,023h,07Eh,0B0h,077h,047h,02Bh + defb 02Bh,02Bh,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LSSWITCH.asm b/src/libiar/LSSWITCH.asm new file mode 100755 index 00000000..ef339157 --- /dev/null +++ b/src/libiar/LSSWITCH.asm @@ -0,0 +1,22 @@ +; LSSWITCH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_S_SWITCH_L06 + rseg RCODE +rcode_base: + public ?L_S_SWITCH_L06 +?L_S_SWITCH_L06 equ rcode_base+00000000h + extern ?S_SWITCH_END_L06 + defb 0E3h,0F5h,0D5h,0C5h,07Bh,096h,023h + defb 05Fh,07Ah,09Eh,023h,057h,079h,09Eh + defb 023h,04Fh,078h,09Eh,023h,047h,07Bh + defb 096h,023h,07Ah,09Eh,023h,079h,0DEh + defb 000h,078h,0DEh,000h,0C1h,0C3h + defw LWRD ?S_SWITCH_END_L06 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LSUBASG.asm b/src/libiar/LSUBASG.asm new file mode 100755 index 00000000..a3e4a104 --- /dev/null +++ b/src/libiar/LSUBASG.asm @@ -0,0 +1,19 @@ +; LSUBASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_SUBASG_L03 + rseg RCODE +rcode_base: + public ?L_SUBASG_L03 +?L_SUBASG_L03 equ rcode_base+00000000h + defb 0F5h,07Eh,093h,077h,05Fh,023h,07Eh + defb 09Ah,077h,057h,023h,07Eh,099h,077h + defb 04Fh,023h,07Eh,098h,077h,047h,02Bh + defb 02Bh,02Bh,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LTOF.asm b/src/libiar/LTOF.asm new file mode 100755 index 00000000..5377924e --- /dev/null +++ b/src/libiar/LTOF.asm @@ -0,0 +1,31 @@ +; LTOF.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_TO_F_L04 + rseg RCODE +rcode_base: + public ?SL_TO_F_L04 +?SL_TO_F_L04 equ rcode_base+00000000h + public ?UL_TO_F_L04 +?UL_TO_F_L04 equ rcode_base+00000016h + extern ?L_NOT_L03 + extern ?L_INC_L03 + defb 0F5h,0D5h,078h,0B1h,0B4h,0B5h,028h + defb 038h,0AFh,0CBh,078h,028h,007h,0CDh + defw LWRD ?L_NOT_L03 + defb 0CDh + defw LWRD ?L_INC_L03 + defb 03Ch,018h,009h,0F5h,0D5h,078h,0B1h + defb 0B4h,0B5h,028h,022h,0AFh,058h,006h + defb 01Fh,0CBh,07Bh,020h,00Ah,0CBh,025h + defb 0CBh,014h,0CBh,011h,0CBh,013h,010h + defb 0F2h,057h,078h,0C6h,07Fh,047h,06Ch + defb 061h,04Bh,0CBh,01Ah,0CBh,018h,038h + defb 002h,0CBh,0B9h,0D1h,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LVSWITCH.asm b/src/libiar/LVSWITCH.asm new file mode 100755 index 00000000..30ce6be4 --- /dev/null +++ b/src/libiar/LVSWITCH.asm @@ -0,0 +1,26 @@ +; LVSWITCH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_V_SWITCH_L06 + rseg RCODE +rcode_base: + public ?L_V_SWITCH_L06 +?L_V_SWITCH_L06 equ rcode_base+00000000h + extern ?V_SWITCH_END_L06 + defb 0E3h,0F5h,0C5h,0DDh,0E5h,0DDh,021h + defb 000h,000h,0DDh,039h,04Eh,023h,046h + defb 018h,002h,023h,023h,023h,078h,0B1h + defb 028h,01Bh,00Bh,07Bh,096h,023h,020h + defb 0F3h,07Ah,096h,020h,0EFh,023h,0DDh + defb 07Eh,002h,096h,023h,020h,0E9h,0DDh + defb 07Eh,003h,096h,020h,0E3h,023h,023h + defb 023h,009h,009h,009h + defb 009h,0DDh,0E1h,0C3h + defw LWRD ?V_SWITCH_END_L06 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LXOR.asm b/src/libiar/LXOR.asm new file mode 100755 index 00000000..1779546a --- /dev/null +++ b/src/libiar/LXOR.asm @@ -0,0 +1,20 @@ +; LXOR.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_XOR_L03 + rseg RCODE +rcode_base: + public ?L_XOR_L03 +?L_XOR_L03 equ rcode_base+00000000h + defb 0EBh,0E3h,0F5h,0E5h,021h,006h,000h + defb 039h,07Eh,0ABh,077h,023h,07Eh,0AAh + defb 077h,0D1h,023h,07Eh,073h,0A9h,04Fh + defb 023h,07Eh,072h,0A8h,047h,0F1h,0D1h + defb 0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/LXORASG.asm b/src/libiar/LXORASG.asm new file mode 100755 index 00000000..13ec8b7f --- /dev/null +++ b/src/libiar/LXORASG.asm @@ -0,0 +1,19 @@ +; LXORASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?L_XORASG_L03 + rseg RCODE +rcode_base: + public ?L_XORASG_L03 +?L_XORASG_L03 equ rcode_base+00000000h + defb 0F5h,07Eh,0ABh,077h,05Fh,023h,07Eh + defb 0AAh,077h,057h,023h,07Eh,0A9h,077h + defb 04Fh,023h,07Eh,0A8h,077h,047h,02Bh + defb 02Bh,02Bh,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MEMCMP.asm b/src/libiar/MEMCMP.asm new file mode 100755 index 00000000..2ace680d --- /dev/null +++ b/src/libiar/MEMCMP.asm @@ -0,0 +1,20 @@ +; MEMCMP.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MEMCMP_L11 + rseg RCODE +rcode_base: + public ?MEMCMP_L11 +?MEMCMP_L11 equ rcode_base+00000000h + defb 0F5h,0C5h,0D5h,079h,0B0h,028h,009h + defb 01Ah,0EDh,0A1h,020h,009h,013h,0EAh + defw rcode_base+7 ; t_push_rel (0000) 00000007 + defb 021h,000h,000h,018h,005h,02Bh,096h + defb 06Fh,09Fh,067h,0D1h,0C1h,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MEMSET.asm b/src/libiar/MEMSET.asm new file mode 100755 index 00000000..e9c1203f --- /dev/null +++ b/src/libiar/MEMSET.asm @@ -0,0 +1,19 @@ +; MEMSET.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MEMSET_L11 + rseg RCODE +rcode_base: + public ?MEMSET_L11 +?MEMSET_L11 equ rcode_base+00000000h + defb 0F5h,0E5h,0D5h,078h,0B1h,028h,00Ch + defb 07Dh,012h,00Bh,078h,0B1h,028h,005h + defb 06Bh,062h,013h,0EDh,0B0h,0D1h,0E1h + defb 0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITOR.asm b/src/libiar/MONITOR.asm new file mode 100755 index 00000000..dffd7bcd --- /dev/null +++ b/src/libiar/MONITOR.asm @@ -0,0 +1,40 @@ +; MONITOR.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR + rseg RCODE +rcode_base: + rseg DATA0 +data0_base: + public ?MONITOR +?MONITOR equ data0_base+00000000h + public ?C_MON_BREAK +?C_MON_BREAK equ data0_base+0000002Fh + public ?DBG_2 +?DBG_2 equ 00000000h + t_symbol_def PUBLIC_REL (0001) 00000000 '?C_MON_CURR_ADDR' + public ?C_MON_ADDR_SIZE +?C_MON_ADDR_SIZE equ 00000003h + defb 0E3h,022h + t_push_rel (0001) 00000003 + defb 02Bh,02Bh,02Bh,022h + t_push_rel (0001) 00000000 + defb 0C5h,0F5h,0EDh,038h,03Ah,047h,0E6h + defb 0F0h,04Fh,07Ch,0B9h,00Eh,000h,030h + defb 00Eh,0CBh,020h,0CBh,020h,0CBh,020h + defb 0CBh,020h,0B8h,038h,003h,0EDh,008h + defb 039h,079h,032h + t_push_rel (0001) 00000002 + defb 0F1h,0C1h,0E1h,000h,000h,0E5h,02Ah + t_push_rel (0001) 00000003 + defb 0E3h,0C9h + t_org_rel (01) 00000000 + t_org_rel (01) 00000003 + t_org_rel (01) 00000005 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORBANKLEAVE.asm b/src/libiar/MONITORBANKLEAVE.asm new file mode 100755 index 00000000..78bb9566 --- /dev/null +++ b/src/libiar/MONITORBANKLEAVE.asm @@ -0,0 +1,20 @@ +; MONITORBANKLEAVE.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_BANK_LEAVE_L09 + rseg RCODE +rcode_base: + public ?MONITOR_BANK_LEAVE_L09 +?MONITOR_BANK_LEAVE_L09 equ rcode_base+00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0F1h,0E2h + defw LWRD ?BANK_FAST_LEAVE_L08 + defb 0FBh,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORBANKLEAVE32.asm b/src/libiar/MONITORBANKLEAVE32.asm new file mode 100755 index 00000000..aed8c51a --- /dev/null +++ b/src/libiar/MONITORBANKLEAVE32.asm @@ -0,0 +1,21 @@ +; MONITORBANKLEAVE32.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_BANK_LEAVE_32_L09 + rseg RCODE +rcode_base: + public ?MONITOR_BANK_LEAVE_32_L09 +?MONITOR_BANK_LEAVE_32_L09 equ rcode_base+00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0F1h,0DDh,0F9h,0DDh,0E1h,0D1h,033h + defb 033h,0E2h + defw LWRD ?BANK_FAST_LEAVE_L08 + defb 0FBh,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORBANKLEAVEIX.asm b/src/libiar/MONITORBANKLEAVEIX.asm new file mode 100755 index 00000000..c076b9f9 --- /dev/null +++ b/src/libiar/MONITORBANKLEAVEIX.asm @@ -0,0 +1,20 @@ +; MONITORBANKLEAVEIX.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_BANK_LEAVE_IX_L09 + rseg RCODE +rcode_base: + public ?MONITOR_BANK_LEAVE_IX_L09 +?MONITOR_BANK_LEAVE_IX_L09 equ rcode_base+00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0F1h,0DDh,0F9h,0DDh,0E1h,0E2h + defw LWRD ?BANK_FAST_LEAVE_L08 + defb 0FBh,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORBANKLEAVEPOP.asm b/src/libiar/MONITORBANKLEAVEPOP.asm new file mode 100755 index 00000000..dec508f1 --- /dev/null +++ b/src/libiar/MONITORBANKLEAVEPOP.asm @@ -0,0 +1,21 @@ +; MONITORBANKLEAVEPOP.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_BANK_LEAVE_POP_L09 + rseg RCODE +rcode_base: + public ?MONITOR_BANK_LEAVE_POP_L09 +?MONITOR_BANK_LEAVE_POP_L09 equ rcode_base+00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0F1h,0DDh,0F9h,0DDh,0E1h,0D1h,0C1h + defb 0E2h + defw LWRD ?BANK_FAST_LEAVE_L08 + defb 0FBh,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORLEAVE.asm b/src/libiar/MONITORLEAVE.asm new file mode 100755 index 00000000..67050a4a --- /dev/null +++ b/src/libiar/MONITORLEAVE.asm @@ -0,0 +1,16 @@ +; MONITORLEAVE.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_LEAVE_L09 + rseg RCODE +rcode_base: + public ?MONITOR_LEAVE_L09 +?MONITOR_LEAVE_L09 equ rcode_base+00000000h + defb 0F1h,0E0h,0FBh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORLEAVE32.asm b/src/libiar/MONITORLEAVE32.asm new file mode 100755 index 00000000..41d2c3fc --- /dev/null +++ b/src/libiar/MONITORLEAVE32.asm @@ -0,0 +1,17 @@ +; MONITORLEAVE32.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_LEAVE_32_L09 + rseg RCODE +rcode_base: + public ?MONITOR_LEAVE_32_L09 +?MONITOR_LEAVE_32_L09 equ rcode_base+00000000h + defb 0F1h,0DDh,0F9h,0DDh,0E1h,0D1h,033h + defb 033h,0E0h,0FBh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORLEAVEIX.asm b/src/libiar/MONITORLEAVEIX.asm new file mode 100755 index 00000000..f09cc547 --- /dev/null +++ b/src/libiar/MONITORLEAVEIX.asm @@ -0,0 +1,17 @@ +; MONITORLEAVEIX.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_LEAVE_IX_L09 + rseg RCODE +rcode_base: + public ?MONITOR_LEAVE_IX_L09 +?MONITOR_LEAVE_IX_L09 equ rcode_base+00000000h + defb 0F1h,0DDh,0F9h,0DDh,0E1h,0E0h,0FBh + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORLEAVEIXPA.asm b/src/libiar/MONITORLEAVEIXPA.asm new file mode 100755 index 00000000..5e08d880 --- /dev/null +++ b/src/libiar/MONITORLEAVEIXPA.asm @@ -0,0 +1,17 @@ +; MONITORLEAVEIXPA.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_LEAVE_IX_PA_L09 + rseg RCODE +rcode_base: + public ?MONITOR_LEAVE_IX_PA_L09 +?MONITOR_LEAVE_IX_PA_L09 equ rcode_base+00000000h + defb 067h,0F1h,07Ch,0DDh,0F9h,0DDh,0E1h + defb 0E0h,0FBh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORLEAVEPA.asm b/src/libiar/MONITORLEAVEPA.asm new file mode 100755 index 00000000..cbb3af0d --- /dev/null +++ b/src/libiar/MONITORLEAVEPA.asm @@ -0,0 +1,16 @@ +; MONITORLEAVEPA.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_LEAVE_PA_L09 + rseg RCODE +rcode_base: + public ?MONITOR_LEAVE_PA_L09 +?MONITOR_LEAVE_PA_L09 equ rcode_base+00000000h + defb 067h,0F1h,07Ch,0E0h,0FBh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/MONITORLEAVEPOP.asm b/src/libiar/MONITORLEAVEPOP.asm new file mode 100755 index 00000000..bf8d1243 --- /dev/null +++ b/src/libiar/MONITORLEAVEPOP.asm @@ -0,0 +1,17 @@ +; MONITORLEAVEPOP.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?MONITOR_LEAVE_POP_L09 + rseg RCODE +rcode_base: + public ?MONITOR_LEAVE_POP_L09 +?MONITOR_LEAVE_POP_L09 equ rcode_base+00000000h + defb 05Fh,0F1h,07Bh,0DDh,0F9h,0DDh,0E1h + defb 0D1h,0C1h,0E0h,0FBh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SCDIV.asm b/src/libiar/SCDIV.asm new file mode 100755 index 00000000..fb9dd99e --- /dev/null +++ b/src/libiar/SCDIV.asm @@ -0,0 +1,23 @@ +; SCDIV.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SC_DIV_L01 + rseg RCODE +rcode_base: + public ?SC_DIV_L01 +?SC_DIV_L01 equ rcode_base+00000000h + extern ?C_FIND_SIGN_L01 + extern ?C_DIVMOD_L01 + defb 0C5h,0D5h,04Fh,0AFh,0CDh + defw LWRD ?C_FIND_SIGN_L01 + defb 0F5h,0CDh + defw LWRD ?C_DIVMOD_L01 + defb 0F1h,0B7h,079h,028h,003h,03Ch,018h + defb 002h,0EEh,0FFh,0D1h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SCMOD.asm b/src/libiar/SCMOD.asm new file mode 100755 index 00000000..7c08b0fa --- /dev/null +++ b/src/libiar/SCMOD.asm @@ -0,0 +1,23 @@ +; SCMOD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SC_MOD_L01 + rseg RCODE +rcode_base: + public ?SC_MOD_L01 +?SC_MOD_L01 equ rcode_base+00000000h + extern ?C_DIVMOD_L01 + extern ?C_FIND_SIGN_L01 + defb 0C5h,0D5h,04Fh,03Eh,001h,0CDh + defw LWRD ?C_FIND_SIGN_L01 + defb 0F5h,0CDh + defw LWRD ?C_DIVMOD_L01 + defb 0F1h,0B7h,07Ah,020h,002h,0EDh,044h + defb 0D1h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SCRSH.asm b/src/libiar/SCRSH.asm new file mode 100755 index 00000000..8fa1ad55 --- /dev/null +++ b/src/libiar/SCRSH.asm @@ -0,0 +1,17 @@ +; SCRSH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SC_RSH_L01 + rseg RCODE +rcode_base: + public ?SC_RSH_L01 +?SC_RSH_L01 equ rcode_base+00000000h + defb 004h,005h,0C8h,0CBh,02Fh,010h,0FCh + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SCRSHASG.asm b/src/libiar/SCRSHASG.asm new file mode 100755 index 00000000..7a443004 --- /dev/null +++ b/src/libiar/SCRSHASG.asm @@ -0,0 +1,19 @@ +; SCRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SC_RSHASG_L01 + rseg RCODE +rcode_base: + public ?SC_RSHASG_L01 +?SC_RSHASG_L01 equ rcode_base+00000000h + extern ?SC_RSH_L01 + defb 07Eh,0CDh + defw LWRD ?SC_RSH_L01 + defb 077h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SDIVMOD.asm b/src/libiar/SDIVMOD.asm new file mode 100755 index 00000000..289801bf --- /dev/null +++ b/src/libiar/SDIVMOD.asm @@ -0,0 +1,19 @@ +; SDIVMOD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_DIVMOD_L02 + rseg RCODE +rcode_base: + public ?S_DIVMOD_L02 +?S_DIVMOD_L02 equ rcode_base+00000000h + defb 021h,000h,000h,03Eh,011h,0CBh,013h + defb 0CBh,012h,03Dh,0C8h,0CBh,015h,0CBh + defb 014h,0EDh,042h,030h,0F2h,009h,018h + defb 0EFh + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SFINDSIGN.asm b/src/libiar/SFINDSIGN.asm new file mode 100755 index 00000000..ef4d6f68 --- /dev/null +++ b/src/libiar/SFINDSIGN.asm @@ -0,0 +1,19 @@ +; SFINDSIGN.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_FIND_SIGN_L02 + rseg RCODE +rcode_base: + public ?S_FIND_SIGN_L02 +?S_FIND_SIGN_L02 equ rcode_base+00000000h + defb 0CBh,078h,028h,009h,0AFh,091h,04Fh + defb 03Eh,000h,098h,047h,03Eh,001h,0CBh + defb 07Ah,0C8h,0F5h,0AFh,093h,05Fh,03Eh + defb 000h,09Ah,057h,0F1h,0EEh,001h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLCMP.asm b/src/libiar/SLCMP.asm new file mode 100755 index 00000000..5441c566 --- /dev/null +++ b/src/libiar/SLCMP.asm @@ -0,0 +1,22 @@ +; SLCMP.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SL_CMP_L03 + rseg RCODE +rcode_base: + public ?SL_CMP_L03 +?SL_CMP_L03 equ rcode_base+00000000h + defb 0EBh,0E3h,0D5h,0C5h,0F5h,0D5h,0C5h + defb 0EBh,021h,00Fh,000h,039h,07Eh,0EEh + defb 080h,047h,072h,02Bh,04Eh,073h,0EBh + defb 0E1h,07Ch,0EEh,080h,067h,0EDh,042h + defb 0E1h,020h,00Ah,0EBh,02Bh,07Eh,02Bh + defb 06Eh,067h,0EBh,0A7h,0EDh,052h,0C1h + defb 078h,0C1h,0E1h,0D1h,033h,033h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLDIV.asm b/src/libiar/SLDIV.asm new file mode 100755 index 00000000..93baf447 --- /dev/null +++ b/src/libiar/SLDIV.asm @@ -0,0 +1,31 @@ +; SLDIV.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SL_DIV_L03 + rseg RCODE +rcode_base: + public ?SL_DIV_L03 +?SL_DIV_L03 equ rcode_base+00000000h + extern ?L_FIND_SIGN_L03 + extern ?L_DIVMOD_L03 + extern ?L_NOT_L03 + extern ?L_INC_L03 + defb 0EBh,0E3h,0F5h,0DDh,0E5h,0DDh,021h + defb 000h,000h,0DDh,039h,0C5h,0D5h,0DDh + defb 056h,009h,0DDh,074h,009h,0DDh,05Eh + defb 008h,0DDh,075h,008h,0AFh,0CDh + defw LWRD ?L_FIND_SIGN_L03 + defb 0CDh + defw LWRD ?L_DIVMOD_L03 + defb 0E1h,0C1h,0B7h,0CCh + defw LWRD ?L_NOT_L03 + defb 0C4h + defw LWRD ?L_INC_L03 + defb 0DDh,0E1h,0F1h,0D1h,033h,033h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLDIVASG.asm b/src/libiar/SLDIVASG.asm new file mode 100755 index 00000000..4ec88b5a --- /dev/null +++ b/src/libiar/SLDIVASG.asm @@ -0,0 +1,22 @@ +; SLDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SL_DIVASG_L03 + rseg RCODE +rcode_base: + public ?SL_DIVASG_L03 +?SL_DIVASG_L03 equ rcode_base+00000000h + extern ?SL_DIV_L03 + extern ?L_END_MULDIVASG_L03 + defb 0C5h,0D5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0CDh + defw LWRD ?SL_DIV_L03 + defb 0C3h + defw LWRD ?L_END_MULDIVASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLMOD.asm b/src/libiar/SLMOD.asm new file mode 100755 index 00000000..5de1a312 --- /dev/null +++ b/src/libiar/SLMOD.asm @@ -0,0 +1,32 @@ +; SLMOD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SL_MOD_L03 + rseg RCODE +rcode_base: + public ?SL_MOD_L03 +?SL_MOD_L03 equ rcode_base+00000000h + extern ?L_FIND_SIGN_L03 + extern ?L_DIVMOD_L03 + extern ?L_NOT_L03 + extern ?L_INC_L03 + defb 0EBh,0E3h,0F5h,0DDh,0E5h,0DDh,021h + defb 000h,000h,0DDh,039h,0C5h,0D5h,0DDh + defb 056h,009h,0DDh,074h,009h,0DDh,05Eh + defb 008h,0DDh,075h,008h,03Eh,001h,0CDh + defw LWRD ?L_FIND_SIGN_L03 + defb 0CDh + defw LWRD ?L_DIVMOD_L03 + defb 0B7h,020h,006h,0CDh + defw LWRD ?L_NOT_L03 + defb 0CDh + defw LWRD ?L_INC_L03 + defb 0DDh,0F9h,0DDh,0E1h,0F1h,0D1h,033h + defb 033h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLMODASG.asm b/src/libiar/SLMODASG.asm new file mode 100755 index 00000000..41c824e1 --- /dev/null +++ b/src/libiar/SLMODASG.asm @@ -0,0 +1,22 @@ +; SLMODASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SL_MODASG_L03 + rseg RCODE +rcode_base: + public ?SL_MODASG_L03 +?SL_MODASG_L03 equ rcode_base+00000000h + extern ?SL_MOD_L03 + extern ?L_END_MULDIVASG_L03 + defb 0C5h,0D5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0CDh + defw LWRD ?SL_MOD_L03 + defb 0C3h + defw LWRD ?L_END_MULDIVASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLRSH.asm b/src/libiar/SLRSH.asm new file mode 100755 index 00000000..e9d8889c --- /dev/null +++ b/src/libiar/SLRSH.asm @@ -0,0 +1,17 @@ +; SLRSH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SL_RSH_L03 + rseg RCODE +rcode_base: + public ?SL_RSH_L03 +?SL_RSH_L03 equ rcode_base+00000000h + defb 0B7h,0C8h,0CBh,028h,0CBh,019h,0CBh + defb 01Ch,0CBh,01Dh,03Dh,020h,0F5h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLRSHASG.asm b/src/libiar/SLRSHASG.asm new file mode 100755 index 00000000..be98c019 --- /dev/null +++ b/src/libiar/SLRSHASG.asm @@ -0,0 +1,22 @@ +; SLRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SL_RSHASG_L03 + rseg RCODE +rcode_base: + public ?SL_RSHASG_L03 +?SL_RSHASG_L03 equ rcode_base+00000000h + extern ?SL_RSH_L03 + extern ?L_END_ASG_L03 + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0EBh,0CDh + defw LWRD ?SL_RSH_L03 + defb 0C3h + defw LWRD ?L_END_ASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLSH.asm b/src/libiar/SLSH.asm new file mode 100755 index 00000000..a3b72ddc --- /dev/null +++ b/src/libiar/SLSH.asm @@ -0,0 +1,17 @@ +; SLSH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_LSH_L02 + rseg RCODE +rcode_base: + public ?S_LSH_L02 +?S_LSH_L02 equ rcode_base+00000000h + defb 004h,005h,0C8h,0EBh,029h,010h,0FDh + defb 0EBh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLSHASG.asm b/src/libiar/SLSHASG.asm new file mode 100755 index 00000000..746658d5 --- /dev/null +++ b/src/libiar/SLSHASG.asm @@ -0,0 +1,19 @@ +; SLSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_LSHASG_L02 + rseg RCODE +rcode_base: + public ?S_LSHASG_L02 +?S_LSHASG_L02 equ rcode_base+00000000h + extern ?S_LSH_L02 + defb 05Eh,023h,056h,0CDh + defw LWRD ?S_LSH_L02 + defb 072h,02Bh,073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLSHASGBCprim.asm b/src/libiar/SLSHASGBCprim.asm new file mode 100755 index 00000000..1c5fa378 --- /dev/null +++ b/src/libiar/SLSHASGBCprim.asm @@ -0,0 +1,18 @@ +; SLSHASGBCprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_LSHASG_BC_prim_L12 + rseg RCODE +rcode_base: + public ?S_LSHASG_BC_prim_L12 +?S_LSHASG_BC_prim_L12 equ rcode_base+00000000h + defb 0D9h,0B7h,028h,007h,0CBh,021h,0CBh + defb 010h,03Dh,020h,0F9h,0C5h,0D9h,0E1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SLSHASGDEprim.asm b/src/libiar/SLSHASGDEprim.asm new file mode 100755 index 00000000..ee6cc856 --- /dev/null +++ b/src/libiar/SLSHASGDEprim.asm @@ -0,0 +1,17 @@ +; SLSHASGDEprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_LSHASG_DE_prim_L12 + rseg RCODE +rcode_base: + public ?S_LSHASG_DE_prim_L12 +?S_LSHASG_DE_prim_L12 equ rcode_base+00000000h + defb 0D9h,0B7h,028h,006h,0EBh,029h,03Dh + defb 020h,0FCh,0EBh,0D5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SMUL.asm b/src/libiar/SMUL.asm new file mode 100755 index 00000000..e5a6ce7e --- /dev/null +++ b/src/libiar/SMUL.asm @@ -0,0 +1,19 @@ +; SMUL.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_MUL_L02 + rseg RCODE +rcode_base: + public ?S_MUL_L02 +?S_MUL_L02 equ rcode_base+00000000h + defb 0F5h,0C5h,0E5h,078h,042h,051h,067h + defb 06Bh,0EDh,04Ch,0EDh,06Ch,0EDh,05Ch + defb 079h,085h,082h,057h,0E1h,0C1h,0F1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SMULASG.asm b/src/libiar/SMULASG.asm new file mode 100755 index 00000000..c773655a --- /dev/null +++ b/src/libiar/SMULASG.asm @@ -0,0 +1,19 @@ +; SMULASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_MULASG_L02 + rseg RCODE +rcode_base: + public ?S_MULASG_L02 +?S_MULASG_L02 equ rcode_base+00000000h + extern ?S_MUL_L02 + defb 05Eh,023h,056h,0CDh + defw LWRD ?S_MUL_L02 + defb 072h,02Bh,073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SMULASGBCprim.asm b/src/libiar/SMULASGBCprim.asm new file mode 100755 index 00000000..3679ce6f --- /dev/null +++ b/src/libiar/SMULASGBCprim.asm @@ -0,0 +1,19 @@ +; SMULASGBCprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_MULASG_BC_prim_L12 + rseg RCODE +rcode_base: + public ?S_MULASG_BC_prim_L12 +?S_MULASG_BC_prim_L12 equ rcode_base+00000000h + extern ?S_MUL_L02 + defb 0C5h,0D9h,0EBh,0E3h,0EBh,0CDh + defw LWRD ?S_MUL_L02 + defb 042h,04Bh,0D1h,0C5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SMULASGDEprim.asm b/src/libiar/SMULASGDEprim.asm new file mode 100755 index 00000000..782bc6ef --- /dev/null +++ b/src/libiar/SMULASGDEprim.asm @@ -0,0 +1,19 @@ +; SMULASGDEprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_MULASG_DE_prim_L12 + rseg RCODE +rcode_base: + public ?S_MULASG_DE_prim_L12 +?S_MULASG_DE_prim_L12 equ rcode_base+00000000h + extern ?S_MUL_L02 + defb 0C5h,0D9h,0E1h,0C5h,044h,04Dh,0CDh + defw LWRD ?S_MUL_L02 + defb 0C1h,0D5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SMULASGIX.asm b/src/libiar/SMULASGIX.asm new file mode 100755 index 00000000..58241196 --- /dev/null +++ b/src/libiar/SMULASGIX.asm @@ -0,0 +1,19 @@ +; SMULASGIX.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_MULASG_IX_L12 + rseg RCODE +rcode_base: + public ?S_MULASG_IX_L12 +?S_MULASG_IX_L12 equ rcode_base+00000000h + extern ?S_MUL_L02 + defb 0D5h,0DDh,0E5h,0D1h,0CDh + defw LWRD ?S_MUL_L02 + defb 0D5h,0EBh,0DDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SMULASGIY.asm b/src/libiar/SMULASGIY.asm new file mode 100755 index 00000000..4d7cadf6 --- /dev/null +++ b/src/libiar/SMULASGIY.asm @@ -0,0 +1,19 @@ +; SMULASGIY.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_MULASG_IY_L12 + rseg RCODE +rcode_base: + public ?S_MULASG_IY_L12 +?S_MULASG_IY_L12 equ rcode_base+00000000h + extern ?S_MUL_L02 + defb 0D5h,0FDh,0E5h,0D1h,0CDh + defw LWRD ?S_MUL_L02 + defb 0D5h,0EBh,0FDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSCMP.asm b/src/libiar/SSCMP.asm new file mode 100755 index 00000000..bf92b9c2 --- /dev/null +++ b/src/libiar/SSCMP.asm @@ -0,0 +1,18 @@ +; SSCMP.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_CMP_L02 + rseg RCODE +rcode_base: + public ?SS_CMP_L02 +?SS_CMP_L02 equ rcode_base+00000000h + defb 0C5h,0E5h,0F5h,07Ch,0EEh,080h,067h + defb 078h,0EEh,080h,047h,0F1h,0A7h,0EDh + defb 042h,0E1h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSDIV.asm b/src/libiar/SSDIV.asm new file mode 100755 index 00000000..b9e5d9d4 --- /dev/null +++ b/src/libiar/SSDIV.asm @@ -0,0 +1,24 @@ +; SSDIV.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_DIV_L02 + rseg RCODE +rcode_base: + public ?SS_DIV_L02 +?SS_DIV_L02 equ rcode_base+00000000h + extern ?S_FIND_SIGN_L02 + extern ?S_DIVMOD_L02 + defb 0F5h,0C5h,0E5h,0AFh,0CDh + defw LWRD ?S_FIND_SIGN_L02 + defb 0F5h,0CDh + defw LWRD ?S_DIVMOD_L02 + defb 0F1h,0B7h,028h,003h,013h,018h,006h + defb 07Bh,02Fh,05Fh,07Ah,02Fh,057h,0E1h + defb 0C1h,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSDIVASG.asm b/src/libiar/SSDIVASG.asm new file mode 100755 index 00000000..ea41231f --- /dev/null +++ b/src/libiar/SSDIVASG.asm @@ -0,0 +1,19 @@ +; SSDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_DIVASG_L02 + rseg RCODE +rcode_base: + public ?SS_DIVASG_L02 +?SS_DIVASG_L02 equ rcode_base+00000000h + extern ?SS_DIV_L02 + defb 05Eh,023h,056h,0CDh + defw LWRD ?SS_DIV_L02 + defb 072h,02Bh,073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSDIVASGBCprim.asm b/src/libiar/SSDIVASGBCprim.asm new file mode 100755 index 00000000..314b806b --- /dev/null +++ b/src/libiar/SSDIVASGBCprim.asm @@ -0,0 +1,20 @@ +; SSDIVASGBCprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_DIVASG_BC_prim_L12 + rseg RCODE +rcode_base: + public ?SS_DIVASG_BC_prim_L12 +?SS_DIVASG_BC_prim_L12 equ rcode_base+00000000h + extern ?SS_DIV_L02 + defb 0C5h,0D9h,0EBh,0E3h,050h,059h,044h + defb 04Dh,0CDh + defw LWRD ?SS_DIV_L02 + defb 042h,04Bh,0D1h,0C5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSDIVASGDEprim.asm b/src/libiar/SSDIVASGDEprim.asm new file mode 100755 index 00000000..9f661442 --- /dev/null +++ b/src/libiar/SSDIVASGDEprim.asm @@ -0,0 +1,19 @@ +; SSDIVASGDEprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_DIVASG_DE_prim_L12 + rseg RCODE +rcode_base: + public ?SS_DIVASG_DE_prim_L12 +?SS_DIVASG_DE_prim_L12 equ rcode_base+00000000h + extern ?SS_DIV_L02 + defb 0C5h,0D9h,0E1h,0C5h,044h,04Dh,0CDh + defw LWRD ?SS_DIV_L02 + defb 0C1h,0D5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSDIVASGIX.asm b/src/libiar/SSDIVASGIX.asm new file mode 100755 index 00000000..a0d97b45 --- /dev/null +++ b/src/libiar/SSDIVASGIX.asm @@ -0,0 +1,19 @@ +; SSDIVASGIX.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_DIVASG_IX_L12 + rseg RCODE +rcode_base: + public ?SS_DIVASG_IX_L12 +?SS_DIVASG_IX_L12 equ rcode_base+00000000h + extern ?SS_DIV_L02 + defb 0D5h,0DDh,0E5h,0D1h,0CDh + defw LWRD ?SS_DIV_L02 + defb 0D5h,0EBh,0DDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSDIVASGIY.asm b/src/libiar/SSDIVASGIY.asm new file mode 100755 index 00000000..3e3b3767 --- /dev/null +++ b/src/libiar/SSDIVASGIY.asm @@ -0,0 +1,19 @@ +; SSDIVASGIY.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_DIVASG_IY_L12 + rseg RCODE +rcode_base: + public ?SS_DIVASG_IY_L12 +?SS_DIVASG_IY_L12 equ rcode_base+00000000h + extern ?SS_DIV_L02 + defb 0D5h,0FDh,0E5h,0D1h,0CDh + defw LWRD ?SS_DIV_L02 + defb 0D5h,0EBh,0FDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSMOD.asm b/src/libiar/SSMOD.asm new file mode 100755 index 00000000..a9cedbf3 --- /dev/null +++ b/src/libiar/SSMOD.asm @@ -0,0 +1,24 @@ +; SSMOD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_MOD_L02 + rseg RCODE +rcode_base: + public ?SS_MOD_L02 +?SS_MOD_L02 equ rcode_base+00000000h + extern ?S_FIND_SIGN_L02 + extern ?S_DIVMOD_L02 + defb 0F5h,0E5h,0C5h,03Eh,001h,0CDh + defw LWRD ?S_FIND_SIGN_L02 + defb 0F5h,0CDh + defw LWRD ?S_DIVMOD_L02 + defb 0F1h,0EBh,0B7h,020h,007h,0AFh,093h + defb 05Fh,03Eh,000h,09Ah,057h,0C1h,0E1h + defb 0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSMODASG.asm b/src/libiar/SSMODASG.asm new file mode 100755 index 00000000..330a92d3 --- /dev/null +++ b/src/libiar/SSMODASG.asm @@ -0,0 +1,19 @@ +; SSMODASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_MODASG_L02 + rseg RCODE +rcode_base: + public ?SS_MODASG_L02 +?SS_MODASG_L02 equ rcode_base+00000000h + extern ?SS_MOD_L02 + defb 05Eh,023h,056h,0CDh + defw LWRD ?SS_MOD_L02 + defb 072h,02Bh,073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSMODASGBCprim.asm b/src/libiar/SSMODASGBCprim.asm new file mode 100755 index 00000000..23e0636e --- /dev/null +++ b/src/libiar/SSMODASGBCprim.asm @@ -0,0 +1,20 @@ +; SSMODASGBCprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_MODASG_BC_prim_L12 + rseg RCODE +rcode_base: + public ?SS_MODASG_BC_prim_L12 +?SS_MODASG_BC_prim_L12 equ rcode_base+00000000h + extern ?SS_MOD_L02 + defb 0C5h,0D9h,0EBh,0E3h,050h,059h,044h + defb 04Dh,0CDh + defw LWRD ?SS_MOD_L02 + defb 042h,04Bh,0D1h,0C5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSMODASGDEprim.asm b/src/libiar/SSMODASGDEprim.asm new file mode 100755 index 00000000..220ba776 --- /dev/null +++ b/src/libiar/SSMODASGDEprim.asm @@ -0,0 +1,19 @@ +; SSMODASGDEprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_MODASG_DE_prim_L12 + rseg RCODE +rcode_base: + public ?SS_MODASG_DE_prim_L12 +?SS_MODASG_DE_prim_L12 equ rcode_base+00000000h + extern ?SS_MOD_L02 + defb 0C5h,0D9h,0E1h,0C5h,044h,04Dh,0CDh + defw LWRD ?SS_MOD_L02 + defb 0C1h,0D5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSMODASGIX.asm b/src/libiar/SSMODASGIX.asm new file mode 100755 index 00000000..eab3eee3 --- /dev/null +++ b/src/libiar/SSMODASGIX.asm @@ -0,0 +1,19 @@ +; SSMODASGIX.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_MODASG_IX_L12 + rseg RCODE +rcode_base: + public ?SS_MODASG_IX_L12 +?SS_MODASG_IX_L12 equ rcode_base+00000000h + extern ?SS_MOD_L02 + defb 0D5h,0DDh,0E5h,0D1h,0CDh + defw LWRD ?SS_MOD_L02 + defb 0D5h,0EBh,0DDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSMODASGIY.asm b/src/libiar/SSMODASGIY.asm new file mode 100755 index 00000000..282b7f94 --- /dev/null +++ b/src/libiar/SSMODASGIY.asm @@ -0,0 +1,19 @@ +; SSMODASGIY.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_MODASG_IY_L12 + rseg RCODE +rcode_base: + public ?SS_MODASG_IY_L12 +?SS_MODASG_IY_L12 equ rcode_base+00000000h + extern ?SS_MOD_L02 + defb 0D5h,0FDh,0E5h,0D1h,0CDh + defw LWRD ?SS_MOD_L02 + defb 0D5h,0EBh,0FDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSRSH.asm b/src/libiar/SSRSH.asm new file mode 100755 index 00000000..02b522d5 --- /dev/null +++ b/src/libiar/SSRSH.asm @@ -0,0 +1,17 @@ +; SSRSH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_RSH_L02 + rseg RCODE +rcode_base: + public ?SS_RSH_L02 +?SS_RSH_L02 equ rcode_base+00000000h + defb 004h,005h,0C8h,0CBh,02Ah,0CBh,01Bh + defb 010h,0FAh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSRSHASG.asm b/src/libiar/SSRSHASG.asm new file mode 100755 index 00000000..8d27338d --- /dev/null +++ b/src/libiar/SSRSHASG.asm @@ -0,0 +1,19 @@ +; SSRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_RSHASG_L02 + rseg RCODE +rcode_base: + public ?SS_RSHASG_L02 +?SS_RSHASG_L02 equ rcode_base+00000000h + extern ?SS_RSH_L02 + defb 05Eh,023h,056h,0CDh + defw LWRD ?SS_RSH_L02 + defb 072h,02Bh,073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSRSHASGBCprim.asm b/src/libiar/SSRSHASGBCprim.asm new file mode 100755 index 00000000..83d6e13a --- /dev/null +++ b/src/libiar/SSRSHASGBCprim.asm @@ -0,0 +1,18 @@ +; SSRSHASGBCprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_RSHASG_BC_prim_L12 + rseg RCODE +rcode_base: + public ?SS_RSHASG_BC_prim_L12 +?SS_RSHASG_BC_prim_L12 equ rcode_base+00000000h + defb 0D9h,0B7h,028h,007h,0CBh,028h,0CBh + defb 019h,03Dh,020h,0F9h,0C5h,0D9h,0E1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSRSHASGDEprim.asm b/src/libiar/SSRSHASGDEprim.asm new file mode 100755 index 00000000..774f92da --- /dev/null +++ b/src/libiar/SSRSHASGDEprim.asm @@ -0,0 +1,18 @@ +; SSRSHASGDEprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_RSHASG_DE_prim_L12 + rseg RCODE +rcode_base: + public ?SS_RSHASG_DE_prim_L12 +?SS_RSHASG_DE_prim_L12 equ rcode_base+00000000h + defb 0D9h,0B7h,028h,007h,0CBh,02Ah,0CBh + defb 01Bh,03Dh,020h,0F9h,0D5h,0D9h,0E1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSRSHASGIX.asm b/src/libiar/SSRSHASGIX.asm new file mode 100755 index 00000000..e0704a7c --- /dev/null +++ b/src/libiar/SSRSHASGIX.asm @@ -0,0 +1,19 @@ +; SSRSHASGIX.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_RSHASG_IX_L12 + rseg RCODE +rcode_base: + public ?SS_RSHASG_IX_L12 +?SS_RSHASG_IX_L12 equ rcode_base+00000000h + extern ?SS_RSH_L02 + defb 0D5h,0DDh,0E5h,0D1h,0CDh + defw LWRD ?SS_RSH_L02 + defb 0D5h,0DDh,0E1h,0EBh,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSRSHASGIY.asm b/src/libiar/SSRSHASGIY.asm new file mode 100755 index 00000000..2c810813 --- /dev/null +++ b/src/libiar/SSRSHASGIY.asm @@ -0,0 +1,19 @@ +; SSRSHASGIY.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?SS_RSHASG_IY_L12 + rseg RCODE +rcode_base: + public ?SS_RSHASG_IY_L12 +?SS_RSHASG_IY_L12 equ rcode_base+00000000h + extern ?SS_RSH_L02 + defb 0D5h,0FDh,0E5h,0D1h,0CDh + defw LWRD ?SS_RSH_L02 + defb 0D5h,0FDh,0E1h,0EBh,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSSWITCH.asm b/src/libiar/SSSWITCH.asm new file mode 100755 index 00000000..bb28ccda --- /dev/null +++ b/src/libiar/SSSWITCH.asm @@ -0,0 +1,20 @@ +; SSSWITCH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_S_SWITCH_L06 + rseg RCODE +rcode_base: + public ?S_S_SWITCH_L06 +?S_S_SWITCH_L06 equ rcode_base+00000000h + extern ?S_SWITCH_END_L06 + defb 0E3h,0F5h,0D5h,07Bh,096h,023h,05Fh + defb 07Ah,09Eh,023h,057h,07Bh,096h,023h + defb 07Ah,09Eh,023h,0C3h + defw LWRD ?S_SWITCH_END_L06 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SSWITCHEND.asm b/src/libiar/SSWITCHEND.asm new file mode 100755 index 00000000..743e7ebc --- /dev/null +++ b/src/libiar/SSWITCHEND.asm @@ -0,0 +1,17 @@ +; SSWITCHEND.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_SWITCH_END_L06 + rseg RCODE +rcode_base: + public ?S_SWITCH_END_L06 +?S_SWITCH_END_L06 equ rcode_base+00000000h + defb 030h,004h,0EBh,023h,029h,019h,05Eh + defb 023h,056h,0EBh,0D1h,0F1h,0E3h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/STRCAT.asm b/src/libiar/STRCAT.asm new file mode 100755 index 00000000..4a86a192 --- /dev/null +++ b/src/libiar/STRCAT.asm @@ -0,0 +1,18 @@ +; STRCAT.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?STRCAT_L11 + rseg RCODE +rcode_base: + public ?STRCAT_L11 +?STRCAT_L11 equ rcode_base+00000000h + defb 0E5h,0D5h,0C5h,0F5h,0AFh,047h,04Fh + defb 0EDh,0B1h,02Bh,0EBh,0BEh,0EDh,0A0h + defb 020h,0FBh,0F1h,0C1h,0D1h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/STRCHR.asm b/src/libiar/STRCHR.asm new file mode 100755 index 00000000..81b1208e --- /dev/null +++ b/src/libiar/STRCHR.asm @@ -0,0 +1,17 @@ +; STRCHR.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?STRCHR_L11 + rseg RCODE +rcode_base: + public ?STRCHR_L11 +?STRCHR_L11 equ rcode_base+00000000h + defb 07Eh,0BBh,0C8h,0B7h,023h,020h,0F9h + defb 021h,000h,000h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/STRCMP.asm b/src/libiar/STRCMP.asm new file mode 100755 index 00000000..006cbc26 --- /dev/null +++ b/src/libiar/STRCMP.asm @@ -0,0 +1,18 @@ +; STRCMP.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?STRCMP_L11 + rseg RCODE +rcode_base: + public ?STRCMP_L11 +?STRCMP_L11 equ rcode_base+00000000h + defb 0F5h,0D5h,01Ah,0BEh,020h,009h,013h + defb 023h,0B7h,020h,0F7h,021h,000h,000h + defb 011h,0CBh,01Ch,0D1h,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/STRCPY.asm b/src/libiar/STRCPY.asm new file mode 100755 index 00000000..ab8be072 --- /dev/null +++ b/src/libiar/STRCPY.asm @@ -0,0 +1,18 @@ +; STRCPY.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?STRCPY_L11 + rseg RCODE +rcode_base: + public ?STRCPY_L11 +?STRCPY_L11 equ rcode_base+00000000h + defb 0F5h,0E5h,0D5h,0C5h,0AFh,0EBh,0BEh + defb 0EDh,0A0h,020h,0FBh,0C1h,0D1h,0E1h + defb 0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/STRLEN.asm b/src/libiar/STRLEN.asm new file mode 100755 index 00000000..965b5b16 --- /dev/null +++ b/src/libiar/STRLEN.asm @@ -0,0 +1,18 @@ +; STRLEN.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?STRLEN_L11 + rseg RCODE +rcode_base: + public ?STRLEN_L11 +?STRLEN_L11 equ rcode_base+00000000h + defb 0C5h,0F5h,0AFh,047h,04Fh,0EDh,0B1h + defb 021h,0FFh,0FFh,0EDh,042h,0F1h,0C1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/SVSWITCH.asm b/src/libiar/SVSWITCH.asm new file mode 100755 index 00000000..cc6ff642 --- /dev/null +++ b/src/libiar/SVSWITCH.asm @@ -0,0 +1,21 @@ +; SVSWITCH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?S_V_SWITCH_L06 + rseg RCODE +rcode_base: + public ?S_V_SWITCH_L06 +?S_V_SWITCH_L06 equ rcode_base+00000000h + extern ?V_SWITCH_END_L06 + defb 0E3h,0F5h,0C5h,04Eh,023h,046h,023h + defb 078h,0B1h,028h,00Dh,00Bh,07Bh,096h + defb 023h,020h,0F5h,07Ah,096h,020h,0F1h + defb 023h,023h,023h,009h,009h,0C3h + defw LWRD ?V_SWITCH_END_L06 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/UCDIV.asm b/src/libiar/UCDIV.asm new file mode 100755 index 00000000..61080706 --- /dev/null +++ b/src/libiar/UCDIV.asm @@ -0,0 +1,19 @@ +; UCDIV.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UC_DIV_L01 + rseg RCODE +rcode_base: + public ?UC_DIV_L01 +?UC_DIV_L01 equ rcode_base+00000000h + extern ?C_DIVMOD_L01 + defb 0C5h,0D5h,04Fh,0CDh + defw LWRD ?C_DIVMOD_L01 + defb 079h,0EEh,0FFh,0D1h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/UCMOD.asm b/src/libiar/UCMOD.asm new file mode 100755 index 00000000..0aba7e45 --- /dev/null +++ b/src/libiar/UCMOD.asm @@ -0,0 +1,19 @@ +; UCMOD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UC_MOD_L01 + rseg RCODE +rcode_base: + public ?UC_MOD_L01 +?UC_MOD_L01 equ rcode_base+00000000h + extern ?C_DIVMOD_L01 + defb 0C5h,0D5h,04Fh,0CDh + defw LWRD ?C_DIVMOD_L01 + defb 07Ah,0D1h,0C1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/UCRSH.asm b/src/libiar/UCRSH.asm new file mode 100755 index 00000000..38fa8067 --- /dev/null +++ b/src/libiar/UCRSH.asm @@ -0,0 +1,17 @@ +; UCRSH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UC_RSH_L01 + rseg RCODE +rcode_base: + public ?UC_RSH_L01 +?UC_RSH_L01 equ rcode_base+00000000h + defb 004h,005h,0C8h,0CBh,03Fh,010h,0FCh + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/UCRSHASG.asm b/src/libiar/UCRSHASG.asm new file mode 100755 index 00000000..2190c0ba --- /dev/null +++ b/src/libiar/UCRSHASG.asm @@ -0,0 +1,19 @@ +; UCRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UC_RSHASG_L01 + rseg RCODE +rcode_base: + public ?UC_RSHASG_L01 +?UC_RSHASG_L01 equ rcode_base+00000000h + extern ?UC_RSH_L01 + defb 07Eh,0CDh + defw LWRD ?UC_RSH_L01 + defb 077h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ULDIV.asm b/src/libiar/ULDIV.asm new file mode 100755 index 00000000..70bffbe4 --- /dev/null +++ b/src/libiar/ULDIV.asm @@ -0,0 +1,25 @@ +; ULDIV.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UL_DIV_L03 + rseg RCODE +rcode_base: + public ?UL_DIV_L03 +?UL_DIV_L03 equ rcode_base+00000000h + extern ?L_DIVMOD_L03 + extern ?L_NOT_L03 + defb 0EBh,0E3h,0F5h,0DDh,0E5h,0DDh,021h + defb 000h,000h,0DDh,039h,0C5h,0D5h,0DDh + defb 056h,009h,0DDh,074h,009h,0DDh,05Eh + defb 008h,0DDh,075h,008h,0CDh + defw LWRD ?L_DIVMOD_L03 + defb 0E1h,0C1h,0CDh + defw LWRD ?L_NOT_L03 + defb 0DDh,0E1h,0F1h,0D1h,033h,033h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ULDIVASG.asm b/src/libiar/ULDIVASG.asm new file mode 100755 index 00000000..64c0bb66 --- /dev/null +++ b/src/libiar/ULDIVASG.asm @@ -0,0 +1,22 @@ +; ULDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UL_DIVASG_L03 + rseg RCODE +rcode_base: + public ?UL_DIVASG_L03 +?UL_DIVASG_L03 equ rcode_base+00000000h + extern ?UL_DIV_L03 + extern ?L_END_MULDIVASG_L03 + defb 0C5h,0D5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0CDh + defw LWRD ?UL_DIV_L03 + defb 0C3h + defw LWRD ?L_END_MULDIVASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ULMOD.asm b/src/libiar/ULMOD.asm new file mode 100755 index 00000000..1b8bf1c3 --- /dev/null +++ b/src/libiar/ULMOD.asm @@ -0,0 +1,23 @@ +; ULMOD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UL_MOD_L03 + rseg RCODE +rcode_base: + public ?UL_MOD_L03 +?UL_MOD_L03 equ rcode_base+00000000h + extern ?L_DIVMOD_L03 + defb 0EBh,0E3h,0F5h,0DDh,0E5h,0DDh,021h + defb 000h,000h,0DDh,039h,0C5h,0D5h,0DDh + defb 056h,009h,0DDh,074h,009h,0DDh,05Eh + defb 008h,0DDh,075h,008h,0CDh + defw LWRD ?L_DIVMOD_L03 + defb 0DDh,0F9h,0DDh,0E1h,0F1h,0D1h,033h + defb 033h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ULMODASG.asm b/src/libiar/ULMODASG.asm new file mode 100755 index 00000000..7fbec554 --- /dev/null +++ b/src/libiar/ULMODASG.asm @@ -0,0 +1,22 @@ +; ULMODASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UL_MODASG_L03 + rseg RCODE +rcode_base: + public ?UL_MODASG_L03 +?UL_MODASG_L03 equ rcode_base+00000000h + extern ?UL_MOD_L03 + extern ?L_END_MULDIVASG_L03 + defb 0C5h,0D5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0CDh + defw LWRD ?UL_MOD_L03 + defb 0C3h + defw LWRD ?L_END_MULDIVASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ULRSH.asm b/src/libiar/ULRSH.asm new file mode 100755 index 00000000..d5914419 --- /dev/null +++ b/src/libiar/ULRSH.asm @@ -0,0 +1,19 @@ +; ULRSH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UL_RSH_L03 + rseg RCODE +rcode_base: + public ?UL_RSH_L03 +?UL_RSH_L03 equ rcode_base+00000000h + defb 0B7h,0C8h,0FEh,008h,038h,009h,06Ch + defb 061h,048h,006h,000h,0D6h,008h,018h + defb 0F2h,0CBh,038h,0CBh,019h,0CBh,01Ch + defb 0CBh,01Dh,03Dh,020h,0F5h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ULRSHASG.asm b/src/libiar/ULRSHASG.asm new file mode 100755 index 00000000..aaf99d4c --- /dev/null +++ b/src/libiar/ULRSHASG.asm @@ -0,0 +1,22 @@ +; ULRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?UL_RSHASG_L03 + rseg RCODE +rcode_base: + public ?UL_RSHASG_L03 +?UL_RSHASG_L03 equ rcode_base+00000000h + extern ?UL_RSH_L03 + extern ?L_END_ASG_L03 + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0EBh,0CDh + defw LWRD ?UL_RSH_L03 + defb 0C3h + defw LWRD ?L_END_ASG_L03 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USDIV.asm b/src/libiar/USDIV.asm new file mode 100755 index 00000000..9694ceb9 --- /dev/null +++ b/src/libiar/USDIV.asm @@ -0,0 +1,20 @@ +; USDIV.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_DIV_L02 + rseg RCODE +rcode_base: + public ?US_DIV_L02 +?US_DIV_L02 equ rcode_base+00000000h + extern ?S_DIVMOD_L02 + defb 0F5h,0E5h,0CDh + defw LWRD ?S_DIVMOD_L02 + defb 07Bh,02Fh,05Fh,07Ah,02Fh,057h,0E1h + defb 0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USDIVASG.asm b/src/libiar/USDIVASG.asm new file mode 100755 index 00000000..39165e63 --- /dev/null +++ b/src/libiar/USDIVASG.asm @@ -0,0 +1,19 @@ +; USDIVASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_DIVASG_L02 + rseg RCODE +rcode_base: + public ?US_DIVASG_L02 +?US_DIVASG_L02 equ rcode_base+00000000h + extern ?US_DIV_L02 + defb 05Eh,023h,056h,0CDh + defw LWRD ?US_DIV_L02 + defb 072h,02Bh,073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USDIVASGBCprim.asm b/src/libiar/USDIVASGBCprim.asm new file mode 100755 index 00000000..79e33487 --- /dev/null +++ b/src/libiar/USDIVASGBCprim.asm @@ -0,0 +1,20 @@ +; USDIVASGBCprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_DIVASG_BC_prim_L12 + rseg RCODE +rcode_base: + public ?US_DIVASG_BC_prim_L12 +?US_DIVASG_BC_prim_L12 equ rcode_base+00000000h + extern ?US_DIV_L02 + defb 0C5h,0D9h,0EBh,0E3h,050h,059h,044h + defb 04Dh,0CDh + defw LWRD ?US_DIV_L02 + defb 042h,04Bh,0D1h,0C5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USDIVASGDEprim.asm b/src/libiar/USDIVASGDEprim.asm new file mode 100755 index 00000000..5a10d6f0 --- /dev/null +++ b/src/libiar/USDIVASGDEprim.asm @@ -0,0 +1,19 @@ +; USDIVASGDEprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_DIVASG_DE_prim_L12 + rseg RCODE +rcode_base: + public ?US_DIVASG_DE_prim_L12 +?US_DIVASG_DE_prim_L12 equ rcode_base+00000000h + extern ?US_DIV_L02 + defb 0C5h,0D9h,0E1h,0C5h,044h,04Dh,0CDh + defw LWRD ?US_DIV_L02 + defb 0C1h,0D5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USDIVASGIX.asm b/src/libiar/USDIVASGIX.asm new file mode 100755 index 00000000..9d78a02f --- /dev/null +++ b/src/libiar/USDIVASGIX.asm @@ -0,0 +1,19 @@ +; USDIVASGIX.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_DIVASG_IX_L12 + rseg RCODE +rcode_base: + public ?US_DIVASG_IX_L12 +?US_DIVASG_IX_L12 equ rcode_base+00000000h + extern ?US_DIV_L02 + defb 0D5h,0DDh,0E5h,0D1h,0CDh + defw LWRD ?US_DIV_L02 + defb 0D5h,0EBh,0DDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USDIVASGIY.asm b/src/libiar/USDIVASGIY.asm new file mode 100755 index 00000000..a1f8b154 --- /dev/null +++ b/src/libiar/USDIVASGIY.asm @@ -0,0 +1,19 @@ +; USDIVASGIY.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_DIVASG_IY_L12 + rseg RCODE +rcode_base: + public ?US_DIVASG_IY_L12 +?US_DIVASG_IY_L12 equ rcode_base+00000000h + extern ?US_DIV_L02 + defb 0D5h,0FDh,0E5h,0D1h,0CDh + defw LWRD ?US_DIV_L02 + defb 0D5h,0EBh,0FDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USMOD.asm b/src/libiar/USMOD.asm new file mode 100755 index 00000000..483da82d --- /dev/null +++ b/src/libiar/USMOD.asm @@ -0,0 +1,19 @@ +; USMOD.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_MOD_L02 + rseg RCODE +rcode_base: + public ?US_MOD_L02 +?US_MOD_L02 equ rcode_base+00000000h + extern ?S_DIVMOD_L02 + defb 0F5h,0E5h,0CDh + defw LWRD ?S_DIVMOD_L02 + defb 0EBh,0E1h,0F1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USMODASG.asm b/src/libiar/USMODASG.asm new file mode 100755 index 00000000..a12694a2 --- /dev/null +++ b/src/libiar/USMODASG.asm @@ -0,0 +1,19 @@ +; USMODASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_MODASG_L02 + rseg RCODE +rcode_base: + public ?US_MODASG_L02 +?US_MODASG_L02 equ rcode_base+00000000h + extern ?US_MOD_L02 + defb 05Eh,023h,056h,0CDh + defw LWRD ?US_MOD_L02 + defb 072h,02Bh,073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USMODASGBCprim.asm b/src/libiar/USMODASGBCprim.asm new file mode 100755 index 00000000..6e5668ad --- /dev/null +++ b/src/libiar/USMODASGBCprim.asm @@ -0,0 +1,20 @@ +; USMODASGBCprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_MODASG_BC_prim_L12 + rseg RCODE +rcode_base: + public ?US_MODASG_BC_prim_L12 +?US_MODASG_BC_prim_L12 equ rcode_base+00000000h + extern ?US_MOD_L02 + defb 0C5h,0D9h,0EBh,0E3h,050h,059h,044h + defb 04Dh,0CDh + defw LWRD ?US_MOD_L02 + defb 042h,04Bh,0D1h,0C5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USMODASGDEprim.asm b/src/libiar/USMODASGDEprim.asm new file mode 100755 index 00000000..b0e81d22 --- /dev/null +++ b/src/libiar/USMODASGDEprim.asm @@ -0,0 +1,19 @@ +; USMODASGDEprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_MODASG_DE_prim_L12 + rseg RCODE +rcode_base: + public ?US_MODASG_DE_prim_L12 +?US_MODASG_DE_prim_L12 equ rcode_base+00000000h + extern ?US_MOD_L02 + defb 0C5h,0D9h,0E1h,0C5h,044h,04Dh,0CDh + defw LWRD ?US_MOD_L02 + defb 0C1h,0D5h,0D9h,0E1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USMODASGIX.asm b/src/libiar/USMODASGIX.asm new file mode 100755 index 00000000..1bc18dbb --- /dev/null +++ b/src/libiar/USMODASGIX.asm @@ -0,0 +1,19 @@ +; USMODASGIX.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_MODASG_IX_L12 + rseg RCODE +rcode_base: + public ?US_MODASG_IX_L12 +?US_MODASG_IX_L12 equ rcode_base+00000000h + extern ?US_MOD_L02 + defb 0D5h,0DDh,0E5h,0D1h,0CDh + defw LWRD ?US_MOD_L02 + defb 0D5h,0EBh,0DDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USMODASGIY.asm b/src/libiar/USMODASGIY.asm new file mode 100755 index 00000000..c0aacd9f --- /dev/null +++ b/src/libiar/USMODASGIY.asm @@ -0,0 +1,19 @@ +; USMODASGIY.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_MODASG_IY_L12 + rseg RCODE +rcode_base: + public ?US_MODASG_IY_L12 +?US_MODASG_IY_L12 equ rcode_base+00000000h + extern ?US_MOD_L02 + defb 0D5h,0FDh,0E5h,0D1h,0CDh + defw LWRD ?US_MOD_L02 + defb 0D5h,0EBh,0FDh,0E1h,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USRSH.asm b/src/libiar/USRSH.asm new file mode 100755 index 00000000..78c48307 --- /dev/null +++ b/src/libiar/USRSH.asm @@ -0,0 +1,17 @@ +; USRSH.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_RSH_L02 + rseg RCODE +rcode_base: + public ?US_RSH_L02 +?US_RSH_L02 equ rcode_base+00000000h + defb 004h,005h,0C8h,0CBh,03Ah,0CBh,01Bh + defb 010h,0FAh,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USRSHASG.asm b/src/libiar/USRSHASG.asm new file mode 100755 index 00000000..f3ba0e4a --- /dev/null +++ b/src/libiar/USRSHASG.asm @@ -0,0 +1,19 @@ +; USRSHASG.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_RSHASG_L02 + rseg RCODE +rcode_base: + public ?US_RSHASG_L02 +?US_RSHASG_L02 equ rcode_base+00000000h + extern ?US_RSH_L02 + defb 05Eh,023h,056h,0CDh + defw LWRD ?US_RSH_L02 + defb 072h,02Bh,073h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USRSHASGBCprim.asm b/src/libiar/USRSHASGBCprim.asm new file mode 100755 index 00000000..5a760b4c --- /dev/null +++ b/src/libiar/USRSHASGBCprim.asm @@ -0,0 +1,18 @@ +; USRSHASGBCprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_RSHASG_BC_prim_L12 + rseg RCODE +rcode_base: + public ?US_RSHASG_BC_prim_L12 +?US_RSHASG_BC_prim_L12 equ rcode_base+00000000h + defb 0D9h,0B7h,028h,007h,0CBh,038h,0CBh + defb 019h,03Dh,020h,0F9h,0C5h,0D9h,0E1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USRSHASGDEprim.asm b/src/libiar/USRSHASGDEprim.asm new file mode 100755 index 00000000..122fb7b5 --- /dev/null +++ b/src/libiar/USRSHASGDEprim.asm @@ -0,0 +1,18 @@ +; USRSHASGDEprim.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_RSHASG_DE_prim_L12 + rseg RCODE +rcode_base: + public ?US_RSHASG_DE_prim_L12 +?US_RSHASG_DE_prim_L12 equ rcode_base+00000000h + defb 0D9h,0B7h,028h,007h,0CBh,03Ah,0CBh + defb 01Bh,03Dh,020h,0F9h,0D5h,0D9h,0E1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USRSHASGIX.asm b/src/libiar/USRSHASGIX.asm new file mode 100755 index 00000000..6b962225 --- /dev/null +++ b/src/libiar/USRSHASGIX.asm @@ -0,0 +1,19 @@ +; USRSHASGIX.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_RSHASG_IX_L12 + rseg RCODE +rcode_base: + public ?US_RSHASG_IX_L12 +?US_RSHASG_IX_L12 equ rcode_base+00000000h + extern ?US_RSH_L02 + defb 0D5h,0DDh,0E5h,0D1h,0CDh + defw LWRD ?US_RSH_L02 + defb 0D5h,0DDh,0E1h,0EBh,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/USRSHASGIY.asm b/src/libiar/USRSHASGIY.asm new file mode 100755 index 00000000..5b1afb90 --- /dev/null +++ b/src/libiar/USRSHASGIY.asm @@ -0,0 +1,19 @@ +; USRSHASGIY.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?US_RSHASG_IY_L12 + rseg RCODE +rcode_base: + public ?US_RSHASG_IY_L12 +?US_RSHASG_IY_L12 equ rcode_base+00000000h + extern ?US_RSH_L02 + defb 0D5h,0FDh,0E5h,0D1h,0CDh + defw LWRD ?US_RSH_L02 + defb 0D5h,0FDh,0E1h,0EBh,0D1h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/VSWITCHEND.asm b/src/libiar/VSWITCHEND.asm new file mode 100755 index 00000000..5cfd62c4 --- /dev/null +++ b/src/libiar/VSWITCHEND.asm @@ -0,0 +1,17 @@ +; VSWITCHEND.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?V_SWITCH_END_L06 + rseg RCODE +rcode_base: + public ?V_SWITCH_END_L06 +?V_SWITCH_END_L06 equ rcode_base+00000000h + defb 009h,009h,07Eh,023h,066h,06Fh,0C1h + defb 0F1h,0E3h,0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/abort.asm b/src/libiar/abort.asm new file mode 100755 index 00000000..2c1f7fd3 --- /dev/null +++ b/src/libiar/abort.asm @@ -0,0 +1,27 @@ +; abort.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module abort + rseg CODE +code_base: + public abort +abort equ code_base+00000000h + extern exit + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + defb 0D5h,011h,001h,000h,03Eh + defb BYTE3 exit + defb 021h + defw LWRD exit + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0D1h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/abs.asm b/src/libiar/abs.asm new file mode 100755 index 00000000..2f91f430 --- /dev/null +++ b/src/libiar/abs.asm @@ -0,0 +1,25 @@ +; abs.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module abs + rseg CODE +code_base: + public abs +abs equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0CBh,07Ah,020h,003h,0EBh,018h,008h + defb 04Bh,042h,0A7h,021h,000h,000h,0EDh + defb 042h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/acos.asm b/src/libiar/acos.asm new file mode 100755 index 00000000..b1fea0d4 --- /dev/null +++ b/src/libiar/acos.asm @@ -0,0 +1,44 @@ +; acos.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module acos + rseg CODE +code_base: + public acos +acos equ code_base+00000000h + extern asin + extern errno + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_SUB_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0CBh,0B8h,0C5h,0D5h,001h,080h,03Fh + defb 021h,000h,000h,0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,00Dh,02Eh,021h,022h + defw LWRD errno + defb 001h,07Fh,07Fh,021h,0FFh,0FFh,018h + defb 019h,0DDh,04Eh,004h,0DDh,046h,005h + defb 03Eh + defb BYTE3 asin + defb 021h + defw LWRD asin + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C5h,0E5h,001h,0C9h,03Fh,021h,0DBh + defb 00Fh,0CDh + defw LWRD ?F_SUB_L04 + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/asin.asm b/src/libiar/asin.asm new file mode 100755 index 00000000..be939ed0 --- /dev/null +++ b/src/libiar/asin.asm @@ -0,0 +1,88 @@ +; asin.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module asin + rseg CODE +code_base: + public asin +asin equ code_base+00000000h + extern atan + extern errno + extern sqrt + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_MUL_L04 + extern ?F_DIV_L04 + extern ?F_SUB_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FAh,0FFh,0CBh,078h,020h,004h,03Eh + defb 001h,018h,001h,0AFh,0DDh,077h,0FEh + defb 0DDh,06Eh,002h,0DDh,066h,003h,0CBh + defb 0B8h,0DDh,070h,005h,0C5h,0E5h,001h + defb 080h,03Fh,021h,000h,000h,0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,00Eh,02Eh,021h,022h + defw LWRD errno + defb 001h,07Fh,07Fh,021h,0FFh,0FFh,0C3h + defw LWRD code_base+000EDh + defb 0DDh,06Eh,004h,0DDh,066h,005h,0E5h + defb 0DDh,06Eh,002h,0DDh,066h,003h,0E5h + defb 0DDh,04Eh,004h,0DDh,046h,005h,0CDh + defw LWRD ?F_MUL_L04 + defb 0C5h,0E5h,001h,080h,03Fh,021h,000h + defb 000h,0CDh + defw LWRD ?F_SUB_L04 + defb 0EBh,03Eh + defb BYTE3 sqrt + defb 021h + defw LWRD sqrt + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,075h,0FAh,0DDh,074h,0FBh,0DDh + defb 071h,0FCh,0DDh,070h,0FDh,0DDh,06Eh + defb 004h,0DDh,066h,005h,0E5h,0DDh,06Eh + defb 002h,0DDh,066h,003h,0E5h,001h,033h + defb 03Fh,069h,061h,0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,033h,0DDh,06Eh,004h,0DDh,066h + defb 005h,0E5h,0DDh,06Eh,002h,0DDh,066h + defb 003h,0E5h,0DDh,04Eh,0FCh,0DDh,046h + defb 0FDh,0DDh,06Eh,0FAh,0DDh,066h,0FBh + defb 0CDh + defw LWRD ?F_DIV_L04 + defb 0EBh,03Eh + defb BYTE3 atan + defb 021h + defw LWRD atan + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C5h,0E5h,001h,0C9h,03Fh,021h,0DBh + defb 00Fh,0CDh + defw LWRD ?F_SUB_L04 + defb 018h,026h,0DDh,06Eh,0FCh,0DDh,066h + defb 0FDh,0E5h,0DDh,06Eh,0FAh,0DDh,066h + defb 0FBh,0E5h,0DDh,04Eh,004h,0DDh,046h + defb 005h,0DDh,06Eh,002h,0DDh,066h,003h + defb 0CDh + defw LWRD ?F_DIV_L04 + defb 0EBh,03Eh + defb BYTE3 atan + defb 021h + defw LWRD atan + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0AFh,0DDh,0B6h,0FEh,020h,008h,079h + defb 0B0h,028h,004h,078h,0EEh,080h,047h + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/assert.asm b/src/libiar/assert.asm new file mode 100755 index 00000000..b4321f5c --- /dev/null +++ b/src/libiar/assert.asm @@ -0,0 +1,50 @@ +; assert.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module assert + rseg CODE +code_base: + rseg CSTR +cstr_base: + public _Assert +_Assert equ cstr_base+00000000h + extern abort + extern printf + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,0E5h + defb 0C5h,0D5h,021h + t_rel_p16 (01) 0000 + defb 0E5h,03Eh + defb BYTE3 printf + defb 021h + defw LWRD printf + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0F1h,0F1h,0F1h,0F1h,03Eh + defb BYTE3 abort + defb 021h + defw LWRD abort + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + t_org_rel (01) 00000000 + defb 041h,073h,073h,065h,072h,074h,069h + defb 06Fh,06Eh,020h,066h,061h,069h,06Ch + defb 065h,064h,03Ah,020h,025h,073h,02Ch + defb 020h,066h,069h,06Ch,065h,020h,025h + defb 073h,02Ch,020h,06Ch,069h,06Eh,065h + defb 020h,025h,064h,00Ah,000h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/atan.asm b/src/libiar/atan.asm new file mode 100755 index 00000000..f69db0a8 --- /dev/null +++ b/src/libiar/atan.asm @@ -0,0 +1,34 @@ +; atan.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module atan + rseg CODE +code_base: + extern __satan + public atan +atan equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0CBh,078h,03Eh + defb BYTE3 __satan + defb 021h + defw LWRD __satan + defb 020h,005h,0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 018h,00Bh,0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 079h,0B0h,028h,004h,078h,0EEh,080h + defb 047h,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/atan2.asm b/src/libiar/atan2.asm new file mode 100755 index 00000000..b8f22296 --- /dev/null +++ b/src/libiar/atan2.asm @@ -0,0 +1,79 @@ +; atan2.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module atan2 + rseg CODE +code_base: + extern __satan + public atan2 +atan2 equ code_base+00000000h + extern errno + extern ?CL64180B_4_06_L00 + extern ?F_DIV_L04 + extern ?F_ADD_L04 + extern ?F_SUB_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 079h,0B0h,020h,017h,0DDh,07Eh,00Ch + defb 0DDh,0B6h,00Dh,020h,00Fh,021h,021h + defb 000h,022h + defw LWRD errno + defb 001h,07Fh,07Fh,021h,0FFh,0FFh,0C3h + defw LWRD code_base+000C8h + defb 0DDh,06Eh,00Ch,0DDh,066h,00Dh,0E5h + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,0E5h + defb 0EBh,0CDh + defw LWRD ?F_ADD_L04 + defb 059h,050h,0DDh,04Eh,002h,0DDh,046h + defb 003h,0EDh,042h,020h,01Ch,0EBh,0DDh + defb 04Eh,004h,0DDh,046h,005h,0EDh,042h + defb 020h,011h,0CBh,078h,020h,005h,001h + defb 0C9h,03Fh,018h,003h,001h,0C9h,0BFh + defb 021h,0DBh,00Fh,018h,070h,0DDh,0CBh + defb 00Dh,07Eh,028h,03Dh,0DDh,0CBh,005h + defb 07Eh,0DDh,06Eh,00Ch + defb 0DDh,066h,00Dh,0E5h,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,0E5h,0CDh + defw LWRD code_base+000CBh + defb 0EBh,03Eh + defb BYTE3 __satan + defb 021h + defw LWRD __satan + defb 020h,010h,0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C5h,0E5h,001h,049h,040h,021h,0DBh + defb 00Fh,0CDh + defw LWRD ?F_SUB_L04 + defb 018h,03Dh,0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C5h,0E5h,001h,049h,0C0h,021h,0DBh + defb 00Fh,0CDh + defw LWRD ?F_ADD_L04 + defb 018h,02Dh,0DDh,0CBh,005h,07Eh,0DDh + defb 06Eh,00Ch,0DDh,066h,00Dh,0E5h,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,0E5h,0CDh + defw LWRD code_base+000CBh + defb 0EBh,03Eh + defb BYTE3 __satan + defb 021h + defw LWRD __satan + defb 020h,005h,0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 018h,00Bh,0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 079h,0B0h,028h,004h,078h,0EEh,080h + defb 047h,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + defb 0DDh,04Eh,004h,0DDh,046h,005h,0DDh + defb 06Eh,002h,0DDh,066h,003h,0C3h + defw LWRD ?F_DIV_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/atof.asm b/src/libiar/atof.asm new file mode 100755 index 00000000..e35eb05d --- /dev/null +++ b/src/libiar/atof.asm @@ -0,0 +1,112 @@ +; atof.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module atof + rseg CODE +code_base: + extern _Small_Ctype + public atof +atof equ code_base+00000000h + extern atoi + extern ?CL64180B_4_06_L00 + extern ?SS_CMP_L02 + extern ?F_MUL_L04 + extern ?F_ADD_L04 + extern ?SL_TO_F_L04 + extern ?F_MULASG_L04 + extern ?F_DIVASG_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0F4h,0FFh,0FDh,0E5h,0DDh,06Eh,002h + defb 0DDh,066h,003h,0E5h,0FDh,0E1h,0DDh + defb 036h,0FEh,000h,0FDh,04Eh,000h,006h + defb 000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,05Eh,028h,004h,0FDh,023h + defb 018h,0EFh,0FDh,07Eh,000h,0FEh,02Dh + defb 020h,006h,0DDh,036h,0FEh,001h,018h + defb 007h,0FDh,07Eh,000h,0FEh,02Bh,020h + defb 002h,0FDh,023h,0AFh,0DDh,077h,0F4h + defb 0DDh,077h,0F5h,0DDh,077h,0F6h,0DDh + defb 077h,0F7h,0FDh,04Eh,000h,006h,000h + defb 021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,056h,028h,023h,0CDh + defw LWRD code_base+00173h + defb 0C5h,0E5h,021h,020h,041h,0E5h,021h + defb 000h,000h,0E5h,0CDh + defw LWRD code_base+00182h + defb 0CDh + defw LWRD ?F_ADD_L04 + defb 0DDh,075h,0F4h,0DDh,074h,0F5h,0DDh + defb 071h,0F6h,0DDh,070h,0F7h,0FDh,023h + defb 018h,0D0h,0AFh,0DDh,077h,0FAh,0DDh + defb 077h,0FBh,0DDh,036h,0FCh,080h,0DDh + defb 036h,0FDh,03Fh,0FDh,07Eh,000h,0FEh + defb 02Eh,020h,03Dh,0FDh,04Eh,001h,006h + defb 000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,056h,0FDh,023h,028h,02Eh + defb 0CDh + defw LWRD code_base+00173h + defb 0C5h,0E5h,021h,020h,041h,0E5h,021h + defb 000h,000h,0E5h,0CDh + defw LWRD code_base+00182h + defb 0CDh + defw LWRD ?F_ADD_L04 + defb 0DDh,075h,0F4h,0DDh,074h,0F5h,0DDh + defb 071h,0F6h,0DDh,070h,0F7h,021h,008h + defb 000h,039h,001h,020h,041h,011h,000h + defb 000h,0CDh + defw LWRD ?F_MULASG_L04 + defb 018h,0C3h,0FDh,04Eh,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,046h,028h,008h,0FDh,046h + defb 000h,0CBh,0E8h,078h,018h,003h,0FDh + defb 07Eh,000h,0FEh,065h,020h,059h,0FDh + defb 023h,0FDh,0E5h,0D1h,03Eh + defb BYTE3 atoi + defb 021h + defw LWRD atoi + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,075h,0F8h,0DDh,074h,0F9h,0DDh + defb 0CBh,0F9h,07Eh,028h,017h,021h,002h + defb 000h,039h,001h,020h,041h,011h,000h + defb 000h,0CDh + defw LWRD ?F_DIVASG_L04 + defb 0DDh,034h,0F8h,020h,0E8h,0DDh,034h + defb 0F9h,018h,0E3h,0DDh,04Eh,0F8h,0DDh + defb 046h,0F9h,021h,000h,000h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,01Bh,023h,023h,039h,001h,020h + defb 041h,011h,000h,000h,0CDh + defw LWRD ?F_MULASG_L04 + defb 0DDh,06Eh,0F8h,0DDh,066h,0F9h,02Bh + defb 0DDh,075h,0F8h,0DDh,074h,0F9h,018h + defb 0D7h,021h,002h,000h,039h,0DDh,04Eh + defb 0FCh,0DDh,046h,0FDh,0DDh,05Eh,0FAh + defb 0DDh,056h,0FBh,0CDh + defw LWRD ?F_DIVASG_L04 + defb 0AFh,0DDh,0B6h,0FEh,028h,00Bh,0EBh + defb 079h,0B0h,028h,012h,078h,0EEh,080h + defb 047h,018h,00Ch,0DDh,04Eh,0F6h,0DDh + defb 046h,0F7h,0DDh,06Eh,0F4h,0DDh,066h + defb 0F5h,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + defb 0FDh,04Eh,000h,021h,0D0h,0FFh,009h + defb 07Ch,007h,09Fh,04Fh,041h,0C3h + defw LWRD ?SL_TO_F_L04 + defb 0DDh,04Eh,0F6h,0DDh,046h,0F7h,0DDh + defb 06Eh,0F4h,0DDh,066h,0F5h,0C3h + defw LWRD ?F_MUL_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/atoi.asm b/src/libiar/atoi.asm new file mode 100755 index 00000000..7c3222e8 --- /dev/null +++ b/src/libiar/atoi.asm @@ -0,0 +1,42 @@ +; atoi.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module atoi + rseg CODE +code_base: + extern _Small_Ctype + public atoi +atoi equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FEh,0FFh,0FDh,0E5h,0DDh,05Eh,002h + defb 0DDh,056h,003h,0DDh,036h,0FEh,000h + defb 06Bh,062h,04Eh,006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,05Eh,028h,003h,013h,018h + defb 0F0h,06Bh,062h,07Eh,0FEh,02Dh,020h + defb 007h,013h,0DDh,036h,0FEh,001h,018h + defb 006h,07Eh,0FEh,02Bh,020h,001h,013h + defb 0FDh,021h,000h,000h,06Bh,062h,04Eh + defb 006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,056h,028h,019h,06Bh,062h + defb 013h,04Eh,0C5h,0FDh,0E5h,0E1h,029h + defb 04Dh,044h,029h,029h,009h,0C1h,009h + defb 001h,0D0h,0FFh,009h,0E5h,0FDh,0E1h + defb 018h,0DAh,0AFh,0DDh,0B6h,0FEh,028h + defb 00Ah,0FDh,0E5h,0C1h,021h,000h,000h + defb 0EDh,042h,018h,003h,0FDh,0E5h,0E1h + defb 0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/atol.asm b/src/libiar/atol.asm new file mode 100755 index 00000000..134577b7 --- /dev/null +++ b/src/libiar/atol.asm @@ -0,0 +1,54 @@ +; atol.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module atol + rseg CODE +code_base: + extern _Small_Ctype + public atol +atol equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?L_MUL_L03 + extern ?L_NEG_L03 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0DDh,0E5h,0F5h,0F5h,0F5h,0D5h,0DDh + defb 0E1h,021h,004h,000h,039h,036h,000h + defb 0DDh,04Eh,000h,006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,05Eh,028h,004h,0DDh,023h + defb 018h,0EFh,0DDh,07Eh,000h,0FEh,02Dh + defb 020h,008h,021h,004h,000h,039h,036h + defb 001h,018h,007h,0DDh,07Eh,000h,0FEh + defb 02Bh,020h,002h,0DDh,023h,068h,060h + defb 039h,0AFh,077h,023h,077h,023h,077h + defb 023h,077h,0DDh,04Eh,000h,006h,000h + defb 021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,056h,028h,044h,0DDh,06Eh + defb 000h,048h,061h,0C5h,0E5h,060h,0C5h + defb 02Eh,00Ah,0E5h,02Bh,02Bh,039h,05Eh + defb 023h,056h,023h,04Eh,023h,046h,0EBh + defb 0CDh + defw LWRD ?L_MUL_L03 + defb 059h,050h,0C1h,009h,0EBh,0C1h,0EDh + defb 04Ah,0E5h,0D5h,021h,0D0h,0FFh,0C1h + defb 009h,0EBh,021h,0FFh,0FFh,0C1h,0EDh + defb 04Ah,04Dh,044h,0EBh,0E5h,021h,002h + defb 000h,039h,0D1h,073h,023h,072h,023h + defb 071h,023h,070h,0DDh,023h,018h,0AFh + defb 021h,004h,000h,039h,0AFh,0B6h,068h + defb 060h,039h,05Eh,023h + defb 056h,023h,04Eh,023h,046h,0EBh,028h + defb 003h,0CDh + defw LWRD ?L_NEG_L03 + defb 0F1h,0F1h,0F1h,0DDh,0E1h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/bsearch.asm b/src/libiar/bsearch.asm new file mode 100755 index 00000000..6c4b950a --- /dev/null +++ b/src/libiar/bsearch.asm @@ -0,0 +1,51 @@ +; bsearch.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module bsearch + rseg CODE +code_base: + public bsearch +bsearch equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?S_MUL_L02 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FAh,0FFh,0FDh,0E5h,0DDh,071h,0FCh + defb 0DDh,070h,0FDh,0DDh,07Eh,00Ah,0DDh + defb 0B6h,00Bh,0CAh + defw LWRD code_base+00096h + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,0CBh + defb 03Ch,0CBh,01Dh,0E5h,0FDh,0E1h,04Dh + defb 044h,0DDh,05Eh,00Ch,0DDh,056h,00Dh + defb 0CDh + defw LWRD ?S_MUL_L02 + defb 0DDh,06Eh,0FCh,0DDh,066h,0FDh,019h + defb 0DDh,075h,0FAh,0DDh,074h,0FBh,04Dh + defb 044h,0DDh,05Eh,002h,0DDh,056h,003h + defb 0DDh,07Eh,010h,0DDh,06Eh,00Eh,0DDh + defb 066h,00Fh,0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 07Dh,0B4h,020h,008h,0DDh,06Eh,0FAh + defb 0DDh,066h,0FBh,018h,03Dh,0CBh,07Ch + defb 028h,00Bh,0FDh,0E5h,0E1h,0DDh,075h + defb 00Ah,0DDh,074h,00Bh,018h,0A3h,0DDh + defb 06Eh,00Ch,0DDh,066h,00Dh,0DDh,04Eh + defb 0FAh,0DDh,046h,0FBh,009h,0DDh,075h + defb 0FCh,0DDh,074h,0FDh,0FDh,0E5h,0C1h + defb 021h,0FFh,0FFh,0A7h + defb 0EDh,042h,04Dh,044h,021h,012h,000h + defb 039h,07Eh,081h,077h,023h,07Eh,088h + defb 077h,0C3h + defw LWRD code_base+0000Dh + defb 06Fh,067h,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/build.ban b/src/libiar/build.ban new file mode 100755 index 00000000..22a086f3 --- /dev/null +++ b/src/libiar/build.ban @@ -0,0 +1,1018 @@ +copy libiar.lib ..\..\..\lib + +rem copy ..\BANKCALL.asm BANKCALL.s01 +rem as-z80 -l -o BANKCALL.s01 +rem @if errorlevel 1 goto failure +rem copy BANKCALL.rel ..\..\..\lib\reliar + +copy ..\BANKCALLDIRECT.asm BANKCALLDIRECT.s01 +as-z80 -l -o BANKCALLDIRECT.s01 +@if errorlevel 1 goto failure +copy BANKCALLDIRECT.rel ..\..\..\lib\reliar + +copy ..\BANKCALLDIRECTEXAF.asm BANKCALLDIRECTEXAF.s01 +as-z80 -l -o BANKCALLDIRECTEXAF.s01 +@if errorlevel 1 goto failure +copy BANKCALLDIRECTEXAF.rel ..\..\..\lib\reliar + +rem copy ..\BANKCALLEXAF.asm BANKCALLEXAF.s01 +rem as-z80 -l -o BANKCALLEXAF.s01 +rem @if errorlevel 1 goto failure +rem copy BANKCALLEXAF.rel ..\..\..\lib\reliar + +rem copy ..\BANKLEAVE.asm BANKLEAVE.s01 +rem as-z80 -l -o BANKLEAVE.s01 +rem @if errorlevel 1 goto failure +rem copy BANKLEAVE.rel ..\..\..\lib\reliar + +copy ..\BANKLEAVE32.asm BANKLEAVE32.s01 +as-z80 -l -o BANKLEAVE32.s01 +@if errorlevel 1 goto failure +copy BANKLEAVE32.rel ..\..\..\lib\reliar + +copy ..\BANKLEAVEDIRECT.asm BANKLEAVEDIRECT.s01 +as-z80 -l -o BANKLEAVEDIRECT.s01 +@if errorlevel 1 goto failure +copy BANKLEAVEDIRECT.rel ..\..\..\lib\reliar + +copy ..\BFCANDASG.asm BFCANDASG.s01 +as-z80 -l -o BFCANDASG.s01 +@if errorlevel 1 goto failure +copy BFCANDASG.rel ..\..\..\lib\reliar + +copy ..\BFCLSHASG.asm BFCLSHASG.s01 +as-z80 -l -o BFCLSHASG.s01 +@if errorlevel 1 goto failure +copy BFCLSHASG.rel ..\..\..\lib\reliar + +copy ..\BFCMULASG.asm BFCMULASG.s01 +as-z80 -l -o BFCMULASG.s01 +@if errorlevel 1 goto failure +copy BFCMULASG.rel ..\..\..\lib\reliar + +copy ..\BFCORASG.asm BFCORASG.s01 +as-z80 -l -o BFCORASG.s01 +@if errorlevel 1 goto failure +copy BFCORASG.rel ..\..\..\lib\reliar + +copy ..\BFCRETVAL.asm BFCRETVAL.s01 +as-z80 -l -o BFCRETVAL.s01 +@if errorlevel 1 goto failure +copy BFCRETVAL.rel ..\..\..\lib\reliar + +copy ..\BFCSHIFTUP.asm BFCSHIFTUP.s01 +as-z80 -l -o BFCSHIFTUP.s01 +@if errorlevel 1 goto failure +copy BFCSHIFTUP.rel ..\..\..\lib\reliar + +copy ..\BFCXORASG.asm BFCXORASG.s01 +as-z80 -l -o BFCXORASG.s01 +@if errorlevel 1 goto failure +copy BFCXORASG.rel ..\..\..\lib\reliar + +copy ..\BFMASKEDLD.asm BFMASKEDLD.s01 +as-z80 -l -o BFMASKEDLD.s01 +@if errorlevel 1 goto failure +copy BFMASKEDLD.rel ..\..\..\lib\reliar + +copy ..\BFMASKEDST.asm BFMASKEDST.s01 +as-z80 -l -o BFMASKEDST.s01 +@if errorlevel 1 goto failure +copy BFMASKEDST.rel ..\..\..\lib\reliar + +copy ..\BFSADDASG.asm BFSADDASG.s01 +as-z80 -l -o BFSADDASG.s01 +@if errorlevel 1 goto failure +copy BFSADDASG.rel ..\..\..\lib\reliar + +copy ..\BFSANDASG.asm BFSANDASG.s01 +as-z80 -l -o BFSANDASG.s01 +@if errorlevel 1 goto failure +copy BFSANDASG.rel ..\..\..\lib\reliar + +copy ..\BFSCDIVASG.asm BFSCDIVASG.s01 +as-z80 -l -o BFSCDIVASG.s01 +@if errorlevel 1 goto failure +copy BFSCDIVASG.rel ..\..\..\lib\reliar + +copy ..\BFSCEXT.asm BFSCEXT.s01 +as-z80 -l -o BFSCEXT.s01 +@if errorlevel 1 goto failure +copy BFSCEXT.rel ..\..\..\lib\reliar + +copy ..\BFSCLDSHIFTDOWN.asm BFSCLDSHIFTDOWN.s01 +as-z80 -l -o BFSCLDSHIFTDOWN.s01 +@if errorlevel 1 goto failure +copy BFSCLDSHIFTDOWN.rel ..\..\..\lib\reliar + +copy ..\BFSCMODASG.asm BFSCMODASG.s01 +as-z80 -l -o BFSCMODASG.s01 +@if errorlevel 1 goto failure +copy BFSCMODASG.rel ..\..\..\lib\reliar + +copy ..\BFSCRSHASG.asm BFSCRSHASG.s01 +as-z80 -l -o BFSCRSHASG.s01 +@if errorlevel 1 goto failure +copy BFSCRSHASG.rel ..\..\..\lib\reliar + +copy ..\BFSLSHASG.asm BFSLSHASG.s01 +as-z80 -l -o BFSLSHASG.s01 +@if errorlevel 1 goto failure +copy BFSLSHASG.rel ..\..\..\lib\reliar + +copy ..\BFSMULASG.asm BFSMULASG.s01 +as-z80 -l -o BFSMULASG.s01 +@if errorlevel 1 goto failure +copy BFSMULASG.rel ..\..\..\lib\reliar + +copy ..\BFSNEGASG.asm BFSNEGASG.s01 +as-z80 -l -o BFSNEGASG.s01 +@if errorlevel 1 goto failure +copy BFSNEGASG.rel ..\..\..\lib\reliar + +copy ..\BFSORASG.asm BFSORASG.s01 +as-z80 -l -o BFSORASG.s01 +@if errorlevel 1 goto failure +copy BFSORASG.rel ..\..\..\lib\reliar + +copy ..\BFSPOSTDEC.asm BFSPOSTDEC.s01 +as-z80 -l -o BFSPOSTDEC.s01 +@if errorlevel 1 goto failure +copy BFSPOSTDEC.rel ..\..\..\lib\reliar + +copy ..\BFSPOSTINC.asm BFSPOSTINC.s01 +as-z80 -l -o BFSPOSTINC.s01 +@if errorlevel 1 goto failure +copy BFSPOSTINC.rel ..\..\..\lib\reliar + +copy ..\BFSPREDEC.asm BFSPREDEC.s01 +as-z80 -l -o BFSPREDEC.s01 +@if errorlevel 1 goto failure +copy BFSPREDEC.rel ..\..\..\lib\reliar + +copy ..\BFSPREINC.asm BFSPREINC.s01 +as-z80 -l -o BFSPREINC.s01 +@if errorlevel 1 goto failure +copy BFSPREINC.rel ..\..\..\lib\reliar + +copy ..\BFSRETVAL.asm BFSRETVAL.s01 +as-z80 -l -o BFSRETVAL.s01 +@if errorlevel 1 goto failure +copy BFSRETVAL.rel ..\..\..\lib\reliar + +copy ..\BFSSDIVASG.asm BFSSDIVASG.s01 +as-z80 -l -o BFSSDIVASG.s01 +@if errorlevel 1 goto failure +copy BFSSDIVASG.rel ..\..\..\lib\reliar + +copy ..\BFSSEXT.asm BFSSEXT.s01 +as-z80 -l -o BFSSEXT.s01 +@if errorlevel 1 goto failure +copy BFSSEXT.rel ..\..\..\lib\reliar + +copy ..\BFSSHIFTUP.asm BFSSHIFTUP.s01 +as-z80 -l -o BFSSHIFTUP.s01 +@if errorlevel 1 goto failure +copy BFSSHIFTUP.rel ..\..\..\lib\reliar + +copy ..\BFSSLDSHIFTDOWN.asm BFSSLDSHIFTDOWN.s01 +as-z80 -l -o BFSSLDSHIFTDOWN.s01 +@if errorlevel 1 goto failure +copy BFSSLDSHIFTDOWN.rel ..\..\..\lib\reliar + +copy ..\BFSSMODASG.asm BFSSMODASG.s01 +as-z80 -l -o BFSSMODASG.s01 +@if errorlevel 1 goto failure +copy BFSSMODASG.rel ..\..\..\lib\reliar + +copy ..\BFSSRSHASG.asm BFSSRSHASG.s01 +as-z80 -l -o BFSSRSHASG.s01 +@if errorlevel 1 goto failure +copy BFSSRSHASG.rel ..\..\..\lib\reliar + +copy ..\BFSSUBASG.asm BFSSUBASG.s01 +as-z80 -l -o BFSSUBASG.s01 +@if errorlevel 1 goto failure +copy BFSSUBASG.rel ..\..\..\lib\reliar + +copy ..\BFSXORASG.asm BFSXORASG.s01 +as-z80 -l -o BFSXORASG.s01 +@if errorlevel 1 goto failure +copy BFSXORASG.rel ..\..\..\lib\reliar + +copy ..\BFUCDIVASG.asm BFUCDIVASG.s01 +as-z80 -l -o BFUCDIVASG.s01 +@if errorlevel 1 goto failure +copy BFUCDIVASG.rel ..\..\..\lib\reliar + +copy ..\BFUCLDSHIFTDOWN.asm BFUCLDSHIFTDOWN.s01 +as-z80 -l -o BFUCLDSHIFTDOWN.s01 +@if errorlevel 1 goto failure +copy BFUCLDSHIFTDOWN.rel ..\..\..\lib\reliar + +copy ..\BFUCMODASG.asm BFUCMODASG.s01 +as-z80 -l -o BFUCMODASG.s01 +@if errorlevel 1 goto failure +copy BFUCMODASG.rel ..\..\..\lib\reliar + +copy ..\BFUCRSHASG.asm BFUCRSHASG.s01 +as-z80 -l -o BFUCRSHASG.s01 +@if errorlevel 1 goto failure +copy BFUCRSHASG.rel ..\..\..\lib\reliar + +copy ..\BFUSDIVASG.asm BFUSDIVASG.s01 +as-z80 -l -o BFUSDIVASG.s01 +@if errorlevel 1 goto failure +copy BFUSDIVASG.rel ..\..\..\lib\reliar + +copy ..\BFUSLDSHIFTDOWN.asm BFUSLDSHIFTDOWN.s01 +as-z80 -l -o BFUSLDSHIFTDOWN.s01 +@if errorlevel 1 goto failure +copy BFUSLDSHIFTDOWN.rel ..\..\..\lib\reliar + +copy ..\BFUSMODASG.asm BFUSMODASG.s01 +as-z80 -l -o BFUSMODASG.s01 +@if errorlevel 1 goto failure +copy BFUSMODASG.rel ..\..\..\lib\reliar + +copy ..\BFUSRSHASG.asm BFUSRSHASG.s01 +as-z80 -l -o BFUSRSHASG.s01 +@if errorlevel 1 goto failure +copy BFUSRSHASG.rel ..\..\..\lib\reliar + +copy ..\CALLIND.asm CALLIND.s01 +as-z80 -l -o CALLIND.s01 +@if errorlevel 1 goto failure +copy CALLIND.rel ..\..\..\lib\reliar + +copy ..\CDIVMOD.asm CDIVMOD.s01 +as-z80 -l -o CDIVMOD.s01 +@if errorlevel 1 goto failure +copy CDIVMOD.rel ..\..\..\lib\reliar + +copy ..\CFINDSIGN.asm CFINDSIGN.s01 +as-z80 -l -o CFINDSIGN.s01 +@if errorlevel 1 goto failure +copy CFINDSIGN.rel ..\..\..\lib\reliar + +copy ..\CLSH.asm CLSH.s01 +as-z80 -l -o CLSH.s01 +@if errorlevel 1 goto failure +copy CLSH.rel ..\..\..\lib\reliar + +copy ..\CLSHASG.asm CLSHASG.s01 +as-z80 -l -o CLSHASG.s01 +@if errorlevel 1 goto failure +copy CLSHASG.rel ..\..\..\lib\reliar + +copy ..\CMUL.asm CMUL.s01 +as-z80 -l -o CMUL.s01 +@if errorlevel 1 goto failure +copy CMUL.rel ..\..\..\lib\reliar + +copy ..\CMULASG.asm CMULASG.s01 +as-z80 -l -o CMULASG.s01 +@if errorlevel 1 goto failure +copy CMULASG.rel ..\..\..\lib\reliar + +copy ..\CSSWITCH.asm CSSWITCH.s01 +as-z80 -l -o CSSWITCH.s01 +@if errorlevel 1 goto failure +copy CSSWITCH.rel ..\..\..\lib\reliar + +copy ..\CVSWITCH.asm CVSWITCH.s01 +as-z80 -l -o CVSWITCH.s01 +@if errorlevel 1 goto failure +copy CVSWITCH.rel ..\..\..\lib\reliar + +rem copy ..\ENTAUTO.asm ENTAUTO.s01 +rem as-z80 -l -o ENTAUTO.s01 +rem @if errorlevel 1 goto failure +rem copy ENTAUTO.rel ..\..\..\lib\reliar + +copy ..\ENTAUTODIRECT.asm ENTAUTODIRECT.s01 +as-z80 -l -o ENTAUTODIRECT.s01 +@if errorlevel 1 goto failure +copy ENTAUTODIRECT.rel ..\..\..\lib\reliar + +rem copy ..\ENTPARM.asm ENTPARM.s01 +rem as-z80 -l -o ENTPARM.s01 +rem @if errorlevel 1 goto failure +rem copy ENTPARM.rel ..\..\..\lib\reliar + +copy ..\ENTPARMDIRECT.asm ENTPARMDIRECT.s01 +as-z80 -l -o ENTPARMDIRECT.s01 +@if errorlevel 1 goto failure +copy ENTPARMDIRECT.rel ..\..\..\lib\reliar + +copy ..\FADDASG.asm FADDASG.s01 +as-z80 -l -o FADDASG.s01 +@if errorlevel 1 goto failure +copy FADDASG.rel ..\..\..\lib\reliar + +copy ..\FADDSUB.asm FADDSUB.s01 +as-z80 -l -o FADDSUB.s01 +@if errorlevel 1 goto failure +copy FADDSUB.rel ..\..\..\lib\reliar + +copy ..\FCMP.asm FCMP.s01 +as-z80 -l -o FCMP.s01 +@if errorlevel 1 goto failure +copy FCMP.rel ..\..\..\lib\reliar + +copy ..\FDEC.asm FDEC.s01 +as-z80 -l -o FDEC.s01 +@if errorlevel 1 goto failure +copy FDEC.rel ..\..\..\lib\reliar + +copy ..\FDECASG.asm FDECASG.s01 +as-z80 -l -o FDECASG.s01 +@if errorlevel 1 goto failure +copy FDECASG.rel ..\..\..\lib\reliar + +copy ..\FDIV.asm FDIV.s01 +as-z80 -l -o FDIV.s01 +@if errorlevel 1 goto failure +copy FDIV.rel ..\..\..\lib\reliar + +copy ..\FDIVASG.asm FDIVASG.s01 +as-z80 -l -o FDIVASG.s01 +@if errorlevel 1 goto failure +copy FDIVASG.rel ..\..\..\lib\reliar + +copy ..\FENDASG2.asm FENDASG2.s01 +as-z80 -l -o FENDASG2.s01 +@if errorlevel 1 goto failure +copy FENDASG2.rel ..\..\..\lib\reliar + +copy ..\FINC.asm FINC.s01 +as-z80 -l -o FINC.s01 +@if errorlevel 1 goto failure +copy FINC.rel ..\..\..\lib\reliar + +copy ..\FINCASG.asm FINCASG.s01 +as-z80 -l -o FINCASG.s01 +@if errorlevel 1 goto failure +copy FINCASG.rel ..\..\..\lib\reliar + +copy ..\FMUL.asm FMUL.s01 +as-z80 -l -o FMUL.s01 +@if errorlevel 1 goto failure +copy FMUL.rel ..\..\..\lib\reliar + +copy ..\FMULASG.asm FMULASG.s01 +as-z80 -l -o FMULASG.s01 +@if errorlevel 1 goto failure +copy FMULASG.rel ..\..\..\lib\reliar + +copy ..\FNEGASG.asm FNEGASG.s01 +as-z80 -l -o FNEGASG.s01 +@if errorlevel 1 goto failure +copy FNEGASG.rel ..\..\..\lib\reliar + +copy ..\FPACK.asm FPACK.s01 +as-z80 -l -o FPACK.s01 +@if errorlevel 1 goto failure +copy FPACK.rel ..\..\..\lib\reliar + +copy ..\FROUND.asm FROUND.s01 +as-z80 -l -o FROUND.s01 +@if errorlevel 1 goto failure +copy FROUND.rel ..\..\..\lib\reliar + +copy ..\FSUBASG.asm FSUBASG.s01 +as-z80 -l -o FSUBASG.s01 +@if errorlevel 1 goto failure +copy FSUBASG.rel ..\..\..\lib\reliar + +copy ..\FTOL.asm FTOL.s01 +as-z80 -l -o FTOL.s01 +@if errorlevel 1 goto failure +copy FTOL.rel ..\..\..\lib\reliar + +copy ..\FUNPACK.asm FUNPACK.s01 +as-z80 -l -o FUNPACK.s01 +@if errorlevel 1 goto failure +copy FUNPACK.rel ..\..\..\lib\reliar + +copy ..\LADDASG.asm LADDASG.s01 +as-z80 -l -o LADDASG.s01 +@if errorlevel 1 goto failure +copy LADDASG.rel ..\..\..\lib\reliar + +copy ..\LAND.asm LAND.s01 +as-z80 -l -o LAND.s01 +@if errorlevel 1 goto failure +copy LAND.rel ..\..\..\lib\reliar + +copy ..\LANDASG.asm LANDASG.s01 +as-z80 -l -o LANDASG.s01 +@if errorlevel 1 goto failure +copy LANDASG.rel ..\..\..\lib\reliar + +copy ..\LDEC.asm LDEC.s01 +as-z80 -l -o LDEC.s01 +@if errorlevel 1 goto failure +copy LDEC.rel ..\..\..\lib\reliar + +copy ..\LDECASG.asm LDECASG.s01 +as-z80 -l -o LDECASG.s01 +@if errorlevel 1 goto failure +copy LDECASG.rel ..\..\..\lib\reliar + +copy ..\LDIVMOD.asm LDIVMOD.s01 +as-z80 -l -o LDIVMOD.s01 +@if errorlevel 1 goto failure +copy LDIVMOD.rel ..\..\..\lib\reliar + +rem copy ..\LEAVE.asm LEAVE.s01 +rem as-z80 -l -o LEAVE.s01 +rem @if errorlevel 1 goto failure +rem copy LEAVE.rel ..\..\..\lib\reliar + +copy ..\LEAVE32.asm LEAVE32.s01 +as-z80 -l -o LEAVE32.s01 +@if errorlevel 1 goto failure +copy LEAVE32.rel ..\..\..\lib\reliar + +copy ..\LEAVEDIRECT.asm LEAVEDIRECT.s01 +as-z80 -l -o LEAVEDIRECT.s01 +@if errorlevel 1 goto failure +copy LEAVEDIRECT.rel ..\..\..\lib\reliar + +copy ..\LENDASG.asm LENDASG.s01 +as-z80 -l -o LENDASG.s01 +@if errorlevel 1 goto failure +copy LENDASG.rel ..\..\..\lib\reliar + +copy ..\LENDMULDIVASG.asm LENDMULDIVASG.s01 +as-z80 -l -o LENDMULDIVASG.s01 +@if errorlevel 1 goto failure +copy LENDMULDIVASG.rel ..\..\..\lib\reliar + +copy ..\LFINDSIGN.asm LFINDSIGN.s01 +as-z80 -l -o LFINDSIGN.s01 +@if errorlevel 1 goto failure +copy LFINDSIGN.rel ..\..\..\lib\reliar + +copy ..\LIBVERSION.asm LIBVERSION.s01 +as-z80 -l -o LIBVERSION.s01 +@if errorlevel 1 goto failure +copy LIBVERSION.rel ..\..\..\lib\reliar + +copy ..\LINC.asm LINC.s01 +as-z80 -l -o LINC.s01 +@if errorlevel 1 goto failure +copy LINC.rel ..\..\..\lib\reliar + +copy ..\LINCASG.asm LINCASG.s01 +as-z80 -l -o LINCASG.s01 +@if errorlevel 1 goto failure +copy LINCASG.rel ..\..\..\lib\reliar + +copy ..\LLSH.asm LLSH.s01 +as-z80 -l -o LLSH.s01 +@if errorlevel 1 goto failure +copy LLSH.rel ..\..\..\lib\reliar + +copy ..\LLSHASG.asm LLSHASG.s01 +as-z80 -l -o LLSHASG.s01 +@if errorlevel 1 goto failure +copy LLSHASG.rel ..\..\..\lib\reliar + +copy ..\LMUL.asm LMUL.s01 +as-z80 -l -o LMUL.s01 +@if errorlevel 1 goto failure +copy LMUL.rel ..\..\..\lib\reliar + +copy ..\LMULASG.asm LMULASG.s01 +as-z80 -l -o LMULASG.s01 +@if errorlevel 1 goto failure +copy LMULASG.rel ..\..\..\lib\reliar + +copy ..\LNEG.asm LNEG.s01 +as-z80 -l -o LNEG.s01 +@if errorlevel 1 goto failure +copy LNEG.rel ..\..\..\lib\reliar + +copy ..\LNEGASG.asm LNEGASG.s01 +as-z80 -l -o LNEGASG.s01 +@if errorlevel 1 goto failure +copy LNEGASG.rel ..\..\..\lib\reliar + +copy ..\LNOT.asm LNOT.s01 +as-z80 -l -o LNOT.s01 +@if errorlevel 1 goto failure +copy LNOT.rel ..\..\..\lib\reliar + +copy ..\LNOTASG.asm LNOTASG.s01 +as-z80 -l -o LNOTASG.s01 +@if errorlevel 1 goto failure +copy LNOTASG.rel ..\..\..\lib\reliar + +copy ..\LOR.asm LOR.s01 +as-z80 -l -o LOR.s01 +@if errorlevel 1 goto failure +copy LOR.rel ..\..\..\lib\reliar + +copy ..\LORASG.asm LORASG.s01 +as-z80 -l -o LORASG.s01 +@if errorlevel 1 goto failure +copy LORASG.rel ..\..\..\lib\reliar + +copy ..\LSSWITCH.asm LSSWITCH.s01 +as-z80 -l -o LSSWITCH.s01 +@if errorlevel 1 goto failure +copy LSSWITCH.rel ..\..\..\lib\reliar + +copy ..\LSUBASG.asm LSUBASG.s01 +as-z80 -l -o LSUBASG.s01 +@if errorlevel 1 goto failure +copy LSUBASG.rel ..\..\..\lib\reliar + +copy ..\LTOF.asm LTOF.s01 +as-z80 -l -o LTOF.s01 +@if errorlevel 1 goto failure +copy LTOF.rel ..\..\..\lib\reliar + +copy ..\LVSWITCH.asm LVSWITCH.s01 +as-z80 -l -o LVSWITCH.s01 +@if errorlevel 1 goto failure +copy LVSWITCH.rel ..\..\..\lib\reliar + +copy ..\LXOR.asm LXOR.s01 +as-z80 -l -o LXOR.s01 +@if errorlevel 1 goto failure +copy LXOR.rel ..\..\..\lib\reliar + +copy ..\LXORASG.asm LXORASG.s01 +as-z80 -l -o LXORASG.s01 +@if errorlevel 1 goto failure +copy LXORASG.rel ..\..\..\lib\reliar + +copy ..\MEMCMP.asm MEMCMP.s01 +as-z80 -l -o MEMCMP.s01 +@if errorlevel 1 goto failure +copy MEMCMP.rel ..\..\..\lib\reliar + +copy ..\MEMSET.asm MEMSET.s01 +as-z80 -l -o MEMSET.s01 +@if errorlevel 1 goto failure +copy MEMSET.rel ..\..\..\lib\reliar + +rem copy ..\MONITOR.asm MONITOR.s01 +rem as-z80 -l -o MONITOR.s01 +rem @if errorlevel 1 goto failure +rem copy MONITOR.rel ..\..\..\lib\reliar + +copy ..\MONITORBANKLEAVE.asm MONITORBANKLEAVE.s01 +as-z80 -l -o MONITORBANKLEAVE.s01 +@if errorlevel 1 goto failure +copy MONITORBANKLEAVE.rel ..\..\..\lib\reliar + +copy ..\MONITORBANKLEAVE32.asm MONITORBANKLEAVE32.s01 +as-z80 -l -o MONITORBANKLEAVE32.s01 +@if errorlevel 1 goto failure +copy MONITORBANKLEAVE32.rel ..\..\..\lib\reliar + +copy ..\MONITORBANKLEAVEIX.asm MONITORBANKLEAVEIX.s01 +as-z80 -l -o MONITORBANKLEAVEIX.s01 +@if errorlevel 1 goto failure +copy MONITORBANKLEAVEIX.rel ..\..\..\lib\reliar + +copy ..\MONITORBANKLEAVEPOP.asm MONITORBANKLEAVEPOP.s01 +as-z80 -l -o MONITORBANKLEAVEPOP.s01 +@if errorlevel 1 goto failure +copy MONITORBANKLEAVEPOP.rel ..\..\..\lib\reliar + +copy ..\MONITORLEAVE.asm MONITORLEAVE.s01 +as-z80 -l -o MONITORLEAVE.s01 +@if errorlevel 1 goto failure +copy MONITORLEAVE.rel ..\..\..\lib\reliar + +copy ..\MONITORLEAVE32.asm MONITORLEAVE32.s01 +as-z80 -l -o MONITORLEAVE32.s01 +@if errorlevel 1 goto failure +copy MONITORLEAVE32.rel ..\..\..\lib\reliar + +copy ..\MONITORLEAVEIX.asm MONITORLEAVEIX.s01 +as-z80 -l -o MONITORLEAVEIX.s01 +@if errorlevel 1 goto failure +copy MONITORLEAVEIX.rel ..\..\..\lib\reliar + +copy ..\MONITORLEAVEIXPA.asm MONITORLEAVEIXPA.s01 +as-z80 -l -o MONITORLEAVEIXPA.s01 +@if errorlevel 1 goto failure +copy MONITORLEAVEIXPA.rel ..\..\..\lib\reliar + +copy ..\MONITORLEAVEPA.asm MONITORLEAVEPA.s01 +as-z80 -l -o MONITORLEAVEPA.s01 +@if errorlevel 1 goto failure +copy MONITORLEAVEPA.rel ..\..\..\lib\reliar + +copy ..\MONITORLEAVEPOP.asm MONITORLEAVEPOP.s01 +as-z80 -l -o MONITORLEAVEPOP.s01 +@if errorlevel 1 goto failure +copy MONITORLEAVEPOP.rel ..\..\..\lib\reliar + +copy ..\SCDIV.asm SCDIV.s01 +as-z80 -l -o SCDIV.s01 +@if errorlevel 1 goto failure +copy SCDIV.rel ..\..\..\lib\reliar + +copy ..\SCMOD.asm SCMOD.s01 +as-z80 -l -o SCMOD.s01 +@if errorlevel 1 goto failure +copy SCMOD.rel ..\..\..\lib\reliar + +copy ..\SCRSH.asm SCRSH.s01 +as-z80 -l -o SCRSH.s01 +@if errorlevel 1 goto failure +copy SCRSH.rel ..\..\..\lib\reliar + +copy ..\SCRSHASG.asm SCRSHASG.s01 +as-z80 -l -o SCRSHASG.s01 +@if errorlevel 1 goto failure +copy SCRSHASG.rel ..\..\..\lib\reliar + +copy ..\SDIVMOD.asm SDIVMOD.s01 +as-z80 -l -o SDIVMOD.s01 +@if errorlevel 1 goto failure +copy SDIVMOD.rel ..\..\..\lib\reliar + +copy ..\SFINDSIGN.asm SFINDSIGN.s01 +as-z80 -l -o SFINDSIGN.s01 +@if errorlevel 1 goto failure +copy SFINDSIGN.rel ..\..\..\lib\reliar + +copy ..\SLCMP.asm SLCMP.s01 +as-z80 -l -o SLCMP.s01 +@if errorlevel 1 goto failure +copy SLCMP.rel ..\..\..\lib\reliar + +copy ..\SLDIV.asm SLDIV.s01 +as-z80 -l -o SLDIV.s01 +@if errorlevel 1 goto failure +copy SLDIV.rel ..\..\..\lib\reliar + +copy ..\SLDIVASG.asm SLDIVASG.s01 +as-z80 -l -o SLDIVASG.s01 +@if errorlevel 1 goto failure +copy SLDIVASG.rel ..\..\..\lib\reliar + +copy ..\SLMOD.asm SLMOD.s01 +as-z80 -l -o SLMOD.s01 +@if errorlevel 1 goto failure +copy SLMOD.rel ..\..\..\lib\reliar + +copy ..\SLMODASG.asm SLMODASG.s01 +as-z80 -l -o SLMODASG.s01 +@if errorlevel 1 goto failure +copy SLMODASG.rel ..\..\..\lib\reliar + +copy ..\SLRSH.asm SLRSH.s01 +as-z80 -l -o SLRSH.s01 +@if errorlevel 1 goto failure +copy SLRSH.rel ..\..\..\lib\reliar + +copy ..\SLRSHASG.asm SLRSHASG.s01 +as-z80 -l -o SLRSHASG.s01 +@if errorlevel 1 goto failure +copy SLRSHASG.rel ..\..\..\lib\reliar + +copy ..\SLSH.asm SLSH.s01 +as-z80 -l -o SLSH.s01 +@if errorlevel 1 goto failure +copy SLSH.rel ..\..\..\lib\reliar + +copy ..\SLSHASG.asm SLSHASG.s01 +as-z80 -l -o SLSHASG.s01 +@if errorlevel 1 goto failure +copy SLSHASG.rel ..\..\..\lib\reliar + +copy ..\SLSHASGBCprim.asm SLSHASGBCprim.s01 +as-z80 -l -o SLSHASGBCprim.s01 +@if errorlevel 1 goto failure +copy SLSHASGBCprim.rel ..\..\..\lib\reliar + +copy ..\SLSHASGDEprim.asm SLSHASGDEprim.s01 +as-z80 -l -o SLSHASGDEprim.s01 +@if errorlevel 1 goto failure +copy SLSHASGDEprim.rel ..\..\..\lib\reliar + +copy ..\SMUL.asm SMUL.s01 +as-z80 -l -o SMUL.s01 +@if errorlevel 1 goto failure +copy SMUL.rel ..\..\..\lib\reliar + +copy ..\SMULASG.asm SMULASG.s01 +as-z80 -l -o SMULASG.s01 +@if errorlevel 1 goto failure +copy SMULASG.rel ..\..\..\lib\reliar + +copy ..\SMULASGBCprim.asm SMULASGBCprim.s01 +as-z80 -l -o SMULASGBCprim.s01 +@if errorlevel 1 goto failure +copy SMULASGBCprim.rel ..\..\..\lib\reliar + +copy ..\SMULASGDEprim.asm SMULASGDEprim.s01 +as-z80 -l -o SMULASGDEprim.s01 +@if errorlevel 1 goto failure +copy SMULASGDEprim.rel ..\..\..\lib\reliar + +copy ..\SMULASGIX.asm SMULASGIX.s01 +as-z80 -l -o SMULASGIX.s01 +@if errorlevel 1 goto failure +copy SMULASGIX.rel ..\..\..\lib\reliar + +copy ..\SMULASGIY.asm SMULASGIY.s01 +as-z80 -l -o SMULASGIY.s01 +@if errorlevel 1 goto failure +copy SMULASGIY.rel ..\..\..\lib\reliar + +copy ..\SSCMP.asm SSCMP.s01 +as-z80 -l -o SSCMP.s01 +@if errorlevel 1 goto failure +copy SSCMP.rel ..\..\..\lib\reliar + +copy ..\SSDIV.asm SSDIV.s01 +as-z80 -l -o SSDIV.s01 +@if errorlevel 1 goto failure +copy SSDIV.rel ..\..\..\lib\reliar + +copy ..\SSDIVASG.asm SSDIVASG.s01 +as-z80 -l -o SSDIVASG.s01 +@if errorlevel 1 goto failure +copy SSDIVASG.rel ..\..\..\lib\reliar + +copy ..\SSDIVASGBCprim.asm SSDIVASGBCprim.s01 +as-z80 -l -o SSDIVASGBCprim.s01 +@if errorlevel 1 goto failure +copy SSDIVASGBCprim.rel ..\..\..\lib\reliar + +copy ..\SSDIVASGDEprim.asm SSDIVASGDEprim.s01 +as-z80 -l -o SSDIVASGDEprim.s01 +@if errorlevel 1 goto failure +copy SSDIVASGDEprim.rel ..\..\..\lib\reliar + +copy ..\SSDIVASGIX.asm SSDIVASGIX.s01 +as-z80 -l -o SSDIVASGIX.s01 +@if errorlevel 1 goto failure +copy SSDIVASGIX.rel ..\..\..\lib\reliar + +copy ..\SSDIVASGIY.asm SSDIVASGIY.s01 +as-z80 -l -o SSDIVASGIY.s01 +@if errorlevel 1 goto failure +copy SSDIVASGIY.rel ..\..\..\lib\reliar + +copy ..\SSMOD.asm SSMOD.s01 +as-z80 -l -o SSMOD.s01 +@if errorlevel 1 goto failure +copy SSMOD.rel ..\..\..\lib\reliar + +copy ..\SSMODASG.asm SSMODASG.s01 +as-z80 -l -o SSMODASG.s01 +@if errorlevel 1 goto failure +copy SSMODASG.rel ..\..\..\lib\reliar + +copy ..\SSMODASGBCprim.asm SSMODASGBCprim.s01 +as-z80 -l -o SSMODASGBCprim.s01 +@if errorlevel 1 goto failure +copy SSMODASGBCprim.rel ..\..\..\lib\reliar + +copy ..\SSMODASGDEprim.asm SSMODASGDEprim.s01 +as-z80 -l -o SSMODASGDEprim.s01 +@if errorlevel 1 goto failure +copy SSMODASGDEprim.rel ..\..\..\lib\reliar + +copy ..\SSMODASGIX.asm SSMODASGIX.s01 +as-z80 -l -o SSMODASGIX.s01 +@if errorlevel 1 goto failure +copy SSMODASGIX.rel ..\..\..\lib\reliar + +copy ..\SSMODASGIY.asm SSMODASGIY.s01 +as-z80 -l -o SSMODASGIY.s01 +@if errorlevel 1 goto failure +copy SSMODASGIY.rel ..\..\..\lib\reliar + +copy ..\SSRSH.asm SSRSH.s01 +as-z80 -l -o SSRSH.s01 +@if errorlevel 1 goto failure +copy SSRSH.rel ..\..\..\lib\reliar + +copy ..\SSRSHASG.asm SSRSHASG.s01 +as-z80 -l -o SSRSHASG.s01 +@if errorlevel 1 goto failure +copy SSRSHASG.rel ..\..\..\lib\reliar + +copy ..\SSRSHASGBCprim.asm SSRSHASGBCprim.s01 +as-z80 -l -o SSRSHASGBCprim.s01 +@if errorlevel 1 goto failure +copy SSRSHASGBCprim.rel ..\..\..\lib\reliar + +copy ..\SSRSHASGDEprim.asm SSRSHASGDEprim.s01 +as-z80 -l -o SSRSHASGDEprim.s01 +@if errorlevel 1 goto failure +copy SSRSHASGDEprim.rel ..\..\..\lib\reliar + +copy ..\SSRSHASGIX.asm SSRSHASGIX.s01 +as-z80 -l -o SSRSHASGIX.s01 +@if errorlevel 1 goto failure +copy SSRSHASGIX.rel ..\..\..\lib\reliar + +copy ..\SSRSHASGIY.asm SSRSHASGIY.s01 +as-z80 -l -o SSRSHASGIY.s01 +@if errorlevel 1 goto failure +copy SSRSHASGIY.rel ..\..\..\lib\reliar + +copy ..\SSSWITCH.asm SSSWITCH.s01 +as-z80 -l -o SSSWITCH.s01 +@if errorlevel 1 goto failure +copy SSSWITCH.rel ..\..\..\lib\reliar + +copy ..\SSWITCHEND.asm SSWITCHEND.s01 +as-z80 -l -o SSWITCHEND.s01 +@if errorlevel 1 goto failure +copy SSWITCHEND.rel ..\..\..\lib\reliar + +copy ..\STRCAT.asm STRCAT.s01 +as-z80 -l -o STRCAT.s01 +@if errorlevel 1 goto failure +copy STRCAT.rel ..\..\..\lib\reliar + +copy ..\STRCHR.asm STRCHR.s01 +as-z80 -l -o STRCHR.s01 +@if errorlevel 1 goto failure +copy STRCHR.rel ..\..\..\lib\reliar + +copy ..\STRCMP.asm STRCMP.s01 +as-z80 -l -o STRCMP.s01 +@if errorlevel 1 goto failure +copy STRCMP.rel ..\..\..\lib\reliar + +copy ..\STRCPY.asm STRCPY.s01 +as-z80 -l -o STRCPY.s01 +@if errorlevel 1 goto failure +copy STRCPY.rel ..\..\..\lib\reliar + +copy ..\STRLEN.asm STRLEN.s01 +as-z80 -l -o STRLEN.s01 +@if errorlevel 1 goto failure +copy STRLEN.rel ..\..\..\lib\reliar + +copy ..\SVSWITCH.asm SVSWITCH.s01 +as-z80 -l -o SVSWITCH.s01 +@if errorlevel 1 goto failure +copy SVSWITCH.rel ..\..\..\lib\reliar + +copy ..\UCDIV.asm UCDIV.s01 +as-z80 -l -o UCDIV.s01 +@if errorlevel 1 goto failure +copy UCDIV.rel ..\..\..\lib\reliar + +copy ..\UCMOD.asm UCMOD.s01 +as-z80 -l -o UCMOD.s01 +@if errorlevel 1 goto failure +copy UCMOD.rel ..\..\..\lib\reliar + +copy ..\UCRSH.asm UCRSH.s01 +as-z80 -l -o UCRSH.s01 +@if errorlevel 1 goto failure +copy UCRSH.rel ..\..\..\lib\reliar + +copy ..\UCRSHASG.asm UCRSHASG.s01 +as-z80 -l -o UCRSHASG.s01 +@if errorlevel 1 goto failure +copy UCRSHASG.rel ..\..\..\lib\reliar + +copy ..\ULDIV.asm ULDIV.s01 +as-z80 -l -o ULDIV.s01 +@if errorlevel 1 goto failure +copy ULDIV.rel ..\..\..\lib\reliar + +copy ..\ULDIVASG.asm ULDIVASG.s01 +as-z80 -l -o ULDIVASG.s01 +@if errorlevel 1 goto failure +copy ULDIVASG.rel ..\..\..\lib\reliar + +copy ..\ULMOD.asm ULMOD.s01 +as-z80 -l -o ULMOD.s01 +@if errorlevel 1 goto failure +copy ULMOD.rel ..\..\..\lib\reliar + +copy ..\ULMODASG.asm ULMODASG.s01 +as-z80 -l -o ULMODASG.s01 +@if errorlevel 1 goto failure +copy ULMODASG.rel ..\..\..\lib\reliar + +copy ..\ULRSH.asm ULRSH.s01 +as-z80 -l -o ULRSH.s01 +@if errorlevel 1 goto failure +copy ULRSH.rel ..\..\..\lib\reliar + +copy ..\ULRSHASG.asm ULRSHASG.s01 +as-z80 -l -o ULRSHASG.s01 +@if errorlevel 1 goto failure +copy ULRSHASG.rel ..\..\..\lib\reliar + +copy ..\USDIV.asm USDIV.s01 +as-z80 -l -o USDIV.s01 +@if errorlevel 1 goto failure +copy USDIV.rel ..\..\..\lib\reliar + +copy ..\USDIVASG.asm USDIVASG.s01 +as-z80 -l -o USDIVASG.s01 +@if errorlevel 1 goto failure +copy USDIVASG.rel ..\..\..\lib\reliar + +copy ..\USDIVASGBCprim.asm USDIVASGBCprim.s01 +as-z80 -l -o USDIVASGBCprim.s01 +@if errorlevel 1 goto failure +copy USDIVASGBCprim.rel ..\..\..\lib\reliar + +copy ..\USDIVASGDEprim.asm USDIVASGDEprim.s01 +as-z80 -l -o USDIVASGDEprim.s01 +@if errorlevel 1 goto failure +copy USDIVASGDEprim.rel ..\..\..\lib\reliar + +copy ..\USDIVASGIX.asm USDIVASGIX.s01 +as-z80 -l -o USDIVASGIX.s01 +@if errorlevel 1 goto failure +copy USDIVASGIX.rel ..\..\..\lib\reliar + +copy ..\USDIVASGIY.asm USDIVASGIY.s01 +as-z80 -l -o USDIVASGIY.s01 +@if errorlevel 1 goto failure +copy USDIVASGIY.rel ..\..\..\lib\reliar + +copy ..\USMOD.asm USMOD.s01 +as-z80 -l -o USMOD.s01 +@if errorlevel 1 goto failure +copy USMOD.rel ..\..\..\lib\reliar + +copy ..\USMODASG.asm USMODASG.s01 +as-z80 -l -o USMODASG.s01 +@if errorlevel 1 goto failure +copy USMODASG.rel ..\..\..\lib\reliar + +copy ..\USMODASGBCprim.asm USMODASGBCprim.s01 +as-z80 -l -o USMODASGBCprim.s01 +@if errorlevel 1 goto failure +copy USMODASGBCprim.rel ..\..\..\lib\reliar + +copy ..\USMODASGDEprim.asm USMODASGDEprim.s01 +as-z80 -l -o USMODASGDEprim.s01 +@if errorlevel 1 goto failure +copy USMODASGDEprim.rel ..\..\..\lib\reliar + +copy ..\USMODASGIX.asm USMODASGIX.s01 +as-z80 -l -o USMODASGIX.s01 +@if errorlevel 1 goto failure +copy USMODASGIX.rel ..\..\..\lib\reliar + +copy ..\USMODASGIY.asm USMODASGIY.s01 +as-z80 -l -o USMODASGIY.s01 +@if errorlevel 1 goto failure +copy USMODASGIY.rel ..\..\..\lib\reliar + +copy ..\USRSH.asm USRSH.s01 +as-z80 -l -o USRSH.s01 +@if errorlevel 1 goto failure +copy USRSH.rel ..\..\..\lib\reliar + +copy ..\USRSHASG.asm USRSHASG.s01 +as-z80 -l -o USRSHASG.s01 +@if errorlevel 1 goto failure +copy USRSHASG.rel ..\..\..\lib\reliar + +copy ..\USRSHASGBCprim.asm USRSHASGBCprim.s01 +as-z80 -l -o USRSHASGBCprim.s01 +@if errorlevel 1 goto failure +copy USRSHASGBCprim.rel ..\..\..\lib\reliar + +copy ..\USRSHASGDEprim.asm USRSHASGDEprim.s01 +as-z80 -l -o USRSHASGDEprim.s01 +@if errorlevel 1 goto failure +copy USRSHASGDEprim.rel ..\..\..\lib\reliar + +copy ..\USRSHASGIX.asm USRSHASGIX.s01 +as-z80 -l -o USRSHASGIX.s01 +@if errorlevel 1 goto failure +copy USRSHASGIX.rel ..\..\..\lib\reliar + +copy ..\USRSHASGIY.asm USRSHASGIY.s01 +as-z80 -l -o USRSHASGIY.s01 +@if errorlevel 1 goto failure +copy USRSHASGIY.rel ..\..\..\lib\reliar + +copy ..\VSWITCHEND.asm VSWITCHEND.s01 +as-z80 -l -o VSWITCHEND.s01 +@if errorlevel 1 goto failure +copy VSWITCHEND.rel ..\..\..\lib\reliar + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/libiar/calloc.asm b/src/libiar/calloc.asm new file mode 100755 index 00000000..bd33119b --- /dev/null +++ b/src/libiar/calloc.asm @@ -0,0 +1,47 @@ +; calloc.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module calloc + rseg CODE +code_base: + public calloc +calloc equ code_base+00000000h + extern malloc + extern ?CL64180B_4_06_L00 + extern ?S_MUL_L02 + extern ?L_INC_L03 + extern ?L_DEC_L03 + extern ?L_DECASG_L03 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0FDh,0E5h,0DDh,0E5h,0C5h,0D5h,0F5h + defb 0F5h,0CDh + defw LWRD ?S_MUL_L02 + defb 0EBh,001h,000h,000h,0E5h,021h,002h + defb 000h,039h,0D1h,073h,023h,072h,023h + defb 071h,023h,070h,03Eh + defb BYTE3 malloc + defb 021h + defw LWRD malloc + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0E5h,0FDh,0E1h,0E5h,0DDh,0E1h,07Dh + defb 0B4h,028h,019h,021h,000h,000h,039h + defb 0CDh + defw LWRD ?L_DECASG_L03 + defb 0EBh,0CDh + defw LWRD ?L_INC_L03 + defb 07Dh,0B4h,0B1h,0B0h,028h,008h,0DDh + defb 036h,000h,000h,0DDh,023h,018h,0E7h + defb 0FDh,0E5h,0E1h,0F1h,0F1h,0F1h,0F1h + defb 0DDh,0E1h,0FDh,0E1h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ceil.asm b/src/libiar/ceil.asm new file mode 100755 index 00000000..cfe2f570 --- /dev/null +++ b/src/libiar/ceil.asm @@ -0,0 +1,33 @@ +; ceil.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ceil + rseg CODE +code_base: + public ceil +ceil equ code_base+00000000h + extern floor + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09EFINED + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0EBh,079h,0B0h,028h,004h,078h,0EEh + defb 080h,047h,0EBh,03Eh + defb BYTE3 floor + defb 021h + defw LWRD floor + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 079h,0B0h,028h,004h,078h,0EEh,080h + defb 047h,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/cos.asm b/src/libiar/cos.asm new file mode 100755 index 00000000..a46fa20f --- /dev/null +++ b/src/libiar/cos.asm @@ -0,0 +1,31 @@ +; cos.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module cos + rseg CODE +code_base: + extern __sinus + public cos +cos equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 02Eh,001h,0E5h,0CBh,0B8h,03Eh + defb BYTE3 __sinus + defb 021h + defw LWRD __sinus + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0F1h,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/cosh.asm b/src/libiar/cosh.asm new file mode 100755 index 00000000..56bfac18 --- /dev/null +++ b/src/libiar/cosh.asm @@ -0,0 +1,64 @@ +; cosh.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module cosh + rseg CODE +code_base: + public cosh +cosh equ code_base+00000000h + extern errno + extern exp + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_MUL_L04 + extern ?F_DIV_L04 + extern ?F_ADD_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FCh,0FFh,0DDh,06Eh,002h,0DDh,066h + defb 003h,0CBh,0B8h,0DDh,070h,005h,0EBh + defb 03Eh + defb BYTE3 exp + defb 021h + defw LWRD exp + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C5h,0E5h,001h,000h,03Fh,069h,061h + defb 0CDh + defw LWRD ?F_MUL_L04 + defb 0DDh,075h,0FCh,0DDh,074h,0FDh,0DDh + defb 071h,0FEh,0DDh,070h,0FFh,021h,0FFh + defb 040h,0E5h,021h,029h,05Ch,0E5h,0DDh + defb 04Eh,004h,0DDh,046h,005h,0DDh,06Eh + defb 002h,0DDh,066h,003h,0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,02Ah,0DDh,06Eh,0FEh,0DDh,066h + defb 0FFh,0E5h,0DDh,06Eh,0FCh,0DDh,066h + defb 0FDh,0E5h,001h,080h,03Eh,021h,000h + defb 000h,0CDh + defw LWRD ?F_DIV_L04 + defb 0C5h,0E5h,0DDh,04Eh,0FEh,0DDh,046h + defb 0FFh,0DDh,06Eh,0FCh,0DDh,066h,0FDh + defb 0CDh + defw LWRD ?F_ADD_L04 + defb 018h,02Dh,021h,031h,043h,0E5h,021h + defb 018h,072h,0E5h,0DDh,06Eh,002h,0DDh + defb 066h,003h,0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,00Eh,0DDh,04Eh,0FEh,0DDh,046h + defb 0FFh,0DDh,06Eh,0FCh,0DDh,066h,0FDh + defb 018h,00Ch,021h,022h,000h,022h + defw LWRD errno + defb 001h,07Fh,07Fh,021h,0FFh,0FFh,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ctype.asm b/src/libiar/ctype.asm new file mode 100755 index 00000000..8fb44257 --- /dev/null +++ b/src/libiar/ctype.asm @@ -0,0 +1,38 @@ +; ctype.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ctype + rseg CODE +code_base: + rseg CONST +const_base: + t_symbol_def PUBLIC_REL (0004) 00000000 '_Small_Ctype' + extern ?CL64180B_4_06_L00 + t_org_rel (04) 00000000 + defb 000h,020h,020h,020h,020h,020h,020h + defb 020h,020h,020h,028h,028h,028h,028h + defb 028h,020h,020h,020h,020h,020h,020h + defb 020h,020h,020h,020h,020h,020h,020h + defb 020h,020h,020h,020h,020h,088h,010h + defb 010h,010h,010h,010h,010h,010h,010h + defb 010h,010h,010h,010h,010h,010h,010h + defb 004h,004h,004h,004h + defb 004h,004h,004h,004h,004h,004h,010h + defb 010h,010h,010h,010h,010h,010h,041h + defb 041h,041h,041h,041h,041h,001h,001h + defb 001h,001h,001h,001h,001h,001h,001h + defb 001h,001h,001h,001h,001h,001h,001h + defb 001h,001h,001h,001h,010h,010h,010h + defb 010h,010h,010h,042h,042h,042h,042h + defb 042h,042h,002h,002h + defb 002h,002h,002h,002h,002h,002h,002h + defb 002h,002h,002h,002h,002h,002h,002h + defb 002h,002h,002h,002h,010h,010h,010h + defb 010h,020h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/daddexp.asm b/src/libiar/daddexp.asm new file mode 100755 index 00000000..15b8601a --- /dev/null +++ b/src/libiar/daddexp.asm @@ -0,0 +1,19 @@ +; daddexp.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ?__daddexp_L11 + rseg RCODE +rcode_base: + public ?__daddexp_L11 +?__daddexp_L11 equ rcode_base+00000000h + defb 0F5h,079h,007h,078h,017h,085h,0CBh + defb 03Fh,0F5h,06Fh,078h,0E6h,080h,0B5h + defb 047h,0CBh,021h,0F1h,0CBh,019h,0F1h + defb 0C9h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/div.asm b/src/libiar/div.asm new file mode 100755 index 00000000..1949b0fa --- /dev/null +++ b/src/libiar/div.asm @@ -0,0 +1,36 @@ +; div.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module div + 00000000 "quot" [0066] 00000002 "rem" [0066] + rseg CODE +code_base: + public div +div equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SS_DIV_L02 + extern ?S_MUL_L02 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FCh,0FFh,0DDh,04Eh,00Ah,0DDh,046h + defb 00Bh,0DDh,05Eh,004h,0DDh,056h,005h + defb 0CDh + defw LWRD ?SS_DIV_L02 + defb 0DDh,073h,0FCh,0DDh,072h,0FDh,0CDh + defw LWRD ?S_MUL_L02 + defb 0DDh,06Eh,004h,0DDh,066h,005h,0A7h + defb 0EDh,052h,0DDh,075h,0FEh,0DDh,074h + defb 0FFh,021h,000h,000h,039h,0DDh,05Eh + defb 002h,0DDh,056h,003h,001h,004h,000h + defb 0D5h,0EDh,0B0h,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/errno.asm b/src/libiar/errno.asm new file mode 100755 index 00000000..bcd01862 --- /dev/null +++ b/src/libiar/errno.asm @@ -0,0 +1,19 @@ +; errno.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module errno + rseg CODE +code_base: + rseg UDATA0 +udata0_base: + t_symbol_def PUBLIC_REL (000A) 00000000 'errno' + extern ?CL64180B_4_06_L00 + t_org_rel (0A) 00000000 + t_org_rel (0A) 00000002 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/exit0.asm b/src/libiar/exit0.asm new file mode 100755 index 00000000..65e515c8 --- /dev/null +++ b/src/libiar/exit0.asm @@ -0,0 +1,22 @@ +; exit0.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module exit0 + rseg RCODE +rcode_base: + public exit +exit equ rcode_base+00000001h + public ?C_EXIT +?C_EXIT equ rcode_base+00000001h + public ?C_FUNCALL +?C_FUNCALL equ rcode_base+00000000h + public ?DBG_0 +?DBG_0 equ 00000000h + defb 000h,018h,0FEh + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/exit1.asm b/src/libiar/exit1.asm new file mode 100755 index 00000000..9923ed31 --- /dev/null +++ b/src/libiar/exit1.asm @@ -0,0 +1,22 @@ +; exit1.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module exit1 + rseg RCODE +rcode_base: + public exit +exit equ rcode_base+00000001h + public ?C_EXIT +?C_EXIT equ rcode_base+00000001h + public ?C_FUNCALL +?C_FUNCALL equ rcode_base+00000000h + public ?DBG_1 +?DBG_1 equ 00000000h + defb 000h,000h,000h,000h,018h,0FBh + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/exit2.asm b/src/libiar/exit2.asm new file mode 100755 index 00000000..3e74a914 --- /dev/null +++ b/src/libiar/exit2.asm @@ -0,0 +1,22 @@ +; exit2.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module exit2 + rseg RCODE +rcode_base: + public exit +exit equ rcode_base+00000001h + public ?C_EXIT +?C_EXIT equ rcode_base+00000001h + public ?C_FUNCALL +?C_FUNCALL equ rcode_base+00000000h + public ?DBG_2 +?DBG_2 equ 00000002h + defb 000h,000h,000h,000h,018h,0FBh + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/exp.asm b/src/libiar/exp.asm new file mode 100755 index 00000000..79d56c44 --- /dev/null +++ b/src/libiar/exp.asm @@ -0,0 +1,118 @@ +; exp.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module exp + rseg CODE +code_base: + extern errno + public exp +exp equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_MUL_L04 + extern ?F_ADD_L04 + extern ?F_SUB_L04 + extern ?F_TO_L_L04 + extern ?SL_TO_F_L04 + extern ?F_MULASG_L04 + extern ?F_ADDASG_L04 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + extern ?__daddexp_L11 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FAh,0FFh,079h,0B0h,020h,008h,001h + defb 080h,03Fh,06Fh,067h,0C3h + defw LWRD code_base+00149h + defb 0DDh,06Eh,002h,0DDh,066h,003h,0CBh + defb 0B8h,0C5h,0E5h,001h,0B0h,042h,021h + defb 000h,000h,0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,019h,02Eh,022h,022h + defw LWRD errno + defb 0DDh,0CBh,005h,07Eh,028h,005h,04Ch + defb 069h,044h,018h,006h,001h,07Fh,07Fh + defb 021h,0FFh,0FFh,0C3h + defw LWRD code_base+00149h + defb 02Eh,008h,039h,001h,0B8h,03Fh,011h + defb 03Bh,0AAh,0CDh + defw LWRD ?F_MULASG_L04 + defb 0EBh,0CBh,0B8h,0CDh + defw LWRD ?F_TO_L_L04 + defb 0DDh,075h,0FEh,0DDh,0CBh,005h,07Eh + defb 028h,01Dh,07Dh,007h,09Fh,067h,044h + defb 04Ch,0CDh + defw LWRD ?SL_TO_F_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+0014Ch + defb 079h,0B0h,028h,003h,0DDh,034h,0FEh + defb 0DDh,07Eh,0FEh,0EDh,044h,0DDh,077h + defb 0FEh,0DDh,06Eh,0FEh,07Dh,007h,09Fh + defb 067h,044h,04Ch,0CDh + defw LWRD ?SL_TO_F_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+0014Ch + defb 0DDh,075h,0FAh,0DDh,074h,0FBh,0DDh + defb 071h,0FCh,0DDh,070h,0FDh,011h,000h + defb 03Fh,0D5h,053h,0D5h,0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,00Fh,06Bh,062h,039h,001h,000h + defb 03Fh,0CDh + defw LWRD ?F_ADDASG_L04 + defb 0DDh,036h,0FFh,001h,018h,003h,0DDh + defb 072h,0FFh,021h,063h,039h,0E5h,021h + defb 08Ch,090h,0E5h,0CDh + defw LWRD code_base+0015Bh + defb 0C5h,0E5h,001h,0A3h,03Ah,021h,0AAh + defb 00Ch,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+0015Bh + defb 0C5h,0E5h,001h,01Eh,03Ch,021h,000h + defb 094h,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+0015Bh + defb 0C5h,0E5h,001h,063h,03Dh,021h,080h + defb 042h,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+0015Bh + defb 0C5h,0E5h,001h,075h,03Eh,021h,0CFh + defb 0FEh,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+0015Bh + defb 0C5h,0E5h,001h,031h,03Fh,021h,015h + defb 072h,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+0015Bh + defb 0C5h,0E5h,001h,080h,03Fh,021h,000h + defb 000h,0CDh + defw LWRD ?F_ADD_L04 + defb 0DDh,075h,002h,0DDh,074h,003h,0DDh + defb 071h,004h,0DDh,070h,005h,0AFh,0DDh + defb 0B6h,0FFh,028h,00Dh,021h,008h,000h + defb 039h,001h,035h,03Fh,011h,0F3h,004h + defb 0CDh + defw LWRD ?F_MULASG_L04 + defb 0DDh,04Eh,004h,0DDh,046h,005h,0DDh + defb 05Eh,002h,0DDh,056h,003h,0DDh,06Eh + defb 0FEh,0CDh + defw LWRD ?__daddexp_L11 + defb 0EBh,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + defb 0DDh,04Eh,004h,0DDh,046h,005h,0DDh + defb 06Eh,002h,0DDh,066h,003h,0C3h + defw LWRD ?F_SUB_L04 + defb 0DDh,04Eh,0FCh,0DDh,046h,0FDh,0DDh + defb 06Eh,0FAh,0DDh,066h,0FBh,0C3h + defw LWRD ?F_MUL_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/exp10.asm b/src/libiar/exp10.asm new file mode 100755 index 00000000..f19c4ba7 --- /dev/null +++ b/src/libiar/exp10.asm @@ -0,0 +1,45 @@ +; exp10.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module exp10 + rseg CODE +code_base: + extern errno + extern exp + public exp10 +exp10 equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_MUL_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0CBh,0B8h,0C5h,0D5h,001h,018h,042h + defb 021h,000h,000h,0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,018h,02Eh,022h,022h + defw LWRD errno + defb 0DDh,0CBh,005h,07Eh,028h,005h,04Ch + defb 069h,044h,018h,023h,001h,07Fh,07Fh + defb 021h,0FFh,0FFh,018h,01Bh,021h,013h + defb 040h,0E5h,021h,08Eh,05Dh,0E5h,0DDh + defb 04Eh,004h,0DDh,046h,005h,0EBh,0CDh + defw LWRD ?F_MUL_L04 + defb 0EBh,03Eh + defb BYTE3 exp + defb 021h + defw LWRD exp + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/fabs.asm b/src/libiar/fabs.asm new file mode 100755 index 00000000..88c42874 --- /dev/null +++ b/src/libiar/fabs.asm @@ -0,0 +1,23 @@ +; fabs.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module fabs + rseg CODE +code_base: + public fabs +fabs equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0EBh,0CBh,0B8h,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/floor.asm b/src/libiar/floor.asm new file mode 100755 index 00000000..e822a2d0 --- /dev/null +++ b/src/libiar/floor.asm @@ -0,0 +1,55 @@ +; floor.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module floor + rseg CODE +code_base: + public floor +floor equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_SUB_L04 + extern ?F_TO_L_L04 + extern ?SL_TO_F_L04 + extern ?F_ADDASG_L04 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FCh,0FFh,021h,018h,04Bh,0E5h,021h + defb 080h,096h,0E5h,0DDh,06Eh,002h,0DDh + defb 066h,003h,0CBh,0B8h,0CDh + defw LWRD ?SL_CMP_L03 + defb 038h,005h,0DDh,046h,005h,018h,05Eh + defb 0DDh,0CBh,005h,07Eh,0DDh,046h,005h + defb 028h,04Fh,0CBh,0B8h,0DDh,070h,005h + defb 0CDh + defw LWRD ?F_TO_L_L04 + defb 0CDh + defw LWRD ?SL_TO_F_L04 + defb 0DDh,075h,0FCh,0DDh,074h,0FDh,0DDh + defb 071h,0FEh,0DDh,070h,0FFh,0C5h,0E5h + defb 0DDh,04Eh,004h,0DDh,046h,005h,0DDh + defb 06Eh,002h,0DDh,066h,003h,0CDh + defw LWRD ?F_SUB_L04 + defb 079h,0B0h,028h,00Dh,021h,000h,000h + defb 039h,001h,080h,03Fh,011h,000h,000h + defb 0CDh + defw LWRD ?F_ADDASG_L04 + defb 0DDh,04Eh,0FEh,079h,0DDh,046h,0FFh + defb 0DDh,06Eh,0FCh,0DDh,066h,0FDh,0B0h + defb 028h,00Ch,078h,0EEh,080h,047h,018h + defb 006h,0CDh + defw LWRD ?F_TO_L_L04 + defb 0CDh + defw LWRD ?SL_TO_F_L04 + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/fmod.asm b/src/libiar/fmod.asm new file mode 100755 index 00000000..c8ce54a0 --- /dev/null +++ b/src/libiar/fmod.asm @@ -0,0 +1,58 @@ +; fmod.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module fmod + rseg CODE +code_base: + extern floor + public fmod +fmod equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?F_MUL_L04 + extern ?F_DIV_L04 + extern ?F_SUB_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FCh,0FFh,0DDh,07Eh,00Ch,0DDh,0B6h + defb 00Dh,020h,006h,04Fh,069h,047h,060h + defb 018h,067h,0DDh,06Eh,00Ch,0DDh,066h + defb 00Dh,0E5h,0DDh,06Eh,00Ah,0DDh,066h + defb 00Bh,0E5h,0DDh,06Eh,002h,0DDh,066h + defb 003h,0CDh + defw LWRD ?F_DIV_L04 + defb 0CBh,078h,05Dh,054h,028h,014h,0CBh + defb 0B8h,03Eh + defb BYTE3 floor + defb 021h + defw LWRD floor + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 079h,0B0h,028h,00Eh,078h,0EEh,080h + defb 047h,018h,008h,03Eh + defb BYTE3 floor + defb 021h + defw LWRD floor + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,075h,0FCh,0DDh,074h,0FDh,0DDh + defb 06Eh,00Ch,0DDh,066h,00Dh,0E5h,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,0E5h,0DDh + defb 06Eh,0FCh,0DDh,066h,0FDh,0CDh + defw LWRD ?F_MUL_L04 + defb 0C5h,0E5h,0DDh,04Eh,004h,0DDh,046h + defb 005h,0DDh,06Eh,002h,0DDh,066h,003h + defb 0CDh + defw LWRD ?F_SUB_L04 + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/formattedread.asm b/src/libiar/formattedread.asm new file mode 100755 index 00000000..1ce84b49 --- /dev/null +++ b/src/libiar/formattedread.asm @@ -0,0 +1,597 @@ +; formattedread.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module _formatted_read + rseg CODE +code_base: + extern _Small_Ctype + public _formatted_read +_formatted_read equ code_base+000001D6h + extern ?CL64180B_4_06_L00 + extern ?SS_CMP_L02 + extern ?SS_RSHASG_L02 + extern ?L_MUL_L03 + extern ?SL_CMP_L03 + extern ?L_NEGASG_L03 + extern ?F_MUL_L04 + extern ?F_DIV_L04 + extern ?F_ADD_L04 + extern ?F_CMP_L04 + extern ?SL_TO_F_L04 + extern ?F_MULASG_L04 + extern ?F_DIVASG_L04 + extern ?F_ADDASG_L04 + extern ?C_V_SWITCH_L06 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?ENT_PARM_DIRECT_L09 + extern ?ENT_AUTO_DIRECT_L09 + extern ?LEAVE_DIRECT_L09 + extern ?LEAVE_32_L09 + extern ?SS_RSHASG_IX_L12 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 000h,000h,011h,000h,000h,0DDh,06Eh + defb 002h,0DDh,066h,003h,07Eh,023h,066h + defb 06Fh,04Eh,006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,056h,028h,048h,0DDh,06Eh + defb 004h,0DDh,066h,005h,07Eh,023h,0B6h + defb 028h,03Dh,0DDh,06Eh,002h,0DDh,066h + defb 003h,04Eh,023h,046h,003h,070h,02Bh + defb 071h,00Bh,00Ah,04Fh,006h,000h,0C5h + defb 0EBh,029h,04Dh,044h,029h,029h,009h + defb 0C1h,009h,001h,0D0h,0FFh,009h,0EBh + defb 04Bh,042h,021h,0E8h + defb 003h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,003h,011h,0E8h,003h,0DDh,06Eh + defb 004h,0DDh,066h,005h,04Eh,023h,046h + defb 00Bh,070h,02Bh,071h,018h,0A3h,0EBh + defb 0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 000h,000h,0DDh,06Eh,002h,0DDh,066h + defb 003h,07Eh,023h,066h,06Fh,05Eh,021h + defw LWRD _Small_Ctype 0001 + defb 04Bh,006h,000h,009h,0CBh,05Eh,028h + defb 011h,0DDh,06Eh,002h,0DDh,066h,003h + defb 04Eh,023h,046h,003h,070h,02Bh,071h + defb 00Ah,05Fh,018h,0E4h,07Bh,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Small_Ctype 0001 + defb 016h,000h,019h,0CBh,04Eh,07Bh,028h + defb 002h,0E6h,05Fh,0DDh,077h,002h,0FEh + defb 041h,038h,00Eh,03Eh,05Ah,0DDh,0BEh + defb 002h,038h,007h,0DDh,07Eh,002h,0C6h + defb 0C9h,018h,00Fh,021h + defw LWRD _Small_Ctype 0001 + defb 0DDh,04Eh,002h,042h,009h,0CBh,056h + defb 028h,008h,079h,0D6h,030h,0DDh,0BEh + defb 004h,038h,002h,03Eh,064h,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FEh,0FFh,0DDh,05Eh,002h,0DDh,056h + defb 003h,0CDh + defw LWRD code_base+00069h + defb 0DDh,077h,0FEh,0FEh,02Bh,028h,004h + defb 0FEh,02Dh,020h,038h,0DDh,06Eh,008h + defb 0DDh,066h,009h,07Eh,023h,0B6h,028h + defb 02Dh,0DDh,06Eh,008h,0DDh,066h,009h + defb 04Eh,023h,046h,00Bh,070h,02Bh,071h + defb 0DDh,07Eh,0FEh,0FEh,02Dh,020h,008h + defb 0DDh,06Eh,004h,0DDh,066h,005h,036h + defb 001h,0DDh,06Eh,002h + defb 0DDh,066h,003h,04Eh,023h,046h,003h + defb 070h,02Bh,071h,00Ah,0DDh,077h,0FEh + defb 0DDh,07Eh,0FEh,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0FDh,0E5h,0DDh,06Eh,008h,0DDh,066h + defb 009h,0E5h,0FDh,0E1h,0FDh,07Eh,000h + defb 0DDh,0BEh,002h,020h,005h,0DDh,07Eh + defb 004h,018h,01Ah,0FDh,07Eh,001h,0B7h + defb 0FDh,023h,028h,007h,0FDh,07Eh,000h + defb 0FEh,05Dh,020h,0E4h,0AFh,0DDh,0B6h + defb 004h,020h,004h,03Eh,001h,018h,001h + defb 0AFh,0FDh,0E1h,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0DDh,0E5h,0F5h,0F5h,0F5h,0F5h,0D5h + defb 0DDh,0E1h,021h,000h,000h,039h,0AFh + defb 077h,023h,077h,023h,036h,020h,023h + defb 036h,041h,023h,077h,023h,077h,023h + defb 036h,080h,023h,036h,03Fh,0DDh,0E5h + defb 0E1h,07Dh,0B4h,028h,033h,0CBh,045h + defb 028h,014h,021h,004h,000h,039h,0E5h + defb 021h,002h,000h,039h + defb 05Eh,023h,056h,023h,04Eh,023h,046h + defb 0E1h,0CDh + defw LWRD ?F_MULASG_L04 + defb 006h,001h,0CDh + defw LWRD ?SS_RSHASG_IX_L12 + defb 07Dh,0B4h,028h,0D8h,021h,000h,000h + defb 039h,0E5h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0E1h,0CDh + defw LWRD ?F_MULASG_L04 + defb 018h,0C6h,021h,004h,000h,039h,05Eh + defb 023h,056h,023h,04Eh,023h,046h,0EBh + defb 0F1h,0F1h,0F1h,0F1h,0DDh,0E1h,0C9h + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0E2h,0FFh,0FDh,0E5h,0DDh,06Eh,002h + defb 0DDh,066h,003h,0E5h,0FDh,0E1h,0FDh + defb 06Eh,000h,0DDh,075h,0FEh,0FDh,066h + defb 001h,0DDh,074h,0FFh,0AFh,0DDh,077h + defb 0F0h,0DDh,077h,0F1h,0DDh,06Eh,004h + defb 0DDh,066h,005h,07Eh,023h,066h,06Fh + defb 046h,004h,005h,0CAh + defw LWRD code_base+00B4Fh + defb 021h + defw LWRD _Small_Ctype 0001 + defb 048h,006h,000h,009h,0CBh,05Eh,028h + defb 026h,0FDh,06Eh,000h,0FDh,066h,001h + defb 04Eh,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,05Eh,028h,00Ah,0FDh,0E5h + defb 0E1h,034h,023h,020h,0EAh,034h,018h + defb 0E7h,0DDh,06Eh,004h,0DDh,066h,005h + defb 034h,023h,020h,0C2h,034h,018h,0BFh + defb 0DDh,06Eh,004h,0DDh,066h,005h,07Eh + defb 023h,066h,06Fh,07Eh,0FEh,025h,020h + defb 010h,0DDh,06Eh,004h,0DDh,066h,005h + defb 046h,023h,066h,068h + defb 023h,07Eh,0FEh,06Eh,028h,00Bh,0FDh + defb 06Eh,000h,0FDh,066h,001h,0AFh,0B6h + defb 0CAh + defw LWRD code_base+00B23h + defb 079h,0FEh,025h,028h,020h,0DDh,06Eh + defb 004h,0DDh,066h,005h,034h,023h,020h + defb 001h,034h,0FDh,0E5h,0D1h,0CDh + defw LWRD code_base+00069h + defb 0B9h,0C2h + defw LWRD code_base+00B4Fh + defb 0FDh,0E5h,0E1h,034h,023h,020h,001h + defb 034h,0C3h + defw LWRD code_base+001F9h + defb 0DDh,036h,0E4h,000h,0DDh,06Eh,004h + defb 0DDh,066h,005h,04Eh,023h,046h,003h + defb 070h,02Bh,071h,00Ah,0DDh,077h,0E3h + defb 0FEh,02Ah,020h,017h,0DDh,06Eh,004h + defb 0DDh,066h,005h,04Eh,023h,046h,003h + defb 070h,02Bh,071h,00Ah,0DDh,077h,0E3h + defb 0DDh,0CBh,0E2h,086h,018h,004h,0DDh + defb 0CBh,0E2h,0C6h,021h + defw LWRD _Small_Ctype 0001 + defb 04Fh,006h,000h,009h,0CBh,056h,028h + defb 02Ch,0DDh,070h,0EEh,0DDh,036h,0EFh + defb 002h,021h,00Eh,000h,039h,04Dh,044h + defb 0DDh,05Eh,004h,0DDh,056h,005h,0CDh + defw LWRD code_base+00000h + defb 0DDh,075h,0E6h,0DDh,074h,0E7h,0DDh + defb 06Eh,004h,0DDh,066h,005h,07Eh,023h + defb 066h,06Fh,046h,0DDh,070h,0E3h,018h + defb 007h,0DDh,070h,0E6h,0DDh,036h,0E7h + defb 002h,0DDh,07Eh,0E2h,0E6h,0F3h,0DDh + defb 077h,0E2h,0DDh,07Eh,0E3h,0FEh,06Ch + defb 028h,004h,0FEh,04Ch,020h,006h,0DDh + defb 0CBh,0E2h,0DEh,018h + defb 00Bh,0FEh,068h,020h,015h,0AFh,028h + defb 004h,0DDh,0CBh,0E2h,0D6h,0DDh,06Eh + defb 004h,0DDh,066h,005h,04Eh,023h,046h + defb 003h,070h,02Bh,071h,00Ah,0DDh,06Eh + defb 004h,0DDh,066h,005h,034h,023h,020h + defb 001h,034h,05Fh,0CDh + defw LWRD ?C_V_SWITCH_L06 + defb 012h,000h,025h,045h,047h,058h,05Bh + defb 063h,064h,065h,066h,067h,068h,069h + defb 06Eh,06Fh,070h,073h,075h,078h + defw LWRD code_base+00B4Fh + defw LWRD code_base+0071Ah + defw LWRD code_base+007BDh + defw LWRD code_base+00A52h + defw LWRD code_base+007ACh + defw LWRD code_base+00713h + defw LWRD code_base+00AE3h + defw LWRD code_base+00720h + defw LWRD code_base+007BDh + defw LWRD code_base+00376h + defw LWRD code_base+00376h + defw LWRD code_base+00376h + defw LWRD code_base+007BDh + defw LWRD code_base+009CAh + defw LWRD code_base+008BFh + defw LWRD code_base+0071Ah + defw LWRD code_base+00376h + defw LWRD code_base+00376h + defw LWRD code_base+00B12h + defb 021h,006h,000h,039h,0E5h,0CDh + defw LWRD code_base+00B5Ah + defb 0E1h,0DDh,077h,0E3h,0DDh,06Eh,0E6h + defb 0DDh,066h,0E7h,0DDh,075h,0EEh,0DDh + defb 074h,0EFh,0AFh,0DDh,077h,0E8h,0DDh + defb 077h,0E9h,0DDh,077h,0EAh,0DDh,077h + defb 0EBh,0DDh,036h,0FCh,0FFh,0DDh,036h + defb 0FDh,0FFh,0DDh,07Eh,0E6h,0DDh,0B6h + defb 0E7h,028h,024h,0DDh,07Eh,0E3h,0FEh + defb 030h,020h,01Dh,0DDh + defb 06Eh,0E6h,0DDh,066h,0E7h,02Bh,0DDh + defb 075h,0E6h,0DDh,074h,0E7h,0FDh,0E5h + defb 0E1h,04Eh,023h,046h,003h,070h,02Bh + defb 071h,00Ah,0DDh,077h,0E3h,018h,0D4h + defb 0DDh,07Eh,0E6h,0DDh,0B6h,0E7h,028h + defb 07Eh,021h + defw LWRD _Small_Ctype 0001 + defb 0DDh,04Eh,0E3h,006h,000h,009h,0CBh + defb 056h,028h,071h,0DDh,06Eh,0FCh,0DDh + defb 066h,0FDh,023h,0DDh,075h,0FCh,0DDh + defb 074h,0FDh,03Eh,026h,0ADh,0B4h,0CAh + defw LWRD code_base+00B23h + defb 0AFh,028h,00Eh,00Eh,026h,023h,0DDh + defb 075h,0FCh,0DDh,074h,0FDh,0EDh,042h + defb 0CAh + defw LWRD code_base+00B23h + defb 0DDh,06Eh,0E6h,0DDh,066h,0E7h,02Bh + defb 0DDh,075h,0E6h,0DDh,074h,0E7h,0DDh + defb 04Eh,0E3h,0CDh + defw LWRD code_base+00B64h + defb 0C5h,0E5h,021h,020h,041h,0E5h,021h + defb 000h,000h,0E5h,0DDh,04Eh,0EAh,0DDh + defb 046h,0EBh,0DDh,06Eh,0E8h,0DDh,066h + defb 0E9h,0CDh + defw LWRD ?F_MUL_L04 + defb 0CDh + defw LWRD ?F_ADD_L04 + defb 0DDh,075h,0E8h,0DDh,074h,0E9h,0DDh + defb 071h,0EAh,0DDh,070h,0EBh,0FDh,0E5h + defb 0E1h,04Eh,023h,046h,003h,070h,02Bh + defb 071h,00Ah,0DDh,077h,0E3h,0C +h,0 h + defb 0 h,0t_h,0abh,0s_h,0vah,0r h,0 h + defb 0 h,0 h,0 h,0 h,0 3h + defw LWRD code_base+003CFh + defb 0DDh,07Eh,0E3h,0FEh,02Eh,0C2h + defw LWRD code_base+004ECh + defb 0DDh,07Eh,0E6h,0DDh,0B6h,0E7h,0CAh + defw LWRD code_base+004ECh + defb 0DDh,06Eh,0E6h,0DDh,066h,0E7h,02Bh + defb 0DDh,075h,0E6h,0DDh,074h,0E7h,0DDh + defb 06Eh,0EEh,0DDh,066h,0EFh,02Bh,0DDh + defb 075h,0EEh,0DDh,074h,0EFh,0AFh,0DDh + defb 077h,0F4h,0DDh,077h,0F5h,0DDh,036h + defb 0F6h,080h,0DDh,036h,0F7h,03Fh,0DDh + defb 07Eh,0E6h,0DDh,0B6h,0E7h,028h,055h + defb 0FDh,0E5h,0E1h,04Eh + defb 023h,046h,003h,070h,02Bh,071h,00Ah + defb 0DDh,077h,0E3h,04Fh,006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,056h,028h,03Ch,0DDh,06Eh + defb 0E6h,0DDh,066h,0E7h,02Bh,0DDh,075h + defb 0E6h,0DDh,074h,0E7h,021h,008h,000h + defb 039h,0E5h,0CDh + defw LWRD code_base+00B64h + defb 0C5h,0E5h,021h,01Ah,000h,039h,001h + defb 0CCh,03Dh,011h,0CDh,0CCh,0CDh + defw LWRD ?F_MULASG_L04 + defb 0EBh,0CDh + defw LWRD ?F_MUL_L04 + defb 0EBh,0E1h,0CDh + defw LWRD ?F_ADDASG_L04 + defb 079h,0B0h,028h,0AEh,0DDh,07Eh,0F6h + defb 0DDh,0B6h,0F7h,020h,0A6h,0C3h + defw LWRD code_base+00B23h + defb 0DDh,06Eh,0E6h,0DDh,066h,0E7h,0DDh + defb 04Eh,0EEh,0DDh,046h,0EFh,0A7h,0EDh + defb 042h,0CAh + defw LWRD code_base+00B23h + defb 0DDh,06Eh,0E6h,0DDh,066h,0E7h,02Bh + defb 0DDh,075h,0E6h,0DDh,074h,0E7h,023h + defb 07Dh,0B4h,0CAh + defw LWRD code_base+0066Fh + defb 021h + defw LWRD _Small_Ctype 0001 + defb 0DDh,04Eh,0E3h,006h,000h,009h,0CBh + defb 046h,028h,006h,041h,0CBh,0E8h,078h + defb 018h,001h,079h,0FEh,065h,0C2h + defw LWRD code_base+0066Fh + defb 0FDh,0E5h,0E1h,034h,023h,020h,001h + defb 034h,0DDh,036h,0E5h,000h,021h,006h + defb 000h,039h,0E5h,0CDh + defw LWRD code_base+00B5Bh + defb 0E1h,04Fh,006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,056h,0CAh + defw LWRD code_base+00B23h + defb 021h,006h,000h,039h,04Dh,044h,0FDh + defb 0E5h,0D1h,0CDh + defw LWRD code_base+00000h + defb 0DDh,075h,0EEh,0DDh,074h,0EFh,0AFh + defb 0DDh,0B6h,0E5h,028h,05Ah,0DDh,04Eh + defb 0EAh,0DDh,046h,0EBh,0DDh,071h,0F6h + defb 0DDh,070h,0F7h,04Dh,044h,021h,026h + defb 000h,0CDh + defw LWRD ?SS_CMP_L02 + defb 0DAh + defw LWRD code_base+00B23h + defb 02Eh,008h,039h,0E5h,059h,050h,0CDh + defw LWRD code_base+00168h + defb 0EBh,0E1h,0CDh + defw LWRD ?F_DIVASG_L04 + defb 0DDh,07Eh,0F6h,0DDh,0B6h,0F7h,028h + defb 009h,0DDh,07Eh,0EAh,0DDh,0B6h,0EBh + defb 0CAh + defw LWRD code_base+00B23h + defb 0AFh,028h,01Eh,0DDh,0CBh,0E2h,05Eh + defb 020h,018h,021h,080h,000h,0E5h,06Ch + defb 0E5h,0DDh,04Eh,0EAh,0DDh,046h,0EBh + defb 0DDh,06Eh,0E8h,0DDh,066h,0E9h,0CDh + defw LWRD ?SL_CMP_L03 + defb 0DAh + defw LWRD code_base+00B23h + defb 0C3h + defw LWRD code_base+0066Fh + defb 0DDh,036h,0F4h,0FFh,0DDh,036h,0F5h + defb 0FFh,0DDh,036h,0F6h,07Fh,0DDh,036h + defb 0F7h,07Fh,0DDh,036h,0ECh,026h,0DDh + defb 077h,0EDh,028h,01Bh,001h,07Fh,07Fh + defb 021h,0FFh,0FFh,0DDh,075h,0F4h,0DDh + defb 074h,0F5h,0DDh,071h,0F6h,0DDh,070h + defb 0F7h,021h,026h,000h,0DDh,075h,0ECh + defb 0DDh,074h,0EDh,0DDh + defb 06Eh,0EEh,0DDh,066h,0EFh,0DDh,04Eh + defb 0FCh,0DDh,046h,0FDh,009h,04Dh,044h + defb 0DDh,06Eh,0ECh,0DDh,066h,0EDh,0CDh + defw LWRD ?SS_CMP_L02 + defb 0DAh + defw LWRD code_base+00B23h + defb 0DDh,06Eh,0EEh,0DDh,066h,0EFh,0DDh + defb 04Eh,0FCh,0DDh,046h,0FDh,009h,0DDh + defb 04Eh,0ECh,0DDh,046h,0EDh,0A7h,0EDh + defb 042h,020h,038h,0DDh,06Eh,0EAh,0DDh + defb 066h,0EBh,0E5h,0DDh,06Eh,0E8h,0DDh + defb 066h,0E9h,0E5h,0DDh,04Eh,0FCh,0DDh + defb 046h,0FDh,0DDh,06Eh,0ECh,0DDh,066h + defb 0EDh,0A7h,0EDh,042h + defb 0EBh,0CDh + defw LWRD code_base+00168h + defb 0C5h,0E5h,0DDh,04Eh,0F6h,0DDh,046h + defb 0F7h,0DDh,06Eh,0F4h,0DDh,066h,0F5h + defb 0CDh + defw LWRD ?F_DIV_L04 + defb 0CDh + defw LWRD ?F_CMP_L04 + defb 0DAh + defw LWRD code_base+00B23h + defb 021h,008h,000h,039h,0E5h,0DDh,05Eh + defb 0EEh,0DDh,056h,0EFh,0CDh + defw LWRD code_base+00168h + defb 0EBh,0E1h,0CDh + defw LWRD ?F_MULASG_L04 + defb 0DDh,0CBh,0E2h,046h,0CAh + defw LWRD code_base+001F9h + defb 0AFh,028h,04Dh,0DDh,0CBh,0E2h,05Eh + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,04Eh + defb 059h,023h,046h,050h,013h,013h,072h + defb 02Bh,073h,069h,060h,07Eh,023h,066h + defb 06Fh,0E5h,028h,018h,0AFh,0DDh,0B6h + defb 0E4h,0DDh,04Eh,0EAh,0DDh,046h,0EBh + defb 028h,058h,0DDh,06Eh,0E8h,0DDh,066h + defb 0E9h,079h,0B0h,028h + defb 04Bh,018h,045h,0AFh,0DDh,0B6h,0E4h + defb 0DDh,04Eh,0EAh,0DDh,046h,0EBh,028h + defb 040h,0DDh,06Eh,0E8h,0DDh,066h,0E9h + defb 079h,0B0h,028h,033h,018h,02Dh,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,04Eh,059h + defb 023h,046h,050h,013h,013h,072h,02Bh + defb 073h,069h,060h,07Eh,023h,066h,06Fh + defb 0E5h,0AFh,0DDh,0B6h + defb 0E4h,0DDh,04Eh,0EAh,0DDh,046h,0EBh + defb 028h,011h,0DDh,06Eh,0E8h,0DDh,066h + defb 0E9h,079h,0B0h,028h,004h,078h,0EEh + defb 080h,047h,0EBh,018h,006h,0DDh,05Eh + defb 0E8h,0DDh,056h,0E9h,0E1h,073h,023h + defb 072h,023h,071h,023h,070h,0DDh,034h + defb 0F0h,020h,003h,0DDh,034h,0F1h,0C3h + defw LWRD code_base+001F9h + defb 0DDh,036h,0ECh,008h,0C3h + defw LWRD code_base+007C1h + defb 0DDh,036h,0ECh,010h,018h,004h,0DDh + defb 036h,0ECh,00Ah,0DDh,036h,0EDh,000h + defb 021h,006h,000h,039h,0E5h,0CDh + defw LWRD code_base+00B5Ah + defb 0E1h,0DDh,077h,0E3h,0FEh,030h,020h + defb 072h,0DDh,07Eh,0E6h,0DDh,0B6h,0E7h + defb 028h,06Ah,0FDh,06Eh,000h,0FDh,066h + defb 001h,023h,04Eh,006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,046h,0FDh,06Eh,000h,0FDh + defb 066h,001h,023h,028h,006h,046h,0CBh + defb 0E8h,078h,018h,001h,07Eh,0FEh,078h + defb 020h,034h,0DDh,04Eh,0E6h,0DDh,046h + defb 0E7h,021h,001h,000h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,026h,0FDh,0E5h,0E1h,07Eh,0C6h + defb 002h,077h,023h,07Eh,0CEh,000h,077h + defb 02Bh,06Eh,067h,046h,0DDh,070h,0E3h + defb 021h,006h,000h,039h,07Eh,0D6h,002h + defb 077h,023h,07Eh,0DEh,000h,077h,0DDh + defb 036h,0ECh,010h,018h,00Eh,03Eh,00Ah + defb 0DDh,0AEh,0ECh,0DDh,0B6h,0EDh,020h + defb 02Fh,0DDh,036h,0ECh + defb 008h,0DDh,036h,0EDh,000h,018h,025h + defb 0DDh,036h,0ECh,010h,0DDh,036h,0EDh + defb 000h,0AFh,028h,00Eh,0DDh,0CBh,0E2h + defb 0DEh,018h,008h,0DDh,036h,0ECh,00Ah + defb 0DDh,036h,0EDh,000h,021h,006h,000h + defb 039h,0E5h,0CDh + defw LWRD code_base+00B5Ah + defb 0E1h,0DDh,077h,0E3h,0DDh,07Eh,0E6h + defb 0DDh,0B6h,0E7h,028h,00Dh,0DDh,04Eh + defb 0ECh,0DDh,05Eh,0E3h,0CDh + defw LWRD code_base+00099h + defb 0FEh,064h,020h,003h,0C3h + defw LWRD code_base+00B23h + defb 0AFh,0DDh,077h,0F8h,0DDh,077h,0F9h + defb 0DDh,077h,0FAh,0DDh,077h,0FBh,0DDh + defb 04Eh,0ECh,0FDh,06Eh,000h,0FDh,066h + defb 001h,05Eh,0CDh + defw LWRD code_base+00099h + defb 04Fh,0DDh,071h,0EEh,0DDh,036h,0EFh + defb 000h,03Eh,064h,0A9h,028h,05Ah,0DDh + defb 06Eh,0E6h,0DDh,066h,0E7h,02Bh,0DDh + defb 075h,0E6h,0DDh,074h,0E7h,023h,07Dh + defb 0B4h,028h,048h,0DDh,06Eh,0ECh,0DDh + defb 066h,0EDh,07Ch,007h,09Fh,04Fh,041h + defb 0C5h,0E5h,0DDh,04Eh,0FAh,0DDh,046h + defb 0FBh,0DDh,06Eh,0F8h + defb 0DDh,066h,0F9h,0CDh + defw LWRD ?L_MUL_L03 + defb 0C5h,0E5h,0DDh,06Eh,0EEh,0DDh,066h + defb 0EFh,07Ch,007h,09Fh,05Fh,053h,0C1h + defb 009h,0EBh,0C1h,0EDh,04Ah,04Dh,044h + defb 0EBh,0DDh,075h,0F8h,0DDh,074h,0F9h + defb 0DDh,071h,0FAh,0DDh,070h,0FBh,0FDh + defb 0E5h,0E1h,034h,023h,020h,08Fh,034h + defb 018h,08Ch,0DDh,0CBh,0E2h,046h,0CAh + defw LWRD code_base+001F9h + defb 0DDh,0B6h,0E4h,028h,007h,021h,018h + defb 000h,039h,0CDh + defw LWRD ?L_NEGASG_L03 + defb 0DDh,0CBh,0E2h,05Eh,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,04Eh,059h,023h,046h + defb 050h,013h,013h,072h,02Bh,073h,069h + defb 060h,07Eh,023h,066h,06Fh,028h,012h + defb 0DDh,04Eh,0FAh,0DDh,046h,0FBh,0DDh + defb 05Eh,0F8h,073h,0DDh,056h,0F9h,023h + defb 072h,023h,018h,006h,0DDh,04Eh,0F8h + defb 0DDh,046h,0F9h,071h + defb 023h,070h,0DDh,034h,0F0h,020h,003h + defb 0DDh,034h,0F1h,0C3h + defw LWRD code_base+001F9h + defb 0DDh,0CBh,0E2h,046h,028h,019h,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,04Eh,059h + defb 023h,046h,050h,013h,013h,072h,02Bh + defb 073h,00Ah,0DDh,077h,0F2h,003h,00Ah + defb 0DDh,077h,0F3h,0DDh,06Eh,004h,0DDh + defb 066h,005h,07Eh,023h,066h,06Fh,046h + defb 0DDh,070h,0E3h,078h,0FEh,05Eh,020h + defb 017h,0DDh,036h,0E4h + defb 000h,0DDh,06Eh,004h,0DDh,066h,005h + defb 04Eh,023h,046h,003h,070h,02Bh,071h + defb 00Ah,0DDh,077h,0E3h,018h,004h,0DDh + defb 036h,0E4h,001h,0AFh,0DDh,0B6h,0E3h + defb 0CAh + defw LWRD code_base+00ACAh + defb 0DDh,0CBh,0E2h,0CEh,0DDh,06Eh,0E6h + defb 0DDh,066h,0E7h,02Bh,0DDh,075h,0E6h + defb 0DDh,074h,0E7h,023h,07Dh,0B4h,028h + defb 063h,0FDh,06Eh,000h,0FDh,066h,001h + defb 0AFh,0B6h,028h,059h,0DDh,06Eh,004h + defb 0DDh,066h,005h,04Eh,023h,046h,0C5h + defb 0DDh,04Eh,0E4h,0FDh,06Eh,000h,0FDh + defb 066h,001h,05Eh,0CDh + defw LWRD code_base+0012Eh + defb 0E1h,0B7h,028h,03Eh,0DDh,0CBh,0E2h + defb 04Eh,028h,012h,0DDh,0CBh,0E2h,046h + defb 028h,008h,0DDh,034h,0F0h,020h,003h + defb 0DDh,034h,0F1h,0DDh,0CBh,0E2h,08Eh + defb 0DDh,0CBh,0E2h,046h,028h,016h,0FDh + defb 06Eh,000h,0FDh,066h,001h,046h,0DDh + defb 06Eh,0F2h,0DDh,066h,0F3h,023h,0DDh + defb 075h,0F2h,0DDh,074h + defb 0F3h,02Bh,070h,0FDh,0E5h,0E1h,034h + defb 023h,020h,08Eh,034h,018h,08Bh,0DDh + defb 0CBh,0E2h,04Eh,020h,011h,0DDh,0CBh + defb 0E2h,046h,028h,00Bh,0DDh,06Eh,0F2h + defb 0DDh,066h,0F3h,077h,0DDh,0CBh,0E2h + defb 0CEh,0DDh,0CBh,0E2h,086h,0DDh,06Eh + defb 004h,0DDh,066h,005h,04Eh,023h,046h + defb 003h,070h,02Bh,071h + defb 00Ah,0B7h,028h,00Fh,0FEh,05Dh,020h + defb 0EBh,0DDh,06Eh,004h,0DDh,066h,005h + defb 034h,023h,020h,001h,034h,0C3h + defw LWRD code_base+00ACAh + defb 0DDh,0CBh,0E2h,046h,028h,019h,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,04Eh,059h + defb 023h,046h,050h,013h,013h,072h,02Bh + defb 073h,00Ah,0DDh,077h,0F2h,003h,00Ah + defb 0DDh,077h,0F3h,03Eh,002h,0DDh,0AEh + defb 0E7h,0DDh,0B6h,0E6h,020h,007h,0DDh + defb 036h,0E6h,001h,0DDh,077h,0E7h,0DDh + defb 06Eh,0E6h,0DDh,066h + defb 0E7h,02Bh,0DDh,075h,0E6h,0DDh,074h + defb 0E7h,023h,07Dh,0B4h,028h,030h,0FDh + defb 06Eh,000h,0FDh,066h,001h,0AFh,0B6h + defb 028h,026h,0DDh,0CBh,0E2h,046h,028h + defb 016h,0FDh,06Eh,000h,0FDh,066h,001h + defb 046h,0DDh,06Eh,0F2h,0DDh,066h,0F3h + defb 023h,0DDh,075h,0F2h,0DDh,074h,0F3h + defb 02Bh,070h,0FDh,0E5h + defb 0E1h,034h,023h,020h,0C1h,034h,018h + defb 0BEh,0DDh,07Eh,0E2h,0E6h,001h,04Fh + defb 006h,000h,021h,010h,000h,039h,07Eh + defb 081h,077h,023h,07Eh,088h,077h,0C3h + defw LWRD code_base+001F9h + defb 0DDh,0CBh,0E2h,046h,028h,019h,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,04Eh,059h + defb 023h,046h,050h,013h,013h,072h,02Bh + defb 073h,00Ah,0DDh,077h,0F2h,003h,00Ah + defb 0DDh,077h,0F3h,0FDh,0E5h,0D1h,0CDh + defw LWRD code_base+00069h + defb 0DDh,06Eh,0E6h,0DDh,066h,0E7h,02Bh + defb 0DDh,075h,0E6h,0DDh,074h,0E7h,023h + defb 07Dh,0B4h,028h,041h,0FDh,06Eh,000h + defb 0FDh,066h,001h,0AFh,0B6h,028h,037h + defb 0FDh,06Eh,000h,0FDh,066h,001h,04Eh + defb 006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,05Eh,020h,026h,0DDh,0CBh + defb 0E2h,046h,028h,016h,0FDh,06Eh,000h + defb 0FDh,066h,001h,046h,0DDh,06Eh,0F2h + defb 0DDh,066h,0F3h,023h,0DDh,075h,0F2h + defb 0DDh,074h,0F3h,02Bh,070h,0FDh,0E5h + defb 0E1h,034h,023h,020h,0B0h,034h,018h + defb 0ADh,0DDh,0CBh,0E2h,046h,028h,010h + defb 0DDh,034h,0F0h,020h + defb 003h,0DDh,034h,0F1h,0DDh,06Eh,0F2h + defb 0DDh,066h,0F3h,036h,000h,0C3h + defw LWRD code_base+001F9h + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,04Eh + defb 059h,023h,046h,050h,013h,013h,072h + defb 02Bh,073h,069h,060h,07Eh,023h,066h + defb 06Fh,0E5h,0DDh,04Eh,0FEh,0DDh,046h + defb 0FFh,0FDh,06Eh,000h,0FDh,066h,001h + defb 0A7h,0EDh,042h,04Dh,044h,0E1h,071h + defb 023h,070h,0C3h + defw LWRD code_base+001F9h + defb 0FDh,0E5h,0E1h,04Eh,023h,046h,003h + defb 070h,02Bh,071h,00Bh,00Ah,0FEh,025h + defb 0CAh + defw LWRD code_base+001F9h + defb 0FDh,06Eh,000h,0FDh,066h,001h,0AFh + defb 0B6h,020h,022h,0DDh,06Eh,004h,0DDh + defb 066h,005h,07Eh,023h,066h,06Fh,04Eh + defb 006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,05Eh,028h,00Dh,0DDh,06Eh + defb 004h,0DDh,066h,005h,034h,023h,020h + defb 0E1h,034h,018h,0DEh,0DDh,06Eh,0F0h + defb 0DDh,066h,0F1h,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + defb 02Bh,02Bh,04Dh,044h,0FDh,0E5h,0D1h + defb 0C3h + defw LWRD code_base+000D7h + defb 021h,0D0h,0FFh,009h,07Ch,007h,09Fh + defb 04Fh,041h,0C3h + defw LWRD ?SL_TO_F_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/formattedwrite.asm b/src/libiar/formattedwrite.asm new file mode 100755 index 00000000..08a638a9 --- /dev/null +++ b/src/libiar/formattedwrite.asm @@ -0,0 +1,612 @@ +; formattedwrite.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module _formatted_write + rseg CODE +code_base: + rseg CSTR +cstr_base: + public _formatted_write +_formatted_write equ cstr_base+00000465h + extern ?CL64180B_4_06_L00 + extern ?SS_MOD_L02 + extern ?SS_CMP_L02 + extern ?SS_DIVASG_L02 + extern ?UL_MOD_L03 + extern ?SL_CMP_L03 + extern ?UL_DIVASG_L03 + extern ?L_NEGASG_L03 + extern ?F_TO_L_L04 + extern ?SL_TO_F_L04 + extern ?F_NEGASG_L04 + extern ?F_MULASG_L04 + extern ?F_DIVASG_L04 + extern ?F_SUBASG_L04 + extern ?C_V_SWITCH_L06 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?ENT_AUTO_DIRECT_L09 + extern ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0F6h,0FFh,0FDh,0E5h,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,0DDh,075h,0F6h,0DDh + defb 074h,0F7h,0AFh,0DDh,077h,0F8h,0DDh + defb 077h,0F9h,021h,080h,03Fh,0E5h,06Fh + defb 067h,0E5h,0CDh + defw LWRD cstr_base+0045Ch + defb 038h,04Dh,021h,0BAh,051h,0E5h,021h + defb 0B7h,043h,0E5h,0CDh + defw LWRD cstr_base+00456h + defb 038h,01Ah,021h,00Eh,000h,039h,001h + defb 015h,050h,011h,0F9h,002h,0CDh + defw LWRD ?F_DIVASG_L04 + defb 021h,004h,000h,039h,0C6h,00Ah,077h + defb 030h,0DDh,023h,034h,018h,0D9h,021h + defb 020h,041h,0E5h,021h,000h,000h,0E5h + defb 0CDh + defw LWRD cstr_base+00456h + defb 038h,017h,021h,00Eh,000h,039h,001h + defb 020h,041h,011h,000h,000h,0CDh + defw LWRD ?F_DIVASG_L04 + defb 0DDh,034h,0F8h,020h,0E1h,0DDh,034h + defb 0F9h,018h,0DCh,018h,062h,079h,0B0h + defb 028h,05Eh,0DDh,06Eh,004h,0DDh,066h + defb 005h,0E5h,0DDh,06Eh,002h,0DDh,066h + defb 003h,0E5h,001h,0DBh,02Eh,021h,0FFh + defb 0E6h,0CDh + defw LWRD ?SL_CMP_L03 + defb 038h,01Ch,021h,00Eh,000h,039h,001h + defb 015h,050h,011h,0F9h,002h,0CDh + defw LWRD ?F_MULASG_L04 + defb 021h,004h,000h,039h,07Eh,0D6h,00Ah + defb 077h,023h,07Eh,0DEh,000h,077h,018h + defb 0CBh,021h,080h,03Fh,0E5h,021h,000h + defb 000h,0E5h,0CDh + defw LWRD cstr_base+00456h + defb 030h,01Ch,021h,00Eh,000h,039h,001h + defb 020h,041h,011h,000h,000h,0CDh + defw LWRD ?F_MULASG_L04 + defb 0DDh,06Eh,0F8h,0DDh,066h,0F9h,02Bh + defb 0DDh,075h,0F8h,0DDh,074h,0F9h,018h + defb 0D7h,0AFh,0DDh,0B6h,00Eh,028h,04Ch + defb 0DDh,04Eh,008h,0DDh,046h,009h,0DDh + defb 06Eh,0F8h,0DDh,066h,0F9h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,01Eh,001h,0FCh,07Fh,03Eh,080h + defb 0ACh,067h,0EDh,042h,038h,013h,021h + defb 014h,000h,039h,07Eh,0DDh,096h,0F8h + defb 077h,023h,07Eh,0DDh,09Eh,0F9h,077h + defb 0DDh,036h,00Ch,000h,0DDh,06Eh,008h + defb 0DDh,066h,009h,02Bh,0DDh,075h,008h + defb 0DDh,074h,009h,0AFh,0DDh,0B6h,010h + defb 028h,006h,0DDh,036h + defb 00Eh,000h,018h,004h,0DDh,036h,010h + defb 001h,0AFh,0DDh,0B6h,00Ch,028h,00Ah + defb 0AFh,0DDh,077h,0FEh,0DDh,077h,0FFh + defb 0C3h + defw LWRD cstr_base+001E4h + defb 0DDh,0CBh,0F9h,07Eh,0CAh + defw LWRD cstr_base+001D4h + defb 0DDh,06Eh,0F6h,0DDh,066h,0F7h,023h + defb 0DDh,075h,0F6h,0DDh,074h,0F7h,02Bh + defb 036h,030h,0DDh,06Eh,008h,0DDh,066h + defb 009h,0DDh,075h,0FAh,0DDh,074h,0FBh + defb 07Dh,0B4h,020h,005h,0DDh,0B6h,010h + defb 028h,010h,0DDh,06Eh,0F6h,0DDh,066h + defb 0F7h,023h,0DDh,075h,0F6h,0DDh,074h + defb 0F7h,02Bh,036h,02Eh + defb 0AFh,0DDh,077h,0FCh,0DDh,077h,0FDh + defb 0DDh,04Eh,0FCh,0DDh,046h,0FDh,00Bh + defb 0DDh,071h,0FCh,0DDh,070h,0FDh,0DDh + defb 06Eh,0F8h,0DDh,066h,0F9h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,027h,0DDh,07Eh,008h,0DDh,0B6h + defb 009h,028h,01Fh,0DDh,06Eh,0F6h,0DDh + defb 066h,0F7h,023h,0DDh,075h,0F6h,0DDh + defb 074h,0F7h,02Bh,036h,030h,0DDh,06Eh + defb 008h,0DDh,066h,009h,02Bh,0DDh,075h + defb 008h,0DDh,074h,009h,018h,0C1h,0DDh + defb 07Eh,0FAh,0DDh,046h,0FBh,02Fh,04Fh + defb 078h,02Fh,047h,0CDh + defw LWRD ?SS_CMP_L02 + defb 0DAh + defw LWRD cstr_base+00345h + defb 0DDh,036h,0FEh,001h,0DDh,036h,0FFh + defb 000h,018h,010h,0DDh,04Eh,0F8h,0DDh + defb 046h,0F9h,06Fh,067h,0EDh,042h,0DDh + defb 075h,0FEh,0DDh,074h,0FFh,0DDh,06Eh + defb 0FEh,0DDh,066h,0FFh,0DDh,075h,0FCh + defb 0DDh,074h,0FDh,0DDh,04Eh,0FCh,0DDh + defb 046h,0FDh,0DDh,06Eh,008h,0DDh,066h + defb 009h,0CDh + defw LWRD ?SS_CMP_L02 + defb 038h,077h,021h,00Eh,000h,039h,0E5h + defb 0DDh,04Eh,004h,0DDh,046h,005h,0DDh + defb 06Eh,002h,0DDh,066h,003h,0CDh + defw LWRD ?F_TO_L_L04 + defb 0DDh,075h,0FAh,07Ch,007h,09Fh,04Fh + defb 041h,0CDh + defw LWRD ?SL_TO_F_L04 + defb 0EBh,0E1h,0CDh + defw LWRD ?F_SUBASG_L04 + defb 021h,00Eh,000h,039h,001h,020h,041h + defb 011h,000h,000h,0CDh + defw LWRD ?F_MULASG_L04 + defb 0DDh,06Eh,0F6h,0DDh,066h,0F7h,023h + defb 0DDh,075h,0F6h,0DDh,074h,0F7h,02Bh + defb 0DDh,07Eh,0FAh,0C6h,030h,077h,0DDh + defb 06Eh,0FCh,0DDh,066h,0FDh,023h,0DDh + defb 075h,0FCh,0DDh,074h,0FDh,02Bh,07Dh + defb 0B4h,020h,098h,0DDh,07Eh,008h,0DDh + defb 0B6h,009h,020h,005h,0DDh,0B6h,010h + defb 028h,08Bh,0DDh,06Eh + defb 0F6h,0DDh,066h,0F7h,023h,0DDh,075h + defb 0F6h,0DDh,074h,0F7h,02Bh,036h,02Eh + defb 0C3h + defw LWRD cstr_base+001F0h + defb 021h,0A0h,040h,0E5h,021h,000h,000h + defb 0E5h,0CDh + defw LWRD cstr_base+00456h + defb 0DAh + defw LWRD cstr_base+00345h + defb 0DDh,06Eh,0F6h,0DDh,066h,0F7h,02Bh + defb 0E5h,0FDh,0E1h,0DDh,036h,0FAh,001h + defb 0DDh,036h,0FBh,000h,0FDh,07Eh,000h + defb 0FEh,02Eh,028h,022h,0FDh,07Eh,000h + defb 0DDh,086h,0FAh,0FDh,077h,000h,0FEh + defb 03Ah,020h,00Eh,0FDh,036h,000h,030h + defb 0DDh,036h,0FAh,001h,0DDh,036h,0FBh + defb 000h,018h,007h,0AFh + defb 0DDh,077h,0FAh,0DDh,077h,0FBh,0FDh + defb 0E5h,0C1h,0DDh,06Eh,00Ah,0DDh,066h + defb 00Bh,0A7h,0EDh,042h,0FDh,02Bh,038h + defb 0C7h,0DDh,07Eh,0FAh,0DDh,0B6h,0FBh + defb 028h,06Ch,0AFh,0DDh,0B6h,00Ch,0DDh + defb 06Eh,0F6h,0DDh,066h,0F7h,028h,036h + defb 0E5h,0FDh,0E1h,0FDh,0E5h,0C1h,0DDh + defb 06Eh,00Ah,0DDh,066h + defb 00Bh,0A7h,0EDh,042h,030h,01Bh,0FDh + defb 07Eh,0FFh,0FEh,02Eh,020h,00Ah,0FDh + defb 046h,0FEh,0FDh,070h,000h,0FDh,02Bh + defb 018h,006h,0FDh,046h,0FFh,0FDh,070h + defb 000h,0FDh,02Bh,018h,0D7h,0DDh,034h + defb 0F8h,020h,027h,0DDh,034h,0F9h,018h + defb 022h,023h,0DDh,075h,0F6h,0DDh,074h + defb 0F7h,0E5h,0FDh,0E1h + defb 0FDh,0E5h,0C1h,0DDh,06Eh,00Ah,0DDh + defb 066h,00Bh,0A7h,0EDh,042h,030h,00Ah + defb 0FDh,046h,0FFh,0FDh,070h,000h,0FDh + defb 02Bh,018h,0E8h,0DDh,06Eh,00Ah,0DDh + defb 066h,00Bh,036h,031h,0AFh,0DDh,0B6h + defb 00Eh,028h,01Fh,0DDh,06Eh,0F6h,0DDh + defb 066h,0F7h,02Bh,07Eh,0FEh,030h,020h + defb 008h,0DDh,075h,0F6h + defb 0DDh,074h,0F7h,018h,0ECh,07Eh,0FEh + defb 02Eh,020h,006h,0DDh,075h,0F6h,0DDh + defb 074h,0F7h,0AFh,0DDh,0B6h,00Ch,0CAh + defw LWRD cstr_base+0044Bh + defb 0DDh,06Eh,0F6h,0DDh,066h,0F7h,077h + defb 0DDh,0CBh,0F9h,07Eh,023h,023h,0DDh + defb 075h,0F6h,0DDh,074h,0F7h,02Bh,028h + defb 015h,036h,02Dh,021h,000h,000h,0DDh + defb 04Eh,0F8h,0DDh,046h,0F9h,0EDh,042h + defb 0DDh,075h,0F8h,0DDh,074h,0F9h,018h + defb 002h,036h,02Bh,021h,002h,000h,039h + defb 07Eh,0C6h,00Ah,077h + defb 023h,07Eh,0CEh,000h,077h,0AFh,0DDh + defb 077h,0FAh,0DDh,077h,0FBh,0DDh,034h + defb 0FAh,020h,003h,0DDh,034h,0FBh,0DDh + defb 06Eh,0F6h,0DDh,066h,0F7h,023h,0DDh + defb 075h,0F6h,0DDh,074h,0F7h,02Bh,001h + defb 00Ah,000h,0DDh,05Eh,0F8h,0DDh,056h + defb 0F9h,0CDh + defw LWRD ?SS_MOD_L02 + defb 07Bh,0C6h,030h,077h,021h,004h,000h + defb 039h,0CDh + defw LWRD ?SS_DIVASG_L02 + defb 07Bh,0B2h,020h,0CFh,001h,002h,080h + defb 0DDh,06Eh,0FAh,0DDh,066h,0FBh,078h + defb 0ACh,067h,0EDh,042h,038h,0BFh,0DDh + defb 06Eh,0FAh,0DDh,066h,0FBh,0DDh,075h + defb 0FCh,0DDh,074h,0FDh,0DDh,04Eh,0FAh + defb 0DDh,046h,0FBh,021h,000h,000h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,032h,0DDh,04Eh,0FCh,0DDh,046h + defb 0FDh,0DDh,06Eh,0FAh,0DDh,066h,0FBh + defb 0A7h,0EDh,042h,001h,0F5h,0FFh,009h + defb 0DDh,04Eh,0F6h,0DDh,046h,0F7h,009h + defb 0E5h,0DDh,05Eh,0FAh,0DDh,056h,0FBh + defb 069h,060h,0A7h,0EDh,052h,046h,0E1h + defb 070h,01Bh,0DDh,073h,0FAh,0DDh,072h + defb 0FBh,018h,0C0h,023h + defb 023h,039h,07Eh,0D6h,00Ah,077h,023h + defb 07Eh,0DEh,000h,077h,0DDh,06Eh,0F6h + defb 0DDh,066h,0F7h,0FDh,0E1h,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0DDh,04Eh,004h,0DDh,046h,005h,0DDh + defb 06Eh,002h,0DDh,066h,003h,0C3h + defw LWRD ?SL_CMP_L03 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 058h,0FFh,0FDh,0E5h,0DDh,06Eh,002h + defb 0DDh,066h,003h,0E5h,0FDh,0E1h,021h + defb 006h,000h,039h,0AFh,077h,023h,077h + defb 0FDh,046h,000h,021h,01Ch,000h,039h + defb 070h,078h,0FEh,025h,0FDh,023h,028h + defb 022h,0AFh,0B0h,020h,00Dh,021h,006h + defb 000h,039h,046h,023h,066h,068h,0FDh + defb 0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + defb 0DDh,04Eh,00Eh,0DDh,046h,00Fh,05Fh + defb 0CDh + defw LWRD cstr_base+00C65h + defb 039h,034h,023h,020h,0D1h,018h,019h + defb 0FDh,07Eh,000h,0FEh,025h,020h,015h + defb 0DDh,04Eh,00Eh,0DDh,046h,00Fh,01Eh + defb 025h,0CDh + defw LWRD cstr_base+00C65h + defb 039h,034h,023h,0FDh,023h,020h,0B6h + defb 034h,018h,0B3h,021h,002h,000h,039h + defb 0E5h,021h,026h,000h,039h,04Dh,044h + defb 0E1h,071h,023h,070h,021h,00Eh,000h + defb 039h,071h,023h,070h,021h,01Ah,000h + defb 039h,036h + t_push_rel (0001) 00000000 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0000 + defb 021h,021h,000h,039h,036h,000h,023h + defb 036h,000h,02Bh,02Bh,02Bh,036h,000h + defb 02Bh,02Bh,036h,000h,0FDh,05Eh,000h + defb 0CDh + defw LWRD ?C_V_SWITCH_L06 + defb 005h,000h,020h,023h,02Bh,02Dh,030h + defw LWRD cstr_base+0053Dh + defw LWRD cstr_base+00534h + defw LWRD cstr_base+00526h + defw LWRD cstr_base+0051Ch + defw LWRD cstr_base+0052Dh + defw LWRD cstr_base+00514h + defb 021h,01Dh,000h,039h,0AFh,0B6h,020h + defb 01Dh,0FDh,046h,000h,021h,01Dh,000h + defb 039h,070h,018h,013h,021h,01Fh,000h + defb 039h,034h,018h,00Ch,021h,022h,000h + defb 039h,034h,018h,005h,021h,021h,000h + defb 039h,034h,0FDh,023h,018h,0BEh,0FDh + defb 07Eh,000h,0FEh,02Ah,021h,010h,000h + defb 039h,020h,033h,0E5h + defb 0DDh,06Eh,010h,0DDh,066h,011h,04Eh + defb 059h,023h,046h,050h,013h,013h,072h + defb 02Bh,073h,069h,060h,04Eh,023h,046h + defb 0E1h,071h,023h,070h,0CBh,078h,028h + defb 011h,021h,010h,000h,039h,0AFh,091h + defb 077h,023h,03Eh,000h,09Eh,077h,021h + defb 01Fh,000h,039h,034h,0FDh,023h,018h + defb 03Dh,0AFh,077h,023h + defb 077h,0FDh,07Eh,000h,0FEh,030h,038h + defb 032h,03Eh,039h,0FDh,0BEh,000h,038h + defb 02Bh,021h,010h,000h,039h,0E5h,0FDh + defb 04Eh,000h,006h,000h,021h,0D0h,0FFh + defb 009h,0E5h,021h,014h,000h,039h,046h + defb 023h,066h,068h,029h,04Dh,044h,029h + defb 029h,009h,04Dh,044h,0E1h,009h,04Dh + defb 044h,0E1h,071h,023h + defb 070h,0FDh,023h,018h,0C7h,021h,01Fh + defb 000h,039h,0AFh,0B6h,028h,004h,023h + defb 023h,036h,000h,0FDh,07Eh,000h,0FEh + defb 02Eh,020h,068h,0FDh,07Eh,001h,0FEh + defb 02Ah,021h,004h,000h,039h,0FDh,023h + defb 020h,01Eh,0E5h,0DDh,06Eh,010h,0DDh + defb 066h,011h,04Eh,059h,023h,046h,050h + defb 013h,013h,072h,02Bh + defb 073h,069h,060h,04Eh,023h,046h,0E1h + defb 071h,023h,070h,0FDh,023h,018h,046h + defb 0AFh,077h,023h,077h,0FDh,07Eh,000h + defb 0FEh,030h,038h,03Bh,03Eh,039h,0FDh + defb 0BEh,000h,038h,034h,021h,004h,000h + defb 039h,0E5h,0FDh,04Eh,000h,006h,000h + defb 021h + defb 0D0h,0FFh,009h,0E5h,021h,008h,000h + defb 039h,046h,023h,066h,068h,029h,04Dh + defb 044h,029h,029h,009h,04Dh,044h,0E1h + defb 009h,04Dh,044h,0E1h,071h,023h,070h + defb 0FDh,023h,018h,0C7h,021h,004h,000h + defb 039h,036h,0FFh,023h,036h,0FFh,021h + defb 020h,000h,039h,036h,000h,02Bh,02Bh + defb 036h,000h,0FDh,07Eh + 00FE4C2804FE6C2003341807FE682005232334FD23FD4600211C00397058FD23CD + defw LWRD ?C_V_SWITCH_L06 + defb 010h,000h,000h,045h,047h,058h,063h + defb 064h,065h,066h,067h,069h,06Eh,06Fh + defb 070h,073h,075h,078h + defw LWRD cstr_base+00B58h + defw LWRD cstr_base+007D9h + defw LWRD cstr_base+007E2h + defw LWRD cstr_base+00728h + defw LWRD cstr_base+007E2h + defw LWRD cstr_base+007C2h + defw LWRD cstr_base+0069Fh + defw LWRD cstr_base+00869h + defw LWRD cstr_base+00A35h + defw LWRD cstr_base+00A4Fh + defw LWRD cstr_base+00A51h + defw LWRD cstr_base+00869h + defw LWRD cstr_base+00706h + defw LWRD cstr_base+007E2h + defw LWRD cstr_base+00A35h + defw LWRD cstr_base+00A51h + defw LWRD cstr_base+00B56h + defb 0AFh,020h,03Fh,028h,00Eh,021h,020h + defb 000h,039h,0B6h,020h,036h,02Bh,02Bh + defb 0B6h,028h,031h,018h,005h,023h,023h + defb 0B6h,028h,02Ah,0DDh,06Eh,010h,0DDh + defb 066h,011h,04Eh,059h,023h,046h,050h + defb 013h,013h,072h,02Bh,073h,069h,060h + defb 07Eh,023h,066h,06Fh,0E5h,021h,008h + defb 000h,039h,05Eh,023h + defb 056h,07Ah,007h,09Fh,04Fh,041h,0E1h + defb 073h,023h,072h,023h,018h,01Fh,0DDh + defb 06Eh,010h,0DDh,066h,011h,04Eh,059h + defb 023h,046h,050h,013h,013h,072h,02Bh + defb 073h,069h,060h,07Eh,023h,066h,06Fh + defb 0E5h,021h,008h,000h,039h,04Eh,023h + defb 046h,0E1h,071h,023h,070h,0C3h + defw LWRD cstr_base+0047Dh + defb 0DDh,06Eh,010h,0DDh,066h,011h,04Eh + defb 059h,023h,046h,050h,013h,013h,072h + defb 02Bh,073h,00Ah,021h,024h,000h,039h + defb 077h,021h,00Eh,000h,039h,034h,023h + defb 020h,001h,034h,0C3h + defw LWRD cstr_base+00B74h + defb 021h,002h,000h,039h,0E5h,0DDh,06Eh + defb 010h,0DDh,066h,011h,04Eh,059h,023h + defb 046h,050h,013h,013h,072h,02Bh,073h + defb 069h,060h,04Eh,023h,046h,0E1h,071h + defb 023h,070h,079h,0B0h,020h,009h,021h + defb 002h,000h,039h,036h + t_push_rel (0001) 00000011 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0011 + defb 021h,004h,000h,039h,023h,0CBh,07Eh + defb 028h,006h,02Bh,036h,010h,023h,036h + defb 027h,021h,00Ch,000h,039h,0AFh,077h + defb 023h,077h,021h,002h,000h,039h,04Eh + defb 023h,046h,003h,070h,02Bh,071h,00Bh + defb 00Ah,0B7h,028h,01Dh,023h,023h,04Eh + defb 023h,046h,021h,00Ch,000h,039h,056h + defb 023h,066h,06Ah,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,00Bh,021h,00Ch,000h,039h,034h + defb 023h,020h,0D6h,034h,018h,0D3h,021h + defb 00Eh,000h,039h,0E5h,021h,004h,000h + defb 039h,04Eh,023h,046h,00Bh,070h,02Bh + defb 071h,0E1h,071h,023h,070h,021h,002h + defb 000h,039h,0E5h,021h,00Eh,000h,039h + defb 04Eh,023h,046h,0E1h,07Eh,091h,077h + defb 023h,07Eh,098h,077h + defb 0C3h + defw LWRD cstr_base+00B74h + defb 021h,022h,000h,039h,0AFh,0B6h,028h + defb 00Fh,021h,004h,000h,039h,07Eh,023h + defb 0B6h,020h,006h,02Bh,034h,023h,020h + defb 001h,034h,021h,01Ah,000h,039h,036h + t_push_rel (0001) 00000020 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0020 + defb 078h,0FEh,070h,028h,003h,0AFh,028h + defb 00Fh,0DDh,06Eh,010h,0DDh,066h,011h + defb 04Eh,059h,023h,046h,050h,013h,013h + defb 018h,025h,021h,01Eh,000h,039h,0B6h + defb 0DDh,06Eh,010h,0DDh,066h,011h,04Eh + defb 059h,023h,046h,050h,013h,013h,028h + defb 011h,013h,013h,072h,02Bh,073h,069h + defb 060h,05Eh,023h,056h + defb 023h,04Eh,023h,046h,0EBh,018h,00Bh + defb 072h,02Bh,073h,00Ah,06Fh,003h,00Ah + defb 067h,001h,000h,000h,0E5h,021h,00Ah + defb 000h,039h,0D1h,073h,023h,072h,023h + defb 071h,023h,070h,021h,01Ch,000h,039h + defb 07Eh,0FEh,06Fh,020h,008h,001h,000h + defb 000h,021h,008h,000h,018h,00Eh,0FEh + defb 075h,020h,004h,02Eh + defb 00Ah,018h,002h,02Eh,010h,001h,000h + defb 000h,061h,0E5h,02Eh,018h,039h,0D1h + defb 073h,023h,072h,023h,071h,023h,070h + defb 021h,01Dh,000h,039h,070h,0C3h + defw LWRD cstr_base+008F4h + defb 0AFh,028h,02Fh,0DDh,06Eh,010h,0DDh + defb 066h,011h,04Eh,059h,023h,046h,050h + defb 013h,013h,013h,013h,072h,02Bh,073h + defb 069h,060h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0E5h,021h,00Ah,000h + defb 039h,0D1h,073h,023h,072h,023h,071h + defb 023h,070h,0CBh,078h,028h,04Eh,018h + defb 040h,023h,023h,0B6h + defb 0DDh,06Eh,010h,0DDh,066h,011h,04Eh + defb 059h,023h,046h,050h,013h,013h,028h + defb 011h,013h,013h,072h,02Bh,073h,069h + defb 060h,05Eh,023h,056h,023h,04Eh,023h + defb 046h,0EBh,018h,00Ch,072h,02Bh,073h + defb 00Ah,06Fh,003h,00Ah,067h,007h,09Fh + defb 04Fh,041h,0E5h,021h,00Ah,000h,039h + defb 0D1h,073h,023h,072h + defb 023h,071h,023h,070h,0CBh,078h,028h + defb 00Ch,02Bh,02Bh,02Bh,0CDh + defw LWRD ?L_NEGASG_L03 + defb 021h,01Dh,000h,039h,036h,02Dh,021h + defb 016h,000h,039h,0AFh,036h,00Ah,023h + defb 077h,023h,077h,023h,077h,021h,002h + defb 000h,039h,0E5h,021h,026h,000h,039h + defb 001h,085h,000h,009h,04Dh,044h,0E1h + defb 071h,023h,070h,021h,00Eh,000h,039h + defb 071h,023h,070h,021h,008h,000h,039h + defb 07Eh,023h,0B6h,023h + defb 0B6h,023h,0B6h,028h,002h,03Eh,001h + defb 021h,023h,000h,039h,077h,021h,004h + defb 000h,039h,07Eh,023h,0B6h,020h,007h + defb 021h,023h,000h,039h,0B6h,028h,04Eh + defb 021h,016h,000h,039h,04Eh,023h,046h + defb 023h,05Eh,023h,056h,0D5h,0C5h,021h + defb 00Ch,000h,039h,05Eh,023h,056h,023h + defb 04Eh,023h,046h,0EBh + defb 0CDh + defw LWRD ?UL_MOD_L03 + defb 0E5h,021h,01Ch,000h,039h,04Eh,023h + defb 046h,0E1h,009h,046h,021h,002h,000h + defb 039h,05Eh,023h,056h,01Bh,072h,02Bh + defb 073h,0EBh,070h,021h,008h,000h,039h + defb 0E5h,021h,018h,000h,039h,05Eh,023h + defb 056h,023h,04Eh,023h,046h,0E1h,0CDh + defw LWRD ?UL_DIVASG_L03 + defb 07Bh,0B2h,0B1h,0B0h,020h,0B2h,021h + defb 004h,000h,039h,023h,0CBh,07Eh,028h + defb 02Dh,021h,021h,000h,039h,0AFh,0B6h + defb 028h,025h,021h,004h,000h,039h,0E5h + defb 021h,01Fh,000h,039h,0AFh,0B6h,028h + defb 004h,00Eh,001h,018h,001h,04Fh,006h + defb 000h,021h,012h,000h,039h,056h,023h + defb 066h,06Ah,0A7h,0EDh + defb 042h,04Dh,044h,0E1h,071h,023h,070h + defb 021h,002h,000h,039h,04Eh,023h,046h + defb 021h,00Eh,000h,039h,056h,023h,066h + defb 06Ah,0A7h,0EDh,042h,0E5h,021h,006h + defb 000h,039h,04Eh,023h,046h,0E1h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,011h,021h,002h,000h,039h,04Eh + defb 023h,046h,00Bh,070h,02Bh,071h,069h + defb 060h,036h,030h,018h,0CFh,021h,022h + defb 000h,039h,0AFh,0B6h,028h,043h,023h + defb 0AFh,0B6h,028h,03Eh,021h,01Ch,000h + defb 039h,07Eh,0FEh,078h,028h,004h,0FEh + defb 058h,020h,011h,021h,002h,000h,039h + defb 04Eh,023h,046h,00Bh + defb 070h,02Bh,071h,0C5h,047h,0E1h,070h + defb 018h,011h,0FEh,06Fh,020h,01Ch,021h + defb 002h,000h,039h,07Eh,023h,066h,06Fh + defb 07Eh,0FEh,030h,028h,00Fh,021h,002h + defb 000h,039h,04Eh,023h,046h,00Bh,070h + defb 02Bh,071h,069h,060h,036h,030h,0C3h + defw LWRD cstr_base+00B74h + defb 078h,0D6h,002h,077h,021h,00Ch,000h + defb 039h,036h,001h,021h,004h,000h,039h + defb 07Eh,023h,0B6h,020h,00Fh,02Bh,036h + defb 001h,023h,077h,018h,008h,036h,000h + defb 021h,00Ch,000h,039h,0AFh,077h,021h + defb 004h,000h,039h,023h,0CBh,07Eh,028h + defb 006h,02Bh,036h,006h,023h,036h,000h + defb 0AFh,0DDh,06Eh,010h + defb 0DDh,066h,011h,04Eh,059h,023h,046h + defb 050h,013h,013h,013h,013h,072h,02Bh + defb 073h,069h,060h,05Eh,023h,056h,023h + defb 04Eh,023h,046h,0EBh,0E5h,021h,014h + defb 000h,039h,0D1h,073h,023h,072h,023h + defb 071h,023h,070h,028h,006h,0CBh,078h + defb 028h,012h,018h,004h,0CBh,078h,028h + defb 00Ch,02Bh,02Bh,02Bh + defb 0CDh + defw LWRD ?F_NEGASG_L04 + defb 021h,01Dh,000h,039h,036h,02Dh,021h + defb 00Eh,000h,039h,0E5h,021h,024h,000h + defb 039h,04Eh,0C5h,021h,010h,000h,039h + defb 04Eh,0C5h,021h,022h,000h,039h,04Eh + defb 0C5h,021h,00Ah,000h,039h,0E5h,021h + defb 01Ah,000h,039h,04Eh,023h,046h,0E1h + defb 07Eh,081h,077h,023h,07Eh,088h,077h + defb 02Bh,06Eh,067h,0E5h + defb 021h,00Eh,000h,039h,04Eh,023h,046h + defb 0C5h,021h,01Eh,000h,039h,05Eh,023h + defb 056h,023h,04Eh,023h,046h,0CDh + defw LWRD cstr_base+00000h + defb 0F1h,0F1h,0F1h,0F1h,0F1h,04Dh,044h + defb 0E1h,071h,023h,070h,021h,021h,000h + defb 039h,0AFh,0B6h,028h,074h,021h,004h + defb 000h,039h,0E5h,021h,01Fh,000h,039h + defb 0AFh,0B6h,028h,004h,00Eh,001h,018h + defb 001h,04Fh,006h,000h,021h,012h,000h + defb 039h,056h,023h,066h,06Ah,0A7h,0EDh + defb 042h,04Dh,044h,0E1h + defb 071h,023h,070h,021h,002h,000h,039h + defb 04Eh,023h,046h,021h,00Eh,000h,039h + defb 056h,023h,066h,06Ah,0A7h,0EDh,042h + defb 0E5h,021h,006h,000h,039h,04Eh,023h + defb 046h,0E1h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,02Fh,021h,002h,000h,039h,04Eh + defb 023h,046h,00Bh,070h,02Bh,071h,069h + defb 060h,036h,030h,018h,0CFh,0FDh,02Bh + defb 021h,002h,000h,039h,036h + t_push_rel (0001) 00000031 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0031 + defb 021h,00Eh,000h,039h,036h + t_push_rel (0001) 00000031 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0031 + defb 02Bh,07Eh,0C6h,003h,077h,023h,07Eh + defb 0CEh,000h,077h,021h,004h,000h,039h + defb 0E5h,02Bh,02Bh,04Eh,023h,046h,021h + defb 010h,000h,039h,056h,023h,066h,06Ah + defb 0A7h,0EDh,042h,04Dh,044h,0E1h,071h + defb 023h,070h,021h,010h,000h,039h,056h + defb 023h,066h,06Ah,0CDh + defw LWRD ?SS_CMP_L02 + defb 021h,00Ch,000h,030h,007h,039h,0AFh + defb 077h,023h,077h,018h,02Dh,039h,0E5h + defb 021h,01Fh,000h,039h,0AFh,0B6h,028h + defb 004h,00Eh,001h,018h,001h,04Fh,006h + defb 000h,021h,012h,000h,039h,023h,066h + defb 06Ah,0A7h,0EDh,042h,0E5h,021h,008h + defb 000h,039h,04Eh,023h,046h,0E1h,0A7h + defb 0EDh,042h,04Dh,044h + defb 0E1h,071h,023h,070h,021h,01Fh,000h + defb 039h,0AFh,0B6h,020h,01Ah,021h,00Ch + defb 000h,039h,04Eh,023h,046h,00Bh,070h + defb 02Bh,071h,0CBh,078h,020h,00Bh,0CDh + defw LWRD cstr_base+00C5Dh + defb 039h,034h,023h,020h,0E9h,034h,018h + defb 0E6h,021h,01Dh,000h,039h,0AFh,0B6h + defb 028h,010h,0DDh,04Eh,00Eh,0DDh,046h + defb 00Fh,05Fh,0CDh + defw LWRD cstr_base+00C65h + defb 039h,034h,023h,020h,001h,034h,021h + defb 004h,000h,039h,04Eh,023h,046h,00Bh + defb 070h,02Bh,071h,0CBh,078h,020h,01Ch + defb 0DDh,04Eh,00Eh,0DDh,046h,00Fh,02Bh + defb 02Bh,05Eh,023h,056h,013h,072h,02Bh + defb 073h,01Bh,01Ah,05Fh,0CDh + defw LWRD cstr_base+00C65h + defb 039h,034h,023h,020h,0D7h,018h,0D4h + defb 021h,01Fh,000h,039h,0AFh,0B6h,028h + defb 01Ah,021h,00Ch,000h,039h,04Eh,023h + defb 046h,00Bh,070h,02Bh,071h,0CBh,078h + defb 020h,00Bh,0CDh + defw LWRD cstr_base+00C5Dh + defb 039h,034h,023h,020h,0E9h,034h,018h + defb 0E6h,0C3h + defw LWRD cstr_base+0047Dh + defb 0DDh,04Eh,00Eh,0DDh,046h,00Fh,01Eh + defb 020h,0DDh,07Eh,00Ch,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 021h,006h,000h,0C9h + t_org_rel (01) 00000000 + defb 030h,031h,032h,033h,034h,035h,036h + defb 037h,038h,039h,041h,042h,043h,044h + defb 045h,046h,000h,028h,06Eh,075h,06Ch + defb 06Ch,020h,070h,06Fh,069h,06Eh,074h + defb 065h,072h,029h,000h,030h,031h,032h + defb 033h,034h,035h,036h,037h,038h,039h + defb 061h,062h,063h,064h,065h,066h,000h + defb 03Fh,03Fh,03Fh,000h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/free.asm b/src/libiar/free.asm new file mode 100755 index 00000000..5c150576 --- /dev/null +++ b/src/libiar/free.asm @@ -0,0 +1,70 @@ +; free.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module free + rseg CODE +code_base: + extern _heap_of_memory + extern _last_heap_object + public free +free equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FAh,0FFh,0FDh,0E5h,02Ah + defw LWRD _heap_of_memory + defb 0DDh,075h,0FCh,0DDh,074h,0FDh,0EDh + defb 05Bh + defw LWRD _heap_of_memory + defb 0DDh,07Eh,002h,0DDh,0B6h,003h,0CAh + defw LWRD code_base+000E0h + defb 0EDh,04Bh + defw LWRD _last_heap_object + defb 06Bh,062h,0A7h,0EDh,042h,0D2h + defw LWRD code_base+000E0h + defb 06Bh,062h,023h,023h,023h,0DDh,04Eh + defb 002h,0DDh,046h,003h,0A7h,0EDh,042h + defb 0C2h + defw LWRD code_base+000D0h + defb 0EBh,0E5h,0FDh,0E1h,0AFh,0B6h,0CAh + defw LWRD code_base+000E0h + defb 0DDh,06Eh,0FCh,0DDh,066h,0FDh,0DDh + defb 075h,0FEh,0DDh,074h,0FFh,0FDh,06Eh + defb 001h,0FDh,066h,002h,0EDh,04Bh + defw LWRD _last_heap_object + defb 0EDh,042h,030h,008h,0FDh,06Eh,001h + defb 0FDh,066h,002h,018h,003h,0FDh,0E5h + defb 0E1h,0DDh,075h,0FAh,0DDh,074h,0FBh + defb 0DDh,06Eh,0FCh,0DDh,066h,0FDh,0AFh + defb 0B6h,020h,02Ch,0DDh,06Eh,0FEh,0DDh + defb 066h,0FFh,023h,0E5h,0DDh,06Eh,0FAh + defb 0DDh,066h,0FBh,0B6h,028h,008h,0FDh + defb 05Eh,001h,0FDh,056h + defb 002h,018h,004h,023h,05Eh,023h,056h + defb 0E1h,073h,023h,072h,0DDh,06Eh,0FEh + defb 0DDh,066h,0FFh,0E5h,0FDh,0E1h,018h + defb 018h,0DDh,06Eh,0FAh,0DDh,066h,0FBh + defb 0AFh,0B6h,020h,00Ah,023h,046h,0FDh + defb 070h,001h,023h,066h,0FDh,074h,002h + defb 0FDh,036h,000h,000h,0FDh,06Eh,001h + defb 0FDh,066h,002h,0EDh + defb 04Bh + defw LWRD _last_heap_object + defb 0EDh,042h,020h,016h,0FDh,022h + defw LWRD _last_heap_object + defb 018h,010h,0DDh,073h,0FCh,0DDh,072h + defb 0FDh,0EBh,023h,046h,023h,066h,068h + defb 0EBh,0C3h + defw LWRD code_base+0001Dh + defb 0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/frexp.asm b/src/libiar/frexp.asm new file mode 100755 index 00000000..a36d31b9 --- /dev/null +++ b/src/libiar/frexp.asm @@ -0,0 +1,31 @@ +; frexp.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module frexp + rseg CODE +code_base: + public frexp +frexp equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 079h,0B0h,020h,00Fh,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,077h,023h,077h,04Fh + defb 069h,047h,060h,018h,022h,079h,007h + defb 078h,017h,0D6h,07Eh,04Fh,007h,09Fh + defb 047h,0DDh,06Eh,00Ah,0DDh,066h,00Bh + defb 071h,023h,070h,0DDh,04Eh,004h,0DDh + defb 046h,005h,0EBh,0CBh,0B0h,0CBh,0B9h + defb 03Eh,03Fh,0B0h,047h + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/getchar.asm b/src/libiar/getchar.asm new file mode 100755 index 00000000..01808f43 --- /dev/null +++ b/src/libiar/getchar.asm @@ -0,0 +1,119 @@ +; getchar.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module getchar + rseg CODE +code_base: + rseg CSTR +cstr_base: + rseg UDATA0 +udata0_base: + extern _low_level_get + public getchar +getchar equ udata0_base+00000022h + extern putchar + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + extern ?ENT_AUTO_DIRECT_L09 + extern ?LEAVE_DIRECT_L09 + defb 0DDh,0E5h,0D5h,0DDh,0E1h,0AFh,0DDh + defb 0B6h,000h,028h,00Ah,0DDh,05Eh,000h + defb 0CDh + defw LWRD udata0_base+00018h + defb 0DDh,023h,018h,0F0h,0DDh,0E1h,0C9h + defb 016h,000h,03Eh + defb BYTE3 putchar + defb 021h + defw LWRD putchar + defb 0C3h + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FEh,0FFh,021h + t_rel_p16 (0A) 0000 + defb 0EDh,04Bh + t_rel_p16 (0A) 0052 + defb 009h,07Eh,0B7h,028h,010h,069h,060h + defb 023h,022h + t_rel_p16 (0A) 0052 + defb 02Bh,001h + t_rel_p16 (0A) 0000 + defb 009h,06Eh,026h,000h,018h,025h,06Fh + defb 067h,022h + t_rel_p16 (0A) 0052 + defb 03Eh + defb BYTE3 ?BANK_FAST_LEAVE_L08 + defb 021h + defw LWRD ?BANK_FAST_LEAVE_L08 + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,075h,0FEh,07Dh,0FEh,01Ah,020h + defb 013h,02Ah + t_rel_p16 (0A) 0052 + defb 07Dh,0B4h,020h,00Ch,011h + t_rel_p16 (01) 0000 + defb 0CDh + defw LWRD udata0_base+00000h + defb 021h,0FFh,0FFh,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + defb 0DDh,046h,0FEh,004h,0E2h + defw LWRD udata0_base+00085h + defb 02Ah + t_rel_p16 (0A) 0052 + defb 07Dh,0B4h,028h,0CFh,02Bh,022h + t_rel_p16 (0A) 0052 + defb 011h + t_rel_p16 (01) 0003 + defb 0CDh + defw LWRD udata0_base+00000h + defb 018h,0C3h,0DDh,07Eh,0FEh,0FEh,003h + defb 020h,00Bh,011h + t_rel_p16 (01) 0007 + defb 0CDh + defw LWRD udata0_base+00000h + defb 021h,051h,000h,018h,023h,0FEh,00Dh + defb 020h,024h,02Ah + t_rel_p16 (0A) 0052 + defb 023h,022h + t_rel_p16 (0A) 0052 + defb 02Bh,001h + t_rel_p16 (0A) 0000 + defb 009h,036h,00Ah,01Eh,00Ah,0CDh + defw LWRD udata0_base+00018h + defb 069h,060h,0EDh,04Bh + t_rel_p16 (0A) 0052 + defb 009h,036h,000h,021h,000h,000h,022h + t_rel_p16 (0A) 0052 + defb 018h,030h,001h,050h,080h,02Ah + t_rel_p16 (0A) 0052 + defb 078h,0ACh,067h,0EDh,042h,030h,01Ah + defb 0DDh,07Eh,0FEh,0FEh,020h,038h,019h + defb 02Ah + t_rel_p16 (0A) 0052 + defb 023h,022h + t_rel_p16 (0A) 0052 + defb 02Bh,001h + t_rel_p16 (0A) 0000 + defb 009h,047h,070h,058h,016h,000h,018h + defb 003h,011h,007h,000h,0CDh + defw LWRD udata0_base+0001Ah + defb 0C3h + defw LWRD udata0_base+00048h + defb 0C3h + defw LWRD udata0_base+00027h + t_org_rel (01) 00000000 + defb 05Eh,05Ah,000h,008h,020h,008h,000h + defb 05Eh,043h,00Ah,000h + t_org_rel (0A) 00000000 + t_org_rel (0A) 00000052 + t_org_rel (0A) 00000054 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/getchar0.asm b/src/libiar/getchar0.asm new file mode 100755 index 00000000..cec5b5b0 --- /dev/null +++ b/src/libiar/getchar0.asm @@ -0,0 +1,22 @@ +; getchar0.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module getchar0 + rseg CODE +code_base: + public getchar +getchar equ code_base+00000000h + public ?C_GETCHAR +?C_GETCHAR equ code_base+00000001h + public ?DBG_0T +?DBG_0T equ 00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0C5h,069h,060h,0C1h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/getchar1.asm b/src/libiar/getchar1.asm new file mode 100755 index 00000000..aa7cb1f8 --- /dev/null +++ b/src/libiar/getchar1.asm @@ -0,0 +1,23 @@ +; getchar1.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module getchar1 + rseg CODE +code_base: + public getchar +getchar equ code_base+00000000h + public ?C_GETCHAR +?C_GETCHAR equ code_base+00000001h + public ?DBG_1T +?DBG_1T equ 00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0C5h,000h,000h,000h,069h,060h,0C1h + defb 0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/getchar2.asm b/src/libiar/getchar2.asm new file mode 100755 index 00000000..c6ee6328 --- /dev/null +++ b/src/libiar/getchar2.asm @@ -0,0 +1,23 @@ +; getchar2.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module getchar2 + rseg CODE +code_base: + public getchar +getchar equ code_base+00000000h + public ?C_GETCHAR +?C_GETCHAR equ code_base+00000001h + public ?DBG_2T +?DBG_2T equ 00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0C5h,000h,000h,000h,069h,060h,0C1h + defb 0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/gets.asm b/src/libiar/gets.asm new file mode 100755 index 00000000..6f9f6a43 --- /dev/null +++ b/src/libiar/gets.asm @@ -0,0 +1,36 @@ +; gets.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module gets + rseg CODE +code_base: + extern getchar + public gets +gets equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0C5h,0FDh,0E5h,0DDh,0E5h,0F5h,0D5h + defb 0FDh,0E1h,0D5h,0DDh,0E1h,03Eh + defb BYTE3 getchar + defb 021h + defw LWRD getchar + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 04Dh,044h,03Eh,00Ah,0A9h,0B0h,028h + defb 00Ch,079h,0A0h,03Ch,028h,007h,0DDh + defb 071h,000h,0DDh,023h,018h,0E4h,079h + defb 0A0h,03Ch,020h,00Ah,0FDh,0E5h,0E1h + defb 0DDh,0E5h,0C1h,0EDh,042h,028h,007h + defb 0DDh,036h,000h,000h,0FDh,0E5h,0E1h + defb 0F1h,0DDh,0E1h,0FDh,0E1h,0C1h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/heap.asm b/src/libiar/heap.asm new file mode 100755 index 00000000..b59ef4b8 --- /dev/null +++ b/src/libiar/heap.asm @@ -0,0 +1,34 @@ +; heap.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module heap + rseg CODE +code_base: + rseg CONST +const_base: + rseg UDATA0 +udata0_base: + rseg IDATA0 +idata0_base: + rseg CDATA0 +cdata0_base: + t_symbol_def PUBLIC_REL (0004) 00000000 '_heap_of_memory' + t_symbol_def PUBLIC_REL (000B) 00000000 '_last_heap_object' + t_symbol_def PUBLIC_REL (0004) 00000002 '_top_of_heap' + extern ?CL64180B_4_06_L00 + t_org_rel (04) 00000000 + t_rel_p16 (0A) 0000 + t_rel_p16 (0A) 07CC + t_org_rel (0A) 00000000 + t_org_rel (0A) 000007D0 + t_org_rel (0B) 00000000 + t_org_rel (0B) 00000002 + t_org_rel (0C) 00000000 + t_rel_p16 (0A) 0000 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/isalnum.asm b/src/libiar/isalnum.asm new file mode 100755 index 00000000..d35a73d9 --- /dev/null +++ b/src/libiar/isalnum.asm @@ -0,0 +1,27 @@ +; isalnum.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module isalnum + rseg CODE +code_base: + extern _Large_Ctype + public isalnum +isalnum equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,007h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/isalpha.asm b/src/libiar/isalpha.asm new file mode 100755 index 00000000..4e625d7f --- /dev/null +++ b/src/libiar/isalpha.asm @@ -0,0 +1,27 @@ +; isalpha.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module isalpha + rseg CODE +code_base: + extern _Large_Ctype + public isalpha +isalpha equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,003h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/iscntrl.asm b/src/libiar/iscntrl.asm new file mode 100755 index 00000000..ab301a39 --- /dev/null +++ b/src/libiar/iscntrl.asm @@ -0,0 +1,27 @@ +; iscntrl.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module iscntrl + rseg CODE +code_base: + extern _Large_Ctype + public iscntrl +iscntrl equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,020h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/isdigit.asm b/src/libiar/isdigit.asm new file mode 100755 index 00000000..f7a0e25e --- /dev/null +++ b/src/libiar/isdigit.asm @@ -0,0 +1,27 @@ +; isdigit.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module isdigit + rseg CODE +code_base: + extern _Large_Ctype + public isdigit +isdigit equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,004h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/isgraph.asm b/src/libiar/isgraph.asm new file mode 100755 index 00000000..45eba307 --- /dev/null +++ b/src/libiar/isgraph.asm @@ -0,0 +1,27 @@ +; isgraph.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module isgraph + rseg CODE +code_base: + extern _Large_Ctype + public isgraph +isgraph equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,017h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/islower.asm b/src/libiar/islower.asm new file mode 100755 index 00000000..77308d47 --- /dev/null +++ b/src/libiar/islower.asm @@ -0,0 +1,27 @@ +; islower.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module islower + rseg CODE +code_base: + extern _Large_Ctype + public islower +islower equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,002h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/isprint.asm b/src/libiar/isprint.asm new file mode 100755 index 00000000..13c8cd90 --- /dev/null +++ b/src/libiar/isprint.asm @@ -0,0 +1,27 @@ +; isprint.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module isprint + rseg CODE +code_base: + extern _Large_Ctype + public isprint +isprint equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,097h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ispunct.asm b/src/libiar/ispunct.asm new file mode 100755 index 00000000..a7f19c7e --- /dev/null +++ b/src/libiar/ispunct.asm @@ -0,0 +1,27 @@ +; ispunct.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ispunct + rseg CODE +code_base: + extern _Large_Ctype + public ispunct +ispunct equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,010h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/isspace.asm b/src/libiar/isspace.asm new file mode 100755 index 00000000..c9ec10b7 --- /dev/null +++ b/src/libiar/isspace.asm @@ -0,0 +1,27 @@ +; isspace.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module isspace + rseg CODE +code_base: + extern _Large_Ctype + public isspace +isspace equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,008h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/isupper.asm b/src/libiar/isupper.asm new file mode 100755 index 00000000..b50c8804 --- /dev/null +++ b/src/libiar/isupper.asm @@ -0,0 +1,27 @@ +; isupper.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module isupper + rseg CODE +code_base: + extern _Large_Ctype + public isupper +isupper equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,001h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/isxdigit.asm b/src/libiar/isxdigit.asm new file mode 100755 index 00000000..a5fa46bb --- /dev/null +++ b/src/libiar/isxdigit.asm @@ -0,0 +1,27 @@ +; isxdigit.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module isxdigit + rseg CODE +code_base: + extern _Large_Ctype + public isxdigit +isxdigit equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Large_Ctype 0001 + defb 019h,07Eh,0E6h,044h,06Fh,026h,000h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/labs.asm b/src/libiar/labs.asm new file mode 100755 index 00000000..92a1901d --- /dev/null +++ b/src/libiar/labs.asm @@ -0,0 +1,26 @@ +; labs.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module labs + rseg CODE +code_base: + public labs +labs equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?L_NEG_L03 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0CBh,078h,0EBh,028h,003h,0CDh + defw LWRD ?L_NEG_L03 + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/largectype.asm b/src/libiar/largectype.asm new file mode 100755 index 00000000..9fe92c6c --- /dev/null +++ b/src/libiar/largectype.asm @@ -0,0 +1,58 @@ +; largectype.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module large_ctype + rseg CODE +code_base: + rseg CONST +const_base: + t_symbol_def PUBLIC_REL (0004) 00000000 '_Large_Ctype' + extern ?CL64180B_4_06_L00 + t_org_rel (04) 00000000 + defb 000h,020h,020h,020h,020h,020h,020h + defb 020h,020h,020h,028h,028h,028h,028h + defb 028h,020h,020h,020h,020h,020h,020h + defb 020h,020h,020h,020h,020h,020h,020h + defb 020h,020h,020h,020h,020h,088h,010h + defb 010h,010h,010h,010h,010h,010h,010h + defb 010h,010h,010h,010h,010h,010h,010h + defb 004h,004h,004h,004h + defb 004h,004h,004h,004h,004h,004h,010h + defb 010h,010h,010h,010h,010h,010h,041h + defb 041h,041h,041h,041h,041h,001h,001h + defb 001h,001h,001h,001h,001h,001h,001h + defb 001h,001h,001h,001h,001h,001h,001h + defb 001h,001h,001h,001h,010h,010h,010h + defb 010h,010h,010h,042h,042h,042h,042h + defb 042h,042h,002h,002h + defb 002h,002h,002h,002h,002h,002h,002h + defb 002h,002h,002h,002h,002h,002h,002h + defb 002h,002h,002h,002h,010h,010h,010h + defb 010h,020h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h,000h,000h,000h,000h,000h,000h + defb 000h + defb 000h,000h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ldexp.asm b/src/libiar/ldexp.asm new file mode 100755 index 00000000..c3d6484f --- /dev/null +++ b/src/libiar/ldexp.asm @@ -0,0 +1,57 @@ +; ldexp.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ldexp + rseg CODE +code_base: + extern errno + public ldexp +ldexp equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SS_CMP_L02 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + extern ?__daddexp_L11 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 000h,000h,0FDh,0E5h,079h,0B0h,028h + defb 046h,079h,007h,078h,017h,0D6h,07Eh + defb 04Fh,007h,09Fh,047h,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,009h,0E5h,0FDh,0E1h + defb 001h,006h,07Fh,0DDh,06Eh,00Ah,0DDh + defb 066h,00Bh,03Eh,080h,0ACh,067h,0EDh + defb 042h,038h,00Eh,001h,083h,07Fh,0FDh + defb 0E5h,0E1h,03Eh,080h + defb 0ACh,067h,0EDh,042h,030h,01Ah,021h + defb 022h,000h,022h + defw LWRD errno + defb 0CDh + defw LWRD code_base+00099h + defb 030h,008h,0DDh,0CBh,005h,07Eh,028h + defb 02Ah,018h,023h,001h,000h,000h,069h + defb 060h,018h,03Ch,0CDh + defw LWRD code_base+00099h + defb 038h,00Bh,0FDh,0E5h,0C1h,021h,080h + defb 000h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,019h,021h,022h,000h,022h + defw LWRD errno + defb 0DDh,0CBh,005h,07Eh,028h,005h,001h + defb 07Fh,0FFh,018h,003h,001h,07Fh,07Fh + defb 021h,0FFh,0FFh,018h,013h,0DDh,04Eh + defb 004h,0DDh,046h,005h,0DDh,05Eh,002h + defb 0DDh,056h,003h,0DDh,06Eh,00Ah,0CDh + defw LWRD ?__daddexp_L11 + defb 0EBh,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + defb 0DDh,04Eh,00Ah,0DDh,046h,00Bh,021h + defb 000h,001h,0C3h + defw LWRD ?SS_CMP_L02 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/ldiv.asm b/src/libiar/ldiv.asm new file mode 100755 index 00000000..3f992331 --- /dev/null +++ b/src/libiar/ldiv.asm @@ -0,0 +1,46 @@ +; ldiv.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module ldiv + 00000000 "quot" [0066] 00000004 "rem" [0066] + rseg CODE +code_base: + public ldiv +ldiv equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?L_MUL_L03 + extern ?SL_DIV_L03 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0F8h,0FFh,0DDh,06Eh,010h,0DDh,066h + defb 011h,0E5h,0DDh,06Eh,00Eh,0DDh,066h + defb 00Fh,0E5h,0DDh,04Eh,00Ch,0DDh,046h + defb 00Dh,0DDh,06Eh,00Ah,0DDh,066h,00Bh + defb 0CDh + defw LWRD ?SL_DIV_L03 + defb 0DDh,075h,0F8h,0DDh,074h,0F9h,0DDh + defb 071h,0FAh,0DDh,070h,0FBh,0DDh,06Eh + defb 010h,0DDh,066h,011h,0E5h,0DDh,06Eh + defb 00Eh,0DDh,066h,00Fh,0E5h,0DDh,06Eh + defb 0F8h,0DDh,066h,0F9h,0CDh + defw LWRD ?L_MUL_L03 + defb 059h,050h,04Dh,044h,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,0A7h,0EDh,042h,04Dh + defb 044h,0DDh,06Eh,00Ch,0DDh,066h,00Dh + defb 0EDh,052h,0E5h,0DDh,071h,0FCh,0DDh + defb 070h,0FDh,0C1h,0DDh,071h,0FEh,0DDh + defb 070h,0FFh,021h,000h,000h,039h,0DDh + defb 05Eh,002h,0DDh,056h,003h,001h,008h + defb 000h,0D5h,0EDh,0B0h + defb 0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/libiar.lib b/src/libiar/libiar.lib new file mode 100755 index 00000000..e7125850 --- /dev/null +++ b/src/libiar/libiar.lib @@ -0,0 +1,195 @@ +reliar\BANKCALLDIRECT.rel +reliar\BANKCALLDIRECTEXAF.rel +reliar\BANKLEAVE32.rel +reliar\BANKLEAVEDIRECT.rel +reliar\BFCANDASG.rel +reliar\BFCLSHASG.rel +reliar\BFCMULASG.rel +reliar\BFCORASG.rel +reliar\BFCRETVAL.rel +reliar\BFCSHIFTUP.rel +reliar\BFCXORASG.rel +reliar\BFMASKEDLD.rel +reliar\BFMASKEDST.rel +reliar\BFSADDASG.rel +reliar\BFSANDASG.rel +reliar\BFSCDIVASG.rel +reliar\BFSCEXT.rel +reliar\BFSCLDSHIFTDOWN.rel +reliar\BFSCMODASG.rel +reliar\BFSCRSHASG.rel +reliar\BFSLSHASG.rel +reliar\BFSMULASG.rel +reliar\BFSNEGASG.rel +reliar\BFSORASG.rel +reliar\BFSPOSTDEC.rel +reliar\BFSPOSTINC.rel +reliar\BFSPREDEC.rel +reliar\BFSPREINC.rel +reliar\BFSRETVAL.rel +reliar\BFSSDIVASG.rel +reliar\BFSSEXT.rel +reliar\BFSSHIFTUP.rel +reliar\BFSSLDSHIFTDOWN.rel +reliar\BFSSMODASG.rel +reliar\BFSSRSHASG.rel +reliar\BFSSUBASG.rel +reliar\BFSXORASG.rel +reliar\BFUCDIVASG.rel +reliar\BFUCLDSHIFTDOWN.rel +reliar\BFUCMODASG.rel +reliar\BFUCRSHASG.rel +reliar\BFUSDIVASG.rel +reliar\BFUSLDSHIFTDOWN.rel +reliar\BFUSMODASG.rel +reliar\BFUSRSHASG.rel +reliar\CALLIND.rel +reliar\CDIVMOD.rel +reliar\CFINDSIGN.rel +reliar\CLSH.rel +reliar\CLSHASG.rel +reliar\CMUL.rel +reliar\CMULASG.rel +reliar\CSSWITCH.rel +reliar\CVSWITCH.rel +reliar\ENTAUTODIRECT.rel +reliar\ENTPARMDIRECT.rel +reliar\FADDASG.rel +reliar\FADDSUB.rel +reliar\FCMP.rel +reliar\FDEC.rel +reliar\FDECASG.rel +reliar\FDIV.rel +reliar\FDIVASG.rel +reliar\FENDASG2.rel +reliar\FINC.rel +reliar\FINCASG.rel +reliar\FMUL.rel +reliar\FMULASG.rel +reliar\FNEGASG.rel +reliar\FPACK.rel +reliar\FROUND.rel +reliar\FSUBASG.rel +reliar\FTOL.rel +reliar\FUNPACK.rel +reliar\LADDASG.rel +reliar\LAND.rel +reliar\LANDASG.rel +reliar\LDEC.rel +reliar\LDECASG.rel +reliar\LDIVMOD.rel +reliar\LEAVE32.rel +reliar\LEAVEDIRECT.rel +reliar\LENDASG.rel +reliar\LENDMULDIVASG.rel +reliar\LFINDSIGN.rel +reliar\LIBVERSION.rel +reliar\LINC.rel +reliar\LINCASG.rel +reliar\LLSH.rel +reliar\LLSHASG.rel +reliar\LMUL.rel +reliar\LMULASG.rel +reliar\LNEG.rel +reliar\LNEGASG.rel +reliar\LNOT.rel +reliar\LNOTASG.rel +reliar\LOR.rel +reliar\LORASG.rel +reliar\LSSWITCH.rel +reliar\LSUBASG.rel +reliar\LTOF.rel +reliar\LVSWITCH.rel +reliar\LXOR.rel +reliar\LXORASG.rel +reliar\MEMCMP.rel +reliar\MEMSET.rel +reliar\MONITORBANKLEAVE.rel +reliar\MONITORBANKLEAVE32.rel +reliar\MONITORBANKLEAVEIX.rel +reliar\MONITORBANKLEAVEPOP.rel +reliar\MONITORLEAVE.rel +reliar\MONITORLEAVE32.rel +reliar\MONITORLEAVEIX.rel +reliar\MONITORLEAVEIXPA.rel +reliar\MONITORLEAVEPA.rel +reliar\MONITORLEAVEPOP.rel +reliar\SCDIV.rel +reliar\SCMOD.rel +reliar\SCRSH.rel +reliar\SCRSHASG.rel +reliar\SDIVMOD.rel +reliar\SFINDSIGN.rel +reliar\SLCMP.rel +reliar\SLDIV.rel +reliar\SLDIVASG.rel +reliar\SLMOD.rel +reliar\SLMODASG.rel +reliar\SLRSH.rel +reliar\SLRSHASG.rel +reliar\SLSH.rel +reliar\SLSHASG.rel +reliar\SLSHASGBCprim.rel +reliar\SLSHASGDEprim.rel +reliar\SMUL.rel +reliar\SMULASG.rel +reliar\SMULASGBCprim.rel +reliar\SMULASGDEprim.rel +reliar\SMULASGIX.rel +reliar\SMULASGIY.rel +reliar\SSCMP.rel +reliar\SSDIV.rel +reliar\SSDIVASG.rel +reliar\SSDIVASGBCprim.rel +reliar\SSDIVASGDEprim.rel +reliar\SSDIVASGIX.rel +reliar\SSDIVASGIY.rel +reliar\SSMOD.rel +reliar\SSMODASG.rel +reliar\SSMODASGBCprim.rel +reliar\SSMODASGDEprim.rel +reliar\SSMODASGIX.rel +reliar\SSMODASGIY.rel +reliar\SSRSH.rel +reliar\SSRSHASG.rel +reliar\SSRSHASGBCprim.rel +reliar\SSRSHASGDEprim.rel +reliar\SSRSHASGIX.rel +reliar\SSRSHASGIY.rel +reliar\SSSWITCH.rel +reliar\SSWITCHEND.rel +reliar\STRCAT.rel +reliar\STRCHR.rel +reliar\STRCMP.rel +reliar\STRCPY.rel +reliar\STRLEN.rel +reliar\SVSWITCH.rel +reliar\UCDIV.rel +reliar\UCMOD.rel +reliar\UCRSH.rel +reliar\UCRSHASG.rel +reliar\ULDIV.rel +reliar\ULDIVASG.rel +reliar\ULMOD.rel +reliar\ULMODASG.rel +reliar\ULRSH.rel +reliar\ULRSHASG.rel +reliar\USDIV.rel +reliar\USDIVASG.rel +reliar\USDIVASGBCprim.rel +reliar\USDIVASGDEprim.rel +reliar\USDIVASGIX.rel +reliar\USDIVASGIY.rel +reliar\USMOD.rel +reliar\USMODASG.rel +reliar\USMODASGBCprim.rel +reliar\USMODASGDEprim.rel +reliar\USMODASGIX.rel +reliar\USMODASGIY.rel +reliar\USRSH.rel +reliar\USRSHASG.rel +reliar\USRSHASGBCprim.rel +reliar\USRSHASGDEprim.rel +reliar\USRSHASGIX.rel +reliar\USRSHASGIY.rel +reliar\VSWITCHEND.rel diff --git a/src/libiar/log.asm b/src/libiar/log.asm new file mode 100755 index 00000000..7ee492e2 --- /dev/null +++ b/src/libiar/log.asm @@ -0,0 +1,103 @@ +; log.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module log + rseg CODE +code_base: + extern errno + extern frexp + public log +log equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_MUL_L04 + extern ?F_DIV_L04 + extern ?F_ADD_L04 + extern ?F_CMP_L04 + extern ?SL_TO_F_L04 + extern ?F_MULASG_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + extern ?__daddexp_L11 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FAh,0FFh,0C5h,0DDh,06Eh,002h,0DDh + defb 066h,003h,0E5h,001h,000h,000h,069h + defb 060h,0CDh + defw LWRD ?F_CMP_L04 + defb 038h,020h,0DDh,07Eh,004h,0DDh,0B6h + defb 005h,020h,00Ah,02Eh,022h,022h + defw LWRD errno + defb 001h,07Fh,0FFh,018h,008h,02Eh,021h + defb 022h + defw LWRD errno + defb 001h,07Fh,07Fh,021h,0FFh,0FFh,0C3h + defw LWRD code_base+00111h + defb 039h,0E5h,0DDh,04Eh,004h,0DDh,046h + defb 005h,0DDh,05Eh,002h,0DDh,056h,003h + defb 03Eh + defb BYTE3 frexp + defb 021h + defw LWRD frexp + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0F1h,0DDh,075h,002h,0DDh,074h,003h + defb 0DDh,071h,004h,0DDh,070h,005h,011h + defb 035h,03Fh,0D5h,011h,0F3h,004h,0D5h + defb 0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,015h,02Eh,001h,0CDh + defw LWRD ?__daddexp_L11 + defb 0DDh,071h,004h,0DDh,070h,005h,0DDh + defb 06Eh,0FAh,0DDh,066h,0FBh,02Bh,0DDh + defb 075h,0FAh,021h,080h,03Fh,0E5h,021h + defb 000h,000h,0E5h,0DDh,06Eh,002h,0DDh + defb 066h,003h,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,021h,080h,0BFh,0E5h,021h + defb 000h,000h,0E5h,0DDh,04Eh,004h,0DDh + defb 046h,005h,0DDh,06Eh,002h,0DDh,066h + defb 003h,0CDh + defw LWRD ?F_ADD_L04 + defb 0CDh + defw LWRD ?F_DIV_L04 + defb 0DDh,075h,002h,0DDh,074h,003h,0DDh + defb 071h,004h,0DDh,070h,005h,0C5h,0E5h + defb 0CDh + defw LWRD ?F_MUL_L04 + defb 0DDh,075h,0FCh,0DDh,074h,0FDh,0DDh + defb 071h,0FEh,0DDh,070h,0FFh,021h,008h + defb 000h,039h,0E5h,001h,0D4h,03Eh,0C5h + defb 001h,022h,092h,0C5h,0CDh + defw LWRD code_base+00114h + defb 0C5h,0E5h,001h,02Ah,03Fh,021h,0DDh + defb 09Bh,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+00114h + defb 0C5h,0E5h,001h,000h,040h,06Ah,061h + defb 0CDh + defw LWRD ?F_ADD_L04 + defb 0EBh,0E1h,0CDh + defw LWRD ?F_MULASG_L04 + defb 0C5h,0D5h,0DDh,06Eh,0FAh,07Dh,007h + defb 09Fh,067h,044h,04Ch,0CDh + defw LWRD ?SL_TO_F_L04 + defb 0C5h,0E5h,001h,031h,03Fh,021h,018h + defb 072h,0CDh + defw LWRD ?F_MUL_L04 + defb 0CDh + defw LWRD ?F_ADD_L04 + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + defb 0DDh,04Eh,0FEh,0DDh,046h,0FFh,0DDh + defb 06Eh,0FCh,0DDh,066h,0FDh,0C3h + defw LWRD ?F_MUL_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/log10.asm b/src/libiar/log10.asm new file mode 100755 index 00000000..40ae16a2 --- /dev/null +++ b/src/libiar/log10.asm @@ -0,0 +1,48 @@ +; log10.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module log10 + rseg CODE +code_base: + extern errno + extern log + public log10 +log10 equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?F_MUL_L04 + extern ?F_CMP_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0C5h,0D5h,001h,000h,000h,069h,060h + defb 0CDh + defw LWRD ?F_CMP_L04 + defb 038h,01Fh,0DDh,07Eh,004h,0DDh,0B6h + defb 005h,020h,00Ah,02Eh,022h,022h + defw LWRD errno + defb 001h,07Fh,0FFh,018h,008h,02Eh,021h + defb 022h + defw LWRD errno + defb 001h,07Fh,07Fh,021h,0FFh,0FFh,018h + defb 019h,0DDh,04Eh,004h,0DDh,046h,005h + defb 03Eh + defb BYTE3 log + defb 021h + defw LWRD log + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C5h,0E5h,001h,0DEh,03Eh,021h,0D9h + defb 05Bh,0CDh + defw LWRD ?F_MUL_L04 + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/longjmp.asm b/src/libiar/longjmp.asm new file mode 100755 index 00000000..10ddb61e --- /dev/null +++ b/src/libiar/longjmp.asm @@ -0,0 +1,23 @@ +; longjmp.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module longjmp + rseg CODE +code_base: + public longjmp +longjmp equ code_base+00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 078h,0B1h,020h,001h,003h,0EBh,05Eh + defb 023h,056h,023h,0EBh,0F9h,0EBh,0C5h + defb 04Eh,023h,046h,023h,05Eh,023h,056h + defb 023h,0D5h,0DDh,0E1h,05Eh,023h,056h + defb 023h,0D5h,0FDh,0E1h,05Eh,023h,056h + defb 023h,07Eh,0E1h,0D5h,0F5h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/longjmp2.asm b/src/libiar/longjmp2.asm new file mode 100755 index 00000000..e88a6e60 --- /dev/null +++ b/src/libiar/longjmp2.asm @@ -0,0 +1,28 @@ +; longjmp2.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module longjmp2 + rseg CODE +code_base: + public longjmp +longjmp equ code_base+00000000h + public ?C_LONGJMP +?C_LONGJMP equ code_base+00000028h + public ?DBG_2 +?DBG_2 equ 00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 078h,0B1h,020h,001h,003h,0EBh,05Eh + defb 023h,056h,023h,0EBh,0F9h,0EBh,0C5h + defb 04Eh,023h,046h,023h,05Eh,023h,056h + defb 023h,0D5h,0DDh,0E1h,05Eh,023h,056h + defb 023h,0D5h,0FDh,0E1h,05Eh,023h,056h + defb 023h,07Eh,0E1h,0D5h,0F5h,000h,000h + defb 000h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/malloc.asm b/src/libiar/malloc.asm new file mode 100755 index 00000000..1a225797 --- /dev/null +++ b/src/libiar/malloc.asm @@ -0,0 +1,85 @@ +; malloc.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module malloc + 00000000 "busy" [0070] 00000001 "next" [0066] + rseg CODE +code_base: + extern _heap_of_memory + extern _last_heap_object + public _make_new_mem_hole +_make_new_mem_hole equ code_base+00000000h + extern _top_of_heap + public malloc +malloc equ code_base+00000047h + extern ?CL64180B_4_06_L00 + extern ?SS_CMP_L02 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 000h,000h,0FDh,0E5h,0DDh,06Eh,002h + defb 0DDh,066h,003h,0E5h,0FDh,0E1h,0FDh + defb 06Eh,001h,0FDh,066h,002h,0A7h,0EDh + defb 042h,04Dh,044h,021h,003h,000h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,01Fh,0FDh,05Eh,001h,0FDh,056h + defb 002h,0DDh,06Eh,004h,0FDh,075h,001h + defb 0DDh,066h,005h,0FDh,074h,002h,0E5h + defb 0FDh,0E1h,0FDh,036h,000h,000h,0FDh + defb 073h,001h,0FDh,072h,002h,0FDh,0E1h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FEh,0FFh,0FDh,0E5h,0DDh,04Eh,002h + defb 0DDh,046h,003h,003h,003h,003h,0C5h + defb 0EDh,04Bh + defw LWRD _last_heap_object + defb 02Ah + defw LWRD _top_of_heap + defb 0A7h,0EDh,042h,0C1h,0A7h,0EDh,042h + defb 038h,02Dh,0FDh,02Ah + defw LWRD _last_heap_object + defb 0FDh,036h,000h,001h,0DDh,06Eh,002h + defb 0DDh,066h,003h,023h,023h,023h,0EDh + defb 04Bh + defw LWRD _last_heap_object + defb 009h,022h + defw LWRD _last_heap_object + defb 0FDh,075h,001h,0FDh,074h,002h,0DDh + defb 04Eh,002h,0DDh,046h,003h,02Ah + defw LWRD _last_heap_object + defb 0A7h,0EDh,042h,018h,05Fh,0EDh,05Bh + defw LWRD _heap_of_memory + defb 0EDh,04Bh + defw LWRD _last_heap_object + defb 06Bh,062h,0A7h,0EDh,042h,030h,04Dh + defb 06Bh,062h,0E5h,0FDh,0E1h,0AFh,0B6h + defb 020h,03Ch,0FDh,06Eh,001h,0FDh,066h + defb 002h,0EDh,052h,001h,0FDh,0FFh,009h + defb 0DDh,04Eh,002h,0DDh,046h,003h,0A7h + defb 0EDh,042h,038h,025h,06Bh,062h,023h + defb 023h,023h,0DDh,075h,0FEh,0DDh,074h + defb 0FFh,0FDh,036h,000h + defb 001h,009h,04Dh,044h,0FDh,0E5h,0D1h + defb 03Eh + defb BYTE3 code_base+0000000h + defb 021h + defw LWRD code_base+00000h + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,06Eh,0FEh,0DDh,066h,0FFh,018h + defb 00Bh,0FDh,05Eh,001h,0FDh,056h,002h + defb 018h,0A8h,021h,000h,000h,0FDh,0E1h + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/mediumread.asm b/src/libiar/mediumread.asm new file mode 100755 index 00000000..968f3ca8 --- /dev/null +++ b/src/libiar/mediumread.asm @@ -0,0 +1,369 @@ +; mediumread.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module _medium_read + rseg CODE +code_base: + extern _Small_Ctype + public _medium_read +_medium_read equ code_base+00000168h + extern ?CL64180B_4_06_L00 + extern ?SS_CMP_L02 + extern ?L_MUL_L03 + extern ?L_NEGASG_L03 + extern ?C_V_SWITCH_L06 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?ENT_PARM_DIRECT_L09 + extern ?ENT_AUTO_DIRECT_L09 + extern ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 000h,000h,011h,000h,000h,0DDh,06Eh + defb 002h,0DDh,066h,003h,07Eh,023h,066h + defb 06Fh,04Eh,006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,056h,028h,048h,0DDh,06Eh + defb 004h,0DDh,066h,005h,07Eh,023h,0B6h + defb 028h,03Dh,0DDh,06Eh,002h,0DDh,066h + defb 003h,04Eh,023h,046h,003h,070h,02Bh + defb 071h,00Bh,00Ah,04Fh,006h,000h,0C5h + defb 0EBh,029h,04Dh,044h,029h,029h,009h + defb 0C1h,009h,001h,0D0h,0FFh,009h,0EBh + defb 04Bh,042h,021h,0E8h + defb 003h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,003h,011h,0E8h,003h,0DDh,06Eh + defb 004h,0DDh,066h,005h,04Eh,023h,046h + defb 00Bh,070h,02Bh,071h,018h,0A3h,0EBh + defb 0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 000h,000h,0DDh,06Eh,002h,0DDh,066h + defb 003h,07Eh,023h,066h,06Fh,05Eh,021h + defw LWRD _Small_Ctype 0001 + defb 04Bh,006h,000h,009h,0CBh,05Eh,028h + defb 011h,0DDh,06Eh,002h,0DDh,066h,003h + defb 04Eh,023h,046h,003h,070h,02Bh,071h + defb 00Ah,05Fh,018h,0E4h,07Bh,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 021h + defw LWRD _Small_Ctype 0001 + defb 016h,000h,019h,0CBh,04Eh,07Bh,028h + defb 002h,0E6h,05Fh,0DDh,077h,002h,0FEh + defb 041h,038h,00Eh,03Eh,05Ah,0DDh,0BEh + defb 002h,038h,007h,0DDh,07Eh,002h,0C6h + defb 0C9h,018h,00Fh,021h + defw LWRD _Small_Ctype 0001 + defb 0DDh,04Eh,002h,042h,009h,0CBh,056h + defb 028h,008h,079h,0D6h,030h,0DDh,0BEh + defb 004h,038h,002h,03Eh,064h,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FEh,0FFh,0DDh,05Eh,002h,0DDh,056h + defb 003h,0CDh + defw LWRD code_base+00069h + defb 0DDh,077h,0FEh,0FEh,02Bh,028h,004h + defb 0FEh,02Dh,020h,038h,0DDh,06Eh,008h + defb 0DDh,066h,009h,07Eh,023h,0B6h,028h + defb 02Dh,0DDh,06Eh,008h,0DDh,066h,009h + defb 04Eh,023h,046h,00Bh,070h,02Bh,071h + defb 0DDh,07Eh,0FEh,0FEh,02Dh,020h,008h + defb 0DDh,06Eh,004h,0DDh,066h,005h,036h + defb 001h,0DDh,06Eh,002h + defb 0DDh,066h,003h,04Eh,023h,046h,003h + defb 070h,02Bh,071h,00Ah,0DDh,077h,0FEh + defb 0DDh,07Eh,0FEh,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0FDh,0E5h,0DDh,06Eh,008h,0DDh,066h + defb 009h,0E5h,0FDh,0E1h,0FDh,07Eh,000h + defb 0DDh,0BEh,002h,020h,005h,0DDh,07Eh + defb 004h,018h,01Ah,0FDh,07Eh,001h,0B7h + defb 0FDh,023h,028h,007h,0FDh,07Eh,000h + defb 0FEh,05Dh,020h,0E4h,0AFh,0DDh,0B6h + defb 004h,020h,004h,03Eh,001h,018h,001h + defb 0AFh,0FDh,0E1h,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0ECh,0FFh,0FDh,0E5h,0DDh,06Eh,002h + defb 0DDh,066h,003h,0E5h,0FDh,0E1h,0FDh + defb 06Eh,000h,0DDh,075h,0FCh,0FDh,066h + defb 001h,0DDh,074h,0FDh,0AFh,0DDh,077h + defb 0F2h,0DDh,077h,0F3h,0DDh,06Eh,004h + defb 0DDh,066h,005h,07Eh,023h,066h,06Fh + defb 046h,004h,005h,0CAh + defw LWRD code_base+00747h + defb 021h + defw LWRD _Small_Ctype 0001 + defb 048h,006h,000h,009h,0CBh,05Eh,028h + defb 026h,0FDh,06Eh,000h,0FDh,066h,001h + defb 04Eh,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,05Eh,028h,00Ah,0FDh,0E5h + defb 0E1h,034h,023h,020h,0EAh,034h,018h + defb 0E7h,0DDh,06Eh,004h,0DDh,066h,005h + defb 034h,023h,020h,0C2h,034h,018h,0BFh + defb 0DDh,06Eh,004h,0DDh,066h,005h,07Eh + defb 023h,066h,06Fh,07Eh,0FEh,025h,020h + defb 010h,0DDh,06Eh,004h,0DDh,066h,005h + defb 046h,023h,066h,068h + defb 023h,07Eh,0FEh,06Eh,028h,00Bh,0FDh + defb 06Eh,000h,0FDh,066h,001h,0AFh,0B6h + defb 0CAh + defw LWRD code_base+0071Bh + defb 079h,0FEh,025h,028h,020h,0DDh,06Eh + defb 004h,0DDh,066h,005h,034h,023h,020h + defb 001h,034h,0FDh,0E5h,0D1h,0CDh + defw LWRD code_base+00069h + defb 0B9h,0C2h + defw LWRD code_base+00747h + defb 0FDh,0E5h,0E1h,034h,023h,020h,001h + defb 034h,0C3h + defw LWRD code_base+0018Bh + defb 0DDh,036h,0FEh,000h,0DDh,06Eh,004h + defb 0DDh,066h,005h,04Eh,023h,046h,003h + defb 070h,02Bh,071h,00Ah,0DDh,077h,0EDh + defb 0FEh,02Ah,020h,017h,0DDh,06Eh,004h + defb 0DDh,066h,005h,04Eh,023h,046h,003h + defb 070h,02Bh,071h,00Ah,0DDh,077h,0EDh + defb 0DDh,0CBh,0ECh,086h,018h,004h,0DDh + defb 0CBh,0ECh,0C6h,021h + defw LWRD _Small_Ctype 0001 + defb 04Fh,006h,000h,009h,0CBh,056h,028h + defb 02Ch,0DDh,070h,0FAh,0DDh,036h,0FBh + defb 002h,021h,010h,000h,039h,04Dh,044h + defb 0DDh,05Eh,004h,0DDh,056h,005h,0CDh + defw LWRD code_base+00000h + defb 0DDh,075h,0EEh,0DDh,074h,0EFh,0DDh + defb 06Eh,004h,0DDh,066h,005h,07Eh,023h + defb 066h,06Fh,046h,0DDh,070h,0EDh,018h + defb 007h,0DDh,070h,0EEh,0DDh,036h,0EFh + defb 002h,0DDh,07Eh,0ECh,0E6h,0F3h,0DDh + defb 077h,0ECh,0DDh,07Eh,0EDh,0FEh,06Ch + defb 028h,004h,0FEh,04Ch,020h,006h,0DDh + defb 0CBh,0ECh,0DEh,018h + defb 00Bh,0FEh,068h,020h,015h,0AFh,028h + defb 004h,0DDh,0CBh,0ECh,0D6h,0DDh,06Eh + defb 004h,0DDh,066h,005h,04Eh,023h,046h + defb 003h,070h,02Bh,071h,00Ah,0DDh,06Eh + defb 004h,0DDh,066h,005h,034h,023h,020h + defb 001h,034h,05Fh,0CDh + defw LWRD ?C_V_SWITCH_L06 + defb 00Dh,000h,025h,058h,05Bh,063h,064h + defb 068h,069h,06Eh,06Fh,070h,073h,075h + defb 078h + defw LWRD code_base+00747h + defw LWRD code_base+00300h + defw LWRD code_base+003ACh + defw LWRD code_base+0064Ah + defw LWRD code_base+0039Bh + defw LWRD code_base+002F9h + defw LWRD code_base+006DBh + defw LWRD code_base+00306h + defw LWRD code_base+003ACh + defw LWRD code_base+003ACh + defw LWRD code_base+005C2h + defw LWRD code_base+004B7h + defw LWRD code_base+00300h + defw LWRD code_base+0070Ah + defb 0DDh,036h,0F0h,008h,0C3h + defw LWRD code_base+003B0h + defb 0DDh,036h,0F0h,010h,018h,004h,0DDh + defb 036h,0F0h,00Ah,0DDh,036h,0F1h,000h + defb 021h,004h,000h,039h,0E5h,021h,016h + defb 000h,039h,04Dh,044h,0FDh,0E5h,0D1h + defb 0CDh + defw LWRD code_base+000D7h + defb 0E1h,0DDh,077h,0EDh,0FEh,030h,020h + defb 072h,0DDh,07Eh,0EEh,0DDh,0B6h,0EFh + defb 028h,06Ah,0FDh,06Eh,000h,0FDh,066h + defb 001h,023h,04Eh,006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,046h,0FDh,06Eh,000h,0FDh + defb 066h,001h,023h,028h,006h,046h,0CBh + defb 0E8h,078h,018h,001h,07Eh,0FEh,078h + defb 020h,034h,0DDh,04Eh,0EEh,0DDh,046h + defb 0EFh,021h,001h,000h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,026h,0FDh,0E5h,0E1h,07Eh,0C6h + defb 002h,077h,023h,07Eh,0CEh,000h,077h + defb 02Bh,06Eh,067h,046h,0DDh,070h,0EDh + defb 021h,004h,000h,039h,07Eh,0D6h,002h + defb 077h,023h,07Eh,0DEh,000h,077h,0DDh + defb 036h,0F0h,010h,018h,00Eh,03Eh,00Ah + defb 0DDh,0AEh,0F0h,0DDh,0B6h,0F1h,020h + defb 038h,0DDh,036h,0F0h + defb 008h,0DDh,036h,0F1h,000h,018h,02Eh + defb 0DDh,036h,0F0h,010h,0DDh,036h,0F1h + defb 000h,0AFh,028h,00Eh,0DDh,0CBh,0ECh + defb 0DEh,018h,008h,0DDh,036h,0F0h,00Ah + defb 0DDh,036h,0F1h,000h,021h,004h,000h + defb 039h,0E5h,021h,016h,000h,039h,04Dh + defb 044h,0FDh,0E5h,0D1h,0CDh + defw LWRD code_base+000D7h + defb 0E1h,0DDh,077h,0EDh,0DDh,07Eh,0EEh + defb 0DDh,0B6h,0EFh,028h,00Dh,0DDh,04Eh + defb 0F0h,0DDh,05Eh,0EDh,0CDh + defw LWRD code_base+00099h + defb 0FEh,064h,020h,003h,0C3h + defw LWRD code_base+0071Bh + defb 0AFh,0DDh,077h,0F6h,0DDh,077h,0F7h + defb 0DDh,077h,0F8h,0DDh,077h,0F9h,0DDh + defb 04Eh,0F0h,0FDh,06Eh,000h,0FDh,066h + defb 001h,05Eh,0CDh + defw LWRD code_base+00099h + defb 04Fh,0DDh,071h,0FAh,0DDh,036h,0FBh + defb 000h,03Eh,064h,0A9h,028h,05Ah,0DDh + defb 06Eh,0EEh,0DDh,066h,0EFh,02Bh,0DDh + defb 075h,0EEh,0DDh,074h,0EFh,023h,07Dh + defb 0B4h,028h,048h,0DDh,06Eh,0F0h,0DDh + defb 066h,0F1h,07Ch,007h,09Fh,04Fh,041h + defb 0C5h,0E5h,0DDh,04Eh,0F8h,0DDh,046h + defb 0F9h,0DDh,06Eh,0F6h + defb 0DDh,066h,0F7h,0CDh + defw LWRD ?L_MUL_L03 + defb 0C5h,0E5h,0DDh,06Eh,0FAh,0DDh,066h + defb 0FBh,07Ch,007h,09Fh,05Fh,053h,0C1h + defb 009h,0EBh,0C1h,0EDh,04Ah,04Dh,044h + defb 0EBh,0DDh,075h,0F6h,0DDh,074h,0F7h + defb 0DDh,071h,0F8h,0DDh,070h,0F9h,0FDh + defb 0E5h,0E1h,034h,023h,020h,08Fh,034h + defb 018h,08Ch,0DDh,0CBh,0ECh,046h,0CAh + defw LWRD code_base+0018Bh + defb 0DDh,0B6h,0FEh,028h,007h,021h,00Ch + defb 000h,039h,0CDh + defw LWRD ?L_NEGASG_L03 + defb 0DDh,0CBh,0ECh,05Eh,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,04Eh,059h,023h,046h + defb 050h,013h,013h,072h,02Bh,073h,069h + defb 060h,07Eh,023h,066h,06Fh,028h,012h + defb 0DDh,04Eh,0F8h,0DDh,046h,0F9h,0DDh + defb 05Eh,0F6h,073h,0DDh,056h,0F7h,023h + defb 072h,023h,018h,006h,0DDh,04Eh,0F6h + defb 0DDh,046h,0F7h,071h + defb 023h,070h,0DDh,034h,0F2h,020h,003h + defb 0DDh,034h,0F3h,0C3h + defw LWRD code_base+0018Bh + defb 0DDh,0CBh,0ECh,046h,028h,019h,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,04Eh,059h + defb 023h,046h,050h,013h,013h,072h,02Bh + defb 073h,00Ah,0DDh,077h,0F4h,003h,00Ah + defb 0DDh,077h,0F5h,0DDh,06Eh,004h,0DDh + defb 066h,005h,07Eh,023h,066h,06Fh,046h + defb 0DDh,070h,0EDh,078h,0FEh,05Eh,020h + defb 017h,0DDh,036h,0FEh + defb 000h,0DDh,06Eh,004h,0DDh,066h,005h + defb 04Eh,023h,046h,003h,070h,02Bh,071h + defb 00Ah,0DDh,077h,0EDh,018h,004h,0DDh + defb 036h,0FEh,001h,0AFh,0DDh,0B6h,0EDh + defb 0CAh + defw LWRD code_base+006C2h + defb 0DDh,0CBh,0ECh,0CEh,0DDh,06Eh,0EEh + defb 0DDh,066h,0EFh,02Bh,0DDh,075h,0EEh + defb 0DDh,074h,0EFh,023h,07Dh,0B4h,028h + defb 063h,0FDh,06Eh,000h,0FDh,066h,001h + defb 0AFh,0B6h,028h,059h,0DDh,06Eh,004h + defb 0DDh,066h,005h,04Eh,023h,046h,0C5h + defb 0DDh,04Eh,0FEh,0FDh,06Eh,000h,0FDh + defb 066h,001h,05Eh,0CDh + defw LWRD code_base+0012Eh + defb 0E1h,0B7h,028h,03Eh,0DDh,0CBh,0ECh + defb 04Eh,028h,012h,0DDh,0CBh,0ECh,046h + defb 028h,008h,0DDh,034h,0F2h,020h,003h + defb 0DDh,034h,0F3h,0DDh,0CBh,0ECh,08Eh + defb 0DDh,0CBh,0ECh,046h,028h,016h,0FDh + defb 06Eh,000h,0FDh,066h,001h,046h,0DDh + defb 06Eh,0F4h,0DDh,066h,0F5h,023h,0DDh + defb 075h,0F4h,0DDh,074h + defb 0F5h,02Bh,070h,0FDh,0E5h,0E1h,034h + defb 023h,020h,08Eh,034h,018h,08Bh,0DDh + defb 0CBh,0ECh,04Eh,020h,011h,0DDh,0CBh + defb 0ECh,046h,028h,00Bh,0DDh,06Eh,0F4h + defb 0DDh,066h,0F5h,077h,0DDh,0CBh,0ECh + defb 0CEh,0DDh,0CBh,0ECh,086h,0DDh,06Eh + defb 004h,0DDh,066h,005h,04Eh,023h,046h + defb 003h,070h,02Bh,071h + defb 00Ah,0B7h,028h,00Fh,0FEh,05Dh,020h + defb 0EBh,0DDh,06Eh,004h,0DDh,066h,005h + defb 034h,023h,020h,001h,034h,0C3h + defw LWRD code_base+006C2h + defb 0DDh,0CBh,0ECh,046h,028h,019h,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,04Eh,059h + defb 023h,046h,050h,013h,013h,072h,02Bh + defb 073h,00Ah,0DDh,077h,0F4h,003h,00Ah + defb 0DDh,077h,0F5h,03Eh,002h,0DDh,0AEh + defb 0EFh,0DDh,0B6h,0EEh,020h,007h,0DDh + defb 036h,0EEh,001h,0DDh,077h,0EFh,0DDh + defb 06Eh,0EEh,0DDh,066h + defb 0EFh,02Bh,0DDh,075h,0EEh,0DDh,074h + defb 0EFh,023h,07Dh,0B4h,028h,030h,0FDh + defb 06Eh,000h,0FDh,066h,001h,0AFh,0B6h + defb 028h,026h,0DDh,0CBh,0ECh,046h,028h + defb 016h,0FDh,06Eh,000h,0FDh,066h,001h + defb 046h,0DDh,06Eh,0F4h,0DDh,066h,0F5h + defb 023h,0DDh,075h,0F4h,0DDh,074h,0F5h + defb 02Bh,070h,0FDh,0E5h + defb 0E1h,034h,023h,020h,0C1h,034h,018h + defb 0BEh,0DDh,07Eh,0ECh,0E6h,001h,04Fh + defb 006h,000h,021h,008h,000h,039h,07Eh + defb 081h,077h,023h,07Eh,088h,077h,0C3h + defw LWRD code_base+0018Bh + defb 0DDh,0CBh,0ECh,046h,028h,019h,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,04Eh,059h + defb 023h,046h,050h,013h,013h,072h,02Bh + defb 073h,00Ah,0DDh,077h,0F4h,003h,00Ah + defb 0DDh,077h,0F5h,0FDh,0E5h,0D1h,0CDh + defw LWRD code_base+00069h + defb 0DDh,06Eh,0EEh,0DDh,066h,0EFh,02Bh + defb 0DDh,075h,0EEh,0DDh,074h,0EFh,023h + defb 07Dh,0B4h,028h,041h,0FDh,06Eh,000h + defb 0FDh,066h,001h,0AFh,0B6h,028h,037h + defb 0FDh,06Eh,000h,0FDh,066h,001h,04Eh + defb 006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,05Eh,020h,026h,0DDh,0CBh + defb 0ECh,046h,028h,016h,0FDh,06Eh,000h + defb 0FDh,066h,001h,046h,0DDh,06Eh,0F4h + defb 0DDh,066h,0F5h,023h,0DDh,075h,0F4h + defb 0DDh,074h,0F5h,02Bh,070h,0FDh,0E5h + defb 0E1h,034h,023h,020h,0B0h,034h,018h + defb 0ADh,0DDh,0CBh,0ECh,046h,028h,010h + defb 0DDh,034h,0F2h,020h + defb 003h,0DDh,034h,0F3h,0DDh,06Eh,0F4h + defb 0DDh,066h,0F5h,036h,000h,0C3h + defw LWRD code_base+0018Bh + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,04Eh + defb 059h,023h,046h,050h,013h,013h,072h + defb 02Bh,073h,069h,060h,07Eh,023h,066h + defb 06Fh,0E5h,0DDh,04Eh,0FCh,0DDh,046h + defb 0FDh,0FDh,06Eh,000h,0FDh,066h,001h + defb 0A7h,0EDh,042h,04Dh,044h,0E1h,071h + defb 023h,070h,0C3h + defw LWRD code_base+0018Bh + defb 0FDh,0E5h,0E1h,04Eh,023h,046h,003h + defb 070h,02Bh,071h,00Bh,00Ah,0FEh,025h + defb 0CAh + defw LWRD code_base+0018Bh + defb 0FDh,06Eh,000h,0FDh,066h,001h,0AFh + defb 0B6h,020h,022h,0DDh,06Eh,004h,0DDh + defb 066h,005h,07Eh,023h,066h,06Fh,04Eh + defb 006h,000h,021h + defw LWRD _Small_Ctype 0001 + defb 009h,0CBh,05Eh,028h,00Dh,0DDh,06Eh + defb 004h,0DDh,066h,005h,034h,023h,020h + defb 0E1h,034h,018h,0DEh,0DDh,06Eh,0F2h + defb 0DDh,066h,0F3h,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/mediumwrite.asm b/src/libiar/mediumwrite.asm new file mode 100755 index 00000000..d46bd06e --- /dev/null +++ b/src/libiar/mediumwrite.asm @@ -0,0 +1,372 @@ +; mediumwrite.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module _medium_write + rseg CODE +code_base: + rseg CSTR +cstr_base: + public _medium_write +_medium_write equ cstr_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SS_CMP_L02 + extern ?UL_MOD_L03 + extern ?UL_DIVASG_L03 + extern ?L_NEGASG_L03 + extern ?C_V_SWITCH_L06 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 05Ch,0FFh,0FDh,0E5h,0DDh,06Eh,002h + defb 0DDh,066h,003h,0E5h,0FDh,0E1h,021h + defb 004h,000h,039h,0AFh,077h,023h,077h + defb 0FDh,046h,000h,078h,0FEh,025h,0FDh + defb 023h,028h,022h,0AFh,0B0h,020h,00Dh + defb 021h,004h,000h,039h,046h,023h,066h + defb 068h,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + defb 0DDh,04Eh,00Eh,0DDh,046h,00Fh,05Fh + defb 0CDh + defw LWRD cstr_base+00701h + defb 039h,034h,023h,020h,0D6h,018h,019h + defb 0FDh,07Eh,000h,0FEh,025h,020h,015h + defb 0DDh,04Eh,00Eh,0DDh,046h,00Fh,01Eh + defb 025h,0CDh + defw LWRD cstr_base+00701h + defb 039h,034h,023h,0FDh,023h,020h,0BBh + defb 034h,018h,0B8h,021h,002h,000h,039h + defb 0E5h,021h,022h,000h,039h,04Dh,044h + defb 0E1h,071h,023h,070h,021h,00Ch,000h + defb 039h,071h,023h,070h,021h,016h,000h + defb 039h,036h + t_push_rel (0001) 00000000 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0000 + defb 021h,01Dh,000h,039h,036h,000h,023h + defb 036h,000h,021h,01Ah,000h,039h,036h + defb 000h,02Bh,02Bh,036h,000h,0FDh,05Eh + defb 000h,0CDh + defw LWRD ?C_V_SWITCH_L06 + defb 005h,000h,020h,023h,02Bh,02Dh,030h + defw LWRD cstr_base+000D4h + defw LWRD cstr_base+000CBh + defw LWRD cstr_base+000BDh + defw LWRD cstr_base+000B3h + defw LWRD cstr_base+000C4h + defw LWRD cstr_base+000ABh + defb 021h,018h,000h,039h,0AFh,0B6h,020h + defb 01Dh,0FDh,046h,000h,021h,018h,000h + defb 039h,070h,018h,013h,021h,01Ah,000h + defb 039h,034h,018h,00Ch,021h,01Eh,000h + defb 039h,034h,018h,005h,021h,01Dh,000h + defb 039h,034h,0FDh,023h,018h,0BEh,0FDh + defb 07Eh,000h,0FEh,02Ah,021h,010h,000h + defb 039h,020h,033h,0E5h + defb 0DDh,06Eh,010h,0DDh,066h,011h,04Eh + defb 059h,023h,046h,050h,013h,013h,072h + defb 02Bh,073h,069h,060h,04Eh,023h,046h + defb 0E1h,071h,023h,070h,0CBh,078h,028h + defb 011h,021h,010h,000h,039h,0AFh,091h + defb 077h,023h,03Eh,000h,09Eh,077h,021h + defb 01Ah,000h,039h,034h,0FDh,023h,018h + defb 03Dh,0AFh,077h,023h + defb 077h,0FDh,07Eh,000h,0FEh,030h,038h + defb 032h,03Eh,039h,0FDh,0BEh,000h,038h + defb 02Bh,021h,010h,000h,039h,0E5h,0FDh + defb 04Eh,000h,006h,000h,021h,0D0h,0FFh + defb 009h,0E5h,021h,014h,000h,039h,046h + defb 023h,066h,068h,029h,04Dh,044h,029h + defb 029h,009h,04Dh,044h,0E1h,009h,04Dh + defb 044h,0E1h,071h,023h + defb 070h,0FDh,023h,018h,0C7h,021h,01Ah + defb 000h,039h,0AFh,0B6h,028h,005h,023h + defb 023h,023h,036h,000h,0FDh,07Eh,000h + defb 0FEh,02Eh,020h,068h,0FDh,07Eh,001h + defb 0FEh,02Ah,021h,006h,000h,039h,0FDh + defb 023h,020h,01Eh,0E5h,0DDh,06Eh,010h + defb 0DDh,066h,011h,04Eh,059h,023h,046h + defb 050h,013h,013h,072h + defb 02Bh,073h,069h,060h,04Eh,023h,046h + defb 0E1h,071h,023h,070h,0FDh,023h,018h + defb 046h,0AFh,077h,023h,077h,0FDh,07Eh + defb 000h,0FEh,030h,038h,03Bh,03Eh,039h + defb 0FDh,0BEh,000h,038h,034h,021h,006h + defb 000h,039h,0E5h,0FDh,04Eh,000h,006h + defb 000h + defb 021h,0D0h,0FFh,009h,0E5h,021h,00Ah + defb 000h,039h,046h,023h,066h,068h,029h + defb 04Dh,044h,029h,029h,009h,04Dh,044h + defb 0E1h,009h,04Dh,044h,0E1h,071h,023h + defb 070h,0FDh,023h,018h,0C7h,021h,006h + defb 000h,039h,036h,0FFh,023h,036h,0FFh + defb 021h,01Bh,000h,039h,036h,000h,023h + defb 036h,000h,0FDh,07Eh + 00FE4C2804FE6C2003341806FE6820042B34FD23FD4600211900397058FD23CD + defw LWRD ?C_V_SWITCH_L06 + defb 010h,000h,000h,045h,047h,058h,063h + defb 064h,065h,066h,067h,069h,06Eh,06Fh + defb 070h,073h,075h,078h + defw LWRD cstr_base+005F0h + defw LWRD cstr_base+0036Dh + defw LWRD cstr_base+00376h + defw LWRD cstr_base+002BAh + defw LWRD cstr_base+00376h + defw LWRD cstr_base+00356h + defw LWRD cstr_base+00235h + defw LWRD cstr_base+003FCh + defw LWRD cstr_base+005C8h + defw LWRD cstr_base+005C8h + defw LWRD cstr_base+005C8h + defw LWRD cstr_base+003FCh + defw LWRD cstr_base+00298h + defw LWRD cstr_base+00376h + defw LWRD cstr_base+005C8h + defw LWRD cstr_base+005C8h + defw LWRD cstr_base+005EEh + defb 0AFh,020h,03Bh,023h,023h,028h,009h + defb 0B6h,020h,034h,023h,0B6h,028h,030h + defb 018h,004h,023h,0B6h,028h,02Ah,0DDh + defb 06Eh,010h,0DDh,066h,011h,04Eh,059h + defb 023h,046h,050h,013h,013h,072h,02Bh + defb 073h,069h,060h,07Eh,023h,066h,06Fh + defb 0E5h,021h,006h,000h,039h,05Eh,023h + defb 056h,07Ah,007h,09Fh + defb 04Fh,041h,0E1h,073h,023h,072h,023h + defb 018h,01Fh,0DDh,06Eh,010h,0DDh,066h + defb 011h,04Eh,059h,023h,046h,050h,013h + defb 013h,072h,02Bh,073h,069h,060h,07Eh + defb 023h,066h,06Fh,0E5h,021h,006h,000h + defb 039h,04Eh,023h,046h,0E1h,071h,023h + defb 070h,0C3h + defw LWRD cstr_base+00018h + defb 0DDh,06Eh,010h,0DDh,066h,011h,04Eh + defb 059h,023h,046h,050h,013h,013h,072h + defb 02Bh,073h,00Ah,021h,020h,000h,039h + defb 077h,021h,00Ch,000h,039h,034h,023h + defb 020h,001h,034h,0C3h + defw LWRD cstr_base+0060Ch + defb 021h,002h,000h,039h,0E5h,0DDh,06Eh + defb 010h,0DDh,066h,011h,04Eh,059h,023h + defb 046h,050h,013h,013h,072h,02Bh,073h + defb 069h,060h,04Eh,023h,046h,0E1h,071h + defb 023h,070h,079h,0B0h,020h,009h,021h + defb 002h,000h,039h,036h + t_push_rel (0001) 00000011 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0011 + defb 021h,006h,000h,039h,023h,0CBh,07Eh + defb 028h,006h,02Bh,036h,010h,023h,036h + defb 027h,021h,00Eh,000h,039h,0AFh,077h + defb 023h,077h,021h,002h,000h,039h,04Eh + defb 023h,046h,003h,070h,02Bh,071h,00Bh + defb 00Ah,0B7h,028h,01Fh,021h,006h,000h + defb 039h,04Eh,023h,046h,021h,00Eh,000h + defb 039h,056h,023h,066h + defb 06Ah,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,00Bh,021h,00Eh,000h,039h,034h + defb 023h,020h,0D4h,034h,018h,0D1h,021h + defb 00Ch,000h,039h,0E5h,021h,004h,000h + defb 039h,04Eh,023h,046h,00Bh,070h,02Bh + defb 071h,0E1h,071h,023h,070h,021h,002h + defb 000h,039h,0E5h,021h,010h,000h,039h + defb 04Eh,023h,046h,0E1h,07Eh,091h,077h + defb 023h,07Eh,098h,077h + defb 0C3h + defw LWRD cstr_base+0060Ch + defb 021h,01Eh,000h,039h,0AFh,0B6h,028h + defb 00Fh,021h,006h,000h,039h,07Eh,023h + defb 0B6h,020h,006h,02Bh,034h,023h,020h + defb 001h,034h,021h,016h,000h,039h,036h + t_push_rel (0001) 00000020 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0020 + defb 078h,0FEh,070h,028h,003h,0AFh,028h + defb 00Fh,0DDh,06Eh,010h,0DDh,066h,011h + defb 04Eh,059h,023h,046h,050h,013h,013h + defb 018h,025h,021h,01Ch,000h,039h,0B6h + defb 0DDh,06Eh,010h,0DDh,066h,011h,04Eh + defb 059h,023h,046h,050h,013h,013h,028h + defb 011h,013h,013h,072h,02Bh,073h,069h + defb 060h,05Eh,023h,056h + defb 023h,04Eh,023h,046h,0EBh,018h,00Bh + defb 072h,02Bh,073h,00Ah,06Fh,003h,00Ah + defb 067h,001h,000h,000h,0E5h,021h,00Ah + defb 000h,039h,0D1h,073h,023h,072h,023h + defb 071h,023h,070h,021h,019h,000h,039h + defb 07Eh,0FEh,06Fh,020h,008h,001h,000h + defb 000h,021h,008h,000h,018h,00Eh,0FEh + defb 075h,020h,004h,02Eh + defb 00Ah,018h,002h,02Eh,010h,001h,000h + defb 000h,061h,0E5h,02Eh,014h,039h,0D1h + defb 073h,023h,072h,023h,071h,023h,070h + defb 023h,023h,023h,070h,0C3h + defw LWRD cstr_base+00488h + defb 0AFh,028h,02Fh,0DDh,06Eh,010h,0DDh + defb 066h,011h,04Eh,059h,023h,046h,050h + defb 013h,013h,013h,013h,072h,02Bh,073h + defb 069h,060h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,0E5h,021h,00Ah,000h + defb 039h,0D1h,073h,023h,072h,023h,071h + defb 023h,070h,0CBh,078h,028h,04Fh,018h + defb 041h,023h,023h,023h + defb 0B6h,0DDh,06Eh,010h,0DDh,066h,011h + defb 04Eh,059h,023h,046h,050h,013h,013h + defb 028h,011h,013h,013h,072h,02Bh,073h + defb 069h,060h,05Eh,023h,056h,023h,04Eh + defb 023h,046h,0EBh,018h,00Ch,072h,02Bh + defb 073h,00Ah,06Fh,003h,00Ah,067h,007h + defb 09Fh,04Fh,041h,0E5h,021h,00Ah,000h + defb 039h,0D1h,073h,023h + defb 072h,023h,071h,023h,070h,0CBh,078h + defb 028h,00Ch,02Bh,02Bh,02Bh,0CDh + defw LWRD ?L_NEGASG_L03 + defb 021h,018h,000h,039h,036h,02Dh,021h + defb 012h,000h,039h,0AFh,036h,00Ah,023h + defb 077h,023h,077h,023h,077h,021h,002h + defb 000h,039h,0E5h,021h,022h,000h,039h + defb 001h,085h,000h,009h,04Dh,044h,0E1h + defb 071h,023h,070h,021h,00Ch,000h,039h + defb 071h,023h,070h,021h,008h,000h,039h + defb 07Eh,023h,0B6h,023h + defb 0B6h,023h,0B6h,028h,002h,03Eh,001h + defb 021h,01Fh,000h,039h,077h,021h,006h + defb 000h,039h,07Eh,023h,0B6h,020h,007h + defb 021h,01Fh,000h,039h,0B6h,028h,04Eh + defb 021h,012h,000h,039h,04Eh,023h,046h + defb 023h,05Eh,023h,056h,0D5h,0C5h,021h + defb 00Ch,000h,039h,05Eh,023h,056h,023h + defb 04Eh,023h,046h,0EBh + defb 0CDh + defw LWRD ?UL_MOD_L03 + defb 0E5h,021h,018h,000h,039h,04Eh,023h + defb 046h,0E1h,009h,046h,021h,002h,000h + defb 039h,05Eh,023h,056h,01Bh,072h,02Bh + defb 073h,0EBh,070h,021h,008h,000h,039h + defb 0E5h,021h,014h,000h,039h,05Eh,023h + defb 056h,023h,04Eh,023h,046h,0E1h,0CDh + defw LWRD ?UL_DIVASG_L03 + defb 07Bh,0B2h,0B1h,0B0h,020h,0B2h,021h + defb 006h,000h,039h,023h,0CBh,07Eh,028h + defb 02Dh,021h,01Dh,000h,039h,0AFh,0B6h + defb 028h,025h,021h,006h,000h,039h,0E5h + defb 021h,01Ah,000h,039h,0AFh,0B6h,028h + defb 004h,00Eh,001h,018h,001h,04Fh,006h + defb 000h,021h,012h,000h,039h,056h,023h + defb 066h,06Ah,0A7h,0EDh + defb 042h,04Dh,044h,0E1h,071h,023h,070h + defb 021h,002h,000h,039h,04Eh,023h,046h + defb 021h,00Ch,000h,039h,056h,023h,066h + defb 06Ah,0A7h,0EDh,042h,0E5h,021h,008h + defb 000h,039h,04Eh,023h,046h,0E1h,0CDh + defw LWRD ?SS_CMP_L02 + defb 030h,011h,021h,002h,000h,039h,04Eh + defb 023h,046h,00Bh,070h,02Bh,071h,069h + defb 060h,036h,030h,018h,0CFh,021h,01Eh + defb 000h,039h,0AFh,0B6h,028h,043h,023h + defb 0AFh,0B6h,028h,03Eh,021h,019h,000h + defb 039h,07Eh,0FEh,078h,028h,004h,0FEh + defb 058h,020h,011h,021h,002h,000h,039h + defb 04Eh,023h,046h,00Bh + defb 070h,02Bh,071h,0C5h,047h,0E1h,070h + defb 018h,011h,0FEh,06Fh,020h,062h,021h + defb 002h,000h,039h,07Eh,023h,066h,06Fh + defb 07Eh,0FEh,030h,028h,055h,021h,002h + defb 000h,039h,04Eh,023h,046h,00Bh,070h + defb 02Bh,071h,069h,060h,036h,030h,018h + defb 044h,021h,002h,000h,039h,036h + t_push_rel (0001) 00000031 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0031 + defb 021h,00Ch,000h,039h,036h + t_push_rel (0001) 00000031 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0031 + defb 02Bh,07Eh,023h,066h,06Fh,0AFh,0B6h + defb 028h,029h,021h,00Ch,000h,039h,034h + defb 023h,020h,0EFh,034h,018h,0ECh,0FDh + defb 02Bh,021h,002h,000h,039h,036h + t_push_rel (0001) 00000054 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0054 + defb 021h,00Ch,000h,039h,036h + t_push_rel (0001) 00000054 + t_pop_8 + defb 023h,036h + t_rel_fi_8 (01) 0054 + defb 02Bh,07Eh,0C6h,003h,077h,023h,07Eh + defb 0CEh,000h,077h,021h,006h,000h,039h + defb 0E5h,021h,004h,000h,039h,04Eh,023h + defb 046h,021h,00Eh,000h,039h,056h,023h + defb 066h,06Ah,0A7h,0EDh,042h,04Dh,044h + defb 0E1h,071h,023h,070h,021h,010h,000h + defb 039h,056h,023h,066h,06Ah,0CDh + defw LWRD ?SS_CMP_L02 + defb 021h,00Eh,000h,030h,007h,039h,0AFh + defb 077h,023h,077h,018h,02Dh,039h,0E5h + defb 021h,01Ah,000h,039h,0AFh,0B6h,028h + defb 004h,00Eh,001h,018h,001h,04Fh,006h + defb 000h,021h,012h,000h,039h,023h,066h + defb 06Ah,0A7h,0EDh,042h,0E5h,021h,00Ah + defb 000h,039h,04Eh,023h,046h,0E1h,0A7h + defb 0EDh,042h,04Dh,044h + defb 0E1h,071h,023h,070h,021h,01Ah,000h + defb 039h,0AFh,0B6h,020h,01Ah,021h,00Eh + defb 000h,039h,04Eh,023h,046h,00Bh,070h + defb 02Bh,071h,0CBh,078h,020h,00Bh,0CDh + defw LWRD cstr_base+006F9h + defb 039h,034h,023h,020h,0E9h,034h,018h + defb 0E6h,021h,018h,000h,039h,0AFh,0B6h + defb 028h,010h,0DDh,04Eh,00Eh,0DDh,046h + defb 00Fh,05Fh,0CDh + defw LWRD cstr_base+00701h + defb 039h,034h,023h,020h,001h,034h,021h + defb 006h,000h,039h,04Eh,023h,046h,00Bh + defb 070h,02Bh,071h,0CBh,078h,020h,01Eh + defb 0DDh,04Eh,00Eh,0DDh,046h,00Fh,021h + defb 002h,000h,039h,05Eh,023h,056h,013h + defb 072h,02Bh,073h,01Bh,01Ah,05Fh,0CDh + defw LWRD cstr_base+00701h + defb 039h,034h,023h,020h,0D5h,018h,0D2h + defb 021h,01Ah,000h,039h,0AFh,0B6h,028h + defb 01Ah,021h,00Eh,000h,039h,04Eh,023h + defb 046h,00Bh,070h,02Bh,071h,0CBh,078h + defb 020h,00Bh,0CDh + defw LWRD cstr_base+006F9h + defb 039h,034h,023h,020h,0E9h,034h,018h + defb 0E6h,0C3h + defw LWRD cstr_base+00018h + defb 0DDh,04Eh,00Eh,0DDh,046h,00Fh,01Eh + defb 020h,0DDh,07Eh,00Ch,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 021h,004h,000h,0C9h + t_org_rel (01) 00000000 + defb 030h,031h,032h,033h,034h,035h,036h + defb 037h,038h,039h,041h,042h,043h,044h + defb 045h,046h,000h,028h,06Eh,075h,06Ch + defb 06Ch,020h,070h,06Fh,069h,06Eh,074h + defb 065h,072h,029h,000h,030h,031h,032h + defb 033h,034h,035h,036h,037h,038h,039h + defb 061h,062h,063h,064h,065h,066h,000h + defb 046h,04Ch,04Fh,041h + defb 054h,053h,03Fh,020h,077h,072h,06Fh + defb 06Eh,067h,020h,066h,06Fh,072h,06Dh + defb 061h,074h,074h,065h,072h,020h,069h + defb 06Eh,073h,074h,061h,06Ch,06Ch,065h + defb 064h,021h,000h,03Fh,03Fh,03Fh,000h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/memchr.asm b/src/libiar/memchr.asm new file mode 100755 index 00000000..790577f7 --- /dev/null +++ b/src/libiar/memchr.asm @@ -0,0 +1,29 @@ +; memchr.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module memchr + rseg CODE +code_base: + public memchr +memchr equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,02Bh + defb 0DDh,075h,00Ah,0DDh,074h,00Bh,023h + defb 07Dh,0B4h,028h,01Bh,0DDh,06Eh,002h + defb 0DDh,066h,003h,0DDh,07Eh,004h,0BEh + defb 028h,011h,021h,002h,000h,039h,07Eh + defb 0C6h,001h,077h,023h,07Eh,0CEh,000h + defb 077h,018h,0D3h,06Fh,067h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/memcmplc.asm b/src/libiar/memcmplc.asm new file mode 100755 index 00000000..10e9929e --- /dev/null +++ b/src/libiar/memcmplc.asm @@ -0,0 +1,27 @@ +; memcmplc.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module memcmplc + rseg CODE +code_base: + public memcmp +memcmp equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + extern ?MEMCMP_L11 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0DDh,04Eh,00Ah,0DDh,046h,00Bh,0DDh + defb 06Eh,004h,0DDh,066h,005h,0CDh + defw LWRD ?MEMCMP_L11 + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/memcpy.asm b/src/libiar/memcpy.asm new file mode 100755 index 00000000..7c374c07 --- /dev/null +++ b/src/libiar/memcpy.asm @@ -0,0 +1,26 @@ +; memcpy.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module memcpy + rseg CODE +code_base: + public memcpy +memcpy equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0DDh,04Eh,00Ah,079h,0DDh,046h,00Bh + defb 0DDh,06Eh,004h,0DDh,066h,005h,0B0h + defb 028h,004h,0D5h,0EDh,0B0h,0D1h,0EBh + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/memmove.asm b/src/libiar/memmove.asm new file mode 100755 index 00000000..5386e989 --- /dev/null +++ b/src/libiar/memmove.asm @@ -0,0 +1,46 @@ +; memmove.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module memmove + rseg CODE +code_base: + public memmove +memmove equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 000h,000h,0FDh,0E5h,0DDh,05Eh,00Ah + defb 0DDh,056h,00Bh,0DDh,06Eh,002h,0DDh + defb 066h,003h,0E5h,0FDh,0E1h,0A7h,0EDh + defb 042h,038h,050h,069h,060h,019h,0DDh + defb 04Eh,002h,0DDh,046h,003h,0A7h,0EDh + defb 042h,038h,042h,021h,004h,000h,039h + defb 04Bh,042h,07Eh,081h,077h,023h,07Eh + defb 088h,077h,023h,07Eh + defb 081h,077h,023h,07Eh,088h,077h,07Bh + defb 062h,01Bh,0B4h,028h,056h,021h,006h + defb 000h,039h,07Eh,0C6h,0FFh,077h,023h + defb 07Eh,0CEh,0FFh,077h,02Bh,02Bh,02Bh + defb 07Eh,0C6h,0FFh,077h,023h,07Eh,0CEh + defb 0FFh,077h,0DDh,06Eh,004h,0DDh,066h + defb 005h,046h,0DDh,06Eh,002h,067h,070h + defb 018h,0D3h,07Bh,062h + defb 01Bh,0B4h,028h,029h,0DDh,06Eh,004h + defb 0DDh,066h,005h,046h,0DDh,06Eh,002h + defb 0DDh,066h,003h,070h,021h,006h,000h + defb 039h,07Eh,0C6h,001h,077h,023h,07Eh + defb 0CEh,000h,077h,02Bh,02Bh,02Bh,07Eh + defb 0C6h,001h,077h,023h,07Eh,0CEh,000h + defb 077h,018h,0D1h,0FDh,0E5h,0E1h,0FDh + defb 0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/memsetlc.asm b/src/libiar/memsetlc.asm new file mode 100755 index 00000000..ca298256 --- /dev/null +++ b/src/libiar/memsetlc.asm @@ -0,0 +1,27 @@ +; memsetlc.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module memsetlc + rseg CODE +code_base: + public memset +memset equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + extern ?MEMSET_L11 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0DDh,04Eh,00Ah,0DDh,046h,00Bh,0DDh + defb 06Eh,004h,0CDh + defw LWRD ?MEMSET_L11 + defb 0EBh,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/modf.asm b/src/libiar/modf.asm new file mode 100755 index 00000000..41ab6f8a --- /dev/null +++ b/src/libiar/modf.asm @@ -0,0 +1,45 @@ +; modf.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module modf + rseg CODE +code_base: + public modf +modf equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_SUB_L04 + extern ?F_TO_L_L04 + extern ?SL_TO_F_L04 + extern ?BANK_FAST_LEAVE_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FCh,0FFh,021h,018h,04Bh,0E5h,021h + defb 080h,096h,0E5h,0DDh,06Eh,002h,0DDh + defb 066h,003h,0CBh,0B8h,0CDh + defw LWRD ?SL_CMP_L03 + defb 0DDh,046h,005h,038h,016h,0E5h,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,0D1h,073h + defb 023h,072h,023h,071h,023h,070h,001h + defb 000h,000h,069h,060h,018h,032h,0CDh + defw LWRD ?F_TO_L_L04 + defb 0CDh + defw LWRD ?SL_TO_F_L04 + defb 0DDh,075h,0FCh,0DDh,074h,0FDh,0E5h + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,0D1h + defb 073h,023h,072h,023h,071h,023h,070h + defb 0C5h,0DDh,06Eh,0FCh,0DDh,066h,0FDh + defb 0E5h,0DDh,04Eh,004h,0DDh,046h,005h + defb 0DDh,06Eh,002h,0DDh,066h,003h,0CDh + defw LWRD ?F_SUB_L04 + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/n.bat b/src/libiar/n.bat new file mode 100755 index 00000000..97a07cd8 --- /dev/null +++ b/src/libiar/n.bat @@ -0,0 +1,4 @@ +cd build +copy ..\build.ban n.bat +call n +cd .. diff --git a/src/libiar/pow.asm b/src/libiar/pow.asm new file mode 100755 index 00000000..53ec32dc --- /dev/null +++ b/src/libiar/pow.asm @@ -0,0 +1,182 @@ +; pow.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module pow + rseg CODE +code_base: + extern abs + extern errno + extern exp + extern floor + extern log + public pow +pow equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_MUL_L04 + extern ?F_DIV_L04 + extern ?F_ADD_L04 + extern ?F_SUB_L04 + extern ?F_TO_L_L04 + extern ?SL_TO_F_L04 + extern ?F_MULASG_L04 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + extern ?__daddexp_L11 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0E4h,0FFh,0FDh,0E5h,0AFh,0DDh,077h + defb 0FAh,0DDh,077h,0FBh,0DDh,07Eh,00Ch + defb 0DDh,0B6h,00Dh,020h,005h,001h,080h + defb 03Fh,018h,06Eh,079h,0B0h,020h,002h + defb 018h,066h,059h,050h,0DDh,06Eh,002h + defb 0DDh,066h,003h,0CBh,0BAh,001h,0FFh + defb 0FFh,0EDh,042h,020h,01Dh,0EBh,001h + defb 07Fh,07Fh,0EDh,042h + defb 020h,015h,021h,022h,000h,022h + defw LWRD errno + defb 0DDh,04Eh,004h,0DDh,046h,005h,0DDh + defb 06Eh,002h,0DDh,066h,003h,0C3h + defw LWRD code_base+00269h + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,001h + defb 0FFh,0FFh,0A7h,0EDh,042h,020h,019h + defb 0DDh,06Eh,00Ch,0DDh,066h,00Dh,001h + defb 07Fh,07Fh,0EDh,042h,020h,00Ch,021h + defb 022h,000h,022h + defw LWRD errno + defb 021h,0FFh,0FFh,0C3h + defw LWRD code_base+00269h + defb 03Eh,080h,0DDh,0AEh,00Ch,0DDh,0A6h + defb 00Dh,0DDh,0A6h,00Bh,0DDh,0A6h,00Ah + defb 03Ch,020h,004h,04Fh,047h,018h,025h + defb 0DDh,0CBh,005h,07Eh,028h,03Ah,0CDh + defw LWRD code_base+0026Eh + defb 0CDh + defw LWRD ?SL_TO_F_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+0027Dh + defb 0C5h,0E5h,001h,080h,034h,021h,000h + defb 000h,0CDh + defw LWRD ?SL_CMP_L03 + defb 030h,00Dh,02Eh,021h,022h + defw LWRD errno + defb 04Ch,044h,021h,000h,000h,0C3h + defw LWRD code_base+00269h + defb 0CDh + defw LWRD code_base+0026Eh + defb 07Dh,0E6h,001h,0DDh,077h,0FAh,0DDh + defb 036h,0FBh,000h,0DDh,046h,005h,0CBh + defb 0B8h,0DDh,070h,005h,0DDh,04Eh,004h + defb 0DDh,046h,005h,0DDh,06Eh,002h,0DDh + defb 066h,003h,0CBh,0B0h,0CBh,0B9h,03Eh + defb 03Fh,0B0h,047h,0DDh,075h,0E8h,0DDh + defb 074h,0E9h,0DDh,071h,0EAh,0DDh,070h + defb 0EBh,0DDh,07Eh,004h + defb 0DDh,046h,005h,007h,078h,017h,0D6h + defb 07Eh,06Fh,007h,09Fh,067h,044h,04Ch + defb 0CDh + defw LWRD ?SL_TO_F_L04 + defb 0C5h,0E5h,0DDh,04Eh,00Ch,0DDh,046h + defb 00Dh,0DDh,06Eh,00Ah,0DDh,066h,00Bh + defb 0CDh + defw LWRD ?F_MUL_L04 + defb 0DDh,075h,0F2h,0DDh,074h,0F3h,0DDh + defb 071h,0F4h,0DDh,070h,0F5h,0EBh,03Eh + defb BYTE3 floor + defb 021h + defw LWRD floor + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,075h,0F6h,0DDh,074h,0F7h,0DDh + defb 071h,0F8h,0DDh,070h,0F9h,0CDh + defw LWRD ?F_TO_L_L04 + defb 0E5h,0FDh,0E1h,0DDh,04Eh,0F8h,0DDh + defb 046h,0F9h,0C5h,0DDh,04Eh,0F6h,0DDh + defb 046h,0F7h,0C5h,0DDh,04Eh,0F4h,0DDh + defb 046h,0F5h,0DDh,06Eh,0F2h,0DDh,066h + defb 0F3h,0CDh + defw LWRD ?F_SUB_L04 + defb 0DDh,075h,0E4h,0DDh,074h,0E5h,0DDh + defb 071h,0E6h,0DDh,070h,0E7h,0FDh,0E5h + defb 0E1h,07Ch,007h,09Fh,04Fh,041h,0CDh + defw LWRD ?SL_TO_F_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+0027Dh + defb 0C5h,0E5h,0DDh,04Eh,0EAh,0DDh,046h + defb 0EBh,0DDh,05Eh,0E8h,0DDh,056h,0E9h + defb 03Eh + defb BYTE3 log + defb 021h + defw LWRD log + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0CDh + defw LWRD ?F_MUL_L04 + defb 0C5h,0E5h,021h,031h,03Fh,0E5h,021h + defb 018h,072h,0E5h,0DDh,04Eh,0E6h,0DDh + defb 046h,0E7h,0DDh,06Eh,0E4h,0DDh,066h + defb 0E5h,0CDh + defw LWRD ?F_MUL_L04 + defb 0CDh + defw LWRD ?F_ADD_L04 + defb 0EBh,03Eh + defb BYTE3 exp + defb 021h + defw LWRD exp + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,075h,0ECh,0DDh,074h,0EDh,0DDh + defb 071h,0EEh,0DDh,070h,0EFh,0AFh,0DDh + defb 077h,0E4h,0DDh,077h,0E5h,0DDh,036h + defb 0E6h,080h,0DDh,036h,0E7h,03Fh,0FDh + defb 0E5h,0D1h,03Eh + defb BYTE3 abs + defb 021h + defw LWRD abs + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,075h,0F0h,0DDh,074h,0F1h,07Dh + defb 0B4h,028h,053h,0DDh,0CBh,0F0h,046h + defb 028h,007h,021h,002h,000h,039h,0CDh + defw LWRD code_base+0028Ch + defb 03Eh,001h,0DDh,0AEh,0F0h,0DDh,0B6h + defb 0F1h,028h,013h,021h,006h,000h,039h + defb 0CDh + defw LWRD code_base+0028Ch + defb 021h,00Eh,000h,039h,023h,0CBh,03Eh + defb 02Bh,0CBh,01Eh,018h,0D6h,0FDh,0E5h + defb 0E1h,0CBh,07Ch,028h,022h,0DDh,06Eh + defb 0E6h,0DDh,066h,0E7h,0E5h,0DDh,06Eh + defb 0E4h,0DDh,066h,0E5h,0E5h,001h,080h + defb 03Fh,06Fh,067h,0CDh + defw LWRD ?F_DIV_L04 + defb 0DDh,075h,0E4h,0DDh,074h,0E5h,0DDh + defb 071h,0E6h,0DDh,070h,0E7h,0DDh,04Eh + defb 0E6h,0DDh,046h,0E7h,0DDh,05Eh,0E4h + defb 0DDh,056h,0E5h,0FDh,0E5h,0E1h,0CDh + defw LWRD ?__daddexp_L11 + defb 021h,00Ah,000h,039h,0CDh + defw LWRD ?F_MULASG_L04 + defb 0DDh,07Eh,0FAh,0DDh,0B6h,0FBh,028h + defb 00Bh,0EBh,079h,0B0h,028h,012h,078h + defb 0EEh,080h,047h,018h,00Ch,0DDh,04Eh + defb 0EEh,0DDh,046h,0EFh,0DDh,06Eh,0ECh + defb 0DDh,066h,0EDh,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_32_L08 + defb 0DDh,04Eh,00Ch,0DDh,046h,00Dh,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,0C3h + defw LWRD ?F_TO_L_L04 + defb 0DDh,04Eh,00Ch,0DDh,046h,00Dh,0DDh + defb 06Eh,00Ah,0DDh,066h,00Bh,0C3h + defw LWRD ?F_SUB_L04 + defb 0DDh,04Eh,0EAh,0DDh,046h,0EBh,0DDh + defb 05Eh,0E8h,0DDh,056h,0E9h,0C3h + defw LWRD ?F_MULASG_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/printf.asm b/src/libiar/printf.asm new file mode 100755 index 00000000..cda370a5 --- /dev/null +++ b/src/libiar/printf.asm @@ -0,0 +1,51 @@ +; printf.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module printf + rseg CODE +code_base: + extern _formatted_write + public printf +printf equ code_base+00000010h + extern putchar + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 016h,000h,03Eh + defb BYTE3 putchar + defb 021h + defw LWRD putchar + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FEh,0FFh,0FDh,0E5h,021h,00Eh,000h + defb 039h,001h,002h,000h,009h,0DDh,075h + defb 0FEh,0DDh,074h,0FFh,069h,060h,039h + defb 0E5h,068h,060h,0E5h,00Eh + defb BYTE3 code_base+0000000h + defb 0C5h,021h + defw LWRD code_base+00000h + defb 0E5h,0DDh,05Eh,00Ah,0DDh,056h,00Bh + defb 03Eh + defb BYTE3 _formatted_write + defb 021h + defw LWRD _formatted_write + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0F1h,0F1h,0F1h,0F1h,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/putchar.asm b/src/libiar/putchar.asm new file mode 100755 index 00000000..5d744c74 --- /dev/null +++ b/src/libiar/putchar.asm @@ -0,0 +1,23 @@ +; putchar.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module putchar + rseg CODE +code_base: + public putchar +putchar equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_PARM_DIRECT_L09 + defb 0EBh,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/putchar0.asm b/src/libiar/putchar0.asm new file mode 100755 index 00000000..5885b53c --- /dev/null +++ b/src/libiar/putchar0.asm @@ -0,0 +1,22 @@ +; putchar0.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module putchar0 + rseg CODE +code_base: + public putchar +putchar equ code_base+00000000h + public ?C_PUTCHAR +?C_PUTCHAR equ code_base+00000003h + public ?DBG_0T +?DBG_0T equ 00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0C5h,04Bh,042h,0C1h,06Bh,062h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/putchar1.asm b/src/libiar/putchar1.asm new file mode 100755 index 00000000..68628d38 --- /dev/null +++ b/src/libiar/putchar1.asm @@ -0,0 +1,23 @@ +; putchar1.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module putchar1 + rseg CODE +code_base: + public putchar +putchar equ code_base+00000000h + public ?C_PUTCHAR +?C_PUTCHAR equ code_base+00000003h + public ?DBG_1T +?DBG_1T equ 00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0C5h,04Bh,042h,000h,000h,000h,0C1h + defb 06Bh,062h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/putchar2.asm b/src/libiar/putchar2.asm new file mode 100755 index 00000000..b61d5c52 --- /dev/null +++ b/src/libiar/putchar2.asm @@ -0,0 +1,23 @@ +; putchar2.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module putchar2 + rseg CODE +code_base: + public putchar +putchar equ code_base+00000000h + public ?C_PUTCHAR +?C_PUTCHAR equ code_base+00000003h + public ?DBG_2T +?DBG_2T equ 00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 0C5h,04Bh,042h,000h,000h,000h,0C1h + defb 06Bh,062h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/puts.asm b/src/libiar/puts.asm new file mode 100755 index 00000000..f716c974 --- /dev/null +++ b/src/libiar/puts.asm @@ -0,0 +1,39 @@ +; puts.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module puts + rseg CODE +code_base: + extern putchar + public puts +puts equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_PARM_DIRECT_L09 + defb 0DDh,0E5h,0D5h,0DDh,0E1h,0AFh,0DDh + defb 0B6h,000h,028h,018h,0DDh,05Eh,000h + defb 016h,000h,03Eh + defb BYTE3 putchar + defb 021h + defw LWRD putchar + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 07Dh,0B4h,0DDh,023h,020h,0E7h,021h + defb 0FFh,0FFh,018h,00Eh,011h,00Ah,000h + defb 03Eh + defb BYTE3 putchar + defb 021h + defw LWRD putchar + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 021h,001h,000h,0DDh,0E1h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/qsort.asm b/src/libiar/qsort.asm new file mode 100755 index 00000000..1371fec0 --- /dev/null +++ b/src/libiar/qsort.asm @@ -0,0 +1,192 @@ +; qsort.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module qsort + rseg CODE +code_base: + rseg IDATA0 +idata0_base: + rseg CDATA0 +cdata0_base: + t_symbol_def PUBLIC_REL (000B) 00000000 '_qbuf' + public qsort +qsort equ cdata0_base+00000281h + extern ?CL64180B_4_06_L00 + extern ?S_MUL_L02 + extern ?SS_CMP_L02 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + extern ?LEAVE_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0FAh,0FFh,0FDh,0E5h,0DDh,06Eh,00Ah + defb 0DDh,066h,00Bh,0E5h,0FDh,0E1h,0DDh + defb 04Eh,008h,0DDh,046h,009h,0DDh,06Eh + defb 004h,0DDh,066h,005h,0CDh + defw LWRD ?SS_CMP_L02 + defb 0D2h + defw LWRD cdata0_base+001FDh + defb 069h,060h,0DDh,04Eh,004h,0DDh,046h + defb 005h,009h,0EBh,0CBh,02Ah,0CBh,01Bh + defb 0FDh,0E5h,0C1h,0CDh + defw LWRD cdata0_base+00276h + defb 0DDh,075h,0FCh,0DDh,074h,0FDh,0DDh + defb 04Eh,004h,0DDh,046h,005h,0DDh,071h + defb 0FAh,0DDh,070h,0FBh,0DDh,04Eh,008h + defb 0DDh,046h,009h,0DDh,071h,0FEh,0DDh + defb 070h,0FFh,0EDh,04Bh + t_rel_p16 (0B) 0000 + defb 0A7h,0EDh,042h,028h,013h,0FDh,0E5h + defb 0C1h,0EDh,05Bh + t_rel_p16 (0B) 0000 + defb 0DDh,06Eh,0FCh,0DDh,066h,0FDh,079h + defb 0B0h,028h,002h,0EDh,0B0h,0DDh,04Eh + defb 0FAh,0DDh,046h,0FBh,0CDh + defw LWRD cdata0_base+00234h + defb 028h,00Eh,0FDh,0E5h,0C5h,0CDh + defw LWRD cdata0_base+0026Dh + defb 0D1h,0C1h,079h,0B0h,028h,002h,0EDh + defb 0B0h,0CDh + defw LWRD cdata0_base+0026Dh + defb 0EDh,04Bh + t_rel_p16 (0B) 0000 + defb 0A7h,0EDh,042h,028h,012h,0FDh,0E5h + defb 0C1h,0FDh,0E5h,0CDh + defw LWRD cdata0_base+0025Bh + defb 02Ah + t_rel_p16 (0B) 0000 + defb 0C1h,079h,0B0h,028h,002h,0EDh,0B0h + defb 02Ah + t_rel_p16 (0B) 0000 + defb 0DDh,075h,0FCh,0DDh,074h,0FDh,0CDh + defw LWRD cdata0_base+00202h + defb 0D2h + defw LWRD cdata0_base+0015Eh + defb 0DDh,04Eh,0FCh,0DDh,046h,0FDh,0C5h + defb 0DDh,05Eh,0FEh,0DDh,056h,0FFh,0CDh + defw LWRD cdata0_base+0021Ch + defb 0C1h,0CDh + defw LWRD cdata0_base+00211h + defb 030h,00Fh,0DDh,06Eh,0FEh,0DDh,066h + defb 0FFh,02Bh,0DDh,075h,0FEh,0DDh,074h + defb 0FFh,018h,0DBh,0CDh + defw LWRD cdata0_base+0026Dh + defb 0E5h,0DDh,04Eh,0FEh,0DDh,046h,0FFh + defb 0CDh + defw LWRD cdata0_base+0024Bh + defb 0E1h,0A7h,0EDh,042h,028h,01Ah,0FDh + defb 0E5h,0C1h,0FDh,0E5h,0CDh + defw LWRD cdata0_base+0025Bh + defb 0D5h,0DDh,04Eh,0FEh,0DDh,046h,0FFh + defb 0CDh + defw LWRD cdata0_base+00273h + defb 0D1h,0C1h,079h,0B0h,028h,002h,0EDh + defb 0B0h,0CDh + defw LWRD cdata0_base+00202h + defb 030h,01Bh,0DDh,04Eh,0FCh,0DDh,046h + defb 0FDh,0C5h,0EBh,0CDh + defw LWRD cdata0_base+0021Ch + defb 0C1h,0CDh + defw LWRD cdata0_base+00211h + defb 038h,00Ah,0DDh,034h,0FAh,020h,0E5h + defb 0DDh,034h,0FBh,018h,0E0h,0DDh,04Eh + defb 0FEh,0DDh,046h,0FFh,0CDh + defw LWRD cdata0_base+00273h + defb 0E5h,0DDh,04Eh,0FAh,0DDh,046h,0FBh + defb 0CDh + defw LWRD cdata0_base+0024Bh + defb 0E1h,0A7h,0EDh,042h,028h,01Ah,0FDh + defb 0E5h,0C1h,0FDh,0E5h,0DDh,05Eh,0FEh + defb 0DDh,056h,0FFh,0CDh + defw LWRD cdata0_base+00261h + defb 0D5h,0CDh + defw LWRD cdata0_base+0026Dh + defb 0D1h,0C1h,079h,0B0h,028h,002h,0EDh + defb 0B0h,0C3h + defw LWRD cdata0_base+000B0h + defb 04Dh,044h,0CDh + defw LWRD cdata0_base+00234h + defb 028h,015h,0FDh,0E5h,0C1h,0FDh,0E5h + defb 0CDh + defw LWRD cdata0_base+0025Bh + defb 0DDh,06Eh,0FCh,0DDh,066h,0FDh,0C1h + defb 079h,0B0h,028h,002h,0EDh,0B0h,0DDh + defb 04Eh,0FAh,0DDh,046h,0FBh,0DDh,06Eh + defb 008h,0DDh,066h,009h,0A7h,0EDh,042h + defb 04Dh,044h,0DDh,05Eh,004h,0DDh,056h + defb 005h,0DDh,06Eh,0FAh,0DDh,066h,0FBh + defb 0A7h,0EDh,052h,0CDh + defw LWRD ?SS_CMP_L02 + defb 0DDh,06Eh,00Eh,0E5h,0DDh,06Eh,00Ch + defb 0DDh,066h,00Dh,0E5h,0FDh,0E5h,030h + defb 026h,0DDh,06Eh,0FAh,0DDh,066h,0FBh + defb 02Bh,0E5h,04Bh,042h,0DDh,05Eh,002h + defb 0DDh,056h,003h,0CDh + defw LWRD cdata0_base+00000h + defb 0E1h,0E1h,0E1h,0E1h,0DDh,06Eh,0FAh + defb 0DDh,066h,0FBh,023h,0DDh,075h,004h + defb 0DDh,074h,005h,018h,028h,0DDh,06Eh + defb 008h,0DDh,066h,009h,0E5h,0DDh,04Eh + defb 0FAh,0DDh,046h,0FBh,003h,0DDh,05Eh + defb 002h,0DDh,056h,003h,0CDh + defw LWRD cdata0_base+00000h + defb 0E1h,0E1h,0E1h,0E1h,0DDh,06Eh,0FAh + defb 0DDh,066h,0FBh,02Bh,0DDh,075h,008h + defb 0DDh,074h,009h,0C3h + defw LWRD cdata0_base+00010h + defb 0FDh,0E1h,0C3h + defw LWRD ?LEAVE_DIRECT_L09 + defb 0DDh,04Eh,0FEh,0DDh,046h,0FFh,0DDh + defb 06Eh,0FAh,0DDh,066h,0FBh,0C3h + defw LWRD ?SS_CMP_L02 + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 04Dh,044h,021h,000h,000h,0C3h + defw LWRD ?SS_CMP_L02 + defb 0FDh,0E5h,0C1h,0CDh + defw LWRD ?S_MUL_L02 + defb 0DDh,06Eh,002h,0DDh,066h,003h,019h + defb 0EBh,0DDh,07Eh,00Eh,0DDh,06Eh,00Ch + defb 0DDh,066h,00Dh,0C9h,0FDh,0E5h,0D1h + defb 0CDh + defw LWRD ?S_MUL_L02 + defb 0DDh,06Eh,002h,0DDh,066h,003h,019h + defb 0DDh,04Eh,0FCh,0DDh,046h,0FDh,0A7h + defb 0EDh,042h,0C9h,0FDh,0E5h,0D1h,0CDh + defw LWRD ?S_MUL_L02 + defb 0DDh,06Eh,002h,0DDh,066h,003h,019h + defb 04Dh,044h,0C9h,0DDh,05Eh,0FAh,0DDh + defb 056h,0FBh,0CDh + defw LWRD ?S_MUL_L02 + defb 0DDh,06Eh,002h,0DDh,066h,003h,019h + defb 0EBh,0C9h,0DDh,04Eh,0FAh,0DDh,046h + defb 0FBh,0FDh,0E5h,0D1h,0CDh + defw LWRD ?S_MUL_L02 + defb 0DDh,06Eh,002h,0DDh,066h,003h,019h + defb 0C9h,0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 080h,0FFh,0DDh,05Eh,00Ah,0DDh,056h + defb 00Bh,021h,080h,000h,0A7h,0EDh,052h + defb 038h,02Ah,021h,000h,000h,039h,022h + t_rel_p16 (0B) 0000 + defb 0DDh,06Eh,00Eh,0E5h,0DDh,06Eh,00Ch + defb 0DDh,066h,00Dh,0E5h,06Bh,062h,0D5h + defb 021h,0FFh,0FFh,009h,0E5h,001h,000h + defb 000h,0DDh,05Eh,002h,0DDh,056h,003h + defb 0CDh + defw LWRD cdata0_base+00000h + defb 0E1h,0E1h,0E1h,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + t_org_rel (0B) 00000000 + t_org_rel (0B) 00000002 + t_org_rel (0C) 00000000 + defb 000h,000h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/rand.asm b/src/libiar/rand.asm new file mode 100755 index 00000000..113c0980 --- /dev/null +++ b/src/libiar/rand.asm @@ -0,0 +1,42 @@ +; rand.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module rand + rseg CODE +code_base: + rseg IDATA0 +idata0_base: + rseg CDATA0 +cdata0_base: + t_symbol_def PUBLIC_REL (000B) 00000000 '__next_rand' + public rand +rand equ cdata0_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?L_MUL_L03 + extern ?BANK_FAST_LEAVE_L08 + defb 0C5h,0D5h,021h,0C6h,041h,0E5h,021h + defb 06Dh,04Eh,0E5h,0EDh,04Bh + t_rel_p16 (0B) 0002 + defb 02Ah + t_rel_p16 (0B) 0000 + defb 0CDh + defw LWRD ?L_MUL_L03 + defb 0C5h,0E5h,021h,039h,030h,0C1h,009h + defb 0EBh,021h,000h,000h,0C1h,0EDh,04Ah + defb 04Dh,044h,0EBh,022h + t_rel_p16 (0B) 0000 + defb 0EDh,043h + t_rel_p16 (0B) 0002 + defb 069h,060h,0CBh,0BCh,0D1h,0C1h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + t_org_rel (0B) 00000000 + t_org_rel (0B) 00000004 + t_org_rel (0C) 00000000 + defb 001h,000h,000h,000h + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/realloc.asm b/src/libiar/realloc.asm new file mode 100755 index 00000000..fe481ed8 --- /dev/null +++ b/src/libiar/realloc.asm @@ -0,0 +1,162 @@ +; realloc.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module realloc + 00000000 "busy" [0072] 00000001 "next" [0066] + rseg CODE +code_base: + extern _heap_of_memory + extern _last_heap_object + extern _make_new_mem_hole + extern _top_of_heap + extern free + extern malloc + public realloc +realloc equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0F2h,0FFh,0FDh,0E5h,02Ah + defw LWRD _heap_of_memory + defb 0DDh,075h,0F6h,0DDh,074h,0F7h,0DDh + defb 06Eh,002h,0DDh,066h,003h,0DDh,075h + defb 0F2h,0DDh,074h,0F3h,07Dh,0B4h,020h + defb 00Dh,059h,050h,03Eh + defb BYTE3 malloc + defb 021h + defw LWRD malloc + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C3h + defw LWRD code_base+00245h + defb 079h,0B0h,020h,00Dh,05Dh,054h,03Eh + defb BYTE3 free + defb 021h + defw LWRD free + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0C3h + defw LWRD code_base+00242h + defb 0EDh,04Bh + defw LWRD _last_heap_object + defb 0DDh,06Eh,0F6h,0DDh,066h,0F7h,0A7h + defb 0EDh,042h,0D2h + defw LWRD code_base+00242h + defb 0DDh,06Eh,0F6h,0DDh,066h,0F7h,023h + defb 023h,023h,0DDh,04Eh,0F2h,0DDh,046h + defb 0F3h,0A7h,0EDh,042h,0DDh,06Eh,0F6h + defb 0DDh,066h,0F7h,0C2h + defw LWRD code_base+00235h + defb 0E5h,0FDh,0E1h,0AFh,0B6h,0CAh + defw LWRD code_base+00242h + defb 0FDh,06Eh,001h,0FDh,066h,002h,0EDh + defb 042h,04Dh,044h,0DDh,06Eh,004h,0DDh + defb 066h,005h,0A7h,0EDh,042h,030h,06Eh + defb 0FDh,06Eh,001h,0FDh,066h,002h,0EDh + defb 04Bh + defw LWRD _last_heap_object + defb 0A7h,0EDh,042h,020h,018h,0DDh,06Eh + defb 004h,0DDh,066h,005h,0DDh,04Eh,0F2h + defb 0DDh,046h,0F3h,009h,0FDh,075h,001h + defb 0FDh,074h,002h,022h + defw LWRD _last_heap_object + defb 018h,044h,0FDh,06Eh,001h,0DDh,075h + defb 0F4h,0FDh,066h,002h,0DDh,074h,0F5h + defb 0AFh,0B6h,0DDh,06Eh,004h,0DDh,066h + defb 005h,0DDh,04Eh,0F2h,0DDh,046h,0F3h + defb 009h,020h,024h,0FDh,075h,001h,0FDh + defb 074h,002h,0FDh,06Eh,001h,0FDh,066h + defb 002h,0E5h,0FDh,0E1h,0FDh,077h,000h + defb 0DDh,06Eh,0F4h,0DDh + defb 066h,0F5h,023h,046h,0FDh,070h,001h + defb 023h,066h,0FDh,074h,002h,018h,003h + defb 0CDh + defw LWRD code_base+0024Ah + defb 0C3h + defw LWRD code_base+0022Dh + defb 0DDh,04Eh,0F2h,0DDh,046h,0F3h,0FDh + defb 06Eh,001h,0FDh,066h,002h,0EDh,042h + defb 0DDh,04Eh,004h,0DDh,046h,005h,0A7h + defb 0EDh,042h,0D2h + defw LWRD code_base+0022Dh + defb 0FDh,06Eh,001h,0FDh,066h,002h,0EDh + defb 04Bh + defw LWRD _last_heap_object + defb 0A7h,0EDh,042h,020h,035h,0DDh,06Eh + defb 004h,0DDh,066h,005h,0DDh,04Eh,0F2h + defb 0DDh,046h,0F3h,009h,04Dh,044h,02Ah + defw LWRD _top_of_heap + defb 0A7h,0EDh,042h,038h,018h,0DDh,06Eh + defb 004h,0DDh,066h,005h,0DDh,04Eh,0F2h + defb 0DDh,046h,0F3h,009h,0FDh,075h,001h + defb 0FDh,074h,002h,022h + defw LWRD _last_heap_object + defb 018h,003h,0C3h + defw LWRD code_base+00242h + defb 0C3h + defw LWRD code_base+0022Dh + defb 0FDh,06Eh,001h,0DDh,075h,0F4h,0FDh + defb 066h,002h,0DDh,074h,0F5h,0AFh,0B6h + defb 020h,03Dh,0DDh,04Eh,0F2h,0DDh,046h + defb 0F3h,023h,056h,023h,066h,06Ah,0EDh + defb 042h,04Dh,044h,0DDh,06Eh,004h,0DDh + defb 066h,005h,0A7h,0EDh,042h,030h,023h + defb 0DDh,06Eh,0F4h,0DDh,066h,0F5h,023h + defb 046h,0FDh,070h,001h + defb 023h,066h,0FDh,074h,002h,0DDh,06Eh + defb 004h,0DDh,066h,005h,0DDh,04Eh,0F2h + defb 0DDh,046h,0F3h,009h,0CDh + defw LWRD code_base+0024Ah + defb 0C3h + defw LWRD code_base+0022Dh + defb 0DDh,05Eh,004h,0DDh,056h,005h,03Eh + defb BYTE3 malloc + defb 021h + defw LWRD malloc + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,075h,0FAh,0DDh,074h,0FBh,07Dh + defb 0B4h,028h,074h,0DDh,04Eh,0F2h,0DDh + defb 046h,0F3h,0FDh,06Eh,001h,0FDh,066h + defb 002h,0EDh,042h,0DDh,075h,0F8h,0DDh + defb 074h,0F9h,0DDh,06Eh,0FAh,0DDh,066h + defb 0FBh,0DDh,075h,0FCh,0DDh,074h,0FDh + defb 0DDh,071h,0FEh,0DDh,070h,0FFh,0DDh + defb 06Eh,0F8h,0DDh,066h + defb 0F9h,02Bh,0DDh,075h,0F8h,0DDh,074h + defb 0F9h,023h,07Dh,0B4h,028h,020h,0DDh + defb 06Eh,0FEh,0DDh,066h,0FFh,023h,0DDh + defb 075h,0FEh,0DDh,074h,0FFh,02Bh,046h + defb 0DDh,06Eh,0FCh,0DDh,066h,0FDh,023h + defb 0DDh,075h,0FCh,0DDh,074h,0FDh,02Bh + defb 070h,018h,0CEh,0DDh,05Eh,0F2h,0DDh + defb 056h,0F3h,03Eh + defb BYTE3 free + defb 021h + defw LWRD free + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0DDh,06Eh,0FAh,0DDh,066h,0FBh,0DDh + defb 075h,0F2h,0DDh,074h,0F3h,018h,002h + defb 018h,015h,0DDh,06Eh,0F2h,0DDh,066h + defb 0F3h,018h,010h,023h,046h,0DDh,070h + defb 0F6h,023h,066h,0DDh,074h,0F7h,0C3h + defw LWRD code_base+0003Eh + defb 021h,000h,000h,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + defb 04Dh,044h,0FDh,0E5h,0D1h,03Eh + defb BYTE3 _make_new_mem_hole + defb 021h + defw LWRD _make_new_mem_hole + defb 0C3h + defw LWRD ?BANK_CALL_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/satan.asm b/src/libiar/satan.asm new file mode 100755 index 00000000..f87991ba --- /dev/null +++ b/src/libiar/satan.asm @@ -0,0 +1,97 @@ +; satan.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module satan + rseg CODE +code_base: + public __satan +__satan equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?SL_CMP_L03 + extern ?F_MUL_L04 + extern ?F_DIV_L04 + extern ?F_ADD_L04 + extern ?F_MULASG_L04 + extern ?BANK_LEAVE_32_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 0F8h,0FFh,0DDh,06Eh,002h,0DDh,066h + defb 003h,0CBh,0B8h,0DDh,070h,005h,0C5h + defb 0E5h,001h,080h,03Fh,021h,000h,000h + defb 0CDh + defw LWRD ?SL_CMP_L03 + defb 038h,032h,0DDh,06Eh,002h,0DDh,066h + defb 003h,001h,000h,000h,0EDh,042h,020h + defb 016h,0DDh,06Eh,004h,0DDh,066h,005h + defb 001h,080h,03Fh,0EDh,042h,020h,009h + defb 001h,049h,03Fh,021h,0DBh,00Fh,0C3h + defw LWRD code_base+00120h + defb 0AFh,0DDh,077h,0FCh,0DDh,077h,0FDh + defb 0DDh,077h,0FEh,0DDh,077h,0FFh,018h + defb 031h,0C5h,0E5h,0CDh + defw LWRD code_base+00123h + defb 0C5h,0E5h,021h,080h,0BFh,0E5h,021h + defb 000h,000h,0E5h,0CDh + defw LWRD code_base+00123h + defb 0CDh + defw LWRD ?F_DIV_L04 + defb 0DDh,075h,002h,0DDh,074h,003h,0DDh + defb 071h,004h,0DDh,070h,005h,0DDh,036h + defb 0FCh,0DBh,0DDh,036h,0FDh,00Fh,0DDh + defb 036h,0FEh,049h,0DDh,036h,0FFh,03Fh + defb 0DDh,06Eh,004h,0DDh,066h,005h,0E5h + defb 0DDh,06Eh,002h,0DDh,066h,003h,0E5h + defb 0DDh,04Eh,004h,0DDh,046h,005h,0CDh + defw LWRD ?F_MUL_L04 + defb 0DDh,075h,0F8h,0DDh,074h,0F9h,0DDh + defb 071h,0FAh,0DDh,070h,0FBh,021h,00Ah + defb 000h,039h,0E5h,001h,086h,040h,0C5h + defb 001h,0EAh,0B4h,0C5h,0DDh,04Eh,0FAh + defb 0DDh,046h,0FBh,0DDh,06Eh,0F8h,0DDh + defb 066h,0F9h,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+00132h + defb 0C5h,0E5h,001h,068h,040h,021h,0B6h + defb 0FDh,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,021h,02Bh,0BCh,0E5h,021h + defb 024h,0FFh,0E5h,0CDh + defw LWRD code_base+00132h + defb 0C5h,0E5h,001h,0A6h,03Eh,021h,088h + defb 044h,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+00132h + defb 0C5h,0E5h,001h,03Fh,040h,021h,018h + defb 0C0h,0CDh + defw LWRD ?F_ADD_L04 + defb 0C5h,0E5h,0CDh + defw LWRD code_base+00132h + defb 0C5h,0E5h,001h,068h,040h,021h,0B5h + defb 0FDh,0CDh + defw LWRD ?F_ADD_L04 + defb 0CDh + defw LWRD ?F_DIV_L04 + defb 0EBh,0E1h,0CDh + defw LWRD ?F_MULASG_L04 + defb 0C5h,0D5h,0DDh,04Eh,0FEh,0DDh,046h + defb 0FFh,0DDh,06Eh,0FCh,0DDh,066h,0FDh + defb 0CDh + defw LWRD ?F_ADD_L04 + defb 0C3h + defw LWRD ?BANK_LEAVE_32_L08 + defb 0DDh,04Eh,004h,0DDh,046h,005h,0DDh + defb 06Eh,002h,0DDh,066h,003h,0C3h + defw LWRD ?F_ADD_L04 + defb 0DDh,04Eh,0FAh,0DDh,046h,0FBh,0DDh + defb 06Eh,0F8h,0DDh,066h,0F9h,0C3h + defw LWRD ?F_MUL_L04 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/scanf.asm b/src/libiar/scanf.asm new file mode 100755 index 00000000..a29b80cd --- /dev/null +++ b/src/libiar/scanf.asm @@ -0,0 +1,59 @@ +; scanf.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module scanf + rseg CODE +code_base: + extern _formatted_read + extern gets + public scanf +scanf equ code_base+00000000h + extern ?CL64180B_4_06_L00 + extern ?BANK_CALL_DIRECT_L08 + extern ?BANK_LEAVE_DIRECT_L08 + extern ?BANK_FAST_LEAVE_L08 + extern ?ENT_AUTO_DIRECT_L09 + defb 0CDh + defw LWRD ?ENT_AUTO_DIRECT_L09 + defb 07Ch,0FFh,0FDh,0E5h,0FDh,021h,000h + defb 000h,021h,002h,000h,039h,0E5h,021h + defb 008h,000h,039h,04Dh,044h,0E1h,0CDh + defw LWRD code_base+0009Dh + defb 07Dh,0B4h,028h,077h,021h,004h,000h + defb 039h,0E5h,021h,092h,000h,039h,001h + defb 002h,000h,009h,04Dh,044h,0E1h,071h + defb 023h,070h,021h,002h,000h,039h,07Eh + defb 023h,066h,06Fh,0AFh,0B6h,028h,01Dh + defb 021h,004h,000h,039h,0E5h,021h,092h + defb 000h,039h,04Dh,044h,021h,004h,000h + defb 039h,0EBh,03Eh + defb BYTE3 _formatted_read + defb 021h + defw LWRD _formatted_read + defb 0CDh + defw LWRD ?BANK_CALL_DIRECT_L08 + defb 0F1h,04Dh,044h,0FDh,009h,0DDh,06Eh + defb 00Ah,0DDh,066h,00Bh,0AFh,0B6h,028h + defb 022h,021h,002h,000h,039h,07Eh,023h + defb 066h,06Fh,0AFh,0B6h,020h,016h,021h + defb 002h,000h,039h,0E5h,021h,008h,000h + defb 039h,04Dh,044h,0E1h,0CDh + defw LWRD code_base+0009Dh + defb 07Dh,0B4h,020h,003h,0DDh,077h,080h + defb 0DDh,06Eh,00Ah,0DDh,066h,00Bh,0AFh + defb 0B6h,020h,0A1h,0FDh,0E5h,0E1h,018h + defb 003h,021h,0FFh,0FFh,0FDh,0E1h,0C3h + defw LWRD ?BANK_LEAVE_DIRECT_L08 + defb 071h,023h,070h,059h,050h,03Eh + defb BYTE3 gets + defb 021h + defw LWRD gets + defb 0C3h + defw LWRD ?BANK_CALL_DIRECT_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/setjmp.asm b/src/libiar/setjmp.asm new file mode 100755 index 00000000..1d560f3a --- /dev/null +++ b/src/libiar/setjmp.asm @@ -0,0 +1,23 @@ +; setjmp.asm +; Nick's reverse engineered subset of the IAR banked 'C' library + +; ----------------------------------------------------------------------------- + + module setjmp + rseg CODE +code_base: + public setjmp +setjmp equ code_base+00000000h + extern ?BANK_FAST_LEAVE_L08 + defb 021h,004h,000h,039h,0EBh,073h,023h + defb 072h,023h,071h,023h,070h,023h,0DDh + defb 0E5h,0D1h,073h,023h,072h,023h,0FDh + defb 0E5h,0D1h,073h,023h,072h,023h,0F1h + defb 0D1h,0D5h,0F5h,073h,023h,072h,023h + defb 077h,021h,000h,000h,0C3h + defw LWRD ?BANK_FAST_LEAVE_L08 + endmod + +; ----------------------------------------------------------------------------- + + end diff --git a/src/libiar/silly.zip b/src/libiar/silly.zip new file mode 100755 index 0000000000000000000000000000000000000000..b52cc16131a4f7d24bbd8271ea300be9220523c8 GIT binary patch literal 158858 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

c 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 + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +------------------------------------------------------------------------------ + + \ No newline at end of file diff --git a/src/libsys/_exit.c b/src/libsys/_exit.c new file mode 100755 index 00000000..c0c28714 --- /dev/null +++ b/src/libsys/_exit.c @@ -0,0 +1,27 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIXV _exit(int val); */ + +#include "syscalls.h" + +#ifdef L_exit +#ifndef HI_TECH_C +UNIXV _exit(int val) + { +#if 0 + _AX = '~'; + geninterrupt(0x29); + _AX = 'x'; + geninterrupt(0x29); +#endif + unix(11, val); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global __exit"); + asm(" signat __exit,4152"); + asm("__exit:"); + asm(" ld hl,11"); + asm(" jp __sys__1"); +#endif +#endif diff --git a/src/libsys/access.c b/src/libsys/access.c new file mode 100755 index 00000000..85eedc28 --- /dev/null +++ b/src/libsys/access.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX access(char *path, int mode); */ + +#include "syscalls.h" + +#ifdef L_access +#ifndef HI_TECH_C +UNIX access(char *path, int mode) + { + return unix(0, path, mode); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _access"); + asm(" signat _access,8250"); + asm("_access:"); + asm(" ld hl,0"); + asm(" jp __sys__2"); +#endif +#endif + + diff --git a/src/libsys/alarm.c b/src/libsys/alarm.c new file mode 100755 index 00000000..3eecc0c5 --- /dev/null +++ b/src/libsys/alarm.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX alarm(uint secs); */ + +#include "syscalls.h" + +#ifdef L_alarm +#ifndef HI_TECH_C +UNIX alarm(uint secs) + { + return unix(1, secs); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _alarm"); + asm(" signat _alarm,4154"); + asm("_alarm:"); + asm(" ld hl,1"); + asm(" jp __sys__1"); +#endif +#endif + + diff --git a/src/libsys/brk.c b/src/libsys/brk.c new file mode 100755 index 00000000..23531c1e --- /dev/null +++ b/src/libsys/brk.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX brk(char *addr); */ + +#include "syscalls.h" + +#ifdef L_brk +#ifndef HI_TECH_C +UNIX brk(char *addr) + { + return unix(2, addr); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _brk"); + asm(" signat _brk,4154"); + asm("_brk:"); + asm(" ld hl,2"); + asm(" jp __sys__1"); +#endif +#endif diff --git a/src/libsys/build-b.ban b/src/libsys/build-b.ban new file mode 100755 index 00000000..e834b895 --- /dev/null +++ b/src/libsys/build-b.ban @@ -0,0 +1,410 @@ +copy ..\libsysb.lib ..\..\..\lib + +copy ..\sys0b.asm sys0b.s01 +as-z80 -l -o sys0b.s01 +@if errorlevel 1 goto failure +copy sys0b.rel ..\..\..\lib\relsysb + +copy ..\sys1b.asm sys1b.s01 +as-z80 -l -o sys1b.s01 +@if errorlevel 1 goto failure +copy sys1b.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_access ..\access +@if errorlevel 1 goto failure +del access.r01 +as-z80 -l -o access.s01 +@if errorlevel 1 goto failure +copy access.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_alarm ..\alarm +@if errorlevel 1 goto failure +del alarm.r01 +as-z80 -l -o alarm.s01 +@if errorlevel 1 goto failure +copy alarm.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_brk ..\brk +@if errorlevel 1 goto failure +del brk.r01 +as-z80 -l -o brk.s01 +@if errorlevel 1 goto failure +copy brk.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_chdir ..\chdir +@if errorlevel 1 goto failure +del chdir.r01 +as-z80 -l -o chdir.s01 +@if errorlevel 1 goto failure +copy chdir.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_chmod ..\chmod +@if errorlevel 1 goto failure +del chmod.r01 +as-z80 -l -o chmod.s01 +@if errorlevel 1 goto failure +copy chmod.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_chown ..\chown +@if errorlevel 1 goto failure +del chown.r01 +as-z80 -l -o chown.s01 +@if errorlevel 1 goto failure +copy chown.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_chroot ..\chroot +@if errorlevel 1 goto failure +del chroot.r01 +as-z80 -l -o chroot.s01 +@if errorlevel 1 goto failure +copy chroot.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_close ..\close +@if errorlevel 1 goto failure +del close.r01 +as-z80 -l -o close.s01 +@if errorlevel 1 goto failure +copy close.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_creat ..\creat +@if errorlevel 1 goto failure +del creat.r01 +as-z80 -l -o creat.s01 +@if errorlevel 1 goto failure +copy creat.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_dup ..\dup +@if errorlevel 1 goto failure +del dup.r01 +as-z80 -l -o dup.s01 +@if errorlevel 1 goto failure +copy dup.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_dup2 ..\dup2 +@if errorlevel 1 goto failure +del dup2.r01 +as-z80 -l -o dup2.s01 +@if errorlevel 1 goto failure +copy dup2.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execve ..\execve +@if errorlevel 1 goto failure +del execve.r01 +as-z80 -l -o execve.s01 +@if errorlevel 1 goto failure +copy execve.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H__exit ..\_exit +@if errorlevel 1 goto failure +del _exit.r01 +as-z80 -l -o _exit.s01 +@if errorlevel 1 goto failure +copy _exit.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fork ..\fork +@if errorlevel 1 goto failure +del fork.r01 +as-z80 -l -o fork.s01 +@if errorlevel 1 goto failure +copy fork.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_falign ..\falign +@if errorlevel 1 goto failure +del falign.r01 +as-z80 -l -o falign.s01 +@if errorlevel 1 goto failure +copy falign.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fstat ..\fstat +@if errorlevel 1 goto failure +del fstat.r01 +as-z80 -l -o fstat.s01 +@if errorlevel 1 goto failure +copy fstat.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getegid ..\getegid +@if errorlevel 1 goto failure +del getegid.r01 +as-z80 -l -o getegid.s01 +@if errorlevel 1 goto failure +copy getegid.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_geteuid ..\geteuid +@if errorlevel 1 goto failure +del geteuid.r01 +as-z80 -l -o geteuid.s01 +@if errorlevel 1 goto failure +copy geteuid.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getfsys ..\getfsys +@if errorlevel 1 goto failure +del getfsys.r01 +as-z80 -l -o getfsys.s01 +@if errorlevel 1 goto failure +copy getfsys.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getgid ..\getgid +@if errorlevel 1 goto failure +del getgid.r01 +as-z80 -l -o getgid.s01 +@if errorlevel 1 goto failure +copy getgid.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpid ..\getpid +@if errorlevel 1 goto failure +del getpid.r01 +as-z80 -l -o getpid.s01 +@if errorlevel 1 goto failure +copy getpid.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getppid ..\getppid +@if errorlevel 1 goto failure +del getppid.r01 +as-z80 -l -o getppid.s01 +@if errorlevel 1 goto failure +copy getppid.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getprio ..\getprio +@if errorlevel 1 goto failure +del getprio.r01 +as-z80 -l -o getprio.s01 +@if errorlevel 1 goto failure +copy getprio.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getuid ..\getuid +@if errorlevel 1 goto failure +del getuid.r01 +as-z80 -l -o getuid.s01 +@if errorlevel 1 goto failure +copy getuid.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ioctl ..\ioctl +@if errorlevel 1 goto failure +del ioctl.r01 +as-z80 -l -o ioctl.s01 +@if errorlevel 1 goto failure +copy ioctl.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_kill ..\kill +@if errorlevel 1 goto failure +del kill.r01 +as-z80 -l -o kill.s01 +@if errorlevel 1 goto failure +copy kill.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_link ..\link +@if errorlevel 1 goto failure +del link.r01 +as-z80 -l -o link.s01 +@if errorlevel 1 goto failure +copy link.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_seek ..\seek +@if errorlevel 1 goto failure +del seek.r01 +as-z80 -l -o seek.s01 +@if errorlevel 1 goto failure +copy seek.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_lseek ..\lseek +@if errorlevel 1 goto failure +del lseek.r01 +as-z80 -l -o lseek.s01 +@if errorlevel 1 goto failure +copy lseek.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mkfifo ..\mkfifo +@if errorlevel 1 goto failure +del mkfifo.r01 +as-z80 -l -o mkfifo.s01 +@if errorlevel 1 goto failure +copy mkfifo.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mknod ..\mknod +@if errorlevel 1 goto failure +del mknod.r01 +as-z80 -l -o mknod.s01 +@if errorlevel 1 goto failure +copy mknod.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_module ..\module +@if errorlevel 1 goto failure +del module.r01 +as-z80 -l -o module.s01 +@if errorlevel 1 goto failure +copy module.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mount ..\mount +@if errorlevel 1 goto failure +del mount.r01 +as-z80 -l -o mount.s01 +@if errorlevel 1 goto failure +copy mount.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_open ..\open +@if errorlevel 1 goto failure +del open.r01 +as-z80 -l -o open.s01 +@if errorlevel 1 goto failure +copy open.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_pause ..\pause +@if errorlevel 1 goto failure +del pause.r01 +as-z80 -l -o pause.s01 +@if errorlevel 1 goto failure +copy pause.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_pipe ..\pipe +@if errorlevel 1 goto failure +del pipe.r01 +as-z80 -l -o pipe.s01 +@if errorlevel 1 goto failure +copy pipe.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_read ..\read +@if errorlevel 1 goto failure +del read.r01 +as-z80 -l -o read.s01 +@if errorlevel 1 goto failure +copy read.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_reboot ..\reboot +@if errorlevel 1 goto failure +del reboot.r01 +as-z80 -l -o reboot.s01 +@if errorlevel 1 goto failure +copy reboot.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sbrk ..\sbrk +@if errorlevel 1 goto failure +del sbrk.r01 +as-z80 -l -o sbrk.s01 +@if errorlevel 1 goto failure +copy sbrk.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setgid ..\setgid +@if errorlevel 1 goto failure +del setgid.r01 +as-z80 -l -o setgid.s01 +@if errorlevel 1 goto failure +copy setgid.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setprio ..\setprio +@if errorlevel 1 goto failure +del setprio.r01 +as-z80 -l -o setprio.s01 +@if errorlevel 1 goto failure +copy setprio.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setuid ..\setuid +@if errorlevel 1 goto failure +del setuid.r01 +as-z80 -l -o setuid.s01 +@if errorlevel 1 goto failure +copy setuid.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_signal ..\signal +@if errorlevel 1 goto failure +del signal.r01 +as-z80 -l -o signal.s01 +@if errorlevel 1 goto failure +copy signal.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_stat ..\stat +@if errorlevel 1 goto failure +del stat.r01 +as-z80 -l -o stat.s01 +@if errorlevel 1 goto failure +copy stat.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_stime ..\stime +@if errorlevel 1 goto failure +del stime.r01 +as-z80 -l -o stime.s01 +@if errorlevel 1 goto failure +copy stime.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_symlink ..\symlink +@if errorlevel 1 goto failure +del symlink.r01 +as-z80 -l -o symlink.s01 +@if errorlevel 1 goto failure +copy symlink.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sync ..\sync +@if errorlevel 1 goto failure +del sync.r01 +as-z80 -l -o sync.s01 +@if errorlevel 1 goto failure +copy sync.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_systrace ..\systrace +@if errorlevel 1 goto failure +del systrace.r01 +as-z80 -l -o systrace.s01 +@if errorlevel 1 goto failure +copy systrace.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_time ..\time +@if errorlevel 1 goto failure +del time.r01 +as-z80 -l -o time.s01 +@if errorlevel 1 goto failure +copy time.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_times ..\times +@if errorlevel 1 goto failure +del times.r01 +as-z80 -l -o times.s01 +@if errorlevel 1 goto failure +copy times.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_umask ..\umask +@if errorlevel 1 goto failure +del umask.r01 +as-z80 -l -o umask.s01 +@if errorlevel 1 goto failure +copy umask.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_umount ..\umount +@if errorlevel 1 goto failure +del umount.r01 +as-z80 -l -o umount.s01 +@if errorlevel 1 goto failure +copy umount.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_unlink ..\unlink +@if errorlevel 1 goto failure +del unlink.r01 +as-z80 -l -o unlink.s01 +@if errorlevel 1 goto failure +copy unlink.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_utime ..\utime +@if errorlevel 1 goto failure +del utime.r01 +as-z80 -l -o utime.s01 +@if errorlevel 1 goto failure +copy utime.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_waitpid ..\waitpid +@if errorlevel 1 goto failure +del waitpid.r01 +as-z80 -l -o waitpid.s01 +@if errorlevel 1 goto failure +copy waitpid.rel ..\..\..\lib\relsysb + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_write ..\write +@if errorlevel 1 goto failure +del write.r01 +as-z80 -l -o write.s01 +@if errorlevel 1 goto failure +copy write.rel ..\..\..\lib\relsysb + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/libsys/build-l.ban b/src/libsys/build-l.ban new file mode 100755 index 00000000..da32baa5 --- /dev/null +++ b/src/libsys/build-l.ban @@ -0,0 +1,410 @@ +copy ..\libsysl.lib ..\..\..\lib + +copy ..\sys0l.asm sys0l.s01 +as-z80 -l -o sys0l.s01 +@if errorlevel 1 goto failure +copy sys0l.rel ..\..\..\lib\relsysl + +copy ..\sys1l.asm sys1l.s01 +as-z80 -l -o sys1l.s01 +@if errorlevel 1 goto failure +copy sys1l.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_access ..\access +@if errorlevel 1 goto failure +del access.r01 +as-z80 -l -o access.s01 +@if errorlevel 1 goto failure +copy access.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_alarm ..\alarm +@if errorlevel 1 goto failure +del alarm.r01 +as-z80 -l -o alarm.s01 +@if errorlevel 1 goto failure +copy alarm.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_brk ..\brk +@if errorlevel 1 goto failure +del brk.r01 +as-z80 -l -o brk.s01 +@if errorlevel 1 goto failure +copy brk.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_chdir ..\chdir +@if errorlevel 1 goto failure +del chdir.r01 +as-z80 -l -o chdir.s01 +@if errorlevel 1 goto failure +copy chdir.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_chmod ..\chmod +@if errorlevel 1 goto failure +del chmod.r01 +as-z80 -l -o chmod.s01 +@if errorlevel 1 goto failure +copy chmod.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_chown ..\chown +@if errorlevel 1 goto failure +del chown.r01 +as-z80 -l -o chown.s01 +@if errorlevel 1 goto failure +copy chown.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_chroot ..\chroot +@if errorlevel 1 goto failure +del chroot.r01 +as-z80 -l -o chroot.s01 +@if errorlevel 1 goto failure +copy chroot.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_close ..\close +@if errorlevel 1 goto failure +del close.r01 +as-z80 -l -o close.s01 +@if errorlevel 1 goto failure +copy close.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_creat ..\creat +@if errorlevel 1 goto failure +del creat.r01 +as-z80 -l -o creat.s01 +@if errorlevel 1 goto failure +copy creat.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_dup ..\dup +@if errorlevel 1 goto failure +del dup.r01 +as-z80 -l -o dup.s01 +@if errorlevel 1 goto failure +copy dup.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_dup2 ..\dup2 +@if errorlevel 1 goto failure +del dup2.r01 +as-z80 -l -o dup2.s01 +@if errorlevel 1 goto failure +copy dup2.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_execve ..\execve +@if errorlevel 1 goto failure +del execve.r01 +as-z80 -l -o execve.s01 +@if errorlevel 1 goto failure +copy execve.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H__exit ..\_exit +@if errorlevel 1 goto failure +del _exit.r01 +as-z80 -l -o _exit.s01 +@if errorlevel 1 goto failure +copy _exit.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fork ..\fork +@if errorlevel 1 goto failure +del fork.r01 +as-z80 -l -o fork.s01 +@if errorlevel 1 goto failure +copy fork.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_falign ..\falign +@if errorlevel 1 goto failure +del falign.r01 +as-z80 -l -o falign.s01 +@if errorlevel 1 goto failure +copy falign.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_fstat ..\fstat +@if errorlevel 1 goto failure +del fstat.r01 +as-z80 -l -o fstat.s01 +@if errorlevel 1 goto failure +copy fstat.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getegid ..\getegid +@if errorlevel 1 goto failure +del getegid.r01 +as-z80 -l -o getegid.s01 +@if errorlevel 1 goto failure +copy getegid.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_geteuid ..\geteuid +@if errorlevel 1 goto failure +del geteuid.r01 +as-z80 -l -o geteuid.s01 +@if errorlevel 1 goto failure +copy geteuid.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getfsys ..\getfsys +@if errorlevel 1 goto failure +del getfsys.r01 +as-z80 -l -o getfsys.s01 +@if errorlevel 1 goto failure +copy getfsys.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getgid ..\getgid +@if errorlevel 1 goto failure +del getgid.r01 +as-z80 -l -o getgid.s01 +@if errorlevel 1 goto failure +copy getgid.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getpid ..\getpid +@if errorlevel 1 goto failure +del getpid.r01 +as-z80 -l -o getpid.s01 +@if errorlevel 1 goto failure +copy getpid.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getppid ..\getppid +@if errorlevel 1 goto failure +del getppid.r01 +as-z80 -l -o getppid.s01 +@if errorlevel 1 goto failure +copy getppid.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getprio ..\getprio +@if errorlevel 1 goto failure +del getprio.r01 +as-z80 -l -o getprio.s01 +@if errorlevel 1 goto failure +copy getprio.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_getuid ..\getuid +@if errorlevel 1 goto failure +del getuid.r01 +as-z80 -l -o getuid.s01 +@if errorlevel 1 goto failure +copy getuid.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_ioctl ..\ioctl +@if errorlevel 1 goto failure +del ioctl.r01 +as-z80 -l -o ioctl.s01 +@if errorlevel 1 goto failure +copy ioctl.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_kill ..\kill +@if errorlevel 1 goto failure +del kill.r01 +as-z80 -l -o kill.s01 +@if errorlevel 1 goto failure +copy kill.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_link ..\link +@if errorlevel 1 goto failure +del link.r01 +as-z80 -l -o link.s01 +@if errorlevel 1 goto failure +copy link.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_seek ..\seek +@if errorlevel 1 goto failure +del seek.r01 +as-z80 -l -o seek.s01 +@if errorlevel 1 goto failure +copy seek.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_lseek ..\lseek +@if errorlevel 1 goto failure +del lseek.r01 +as-z80 -l -o lseek.s01 +@if errorlevel 1 goto failure +copy lseek.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mkfifo ..\mkfifo +@if errorlevel 1 goto failure +del mkfifo.r01 +as-z80 -l -o mkfifo.s01 +@if errorlevel 1 goto failure +copy mkfifo.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mknod ..\mknod +@if errorlevel 1 goto failure +del mknod.r01 +as-z80 -l -o mknod.s01 +@if errorlevel 1 goto failure +copy mknod.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_module ..\module +@if errorlevel 1 goto failure +del module.r01 +as-z80 -l -o module.s01 +@if errorlevel 1 goto failure +copy module.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_mount ..\mount +@if errorlevel 1 goto failure +del mount.r01 +as-z80 -l -o mount.s01 +@if errorlevel 1 goto failure +copy mount.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_open ..\open +@if errorlevel 1 goto failure +del open.r01 +as-z80 -l -o open.s01 +@if errorlevel 1 goto failure +copy open.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_pause ..\pause +@if errorlevel 1 goto failure +del pause.r01 +as-z80 -l -o pause.s01 +@if errorlevel 1 goto failure +copy pause.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_pipe ..\pipe +@if errorlevel 1 goto failure +del pipe.r01 +as-z80 -l -o pipe.s01 +@if errorlevel 1 goto failure +copy pipe.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_read ..\read +@if errorlevel 1 goto failure +del read.r01 +as-z80 -l -o read.s01 +@if errorlevel 1 goto failure +copy read.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_reboot ..\reboot +@if errorlevel 1 goto failure +del reboot.r01 +as-z80 -l -o reboot.s01 +@if errorlevel 1 goto failure +copy reboot.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sbrk ..\sbrk +@if errorlevel 1 goto failure +del sbrk.r01 +as-z80 -l -o sbrk.s01 +@if errorlevel 1 goto failure +copy sbrk.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setgid ..\setgid +@if errorlevel 1 goto failure +del setgid.r01 +as-z80 -l -o setgid.s01 +@if errorlevel 1 goto failure +copy setgid.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setprio ..\setprio +@if errorlevel 1 goto failure +del setprio.r01 +as-z80 -l -o setprio.s01 +@if errorlevel 1 goto failure +copy setprio.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_setuid ..\setuid +@if errorlevel 1 goto failure +del setuid.r01 +as-z80 -l -o setuid.s01 +@if errorlevel 1 goto failure +copy setuid.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_signal ..\signal +@if errorlevel 1 goto failure +del signal.r01 +as-z80 -l -o signal.s01 +@if errorlevel 1 goto failure +copy signal.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_stat ..\stat +@if errorlevel 1 goto failure +del stat.r01 +as-z80 -l -o stat.s01 +@if errorlevel 1 goto failure +copy stat.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_stime ..\stime +@if errorlevel 1 goto failure +del stime.r01 +as-z80 -l -o stime.s01 +@if errorlevel 1 goto failure +copy stime.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_symlink ..\symlink +@if errorlevel 1 goto failure +del symlink.r01 +as-z80 -l -o symlink.s01 +@if errorlevel 1 goto failure +copy symlink.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_sync ..\sync +@if errorlevel 1 goto failure +del sync.r01 +as-z80 -l -o sync.s01 +@if errorlevel 1 goto failure +copy sync.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_systrace ..\systrace +@if errorlevel 1 goto failure +del systrace.r01 +as-z80 -l -o systrace.s01 +@if errorlevel 1 goto failure +copy systrace.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_time ..\time +@if errorlevel 1 goto failure +del time.r01 +as-z80 -l -o time.s01 +@if errorlevel 1 goto failure +copy time.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_times ..\times +@if errorlevel 1 goto failure +del times.r01 +as-z80 -l -o times.s01 +@if errorlevel 1 goto failure +copy times.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_umask ..\umask +@if errorlevel 1 goto failure +del umask.r01 +as-z80 -l -o umask.s01 +@if errorlevel 1 goto failure +copy umask.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_umount ..\umount +@if errorlevel 1 goto failure +del umount.r01 +as-z80 -l -o umount.s01 +@if errorlevel 1 goto failure +copy umount.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_unlink ..\unlink +@if errorlevel 1 goto failure +del unlink.r01 +as-z80 -l -o unlink.s01 +@if errorlevel 1 goto failure +copy unlink.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_utime ..\utime +@if errorlevel 1 goto failure +del utime.r01 +as-z80 -l -o utime.s01 +@if errorlevel 1 goto failure +copy utime.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_waitpid ..\waitpid +@if errorlevel 1 goto failure +del waitpid.r01 +as-z80 -l -o waitpid.s01 +@if errorlevel 1 goto failure +copy waitpid.rel ..\..\..\lib\relsysl + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DMAKE_ALL -H_write ..\write +@if errorlevel 1 goto failure +del write.r01 +as-z80 -l -o write.s01 +@if errorlevel 1 goto failure +copy write.rel ..\..\..\lib\relsysl + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/libsys/chdir.c b/src/libsys/chdir.c new file mode 100755 index 00000000..aefceb8a --- /dev/null +++ b/src/libsys/chdir.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX chdir(char *dir); */ + +#include "syscalls.h" + +#ifdef L_chdir +#ifndef HI_TECH_C +UNIX chdir(char *dir) + { + return unix(3, dir); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _chdir"); + asm(" signat _chdir,4154"); + asm("_chdir:"); + asm(" ld hl,3"); + asm(" jp __sys__1"); +#endif +#endif diff --git a/src/libsys/chmod.c b/src/libsys/chmod.c new file mode 100755 index 00000000..f41fde06 --- /dev/null +++ b/src/libsys/chmod.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX chmod(char *path, mode_t mode); */ + +#include "syscalls.h" + +#ifdef L_chmod +#ifndef HI_TECH_C +UNIX chmod(char *path, mode_t mode) + { + return unix(4, path, mode); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _chmod"); + asm(" signat _chmod,8250"); + asm("_chmod:"); + asm(" ld hl,4"); + asm(" jp __sys__2"); +#endif +#endif diff --git a/src/libsys/chown.c b/src/libsys/chown.c new file mode 100755 index 00000000..99de4f72 --- /dev/null +++ b/src/libsys/chown.c @@ -0,0 +1,24 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX chown(char *path, int owner, int group); */ + +#include "syscalls.h" + +#ifdef L_chown +#ifndef HI_TECH_C +UNIX chown(char *path, int owner, int group) + { + return unix(5, path, owner, group); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__3"); + asm(" global _chown"); + asm(" signat _chown,12346"); + asm("_chown:"); + asm(" pop hl"); + asm(" ex (sp),hl"); + asm(" push hl"); + asm(" ld hl,5"); + asm(" jp __sys__3"); +#endif +#endif diff --git a/src/libsys/chroot.c b/src/libsys/chroot.c new file mode 100755 index 00000000..6431c1f1 --- /dev/null +++ b/src/libsys/chroot.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX chroot(char *dir); */ + +#include "syscalls.h" + +#ifdef L_chroot +#ifndef HI_TECH_C +UNIX chroot(char *dir) + { + return unix(39, dir); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _chroot"); + asm(" signat _chroot,4154"); + asm("_chroot:"); + asm(" ld hl,39"); + asm(" jp __sys__1"); +#endif +#endif diff --git a/src/libsys/close.c b/src/libsys/close.c new file mode 100755 index 00000000..f85d1e66 --- /dev/null +++ b/src/libsys/close.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX close(int uindex); */ + +#include "syscalls.h" + +#ifdef L_close +#ifndef HI_TECH_C +UNIX close(int uindex) + { + return unix(6, uindex); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _close"); + asm(" signat _close,4154"); + asm("_close:"); + asm(" ld hl,6"); + asm(" jp __sys__1"); +#endif +#endif diff --git a/src/libsys/creat.c b/src/libsys/creat.c new file mode 100755 index 00000000..b87df627 --- /dev/null +++ b/src/libsys/creat.c @@ -0,0 +1,17 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX creat(char *name, mode_t mode); */ + +#include "syscalls.h" +#include "fcntl.h" + +/* this was not defined by syscalls.h, because it would break open.c */ +/* here we need to define it as varargs so that IAR will not use regparms */ +extern int open __P((char *name, uint flag, ...)); + +#ifdef L_creat +UNIX creat(char *name, mode_t mode) { + return open(name,O_CREAT|O_WRONLY|O_TRUNC,mode); +} +#endif + + diff --git a/src/libsys/dup.c b/src/libsys/dup.c new file mode 100755 index 00000000..8bc4e5b3 --- /dev/null +++ b/src/libsys/dup.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX dup(int oldd); */ + +#include "syscalls.h" + +#ifdef L_dup +#ifndef HI_TECH_C +UNIX dup(int oldd) + { + return unix(8, oldd); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _dup"); + asm(" signat _dup,4154"); + asm("_dup:"); + asm(" ld hl,8"); + asm(" jp __sys__1"); +#endif +#endif diff --git a/src/libsys/dup2.c b/src/libsys/dup2.c new file mode 100755 index 00000000..bdf85a2d --- /dev/null +++ b/src/libsys/dup2.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX dup2(int oldd, int newd); */ + +#include "syscalls.h" + +#ifdef L_dup2 +#ifndef HI_TECH_C +UNIX dup2(int oldd, int newd) + { + return unix(9, oldd, newd); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _dup2"); + asm(" signat _dup2,8250"); + asm("_dup2:"); + asm(" ld hl,9"); + asm(" jp __sys__2"); +#endif +#endif diff --git a/src/libsys/execve.c b/src/libsys/execve.c new file mode 100755 index 00000000..75a200a9 --- /dev/null +++ b/src/libsys/execve.c @@ -0,0 +1,24 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX execve(char *name, char *argv[], char *envp[]); */ + +#include "syscalls.h" + +#ifdef L_execve +#ifndef HI_TECH_C +UNIX execve(char *name, char *argv[], char *envp[]) + { + return unix(10, name, argv, envp); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__3"); + asm(" global _execve"); + asm(" signat _execve,12346"); + asm("_execve:"); + asm(" pop hl"); + asm(" ex (sp),hl"); + asm(" push hl"); + asm(" ld hl,10"); + asm(" jp __sys__3"); +#endif +#endif diff --git a/src/libsys/falign.c b/src/libsys/falign.c new file mode 100755 index 00000000..f49e76e0 --- /dev/null +++ b/src/libsys/falign.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX falign(int fd, int parm); */ + +#include "syscalls.h" + +#ifdef L_falign +#ifndef HI_TECH_C +UNIX falign(int fd, int parm) + { + return unix(40, fd, parm); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _falign"); + asm(" signat _falign,8250"); + asm("_falign:"); + asm(" ld hl,13"); + asm(" jp __sys__2"); +#endif +#endif diff --git a/src/libsys/fork.c b/src/libsys/fork.c new file mode 100755 index 00000000..bacf269a --- /dev/null +++ b/src/libsys/fork.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX fork(void); */ + +#include "syscalls.h" + +#ifdef L_fork +#ifndef HI_TECH_C +UNIX fork(void) + { + return unix(12); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _fork"); + asm(" signat _fork,26"); + asm("_fork:"); + asm(" ld hl,12"); + asm(" jp __sys__"); +#endif +#endif diff --git a/src/libsys/fstat.c b/src/libsys/fstat.c new file mode 100755 index 00000000..56b671a1 --- /dev/null +++ b/src/libsys/fstat.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX fstat(int fd, void *buf); */ + +#include "syscalls.h" + +#ifdef L_fstat +#ifndef HI_TECH_C +UNIX fstat(int fd, void *buf) + { + return unix(13, fd, buf); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _fstat"); + asm(" signat _fstat,8250"); + asm("_fstat:"); + asm(" ld hl,13"); + asm(" jp __sys__2"); +#endif +#endif diff --git a/src/libsys/getegid.c b/src/libsys/getegid.c new file mode 100755 index 00000000..8a7991b4 --- /dev/null +++ b/src/libsys/getegid.c @@ -0,0 +1,31 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX getegid(void); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_getegid +#ifndef HI_TECH_C +UNIX getegid(void) + { +#if 0 + return unix_get(GET_EGID); +#else + return unix(7, GET_EGID); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __getset"); + asm(" global _getegid"); + asm(" signat _getegid,26"); + asm("_getegid:"); + asm(" ld de," __str1(GET_EGID)); + asm(" jp __getset"); +#endif +#endif + + diff --git a/src/libsys/geteuid.c b/src/libsys/geteuid.c new file mode 100755 index 00000000..7d3a283e --- /dev/null +++ b/src/libsys/geteuid.c @@ -0,0 +1,31 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX geteuid(void); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_geteuid +#ifndef HI_TECH_C +UNIX geteuid(void) + { +#if 0 + return unix_get(GET_EUID); +#else + return unix(7, GET_EUID); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __getset"); + asm(" global _geteuid"); + asm(" signat _geteuid,26"); + asm("_geteuid:"); + asm(" ld de," __str1(GET_EUID)); + asm(" jp __getset"); +#endif +#endif + + diff --git a/src/libsys/getfsys.c b/src/libsys/getfsys.c new file mode 100755 index 00000000..14181094 --- /dev/null +++ b/src/libsys/getfsys.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX getfsys(int dev, void *buf); */ + +#include "syscalls.h" + +#ifdef L_getfsys +#ifndef HI_TECH_C +UNIX getfsys(int dev, void *buf) + { + return unix(14, dev, buf); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _getfsys"); + asm(" signat _getfsys,8250"); + asm("_getfsys:"); + asm(" ld hl,14"); + asm(" jp __sys__2"); +#endif +#endif diff --git a/src/libsys/getgid.c b/src/libsys/getgid.c new file mode 100755 index 00000000..c5c130cf --- /dev/null +++ b/src/libsys/getgid.c @@ -0,0 +1,31 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX getgid(void); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_getgid +#ifndef HI_TECH_C +UNIX getgid(void) + { +#if 0 + return unix_get(GET_GID); +#else + return unix(7, GET_GID); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __getset"); + asm(" global _getgid"); + asm(" signat _getgid,26"); + asm("_getgid:"); + asm(" ld de," __str1(GET_GID)); + asm(" jp __getset"); +#endif +#endif + + diff --git a/src/libsys/getpid.c b/src/libsys/getpid.c new file mode 100755 index 00000000..3ee33623 --- /dev/null +++ b/src/libsys/getpid.c @@ -0,0 +1,31 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX getpid(void); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_getpid +#ifndef HI_TECH_C +UNIX getpid(void) + { +#if 0 + return unix_get(GET_PID); +#else + return unix(7, GET_PID); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __getset"); + asm(" global _getpid"); + asm(" signat _getpid,26"); + asm("_getpid:"); + asm(" ld de," __str1(GET_PID)); + asm(" jp __getset"); +#endif +#endif + + diff --git a/src/libsys/getppid.c b/src/libsys/getppid.c new file mode 100755 index 00000000..4d36b5be --- /dev/null +++ b/src/libsys/getppid.c @@ -0,0 +1,31 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX getppid(void); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_getppid +#ifndef HI_TECH_C +UNIX getppid(void) + { +#if 0 + return unix_get(GET_PPID); +#else + return unix(7, GET_PPID); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __getset"); + asm(" global _getppid"); + asm(" signat _getppid,26"); + asm("_getppid:"); + asm(" ld de," __str1(GET_PPID)); + asm(" jp __getset"); +#endif +#endif + + diff --git a/src/libsys/getprio.c b/src/libsys/getprio.c new file mode 100755 index 00000000..53dd8e92 --- /dev/null +++ b/src/libsys/getprio.c @@ -0,0 +1,31 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX getprio(void); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_getprio +#ifndef HI_TECH_C +UNIX getprio(void) + { +#if 0 + return unix_get(GET_PRIO); +#else + return unix(7, GET_PRIO); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __getset"); + asm(" global _getprio"); + asm(" signat _getprio,26"); + asm("_getprio:"); + asm(" ld de," __str1(GET_PRIO)); + asm(" jp __getset"); +#endif +#endif + + diff --git a/src/libsys/getuid.c b/src/libsys/getuid.c new file mode 100755 index 00000000..b7cda904 --- /dev/null +++ b/src/libsys/getuid.c @@ -0,0 +1,31 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX getuid(void); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_getuid +#ifndef HI_TECH_C +UNIX getuid(void) + { +#if 0 + return unix_get(GET_UID); +#else + return unix(7, GET_UID); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __getset"); + asm(" global _getuid"); + asm(" signat _getuid,26"); + asm("_getuid:"); + asm(" ld de," __str1(GET_UID)); + asm(" jp __getset"); +#endif +#endif + + diff --git a/src/libsys/ioctl.c b/src/libsys/ioctl.c new file mode 100755 index 00000000..8fffb0ab --- /dev/null +++ b/src/libsys/ioctl.c @@ -0,0 +1,49 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX ioctl(fd, req, ...) */ + +#include "syscalls.h" + +#ifndef SYSCADDR +#define SEPH +#include "unix.h" +#endif + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) +#define dosyscall() asm(" call " __str1(SYSCADDR)) + +#ifdef L_ioctl +#ifndef HI_TECH_C +UNIX ioctl(int fd, int req, int arg, ...) /* makes IAR use stack params */ + { + return unix(15, fd, req, arg); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _ioctl"); + asm(" signat _ioctl,4122"); + asm("_ioctl:"); + asm(" push ix"); + asm(" ld ix,0"); + asm(" add ix,sp"); + asm(" ld l,(ix+6)"); + asm(" ld h,(ix+7)"); + asm(" push hl"); + asm(" ld l,(ix+4)"); + asm(" ld h,(ix+5)"); + asm(" push hl"); + asm(" push de"); + asm(" ld hl,15"); + asm(" push hl"); + dosyscall(); + asm(" call __ret__"); + asm(" pop ix"); /* discards HL */ + asm(" pop ix"); /* discards DE */ + asm(" pop ix"); /* discards first HL */ + asm(" pop ix"); /* discards second HL */ + asm(" pop ix"); + asm(" ret"); +#endif +#endif diff --git a/src/libsys/kill.c b/src/libsys/kill.c new file mode 100755 index 00000000..7e3b4655 --- /dev/null +++ b/src/libsys/kill.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX kill(int pid, int sig); */ + +#include "syscalls.h" + +#ifdef L_kill +#ifndef HI_TECH_C +UNIX kill(int pid, int sig) + { + return unix(16, pid, sig); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _kill"); + asm(" signat _kill,8250"); + asm("_kill:"); + asm(" ld hl,16"); + asm(" jp __sys__2"); +#endif +#endif diff --git a/src/libsys/libsysb.lib b/src/libsys/libsysb.lib new file mode 100755 index 00000000..6c982515 --- /dev/null +++ b/src/libsys/libsysb.lib @@ -0,0 +1,58 @@ +relsysb\access.rel +relsysb\alarm.rel +relsysb\brk.rel +relsysb\chdir.rel +relsysb\chmod.rel +relsysb\chown.rel +relsysb\chroot.rel +relsysb\close.rel +relsysb\creat.rel +relsysb\dup.rel +relsysb\dup2.rel +relsysb\execve.rel +relsysb\_exit.rel +relsysb\falign.rel +relsysb\fork.rel +relsysb\fstat.rel +relsysb\getegid.rel +relsysb\geteuid.rel +relsysb\getfsys.rel +relsysb\getgid.rel +relsysb\getpid.rel +relsysb\getppid.rel +relsysb\getprio.rel +relsysb\getuid.rel +relsysb\ioctl.rel +relsysb\kill.rel +relsysb\link.rel +relsysb\lseek.rel +relsysb\mkfifo.rel +relsysb\mknod.rel +relsysb\module.rel +relsysb\mount.rel +relsysb\open.rel +relsysb\pause.rel +relsysb\pipe.rel +relsysb\read.rel +relsysb\reboot.rel +relsysb\sbrk.rel +relsysb\seek.rel +relsysb\setgid.rel +relsysb\setprio.rel +relsysb\setuid.rel +relsysb\signal.rel +relsysb\stat.rel +relsysb\stime.rel +relsysb\symlink.rel +relsysb\sync.rel +relsysb\sys0b.rel +relsysb\sys1b.rel +relsysb\systrace.rel +relsysb\time.rel +relsysb\times.rel +relsysb\umask.rel +relsysb\umount.rel +relsysb\unlink.rel +relsysb\utime.rel +relsysb\waitpid.rel +relsysb\write.rel diff --git a/src/libsys/libsysl.lib b/src/libsys/libsysl.lib new file mode 100755 index 00000000..1cb0d327 --- /dev/null +++ b/src/libsys/libsysl.lib @@ -0,0 +1,58 @@ +relsysl\access.rel +relsysl\alarm.rel +relsysl\brk.rel +relsysl\chdir.rel +relsysl\chmod.rel +relsysl\chown.rel +relsysl\chroot.rel +relsysl\close.rel +relsysl\creat.rel +relsysl\dup.rel +relsysl\dup2.rel +relsysl\execve.rel +relsysl\_exit.rel +relsysl\falign.rel +relsysl\fork.rel +relsysl\fstat.rel +relsysl\getegid.rel +relsysl\geteuid.rel +relsysl\getfsys.rel +relsysl\getgid.rel +relsysl\getpid.rel +relsysl\getppid.rel +relsysl\getprio.rel +relsysl\getuid.rel +relsysl\ioctl.rel +relsysl\kill.rel +relsysl\link.rel +relsysl\lseek.rel +relsysl\mkfifo.rel +relsysl\mknod.rel +relsysl\module.rel +relsysl\mount.rel +relsysl\open.rel +relsysl\pause.rel +relsysl\pipe.rel +relsysl\read.rel +relsysl\reboot.rel +relsysl\sbrk.rel +relsysl\seek.rel +relsysl\setgid.rel +relsysl\setprio.rel +relsysl\setuid.rel +relsysl\signal.rel +relsysl\stat.rel +relsysl\stime.rel +relsysl\symlink.rel +relsysl\sync.rel +relsysl\sys0l.rel +relsysl\sys1l.rel +relsysl\systrace.rel +relsysl\time.rel +relsysl\times.rel +relsysl\umask.rel +relsysl\umount.rel +relsysl\unlink.rel +relsysl\utime.rel +relsysl\waitpid.rel +relsysl\write.rel diff --git a/src/libsys/link.c b/src/libsys/link.c new file mode 100755 index 00000000..318b03bf --- /dev/null +++ b/src/libsys/link.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX link(char *oldname, char *newname); */ + +#include "syscalls.h" + +#ifdef L_link +#ifndef HI_TECH_C +UNIX link(char *oldname, char *newname) + { + return unix(17, oldname, newname); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _link"); + asm(" signat _link,8250"); + asm("_link:"); + asm(" ld hl,17"); + asm(" jp __sys__2"); +#endif +#endif diff --git a/src/libsys/lseek.c b/src/libsys/lseek.c new file mode 100755 index 00000000..61f32ada --- /dev/null +++ b/src/libsys/lseek.c @@ -0,0 +1,61 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIXL lseek(int file, off_t offset, int flag); */ + +#include "syscalls.h" + +#ifndef SYSCADDR +#define SEPH +#include "unix.h" +#endif + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) +#define dosyscall() asm(" call " __str1(SYSCADDR)) + +#ifdef L_lseek +#ifndef HI_TECH_C +UNIXL lseek(int file, off_t offset, int flag) + { + return unix_long(25, file, offset, flag); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _lseek"); + asm(" signat _lseek,12348"); + asm("_lseek:"); + asm(" pop hl"); /* HL=ret addr */ + asm(" push ix"); /* save IX */ + asm(" ld ix,0"); + asm(" add ix,sp"); + asm(" ld c,(ix+6)"); + asm(" ld b,(ix+7)"); /* BC=flag */ + asm(" push bc"); + asm(" ld (ix+6),l"); + asm(" ld (ix+7),h"); /* put ret addr after arguments in stack */ + asm(" pop ix"); /* IX=flag (was in BC) */ + asm(" ex (sp),ix"); /* IX=original value, put flag in stack */ + asm(" pop hl"); /* HL=flag */ + asm(" pop bc"); /* BC=offset lsw */ + asm(" ex (sp),hl"); /* put flag in stack, HL=offset msw */ + asm(" push hl"); /* put offset msw in stack */ + asm(" push bc"); /* put offset lsw in stack */ + asm(" push de"); /* put file in stack */ + asm(" ld hl,25"); /* syscall */ + asm(" push hl"); + dosyscall(); + asm(" inc sp"); + asm(" inc sp"); /* discards syscall number */ + asm(" inc sp"); + asm(" inc sp"); /* discards flag */ + asm(" inc sp"); + asm(" inc sp"); + asm(" inc sp"); + asm(" inc sp"); /* discards offset */ + asm(" inc sp"); + asm(" inc sp"); /* discards file */ + asm(" ex de,hl"); /* cancel EX DE,HL in __ret__ */ + asm(" jp __ret__"); +#endif +#endif diff --git a/src/libsys/mkfifo.c b/src/libsys/mkfifo.c new file mode 100755 index 00000000..0ff0fab4 --- /dev/null +++ b/src/libsys/mkfifo.c @@ -0,0 +1,14 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX mkfifo(char *name, mode_t mode); */ + +#include "syscalls.h" +#include +#ifndef SYSCADDR /* Nick */ +#include "unix.h" +#endif /* Nick */ + +#ifdef L_mkfifo +UNIX mkfifo(char *name, mode_t mode) { + return mknod(name, mode | S_IFPIPE, (dev_t) 0); +} +#endif diff --git a/src/libsys/mknod.c b/src/libsys/mknod.c new file mode 100755 index 00000000..dd91aa64 --- /dev/null +++ b/src/libsys/mknod.c @@ -0,0 +1,24 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX mknod(char *name, mode_t mode, int dev); */ + +#include "syscalls.h" + +#ifdef L_mknod +#ifndef HI_TECH_C +UNIX mknod(char *name, mode_t mode, int dev) + { + return unix(18, name, mode, dev); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__3"); + asm(" global _mknod"); + asm(" signat _mknod,12346"); + asm("_mknod:"); + asm(" pop hl"); + asm(" ex (sp),hl"); + asm(" push hl"); + asm(" ld hl,18"); + asm(" jp __sys__3"); +#endif +#endif diff --git a/src/libsys/module.c b/src/libsys/module.c new file mode 100755 index 00000000..b338af0e --- /dev/null +++ b/src/libsys/module.c @@ -0,0 +1,159 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX modulereg(uint sig, int (*func)()); */ +/* UNIX moduledereg(uint sig); */ +/* UNIX modulecall(uint sig, uint fcn, char *args, int argsize); */ +/* UNIX modulesendreply(int pid, int fcn, char *repladdr, int replysize); */ +/* UNIX modulereply(int sig, int fcn, char *repladdr); */ + +#include "syscalls.h" + +#ifndef SYSCADDR +#define SEPH +#include "unix.h" +#endif + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) +#define dosyscall() asm(" call " __str1(SYSCADDR)) + +#ifdef UZIX_MODULE +#ifndef HI_TECH_C +UNIX modulereg(uint sig, int (*func)()) + { + return unix(40, sig, func); + } + +UNIX moduledereg(uint sig) + { + return unix(41, sig); + } + +UNIX modulecall(uint sig, uint fcn, char *args, int argsize) + { + return unix(42, sig, fcn, args, argsize); + } + +UNIX modulesendreply(int pid, int fcn, char *repladdr, int replysize) + { + return unix(43, pid, fcn, repladdr, replysize); + } + +UNIX modulereply(int sig, int fcn, char *repladdr) + { + return unix(44, sig, fcn, repladdr); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + + asm(" global _modulereg"); + asm(" signat _modulereg, 8250"); + asm("_modulereg:"); + asm(" ld hl,40"); + asm(" jp __sys__2"); + + asm(" global _moduledereg"); + asm(" signat _moduledereg, 4154"); + asm("_moduledereg:"); + asm(" ld hl,41"); + asm(" jp __sys__1"); + + asm(" global _modulecall"); + asm(" signat _modulecall, 16442"); + asm("_modulecall:"); + /* DE=module sign + BC=function + on stack: retaddr args argsize + */ + asm(" exx"); + asm(" pop bc"); /* BC'=ret addr */ + asm(" pop de"); /* DE'=args */ + asm(" pop hl"); /* HL'=argsize */ + asm(" push bc"); + asm(" push hl"); + asm(" push de"); + asm(" exx"); /* now stack is: args argsize retaddr */ + asm(" push bc"); + asm(" push de"); /* now is: DE BC args argsize retaddr */ + asm(" ld hl,42"); /* syscall */ + asm(" push hl"); + dosyscall(); + asm(" inc sp"); + asm(" inc sp"); /* discards syscall number */ + asm(" inc sp"); + asm(" inc sp"); /* discards argsize */ + asm(" inc sp"); + asm(" inc sp"); /* discards args */ + asm(" inc sp"); + asm(" inc sp"); /* discards fcn */ + asm(" inc sp"); + asm(" inc sp"); /* discards sig */ + asm(" ex de,hl"); /* cancel EX DE,HL in __ret__ */ + asm(" jp __ret__"); + + asm(" global _modulesendreply"); + asm(" signat _modulesendreply, 16442"); + asm("_modulesendreply:"); + /* DE=PID + BC=function + on stack: retaddr args argsize + */ + asm(" exx"); + asm(" pop bc"); /* BC'=ret addr */ + asm(" pop de"); /* DE'=args */ + asm(" pop hl"); /* HL'=argsize */ + asm(" push bc"); + asm(" push hl"); + asm(" push de"); + asm(" exx"); /* now stack is: args argsize retaddr */ + asm(" push bc"); + asm(" push de"); /* now is: DE BC args argsize retaddr */ + asm(" ld hl,43"); /* syscall */ + asm(" push hl"); + dosyscall(); + asm(" inc sp"); + asm(" inc sp"); /* discards syscall number */ + asm(" inc sp"); + asm(" inc sp"); /* discards replysize */ + asm(" inc sp"); + asm(" inc sp"); /* discards repladdr */ + asm(" inc sp"); + asm(" inc sp"); /* discards fcn */ + asm(" inc sp"); + asm(" inc sp"); /* discards pid */ + asm(" ex de,hl"); /* cancel EX DE,HL in __ret__ */ + asm(" jp __ret__"); + + asm(" global _modulereply"); + asm(" signat _modulereply, 12346"); + asm("_modulereply:"); + /* DE=module sign + BC=function + on stack: retaddr addr + */ + asm(" exx"); + asm(" pop bc"); /* BC'=ret addr */ + asm(" pop de"); /* DE'=addr */ + asm(" push bc"); + asm(" push de"); + asm(" exx"); /* now stack is: addr retaddr */ + asm(" push bc"); + asm(" push de"); /* now is: DE BC addr retaddr */ + asm(" ld hl,44"); /* syscall */ + asm(" push hl"); + dosyscall(); + asm(" inc sp"); + asm(" inc sp"); /* discards syscall number */ + asm(" inc sp"); + asm(" inc sp"); /* discards repladdr */ + asm(" inc sp"); + asm(" inc sp"); /* discards fcn */ + asm(" inc sp"); + asm(" inc sp"); /* discards sig */ + asm(" ex de,hl"); /* cancel EX DE,HL in __ret__ */ + asm(" jp __ret__"); +#endif +#endif + + diff --git a/src/libsys/mount.c b/src/libsys/mount.c new file mode 100755 index 00000000..ca9537cd --- /dev/null +++ b/src/libsys/mount.c @@ -0,0 +1,24 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX mount(char *spec, char *dir, int rwflag); */ + +#include "syscalls.h" + +#ifdef L_mount +#ifndef HI_TECH_C +UNIX mount(char *spec, char *dir, int rwflag) + { + return unix(19, spec, dir, rwflag); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__3"); + asm(" global _mount"); + asm(" signat _mount,12346"); + asm("_mount:"); + asm(" pop hl"); + asm(" ex (sp),hl"); + asm(" push hl"); + asm(" ld hl,19"); + asm(" jp __sys__3"); +#endif +#endif diff --git a/src/libsys/n.bat b/src/libsys/n.bat new file mode 100755 index 00000000..fda184d3 --- /dev/null +++ b/src/libsys/n.bat @@ -0,0 +1,12 @@ +md build-l +cd build-l +copy ..\build-l.ban n.bat +call n +cd .. + +md build-b +cd build-b +copy ..\build-b.ban n.bat +call n +cd .. + diff --git a/src/libsys/open.c b/src/libsys/open.c new file mode 100755 index 00000000..e3ff9df6 --- /dev/null +++ b/src/libsys/open.c @@ -0,0 +1,49 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX open(char *name, int flag, ...); */ + +#include "syscalls.h" + +#ifndef SYSCADDR +#define SEPH +#include "unix.h" +#endif + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) +#define dosyscall() asm(" call " __str1(SYSCADDR)) + +#ifdef L_open +#ifndef HI_TECH_C +UNIX open(char *name, uint flag, int arg, ...) /* makes IAR use stack params */ + { + return unix(20, name, flag, arg); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _open"); + asm(" signat _open,4122"); + asm("_open:"); + asm(" push ix"); + asm(" ld ix,0"); + asm(" add ix,sp"); + asm(" ld l,(ix+6)"); + asm(" ld h,(ix+7)"); + asm(" push hl"); /* last parameter in stack */ + asm(" ld l,(ix+4)"); + asm(" ld h,(ix+5)"); + asm(" push hl"); /* flag in stack */ + asm(" push de"); /* name in stack */ + asm(" ld hl,20"); + asm(" push hl"); + dosyscall(); + asm(" call __ret__"); + asm(" pop ix"); /* discards HL (syscall number) */ + asm(" pop ix"); /* discards DE */ + asm(" pop ix"); /* discards first HL */ + asm(" pop ix"); /* discards second HL */ + asm(" pop ix"); /* restore original IX */ + asm(" ret"); +#endif +#endif diff --git a/src/libsys/pause.c b/src/libsys/pause.c new file mode 100755 index 00000000..c40a93b9 --- /dev/null +++ b/src/libsys/pause.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX pause(void); */ + +#include "syscalls.h" + +#ifdef L_pause +#ifndef HI_TECH_C +UNIX pause(void) + { + return unix(21); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _pause"); + asm(" signat _pause,26"); + asm("_pause:"); + asm(" ld hl,21"); + asm(" jp __sys__"); +#endif +#endif + + diff --git a/src/libsys/pipe.c b/src/libsys/pipe.c new file mode 100755 index 00000000..202768ea --- /dev/null +++ b/src/libsys/pipe.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX pipe(int fildes[]); */ + +#include "syscalls.h" + +#ifdef L_pipe +#ifndef HI_TECH_C +UNIX pipe(int fildes[]) + { + return unix(22, fildes); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _pipe"); + asm(" signat _pipe,4154"); + asm("_pipe:"); + asm(" ld hl,22"); + asm(" jp __sys__1"); +#endif +#endif + + diff --git a/src/libsys/read.c b/src/libsys/read.c new file mode 100755 index 00000000..bbfd61ab --- /dev/null +++ b/src/libsys/read.c @@ -0,0 +1,26 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX read(int d, void *buf, uint nbytes); */ + +#include "syscalls.h" + +#ifdef L_read +#ifndef HI_TECH_C +UNIX read(int d, void *buf, uint nbytes) + { + return unix(23, d, buf, nbytes); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__3"); + asm(" global _read"); + asm(" signat _read,12346"); + asm("_read:"); + asm(" pop hl"); + asm(" ex (sp),hl"); + asm(" push hl"); + asm(" ld hl,23"); + asm(" jp __sys__3"); +#endif +#endif + + diff --git a/src/libsys/reboot.c b/src/libsys/reboot.c new file mode 100755 index 00000000..c271133d --- /dev/null +++ b/src/libsys/reboot.c @@ -0,0 +1,26 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX reboot(char p1, char p2); */ + +#include "syscalls.h" + +#ifdef L_reboot +#ifndef HI_TECH_C +UNIX reboot(char p1, char p2) + { + return unix(37, p1, p2); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _reboot"); + asm(" signat _reboot,8250"); + asm("_reboot:"); + asm(" ld b,0"); + asm(" ld d,0"); + /* p1/p2 are char, not int, so D and B must be zeroed */ + asm(" ld hl,37"); + asm(" jp __sys__2"); +#endif +#endif + + diff --git a/src/libsys/sbrk.c b/src/libsys/sbrk.c new file mode 100755 index 00000000..e788b422 --- /dev/null +++ b/src/libsys/sbrk.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX sbrk(uint incr); */ + +#include "syscalls.h" + +#ifdef L_sbrk +#ifndef HI_TECH_C +UNIX sbrk(uint incr) + { + return unix(24, incr); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _sbrk"); + asm(" signat _sbrk,4154"); + asm("_sbrk:"); + asm(" ld hl,24"); + asm(" jp __sys__1"); +#endif +#endif + + diff --git a/src/libsys/seek.c b/src/libsys/seek.c new file mode 100755 index 00000000..7f4ee57e --- /dev/null +++ b/src/libsys/seek.c @@ -0,0 +1,61 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX seek(int file, uint offset, int flag); */ + +#include "syscalls.h" + +#ifndef SYSCADDR +#define SEPH +#include "unix.h" +#endif + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) +#define dosyscall() asm(" call " __str1(SYSCADDR)) + +#ifdef L_lseek /* should be L_seek */ +#ifndef HI_TECH_C +UNIX seek(int file, uint offset, int flag) + { + return unix(25, file, offset, flag); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _lseek"); + asm(" signat _lseek,12348"); + asm("_lseek:"); + asm(" pop hl"); /* HL=ret addr */ + asm(" push ix"); /* save IX */ + asm(" ld ix,0"); + asm(" add ix,sp"); + asm(" ld c,(ix+6)"); + asm(" ld b,(ix+7)"); /* BC=flag */ + asm(" push bc"); + asm(" ld (ix+6),l"); + asm(" ld (ix+7),h"); /* put ret addr after arguments in stack */ + asm(" pop ix"); /* IX=flag (was in BC) */ + asm(" ex (sp),ix"); /* IX=original value, put flag in stack */ + asm(" pop hl"); /* HL=flag */ + asm(" pop bc"); /* BC=offset lsw */ + asm(" ex (sp),hl"); /* put flag in stack, HL=offset msw */ + asm(" push hl"); /* put offset msw in stack */ + asm(" push bc"); /* put offset lsw in stack */ + asm(" push de"); /* put file in stack */ + asm(" ld hl,25"); /* syscall */ + asm(" push hl"); + dosyscall(); + asm(" inc sp"); + asm(" inc sp"); /* discards syscall number */ + asm(" inc sp"); + asm(" inc sp"); /* discards flag */ + asm(" inc sp"); + asm(" inc sp"); + asm(" inc sp"); + asm(" inc sp"); /* discards offset */ + asm(" inc sp"); + asm(" inc sp"); /* discards file */ + asm(" ex de,hl"); /* cancel EX DE,HL in __ret__ */ + asm(" jp __ret__"); +#endif +#endif diff --git a/src/libsys/setgid.c b/src/libsys/setgid.c new file mode 100755 index 00000000..6a0cf7dd --- /dev/null +++ b/src/libsys/setgid.c @@ -0,0 +1,32 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX setgid(int gid); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_setgid +#ifndef HI_TECH_C +UNIX setgid(int gid) + { +#if 0 + return unix_set(SET_GID, gid); +#else + return unix(7, SET_GID, gid); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __setset"); + asm(" global _setgid"); + asm(" signat _setgid,4154"); + asm("_setgid:"); + asm(" push de"); + asm(" ld de," __str1(SET_GID)); + asm(" jp __setset"); +#endif +#endif + + diff --git a/src/libsys/setprio.c b/src/libsys/setprio.c new file mode 100755 index 00000000..6442c0b0 --- /dev/null +++ b/src/libsys/setprio.c @@ -0,0 +1,32 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX setprio(int pid, char prio); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_setprio +#ifndef HI_TECH_C +UNIX setprio(int pid, char prio) + { + return unix(7, SET_PRIO, pid, prio); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__3"); + asm(" global _setprio"); + asm(" signat _setprio,8250"); + asm("_setprio:"); + asm(" ld b,0"); + asm(" push bc"); + asm(" ld b,d"); + asm(" ld c,e"); + asm(" ld de," __str1(SET_PRIO)); + asm(" ld hl,7"); + asm(" jp __sys__3"); +#endif +#endif + + diff --git a/src/libsys/setuid.c b/src/libsys/setuid.c new file mode 100755 index 00000000..4fbaf671 --- /dev/null +++ b/src/libsys/setuid.c @@ -0,0 +1,32 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX setuid(int uid); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_setuid +#ifndef HI_TECH_C +UNIX setuid(int uid) + { +#if 0 + return unix_set(SET_UID, uid); +#else + return unix(7, SET_UID, uid); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __setset"); + asm(" global _setuid"); + asm(" signat _setuid,4154"); + asm("_setuid:"); + asm(" push de"); + asm(" ld de," __str1(SET_UID)); + asm(" jp __setset"); +#endif +#endif + + diff --git a/src/libsys/signal.c b/src/libsys/signal.c new file mode 100755 index 00000000..f44bb037 --- /dev/null +++ b/src/libsys/signal.c @@ -0,0 +1,24 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX signal(signal_t sig, sig_t func); */ + +#include "syscalls.h" + +#ifdef L_signal +#ifndef HI_TECH_C +sig_t signal(signal_t sig, sig_t func) + { + return (sig_t)unix_long(26, sig, func); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _signal"); + asm(" signat _signal,8250"); + asm("_signal:"); + asm(" ld d,0"); /* SIG is 8 uchar, but is passed to UNIX as uint */ + asm(" ld hl,26"); + asm(" jp __sys__2"); +#endif +#endif + + diff --git a/src/libsys/stat.c b/src/libsys/stat.c new file mode 100755 index 00000000..6a1ce62b --- /dev/null +++ b/src/libsys/stat.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX stat(char *path, void *buf); */ + +#include "syscalls.h" + +#ifdef L_stat +#ifndef HI_TECH_C +UNIX stat(char *path, void *buf) + { + return unix(27, path, buf); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _stat"); + asm(" signat _stat,8250"); + asm("_stat:"); + asm(" ld hl,27"); + asm(" jp __sys__2"); +#endif +#endif + + diff --git a/src/libsys/stime.c b/src/libsys/stime.c new file mode 100755 index 00000000..4e7637aa --- /dev/null +++ b/src/libsys/stime.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX stime(time_t *tvec); */ + +#include "syscalls.h" + +#ifdef L_stime +#ifndef HI_TECH_C +UNIX stime(time_t *tvec) + { + return unix(28, tvec); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _stime"); + asm(" signat _stime,4154"); + asm("_stime:"); + asm(" ld hl,28"); + asm(" jp __sys__1"); +#endif +#endif + + diff --git a/src/libsys/symlink.c b/src/libsys/symlink.c new file mode 100755 index 00000000..a25f5383 --- /dev/null +++ b/src/libsys/symlink.c @@ -0,0 +1,21 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX symlink(char *oldname, char *newname); */ + +#include "syscalls.h" + +#ifdef L_symlink +#ifndef HI_TECH_C +UNIX symlink(char *oldname, char *newname) + { + return unix(38, oldname, newname); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _symlink"); + asm(" signat _symlink,8250"); + asm("_symlink:"); + asm(" ld hl,38"); + asm(" jp __sys__2"); +#endif +#endif diff --git a/src/libsys/sync.c b/src/libsys/sync.c new file mode 100755 index 00000000..864f4a5d --- /dev/null +++ b/src/libsys/sync.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX sync(void); */ + +#include "syscalls.h" + +#ifdef L_sync +#ifndef HI_TECH_C +UNIX sync(void) + { + return unix(29); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _sync"); + asm(" signat _sync,26"); + asm("_sync:"); + asm(" ld hl,29"); + asm(" jp __sys__"); +#endif +#endif + + diff --git a/src/libsys/sys0b.asm b/src/libsys/sys0b.asm new file mode 100755 index 00000000..ed715143 --- /dev/null +++ b/src/libsys/sys0b.asm @@ -0,0 +1,45 @@ +; sys0b.asm by Nick for UZI180, adapted from UZI280 syscalls.mac + +; ----------------------------------------------------------------------------- + + module _sys0b + + extern errno ; vendor _errno + + extern ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + rseg CODE + + public unix ; vendor _unix + +unix:: + ld hl,4 + add hl,sp ; assumes banked calling convention + + push bc + push de + + ld e,(hl) + inc hl + ld d,(hl) + inc hl ; de = callno (1st argument) + + ld c,l + ld b,h ; bc -> stack frame (2nd argument) + + rst 30h ; call the kernel function dispatcher + jr nc,no_error ; no error, hl has return value already + + ld (errno),hl ; vendor _errno + ld hl,-1 ; dedicated return value meaning error + +no_error: + pop de + pop bc + jp ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + END diff --git a/src/libsys/sys0l.asm b/src/libsys/sys0l.asm new file mode 100755 index 00000000..c5794a70 --- /dev/null +++ b/src/libsys/sys0l.asm @@ -0,0 +1,43 @@ +; sys0l.asm by Nick for UZI180, adapted from UZI280 syscalls.mac + +; ----------------------------------------------------------------------------- + + module _sys0l + + extern errno ; vendor _errno + +; ----------------------------------------------------------------------------- + + rseg CODE + + public unix ; vendor _unix + +unix:: + ld hl,2 + add hl,sp ; assumes non-banked calling convention + + push bc + push de + + ld e,(hl) + inc hl + ld d,(hl) + inc hl ; de = callno (1st argument) + + ld c,l + ld b,h ; bc -> stack frame (2nd argument) + + rst 30h ; call the kernel function dispatcher + jr nc,no_error ; no error, hl has return value already + + ld (errno),hl ; vendor _errno + ld hl,-1 ; dedicated return value meaning error + +no_error: + pop de + pop bc + ret + +; ----------------------------------------------------------------------------- + + END diff --git a/src/libsys/sys1b.asm b/src/libsys/sys1b.asm new file mode 100755 index 00000000..7f7d8901 --- /dev/null +++ b/src/libsys/sys1b.asm @@ -0,0 +1,47 @@ +; sys1b.asm by Nick for UZI180, adapted from UZI280 syscalls.mac + +; ----------------------------------------------------------------------------- + + module _sys1b + + extern errno ; vendor _errno + + extern ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + rseg CODE + + public unix_long ; vendor _unix_long + +unix_long:: + ld hl,4 + add hl,sp ; assumes non-banked calling convention + + ;push bc + push de + + ld e,(hl) + inc hl + ld d,(hl) + inc hl ; de = callno (1st argument) + + ld c,l + ld b,h ; bc -> stack frame (2nd argument) + + rst 30h ; call the kernel function dispatcher + jr nc,no_error ; no error, hl has return value already + + ld (errno),hl ; vendor _errno + ld hl,-1 ; dedicated return value meaning error + ld c,l + ld b,h ; sign extend for maximal politeness + +no_error: + pop de + ;pop bc ; bc:hl has syscall return value + jp ?BANK_FAST_LEAVE_L08 + +; ----------------------------------------------------------------------------- + + END diff --git a/src/libsys/sys1l.asm b/src/libsys/sys1l.asm new file mode 100755 index 00000000..5ae796ab --- /dev/null +++ b/src/libsys/sys1l.asm @@ -0,0 +1,45 @@ +; sys1l.asm by Nick for UZI180, adapted from UZI280 syscalls.mac + +; ----------------------------------------------------------------------------- + + module _sys1l + + extern errno ; vendor _errno + +; ----------------------------------------------------------------------------- + + rseg CODE + + public unix_long ; vendor _unix_long + +unix_long:: + ld hl,2 + add hl,sp ; assumes non-banked calling convention + + ;push bc + push de + + ld e,(hl) + inc hl + ld d,(hl) + inc hl ; de = callno (1st argument) + + ld c,l + ld b,h ; bc -> stack frame (2nd argument) + + rst 30h ; call the kernel function dispatcher + jr nc,no_error ; no error, hl has return value already + + ld (errno),hl ; vendor _errno + ld hl,-1 ; dedicated return value meaning error + ld c,l + ld b,h ; sign extend for maximal politeness + +no_error: + pop de + ;pop bc ; bc:hl has syscall return value + ret + +; ----------------------------------------------------------------------------- + + END diff --git a/src/libsys/syscalls.h b/src/libsys/syscalls.h new file mode 100755 index 00000000..d9914c1f --- /dev/null +++ b/src/libsys/syscalls.h @@ -0,0 +1,82 @@ +/* + * UZIX syscall for MSX-implementation + */ + +#define SKIP_SYSCALLS /* Nick */ +#include + +#ifndef SYSCADDR +#define SEPH +#include "unix.h" +#endif + +#define UNIX int +#define UNIXL long +#define UNIXV void + +#define UZIX_MODULE + +#ifndef __DOS__ + +#ifdef MAKE_ALL +#define L___syscall +#define L_access +#define L_alarm +#define L_brk +#define L_chdir +#define L_chroot +#define L_chmod +#define L_chown +#define L_close +#define L_creat +#define L_dup +#define L_dup2 +#define L_execve +#define L_exit +#define L_fork +#define L_fstat +#if 1 /* Nick free bitmap */ +#define L_falign +#endif +#define L_getfsys +#define L_ioctl +#define L_kill +#define L_link +#define L_symlink +#define L_mknod +#define L_mkfifo +#define L_mount +#define L_open +#define L_pause +#define L_pipe +#define L_read +#define L_sbrk +#define L_lseek +#define L_signal +#define L_stat +#define L_stime +#define L_sync +#define L_time +#define L_times +#define L_umount +#define L_unlink +#define L_utime +#define L_waitpid +#define L_write +#define L_reboot + +#define L_getgid +#define L_getegid +#define L_getpid +#define L_getppid +#define L_getuid +#define L_geteuid +#define L_getprio +#define L_setgid +#define L_setuid +#define L_setprio +#define L_umask +#define L_systrace +#endif + +#endif diff --git a/src/libsys/systrace.c b/src/libsys/systrace.c new file mode 100755 index 00000000..3d4fd3ca --- /dev/null +++ b/src/libsys/systrace.c @@ -0,0 +1,32 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX systrace(int onoff); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_systrace +#ifndef HI_TECH_C +UNIX systrace(int onoff) + { +#if 0 + return unix_set(SET_TRACE, onoff); +#else + return unix(7, SET_TRACE, onoff); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __setset"); + asm(" global _systrace"); + asm(" signat _systrace,4154"); + asm("_systrace:"); + asm(" push de"); + asm(" ld de," __str1(SET_TRACE)); + asm(" jp __setset"); +#endif +#endif + + diff --git a/src/libsys/time.c b/src/libsys/time.c new file mode 100755 index 00000000..77e10688 --- /dev/null +++ b/src/libsys/time.c @@ -0,0 +1,35 @@ +/********** MSX-UZIX version of syscalls ************/ +/* time_t time(time_t *tvec); */ + +#include "syscalls.h" + +#ifdef L_time +#ifdef HI_TECH_C + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); +#endif + +UNIX gtime(time_t *tvec); + +#ifndef HI_TECH_C +UNIX gtime(time_t *tvec) + { + return unix(30, tvec); + } +#else + asm("_gtime:"); + asm(" ld hl,30"); + asm(" jp __sys__1"); +#endif + +time_t time(time_t *tvec) { + time_t ttvec; + + if (tvec == NULL) { + gtime(&ttvec); + return ttvec; + } + gtime(tvec); + return *tvec; +} +#endif diff --git a/src/libsys/times.c b/src/libsys/times.c new file mode 100755 index 00000000..0019b4fe --- /dev/null +++ b/src/libsys/times.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX times(struct tms *tvec); */ + +#include "syscalls.h" + +#ifdef L_times +#ifndef HI_TECH_C +UNIX times(struct tms *tvec) + { + return unix(31, tvec); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _times"); + asm(" signat _times,4154"); + asm("_times:"); + asm(" ld hl,31"); + asm(" jp __sys__1"); +#endif +#endif + + diff --git a/src/libsys/umask.c b/src/libsys/umask.c new file mode 100755 index 00000000..137957f8 --- /dev/null +++ b/src/libsys/umask.c @@ -0,0 +1,32 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX umask(int mask); */ + +#include "syscalls.h" + +#define __str3(x) __STRING(x) +#define __str2(x) __str3(x) +#define __str1(x) __str2(x) + +#ifdef L_umask +#ifndef HI_TECH_C +UNIX umask(int mask) + { +#if 0 + return unix_set(SET_UMASK, mask); +#else + return unix(7, SET_UMASK, mask); +#endif + } +#else + asm(" psect text,class=CODE"); + asm(" global __setset"); + asm(" global _umask"); + asm(" signat _umask,4154"); + asm("_umask:"); + asm(" push de"); + asm(" ld de," __str1(SET_UMASK)); + asm(" jp __setset"); +#endif +#endif + + diff --git a/src/libsys/umount.c b/src/libsys/umount.c new file mode 100755 index 00000000..2d0ab991 --- /dev/null +++ b/src/libsys/umount.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX umount(char *spec); */ + +#include "syscalls.h" + +#ifdef L_umount +#ifndef HI_TECH_C +UNIX umount(char *spec) + { + return unix(32, spec); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _umount"); + asm(" signat _umount,4154"); + asm("_umount:"); + asm(" ld hl,32"); + asm(" jp __sys__1"); +#endif +#endif + + diff --git a/src/libsys/unlink.c b/src/libsys/unlink.c new file mode 100755 index 00000000..26951175 --- /dev/null +++ b/src/libsys/unlink.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX unlink(char *path); */ + +#include "syscalls.h" + +#ifdef L_unlink +#ifndef HI_TECH_C +UNIX unlink(char *path) + { + return unix(33, path); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _unlink"); + asm(" signat _unlink,4154"); + asm("_unlink:"); + asm(" ld hl,33"); + asm(" jp __sys__1"); +#endif +#endif + + diff --git a/src/libsys/utime.c b/src/libsys/utime.c new file mode 100755 index 00000000..62e2634e --- /dev/null +++ b/src/libsys/utime.c @@ -0,0 +1,23 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX utime(char *path, struct utimbuf *buf); */ + +#include "syscalls.h" + +#ifdef L_utime +#ifndef HI_TECH_C +UNIX utime(char *path, struct utimbuf *buf) + { + return unix(34, path, buf); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__, __sys__1, __sys__2, __ret__"); + asm(" global _utime"); + asm(" signat _utime,8250"); + asm("_utime:"); + asm(" ld hl,34"); + asm(" jp __sys__2"); +#endif +#endif + + diff --git a/src/libsys/waitpid.c b/src/libsys/waitpid.c new file mode 100755 index 00000000..d8baa180 --- /dev/null +++ b/src/libsys/waitpid.c @@ -0,0 +1,24 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX waitpid(int pid, int *statloc, int options); */ + +#include "syscalls.h" + +#ifdef L_waitpid +#ifndef HI_TECH_C +int waitpid(int pid, int *statloc, int options) + { + return unix(35, pid, statloc, options); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__3"); + asm(" global _waitpid"); + asm(" signat _waitpid,12346"); + asm("_waitpid:"); + asm(" pop hl"); + asm(" ex (sp),hl"); + asm(" push hl"); + asm(" ld hl,35"); + asm(" jp __sys__3"); +#endif +#endif diff --git a/src/libsys/write.c b/src/libsys/write.c new file mode 100755 index 00000000..0efdaeb2 --- /dev/null +++ b/src/libsys/write.c @@ -0,0 +1,26 @@ +/********** MSX-UZIX version of syscalls ************/ +/* UNIX write(int d, void *buf, uint nbytes); */ + +#include "syscalls.h" + +#ifdef L_write +#ifndef HI_TECH_C +UNIX write(int d, void *buf, uint nbytes) + { + return unix(36, d, buf, nbytes); + } +#else + asm(" psect text,class=CODE"); + asm(" global __sys__3"); + asm(" global _write"); + asm(" signat _write,12346"); + asm("_write:"); + asm(" pop hl"); + asm(" ex (sp),hl"); + asm(" push hl"); + asm(" ld hl,36"); + asm(" jp __sys__3"); +#endif +#endif + + diff --git a/src/link-z80/aslink.h b/src/link-z80/aslink.h new file mode 100755 index 00000000..23620306 --- /dev/null +++ b/src/link-z80/aslink.h @@ -0,0 +1,908 @@ +/* aslink.h */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With enhancements from + * John L. Hartman (JLH) + * jhartman@compuserve.com + * + * Bill McKinnon + * w_mckinnon@conknet.com + */ + +#define VERSION "V03.11" + +/*)Module aslink.h + * + * The module aslink.h contains the definitions for constants, + * structures, global variables, and LKxxxx functions + * contained in the LKxxxx.c files. + */ + +/*)BUILD + $(PROGRAM) = ASLINK + $(INCLUDE) = ASLINK.H + $(FILES) = { + LKMAIN.C + LKLEX.C + LKAREA.C + LKHEAD.C + LKSYM.C + LKEVAL.C + LKDATA.C + LKLIST.C + LKRLOC.C + LKLIBR.C + LKS19.C + LKIHX.C + } + $(STACK) = 2000 +*/ + +/* DECUS C void definition */ +/* File/extension seperator */ + +#ifdef decus +#define VOID char +#define FSEPX '.' +#endif + +/* PDOS C void definition */ +/* File/extension seperator */ + +#ifdef PDOS +#define VOID char +#define FSEPX ':' +#endif + +/* Default void definition */ +/* File/extension seperator */ + +#ifndef VOID +#define VOID void +#define FSEPX '.' +#define OTHERSYSTEM +#endif + +/* + * Error definitions + */ +#define ER_NONE 0 /* No error */ +#define ER_WARNING 1 /* Warning */ +#define ER_ERROR 2 /* Assembly error */ +#define ER_FATAL 3 /* Fatal error */ + +/* + * This file defines the format of the + * relocatable binary file. + */ + +#define NCPS 80 /* characters per symbol */ +#define NDATA 16 /* actual data */ +#define NINPUT 200 /* Input buffer size */ +#define NHASH 64 /* Buckets in hash table */ +#define HMASK 077 /* Hash mask */ +#define NLPP 60 /* Lines per page */ +#define NTXT 16 /* T values */ +#define NMAX 78 /* Maximum S19/IHX line length */ +#define FILSPC 80 /* File spec length */ + +/* + * The "R_" relocation constants define values used in + * generating the assembler relocation output data for + * areas, symbols, and code. + * + * + * Relocation types. + * + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | MSB | PAGn| PAG0| USGN| BYT2| PCR | SYM | BYT | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + */ + +#define R_WORD 0000 /* 16 bit */ +#define R_BYTE 0001 /* 8 bit */ + +#define R_AREA 0000 /* Base type */ +#define R_SYM 0002 + +#define R_NORM 0000 /* PC adjust */ +#define R_PCR 0004 + +#define R_BYT1 0000 /* Byte count for R_BYTE = 1 */ +#define R_BYTX 0010 /* Byte count for R_BYTE = X */ + +#define R_SGND 0000 /* Signed value */ +#define R_USGN 0020 /* Unsigned value */ + +#if 1 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ +#define R_BYTE3 0040 /* byte after 'high' byte */ +#define R_BYTE4 0100 /* byte after 'byte3' byte */ +#else +#define R_NOPAG 0000 /* Page Mode */ +#define R_PAG0 0040 /* Page '0' */ +#define R_PAG 0100 /* Page 'nnn' */ +#endif + +#define R_LSB 0000 /* output low byte */ +#define R_MSB 0200 /* output high byte */ + +/* + * Additional "R_" functionality is required to support + * some microprocesssor architectures. The 'illegal' + * "R_" mode of R_WORD | R_BYTX is used as a designator + * of the extended R_ modes. The extended modes replace + * the PAGING modes and are being added in an adhoc manner + * as follows: + * + * Extended Mode relocation flags + * + * 7 6 5 4 3 2 1 0 + * +-----+-----+-----+-----+-----+-----+-----+-----+ + * | MSB | x | x | USGN| 1 | PCR | SYM | 0 | + * +-----+-----+-----+-----+-----+-----+-----+-----+ + */ + +#define R_ECHEK 0011 /* Extended Mode Check Bits */ +#define R_EXTND 0010 /* Extended Mode Code */ +#define R_EMASK 0151 /* Extended Mode Mask */ + +/* #define R_AREA 0000 */ /* Base type */ +/* #define R_SYM 0002 */ + +/* #define R_NORM 0000 */ /* PC adjust */ +/* #define R_PCR 0004 */ + +/* #define R_SGND 0000 */ /* Signed value */ +/* #define R_USGN 0020 */ /* Unsigned value */ + +/* #define R_LSB 0000 */ /* output low byte */ +/* #define R_MSB 0200 */ /* output high byte */ + +#define R_J11 0010 /* JLH: 11 bit JMP and CALL (8051) */ +#define R_J19 0050 /* BM: 19 bit JMP and CALL (DS80C390) */ +#define R_3BYTE 0110 /* 24 bit */ +#define R_4BYTE 0150 /* 32 bit */ + +/* + * Global symbol types. + */ +#define S_REF 1 /* referenced */ +#define S_DEF 2 /* defined */ + +/* + * Area types + */ +#define A_NUL 001 /* Nick, means segment only defines symbols */ +#define A_CON 000 /* concatenate */ +#define A_OVR 004 /* overlay */ +#define A_REL 000 /* relocatable */ +#define A_ABS 010 /* absolute */ +#define A_NOPAG 000 /* non-paged */ +#define A_PAG 020 /* paged */ + +/* + * File types + */ +#define F_STD 1 /* stdin */ +#define F_LNK 2 /* File.lnk */ +#define F_REL 3 /* File.rel */ + +/* + * General assembler address type + */ +typedef unsigned int a_uint; + +/* + * The structures of head, area, areax, and sym are created + * as the REL files are read during the first pass of the + * linker. The struct head is created upon encountering a + * H directive in the REL file. The structure contains a + * link to a link file structure (struct lfile) which describes + * the file containing the H directive, the number of data/code + * areas contained in this header segment, the number of + * symbols referenced/defined in this header segment, a pointer + * to an array of pointers to areax structures (struct areax) + * created as each A directive is read, and a pointer to an + * array of pointers to symbol structures (struct sym) for + * all referenced/defined symbols. As H directives are read + * from the REL files a linked list of head structures is + * created by placing a link to the new head structure + * in the previous head structure. + */ +struct head +{ + struct head *h_hp; /* Header link */ + struct lfile *h_lfile;/* Associated file */ + int h_narea; /* # of areas */ + struct areax **a_list; /* Area list */ + int h_nglob; /* # of global symbols */ + struct sym **s_list; /* Globle symbol list */ + char * m_id; /* Module name */ +}; + +/* + * A structure area is created for each 'unique' data/code + * area definition found as the REL files are read. The + * struct area contains the name of the area, a flag byte + * which contains the area attributes (REL/CON/OVR/ABS), + * the area base address set flag byte (-b option), and the + * area base address and total size which will be filled + * in at the end of the first pass through the REL files. + * As A directives are read from the REL files a linked + * list of unique area structures is created by placing a + * link to the new area structure in the previous area structure. + */ +struct area +{ + struct area *a_ap; /* Area link */ + struct areax *a_axp; /* Area extension link */ +#if 1 /* Nick */ + a_uint a_addr; /* logical beginning address of area */ + a_uint a_size; /* logical size of the area */ + a_uint a_incr; /* logical banksize increment */ + a_uint a_paddr; /* physical beginning address of area */ + a_uint a_psize; /* physical size of the area */ + a_uint a_pincr; /* physical banksize increment */ + a_uint a_baddr; /* banksize threshold for advancing the bank */ + a_uint a_bsize; /* banksize counter for advancing the bank */ + a_uint a_bincr; /* banksize increment allows overlaid banks */ + char a_bset; /* logical base address set */ + char a_iset; /* logical banksize increment set */ + char a_pbset; /* physical base address set */ + char a_piset; /* physical banksize increment set */ + char a_baset; /* banksize threshold set */ + char a_biset; /* banksize increment set */ + char a_bcflg; /* bank concatenation flag for area */ +#else + a_uint a_addr; /* Beginning address of area */ + a_uint a_size; /* Total size of the area */ + char a_bset; /* Area base address set */ +#endif + char a_flag; /* Flag byte */ + char * a_id; /* Name */ +}; + +/* + * An areax structure is created for every A directive found + * while reading the REL files. The struct areax contains a + * link to the 'unique' area structure referenced by the A + * directive and to the head structure this area segment is + * a part of. The size of this area segment as read from the + * A directive is placed in the areax structure. The beginning + * address of this segment will be filled in at the end of the + * first pass through the REL files. As A directives are read + * from the REL files a linked list of areax structures is + * created for each unique area. The final areax linked + * list has at its head the 'unique' area structure linked + * to the linked areax structures (one areax structure for + * each A directive for this area). + */ +struct areax +{ + struct areax *a_axp; /* Area extension link */ + struct area *a_bap; /* Base area link */ + struct head *a_bhp; /* Base header link */ + a_uint a_addr; /* Beginning address of section */ +#if 1 /* Nick */ + a_uint a_paddr; /* Beginning physical address of section */ +#endif + a_uint a_size; /* Size of the area in section */ +}; + +/* + * A sym structure is created for every unique symbol + * referenced/defined while reading the REL files. The + * struct sym contains the symbol's name, a flag value + * (not used in this linker), a symbol type denoting + * referenced/defined, and an address which is loaded + * with the relative address within the area in which + * the symbol was defined. The sym structure also + * contains a link to the area where the symbol was defined. + * The sym structures are linked into linked lists using + * the symbol link element. + */ +struct sym +{ + struct sym *s_sp; /* Symbol link */ + struct areax *s_axp; /* Symbol area link */ + char s_type; /* Symbol subtype */ + char s_flag; /* Flag byte */ + a_uint s_addr; /* Address */ + char *s_id; /* Name (JLH) */ + char *m_id; /* Module symbol define in */ +}; + +/* + * The structure lfile contains a pointer to a + * file specification string, an index which points + * to the file name (past the 'path'), the file type, + * an object output flag, and a link to the next + * lfile structure. + */ +struct lfile +{ + struct lfile *f_flp; /* lfile link */ + int f_type; /* File type */ + char *f_idp; /* Pointer to file spec */ + int f_idx; /* Index to file name */ + int f_obj; /* Object output flag */ +}; + +/* + * The struct base contains a pointer to a + * base definition string and a link to the next + * base structure. + */ +struct base +{ + struct base *b_base; /* Base link */ + char *b_strp; /* String pointer */ +}; + +/* + * The struct globl contains a pointer to a + * global definition string and a link to the next + * global structure. + */ +struct globl +{ + struct globl *g_globl; /* Global link */ + char *g_strp; /* String pointer */ +}; + +/* + * A structure sdp is created for each 'unique' paged + * area definition found as the REL files are read. + * As P directives are read from the REL files a linked + * list of unique sdp structures is created by placing a + * link to the new sdp structure in the previous area structure. + */ +struct sdp +{ + struct area *s_area; /* Paged Area link */ + struct areax *s_areax; /* Paged Area Extension Link */ + a_uint s_addr; /* Page address offset */ +}; + +/* + * The structure rerr is loaded with the information + * required to report an error during the linking + * process. The structure contains an index value + * which selects the areax structure from the header + * areax structure list, a mode value which selects + * symbol or area relocation, the base address in the + * area section, an area/symbol list index value, and + * an area/symbol offset value. + */ +struct rerr +{ + int aindex; /* Linking area */ + int mode; /* Relocation mode */ + a_uint rtbase; /* Base address in section */ + int rindex; /* Area/Symbol reloaction index */ + a_uint rval; /* Area/Symbol offset value */ +}; + +/* + * The structure lbpath is created for each library + * path specification input by the -k option. The + * lbpath structures are linked into a list using + * the next link element. + */ +struct lbpath { + struct lbpath *next; + char *path; +}; + +/* + * The structure lbname is created for all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file. The element path points to + * the path string, element libfil points to the library + * file string, and the element libspc is the concatenation + * of the valid path and libfil strings. + * + * The lbpath structures are linked into a list + * using the next link element. + * + * Each library file contains a list of object files + * that are contained in the particular library. e.g.: + * + * \iolib\termio + * \inilib\termio + * + * Only one specification per line is allowed. + */ +struct lbname { + struct lbname *next; + char *path; + char *libfil; + char *libspc; + int f_obj; +}; + +/* + * The function fndsym() searches through all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file for a symbol definition. + * + * The structure lbfile is created for the first library + * object file which contains the definition for the + * specified undefined symbol. + * + * The element libspc points to the library file path specification + * and element relfil points to the object file specification string. + * The element filspc is the complete path/file specification for + * the library file to be imported into the linker. The f_obj + * flag specifies if the object code from this file is + * to be output by the linker. The file specification + * may be formed in one of two ways: + * + * (1) If the library file contained an absolute + * path/file specification then this becomes filspc. + * (i.e. C:\...) + * + * (2) If the library file contains a relative path/file + * specification then the concatenation of the path + * and this file specification becomes filspc. + * (i.e. \...) + * + * The lbpath structures are linked into a list + * using the next link element. + */ +struct lbfile { + struct lbfile *next; + char *libspc; + char *relfil; + char *filspc; + int f_obj; +}; + +/* + * External Definitions for all Global Variables + */ + +extern char *_abs_; /* = { ". .ABS." }; + */ +extern int lkerr; /* ASLink error flag + */ +extern char *ip; /* pointer into the REL file + * text line in ib[] + */ +extern char ib[NINPUT]; /* REL file text line + */ +extern char *rp; /* pointer into the LST file + * text line in rb[] + */ +extern char rb[NINPUT]; /* LST file text line being + * address relocated + */ +extern char ctype[]; /* array of character types, one per + * ASCII character + */ + +/* + * Character Type Definitions + */ +#define SPACE '\000' +#define ETC '\000' +#define LETTER '\001' +#define DIGIT '\002' +#define BINOP '\004' +#define RAD2 '\010' +#define RAD8 '\020' +#define RAD10 '\040' +#define RAD16 '\100' +#define ILL '\200' + +#define DGT2 DIGIT|RAD16|RAD10|RAD8|RAD2 +#define DGT8 DIGIT|RAD16|RAD10|RAD8 +#define DGT10 DIGIT|RAD16|RAD10 +#define LTR16 LETTER|RAD16 + +extern char ccase[]; /* an array of characters which + * perform the case translation function + */ + +extern struct lfile *filep; /* The pointers (lfile *) filep, + * (lfile *) cfp, and (FILE *) sfp + * are used in conjunction with + * the routine getline() to read + * asmlnk commands from + * (1) the standard input or + * (2) or a command file + * and to read the REL files + * sequentially as defined by the + * asmlnk input commands. + * + * The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + */ +extern struct lfile *cfp; /* The pointer *cfp points to the + * current lfile structure + */ +extern struct lfile *startp;/* asmlnk startup file structure + */ +#if 1 /* Nick */ +extern struct lfile *outfp; /* pointer to an lfile structure + * containing an input REL file + * specification, or -o specification + */ +#endif +extern struct lfile *linkp; /* pointer to first lfile structure + * containing an input REL file + * specification + */ +extern struct lfile *lfp; /* pointer to current lfile structure + * being processed by parse() + */ +extern struct head *headp; /* The pointer to the first + * head structure of a linked list + */ +extern struct head *hp; /* Pointer to the current + * head structure + */ +extern struct area *areap; /* The pointer to the first + * area structure of a linked list + */ +extern struct area *ap; /* Pointer to the current + * area structure + */ +extern struct areax *axp; /* Pointer to the current + * areax structure + */ +extern struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ +extern struct base *basep; /* The pointer to the first + * base structure + */ +extern struct base *bsp; /* Pointer to the current + * base structure + */ +extern struct globl *globlp;/* The pointer to the first + * globl structure + */ +extern struct globl *gsp; /* Pointer to the current + * globl structure + */ +extern struct sdp sdp; /* Base Paged structure + */ +extern struct rerr rerr; /* Structure containing the + * linker error information + */ +extern FILE *ofp; /* Linker Output file handle + */ +extern FILE *mfp; /* Map output file handle + */ +extern FILE *rfp; /* File handle for output + * address relocated ASxxxx + * listing file + */ +extern FILE *sfp; /* The file handle sfp points to the + * currently open file + */ +extern FILE *tfp; /* File handle for input + * ASxxxx listing file + */ +extern int oflag; /* Output file type flag + */ +extern int objflg; /* Linked file/library object output flag + */ +extern int mflag; /* Map output flag + */ +extern int xflag; /* Map file radix type flag + */ +extern int pflag; /* print linker command file flag + */ +extern int uflag; /* Listing relocation flag + */ +extern int wflag; /* Enable wide format listing + */ +extern int zflag; /* Enable symbol case sensitivity + */ +extern int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +extern int line; /* current line number + */ +extern int page; /* current page number + */ +extern int lop; /* current line number on page + */ +extern int pass; /* linker pass number + */ +extern int rtcnt; /* count of elements in the + * rtval[] and rtflg[] arrays + */ +extern a_uint rtval[]; /* data associated with relocation + */ +extern int rtflg[]; /* indicates if rtval[] value is + * to be sent to the output file. + */ +extern char rtbuf[]; /* S19/IHX output buffer + */ +extern int rtaflg; /* rtbuf[] processing + */ +extern a_uint rtadr0; /* + */ +extern a_uint rtadr1; /* + */ +extern a_uint rtadr2; /* + */ +extern int obj_flag; /* Linked file/library object output flag + */ +extern int a_bytes; /* REL file T Line address length + */ +extern int hilo; /* REL file byte ordering + */ +extern a_uint a_mask; /* Address Mask + */ +extern a_uint s_mask; /* Sign Mask + */ +extern a_uint v_mask; /* Value Mask + */ +extern int gline; /* LST file relocation active + * for current line + */ +extern int gcntr; /* LST file relocation active + * counter + */ +extern struct lbpath *lbphead; /* pointer to the first + * library path structure + */ +extern struct lbname *lbnhead; /* pointer to the first + * library name structure + */ +extern struct lbfile *lbfhead; /* pointer to the first + * library file structure + */ + +/* C Library function definitions */ +/* for reference only +extern VOID exit(); +extern int fclose(); +extern char * fgets(); +extern FILE * fopen(); +extern int fprintf(); +extern VOID free(); +extern VOID * malloc(); +extern char putc(); +extern char * strcpy(); +extern int strlen(); +extern char * strncpy(); +extern char * strrchr(); +*/ + +/* Program function definitions */ + +#ifdef OTHERSYSTEM + +/* lkmain.c */ +extern FILE * afile(char *fn, char *ft, int wf); +extern VOID bassav(void); +extern int fndidx(char *str); +extern VOID gblsav(void); +extern VOID link(void); +extern VOID lkexit(int i); +extern int main(int argc, char *argv[]); +extern VOID map(void); +extern int parse(void); +extern VOID doparse(void); +extern VOID setbas(void); +extern VOID setgbl(void); +extern VOID usage(int n); + +/* lklex.c */ +extern char endline(void); +extern int get(void); +extern VOID getfid(char *str, int c); +extern VOID getid(char *id, int c); +extern int getline(void); +extern int getmap(int d); +extern int getnb(void); +extern int more(void); +extern VOID skip(int c); +extern VOID unget(int c); + +/* lkarea.c */ +extern VOID lkparea(char *id); +extern VOID lnkarea(void); +extern VOID lnksect(struct area *tap); +extern VOID newarea(void); + +/* lkhead.c */ +extern VOID module(void); +extern VOID newhead(void); + +/* lksym.c */ +extern int hash(char *p, int cflag); +extern struct sym * lkpsym(char *id, int f); +extern char * new(unsigned int n); +extern struct sym * newsym(void); +extern char * strsto(char *str); +extern VOID symdef(FILE *fp); +extern int symeq(char *p1, char *p2, int cflag); +extern VOID syminit(void); +extern VOID symmod(FILE *fp, struct sym *tsp); +extern a_uint symval(struct sym *tsp); + +/* lkeval.c */ +extern int digit(int c, int r); +extern a_uint eval(void); +extern a_uint expr(int n); +extern int oprio(int c); +extern a_uint term(void); + +/* lklist.c */ +extern int dgt(int rdx, char *str, int n); +extern VOID newpag(FILE *fp); +extern VOID slew(struct area *xp); +extern VOID lstarea(struct area *xp); +extern VOID lkulist(int i); +extern VOID lkalist(a_uint pc); +extern VOID lkglist(a_uint pc, int v); + +/* lkrloc.c */ +extern a_uint adb_1b(a_uint v, int i); +extern a_uint adb_2b(a_uint v, int i); +extern a_uint adb_3b(a_uint v, int i); +extern a_uint adb_4b(a_uint v, int i); +extern a_uint adb_xb(a_uint v, int i); +#ifdef R_BYTE4 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ +extern a_uint adb_byte4(a_uint v, int i); +#endif +#ifdef R_BYTE3 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ +extern a_uint adb_byte3(a_uint v, int i); +#endif +extern a_uint adb_hi(a_uint v, int i); +extern a_uint adb_lo(a_uint v, int i); +extern a_uint adw_xb(int x, a_uint v, int i); +extern a_uint evword(void); +extern VOID rele(void); +extern VOID reloc(int c); +extern VOID relt(void); +extern VOID relr(void); +extern VOID relp(void); +extern VOID relerr(char *str); +extern char * errmsg[]; +extern VOID errdmp(FILE *fptr, char *str); +extern VOID relerp(char *str); +extern VOID erpdmp(FILE *fptr, char *str); +extern VOID prntval(FILE *fptr, a_uint v); + +/* lklibr.c */ +extern VOID addfile(char *path, char *libfil); +extern VOID addlib(void); +extern VOID addpath(void); +extern int fndsym(char *name); +extern VOID library(void); +extern VOID loadfile(char *filspc); +extern VOID search(void); + +/* lkout.c */ +extern VOID lkout(int i); +extern VOID ixx(int i); +extern VOID iflush(void); +extern VOID sxx(int i); +extern VOID sflush(void); + +#else + +/* lkmain.c */ +extern FILE * afile(); +extern VOID bassav(); +extern int fndidx(); +extern VOID gblsav(); +extern VOID link(); +extern VOID lkexit(); +extern int main(); +extern VOID map(); +extern int parse(); +extern VOID doparse(); +extern VOID setbas(); +extern VOID setgbl(); +extern VOID usage(); + +/* lklex.c */ +extern char endline(); +extern int get(); +extern VOID getfid(); +extern VOID getid(); +extern int getline(); +extern int getmap(); +extern int getnb(); +extern int more(); +extern VOID skip(); +extern VOID unget(); + +/* lkarea.c */ +extern VOID lkparea(); +extern VOID lnkarea(); +extern VOID lnksect(); +extern VOID newarea(); + +/* lkhead.c */ +extern VOID module(); +extern VOID newhead(); + +/* lksym.c */ +extern int hash(); +extern struct sym * lkpsym(); +extern VOID * new(); +extern struct sym * newsym(); +extern char * strsto(); +extern VOID symdef(); +extern int symeq(); +extern VOID syminit(); +extern VOID symmod(); +extern a_uint symval(); + +/* lkeval.c */ +extern int digit(); +extern a_uint eval(); +extern a_uint expr(); +extern int oprio(); +extern a_uint term(); + +/* lklist.c */ +extern int dgt(); +extern VOID newpag(); +extern VOID slew(); +extern VOID lstarea(); +extern VOID lkulist(); +extern VOID lkalist(); +extern VOID lkglist(); + +/* lkrloc.c */ +extern a_uint adb_1b(); +extern a_uint adb_2b(); +extern a_uint adb_3b(); +extern a_uint adb_4b(); +extern a_uint adb_xb(); +extern a_uint adb_hi(); +extern a_uint adb_lo(); +extern a_uint adw_xb(); +extern a_uint evword(); +extern VOID rele(); +extern VOID reloc(); +extern VOID relt(); +extern VOID relr(); +extern VOID relp(); +extern VOID relerr(); +extern char * errmsg[]; +extern VOID errdmp(); +extern VOID relerp(); +extern VOID erpdmp(); +extern VOID prntval(); + +/* lklibr.c */ +extern VOID addfile(); +extern VOID addlib(); +extern VOID addpath(); +extern int fndsym(); +extern VOID library(); +extern VOID loadfile(); +extern VOID search(); + +/* lkout.c */ +extern VOID lkout(); +extern VOID ixx(); +extern VOID iflush(); +extern VOID sxx(); +extern VOID sflush(); + +#endif + diff --git a/src/link-z80/link-z80.exe b/src/link-z80/link-z80.exe new file mode 100755 index 0000000000000000000000000000000000000000..f6760bf1dfa41e57c23be60e0fe451bc106ab6ab GIT binary patch literal 106545 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 LF}k{V9``>0Qgqci literal 0 HcmV?d00001 diff --git a/src/link-z80/link-z80.lnk b/src/link-z80/link-z80.lnk new file mode 100755 index 00000000..e99dbd90 --- /dev/null +++ b/src/link-z80/link-z80.lnk @@ -0,0 +1,16 @@ +/debug +/subsystem:console +"/libpath:c:\Program Files\Microsoft Visual Studio\VC98\lib" +/map:link-z80.map +/out:link-z80.exe +lkarea.obj +lkdata.obj +lkeval.obj +lkhead.obj +lklex.obj +lklibr.obj +lklist.obj +lkmain.obj +lkout.obj +lkrloc.obj +lksym.obj diff --git a/src/link-z80/lkarea.c b/src/link-z80/lkarea.c new file mode 100755 index 00000000..723d7c36 --- /dev/null +++ b/src/link-z80/lkarea.c @@ -0,0 +1,607 @@ +/* lkarea.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lkarea.c + * + * The module lkarea.c contains the functions which + * create and link together all area definitions read + * from the .rel file(s). + * + * lkarea.c contains the following functions: + * VOID lnkarea() + * VOID lnksect() + * VOID lkparea() + * VOID newarea() + * + * lkarea.c contains no global variables. + */ + +/*)Function VOID newarea() + * + * The function newarea() creates and/or modifies area + * and areax structures for each A directive read from + * the .rel file(s). The function lkparea() is called + * to find tha area structure associated with this name. + * If the area does not yet exist then a new area + * structure is created and linked to any existing + * linked area structures. The area flags are copied + * into the area flag variable. For each occurence of + * an A directive an areax structure is created and + * linked to the areax structures associated with this + * area. The size of this area section is placed into + * the areax structure. The flag value for all subsequent + * area definitions for the same area are compared and + * flagged as an error if they are not identical. + * The areax structure created for every occurence of + * an A directive is loaded with a pointer to the base + * area structure and a pointer to the associated + * head structure. And finally, a pointer to this + * areax structure is loaded into the list of areax + * structures in the head structure. Refer to lkdata.c + * for details of the structures and their linkage. + * + * local variables: + * areax **halp pointer to an array of pointers + * int i counter, loop variable, value + * char id[] id string + * int narea number of areas in this head structure + * areax * taxp pointer to an areax structure + * to areax structures + * + * global variables: + * area *ap Pointer to the current + * area structure + * areax *axp Pointer to the current + * areax structure + * head *hp Pointer to the current + * head structure + * int lkerr error flag + * + * functions called: + * a_uint eval() lkeval.c + * VOID exit() c_library + * int fprintf() c_library + * VOID getid() lklex.c + * VOID lkparea() lkarea.c + * VOID skip() lklex.c + * + * side effects: + * The area and areax structures are created and + * linked with the appropriate head structures. + * Failure to allocate area or areax structure + * space will terminate the linker. Other internal + * errors most likely caused by corrupted .rel + * files will also terminate the linker. + */ + +/* + * Create an area entry. + * + * A xxxxxx size nnnn flags mm + * | | | + * | | `-- ap->a_flag + * | `------------- axp->a_size + * `------------------------- ap->a_id + * + */ +VOID +newarea() +{ + register int i, narea; + struct areax *taxp; + struct areax **halp; + char id[NCPS]; + + /* + * Create Area entry + */ + getid(id, -1); + lkparea(id); + /* + * Evaluate area size + */ + skip(-1); + axp->a_size = eval(); + /* + * Evaluate flags + */ + skip(-1); + i = 0; + taxp = ap->a_axp; + while (taxp->a_axp) { + ++i; + taxp = taxp->a_axp; + } + if (i == 0) { + ap->a_flag = eval(); + } else { +#if 0 /* Nick */ + i = eval(); + if (i && (ap->a_flag != i)) { + fprintf(stderr, "Conflicting flags in area %s\n", id); + lkerr++; + } +#endif + } + /* + * Place pointer in header area list + */ + if (headp == NULL) { + fprintf(stderr, "No header defined\n"); + lkexit(ER_FATAL); + } + narea = hp->h_narea; + halp = hp->a_list; + for (i=0; i < narea ;++i) { + if (halp[i] == NULL) { + halp[i] = taxp; + return; + } + } + fprintf(stderr, "Header area list overflow\n"); + lkexit(ER_FATAL); +} + +/*)Function VOID lkparea(id) + * + * char * id pointer to the area name string + * + * The function lkparea() searches the linked area structures + * for a name match. If the name is not found then an area + * structure is created. An areax structure is created and + * appended to the areax structures linked to the area structure. + * The associated base area and head structure pointers are + * loaded into the areax structure. + * + * local variables: + * area * tap pointer to an area structure + * areax * taxp pointer to an areax structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * areax *axp Pointer to the current + * areax structure + * + * functions called: + * VOID * new() lksym() + * char * strsto() lksym.c + * int symeq() lksym.c + * + * side effects: + * Area and/or areax structures are created. + * Failure to allocate space for created structures + * will terminate the linker. + */ + +VOID +lkparea(id) +char *id; +{ + register struct area *tap; + register struct areax *taxp; + + ap = areap; + axp = (struct areax *) new (sizeof(struct areax)); + while (ap) { + if (symeq(id, ap->a_id, 0)) { + taxp = ap->a_axp; + while (taxp->a_axp) + taxp = taxp->a_axp; + taxp->a_axp = axp; + axp->a_bap = ap; + axp->a_bhp = hp; + return; + } + ap = ap->a_ap; + } + ap = (struct area *) new (sizeof(struct area)); + if (areap == NULL) { + areap = ap; + } else { + tap = areap; + while (tap->a_ap) + tap = tap->a_ap; + tap->a_ap = ap; + } + ap->a_axp = axp; + axp->a_bap = ap; + axp->a_bhp = hp; + ap->a_id = strsto(id); +} + +/*)Function VOID lnkarea() + * + * The function lnkarea() resolves all area addresses. + * The function evaluates each area structure (and all + * the associated areax structures) in sequence. The + * linking process supports four (4) possible area types: + * + * ABS/OVR - All sections (each individual areax + * section) starts at the identical base + * area address overlaying all other + * areax sections for this area. The + * size of the area is largest of the area + * sections. + * + * ABS/CON - All sections (each individual areax + * section) are concatenated with the + * first section starting at the base + * area address. The size of the area + * is the sum of the section sizes. + * + * NOTE: Multiple absolute (ABS) areas are + * never concatenated with each other, + * thus absolute area A and absolute area + * B will overlay each other if they begin + * at the same location (the default is + * always address 0 for absolute areas). + * + * REL/OVR - All sections (each individual areax + * section) starts at the identical base + * area address overlaying all other + * areax sections for this area. The + * size of the area is largest of the area + * sections. + * + * REL/CON - All sections (each individual areax + * section) are concatenated with the + * first section starting at the base + * area address. The size of the area + * is the sum of the section sizes. + * + * NOTE: Relocatable (REL) areas are always concatenated + * with each other, thus relocatable area B + * (defined after area A) will follow + * relocatable area A independent of the + * starting address of area A. Within a + * specific area each areax section may be + * overlayed or concatenated with other + * areax sections. + * + * + * If a base address for an area is specified then the + * area will start at that address. Any relocatable + * areas defined subsequently will be concatenated to the + * previous relocatable area if it does not have a base + * address specified. + * + * The names s_ and l_ are created to + * define the starting address and length of each area. + * + * local variables: + * a_uint rloc ;current relocation address + * char temp[] ;temporary string + * struct symbol *sp ;symbol structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * + * functions called: + * int fprintf() c_library + * VOID lnksect() lkarea.c + * symbol *lkpsym() lksysm.c + * char * strncpy() c_library + * int symeq() lksysm.c + * + * side effects: + * All area and areax addresses and sizes are + * determined and saved in their respective + * structures. + */ + +/* + * Resolve all area addresses. + */ +VOID +lnkarea() +{ + register int rloc; +#if 1 /* Nick */ + register int prloc; + register int bsize; +#endif + char temp[NCPS+2]; + struct sym *sp; + + rloc = 0; +#if 1 /* Nick */ + prloc = 0; + bsize = 0; +#endif + ap = areap; + while (ap) { + if (ap->a_flag&A_ABS) { + /* + * Absolute sections + */ + lnksect(ap); + } else { + /* + * Relocatable sections + */ + if (ap->a_bset == 0) + ap->a_addr = rloc; +#if 1 /* Nick */ + if (ap->a_pbset == 0) + { + ap->a_paddr = prloc; + } + if (ap->a_baset && (ap->a_bcflg == 0)) + { + /* it's a banked area, but not concatenated */ + /* so reset the counter for advancing banks */ + ap->a_bsize = 0; + } + else + { + /* banked area, pass in concatenation info */ + /* unbanked area, collect info resolve later */ + ap->a_bsize = bsize; + } +#endif + lnksect(ap); +#if 1 /* Nick */ + if ((ap->a_flag & A_NUL) == 0) + { + rloc = ap->a_addr + ap->a_size; + prloc = ap->a_paddr + ap->a_psize; + bsize = ap->a_bsize; /* place to concatenate */ + } +#else + rloc = ap->a_addr + ap->a_size; +#endif + } + + /* + * Create symbols called: + * s_ the start address of the area + * e_ the start of the following area (Nick) + * l_ the length of the area + */ + + if (! symeq(ap->a_id, _abs_, 0)) { + strcpy(temp+2, ap->a_id); + *(temp+1) = '_'; + + *temp = 's'; + sp = lkpsym(temp, 1); + sp->s_addr = ap->a_addr; + sp->s_axp = NULL; + sp->s_type |= S_DEF; + +#if 1 /* Nick */ + *temp = 'e'; + sp = lkpsym(temp, 1); + sp->s_addr = ap->a_addr + ap->a_size; + sp->s_axp = NULL; + sp->s_type |= S_DEF; +#endif + + *temp = 'l'; + sp = lkpsym(temp, 1); + sp->s_addr = ap->a_size; + sp->s_axp = NULL; + sp->s_type |= S_DEF; + } + ap = ap->a_ap; + } +} + +/*)Function VOID lnksect() + * + * area * tap pointer to an area structure + * + * The function lnksect() is the function called by + * lnkarea() to resolve the areax addresses. Refer + * to the function lnkarea() for more detail. Pageing + * boundary and length errors will be reported by this + * function. + * + * local variables: + * a_uint size size of area + * a_uint addr address of area + * areax * taxp pointer to an areax structure + * + * global variables: + * int lkerr error flag + * + * functions called: + * none + * + * side effects: + * All area and areax addresses and sizes area determined + * and linked into the structures. + */ + +VOID +lnksect(tap) +register struct area *tap; +{ + register a_uint size, addr; +#if 1 /* Nick */ + register a_uint psize, paddr; + register a_uint bsize, baddr, bbump; +#endif + register struct areax *taxp; + + size = 0; + addr = tap->a_addr; +#if 1 /* Nick */ + psize = 0; + paddr = tap->a_paddr; + bsize = tap->a_bsize; /* really the counter for advancing banks */ + baddr = tap->a_baddr; /* really the threshold for advancing banks */ +#endif + if ((tap->a_flag&A_PAG) && (addr & 0xFF)) { + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %s Boundary Error\n", + tap->a_id); + lkerr++; + } + taxp = tap->a_axp; + if (tap->a_flag&A_OVR) { + /* + * Overlayed sections + */ + while (taxp) { + taxp->a_addr = addr; +#if 1 /* Nick */ + taxp->a_paddr = paddr; +#endif + if (taxp->a_size > size) + size = taxp->a_size; +#if 1 /* Nick */ + if (taxp->a_size > psize) + psize = taxp->a_size; + if (taxp->a_size > bsize) + bsize = taxp->a_size; +#endif + taxp = taxp->a_axp; + } + } +#if 1 /* Nick */ + else if (tap->a_baset) /* if a banksize threshold has been set */ + { + /* concatenated sections, each must fit wholly within a bank */ + + /* if the start address has been explicitly set, it doesn't */ + /* take into account bytes or pages already occupied by non- */ + /* banked data from previously linked areas. in this case, */ + /* adjust it to compensate, although the value will be crazy */ + /* until the offset has been resolved into banks during the */ + /* loop below. it's done in this order to save code space. */ + if (tap->a_bset) + { + addr += bsize; + } + if (tap->a_pbset) + { + paddr += bsize; + } + + /* if this is the first areax section, we may need to skip */ + /* banks which are full of code from an earlier non-banked */ + /* area. if this is a subsequent areax section, or the */ + /* previous area was also banked, we just need to skip any */ + /* bytes already used in the current bank. in this latter */ + /* case the bank is only advanced when it has got too full. */ + while (taxp) + { +#if 0 + printf("%08x + %08x = %08x, baddr = %08x\n", + bsize, taxp->a_size, bsize + taxp->a_size, baddr); + fflush(stdout); +#endif + while ((bsize + taxp->a_size) > baddr) + { + if (bsize == 0) /* already at start of bank? */ + { + fprintf(stderr, + "\n?ASlink-Warning-" + "Banked Area %s " + "Length Error\n", + tap->a_id); +#if 0 + fflush(stderr); +#endif + lkerr++; + break; + } + + bbump = min(bsize, baddr); + bsize -= bbump; + + addr -= bbump; /* go back to start of page */ + size -= bbump; /* forget how much we used */ + if (tap->a_iset) /* logical increment set? */ + { + addr += tap->a_incr; + size += tap->a_incr; + } + else + { + addr += baddr; + size += baddr; + } + + paddr -= bbump; /* go back to start of page */ + psize -= bbump; /* forget how much we used */ + if (tap->a_piset) /* physical increment set? */ + { + paddr += tap->a_pincr; + psize += tap->a_pincr; + } + else + { + paddr += baddr; + psize += baddr; + } + } + + taxp->a_addr = addr; + taxp->a_paddr = paddr; + addr += taxp->a_size; + paddr += taxp->a_size; + bsize += taxp->a_size; + taxp = taxp->a_axp; + } + } +#endif + else { + /* + * Concatenated sections + */ + while (taxp) { + taxp->a_addr = addr; +#if 1 /* Nick */ + taxp->a_paddr = paddr; +#endif + addr += taxp->a_size; +#if 1 /* Nick */ + paddr += taxp->a_size; +#endif + size += taxp->a_size; +#if 1 /* Nick */ + psize += taxp->a_size; + bsize += taxp->a_size; +#endif + taxp = taxp->a_axp; + } + } + tap->a_size = size; +#if 1 /* Nick */ + tap->a_psize = psize; + tap->a_bsize = bsize; +#endif + if ((tap->a_flag&A_PAG) && (size > 256)) { + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %s Length Error\n", + tap->a_id); + lkerr++; + } +} diff --git a/src/link-z80/lkdata.c b/src/link-z80/lkdata.c new file mode 100755 index 00000000..cb742844 --- /dev/null +++ b/src/link-z80/lkdata.c @@ -0,0 +1,509 @@ +/* lkdata.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With enhancements from + * John L. Hartman (JLH) + * jhartman@compuserve.com + * + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lkdata.c + * + * The module lkdata contains the global variables + * and structures used in the linker aslink. + */ + +/* + * Definitions for all Global Variables + */ + +char *_abs_ = { ". .ABS." }; + +int lkerr; /* Linker error flag + */ +char *ip; /* Pointer into the REL file text line in ib[] + */ +char ib[NINPUT]; /* REL file text line + */ +char *rp; /* pointer into the LST file + * text line in rb[] + */ +char rb[NINPUT]; /* LST file text line being + * address relocated + */ +int oflag; /* Output file type flag + */ +int objflg; /* Linked file/library object output flag + */ +int mflag; /* Map output flag + */ +int xflag; /* Map file radix type flag + */ +int pflag; /* print linker command file flag + */ +int uflag; /* Listing relocation flag + */ +int wflag; /* Enable wide format listing + */ +int zflag; /* Enable symbol case sensitivity + */ +int radix; /* current number conversion radix: + * 2 (binary), 8 (octal), 10 (decimal), + * 16 (hexadecimal) + */ +int line; /* current line number + */ +int page; /* current page number + */ +int lop; /* current line number on page + */ +int pass; /* linker pass number + */ +int rtcnt; /* count of elements in the + * rtval[] and rtflg[] arrays + */ +a_uint rtval[NTXT]; /* data associated with relocation + */ +int rtflg[NTXT]; /* indicates if rtval[] value is + * to be sent to the output file. + */ +char rtbuf[NMAX]; /* S19/IHX output buffer + */ +int rtaflg = 1; /* rtbuf[] processing + */ +a_uint rtadr0 = 0; /* + */ +a_uint rtadr1 = 0; /* + */ +a_uint rtadr2 = 0; /* + */ +int obj_flag = 0; /* Linked file/library object output flag + */ +int a_bytes; /* REL file T Line address length + */ +int hilo; /* REL file byte ordering + */ +a_uint a_mask; /* Address Mask + */ +a_uint s_mask; /* Sign Mask + */ +a_uint v_mask; /* Value Mask + */ +int gline; /* LST file relocation active + * for current line + */ +int gcntr; /* LST file relocation active + * counter + */ + +/* + * The structure lfile contains a pointer to a + * file specification string, an index which points + * to the file name (past the 'path'), the file type, + * an object output flag, and a link to the next + * lfile structure. + * + * struct lfile + * { + * struct lfile *f_flp; lfile link + * int f_type; File type + * char *f_idp; Pointer to file spec + * int f_idx; Index to file name + * int f_obj; Object output flag + * }; + */ +struct lfile *filep; /* The pointers (lfile *) filep, + * (lfile *) cfp, and (FILE *) sfp + * are used in conjunction with + * the routine getline() to read + * asmlnk commands from + * (1) the standard input or + * (2) or a command file + * and to read the REL files + * sequentially as defined by the + * asmlnk input commands. + * + * The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + */ +struct lfile *cfp; /* The pointer *cfp points to the + * current lfile structure + */ +struct lfile *startp;/* asmlnk startup file structure + */ +#if 1 /* Nick */ +struct lfile *outfp; /* pointer to an lfile structure + * containing an input REL file + * specification, or -o specification + */ +#endif +struct lfile *linkp; /* pointer to first lfile structure + * containing an input REL file + * specification + */ +struct lfile *lfp; /* pointer to current lfile structure + * being processed by parse() + */ +FILE *ofp; /* Output file handle + * for word formats + */ +FILE *mfp; /* Map output file handle + */ +FILE *rfp; /* File handle for output + * address relocated ASxxxx + * listing file + */ +FILE *sfp; /* The file handle sfp points to the + * currently open file + */ +FILE *tfp; /* File handle for input + * ASxxxx listing file + */ + +/* + * The structures of head, area, areax, and sym are created + * as the REL files are read during the first pass of the + * linker. The struct head is created upon encountering a + * H directive in the REL file. The structure contains a + * link to a link file structure (struct lfile) which describes + * the file containing the H directive, the number of data/code + * areas contained in this header segment, the number of + * symbols referenced/defined in this header segment, a pointer + * to an array of pointers to areax structures (struct areax) + * created as each A directive is read, and a pointer to an + * array of pointers to symbol structures (struct sym) for + * all referenced/defined symbols. As H directives are read + * from the REL files a linked list of head structures is + * created by placing a link to the new head structure + * in the previous head structure. + * + * struct head + * { + * struct head *h_hp; Header link + * struct lfile *h_lfile; Associated file + * int h_narea; # of areas + * struct areax **a_list; Area list + * int h_nglob; # of global symbols + * struct sym **s_list; Global symbol list + * char * m_id; Module name + * }; + */ +struct head *headp; /* The pointer to the first + * head structure of a linked list + */ +struct head *hp; /* Pointer to the current + * head structure + */ + +/* + * A structure area is created for each 'unique' data/code + * area definition found as the REL files are read. The + * struct area contains the name of the area, a flag byte + * which contains the area attributes (REL/CON/OVR/ABS), + * the area base address set flag byte (-b option), and the + * area base address and total size which will be filled + * in at the end of the first pass through the REL files. + * As A directives are read from the REL files a linked + * list of unique area structures is created by placing a + * link to the new area structure in the previous area structure. + * + * struct area + * { + * struct area *a_ap; Area link + * struct areax *a_axp; Area extension link + * a_uint a_addr; Beginning address of area + * a_uint a_size; Total size of the area + * char a_bset; Area base address set + * char a_flag; Flag byte + * char * a_id; Name + * }; + */ +struct area *areap; /* The pointer to the first + * area structure of a linked list + */ +struct area *ap; /* Pointer to the current + * area structure + */ + +/* + * An areax structure is created for every A directive found + * while reading the REL files. The struct areax contains a + * link to the 'unique' area structure referenced by the A + * directive and to the head structure this area segment is + * a part of. The size of this area segment as read from the + * A directive is placed in the areax structure. The beginning + * address of this segment will be filled in at the end of the + * first pass through the REL files. As A directives are read + * from the REL files a linked list of areax structures is + * created for each unique area. The final areax linked + * list has at its head the 'unique' area structure linked + * to the linked areax structures (one areax structure for + * each A directive for this area). + * + * struct areax + * { + * struct areax *a_axp; Area extension link + * struct area *a_bap; Base area link + * struct head *a_bhp; Base header link + * a_uint a_addr; Beginning address of section + * a_uint a_size; Size of the area in section + * }; + */ +struct areax *axp; /* Pointer to the current + * areax structure + */ + +/* + * A sym structure is created for every unique symbol + * referenced/defined while reading the REL files. The + * struct sym contains the symbol's name, a flag value + * (not used in this linker), a symbol type denoting + * referenced/defined, and an address which is loaded + * with the relative address within the area in which + * the symbol was defined. The sym structure also + * contains a link to the area where the symbol was defined. + * The sym structures are linked into linked lists using + * the symbol link element. + * + * struct sym + * { + * struct sym *s_sp; Symbol link + * struct areax *s_axp; Symbol area link + * char s_type; Symbol subtype + * char s_flag; Flag byte + * a_uint s_addr; Address + * char *s_id; Name (JLH) + * char *m_id; Module + * }; + */ +struct sym *symhash[NHASH]; /* array of pointers to NHASH + * linked symbol lists + */ +/* + * The struct base contains a pointer to a + * base definition string and a link to the next + * base structure. + * + * struct base + * { + * struct base *b_base; Base link + * char *b_strp; String pointer + * }; + */ +struct base *basep; /* The pointer to the first + * base structure + */ +struct base *bsp; /* Pointer to the current + * base structure + */ + +/* + * The struct globl contains a pointer to a + * global definition string and a link to the next + * global structure. + * + * struct globl + * { + * struct globl *g_globl; Global link + * char *g_strp; String pointer + * }; + */ +struct globl *globlp;/* The pointer to the first + * globl structure + */ +struct globl *gsp; /* Pointer to the current + * globl structure + */ + +/* + * A structure sdp is created for each 'unique' paged + * area definition found as the REL files are read. + * As P directives are read from the REL files a linked + * list of unique sdp structures is created by placing a + * link to the new sdp structure in the previous area structure. + * + * struct sdp + * { + * struct area *s_area; Paged Area link + * struct areax *s_areax; Paged Area Extension Link + * a_uint s_addr; Page address offset + * }; + */ +struct sdp sdp; /* Base Page Structure */ + +/* + * The structure rerr is loaded with the information + * required to report an error during the linking + * process. The structure contains an index value + * which selects the areax structure from the header + * areax structure list, a mode value which selects + * symbol or area relocation, the base address in the + * area section, an area/symbol list index value, and + * an area/symbol offset value. + * + * struct rerr + * { + * int aindex; Linking area + * int mode; Relocation mode + * a_uint rtbase; Base address in section + * int rindex; Area/Symbol reloaction index + * a_uint rval; Area/Symbol offset value + * }; + */ +struct rerr rerr; /* Structure containing the + * linker error information + */ + +/* + * The structure lbpath is created for each library + * path specification input by the -k option. The + * lbpath structures are linked into a list using + * the next link element. + * + * struct lbpath { + * struct lbpath *next; + * char *path; + * }; + */ +struct lbpath *lbphead; /* pointer to the first + * library path structure + */ + +/* + * The structure lbname is created for all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file. The element path points to + * the path string, element libfil points to the library + * file string, and the element libspc is the concatenation + * of the valid path and libfil strings. + * + * The lbpath structures are linked into a list + * using the next link element. + * + * Each library file contains a list of object files + * that are contained in the particular library. e.g.: + * + * \iolib\termio + * \inilib\termio + * + * Only one specification per line is allowed. + * + * struct lbname { + * struct lbname *next; + * char *path; + * char *libfil; + * char *libspc; + * char f_obj; + * }; + */ +struct lbname *lbnhead; /* pointer to the first + * library name structure + */ + +/* + * The function fndsym() searches through all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file for a symbol definition. + * + * The structure lbfile is created for the first library + * object file which contains the definition for the + * specified undefined symbol. + * + * The element libspc points to the library file path specification + * and element relfil points to the object file specification string. + * The element filspc is the complete path/file specification for + * the library file to be imported into the linker. The f_obj + * flag specifies if the object code from this file is + * to be output by the linker. The file specification + * may be formed in one of two ways: + * + * (1) If the library file contained an absolute + * path/file specification then this becomes filspc. + * (i.e. C:\...) + * + * (2) If the library file contains a relative path/file + * specification then the concatenation of the path + * and this file specification becomes filspc. + * (i.e. \...) + * + * The lbpath structures are linked into a list + * using the next link element. + * + * struct lbfile { + * struct lbfile *next; + * char *libspc; + * char *relfil; + * char *filspc; + * int f_obj; + * }; + */ +struct lbfile *lbfhead; /* pointer to the first + * library file structure + */ + +/* + * array of character types, one per + * ASCII character + */ +char ctype[128] = { +/*NUL*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*BS*/ ILL, SPACE, ILL, ILL, SPACE, ILL, ILL, ILL, +/*DLE*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*CAN*/ ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL, +/*SPC*/ SPACE, ETC, ETC, ETC, LETTER, BINOP, BINOP, ETC, +/*(*/ ETC, ETC, BINOP, BINOP, ETC, BINOP, LETTER, BINOP, +/*0*/ DGT2, DGT2, DGT8, DGT8, DGT8, DGT8, DGT8, DGT8, +/*8*/ DGT10, DGT10, ETC, ETC, BINOP, ETC, BINOP, ETC, +/*@*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*H*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*P*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*X*/ LETTER, LETTER, LETTER, ETC, ETC, ETC, BINOP, LETTER, +/*`*/ ETC, LTR16, LTR16, LTR16, LTR16, LTR16, LTR16, LETTER, +/*h*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*p*/ LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, +/*x*/ LETTER, LETTER, LETTER, ETC, BINOP, ETC, ETC, ETC +}; + +/* + * an array of characters which + * perform the case translation function + */ +char ccase[128] = { +/*NUL*/ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', +/*BS*/ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', +/*DLE*/ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', +/*CAN*/ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', +/*SPC*/ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', +/*(*/ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', +/*0*/ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', +/*8*/ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', +/*@*/ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*H*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*P*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*X*/ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', +/*`*/ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', +/*h*/ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', +/*p*/ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', +/*x*/ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177' +}; diff --git a/src/link-z80/lkeval.c b/src/link-z80/lkeval.c new file mode 100755 index 00000000..b303afa0 --- /dev/null +++ b/src/link-z80/lkeval.c @@ -0,0 +1,443 @@ +/* lkeval.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lkeval.c + * + * The module lkeval.c contains the routines to evaluate + * arithmetic/numerical expressions. The functions in + * lkeval.c perform a recursive evaluation of the arithmetic + * expression read from the input text line. + * The expression may include binary/unary operators, brackets, + * symbols, labels, and constants in hexadecimal, decimal, octal + * and binary. Arithmetic operations are prioritized and + * evaluated by normal arithmetic conventions. + * + * lkeval.c contains the following functions: + * int digit() + * a_uint eval() + * a_uint expr() + * int oprio() + * a_uint term() + * + * lkeval.c contains no local/static variables + */ + +/*)Function a_uint eval() + * + * The function eval() evaluates a character string to a + * numerical value. + * + * Notes about the arithmetic: + * The coding emulates X-Bit unsigned + * arithmetic operations. This allows + * program compilation without regard to the + * intrinsic integer length of the host + * machine. + * + * local variables: + * int c character from input string + * int v value of character in current radix + * a_uint n evaluation value + * + * global variables: + * int radix current number conversion radix + * + * functions called: + * int digit() lkeval.c + * int get() lklex.c + * int getnb() lklex.c + * VOID unget() lklex.c + * + * side effects: + * Input test is scanned and evaluated to a + * numerical value. + */ + +a_uint +eval() +{ + register int c, v; + register a_uint n; + + c = getnb(); + n = 0; + while ((v = digit(c, radix)) >= 0) { + n = n*radix + v; + c = get(); + } + unget(c); + return((n & s_mask) ? n | ~v_mask : n & v_mask); +} + +/*)Function a_uint expr(n) + * + * int n a firewall priority; all top + * level calls (from the user) + * should be made with n set to 0. + * + * The function expr() evaluates an expression and + * returns the value. + * + * Notes about the arithmetic: + * The coding emulates X-Bit unsigned + * arithmetic operations. This allows + * program compilation without regard to the + * intrinsic integer length of the host + * machine. + * + * local variables: + * int c current input text character + * int p current operator priority + * a_uint v value returned by term() + * a_uint ve value returned by a + * recursive call to expr() + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * int lkerr error flag + * FILE * stderr c_library + * + * functions called: + * VOID expr() lkeval.c + * int fprintf() c_library + * int getnb() lklex.c + * int oprio() lkeval.c + * VOID term() lkeval.c + * VOID unget() lklex.c + * + * + * side effects: + * An expression is evaluated by scanning the input + * text string. + */ + +a_uint +expr (n) +int n; +{ + register int c, p; + register a_uint v, ve; + + v = term(); + while (ctype[c = getnb()] & BINOP) { + if ((p = oprio(c)) <= n) + break; + if ((c == '>' || c == '<') && c != get()) { + fprintf(stderr, "Invalid expression"); + lkerr++; + return(v); + } + ve = expr(p); + + /* + * X-Bit Unsigned Arithmetic + */ + v &= a_mask; + ve &= a_mask; + + if (c == '+') { + v += ve; + } else + if (c == '-') { + v -= ve; + } else { + switch (c) { + + case '*': + v *= ve; + break; + + case '/': + if (ve == 0) { + v = 0; + } else { + v /= ve; + } + break; + + case '&': + v &= ve; + break; + + case '|': + v |= ve; + break; + + case '%': + if (ve == 0) { + v = 0; + } else { + v %= ve; + } + break; + + case '^': + v ^= ve; + break; + + case '<': + v <<= ve; + break; + + case '>': + v >>= ve; + break; + } + } + v = (v & s_mask) ? v | ~v_mask : v & v_mask; + } + unget(c); + return(v); +} + +/*)Function a_uint term() + * + * The function term() evaluates a single constant + * or symbol value prefaced by any unary operator + * ( +, -, ~, ', ", >, or < ). + * + * Notes about the arithmetic: + * The coding emulates X-Bit unsigned + * arithmetic operations. This allows + * program compilation without regard to the + * intrinsic integer length of the host + * machine. + * + * local variables: + * int c current character + * char id[] symbol name + * int n value of digit in current radix + * int r current evaluation radix + * sym * sp pointer to a sym structure + * a_uint v evaluation value + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * int lkerr error flag + * + * functions called: + * int digit() lkeval.c + * VOID expr() lkeval.c + * int fprintf() c_library + * int get() lklex.c + * VOID getid() lklex.c + * int getmap() lklex.c + * int getnb() lklex.c + * sym * lkpsym() lksym.c + * a_uint symval() lksym.c + * VOID unget() lklex.c + * + * side effects: + * An arithmetic term is evaluated by scanning input text. + */ + +a_uint +term() +{ + register int c, r, n; + register a_uint v; + struct sym *sp; + char id[NCPS]; + + c = getnb(); + if (c == '#') { c = getnb(); } + if (c == '(') { + v = expr(0); + if (getnb() != ')') { + fprintf(stderr, "Missing delimiter"); + lkerr++; + } + return(v); + } + if (c == '-') { + return(~expr(100)+1); + } + if (c == '~') { + return(~expr(100)); + } + if (c == '\'') { + return(getmap(-1)&0377); + } + if (c == '\"') { + if (hilo) { + v = (getmap(-1)&0377)<<8; + v |= getmap(-1)&0377; + } else { + v = getmap(-1)&0377; + v |= (getmap(-1)&0377)<<8; + } + return((v & s_mask) ? v | ~v_mask : v & v_mask); + } + if (c == '>' || c == '<') { + v = expr(100); + if (c == '>') + v >>= 8; + return(v&0377); + } + if (ctype[c] & DIGIT) { + r = 10; + if (c == '0') { + c = get(); + switch (c) { + case 'b': + case 'B': + r = 2; + c = get(); + break; + case '@': + case 'o': + case 'O': + case 'q': + case 'Q': + r = 8; + c = get(); + break; + case 'd': + case 'D': + r = 10; + c = get(); + break; + case 'h': + case 'H': + case 'x': + case 'X': + r = 16; + c = get(); + break; + default: + break; + } + } + v = 0; + while ((n = digit(c, r)) >= 0) { + v = r*v + n; + c = get(); + } + unget(c); + return((v & s_mask) ? v | ~v_mask : v & v_mask); + } + if (ctype[c] & LETTER) { + getid(id, c); + if ((sp = lkpsym(id, 0)) == NULL) { + fprintf(stderr, "Undefined symbol %s\n", id); + lkerr++; + return(0); + } else { + return(symval(sp)); + } + } + fprintf(stderr, "Unknown operator %c\n", c); + lkerr++; + return(0); +} + +/*)Function int digit(c, r) + * + * int c digit character + * int r current radix + * + * The function digit() returns the value of c + * in the current radix r. If the c value is not + * a number of the current radix then a -1 is returned. + * + * local variables: + * none + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * + * functions called: + * none + * + * side effects: + * none + */ + +int +digit(c, r) +register int c, r; +{ + if (r == 16) { + if (ctype[c] & RAD16) { + if (c >= 'A' && c <= 'F') + return (c - 'A' + 10); + if (c >= 'a' && c <= 'f') + return (c - 'a' + 10); + return (c - '0'); + } + } else + if (r == 10) { + if (ctype[c] & RAD10) + return (c - '0'); + } else + if (r == 8) { + if (ctype[c] & RAD8) + return (c - '0'); + } else + if (r == 2) { + if (ctype[c] & RAD2) + return (c - '0'); + } + return (-1); +} + +/*)Function int oprio(c) + * + * int c operator character + * + * The function oprio() returns a relative priority + * for all valid unary and binary operators. + * + * local variables: + * none + * + * global variables: + * none + * + * functions called: + * none + * + * side effects: + * none + */ + +int +oprio(c) +register int c; +{ + if (c == '*' || c == '/' || c == '%') + return (10); + if (c == '+' || c == '-') + return (7); + if (c == '<' || c == '>') + return (5); + if (c == '^') + return (4); + if (c == '&') + return (3); + if (c == '|') + return (1); + return (0); +} diff --git a/src/link-z80/lkhead.c b/src/link-z80/lkhead.c new file mode 100755 index 00000000..5f7622fc --- /dev/null +++ b/src/link-z80/lkhead.c @@ -0,0 +1,164 @@ +/* lkhead.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*Module lkhead.c + * + * The module lkhead.c contains the function newhead() which + * creates a head structure and the function module() which + * loads the module name into the current head structure. + * + * lkhead.c contains the following functions: + * VOID newhead() + * VOID module() + * + * lkhead.c contains no local variables. + */ + +/*)Function VOID newhead() + * + * The function newhead() creates a head structure. All head + * structures are linked to form a linked list of head structures + * with the current head structure at the tail of the list. + * + * local variables: + * int i evaluation value + * head * thp temporary pointer + * to a header structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * lfile *cfp The pointer *cfp points to the + * current lfile structure + * head *headp The pointer to the first + * head structure of a linked list + * head *hp Pointer to the current + * head structure + * + * functions called: + * a_uint expr() lkeval.c + * VOID * new() lksym.c + * VOID lkparea() lkarea.c + * + * side effects: + * A new head structure is created and linked to any + * existing linked head structure. The head structure + * parameters of file handle, number of areas, and number + * of global symbols are loaded into the structure. + * The default area "_abs_" is created when the first + * head structure is created and an areax structure is + * created for every head structure called. + */ + +/* + * Create a new header entry. + * + * H n areas n global symbols + * | | + * | `---- hp->h_nglob + * `------------ hp->h_narea + * + */ +VOID +newhead() +{ + register int i; + struct head *thp; + + hp = (struct head *) new (sizeof(struct head)); + if (headp == NULL) { + headp = hp; + } else { + thp = headp; + while (thp->h_hp) + thp = thp->h_hp; + thp->h_hp = hp; + } + /* + * Defalt to No Module Defined + */ + hp->m_id = ""; + /* + * Set file pointer + */ + hp->h_lfile = cfp; + /* + * Evaluate and build Area pointer list + */ + i = hp->h_narea = eval(); + if (i) + hp->a_list = (struct areax **) new (i*sizeof(struct areax *)); + /* + * Evaluate and build Global symbol pointer list + */ + skip(-1); + i = hp->h_nglob = eval(); + if (i) + hp->s_list = (struct sym **) new (i*sizeof(struct sym *)); + /* + * Setup Absolute DEF linkage. + */ + lkparea(_abs_); + ap->a_flag = A_ABS|A_OVR; +} + +/*)Function VOID module() + * + * The function module() copies the module name into + * the current head structure. + * + * local variables: + * char id[] module id string + * + * global variables: + * head *headp The pointer to the first + * head structure of a linked list + * head *hp Pointer to the current + * head structure + * int lkerr error flag + * FILE * stderr c_library + * + * functions called: + * int fprintf() c_library + * VOID getid() lklex.c + * char * strsto() lksym.c + * + * side effects: + * The module name is copied into the head structure. + */ + +/* + * Module Name + */ +VOID +module() +{ + char id[NCPS]; + + if (headp) { + getid(id, -1); + hp->m_id = strsto(id); + } else { + fprintf(stderr, "No header defined\n"); + lkerr++; + } +} diff --git a/src/link-z80/lklex.c b/src/link-z80/lklex.c new file mode 100755 index 00000000..228ec57f --- /dev/null +++ b/src/link-z80/lklex.c @@ -0,0 +1,537 @@ +/* lklex.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lklex.c + * + * The module lklex.c contains the general lexical analysis + * functions used to scan the text lines from the .rel files. + * + * lklex.c contains the fllowing functions: + * char endline() + * int get() + * VOID getfid() + * VOID getid() + * int getline() + * int getmap() + * int getnb() + * int more() + * VOID skip() + * VOID unget() + * + * lklex.c contains no local variables. + */ + +/*)Function VOID getid(id,c) + * + * char * id a pointer to a string of + * maximum length NCPS-1 + * int c mode flag + * >=0 this is first character to + * copy to the string buffer + * <0 skip white space + * + * The function getid() scans the current input text line + * from the current position copying the next LETTER | DIGIT string + * into the external string buffer (id). The string ends when a non + * LETTER or DIGIT character is found. The maximum number of characters + * copied is NCPS-1. If the input string is larger than NCPS-1 + * characters then the string is truncated. The string is always + * NULL terminated. If the mode argument (c) is >=0 then (c) is + * the first character copied to the string buffer, if (c) is <0 + * then intervening white space (SPACES and TABS) are skipped. + * + * local variables: + * char * p pointer to external string buffer + * int c current character value + * + * global variables: + * char ctype[] a character array which defines the + * type of character being processed. + * This index is the character + * being processed. + * + * called functions: + * int get() lklex.c + * int getnb() lklex.c + * VOID unget() lklex.c + * + * side effects: + * use of getnb(), get(), and unget() updates the + * global pointer ip the position in the current + * input text line. + */ + +VOID +getid(id, c) +register int c; +char *id; +{ + register char *p; + + if (c < 0) { + c = getnb(); + } + p = id; + do { + if (p < &id[NCPS-1]) + *p++ = c; + } while (ctype[c=get()] & (LETTER|DIGIT)); + unget(c); + *p++ = 0; +} + +/*)Function VOID getfid(str,c) + * + * char * str a pointer to a string of + * maximum length FILSPC-1 + * int c this is first character to + * copy to the string buffer + * + * The function getfid() copies a string of characters from + * the current text line into the external string buffer (str). + * The maximum number of characters copied is FILSPC-1. The + * string is terminated by a 'space', 'tab' or end of string. + * + * local variables: + * char * p pointer to external string buffer + * int c current character value + * + * called functions: + * int get() lklex.c + * + * side effects: + * use of get() updates the global pointer ip + * the position in the current input text line. + */ + +VOID +getfid(str, c) +register int c; +char *str; +{ + register char *p; + + p = str; + do { + if (p < &str[FILSPC-1]) + *p++ = c; + c = get(); + } while ((c != 0) && (c != ' ') && (c != '\t')); + *p++ = 0; +} + +/*)Function int getnb() + * + * The function getnb() scans the current input text + * line returning the first character not a SPACE or TAB. + * + * local variables: + * int c current character from input + * + * global variables: + * none + * + * called functions: + * int get() lklex.c + * + * side effects: + * use of get() updates the global pointer ip, the position + * in the current input text line + */ + +int +getnb() +{ + register int c; + + while ((c=get())==' ' || c=='\t') + ; + return (c); +} + +/*)Function VOID skip(c) + * + * The function skip() scans the input text skipping all + * letters and digits. + * + * local variables: + * int c last character read + * none + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * + * functions called: + * int get() lklex.c + * int getnb() lklex.c + * VOID unget() lklex.c + * + * side effects: + * Input letters and digits are skipped. + */ + +VOID +skip(c) +register int c; +{ + if (c < 0) + c = getnb(); + while (ctype[c=get()] & (LETTER|DIGIT)) { ; } + unget(c); +} + +/*)Function int get() + * + * The function get() returns the next character in the + * input text line, at the end of the line a + * NULL character is returned. + * + * local variables: + * int c current character from + * input text line + * + * global variables: + * char * ip pointer into the current + * input text line + * + * called functions: + * none + * + * side effects: + * updates ip to the next character position in the + * input text line. If ip is at the end of the + * line, ip is not updated. + */ + +int +get() +{ + register int c; + + if ((c = *ip) != 0) + ++ip; + return (c & 0x007F); +} + +/*)Function VOID unget(c) + * + * int c value of last character + * read from input text line + * + * If (c) is not a NULL character then the global pointer ip + * is updated to point to the preceeding character in the + * input text line. + * + * NOTE: This function does not push the character (c) + * back into the input text line, only + * the pointer ip is changed. + * + * local variables: + * int c last character read + * from input text line + * + * global variables: + * char * ip position into the current + * input text line + * + * called functions: + * none + * + * side effects: + * ip decremented by 1 character position + */ + +VOID +unget(c) +int c; +{ + if (c != 0) + --ip; +} + +/*)Function int getmap(d) + * + * int d value to compare with the + * input text line character + * + * The function getmap() converts the 'C' style characters \b, \f, + * \n, \r, and \t to their equivalent ascii values and also + * converts 'C' style octal constants '\123' to their equivalent + * numeric values. If the first character is equivalent to (d) then + * a (-1) is returned, if the end of the line is detected then + * a 'q' error terminates the parse for this line, or if the first + * character is not a \ then the character value is returned. + * + * local variables: + * int c value of character + * from input text line + * int n looping counter + * int v current value of numeric conversion + * + * global variables: + * none + * + * called functions: + * int get() lklex.c + * VOID unget() lklex.c + * + * side effects: + * use of get() updates the global pointer ip the position + * in the current input text line + */ + +int +getmap(d) +int d; +{ + register int c, n, v; + + if ((c = get()) == '\0') + return (-1); + if (c == d) + return (-1); + if (c == '\\') { + c = get(); + switch (c) { + + case 'b': + c = '\b'; + break; + + case 'f': + c = '\f'; + break; + + case 'n': + c = '\n'; + break; + + case 'r': + c = '\r'; + break; + + case 't': + c = '\t'; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + n = 0; + v = 0; + while (++n<=3 && c>='0' && c<='7') { + v = (v<<3) + c - '0'; + c = get(); + } + unget(c); + c = v; + break; + } + } + return (c); +} + +/*)Function int getline() + * + * The function getline() reads a line of input text from a + * .rel source text file, a .lnk command file or from stdin. + * Lines of text are processed from a single .lnk file or + * multiple .rel files until all files have been read. + * The input text line is copied into the global string ib[] + * and converted to a NULL terminated string. The function + * getline() returns a (1) after succesfully reading a line + * or a (0) if all files have been read. + * This function also opens each input .lst file and output + * .rst file as each .rel file is processed. + * + * local variables: + * int i string length + * int ftype file type + * char * fid file name + * + * global variables: + * lfile *cfp The pointer *cfp points to the + * current lfile structure + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * int gline get a line from the LST file + * to translate for the RST file + * char ib[NINPUT] REL file text line + * int pass linker pass number + * int pflag print linker command file flag + * FILE *rfp The file handle to the current + * output RST file + * FILE *sfp The file handle sfp points to the + * currently open file + * FILE * stdin c_library + * FILE * stdout c_library + * FILE *tfp The file handle to the current + * LST file being scanned + * int uflag update listing flag + * + * called functions: + * FILE * afile() lkmain.c + * int fclose() c_library + * char * fgets() c_library + * int fprintf() c_library + * VOID lkulist() lklist.c + * VOID lkexit() lkmain.c + * int strlen() c_library + * + * side effects: + * The input stream is scanned. The .rel files will be + * opened and closed sequentially scanning each in turn. + */ + +int +getline() +{ + register int i, ftype; + register char *fid; + +loop: if (cfp && cfp->f_type == F_STD) + fprintf(stdout, "ASlink >> "); + + if (sfp == NULL || fgets(ib, sizeof(ib)-2, sfp) == NULL) { + obj_flag = 0; + if (sfp) { + if(sfp != stdin) { + fclose(sfp); + } + sfp = NULL; + lkulist(0); + } + if (cfp == NULL) { + cfp = filep; + } else { + cfp = cfp->f_flp; + } + if (cfp) { + ftype = cfp->f_type; + fid = cfp->f_idp; + if (ftype == F_STD) { + sfp = stdin; + } else + if (ftype == F_LNK) { + sfp = afile(fid, "lnk", 0); + } else + if (ftype == F_REL) { + obj_flag = cfp->f_obj; + sfp = afile(fid, "", 0); + if (uflag && (obj_flag == 0) && pass != 0) { + if ((tfp = afile(fid, "lst", 0)) != NULL) { + if ((rfp = afile(fid, "rst", 1)) == NULL) { + fclose(tfp); + tfp = NULL; + } + } + } + gline = 1; + } else { + fprintf(stderr, "Invalid file type\n"); + lkexit(ER_FATAL); + } + if (sfp == NULL) { + lkexit(ER_FATAL); + } + goto loop; + } else { + filep = NULL; + return(0); + } + } + i = strlen(ib) - 1; + if (ib[i] == '\n') + ib[i] = 0; + return (1); +} + +/*)Function int more() + * + * The function more() scans the input text line + * skipping white space (SPACES and TABS) and returns a (0) + * if the end of the line or a comment delimeter (;) is found, + * or a (1) if their are additional characters in the line. + * + * local variables: + * int c next character from + * the input text line + * + * global variables: + * none + * + * called functions: + * int getnb() lklex.c + * VOID unget() lklex.c + * + * side effects: + * use of getnb() and unget() updates the global pointer ip + * the position in the current input text line + */ + +int +more() +{ + register int c; + + c = getnb(); + unget(c); + return( (c == '\0' || c == ';') ? 0 : 1 ); +} + +/*)Function char endline() + * + * The function endline() scans the input text line + * skipping white space (SPACES and TABS) and returns the next + * character or a (0) if the end of the line is found or a + * comment delimiter (;) is found. + * + * local variables: + * int c next character from + * the input text line + * + * global variables: + * none + * + * called functions: + * int getnb() lklex.c + * + * side effects: + * Use of getnb() updates the global pointer ip the + * position in the current input text line. + */ + +char +endline() +{ + register int c; + + c = getnb(); + return( (c == '\0' || c == ';') ? 0 : c ); +} diff --git a/src/link-z80/lklibr.c b/src/link-z80/lklibr.c new file mode 100755 index 00000000..a68dad8d --- /dev/null +++ b/src/link-z80/lklibr.c @@ -0,0 +1,626 @@ +/* lklibr.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With contributions for the + * object libraries from + * Ken Hornstein + * kenh@cmf.nrl.navy.mil + * + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lklibr.c + * + * The module lklibr.c contains the functions which + * (1) specify the path(s) to library files [.LIB] + * (2) specify the library file(s) [.LIB] to search + * (3) search the library files for specific symbols + * and link the module containing this symbol + * + * lklibr.c contains the following functions: + * VOID addpath() + * VOID addlib() + * VOID addfile() + * VOID search() + * VOID fndsym() + * VOID library() + * VOID loadfile() + * + */ + +/*)Function VOID addpath() + * + * The function addpath() creates a linked structure containing + * the paths to various object module library files. + * + * local variables: + * lbpath *lbph pointer to new path structure + * lbpath *lbp temporary pointer + * + * global variables: + * lbpath *lbphead The pointer to the first + * path structure + * + * functions called: + * int getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c + * + * side effects: + * An lbpath structure may be created. + */ + +VOID +addpath() +{ + struct lbpath *lbph, *lbp; + + lbph = (struct lbpath *) new (sizeof(struct lbpath)); + if (lbphead == NULL) { + lbphead = lbph; + } else { + lbp = lbphead; + while (lbp->next) + lbp = lbp->next; + lbp->next = lbph; + } + unget(getnb()); + lbph->path = (char *) new (strlen(ip)+1); + strcpy(lbph->path, ip); +} + +/*)Function VOID addlib() + * + * The function addlib() tests for the existance of a + * library path structure to determine the method of + * adding this library file to the library search structure. + * + * This function calls the function addfile() to actually + * add the library file to the search list. + * + * local variables: + * lbpath *lbph pointer to path structure + * + * global variables: + * lbpath *lbphead The pointer to the first + * path structure + * + * functions called: + * VOID addfile() lklibr.c + * int getnb() lklex.c + * VOID unget() lklex.c + * + * side effects: + * The function addfile() may add the file to + * the library search list. + */ + +VOID +addlib() +{ + struct lbpath *lbph; + + unget(getnb()); + + if (lbphead == NULL) { + addfile(NULL,ip); + return; + } + for (lbph=lbphead; lbph; lbph=lbph->next) { + addfile(lbph->path,ip); + } +} + +/*)Function VOID addfile(path,libfil) + * + * char *path library path specification + * char *libfil library file specification + * + * The function addfile() searches for the library file + * by concatenating the path and libfil specifications. + * if the library is found, an lbname structure is created + * and linked to any previously defined structures. This + * linked list is used by the function fndsym() to attempt + * to find any undefined symbols. + * + * The function does not report an error on invalid + * path / file specifications or if the file is not found. + * + * local variables: + * lbname *lbnh pointer to new name structure + * lbname *lbn temporary pointer + * char * str path / file string + * char * strend end of path pointer + * + * global variables: + * lbname *lbnhead The pointer to the first + * path structure + * int objflg linked file/library object output flag + * + * functions called: + * VOID * malloc() c_library + * int strlen() c_library + * char * strcpy() c_library + * + * side effects: + * An lbname structure may be created. + */ + +VOID +addfile(path,libfil) +char *path; +char *libfil; +{ + FILE *fp; + char *str, *strend; + struct lbname *lbnh, *lbn; + + if ((path != NULL) && (strchr(libfil,':') == NULL)){ +#if 1 /* Nick */ + str = (char *) malloc (strlen(path) + strlen(libfil) + 6); + strcpy(str, path); + if (*str) + { + strend = str + strlen(str) - 1; +#ifdef WIN32 + if (*strend != '\\') + { + strcpy(++strend, "\\"); + } + if (*libfil == '\\') +#else + if (*strend != '/') + { + strcpy(++strend, "/"); + } + if (*libfil == '/') +#endif + { + strcpy(strend + 1, libfil + 1); + } + else + { + strcpy(strend + 1, libfil); + } + } +#else + str = (char *) malloc (strlen(path) + strlen(libfil) + 5); + strcpy(str,path); + strend = str + strlen(str) - 1; + if ((*libfil == '\\' && *strend == '\\') || + (*libfil == '/' && *strend == '/')) { + *strend = '\0'; + } + strcat(str,libfil); +#endif + } else { + str = (char *) malloc (strlen(libfil) + 5); + strcpy(str,libfil); + } + if(strchr(str,FSEPX) == NULL) { + sprintf(&str[strlen(str)], "%clib", FSEPX); + } +/* printf("trying \"%s\"\n", str); */ + if ((fp = fopen(str, "r")) != NULL) { + fclose(fp); + lbnh = (struct lbname *) new (sizeof(struct lbname)); + if (lbnhead == NULL) { + lbnhead = lbnh; + } else { + lbn = lbnhead; + while (lbn->next) + lbn = lbn->next; + lbn->next = lbnh; + } + if ((path != NULL) && (strchr(libfil,':') == NULL)){ + lbnh->path = path; + } + lbnh->libfil = (char *) new (strlen(libfil) + 1); + strcpy(lbnh->libfil,libfil); + lbnh->libspc = str; + lbnh->f_obj = objflg; + } else { + free(str); + } +} + +/*)Function VOID search() + * + * The function search() looks through all the symbol tables + * at the end of pass 1. If any undefined symbols are found + * then the function fndsym() is called. Function fndsym() + * searches any specified library files to automagically + * import the object modules containing the needed symbol. + * + * After a symbol is found and imported by the function + * fndsym() the symbol tables are again searched. The + * symbol tables are search until no more symbols can be + * resolved within the library files. This ensures that + * back references from one library module to another are + * also resolved. + * + * local variables: + * int i temporary counter + * sym *sp pointer to a symbol structure + * int symfnd found a symbol flag + * + * global variables: + * sym *symhash[] array of pointers to symbol tables + * + * functions called: + * int fndsym() lklibr.c + * + * side effects: + * If a symbol is found then the library object module + * containing the symbol will be imported and linked. + */ + +VOID +search() +{ + register struct sym *sp; + register int i,symfnd; + + /* + * Look for undefined symbols. Keep + * searching until no more symbols are resolved. + */ + symfnd = 1; + while (symfnd) { + symfnd = 0; + /* + * Look through all the symbols + */ + for (i=0; is_type & S_DEF) == 0) { + if (fndsym(sp->s_id)) { + symfnd++; + } + } + sp = sp->s_sp; + } + } + } +} + +/*)Function VOID fndsym(name) + * + * char *name symbol name to find + * + * The function fndsym() searches through all combinations of the + * library path specifications (input by the -k option) and the + * library file specifications (input by the -l option) that + * lead to an existing file. + * + * The file specification may be formed in one of two ways: + * + * (1) If the library file contained an absolute + * path/file specification then this becomes filspc. + * (i.e. C:\...) + * + * (2) If the library file contains a relative path/file + * specification then the concatenation of the path + * and this file specification becomes filspc. + * (i.e. \...) + * + * The structure lbfile is created for the first library + * object file which contains the definition for the + * specified undefined symbol. + * + * If the library file [.LIB] contains file specifications for + * non existant files, no errors are returned. + * + * local variables: + * char buf[] [.REL] file input line + * char c [.REL] file input character + * FILE *fp file handle for object file + * lbfile *lbf temporary pointer + * lbfile *lbfh pointer to lbfile structure + * int lbscan scan library file flag + * FILE *libfp file handle for library file + * lbname *lbnh pointer to lbname structure + * char *path file specification path + * char relfil[] [.REL] file specification + * char *str combined path and file specification + * char *strend end of path pointer + * char symname[] [.REL] file symbol string + * + * global variables: + * lbname *lbnhead The pointer to the first + * name structure + * lbfile *lbfhead The pointer to the first + * file structure + * int obj_flag linked file/library object output flag + * + * functions called: + * int fclose() c_library + * int fgets() c_library + * FILE *fopen() c_library + * VOID free() c_library + * VOID lkexit() lkmain.c + * VOID loadfile() lklibr.c + * VOID * malloc() c_library + * char * sprintf() c_library + * int sscanf() c_library + * char * strcat() c_library + * char * strchr() c_library + * char * strcpy() c_library + * int strlen() c_library + * int strncmp() c_library + * VOID unget() lklex.c + * + * side effects: + * If the symbol is found then a new lbfile structure + * is created and added to the linked list of lbfile + * structures. The file containing the found symbol + * is linked. + */ + +int +fndsym(name) +char *name; +{ + FILE *libfp, *fp; + struct lbname *lbnh; + struct lbfile *lbfh, *lbf; + char relfil[NINPUT+2]; + char buf[NINPUT+2]; + char symname[NINPUT]; + char *path,*str,*strend; + char c; + int lbscan; + + /* + * Search through every library in the linked list "lbnhead". + */ + +/*1*/ for (lbnh=lbnhead; lbnh; lbnh=lbnh->next) { + if ((libfp = fopen(lbnh->libspc, "r")) == NULL) { + fprintf(stderr, "Cannot open library file %s\n", + lbnh->libspc); + lkexit(ER_FATAL); + } + path = lbnh->path; + + /* + * Read in a line from the library file. + * This is the relative file specification + * for a .REL file in this library. + */ + +/*2*/ while (fgets(relfil, NINPUT, libfp) != NULL) { + relfil[NINPUT+1] = '\0'; + relfil[strlen(relfil) - 1] = '\0'; +#if 1 /* Nick */ + if ((path != NULL) && (strchr(relfil,':') == NULL)) { +#else + if (path != NULL) { +#endif +#if 1 /* Nick */ + str = (char *) malloc(strlen(path) + + strlen(relfil) + 6); + strcpy(str, path); + if (*str) + { + strend = str + strlen(str) - 1; +#ifdef WIN32 + if (*strend != '\\') + { + strcpy(++strend, "\\"); + } + if (*relfil == '\\') +#else + if (*strend != '/') + { + strcpy(++strend, "/"); + } + if (*relfil == '/') +#endif + { + strcpy(strend + 1, relfil + 1); + } + else + { + strcpy(strend + 1, relfil); + } + } +#else + str = (char *) malloc (strlen(path)+strlen(relfil)+5); + strcpy(str,path); + strend = str + strlen(str) - 1; + if ((*relfil == '\\' && *strend == '\\') || + (*relfil == '/' && *strend == '/')) { + *strend = '\0'; + } + strcat(str,relfil); +#endif + } else { + str = (char *) malloc (strlen(relfil) + 5); + strcpy(str,relfil); + } + if(strchr(str,FSEPX) == NULL) { + sprintf(&str[strlen(str)], "%crel", FSEPX); + } +/* printf("scanning \"%s\"\n", str); */ + /* + * Scan only files not yet loaded + */ + for (lbf=lbfhead, lbscan=1; lbf&&lbscan; lbf=lbf->next) { + if (strcmp(lbf->filspc,str) == 0) { + lbscan = 0; + } + } +/*3*/ if (lbscan && (fp = fopen(str, "r")) != NULL) { + + /* + * Read in the object file. Look for lines that + * begin with "S" and end with "D". These are + * symbol table definitions. If we find one, see + * if it is our symbol. Make sure we only read in + * our object file and don't go into the next one. + */ + +/*4*/ while (fgets(buf, NINPUT, fp) != NULL) { + + buf[NINPUT+1] = '\0'; + buf[strlen(buf) - 1] = '\0'; + + /* + * When a 'T line' is found terminate file scan. + * All 'S lines' preceed 'T lines' in .REL files. + */ + if (buf[0] == 'T') + break; + + /* + * Skip everything that's not a symbol record. + */ + if (buf[0] != 'S') + continue; + + sscanf(buf, "S %s %c", symname, &c); + + /* + * If we find a symbol definition for the + * symbol we're looking for, load in the + * file and add it to lbfhead so it gets + * loaded on pass number 2. + */ +/*5*/ if (strncmp(symname, name, NCPS) == 0 && c == 'D') { + + lbfh = (struct lbfile *) new (sizeof(struct lbfile)); + if (lbfhead == NULL) { + lbfhead = lbfh; + } else { + lbf = lbfhead; + while (lbf->next) + lbf = lbf->next; + lbf->next = lbfh; + } + lbfh->libspc = lbnh->libspc; + lbfh->filspc = str; + lbfh->relfil = (char *) new (strlen(relfil) + 1); + strcpy(lbfh->relfil,relfil); + lbfh->f_obj = lbnh->f_obj; + fclose(fp); + fclose(libfp); + obj_flag = lbfh->f_obj; + loadfile(str); + return (1); + +/*5*/ } + +/*4*/ } + fclose(fp); +/*3*/ } + free(str); +/*2*/ } + fclose(libfp); +/*1*/ } + return(0); +} + +/*)Function VOID library() + * + * The function library() links all the library object files + * contained in the lbfile structures. + * + * local variables: + * lbfile *lbfh pointer to lbfile structure + * + * global variables: + * lbfile *lbfhead pointer to first lbfile structure + * int obj_flag linked file/library object output flag + * + * functions called: + * VOID loadfile lklibr.c + * + * side effects: + * Links all files contained in the lbfile structures. + */ + +VOID +library() +{ + struct lbfile *lbfh; + + for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { + obj_flag = lbfh->f_obj; + loadfile(lbfh->filspc); + } +} + +/*)Function VOID loadfile(filspc) + * + * char *filspc library object file specification + * + * The function loadfile() links the library object module. + * + * local variables: + * FILE *fp file handle + * int i input line length + * char str[] file input line + * + * global variables: + * char *ip pointer to linker input string + * + * functions called: + * int fclose() c_library + * int fgets() c_library + * FILE * fopen() c_library + * VOID link() lkmain.c + * int strlen() c_library + * + * side effects: + * If file exists it is linked. + */ + +VOID +loadfile(filspc) +char *filspc; +{ + FILE *fp; + char str[NINPUT+2]; + int i; + + if ((fp = fopen(filspc,"r")) != NULL) { + while (fgets(str, NINPUT, fp) != NULL) { + str[NINPUT+1] = '\0'; + i = strlen(str) - 1; + if (str[i] == '\n') + str[i] = '\0'; + ip = str; + link(); + } + fclose(fp); + } +} diff --git a/src/link-z80/lklist.c b/src/link-z80/lklist.c new file mode 100755 index 00000000..0c0c821b --- /dev/null +++ b/src/link-z80/lklist.c @@ -0,0 +1,1007 @@ +/* lklist.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lklist.c + * + * The module lklist.c contains the functions which + * output the linker .map file and produce a relocated + * listing .rst file. + * + * lklist.c contains the following functions: + * int dgt() + * VOID newpag() + * VOID slew() + * VOID lstarea() + * VOID lkulist() + * VOID lkalist() + * VOID lkglist() + * + * lklist.c contains no local variables. + */ + +/*)Function VOID newpag() + * + * The function newpag() outputs a page skip, writes the + * first page header line, sets the line count to 1, and + * increments the page counter. + * + * local variables: + * none + * + * global variables: + * int lop current line number on page + * int page current page number + * + * functions called: + * int fprintf() c_library + * + * side effects: + * The page and line counters are updated. + */ + +VOID +newpag(fp) +FILE *fp; +{ +#if 1 /* Nick */ + if (pflag) +#endif + fprintf(fp, "\fASxxxx Linker %s, page %u.\n", VERSION, ++page); + lop = 1; +} + +/*)Function int dgt(rdx,str,n) + * + * int rdx radix bit code + * char *str pointer to the test string + * int n number of characters to check + * + * The function dgt() verifies that the string under test + * is of the specified radix. + * + * local variables: + * int i loop counter + * + * global variables: + * ctype[] array of character types + * + * functions called: + * none + * + * side effects: + * none + */ + +int +dgt(rdx, str, n) +int rdx, n; +char *str; +{ + int i; + + for (i=0; i= NLPP) { + newpag(mfp); + switch(xflag) { + default: +#if 1 /* Nick */ + case 0: frmta = "Hexadecimal"; break; +#else + case 0: frmta = "Hexidecimal"; break; +#endif + case 1: frmta = "Octal"; break; + case 2: frmta = "Decimal"; break; + } + fprintf(mfp, "%s [%d-Bits]\n\n", frmta, a_bytes*8); + fprintf(mfp, + "Area Addr "); + fprintf(mfp, + " Size Decimal Bytes (Attributes)\n"); + fprintf(mfp, + "-------------------- ---- "); + fprintf(mfp, + " ---- ------- ----- ------------\n"); + + ai = xp->a_addr & a_mask; + aj = xp->a_size & a_mask; + + /* + * Output Area Header + */ + ptr = &xp->a_id[0]; + fprintf(mfp, "%-19.19s", ptr); + switch(a_bytes) { + default: + case 2: + switch(xflag) { + default: + case 0: frmta = " %04X %04X"; break; + case 1: frmta = " %06o %06o"; break; + case 2: frmta = " %05u %05u"; break; + } + frmtb = " = %6u. bytes "; break; + case 3: + switch(xflag) { + default: + case 0: frmta = " %06X %06X"; break; + case 1: frmta = " %08o %08o"; break; + case 2: frmta = " %08u %08u"; break; + } + frmtb = " = %8u. bytes "; break; + case 4: + switch(xflag) { + default: + case 0: frmta = " %08X %08X"; break; + case 1: frmta = " %011o %011o"; break; + case 2: frmta = " %010u %010u"; break; + } + frmtb = " = %10u. bytes "; break; + } + fprintf(mfp, frmta, ai, aj); + fprintf(mfp, frmtb, aj); + + if (xp->a_flag & A_ABS) { + fprintf(mfp, "(ABS"); +#if 1 /* Nick */ + } else if (xp->a_flag & A_NUL) { + fprintf(mfp, "(NUL"); +#endif + } else { + fprintf(mfp, "(REL"); + } + if (xp->a_flag & A_OVR) { + fprintf(mfp, ",OVR"); + } else { + fprintf(mfp, ",CON"); + } + if (xp->a_flag & A_PAG) { + fprintf(mfp, ",PAG"); + } + fprintf(mfp, ")\n"); + + if (xp->a_flag & A_PAG) { + ai = (ai & 0xFF); + aj = (aj > 256); + if (ai || aj) { fprintf(mfp, " "); lop += 1; } + if (ai) { fprintf(mfp, " Boundary"); } + if (ai & aj) { fprintf(mfp, " /"); } + if (aj) { fprintf(mfp, " Length"); } + if (ai || aj) { fprintf(mfp, " Error\n"); } + } + + if (wflag) { + putc('\n', mfp); + fprintf(mfp, + " Value Global "); + fprintf(mfp, + " Global Defined In Module\n"); + fprintf(mfp, + " ----- --------------------------------"); + fprintf(mfp, + " ------------------------\n"); + } else { + switch(a_bytes) { + default: + case 2: frmta = " Value Global "; + frmtb = " ----- ------ "; + n = 4; break; + case 3: + case 4: frmta = " Value Global "; + frmtb = " ----- ------ "; + n = 3; break; + } + putc('\n', mfp); + for(i=0;ia_axp; + while (oxp) { + for (i=0; is_axp) + ++nmsym; + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } + if (nmsym == 0) { + return; + } + + /* + * Allocate space for an array of pointers to symbols + * and load array. + */ + if ( (p = (struct sym **) malloc(nmsym*sizeof(struct sym *))) + == NULL) { + fprintf(mfp, "Insufficient space to build Map Segment.\n"); + return; + } + nmsym = 0; + oxp = xp->a_axp; + while (oxp) { + for (i=0; is_axp) { + p[nmsym++] = sp; + } + sp = sp->s_sp; + } + } + oxp = oxp->a_axp; + } + + /* + * Bubble Sort of Addresses in Symbol Table Array + */ + j = 1; + while (j) { + j = 0; + sp = p[0]; + a0 = sp->s_addr + sp->s_axp->a_addr; + for (i=1; is_addr + sp->s_axp->a_addr; + if (a0 > ai) { + j = 1; + p[i] = p[i-1]; + p[i-1] = sp; + } + a0 = ai; + } + } + + /* + * Repeat Counter + */ + switch(a_bytes) { + default: + case 2: n = 4; break; + case 3: + case 4: n = 3; break; + } + + /* + * Symbol Table Output + */ + i = 0; + while (i < nmsym) { + if (wflag) { + slew(xp); + switch(a_bytes) { + default: + case 2: frmt = " "; break; + case 3: + case 4: frmt = " "; break; + } + fprintf(mfp, frmt); + } else + if ((i % n) == 0) { + slew(xp); + switch(a_bytes) { + default: + case 2: frmt = " "; break; + case 3: + case 4: frmt = " "; break; + } + fprintf(mfp, frmt); + } + + sp = p[i]; + aj = (sp->s_addr + sp->s_axp->a_addr) & a_mask; + switch(a_bytes) { + default: + case 2: + switch(xflag) { + default: + case 0: frmt = " %04X "; break; + case 1: frmt = "%06o "; break; + case 2: frmt = " %05u "; break; + } + break; + case 3: + switch(xflag) { + default: + case 0: frmt = " %06X "; break; + case 1: frmt = " %08o "; break; + case 2: frmt = " %08u "; break; + } + break; + case 4: + switch(xflag) { + default: + case 0: frmt = " %08X "; break; + case 1: frmt = "%011o "; break; + case 2: frmt = " %010u "; break; + } + break; + } + fprintf(mfp, frmt, aj); + + ptr = &sp->s_id[0]; + if (wflag) { + fprintf(mfp, "%-32.32s", ptr); + i++; + ptr = &sp->m_id[0]; + if(ptr) { + fprintf(mfp, " %-.28s", ptr); + } + } else { + switch(a_bytes) { + default: + case 2: frmt = "%-8.8s"; break; + case 3: + case 4: frmt = "%-9.9s"; break; + } + fprintf(mfp, frmt, ptr); + if (++i < nmsym) + if (i % n != 0) + fprintf(mfp, " | "); + } + if (wflag || (i % n == 0)) { + putc('\n', mfp); + } + } + if (i % n != 0) { + putc('\n', mfp); + } + free(p); +} + +/*)Function VOID lkulist(i) + * + * int i i # 0 process LST to RST file + * i = 0 copy remainder of LST file + * to RST file and close files + * + * The function lkulist() creates a relocated listing (.rst) + * output file from the ASxxxx assembler listing (.lst) + * files. The .lst file's program address and code bytes + * are changed to reflect the changes made by ASlink as + * the .rel files are combined into a single relocated + * output file. + * + * local variables: + * a_uint pc current program counter address + * + * global variables: + * int a_bytes T Line Address Bytes + * int hilo byte order + * int gline get a line from the LST file + * to translate for the RST file + * char rb[] read listing file text line + * FILE *rfp The file handle to the current + * output RST file + * int rtcnt count of data words + * int rtflg[] output the data flag + * a_uint rtval[] relocated data + * FILE *tfp The file handle to the current + * LST file being scanned + * + * functions called: + * a_uint adb_xb() lkrloc.c + * int fclose() c_library + * int fgets() c_library + * int fprintf() c_library + * VOID lkalist() lklist.c + * VOID lkglist() lklist.c + * + * side effects: + * A .rst file is created for each available .lst + * file associated with a .rel file. + */ + +VOID +lkulist(i) +int i; +{ + a_uint pc; + + /* + * Exit if listing file is not open + */ + if (tfp == NULL) + return; + + /* + * Normal processing of LST to RST + */ + if (i) { + /* + * Evaluate current code address + */ + pc = adb_xb(0, 0); + + /* + * Line with only address + */ + if (rtcnt == a_bytes) { + lkalist(pc); + + /* + * Line with address and code + */ + } else { + for (i=a_bytes; i < rtcnt; i++) { + if (rtflg[i]) { + lkglist(pc++, rtval[i] & 0xFF); + } + } + } + /* + * Copy remainder of LST to RST + */ + } else { + if (gline == 0) + fprintf(rfp, "%s", rb); + + while (fgets(rb, sizeof(rb)-2, tfp) != 0) { + fprintf(rfp, "%s", rb); + } + fclose(tfp); + tfp = NULL; + fclose(rfp); + rfp = NULL; + } +} + +/*)Function VOID lkalist(pc) + * + * int pc current program counter value + * + * The function lkalist() performs the following functions: + * + * (1) if the value of gline = 0 then the current listing + * file line is copied to the relocated listing file output. + * + * (2) the listing file is read line by line and copied to + * the relocated listing file until a valid source + * line number and a program counter value of the correct + * radix is found. The new relocated pc value is substituted + * and the line is written to the RST file. + * + * local variables: + * int i loop counter + * int m character count + * int n character index + * int r character radix + * char * frmt temporary format specifier + * char str[] temporary string + * + * global variables: + * int gcntr data byte counter + * int gline get a line from the LST file + * to translate for the RST file + * char rb[] read listing file text line + * char *rp pointer to listing file text line + * FILE *rfp The file handle to the current + * output RST file + * FILE *tfp The file handle to the current + * LST file being scanned + * + * functions called: + * int dgt() lklist.c + * int fclose() c_library + * int fgets() c_library + * int fprintf() c_library + * int sprintf() c_library + * char * strncpy() c_library + * + * side effects: + * Lines of the LST file are copied to the RST file, + * the last line copied has the code address + * updated to reflect the program relocation. + */ + +/* The Output Formats +| Tabs- | | | | | | + 11111111112222222222333333333344444----- +012345678901234567890123456789012345678901234----- + | | | | | +ee XXXX xx xx xx xx xx xx LLLLL ************* HEX(16) +ee 000000 ooo ooo ooo ooo LLLLL ************* OCTAL(16) +ee DDDDD ddd ddd ddd ddd LLLLL ************* DECIMAL(16) + XXXX + OOOOOO + DDDDD + +| Tabs- | | | | | | + 11111111112222222222333333333344444----- +012345678901234567890123456789012345678901234----- + | | | | | +ee XXXXXX xx xx xx xx xx xx xx LLLLL ********* HEX(24) +ee OO000000 ooo ooo ooo ooo ooo LLLLL ********* OCTAL(24) +ee DDDDDDDD ddd ddd ddd ddd ddd LLLLL ********* DECIMAL(24) + XXXXXX + OOOOOOOO + DDDDDDDD + +| Tabs- | | | | | | + 11111111112222222222333333333344444----- +012345678901234567890123456789012345678901234----- + | | | | | +ee XXXXXXXX xx xx xx xx xx xx xx LLLLL ********* HEX(32) +eeOOOOO000000 ooo ooo ooo ooo ooo LLLLL ********* OCTAL(32) +ee DDDDDDDDDD ddd ddd ddd ddd ddd LLLLL ********* DECIMAL(32) + XXXXXXXX + OOOOOOOOOOO + DDDDDDDDDD +*/ + +VOID +lkalist(pc) +a_uint pc; +{ + char str[16]; + char *frmt; + int i, m, n, r; + + /* + * Truncate (int) to N-Bytes + */ + pc &= a_mask; + + /* + * Exit if listing file is not open + */ +loop: if (tfp == NULL) + return; + + /* + * Copy current LST to RST + */ + if (gline == 0) { + fprintf(rfp, "%s", rb); + gline = 1; + } + + /* + * Clear text line buffer + */ + for (i=0,rp=rb; i +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lkmain.c + * + * The module lkmain.c contains the functions which + * (1) input the linker options, parameters, and specifications + * (2) perform a two pass link + * (3) produce the appropriate linked data output and/or + * link map file and/or relocated listing files. + * + * lkmain.c contains the following functions: + * FILE * afile() + * VOID bassav() + * VOID gblsav() + * VOID link() + * VOID lkexit() + * int fndidx() + * int main() + * VOID map() + * int parse() + * VOID doparse() + * VOID setbas() + * VOID setgbl() + * VOID usage() + * + * lkmain.c contains the following local variables: + * char * usetext[] array of pointers to the + * command option tect lines + * + */ + +/*)Function int main(argc,argv) + * + * int argc number of command line arguments + 1 + * char * argv[] array of pointers to the command line + * arguments + * + * The function main() evaluates the command line arguments to + * determine if the linker parameters are to input through 'stdin' + * or read from a command file. The functiond getline() and parse() + * are to input and evaluate the linker parameters. The linking process + * proceeds by making the first pass through each .rel file in the order + * presented to the linker. At the end of the first pass the setbase(), + * lnkarea(), setgbl(), and symdef() functions are called to evaluate + * the base address terms, link all areas, define global variables, + * and look for undefined symbols. Following these routines a linker + * map file may be produced and the linker output files may be opened. + * The second pass through the .rel files will output the linked data + * in one of the four supported formats. + * + * local variables: + * char * frmt temporary format specifier + * int c character from argument string + * int i loop counter + * int j loop counter + * int k loop counter + * + * global variables: + * text line in ib[] + * lfile *cfp The pointer *cfp points to the + * current lfile structure + * char ctype[] array of character types, one per + * ASCII character + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * head *hp Pointer to the current + * head structure + * char ib[NINPUT] .rel file text line + * char *ip pointer into the .rel file + * lfile *linkp pointer to first lfile structure + * containing an input .rel file + * specification + * int lkerr error flag + * int mflag Map output flag + * int oflag Output file type flag + * FILE *ofp Output file handle + * for word formats + * FILE *ofph Output file handle + * for high byte format + * FILE *ofpl Output file handle + * for low byte format + * int pass linker pass number + * int pflag print linker command file flag + * int radix current number conversion radix + * FILE *sfp The file handle sfp points to the + * currently open file + * lfile *startp asmlnk startup file structure + * FILE * stdout c_library + * + * functions called: + * FILE * afile() lkmain.c + * int fclose() c_library + * int fprintf() c_library + * int getline() lklex.c + * VOID library() lklibr.c + * VOID link() lkmain.c + * VOID lkexit() lkmain.c + * VOID lnkarea() lkarea.c + * VOID map() lkmain.c + * VOID new() lksym.c + * int parse() lkmain.c + * VOID reloc() lkreloc.c + * VOID search() lklibr.c + * VOID setbas() lkmain.c + * VOID setgbl() lkmain.c + * char * sprintf() c_library + * VOID symdef() lksym.c + * VOID usage() lkmain.c + * + * side effects: + * Completion of main() completes the linking process + * and may produce a map file (.map) and/or a linked + * data files (.ihx or .s19) and/or one or more + * relocated listing files (.rst). + */ + +int +main(argc, argv) +int argc; +char *argv[]; +{ + register int c, i, j, k; + register char *frmt; + + fprintf(stdout, "\n"); + + startp = (struct lfile *) new (sizeof (struct lfile)); + startp->f_idp = ""; + + pflag = 0; /* Nick 1; */ + + for(i=1; i> %s\n", ip); +#endif + parse(); + k++; + } + } else { + strcpy(ip, argv[i]); +#if 0 /* Nick */ + if(pflag) + fprintf(stdout, "ASlink >> %s\n", ip); +#endif + parse(); + } + } + + if (linkp == NULL) + usage(ER_FATAL); + + syminit(); + for (pass=0; pass<2; ++pass) { + cfp = NULL; + sfp = NULL; + filep = linkp; + hp = NULL; + radix = 10; + + while (getline()) { + ip = ib; + link(); + } + if (pass == 0) { + /* + * Search libraries for global symbols + */ + search(); + /* + * Set area base addresses. + */ + setbas(); + /* + * Link all area addresses. + */ + lnkarea(); + /* + * Process global definitions. + */ + setgbl(); + /* + * Check for undefined globals. + */ + symdef(stderr); + /* + * Output Link Map. + */ + if (mflag) + map(); + /* + * Open output file + */ + if (oflag == 1) { + switch(a_bytes) { + default: + case 2: frmt = "ihx"; break; + case 3: + case 4: frmt = "i86"; break; + } +#if 1 /* Nick */ + ofp = afile(outfp->f_idp, frmt, 1); +#else + ofp = afile(linkp->f_idp, frmt, 1); +#endif + if (ofp == NULL) { + lkexit(ER_FATAL); + } + } else + if (oflag == 2) { + switch(a_bytes) { + default: + case 2: frmt = "s19"; break; + case 3: frmt = "s28"; break; + case 4: frmt = "s37"; break; + } +#if 1 /* Nick */ + ofp = afile(outfp->f_idp, frmt, 1); +#else + ofp = afile(linkp->f_idp, frmt, 1); +#endif + if (ofp == NULL) { + lkexit(ER_FATAL); + } + } + } else { + /* + * Link in library files + */ + library(); + reloc('E'); + } + } + lkexit(lkerr ? ER_ERROR : ER_NONE); + return(0); +} + +/*)Function VOID lkexit(i) + * + * int i exit code + * + * The function lkexit() explicitly closes all open + * files and then terminates the program. + * + * local variables: + * none + * + * global variables: + * FILE * mfp file handle for .map + * FILE * ofp file handle for .ihx/.s19 + * FILE * rfp file hanlde for .rst + * FILE * sfp file handle for .rel + * FILE * tfp file handle for .lst + * + * functions called: + * int fclose() c_library + * VOID exit() c_library + * + * side effects: + * All files closed. Program terminates. + */ + +VOID +lkexit(i) +int i; +{ + if (mfp != NULL) fclose(mfp); + if (ofp != NULL) fclose(ofp); + if (rfp != NULL) fclose(rfp); + if (sfp != NULL) { if (sfp != stdin) fclose(sfp); } + if (tfp != NULL) fclose(tfp); + exit(i); +} + +/*)Function link() + * + * The function link() evaluates the directives for each line of + * text read from the .rel file(s). The valid directives processed + * are: + * X, D, Q, H, M, A, S, T, R, and P. + * + * local variables: + * int c first non blank character of a line + * + * global variables: + * head *headp The pointer to the first + * head structure of a linked list + * head *hp Pointer to the current + * head structure + * sdp sdp Base Paged structure + * int a_bytes T Line address bytes + * int hilo Byte ordering + * int pass linker pass number + * int radix current number conversion radix + * + * functions called: + * char endline() lklex.c + * int get() lklex.c + * VOID module() lkhead.c + * VOID newarea() lkarea.c + * VOID newhead() lkhead.c + * sym * newsym() lksym.c + * VOID reloc() lkreloc.c + * + * side effects: + * Head, area, and symbol structures are created and + * the radix is set as the .rel file(s) are read. + */ + +VOID +link() +{ + register int c; + + if ((c=endline()) == 0) { return; } + switch (c) { + + case 'X': + radix = 16; + break; + + case 'D': + radix = 10; + break; + + case 'Q': + radix = 8; + break; + + case 'H': + if (pass == 0) { + newhead(); + } else { + if (hp == 0) { + hp = headp; + } else { + hp = hp->h_hp; + } + } + sdp.s_area = NULL; + sdp.s_areax = NULL; + sdp.s_addr = 0; + break; + + case 'M': + if (pass == 0) + module(); + break; + + case 'A': + if (pass == 0) + newarea(); + if (sdp.s_area == NULL) { + sdp.s_area = areap; + sdp.s_areax = areap->a_axp; + sdp.s_addr = 0; + } + break; + + case 'S': + if (pass == 0) + newsym(); + break; + + case 'T': + case 'R': + case 'P': + if (pass == 0) + break; + reloc(c); + break; + + default: + break; + } + if (c == 'X' || c == 'D' || c == 'Q') { + while ((c = get()) != 0) { + switch(c) { + case 'H': + hilo = 1; + break; + + case 'L': + hilo = 0; + break; + + case '2': + a_bytes = 2; + break; + + case '3': + a_bytes = 3; + break; + + case '4': + a_bytes = 4; + break; + + default: + break; + } + } + switch(a_bytes) { + default: + a_bytes = 2; + case 2: + a_mask = 0x0000FFFF; + s_mask = 0x00008000; + v_mask = 0x00007FFF; + break; + + case 3: + a_mask = 0x00FFFFFF; + s_mask = 0x00800000; + v_mask = 0x007FFFFF; + break; + + case 4: + a_mask = 0xFFFFFFFF; + s_mask = 0x80000000; + v_mask = 0x7FFFFFFF; + break; + } + } +} + +/*)Function VOID map() + * + * The function map() opens the output map file and calls the various + * routines to + * (1) output the variables in each area, + * (2) list the files processed with module names, + * (3) list the libraries file processed, + * (4) list base address definitions, + * (5) list global variable definitions, and + * (6) list any undefined variables. + * + * local variables: + * int i counter + * head * hdp pointer to head structure + * lbfile *lbfh pointer to library file structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * head *headp The pointer to the first + * head structure of a linked list + * lbfile *lbfhead The pointer to the first + * lbfile structure of a linked list + * lfile *linkp pointer to first lfile structure + * containing an input REL file + * specification + * int lop current line number on page + * FILE *mfp Map output file handle + * int page current page number + * + * functions called: + * FILE * afile() lkmain.c + * int fprintf() c_library + * VOID lkexit() lkmain.c + * VOID lstarea() lklist.c + * VOID newpag() lklist.c + * VOID symdef() lksym.c + * + * side effects: + * The map file is created. + */ + +VOID +map() +{ + register int i; + register struct head *hdp; + register struct lbfile *lbfh; + + /* + * Open Map File + */ +#if 1 /* Nick */ + mfp = afile(outfp->f_idp, "map", 1); +#else + mfp = afile(linkp->f_idp, "map", 1); +#endif + if (mfp == NULL) { + lkexit(ER_FATAL); + } + + /* + * Output Map Area Lists + */ + page = 0; + lop = NLPP; + ap = areap; + while (ap) { + lstarea(ap); + ap = ap->a_ap; + } + /* + * List Linked Files + */ + newpag(mfp); + fprintf(mfp, +"\nFiles Linked [ module(s) ]\n\n"); + hdp = headp; + filep = linkp; + while (filep) { + fprintf(mfp, "%-40.40s [ ", filep->f_idp); + i = 0; + while ((hdp != NULL) && (hdp->h_lfile == filep)) { + if (i) + fprintf(mfp, ",\n%44s", ""); + fprintf(mfp, "%-.32s", hdp->m_id); + hdp = hdp->h_hp; + i++; + } + if (i) + fprintf(mfp, " ]"); + fprintf(mfp, "\n"); + filep = filep->f_flp; + } + fprintf(mfp, "\n"); + /* + * List Linked Libraries + */ + if (lbfhead != NULL) { + fprintf(mfp, +"\nLibraries Linked [ object file ]\n\n"); + for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { + fprintf(mfp, "%-40.40s [ %-.32s ]\n", + lbfh->libspc, lbfh->relfil); + } + fprintf(mfp, "\n"); + } + /* + * List Base Address Definitions + */ + if (basep) { + newpag(mfp); + fprintf(mfp, "\nUser Base Address Definitions\n\n"); + bsp = basep; + while (bsp) { + fprintf(mfp, "%s\n", bsp->b_strp); + bsp = bsp->b_base; + } + } + /* + * List Global Definitions + */ + if (globlp) { + newpag(mfp); + fprintf(mfp, "\nUser Global Definitions\n\n"); + gsp = globlp; + while (gsp) { + fprintf(mfp, "%s\n", gsp->g_strp); + gsp = gsp->g_globl; + } + } +#if 1 /* Nick */ + if (pflag) +#endif + fprintf(mfp, "\n\f"); + symdef(mfp); +} + +/*)Function int parse() + * + * The function parse() evaluates all command line or file input + * linker directives and updates the appropriate variables. + * + * local variables: + * int c character value + * int idx string index + * int sv_type save type of processing + * char *p; string pointer + * char fid[] file id string + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * lfile *lfp pointer to current lfile structure + * being processed by parse() + * lfile *linkp pointer to first lfile structure + * containing an input REL file + * specification + * int mflag Map output flag + * int oflag Output file type flag + * int objflg Linked file/library output object flag + * int pflag print linker command file flag + * FILE * stderr c_library + * int uflag Relocated listing flag + * int xflag Map file radix type flag + * int wflag Wide listing format + * int zflag Enable symbol case sensitivity + * + * Functions called: + * VOID addlib() lklibr.c + * VOID addpath() lklibr.c + * VOID bassav() lkmain.c + * VOID doparse() lkmain.c + * int fprintf() c_library + * VOID gblsav() lkmain.c + * VOID getfid() lklex.c + * int get() lklex.c + * int getnb() lklex.c + * VOID lkexit() lkmain.c + * char * strsto() lksym.c + * int strlen() c_library + * + * side effects: + * Various linker flags are updated and the linked + * structure lfile is created. + */ + +int +parse() +{ + register int c, idx; + register char *p; + int sv_type; + char fid[FILSPC+FILSPC]; + + while ((c = getnb()) != 0) { + if ( c == '-') { + while (ctype[c=get()] & LETTER) { + switch(c) { + + case 'c': + case 'C': + if (startp->f_type != 0) + break; + startp->f_type = F_STD; + doparse(); + return(0); + + case 'f': + case 'F': + if (startp->f_type == F_LNK) + return(0); + unget(getnb()); + if (*ip == 0) + usage(ER_FATAL); + sv_type = startp->f_type; + startp->f_idp = ip; + startp->f_idx = fndidx(ip); + startp->f_type = F_LNK; + doparse(); + if (sv_type == F_STD) { + cfp = NULL; + sfp = NULL; + startp->f_type = F_STD; + filep = startp; + } + return(0); + + case 'i': + case 'I': + oflag = 1; + break; + + case 's': + case 'S': + oflag = 2; + break; + + case 'o': + case 'O': +#if 1 /* Nick */ + /* note, this will never be freed */ + outfp = (struct lfile *) + new (sizeof (struct lfile)); + +#if 1 + c = getnb(); + if (ctype[c] == ILL) + { + return 0; /* ignore it */ + } + + /* + * Copy Path from .LNK file + */ + idx = startp->f_idx; + strncpy(fid, startp->f_idp, idx); + /* + * Concatenate the output file spec + */ + getfid(fid + idx, c); + /* + * If output file spec has a path + * use it + * else + * use path of .LNK file + */ + if (fndidx(fid + idx) != 0) { + p = fid + idx; + } else { + p = fid; + } + /* + * Save output file specification + */ + outfp->f_idp = strsto(p); + outfp->f_idx = fndidx(p); +#else + unget(getnb()); + outfp->f_idp = strsto(ip); + outfp->f_idx = fndidx(ip); +#endif + + /* don't process any more switches */ + return 0; + + case 'y': + case 'Y': +#endif + objflg = 0; + break; + + case 'v': + case 'V': + objflg = 1; + break; + + case 'm': + case 'M': + ++mflag; + break; + + case 'u': + case 'U': + uflag = 1; + break; + + case 'x': + case 'X': + xflag = 0; + break; + + case 'q': + case 'Q': + xflag = 1; + break; + + case 'd': + case 'D': + xflag = 2; + break; + + case 'e': + case 'E': + return(1); + + case 'n': + case 'N': + pflag = 0; + break; + + case 'p': + case 'P': + pflag = 1; + break; + + case 'b': + case 'B': + bassav(); + return(0); + + case 'g': + case 'G': + gblsav(); + return(0); + + case 'k': + case 'K': + addpath(); + return(0); + + case 'l': + case 'L': + addlib(); + return(0); + + case 'w': + case 'W': + ++wflag; + break; + + case 'z': + case 'Z': + ++zflag; + break; + + default: + fprintf(stderr, + "Unkown option -%c ignored\n", c); + break; + } + } + } else + if (ctype[c] != ILL) { + if (linkp == NULL) { + linkp = (struct lfile *) + new (sizeof (struct lfile)); +#if 1 /* Nick */ + if (outfp == NULL) + { + outfp = linkp; + } +#endif + lfp = linkp; + } else { + lfp->f_flp = (struct lfile *) + new (sizeof (struct lfile)); + lfp = lfp->f_flp; + } + /* + * Copy Path from .LNK file + */ + idx = startp->f_idx; + strncpy(fid, startp->f_idp, idx); + /* + * Concatenate the .REL file spec + */ + getfid(fid + idx, c); + /* + * If .REL file spec has a path + * use it + * else + * use path of .LNK file + */ + if (fndidx(fid + idx) != 0) { + p = fid + idx; + } else { + p = fid; + } + /* + * Save .REL file specification + */ + lfp->f_idp = strsto(p); + lfp->f_idx = fndidx(p); + lfp->f_type = F_REL; + lfp->f_obj = objflg; + } else { + fprintf(stderr, "Invalid input"); + lkexit(ER_FATAL); + } + } + return(0); +} + +/*)Function VOID doparse() + * + * The function doparse() evaluates all interactive + * command line or file input linker directives and + * updates the appropriate variables. + * + * local variables: + * none + * + * global variables: + * FILE * stdin standard input + * FILE * stdout standard output + * lfile *cfp The pointer *cfp points to the + * current lfile structure + * FILE *sfp The file handle sfp points to the + * currently open file + * char ib[NINPUT] .rel file text line + * char *ip pointer into the .rel file + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * lfile *startp asmlnk startup file structure + * int pflag print linker command file flag + * + * Functions called: + * int fclose() c_library + * int fprintf() c_library + * VOID getfid() lklex.c + * int getline() lklex.c + * int parse() lkmain.c + * + * side effects: + * Various linker flags are updated and the linked + * structure lfile may be updated. + */ + +VOID +doparse() +{ + cfp = NULL; + sfp = NULL; + filep = startp; + while (1) { + ip = ib; + if (getline() == 0) + break; +#if 0 /* Nick */ + if (pflag && cfp->f_type != F_STD) + fprintf(stdout, "ASlink >> %s\n", ip); +#endif + if (*ip == 0 || parse()) + break; + } +#if 1 /* Nick */ + if (sfp != NULL && sfp != stdin) { +#else + if(sfp != stdin) { +#endif + fclose(sfp); + } + sfp = NULL; + startp->f_idp = ""; + startp->f_idx = 0; + startp->f_type = 0; +} + +/*)Function VOID bassav() + * + * The function bassav() creates a linked structure containing + * the base address strings input to the linker. + * + * local variables: + * none + * + * global variables: + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * char *ip pointer into the REL file + * text line in ib[] + * + * functions called: + * int getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c + * + * side effects: + * The basep structure is created. + */ + +VOID +bassav() +{ + if (basep == NULL) { + basep = (struct base *) + new (sizeof (struct base)); + bsp = basep; + } else { + bsp->b_base = (struct base *) + new (sizeof (struct base)); + bsp = bsp->b_base; + } + unget(getnb()); + bsp->b_strp = (char *) new (strlen(ip)+1); + strcpy(bsp->b_strp, ip); +} + +/*)Function VOID setbas() + * + * The function setbas() scans the base address lines in the + * basep structure, evaluates the arguments, and sets beginning + * address of the specified areas. + * + * local variables: + * int v expression value + * char id[] base id string + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * char *ip pointer into the REL file + * text line in ib[] + * int lkerr error flag + * + * functions called: + * a_uint expr() lkeval.c + * int fprintf() c_library + * VOID getid() lklex.c + * int getnb() lklex.c + * int symeq() lksym.c + * + * side effects: + * The base address of an area is set. + */ + +VOID +setbas() +{ + register int v; + char id[NCPS]; +#if 1 /* Nick */ + int increment; + int set_logical, set_physical; + int set_banksize, bank_concatenate; + int set_increment; +#endif + + bsp = basep; + while (bsp) { + ip = bsp->b_strp; + getid(id, -1); +#if 1 /* Nick */ + set_logical = 0; + set_physical = 0; + set_banksize = 0; + bank_concatenate = 0; + if (strcmp(id, "l") == 0 || strcmp(id, "L") == 0) + { + set_logical = 1; /* only want to set logical base */ + getid(id, -1); + } + else if (strcmp(id, "p") == 0 || strcmp(id, "P") == 0) + { + set_physical = 1; /* only want to set physical base */ + getid(id, -1); + } + else if (strcmp(id, "b") == 0 || strcmp(id, "B") == 0) + { + set_banksize = 1; /* only want to set bank size */ + getid(id, -1); + } + else if (strcmp(id, "c") == 0 || strcmp(id, "C") == 0) + { + set_banksize = 1; /* want to set bank size */ + bank_concatenate = 1; /* and start partway into bank */ + getid(id, -1); + } + else + { + set_logical = 1; + set_physical = 1; /* same logical and physical base */ + } +#endif + if (getnb() == '=') { + v = expr(0); +#if 1 /* Nick */ + set_increment = 0; + if (more() && getnb() == ',') + { + set_increment = 1; + increment = expr(0); + } +#endif + for (ap = areap; ap != NULL; ap = ap->a_ap) { + if (symeq(id, ap->a_id, 0)) + break; + } + if (ap == NULL) { + fprintf(stderr, + "No definition of area %s\n", id); + lkerr++; + } else { +#if 1 /* Nick */ + if (set_logical) + { + ap->a_addr = v; + ap->a_bset = 1; + if (set_increment) + { + ap->a_incr = increment; + ap->a_iset = 1; + } + } + if (set_physical) + { + ap->a_paddr = v; + ap->a_pbset = 1; + if (set_increment) + { + ap->a_pincr = increment; + ap->a_piset = 1; + } + } + if (set_banksize && v) + { + ap->a_baddr = v; + ap->a_baset = 1; + if (set_increment && increment) + { + ap->a_bincr = increment; + ap->a_biset = 1; + } + } + if (bank_concatenate) + { + ap->a_bcflg = 1; + } +#else + ap->a_addr = v; + ap->a_bset = 1; +#endif + } + } else { + fprintf(stderr, "No '=' in base expression"); + lkerr++; + } + bsp = bsp->b_base; + } +} + +/*)Function VOID gblsav() + * + * The function gblsav() creates a linked structure containing + * the global variable strings input to the linker. + * + * local variable: + * none + * + * global variables: + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * char *ip pointer into the REL file + * text line in ib[] + * int lkerr error flag + * + * functions called: + * int getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c + * + * side effects: + * The globlp structure is created. + */ + +VOID +gblsav() +{ + if (globlp == NULL) { + globlp = (struct globl *) + new (sizeof (struct globl)); + gsp = globlp; + } else { + gsp->g_globl = (struct globl *) + new (sizeof (struct globl)); + gsp = gsp->g_globl; + } + unget(getnb()); + gsp->g_strp = (char *) new (strlen(ip)+1); + strcpy(gsp->g_strp, ip); +} + +/*)Function VOID setgbl() + * + * The function setgbl() scans the global variable lines in the + * globlp structure, evaluates the arguments, and sets a variable + * to this value. + * + * local variables: + * int v expression value + * char id[] base id string + * sym * sp pointer to a symbol structure + * + * global variables: + * char *ip pointer into the REL file + * text line in ib[] + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * FILE * stderr c_library + * int lkerr error flag + * + * functions called: + * a_uint expr() lkeval.c + * int fprintf() c_library + * VOID getid() lklex.c + * int getnb() lklex.c + * sym * lkpsym() lksym.c + * + * side effects: + * The value of a variable is set. + */ + +VOID +setgbl() +{ + register int v; + register struct sym *sp; + char id[NCPS]; + + gsp = globlp; + while (gsp) { + ip = gsp->g_strp; + getid(id, -1); + if (getnb() == '=') { + v = expr(0); + sp = lkpsym(id, 0); + if (sp == NULL) { + fprintf(stderr, + "No definition of symbol %s\n", id); + lkerr++; + } else { + if (sp->s_type & S_DEF) { + fprintf(stderr, + "Redefinition of symbol %s\n", id); + lkerr++; + sp->s_axp = NULL; + } + sp->s_addr = v; + sp->s_type |= S_DEF; + } + } else { + fprintf(stderr, "No '=' in global expression"); + lkerr++; + } + gsp = gsp->g_globl; + } +} + +/*)Function FILE * afile(fn, ft, wf) + * + * char * fn file specification string + * char * ft file type string + * int wf read(0)/write(1) flag + * + * The function afile() opens a file for reading or writing. + * (1) If the file type specification string ft + * is not NULL then a file specification is + * constructed with the file path\name in fn + * and the extension in ft. + * (2) If the file type specification string ft + * is NULL then the file specification is + * constructed from fn. If fn does not have + * a file type then the default .rel file + * type is appended to the file specification. + * + * afile() returns a file handle for the opened file or aborts + * the assembler on an open error. + * + * local variables: + * int c character value + * char fb[] constructed file specification string + * FILE * fp filehandle for opened file + * char * p1 pointer to filespec string fn + * char * p2 pointer to filespec string fb + * char * p3 pointer to filetype string ft + * + * global variables: + * int lkerr error flag + * + * functions called: + * int fndidx() lkmain.c + * FILE * fopen() c_library + * int fprintf() c_library + * + * side effects: + * File is opened for read or write. + */ + +FILE * +afile(fn, ft, wf) +char *fn; +char *ft; +int wf; +{ + register char *p1, *p2, *p3; + register int c; +#if 1 /* Nick */ + int l; +#endif + FILE *fp; + char fb[FILSPC]; + + if (strlen(fn) > (FILSPC-5)) { + fprintf(stderr, "File Specification %s is too long.", fn); + lkerr++; + return(NULL); + } + + /* + * Skip The Path + */ + strcpy(fb, fn); + c = fndidx(fb); + p1 = &fb[c]; + p2 = &fn[c]; + + /* + * Skip to File Extension Seperator + */ +#if 1 /* Nick */ + l = strlen(p2); + for (c = l - 1; c >= 0; c--) + { + if (p2[c] == FSEPX) + { + l = c; + break; + } +#ifdef WIN32 + if (p2[c] == '\\' || p2[c] == ':') +#else + if (p2[c] == '/' || p2[c] == ':') +#endif + { + break; + } + } + p1 += l; + p2 += l; + + c = *p2++; +#else + while ((c = *p2++) != 0 && c != FSEPX) { + p1++; + } +#endif + *p1++ = FSEPX; + + /* + * Copy File Extension + */ + p3 = ft; + if (*p3 == 0) { + if (c == FSEPX) { + p3 = p2; + } else { + p3 = "rel"; + } + } + while ((c = *p3++) != 0) { + if (p1 < &fb[FILSPC-1]) + *p1++ = c; + } + *p1++ = 0; + if ((fp = fopen(fb, wf?"w":"r")) == NULL) { + fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open"); + lkerr++; + } + return (fp); +} + +/*)Function int fndidx(str) + * + * char * str file specification string + * + * The function fndidx() scans the file specification string + * to find the index to the file name. If the file + * specification contains a 'path' then the index will + * be non zero. + * + * fndidx() returns the index value. + * + * local variables: + * char * p1 temporary pointer + * char * p2 temporary pointer + * + * global variables: + * none + * + * functions called: + * char * strrchr() c_library + * + * side effects: + * none + */ + +int +fndidx(str) +char *str; +{ + register char *p1, *p2; + + /* + * Skip Path Delimiters + */ + p1 = str; + if ((p2 = strrchr(p1, ':')) != NULL) { p1 = p2 + 1; } + if ((p2 = strrchr(p1, '/')) != NULL) { p1 = p2 + 1; } + if ((p2 = strrchr(p1, '\\')) != NULL) { p1 = p2 + 1; } + + return(p1 - str); +} + +char *usetxt[] = { + "Usage: [-Options] [-Option with arg] file [file ...]", +#if 0 + " -p Echo commands to stdout (default)", + " -n No echo of commands to stdout", +#endif + "Alternates to Command Line Input:", + " -c ASlink >> prompt input", + " -f file[.lnk] Command File input", + "Librarys:", + " -k Library path specification, one per -k", + " -l Library file specification, one per -l", + "Relocation:", +#if 1 /* Nick */ + " -b area base address=expression (no logical/physical mapping)", + " -bl area base address=expression (only sets the logical address)", + " -bp area base address=expression (only sets the physical address)", +#else + " -b area base address=expression", +#endif + " -g global symbol=expression", + "Map format:", + " -m Map output generated as file[.map]", +#if 1 /* Nick */ + " -p Paginate map file", + " -n No pagination of map file (default)", +#endif + " -w Wide listing format for map file", +#if 1 /* Nick */ + " -x Hexadecimal (default)", +#else + " -x Hexidecimal (default)", +#endif + " -d Decimal", + " -q Octal", + "Output:", + " -i Intel Hex as file[.i--]", + " -s Motorola S Record as file[.s--]", +#if 1 /* Nick */ + " -o Output filename (default is first source filename)", + " -v Linked file/library object output disable", + " -y Linked file/library object output enable (default)", +#else + " -o Linked file/library object output enable (default)", + " -v Linked file/library object output disable", +#endif + "List:", + " -u Update listing file(s) with link data as file(s)[.rst]", +#if 1 /* Nick */ + "Case sensitivity:", + " -z Enable case sensitivity for symbols", +#else + "Case Sensitivity:", + " -z Enable Case Sensitivity for Symbols", +#endif + "End:", + " -e or null line terminates input", + "", + 0 +}; + +/*)Function VOID usage(n) + * + * int n exit code + * + * The function usage() outputs to the stderr device the + * linker name and version and a list of valid linker options. + * + * local variables: + * char ** dp pointer to an array of + * text string pointers. + * + * global variables: + * FILE * stderr c_library + * + * functions called: + * int fprintf() c_library + * + * side effects: + * none + */ + +VOID +usage(n) +int n; +{ + register char **dp; + + fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION); + for (dp = usetxt; *dp; dp++) + fprintf(stderr, "%s\n", *dp); + lkexit(n); +} diff --git a/src/link-z80/lkout.c b/src/link-z80/lkout.c new file mode 100755 index 00000000..05368a84 --- /dev/null +++ b/src/link-z80/lkout.c @@ -0,0 +1,576 @@ +/* lkout.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With enhancements by + * + * G. Osborn + * gary@s-4.com. + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lkout.c + * + * The module lkout.c contains the dispatch + * function to create the relocated object + * code output in the required format. + * + * lkout.c contains the following functions: + * VOID lkout() + * VOID ixx() + * VOID iflush() + * VOID sxx() + * VOID sflush() + * + * lkout.c contains no local variables. + */ + +/*)Function lkout(i) + * + * int i 1 - process data + * 0 - end of data + * + * The function lkout() dispatches to the + * required output format routine. + * + * local variables: + * none + * + * global variables: + * int` oflag output type flag + * int obj_flag Output enabled flag + * + * functions called: + * VOID ixx() lkout.c + * VOID sxx() lkout.c + * + * side effects: + * The REL data is output in the required format. + */ + + +VOID +lkout(i) +int i; +{ + if (i && obj_flag) { return; } + + /* + * Intel Formats + */ + if (oflag == 1) { + ixx(i); + } else + /* + * Motorola Formats + */ + if (oflag == 2) { + sxx(i); + } +} + +/*Intel Format + * Record Mark Field - This field signifies the start of a + * record, and consists of an ascii colon + * (:). + * + * Record Length Field - This field consists of two ascii + * characters which indicate the number of + * data bytes in this record. The + * characters are the result of converting + * the number of bytes in binary to two + * ascii characters, high digit first. An + * End of File record contains two ascii + * zeros in this field. + * + * Load Address Field - This field consists of the four ascii + * characters which result from converting + * the the binary value of the address in + * which to begin loading this record. The + * order is as follows: + * + * High digit of high byte of address. + * Low digit of high byte of address. + * High digit of low byte of address. + * Low digit of low byte of address. + * + * In an End of File record this field con- + * sists of either four ascii zeros or the + * program entry address. Currently the + * entry address option is not supported. + * + * Record Type Field - This field identifies the record type, + * which is either 0 for data records, 1 + * for an End of File record, or 4 for a + * segment record. It consists + * of two ascii characters, with the high + * digit of the record type first, followed + * by the low digit of the record type. + * + * Data Field - This field consists of the actual data, + * converted to two ascii characters, high + * digit first. There are no data bytes in + * the End of File record. + * + * Checksum Field - The checksum field is the 8 bit binary + * sum of the record length field, the load + * address field, the record type field, + * and the data field. This sum is then + * negated (2's complement) and converted + * to two ascii characters, high digit + * first. + */ + +/*)Function ixx(i) + * + * int i 1 - process data + * 0 - end of data + * + * The function ixx() loads the output buffer with + * the relocated data. + * + * local variables: + * a_uint j temporary + * + * global variables: + * int hilo byte order + * FILE * ofp output file handle + * int rtcnt count of data words + * int rtflg[] output the data flag + * a_uint rtval[] relocated data + * char rtbuf[] output buffer + * a_uint rtadr0 address temporary + * a_uint rtadr1 address temporary + * a_uint rtadr2 address temporary + * + * functions called: + * int fprintf() c_library + * VOID iflush() lkout.c + * + * side effects: + * The data is placed into the output buffer. + */ + +/* + * The number of Data Field bytes is: + * + * 1 Record Mark Field + * 2 Record Length Field + * 4 Load Address Field + * 2 Record Type Field + * 2 Checksum Field + * + * Plus 32 data bytes (64 characters) + */ + +#define MAXBYTES 32 + +VOID +ixx(i) +int i; +{ + register a_uint j; + register int k; + + if (i) { +#if 0 /* Nick, for debugging purposes only */ + for (i=0,rtadr2=0; i %08x\n", rtadr2); +#endif + if (hilo == 0) { + switch(a_bytes){ + default: + case 2: + j = rtval[0]; + rtval[0] = rtval[1]; + rtval[1] = j; + break; + case 3: + j = rtval[0]; + rtval[0] = rtval[2]; + rtval[2] = j; + break; + case 4: + j = rtval[0]; + rtval[0] = rtval[3]; + rtval[3] = j; +#if 1 /* Nick very bad bugfix!! */ + j = rtval[1]; +#else + j = rtval[2]; +#endif + rtval[1] = rtval[2]; + rtval[2] = j; + } + } + for (i=0,rtadr2=0; i %08x\n", rtadr2); */ + + if ((rtadr2 != rtadr1) || rtaflg) { + /* + * data bytes not contiguous between records + */ + iflush(); + rtadr0 = rtadr1 = rtadr2; + rtaflg = 0; + } + for (k=a_bytes; k> 8; + fprintf(ofp, ":%02X%04X00", reclen, lo_addr); + for (i=0; i 2) { + hi_addr = rtadr2 >> 16; + if ((hi_addr != (rtadr1 >> 16)) || rtaflg) { + chksum = 0x02; + chksum += 0x00; + chksum += 0x00; + chksum += 0x04; + chksum += hi_addr; + chksum += hi_addr >> 8; + fprintf(ofp, ":02000004%04X%02X\n", hi_addr, (~chksum + 1) & 0x00ff); + } + } +} + +/*)S19/S28/S37 Formats + * Record Type Field - This field signifies the start of a + * record and identifies the the record + * type as follows: + * + * 2-Byte Address: Ascii S1 - Data Record + * Ascii S9 - End of File Record + * 3-Byte Address: Ascii S2 - Data Record + * Ascii S8 - End of File Record + * 4-Byte Address: Ascii S3 - Data Record + * Ascii S7 - End of File Record + * + * Record Length Field - This field specifies the record length + * which includes the address, data, and + * checksum fields. The 8 bit record + * length value is converted to two ascii + * characters, high digit first. + * + * Load Address Field - This field consists of the 4/6/8 ascii + * characters which result from converting + * the the binary value of the address in + * which to begin loading this record. The + * order is as follows: + * + * S37: High digit of fourth byte of address. + * Low digit of fourth byte of address. + * S28/S37: High digit of third byte of address. + * Low digit of third byte of address. + * S19/S28/S37: High digit of high byte of address. + * Low digit of high byte of address. + * High digit of low byte of address. + * Low digit of low byte of address. + * + * In an End of File record this field con- + * sists of either 4/6/8 ascii zeros or the + * program entry address. Currently the + * entry address option is not supported. + * + * Data Field - This field consists of the actual data, + * converted to two ascii characters, high + * digit first. There are no data bytes in + * the End of File record. + * + * Checksum Field - The checksum field is the 8 bit binary + * sum of the record length field, the load + * address field, and the data field. This + * sum is then complemented (1's comple- + * ment) and converted to two ascii + * characters, high digit first. + */ + +/*)Function sxx(i) + * + * int i 1 - process data + * 0 - end of data + * + * The function s19() loads the output buffer with + * the relocated data. + * + * local variables: + * a_uint j temporary + * char * frmt temporary format specifier + * + * global variables: + * int hilo byte order + * FILE * ofp output file handle + * int rtcnt count of data words + * int rtflg[] output the data flag + * a_uint rtval[] relocated data + * char rtbuf[] output buffer + * a_uint rtadr0 address temporary + * a_uint rtadr1 address temporary + * a_uint rtadr2 address temporary + * + * functions called: + * int fprintf() c_library + * VOID sflush() lkout.c + * + * side effects: + * The data is placed into the output buffer. + */ + +/* + * Number of Data Field bytes is: + * + * 2 Record Type Field + * 2 Record Length Field + * 4/6/8 Load Address Field + * 2 Checksum Field + * + * Plus 32 data bytes (64 characters) + */ + +#define MAXBYTES 32 + +VOID +sxx(i) +int i; +{ + register a_uint j; + register int k; + register char *frmt; + + if (i) { + if (hilo == 0) { + switch(a_bytes){ + default: + case 2: + j = rtval[0]; + rtval[0] = rtval[1]; + rtval[1] = j; + break; + case 3: + j = rtval[0]; + rtval[0] = rtval[2]; + rtval[2] = j; + break; + case 4: + j = rtval[0]; + rtval[0] = rtval[3]; + rtval[3] = j; + j = rtval[2]; + rtval[1] = rtval[2]; + rtval[2] = j; + } + } + for (i=0,rtadr2=0; i>=8) { + chksum += addr; + } + switch(a_bytes) { + default: + case 2: frmt = "S1%02X%04X"; break; + case 3: frmt = "S2%02X%06X"; break; + case 4: frmt = "S3%02X%08X"; break; + } + fprintf(ofp, frmt, reclen, rtadr0); + for (i=0; i +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lkrloc.c + * + * The module lkrloc.c contains the functions which + * perform the relocation calculations. + * + * lkrloc.c contains the following functions: + * a_uint adb_1b() + * a_uint adb_2b() + * a_uint adb_3b() + * a_uint adb_4b() + * a_uint adb_xb() + * a_uint adb_lo() + * a_uint adb_hi() + * a_uint adw_xb() + * VOID erpdmp() + * VOID errdmp() + * a_uint evword() + * VOID prntval() + * VOID rele() + * VOID relerr() + * VOID relerp() + * VOID reloc() + * VOID relp() + * VOID relr() + * VOID relt() + * + * lkrloc.c the local variable errmsg[]. + * + */ + +/*)Function VOID reloc(c) + * + * int c process code + * + * The function reloc() calls a particular relocation + * function determined by the process code. + * + * local variable: + * none + * + * global variables: + * int lkerr error flag + * + * called functions: + * int fprintf() c_library + * VOID rele() lkrloc.c + * VOID relp() lkrloc.c + * VOID relr() lkrloc.c + * VOId relt() lkrloc.c + * + * side effects: + * Refer to the called relocation functions. + * + */ + +VOID +reloc(c) +int c; +{ + switch(c) { + + case 'T': + relt(); + break; + + case 'R': + relr(); + break; + + case 'P': + relp(); + break; + + case 'E': + rele(); + break; + + default: + fprintf(stderr, "Undefined Relocation Operation\n"); + lkerr++; + break; + + } +} + + +/*)Function VOID relt() + * + * The function relt() evaluates a T line read by + * the linker. Each byte value read is saved in the + * rtval[] array, rtflg[] is set, and the number of + * evaluations is maintained in rtcnt. + * + * T Line + * + * T xx xx nn nn nn nn nn ... + * + * + * In: "T n0 n1 n2 n3 ... nn" + * + * Out: 0 1 2 .. rtcnt + * +----+----+----+----+----+ + * rtval | n0 | n1 | n2 | .. | nn | + * +----+----+----+----+----+ + * rtflag| 1 | 1 | 1 | 1 | 1 | + * +----+----+----+----+----+ + * + * The T line contains the assembled code output by the assem- + * bler with xx xx being the offset address from the current area + * base address and nn being the assembled instructions and data in + * byte format. + * + * local variable: + * none + * + * global variables: + * int rtcnt number of values evaluated + * int rtflg[] array of evaluation flags + * int rtval[] array of evaluation values + * + * called functions: + * int eval() lkeval.c + * int more() lklex.c + * + * side effects: + * Linker input T line evaluated. + * + */ + +VOID +relt() +{ + rtcnt = 0; + while (more()) { + if (rtcnt < NTXT) { + rtval[rtcnt] = eval(); + rtflg[rtcnt] = 1; + rtcnt++; + } + } +} + +/*)Function VOID relr() + * + * The function relr() evaluates a R line read by + * the linker. The R line data is combined with the + * previous T line data to perform the relocation of + * code and data bytes. The S19 / IHX output and + * translation of the LST files to RST files may be + * performed. + * + * R Line + * + * R 0 0 nn nn n1 n2 xx xx ... + * + * The R line provides the relocation information to the linker. + * The nn nn value is the current area index, i.e. which area the + * current values were assembled. Relocation information is en- + * coded in groups of 4 bytes: + * + * 1. n1 is the relocation mode and object format + * 1. bit 0 word(0x00)/byte(0x01) + * 2. bit 1 relocatable area(0x00)/symbol(0x02) + * 3. bit 2 normal(0x00)/PC relative(0x04) relocation + * 4. bit 3 1-byte(0x00)/2-byte(0x08) byte data + * 5. bit 4 signed(0x00)/unsigned(0x10) byte data + * 6. bit 5 normal(0x00)/page '0'(0x20) reference + * 7. bit 6 normal(0x00)/page 'nnn'(0x40) reference + * 8. bit 7 LSB(0x00)/MSB(0x80) byte + * + * 2. n2 is a byte index into the corresponding (i.e. pre- + * ceeding) T line data (i.e. a pointer to the data to be + * updated by the relocation). The T line data may be + * 1-byte or 2-byte byte data format or 2-byte word + * format. + * + * 3. xx xx is the area/symbol index for the area/symbol be- + * ing referenced. the corresponding area/symbol is found + * in the header area/symbol lists. + * + * The groups of 4 bytes are repeated for each item requiring relo- + * cation in the preceeding T line. + * + * local variable: + * areax **a pointer to array of area pointers + * int aindex area index + * char *errmsg[] array of pointers to error strings + * int error error code + * int lkerr error flag + * int mode relocation mode + * adrr_t paga paging base area address + * a_uint pags paging symbol address + * a_uint pc relocated base address + * a_uint r PCR relocation value + * a_uint reli relocation initial value + * a_uint relv relocation final value + * int rindex symbol / area index + * a_uint rtbase base code address + * a_uint rtofst rtval[] index offset + * int rtp index into T data + * sym **s pointer to array of symbol pointers + * + * global variables: + * int a_bytes T Line Address Bytes + * head *hp pointer to the head structure + * int oflag output type flag + * rerr rerr linker error structure + * FILE *stderr standard error device + * int uflag relocation listing flag + * + * called functions: + * a_uint adb_1b() lkrloc.c + * a_uint adb_2b() lkrloc.c + * a_uint adb_xb() lkrloc.c + * a_uint adb_lo() lkrloc.c + * a_uint adb_hi() lkrloc.c + * a_uint evword() lkrloc.c + * int eval() lkeval.c + * int fprintf() c_library + * VOID lkout() lkout.c + * VOID lkulist lklist.c + * int more() lklex.c + * VOID relerr() lkrloc.c + * int symval() lksym.c + * + * side effects: + * The R and T lines are combined to produce + * relocated code and data. Output Sxx / Ixx + * and relocated listing files may be produced. + * + */ + +VOID +relr() +{ + register int mode; + register a_uint reli, relv; + int aindex, rindex, rtp, error, v; + a_uint rtbase, rtofst, rtpofst, pc; +#ifdef R_PAG0 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + a_uint paga, pags; +#endif + struct areax **a; + struct sym **s; + + /* + * Get area and symbol lists + */ + a = hp->a_list; + s = hp->s_list; + + /* + * Verify Area Mode + */ + if (eval() != (R_WORD | R_AREA) || eval()) { + fprintf(stderr, "R input error\n"); + lkerr++; + } + + /* + * Get area pointer + */ + aindex = evword(); + if (aindex >= hp->h_narea) { + fprintf(stderr, "R area error\n"); + lkerr++; + return; + } + + /* + * Base values + */ + rtbase = adb_xb(0, 0); + rtofst = a_bytes; + + /* + * Relocate address + */ + pc = adb_xb(a[aindex]->a_addr, 0); +#if 0 /* Nick */ + /* unrelocate from logical address, and put it at physical */ + adb_xb(a[aindex]->a_paddr - a[aindex]->a_addr, 0); +#endif + +#if 0 /* Nick, for debugging purposes only */ + printf("rtbase = 0x%08x, pc = 0x%08x\n", rtbase, pc); + for (error=0,rtadr2=0; error %08x\n", rtadr2); +#endif + + /* + * Do remaining relocations + */ + while (more()) { + error = 0; + relv = 0; + rtpofst = rtofst; + mode = eval(); + rtp = eval(); + rindex = evword(); + + /* + * R_SYM or R_AREA references + */ + if (mode & R_SYM) { + if (rindex >= hp->h_nglob) { + fprintf(stderr, "R symbol error\n"); + lkerr++; + return; + } + reli = symval(s[rindex]); + } else { + if (rindex >= hp->h_narea) { + fprintf(stderr, "R area error\n"); + lkerr++; + return; + } + reli = a[rindex]->a_addr; + } + + /* + * R_PCR addressing + */ + if (mode & R_PCR) { + if (mode & R_BYTE) { + reli -= (pc + (rtp-rtofst) + 1); + } else { + reli -= (pc + (rtp-rtofst) + 2); + } + } + + /* + * Standard Modes + */ + if ((mode & R_ECHEK) != R_EXTND) { +#ifdef R_PAG0 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + paga = 0; + pags = 0; + /* + * R_PAG0 or R_PAG addressing + */ + if (mode & (R_PAG0|R_PAG)) { + paga = sdp.s_area->a_addr; + pags = sdp.s_addr; + reli -= paga + pags; + } +#endif + + /* + * R_BYTE or R_WORD operation + */ + if (mode & R_BYTE) { + if (mode & R_BYTX) { +#ifdef R_BYTE4 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + if (mode & R_BYTE4) + { + relv = adb_byte4(reli, rtp); + } + else +#endif +#ifdef R_BYTE3 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + if (mode & R_BYTE3) + { + relv = adb_byte3(reli, rtp); + } + else +#endif + if (mode & R_MSB) { + relv = adb_hi(reli, rtp); + } else { + relv = adb_lo(reli, rtp); + } + rtofst += (a_bytes - 1); + } else { + relv = adb_1b(reli, rtp); + } + } else { + relv = adw_xb(2, reli, rtp); + rtofst += (a_bytes - 2); + } + +#ifdef R_PAG0 /* Nick has reassigned the R_PAG0 and R_PAG bits! */ + /* + * Page Relocation Error Checking + */ + if (mode & R_PAG0 && (relv & ~0xFF || paga || pags)) + error = 4; + if (mode & R_PAG && (relv & ~0xFF)) + error = 5; +#endif + /* + * Extended Modes + */ + } else { + switch(mode & R_EMASK) { + case R_J11: + if ((hilo == 0) || (a_bytes < 2)) { + error = 8; + } + /* + * JLH: 11 bit jump destination for 8051. + * Forms two byte instruction with + * op-code bits in the MIDDLE! + * rtp points at 3 byte locus: + * first two will get the address, + * third one has raw op-code + */ + relv = adw_xb(2, reli, rtp); + + /* + * Calculate absolute destination + * relv must be on same 2K page as pc + */ + if ((relv & ~0x7ff) != + ((pc + rtp - rtofst) & ~0x7ff)) { + error = 6; + } + + rtofst += (a_bytes - 2); + + /* + * Merge MSB with op-code, + * ignoring top 5 bits of address. + * Then hide the op-code. + */ + rtval[rtp + (a_bytes - 2)] = + rtval[rtp + a_bytes] | + ((rtval[rtp + (a_bytes - 2)] & 0x07)<<5); + rtflg[rtp + a_bytes] = 0; + rtofst += 1; + break; + + case R_J19: + if ((hilo == 0) || (a_bytes < 3)) { + error = 8; + } + /* + * BK: 19 bit jump destination for DS80C390. + * Forms four byte instruction with + * op-code bits in the MIDDLE! + * rtp points at 4 byte locus: + * first three will get the address, + * fourth one has raw op-code + */ + relv = adw_xb(3, reli, rtp); + + /* + * Calculate absolute destination + * relv must be on same 512K page as pc + */ + if ((relv & ~0x7ffff) != + ((pc + rtp - rtofst) & ~0x7ffff)) { + error = 7; + } + + rtofst += (a_bytes - 3); + + /* + * Merge MSB with op-code, + * ignoring top 5 bits of address. + * Then hide the op-code. + */ + rtval[rtp + (a_bytes - 3)] = + rtval[rtp + a_bytes] | + ((rtval[rtp + (a_bytes - 3)] & 0x07)<<5); + rtflg[rtp + a_bytes] = 0; + rtofst += 1; + break; + + case R_3BYTE: + /* + * 24 bit destination + */ +#if 1 /* Nick */ + /* ensures the rtflg array is maintained */ + relv = adw_xb(3, reli, rtp); +#else + relv = adb_3b(reli, rtp); +#endif + break; + + case R_4BYTE: + /* + * 32 bit destination + */ +#if 1 /* Nick */ + /* ensures the rtflg array is maintained */ + /* although it doesn't matter in this case */ + relv = adw_xb(4, reli, rtp); +#else + relv = adb_4b(reli, rtp); +#endif + break; + + default: + error = 8; + break; + } + } + + /* + * Unsigned Byte Checking + */ + if (mode & R_USGN && mode & R_BYTE && relv & ~0xFF) + error = 1; + + /* + * PCR Relocation Error Checking + */ + if (mode & R_PCR) { + v = relv - reli; + if ((mode & R_BYTE) && (mode & R_BYTX)) { + if ((v < ~0x7F) || (v > 0x7F)) + error = 2; + } else { + if ((v < ~0x7FFF) || (v > 0x7FFF)) + error = 3; + } + } + + /* + * Error Processing + */ + if (error) { + rerr.aindex = aindex; + rerr.mode = mode; + rerr.rtbase = rtbase + rtp - rtpofst; + rerr.rindex = rindex; + rerr.rval = relv - reli; + relerr(errmsg[error-1]); + } + } + if (uflag != 0) { + lkulist(1); + } + if (oflag != 0) { +#if 1 /* Nick */ + /* unrelocate from logical address, and put it at physical */ + adb_xb(a[aindex]->a_paddr - a[aindex]->a_addr, 0); +#endif + lkout(1); + } +} + +char *errmsg[] = { + "Unsigned Byte error", + "Byte PCR relocation error", + "Word PCR relocation error", + "Page0 relocation error", + "Page Mode relocation error", + "2K Page relocation error", + "512K Page relocation error", + "Undefined Extended Mode error" +}; + + +/*)Function VOID relp() + * + * The function relp() evaluates a P line read by + * the linker. The P line data is combined with the + * previous T line data to set the base page address + * and test the paging boundary and length. + * + * P Line + * + * P 0 0 nn nn n1 n2 xx xx + * + * The P line provides the paging information to the linker as + * specified by a .setdp directive. The format of the relocation + * information is identical to that of the R line. The correspond- + * ing T line has the following information: + * T xx xx aa aa bb bb + * + * Where aa aa is the area reference number which specifies the + * selected page area and bb bb is the base address of the page. + * bb bb will require relocation processing if the 'n1 n2 xx xx' is + * specified in the P line. The linker will verify that the base + * address is on a 256 byte boundary and that the page length of an + * area defined with the PAG type is not larger than 256 bytes. + * + * local variable: + * areax **a pointer to array of area pointers + * int aindex area index + * int mode relocation mode + * a_uint relv relocation value + * int rindex symbol / area index + * int rtp index into T data + * sym **s pointer to array of symbol pointers + * + * global variables: + * head *hp pointer to the head structure + * int lkerr error flag + * sdp sdp base page structure + * FILE *stderr standard error device + * + * called functions: + * a_uint adb_2b() lkrloc.c + * a_uint evword() lkrloc.c + * int eval() lkeval.c + * int fprintf() c_library + * int more() lklex.c + * int symval() lksym.c + * + * side effects: + * The P and T lines are combined to set + * the base page address and report any + * paging errors. + * + */ + +VOID +relp() +{ + register int aindex, rindex; + int mode, rtp; + a_uint relv; + struct areax **a; + struct sym **s; + + /* + * Get area and symbol lists + */ + a = hp->a_list; + s = hp->s_list; + + /* + * Verify Area Mode + */ + if (eval() != (R_WORD | R_AREA) || eval()) { + fprintf(stderr, "P input error\n"); + lkerr++; + } + + /* + * Get area pointer + */ + aindex = evword(); + if (aindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + + /* + * Do remaining relocations + */ + while (more()) { + mode = eval(); + rtp = eval(); + rindex = evword(); + + /* + * R_SYM or R_AREA references + */ + if (mode & R_SYM) { + if (rindex >= hp->h_nglob) { + fprintf(stderr, "P symbol error\n"); + lkerr++; + return; + } + relv = symval(s[rindex]); + } else { + if (rindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + relv = a[rindex]->a_addr; + } + adb_xb(relv, rtp); + } + + /* + * Paged values + */ + aindex = adb_xb(0,a_bytes); + if (aindex >= hp->h_narea) { + fprintf(stderr, "P area error\n"); + lkerr++; + return; + } + sdp.s_areax = a[aindex]; + sdp.s_area = sdp.s_areax->a_bap; + sdp.s_addr = adb_xb(0,a_bytes*2); + if (sdp.s_area->a_addr & 0xFF || sdp.s_addr & 0xFF) + relerp("Page Definition Boundary Error"); +} + +/*)Function VOID rele() + * + * The function rele() closes all open output files + * at the end of the linking process. + * + * local variable: + * none + * + * global variables: + * int oflag output type flag + * int uflag relocation listing flag + * + * called functions: + * VOID iout() lkout.c + * VOID lkulist() lklist.c + * + * side effects: + * All open output files are closed. + * + */ + +VOID +rele() +{ + if (uflag != 0) { + lkulist(0); + } + if (oflag != 0) { + lkout(0); + } +} + +/*)Function a_uint evword() + * + * The function evword() combines two byte values + * into a single word value. + * + * local variable: + * a_uint v temporary evaluation variable + * + * global variables: + * hilo byte ordering parameter + * + * called functions: + * int eval() lkeval.c + * + * side effects: + * Relocation text line is scanned to combine + * two byte values into a single word value. + * + */ + +a_uint +evword() +{ + register a_uint v; + + if (hilo) { + v = (eval() << 8); + v += eval(); + } else { + v = eval(); + v += (eval() << 8); + } + return(v); +} + +/*)Function a_uint adb_1b(v, i) + * + * int v value to add to byte + * int i rtval[] index + * + * The function adb_1b() adds the value of v to + * the single byte value contained in rtval[i]. + * The new value of rtval[i] is returned. + * + * local variable: + * none + * + * global variables: + * none + * + * called functions: + * none + * + * side effects: + * The byte value of rtval[] is changed. + * + */ + +a_uint +adb_1b(v, i) +register a_uint v; +register int i; +{ + return(rtval[i] += v); +} + +/*)Function a_uint adb_2b(v, i) + * + * int v value to add to word + * int i rtval[] index + * + * The function adb_2b() adds the value of v to the + * 2 byte value contained in rtval[i] and rtval[i+1]. + * The new value of rtval[i] / rtval[i+1] is returned. + * + * local variable: + * a_uint j temporary evaluation variable + * + * global variables: + * hilo byte ordering parameter + * + * called functions: + * none + * + * side effects: + * The 2 byte value of rtval[] is changed. + * + */ + +a_uint +adb_2b(v, i) +register a_uint v; +register int i; +{ + register a_uint j; + + if (hilo) { + j = v + (rtval[i] << 8) + + (rtval[i+1] & 0xff); + rtval[i] = (j >> 8) & 0xff; + rtval[i+1] = j & 0xff; + } else { + j = v + (rtval[i] & 0xff) + + (rtval[i+1] << 8); + rtval[i] = j & 0xff; + rtval[i+1] = (j >> 8) & 0xff; + } + return(j); +} + +/*)Function a_uint adb_3b(v, i) + * + * int v value to add to word + * int i rtval[] index + * + * The function adb_3b() adds the value of v to the + * three byte value contained in rtval[i], rtval[i+1], and rtval[i+2]. + * The new value of rtval[i] / rtval[i+1] / rtval[i+2] is returned. + * + * local variable: + * a_uint j temporary evaluation variable + * + * global variables: + * hilo byte ordering parameter + * + * called functions: + * none + * + * side effects: + * The 3 byte value of rtval[] is changed. + * + */ + +a_uint +adb_3b(v, i) +register a_uint v; +register int i; +{ + register a_uint j; + + if (hilo) { + j = v + (((rtval[i] << 16) & 0xff0000) + + ((rtval[i+1] << 8 ) & 0xff00) + + ((rtval[i+2]) & 0xff)); + rtval[i] = (j >> 16) & 0xff; + rtval[i+1] = (j >> 8) & 0xff; + rtval[i+2] = j & 0xff; + } else { + j = v + (((rtval[i+2] << 16) & 0xff0000) + + ((rtval[i+1] << 8 ) & 0xff00) + + ((rtval[i]) & 0xff)); + rtval[i] = j & 0xff; + rtval[i+1] = (j >> 8) & 0xff; + rtval[i+2] = (j >> 16) & 0xff; + } + return(j); +} + +/*)Function a_uint adb_4b(v, i) + * + * int v value to add to word + * int i rtval[] index + * + * The function adb_4b() adds the value of v to the + * four byte value contained in rtval[i], ..., rtval[i+3]. + * The new value of rtval[i], ..., rtval[i+3] is returned. + * + * local variable: + * a_uint j temporary evaluation variable + * + * global variables: + * hilo byte ordering parameter + * + * called functions: + * none + * + * side effects: + * The 4 byte value of rtval[] is changed. + * + */ + +a_uint +adb_4b(v, i) +register a_uint v; +register int i; +{ + register a_uint j; + + if (hilo) { + j = v + (((rtval[i] << 24) & 0xff000000) + + ((rtval[i+1] << 16) & 0xff0000) + + ((rtval[i+2] << 8 ) & 0xff00) + + ((rtval[i+3]) & 0xff)); + rtval[i] = (j >> 24) & 0xff; + rtval[i+1] = (j >> 16) & 0xff; + rtval[i+2] = (j >> 8) & 0xff; + rtval[i+3] = j & 0xff; + } else { + j = v + (((rtval[i+3] << 24) & 0xff000000) + + ((rtval[i+2] << 16) & 0xff0000) + + ((rtval[i+1] << 8 ) & 0xff00) + + ((rtval[i]) & 0xff)); + rtval[i] = j & 0xff; + rtval[i+1] = (j >> 8) & 0xff; + rtval[i+2] = (j >> 16) & 0xff; + rtval[i+3] = (j >> 24) & 0xff; + } + return(j); +} + +/*)Function a_uint adb_xb(v, i) + * + * int v value to add to x-bytes + * int i rtval[] index + * + * The function adx_x() adds the value of v to + * the value contained in rtval[i] for x-bytes. + * The new value of rtval[i] for x-bytes is returned. + * + * local variable: + * none + * + * global variables: + * none + * + * called functions: + * a_uint adb_1b() lkrloc.c + * a_uint adb_2b() lkrloc.c + * a_uint adb_3b() lkrloc.c + * a_uint adb_4b() lkrloc.c + * + * side effects: + * The x-byte value of rtval[] is changed. + * + */ + +a_uint +adb_xb(v, i) +register a_uint v; +register int i; +{ + a_uint j; + + switch(a_bytes){ + case 1: + j = adb_1b(v, i); + return(j & 0x80 ? j | ~0x7F : j & 0x7F); + case 2: + j = adb_2b(v, i); + return(j & 0x8000 ? j | ~0x7FFF : j & 0x7FFF); + case 3: + j = adb_3b(v, i); + return(j & 0x800000 ? j | ~0x7FFFFF : j & 0x7FFFFF); + case 4: + j = adb_4b(v, i); + return(j & 0x80000000 ? j | ~0x7FFFFFFF : j & 0x7FFFFFFF); + default: + return(0); + } + return(0); +} + +/*)Function a_uint adb_lo(v, i) + * + * int v value to add to byte + * int i rtval[] index + * + * The function adb_lo() adds the value of v to the + * value contained in rtval[i] through rtval[i + a_bytes - 1]. + * The new value of rtval[i] ... is returned. + * The rtflg[] flags are cleared for all rtval[i] ... except + * the LSB. + * + * local variable: + * a_uint j temporary evaluation variable + * + * global variables: + * hilo byte ordering parameter + * + * called functions: + * none + * + * side effects: + * The value of rtval[] is changed. + * The rtflg[] values corresponding to all bytes + * except the LSB of the value are cleared to reflect + * the fact that the LSB is the selected byte. + * + */ + +a_uint +adb_lo(v, i) +a_uint v; +int i; +{ + register a_uint j; + register int m, n; + + j = adb_xb(v, i); + /* + * LSB is lowest order byte of data + */ + m = (hilo ? a_bytes-1 : 0); + for (n=0; na_list; + s = hp->s_list; + + mode = rerr.mode; + aindex = rerr.aindex; + rindex = rerr.rindex; + + /* + * Print Error + */ + fprintf(fptr, "\n?ASlink-Warning-%s", str); + lkerr++; + + /* + * Print symbol if symbol based + */ + if (mode & R_SYM) { + fprintf(fptr, " for symbol %s\n", + &s[rindex]->s_id[0]); + } else { + fprintf(fptr, "\n"); + } + + /* + * Print Ref Info + */ +/* 11111111112222222222333333333344444444445555555555666666666677777*/ +/*12345678901234567890123456789012345678901234567890123456789012345678901234*/ +/* | | | | */ + fprintf(fptr, +" file module area offset\n"); + fprintf(fptr, +" Refby %-14.14s %-14.14s %-14.14s ", + hp->h_lfile->f_idp, + &hp->m_id[0], + &a[aindex]->a_bap->a_id[0]); + prntval(fptr, rerr.rtbase); + + /* + * Print Def Info + */ + if (mode & R_SYM) { + raxp = s[rindex]->s_axp; + } else { + raxp = a[rindex]; + } +/* 11111111112222222222333333333344444444445555555555666666666677777*/ +/*12345678901234567890123456789012345678901234567890123456789012345678901234*/ +/* | | | | */ + fprintf(fptr, +" Defin %-14.14s %-14.14s %-14.14s ", + raxp->a_bhp->h_lfile->f_idp, + &raxp->a_bhp->m_id[0], + &raxp->a_bap->a_id[0]); + if (mode & R_SYM) { + prntval(fptr, s[rindex]->s_addr); + } else { + prntval(fptr, rerr.rval); + } +} + +/*)Function VOID prntval(fptr, v) + * + * FILE *fptr output file handle + * a_uint v value to output + * + * The function prntval() outputs the value v, in the + * currently selected radix, to the device specified + * by fptr. + * + * local variable: + * none + * + * global variables: + * int xflag current radix + * + * called functions: + * int fprintf() c_library + * + * side effects: + * none + * + */ + +VOID +prntval(fptr, v) +FILE *fptr; +a_uint v; +{ + register char *frmt; + + switch(xflag) { + default: + case 0: + switch(a_bytes) { + default: + case 2: frmt = " %04X\n"; break; + case 3: frmt = " %06X\n"; break; + case 4: frmt = " %08X\n"; break; + } + break; + case 1: + switch(a_bytes) { + default: + case 2: frmt = " %06o\n"; break; + case 3: frmt = " %08o\n"; break; + case 4: frmt = "%011o\n"; break; + } + break; + case 2: + switch(a_bytes) { + default: + case 2: frmt = " %05u\n"; break; + case 3: frmt = " %08u\n"; break; + case 4: frmt = " %010u\n"; break; + } + break; + } + fprintf(fptr, frmt, v); +} + +/*)Function VOID relerp(str) + * + * char *str error string + * + * The function relerp() outputs the paging error string to + * stderr and to the map file (if it is open). + * + * local variable: + * none + * + * global variables: + * FILE *mfp handle for the map file + * + * called functions: + * VOID erpdmp() lkrloc.c + * + * side effects: + * Error message inserted into map file. + * + */ + +VOID +relerp(str) +char *str; +{ + erpdmp(stderr, str); + if (mfp) + erpdmp(mfp, str); +} + +/*)Function VOID erpdmp(fptr, str) + * + * FILE *fptr output file handle + * char *str error string + * + * The function erpdmp() outputs the error string str + * to the device specified by fptr. + * + * local variable: + * head *thp pointer to head structure + * + * global variables: + * int lkerr error flag + * sdp sdp base page structure + * + * called functions: + * int fprintf() c_library + * VOID prntval() lkrloc.c + * + * side effects: + * Error reported. + * + */ + +VOID +erpdmp(fptr, str) +FILE *fptr; +char *str; +{ + register struct head *thp; + + thp = sdp.s_areax->a_bhp; + + /* + * Print Error + */ + fprintf(fptr, "\n?ASlink-Warning-%s\n", str); + lkerr++; + + /* + * Print PgDef Info + */ +/* 111111111122222222223333333333444444444455555555556666666666777*/ +/*123456789012345678901234567890123456789012345678901234567890123456789012*/ + fprintf(fptr, +" file module pgarea pgoffset\n"); + fprintf(fptr, +" PgDef %-14.14s %-14.14s %-14.14s ", + thp->h_lfile->f_idp, + &thp->m_id[0], + &sdp.s_area->a_id[0]); + prntval(fptr, sdp.s_area->a_addr + sdp.s_addr); +} diff --git a/src/link-z80/lksym.c b/src/link-z80/lksym.c new file mode 100755 index 00000000..46fe1a4f --- /dev/null +++ b/src/link-z80/lksym.c @@ -0,0 +1,768 @@ +/* lksym.c */ + +/* + * (C) Copyright 1989-2002 + * All Rights Reserved + * + * Alan R. Baldwin + * 721 Berkeley St. + * Kent, Ohio 44240 + * + * With enhancements from + * John L. Hartman (JLH) + * jhartman@compuserve.com + * + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "aslink.h" + +/*)Module lksym.c + * + * The module lksym.c contains the functions that operate + * on the symbol structures. + * + * lksym.c contains the following functions: + * int hash() + * sym * lkpsym() + * char * new() + * sym * newsym() + * char * strsto() + * VOID symdef() + * int symeq() + * VOID syminit() + * VOID symmod() + * a_uint symval() + * + * lksym.c contains the static variables: + * char * pnext + * int bytes + * used by the string store function. + */ + +/*)Function VOID syminit() + * + * The function syminit() is called to clear the hashtable. + * + * local variables: + * sym ** spp pointer to an array of + * sym structure pointers + * + * global variables: + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * + * functions called: + * none + * + * side effects: + * (1) The symbol hash tables are cleared + */ + +VOID +syminit() +{ + struct sym **spp; + + spp = &symhash[0]; + while (spp < &symhash[NHASH]) + *spp++ = NULL; +} + +/*)Function sym * newsym() + * + * The function newsym() is called to evaluate the symbol + * definition/reference directive from the .rel file(s). + * If the symbol is not found in the symbol table a new + * symbol structure is created. Evaluation of the + * directive determines if this is a reference or a definition. + * Multiple definitions of the same variable will be flagged + * as an error if the values are not identical. A symbol + * definition places the symbol value and area extension + * into the symbols data structure. And finally, a pointer + * to the symbol structure is placed into the head structure + * symbol list. Refer to the description of the header, symbol, + * area, and areax structures in lkdata.c for structure and + * linkage details. + * + * local variables: + * int c character from input text + * int i evaluation value + * char id[] symbol name + * int nglob number of symbols in this header + * sym * tsp pointer to symbol structure + * sym ** s list of pointers to symbol structures + * + * global variables: + * areax *axp Pointer to the current + * areax structure + * head *headp The pointer to the first + * head structure of a linked list + * int lkerr error flag + * + * functions called: + * a_uint eval() lkeval.c + * VOID exit() c_library + * int fprintf() c_library + * int get() lklex.c + * int getnb() lklex.c + * sym * lkpsym() lksym.c + * + * side effects: + * A symbol structure is created and/or modified. + * If structure space allocation fails linker will abort. + * Several severe errors (these are internal errors + * indicating a corrupted .rel file or corrupted + * assembler or linker) will terminated the linker. + */ + +/* + * Find/Create a global symbol entry. + * + * S xxxxxx Defnnnn + * | | | + * | | `-- sp->s_addr + * | `----- sp->s_type + * `------------ sp->s_id + * + */ +struct sym * +newsym() +{ + register int c, i, nglob; + struct sym *tsp; + struct sym **s; + char id[NCPS]; + + getid(id, -1); + tsp = lkpsym(id, 1); + c = getnb();get();get(); + if (c == 'R') { + tsp->s_type |= S_REF; + if (eval()) { + fprintf(stderr, "Non zero S_REF\n"); + lkerr++; + } + } else + if (c == 'D') { + i = eval(); + if (tsp->s_type & S_DEF) { +#if 1 /* Nick */ + if ((ap->a_flag & A_ABS) == 0 || + tsp->s_addr != (a_uint)i) { +#else + if (tsp->s_addr != (a_uint) i) { +#endif + fprintf(stderr, + "Multiple definition of %s\n", id); + lkerr++; + } + } else { + /* + * Set value and area extension link. + */ + tsp->s_addr = (a_uint) i; + tsp->s_axp = axp; + tsp->s_type |= S_DEF; + tsp->m_id = hp->m_id; + } + } else { + fprintf(stderr, "Invalid symbol type %c for %s\n", c, id); + lkexit(ER_FATAL); + } + /* + * Place pointer in header symbol list + */ + if (headp == NULL) { + fprintf(stderr, "No header defined\n"); + lkexit(ER_FATAL); + } + nglob = hp->h_nglob; + s = hp->s_list; + for (i=0; i < nglob ;++i) { + if (s[i] == NULL) { + s[i] = tsp; + return(tsp); + } + } + fprintf(stderr, "Header symbol list overflow\n"); + lkexit(ER_FATAL); + return(NULL); +} + +/*)Function sym * lkpsym(id,f) + * + * char * id symbol name string + * int f f == 0, lookup only + * f != 0, create if not found + * + * The function lookup() searches the symbol hash tables for + * a symbol name match returning a pointer to the sym structure. + * If the symbol is not found then a sym structure is created, + * initialized, and linked to the appropriate hash table if f != 0. + * A pointer to this new sym structure is returned or a NULL + * pointer is returned if f == 0. + * + * local variables: + * int h computed hash value + * sym * sp pointer to a sym structure + * + * global varaibles: + * sym * symhash[] array of pointers to NHASH + * linked symbol lists + * + * functions called: + * int hash() lksym.c + * char * new() lksym.c + * int symeq() lksym.c + * + * side effects: + * If the function new() fails to allocate space + * for the new sym structure the linker terminates. + */ + +struct sym * +lkpsym(id, f) +char *id; +int f; +{ + register struct sym *sp; + register int h; + + h = hash(id, zflag); + sp = symhash[h]; + while (sp != NULL) { + if (symeq(id, sp->s_id, zflag)) + return (sp); + sp = sp->s_sp; + } + if (f == 0) + return (NULL); + sp = (struct sym *) new (sizeof(struct sym)); + sp->s_sp = symhash[h]; + symhash[h] = sp; + sp->s_id = strsto(id); /* JLH */ + return (sp); +} + +/*)Function a_uint symval(tsp) + * + * sym * tsp pointer to a symbol structure + * + * The function symval() returns the value of the + * relocated symbol by adding the variable definition + * value to the areax base address. + * + * local variables: + * a_uint val relocated address value + * + * global variables: + * none + * + * functions called: + * none + * + * side effects: + * none + */ + +a_uint +symval(tsp) +register struct sym *tsp; +{ + register a_uint val; + + val = tsp->s_addr; + if (tsp->s_axp) { + val += tsp->s_axp->a_addr; + } + return(val); +} + +/*)Function VOID symdef(fp) + * + * FILE * fp file handle for output + * + * The function symdef() scans the hashed symbol table + * searching for variables referenced but not defined. + * Undefined variables are linked to the default + * area "_CODE" and reported as referenced by the + * appropriate module. + * + * local variables: + * int i hash table index loop variable + * sym * sp pointer to linked symbol structure + * + * global variables: + * area *areap The pointer to the first + * area structure of a linked list + * sym *symhash[NHASH] array of pointers to NHASH + * linked symbol lists + * + * functions called: + * symmod() lksym.c + * + * side effects: + * Undefined variables have their areas set to "_CODE". + */ + +VOID +symdef(fp) +FILE *fp; +{ + register struct sym *sp; + register int i; + + for (i=0; is_axp == NULL) + sp->s_axp = areap->a_axp; + if ((sp->s_type & S_DEF) == 0) + symmod(fp, sp); + sp = sp->s_sp; + } + } +} + +/*)Function VOID symmod(fp,tsp) + * + * FILE * fp output file handle + * sym * tsp pointer to a symbol structure + * + * The function symmod() scans the header structures + * searching for a reference to the symbol structure + * pointed to by tsp. The function then generates an error + * message whichs names the module having referenced the + * undefined variable. + * + * local variables: + * int i loop counter + * sym ** p pointer to a list of pointers + * to symbol structures + * + * global variables: + * head *headp The pointer to the first + * head structure of a linked list + * head *hp Pointer to the current + * head structure + * int lkerr error flag + * + * functions called: + * int fprintf() c_library + * + * side effects: + * Error output generated. + */ + +VOID +symmod(fp, tsp) +FILE *fp; +struct sym *tsp; +{ + register int i; + struct sym **p; + + if ((hp = headp) != NULL) { + while(hp) { + p = hp->s_list; + for (i=0; ih_nglob; ++i) { + if (p[i] == tsp) { + fprintf(fp, + "\n?ASlink-Warning-Undefined Global %s ", + tsp->s_id); + fprintf(fp, + "referenced by module %s\n", + hp->m_id); + lkerr++; + } + } + hp = hp->h_hp; + } + } +} + +/*)Function int symeq(p1, p2, cflag) + * + * int cflag case sensitive flag + * char * p1 name string + * char * p2 name string + * + * The function symeq() compares the two name strings for a match. + * The return value is 1 for a match and 0 for no match. + * + * cflag == 0 case insensitve compare + * cflag != 0 case sensitive compare + * + * local variables: + * int n loop counter + * + * global variables: + * char ccase[] an array of characters which + * perform the case translation function + * + * functions called: + * none + * + * side effects: + * none + * + */ + +int +symeq(p1, p2, cflag) +register char *p1, *p2; +int cflag; +{ + register int n; + + n = strlen(p1) + 1; + if(cflag) { + /* + * Case Sensitive Compare + */ + do { + if (*p1++ != *p2++) + return (0); + } while (--n); + } else { + /* + * Case Insensitive Compare + */ + do { + if (ccase[*p1++ & 0x007F] != ccase[*p2++ & 0x007F]) + return (0); + } while (--n); + } + return (1); +} + +/*)Function int hash(p, cflag) + * + * char * p pointer to string to hash + * int cflag case sensitive flag + * + * The function hash() computes a hash code using the sum + * of all characters mod table size algorithm. + * + * cflag == 0 case insensitve hash + * cflag != 0 case sensitive hash + * + * local variables: + * int h accumulated character sum + * + * global variables: + * char ccase[] an array of characters which + * perform the case translation function + * + * functions called: + * none + * + * side effects: + * none + */ + +int +hash(p, cflag) +register char *p; +register int cflag; +{ + register int h; + + h = 0; + while (*p) { + if(cflag) { + /* + * Case Sensitive Hash + */ + h += *p++; + } else { + /* + * Case Insensitive Hash + */ + h += ccase[*p++ & 0x007F]; + } + } + return (h&HMASK); +} + +#if decus + +/*)Function char * strsto(str) + * + * char * str pointer to string to save + * + * Allocate space for "str", copy str into new space. + * Return a pointer to the allocated string. + * + * This function based on code by + * John L. Hartman + * jhartman@compuserve.com + * + * local variables: + * int l string length + 1 + * char * p string location + * + * global variables: + * none + * + * functions called: + * char * new() assym.c + * char * strncpy() c_library + * + * side effects: + * Space allocated for string, string copied + * to space. Out of Space terminates linker. + */ + +char * +strsto(str) +char *str; +{ + int l; + char *p; + + /* + * What we need, including a null. + */ + l = strlen(str) + 1; + p = (char *) new (l); + + /* + * Copy the name and terminating null. + */ + strncpy(p, str, l); + return(p); +} + +/* + * This code is optimized for the PDP-11 (decus) + * which has a limited program space of 56K Bytes ! + * Short strings and small structures are allocated + * from a memory hunk in new() to reduce the overhead + * from allocations directly by malloc(). Longer + * allocations are made directly by malloc. + * PDP-11 addressing requires that variables + * are allocated on a word boundary, (strings donot + * have this restriction,) all allocations will have + * at most 1 extra byte to maintain the word boundary + * requirement. + */ + +/*)Function char * new(n) + * + * unsigned int n allocation size in bytes + * + * The function new() allocates n bytes of space and returns + * a pointer to this memory. If no space is available the + * linker is terminated. + * + * Allocate space for "str", copy str into new space. + * Return a pointer to the allocated string. + * + * This function based on code by + * John L. Hartman + * jhartman@compuserve.com + * + * local variables: + * int bytes bytes remaining in buffer area + * int i loop counter + * char * p pointer to head of copied string + * char * pnext next location in buffer area + * char * q a general pointer + * + * global variables: + * none + * + * functions called: + * int fprintf() c_library + * VOID * malloc() c_library + * + * side effects: + * Memory is allocated, if allocation fails + * the linker is terminated. + */ + +/* + * To avoid wasting memory headers on small allocations, we + * allocate a big chunk and parcel it out as required. + * These static variables remember our hunk. + */ + +#define STR_SPC 1024 +#define STR_MIN 16 +static char * pnext = NULL; +static int bytes = 0; + +char * +new(n) +unsigned int n; +{ + register char *p,*q; + register unsigned int i; + + /* + * Always an even byte count + */ + n = (n+1) & 0xFFFE; + + if (n > STR_MIN) { + /* + * For allocations larger than + * most structures and short strings + * allocate the space directly. + */ + p = (char *) malloc(n); + } else { + /* + * For smaller structures and + * strings allocate from the hunk. + */ + if (n > bytes) { + /* + * No space. Allocate a new hunk. + * We lose the pointer to any old hunk. + * We don't care, as the pieces are never deleted. + */ + pnext = (char *) malloc (STR_SPC); + bytes = STR_SPC; + } + p = pnext; + pnext += n; + bytes -= n; + } + if (p == NULL) { + fprintf(stderr, "Out of space!\n"); + lkexit(ER_FATAL); + } + for (i=0,q=p; i bytes) { + /* + * No space. Allocate a new hunk. + * We lose the pointer to any old hunk. + * We don't care, as the strings are never deleted. + */ + pnext = (char *) new (STR_SPC); + bytes = STR_SPC; + } + + /* + * Copy the name and terminating null. + */ + p = pnext; + strncpy(p, str, l); + + pnext += l; + bytes -= l; + + return(p); +} + +/*)Function char * new(n) + * + * unsigned int n allocation size in bytes + * + * The function new() allocates n bytes of space and returns + * a pointer to this memory. If no space is available the + * linker is terminated. + * + * local variables: + * char * p a general pointer + * char * q a general pointer + * + * global variables: + * none + * + * functions called: + * int fprintf() c_library + * VOID * malloc() c_library + * + * side effects: + * Memory is allocated, if allocation fails + * the linker is terminated. + */ + +char * +new(n) +unsigned int n; +{ + register char *p,*q; + register unsigned int i; + + if ((p = (char *) malloc(n)) == NULL) { + fprintf(stderr, "Out of space!\n"); + lkexit(ER_FATAL); + } + for (i=0,q=p; i + + +Development starting with GNU make 3.76 by: + Paul D. Smith + + +GNU Make User's Manual + Written by: + Richard M. Stallman + + Edited by: + Roland McGrath + Bob Chassell + Melissa Weisshaus + Paul D. Smith + +----------------------------------- +GNU make porting efforts: + + Port to VMS by: + Klaus Kaempf + Archive support/Bug fixes by: + John W. Eaton + Martin Zinser + + Port to Amiga by: + Aaron Digulla + + + Port to MS-DOS (DJGPP) and MS-Windows 95/NT by: + DJ Delorie + Rob Tulloh + Eli Zaretskii + +----------------------------------- +Other contributors: + + Janet Carson + Howard Chu + Paul Eggert + Klaus Heinz + Michael Joosten + Jim Kelton + David Lubbren + Tim Magill + Greg McGary + Han-Wen Nienhuys + Andreas Schwab + Carl Staelin (Princeton University) + Ian Stewartson (Data Logic Limited) + +With suggestions/comments/bug reports from a cast of ... well ... +hundreds, anyway :) diff --git a/src/make-3.80/COPYING b/src/make-3.80/COPYING new file mode 100755 index 00000000..a3f6b12e --- /dev/null +++ b/src/make-3.80/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/src/make-3.80/ChangeLog b/src/make-3.80/ChangeLog new file mode 100755 index 00000000..2ca872ba --- /dev/null +++ b/src/make-3.80/ChangeLog @@ -0,0 +1,857 @@ +2002-10-03 Paul D. Smith + + Version 3.80 released. + + * dir.c: Change hash functions to use K&R function definition style. + * function.c: Ditto. + * read.c: Ditto. + * variable.c: Ditto. + + Update to automake 1.7. + + * Makefile.am (AUTOMAKE_OPTIONS): Update to require 1.7. + (pdf): Remove this target as automake now provides one. + + * configure.in: Change AM_CONFIG_HEADER to AC_CONFIG_HEADERS. + +2002-09-30 Martin P.J. Zinser + + * makefile.com: Updates for GNU make 3.80. + * makefile.vms: Ditto. + +2002-09-23 Paul D. Smith + + * read.c (enum make_word_type): Remove w_comment. + (get_next_mword): Don't treat comment characters as special; where + this function is used we will never see a comment (it's stripped + before we get here) and treating comments specially means that + targets like "foo\#bar" aren't handled properly. + +2002-09-18 Paul D. Smith + + * doc/make.texi (Bugs): Update with some info on Savannah, etc. + + * read.c (eval): Expansion of arguments to export/unexport was + ignoring all arguments after the first one. Change the algorithm + to expand the whole line once, then parse the results. + +2002-09-17 Paul D. Smith + + Fix Bug #940 (plus another bug I found while looking at this): + + * read.c (record_target_var): enter_file() will add a new entry if + it's a double-colon target: we don't want to do that in this + situation. Invoke lookup_file() and only enter_file() if it does + not already exist. If the file we get back is a double-colon then + add this variable to the "root" double-colon target. + + * variable.c (initialize_file_variables): If this file is a + double-colon target but is not the "root" target, then initialize + the root and make the root's variable list the parent of our + variable list. + +2002-09-13 Paul D. Smith + + * doc/make.texi (MAKE Variable): Add some indexing for "+". + + * hash.c (round_up_2): Get rid of a warning. + +2002-09-12 Paul D. Smith + + * Makefile.am (loadavg_SOURCES, loadavg.c): Tiptoe around automake + so it doesn't complain about getloadavg.c. + + * commands.c (set_file_variables): Make sure we always alloca() at + least 1 character for the value of $? (for '\0'). + +2002-09-11 Paul D. Smith + + * hash.h (STRING_COMPARE, ISTRING_COMPARE, STRING_N_COMPARE): Fix + macro to use RESULT instead of the incorrect _RESULT_. + + * make.h (HAVE_BROKEN_RESTART): Add prototypes for atomic_stat() + and atomic_readdir(). We need to #include dirent.h to get this to + work. + * misc.c (atomic_readdir): Fix typos. + +2002-09-10 Paul D. Smith + + * read.c (eval): Expand variable lists given to export and + unexport, so that "export $(LIST_OF_VARIABLES)" (etc.) works. + (conditional_line): Ditto for "ifdef". Fixes bug #103. + + * doc/make.texi (Variables/Recursion): Document this. + (Conditional Syntax): And here. + +2002-09-09 Paul D. Smith + + * configure.in: Check for memmove(). + +2002-09-07 Paul D. Smith + + * configure.in (HAVE_BROKEN_RESTART): Define this on PTX systems; + Michael Sterrett reports that while it has + SA_RESTART, it does not work properly. + + * misc.c (atomic_stat): If HAVE_BROKEN_RESTART, create a function + that invokes stat() and loops to do it again if it returns EINTR. + (atomic_readdir): Ditto, with readdir(). + + * make.h (stat, readdir): If HAVE_BROKEN_RESTART, alias stat() + and readdir() to atomic_stat() and atomic_readdir(). + +2002-09-04 Paul D. Smith + + * implicit.c (pattern_search): Daniel + reports that GNU make sometimes doesn't recognize that targets can + be made, when directories can be created as prerequisites. He + reports that changing the order of predicates in the DEP->changed + flag test so that lookup_file() is always performed, solves this + problem. + +2002-08-08 Paul D. Smith + + * configure.in: Require a newer version of gettext. + + * misc.c (perror_with_name): Translate the format string (for + right-to-left language support). + (pfatal_with_name): Ditto. + + * main.c: Create a static array of strings to store the usage + text. This is done to facilitate translations. + (struct command_switch): Remove argdesc and description fields. + (switches): Remove values for obsolete fields. + (print_usage): Print each element of the usage array. + + * hash.c: Change function definitions to be K&R style. + +2002-08-02 Paul D. Smith + + * NEWS: Remove the mention of .TARGETS; we aren't going to publish + this one because it's too hard to get right. We'll look at it for + a future release. + * main.c (main): Don't create the .TARGETS variable. + * variable.c (handle_special_var): Don't handle .TARGETS. + +2002-08-01 Paul D. Smith + + * main.c (switches): Add a new option, -B (--always-make). If + specified, make will rebuild all targets that it encounters even + if they don't appear to be out of date. + (always_make_flag): New flag. + * make.h: Extern always_make_flag. + * remake.c (update_file_1): Check always_make_flag; if it's set we + will always rebuild any target we can, even if none of its + prerequisites are newer. + * NEWS: Mention it. + + * doc/make.texi (Shell Function): Make it clear that make + variables marked as "export" are not passed to instances of the + shell function. + + Add new introspection variable .VARIABLES and .TARGETS. + + * variable.c (handle_special_var): New function. If the variable + reference passed in is "special" (.VARIABLES or .TARGETS), + calculate the new value if necessary. .VARIABLES is handled here: + walk through the hash of defined variables and construct a value + which is a list of the names. .TARGETS is handled by + build_target_list(). + (lookup_variable): Invoke handle_special_var(). + * file.c (build_target_list): Walk through the hask of known files + and construct a list of the names of all the ones marked as + targets. + * main.c (main): Initialize them to empty (and as simple variables). + * doc/make.texi (Special Variables): Document them. + * NEWS: Mention them. + + * variable.h (struct variable): Add a new flag "exportable" which + is true if the variable name is valid for export. + * variable.c (define_variable_in_set): Set "exportable" when a new + variable is defined. + (target_environment): Use the "exportable" flag instead of + re-checking the name here... an efficiency improvement. + +2002-07-31 Paul D. Smith + + * config.h-vms.template: Updates to build on VMS. Thanks to + Brian_Benning@aksteel.com for helping verify the build. + * makefile.com: Build the new hash.c file. + * hash.h: Use strcpmi(), not stricmp(), in the + HAVE_CASE_INSENSITIVE_FS case. + +2002-07-30 Paul D. Smith + + * hash.h (ISTRING_COMPARE, return_ISTRING_COMPARE): Add missing + backslashes to the HAVE_CASE_INSENSITIVE_FS case. + Reported by . + +2002-07-10 Paul D. Smith + + * variable.c (pop_variable_scope): Remove variable made unused by + new hash infrastructure. + * read.c (dep_hash_cmp): Rewrite this to handle ignore_mtime + comparisons as well as name comparisons. + * variable.h: Add a prototype for new hash_init_function_table(). + * file.c (lookup_file): Remove variables made unused by new hash + infrastructure. + * dir.c (directory_contents_hash_2): Missing return of hash value. + (dir_contents_file_exists_p): Remove variables made unused by new + hash infrastructure. + + + Installed Greg McGary's integration of the hash functions from the + GNU id-utils package: + +2002-07-10 Greg McGary + + * scripts/functions/filter-out: Add literals to to the + pattern space in order to add complexity, and trigger + use of an internal hash table. Fix documentation strings. + * scripts/targets/INTERMEDIATE: Reverse order of files + passed to expected `rm' command. + +2002-07-10 Greg McGary + + * Makefile.am (SRCS): Add hash.c (noinst_HEADERS): Add hash.h + * hash.c: New file, taken from id-utils. + * hash.h: New file, taken from id-utils. + + * make.h (HASH, HASHI): Remove macros. + (find_char_unquote): Change arglist in decl. + (hash_init_directories): New function decl. + * variable.h (hash.h): New #include. + (MAKELEVEL_NAME, MAKELEVEL_LENGTH): New constants. + * filedef.h (hash.h): New #include. + (struct file) [next]: Remove member. + (file_hash_enter): Remove function decl. + (init_hash_files): New function decl. + + * ar.c (ar_name): Delay call to strlen until needed. + * main.c (initialize_global_hash_tables): New function. + (main): Call it. Use MAKELEVEL_NAME & MAKELEVEL_LENGTH. + * misc.c (remove_comments): Pass char constants to find_char_unquote. + * remake.c (notice_finished_file): Update last_mtime on `prev' chain. + + * dir.c (hash.h): New #include. + (struct directory_contents) [next, files]: Remove members. + [ctime]: Add member for VMS. [dirfiles]: Add hash-table member. + (directory_contents_hash_1, directory_contents_hash_2, + directory_contents_hash_cmp): New functions. + (directories_contents): Change type to `struct hash_table'. + (struct directory) [next]: Remove member. + (directory_hash_1, directory_hash_2, directory_hash_cmp): New funcs. + (directory): Change type to `struct hash_table'. + (struct dirfile) [next]: Remove member. + [length]: Add member. [impossible]: widen type to fill alignment gap. + (dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp): New functions. + (find_directory): Use new hash table package. + (dir_contents_file_exists_p): Likewise. + (file_impossible): Likewise. + (file_impossible_p): Likewise. + (print_dir_data_base): Likewise. + (open_dirstream): Likewise. + (read_dirstream): Likewise. + (hash_init_directories): New function. + + * file.c (hash.h): New #include. + (file_hash_1, file_hash_2, file_hash_cmp): New functions. + (files): Change type to `struct hash_table'. + (lookup_file): Use new hash table package. + (enter_file): Likewise. + (remove_intermediates): Likewise. + (snap_deps): Likewise. + (print_file_data_base): Likewise. + + * function.c + (function_table_entry_hash_1, function_table_entry_hash_2, + function_table_entry_hash_cmp): New functions. + (lookup_function): Remove `table' argument. + Use new hash table package. + (struct a_word) [chain, length]: New members. + (a_word_hash_1, a_word_hash_2, a_word_hash_cmp): New functions. + (struct a_pattern): New struct. + (func_filter_filterout): Pass through patterns noting boundaries + and '%', if present. Note a_word length. Use a hash table if + arglists are large enough to justify cost. + (function_table_init): Renamed from function_table. + (function_table): Declare as `struct hash_table'. + (FUNCTION_TABLE_ENTRIES): New constant. + (hash_init_function_table): New function. + + * read.c (hash.h): New #include. + (read_makefile): Pass char constants to find_char_unquote. + (dep_hash_1, dep_hash_2, dep_hash_cmp): New functions. + (uniquize_deps): Use hash table to efficiently identify duplicates. + (find_char_unquote): Accept two char-constant stop chars, rather + than a string constant, avoiding zillions of calls to strchr. + Tighten inner search loops to test only for desired delimiters. + + * variable.c (variable_hash_1, variable_hash_2, + variable_hash_cmp): New functions. + (variable_table): Declare as `struct hash_table'. + (global_variable_set): Remove initialization. + (init_hash_global_variable_set): New function. + (define_variable_in_set): Use new hash table package. + (lookup_variable): Likewise. + (lookup_variable_in_set): Likewise. + (initialize_file_variables): Likewise. + (pop_variable_scope): Likewise. + (create_new_variable_set): Likewise. + (merge_variable_sets): Likewise. + (define_automatic_variables): Likewise. + (target_environment): Likewise. + (print_variable_set): Likewise. + +2002-07-10 Paul D. Smith + + Implement the SysV make syntax $$@, $$(@D), and $$(@F) in the + prerequisite list. A real SysV make will expand the entire + prerequisites list _twice_: we don't do that as it's a big + backward-compatibility problem. We only replace those specific + variables. + + * read.c (record_files): Replace any $@, $(@D), and $(@F) variable + references left in the list of prerequisites. Check for .POSIX as + we record targets, so we can disable non-POSIX behavior while + reading makefiles as well as running them. + (eval): Check the prerequisite list to see if we have anything + that looks like a SysV prerequisite variable reference. + +2002-07-09 Paul D. Smith + + * doc/make.texi (Prerequisite Types): Add a new section describing + order-only prerequisites. + + * read.c (uniquize_deps): If we have the same file as both a + normal and order-only prereq, get rid of the order-only prereq, + since the normal one supersedes it. + +2002-07-08 Paul D. Smith + + * AUTHORS: Added Greg McGary to the AUTHORS file. + * NEWS: Blurbed order-only prerequisites. + * file.c (print_file): Show order-only deps properly when printing + the database. + + * maintMakefile: Add "update" targets for wget'ing the latest + versions of various external files. Taken from Makefile.maint in + autoconf, etc. + + * dosbuild.bat: Somehow we got _double_ ^M's. Remove them. + Reported by Eli Zaretskii . + +2002-07-07 Paul D. Smith + + * po/*.po: Remove. We'll use wget to retrieve them at release + time. + + * variable.c (do_variable_definition) [W32]: On W32 using cmd + rather than a shell you get an exception. Make sure we look up + the variable. Patch provided by Eli Zaretskii . + + * remake.c (notice_finished_file): Fix handling of -t flag. + Patch provided by Henning Makholm . + + * implicit.c (pattern_search): Some systems apparently run short + of stack space, and using alloca() in this function caused an + overrun. I modified it to use xmalloc() on the two variables + which seemed like they might get large. Fixes Bug #476. + + * main.c (print_version): Update copyright notice to conform with + GNU standards. + (print_usage): Update help output. + + * function.c (func_eval): Create a new make function, $(eval + ...). Expand the arguments, put them into a buffer, then invoke + eval_buffer() on the resulting string. + (func_quote): Create a new function, $(quote VARNAME). Inserts + the value of the variable VARNAME without expanding it any + further. + + * read.c (struct ebuffer): Change the linebuffer structure to an + "eval buffer", which can be either a file or a buffer. + (eval_makefile): Move the code in the old read_makefile() which + located a makefile into here: create a struct ebuffer with that + information. Have it invoke the new function eval() with that + ebuffer. + (eval_buffer): Create a new function that creates a struct ebuffer + that holds a string buffer instead of a file. Have it invoke + eval() with that ebuffer. + (eval): New function that contains the guts of the old + read_makefile() function: this function parses makefiles. Obtains + data to parse from the provided ebuffer. Some modifications to + make the flow of the function cleaner and clearer. Still could + use some work here... + (do_define): Takes a struct ebuffer instead of a FILE*. Read the + contents of the define/endef variable from the ebuffer. + (readstring): Read the next line from a string-style ebuffer. + (readline): Read the next line from an ebuffer. If it's a string + ebuffer, invoke readstring(). If it's a FILE* ebuffer, read it + from the file. + + * dep.h (eval_buffer): Prototype eval_buffer(); + + * variable.c (do_variable_definition): Make sure that all + non-target-specific variables are registered in the global set. + If we're invoked from an $(eval ...) we might be inside a $(call + ...) or other function which has pushed a variable scope; we still + want to define our variables from evaluated makefile code in the + global scope. + +2002-07-03 Greg McGary + + * dep.h (struct dep) [ignore_mtime]: New member. + [changed]: convert to a bitfield. + * implicit.c (pattern_search): Zero ignore_mtime. + * main.c (main, handle_non_switch_argument): Likewise. + * rule.c (convert_suffix_rule): Likewise. + * read.c (read_all_makefiles, read_makefile, multi_glob): Likewise. + (read_makefile): Parse '|' in prerequisite list. + (uniquize_deps): Consider ignore_mtime when comparing deps. + * remake.c (update_file_1, check_dep): Don't force remake for + dependencies that have d->ignore_mtime. + * commands.c (FILE_LIST_SEPARATOR): New constant. + (set_file_variables): Don't include a + prerequisite in $+, $^ or $? if d->ignore_mtime. + Define $|. + +2002-06-18 Paul D. Smith + + * make.texinfo: Updates for next revision. New date/rev/etc. + Recreate all Info menus. Change license on the manual to the GNU + Free Documentation License. A number of typos. + (Variables Simplify): Don't use "-" before it's defined. + (Automatic Prerequisites): Rewrite the target example to work + properly if the compile fails. Remove incorrect comments about + how "set -e" behaves. + (Text Functions): Move the "word", "wordlist", "words", and + "firstword" functions here, from "File Name Functions". + * make-stds.texi: Update from latest GNU version. + * fdl.texi: (created) Import the latest GNU version. + +2002-06-06 Paul D. Smith + + * variable.c (do_variable_definition): New function: extract the + part of try_variable_definition() that actually sets the value + into a separate function. + (try_variable_definition): Call do_variable_definition() after + parsing the variable definition string. + (define_variable_in_set): Make the name argument const. + + * variable.h (enum variable_flavor): Make public. + (do_variable_definition): Create prototype. + + * read.c (read_all_makefiles): Create a new built-in variable, + MAKEFILE_LIST. + (read_makefile): Add each makefile read in to this variable value. + +2002-05-18 Eli Zaretskii + + * Makefile.DOS.template: Tweak according to changes in the + distribution. Add back the dependencies of *.o files. + + * configh.dos.template: Synchronize with config.h.in. + +2002-05-09 Paul D. Smith + + * file.c (file_timestamp_now): Use K&R function declaration. + + * getloadavg.c (getloadavg): Merge setlocale() fix from sh-utils + getloadavg.c. Autoconf thinks QNX is SVR4-like, but it isn't, so + #undef it. Remove predefined setup of NLIST_STRUCT. Decide + whether to include nlist.h based on HAVE_NLIST_H. Change obsolete + NLIST_NAME_UNION to new HAVE_STRUCT_NLIST_N_UN_N_NAME. + * configure.in (NLIST_STRUCT): Define this if we have nlist.h and + nlist.n_name is a pointer rather than an array. + + * acinclude.m4 (make_FUNC_SETVBUF_REVERSED): Grab the latest + version of AC_FUNC_SETVBUF_REVERSED from autoconf CVS. + * configure.in: Use it instead of the old version. + + * main.c (main): Prefer setvbuf() to setlinebuf(). + +2002-05-08 Paul D. Smith + + * Makefile.am (make_LDADD): Add GETLOADAVG_LIBS. + (loadavg_LDADD): Ditto. + +2002-04-29 Paul D. Smith + + * expand.c (recursively_expand_for_file): Rename + recursively_expand() to recursively_expand_for_file() and provide + an extra argument, struct file. If the argument is provided, set + the variable scope to that of the file before expanding. + * variable.h (recursively_expand): Make this a macro that invokes + recursively_expand_for_file() with a NULL file pointer. + * variable.c (target_environment): Call the renamed function and + provide the current file context. + Fixes Debian bug #144306. + +2002-04-28 Paul D. Smith + + Allow $(call ...) user-defined variables to be self-referencing + without throwing an error. Allows implementation of transitive + closures, among other possibly useful things. + Requested by: Philip Guenther + + * variable.h (struct variable): Add a new field: exp_count, and + new macros to hold its size and maximum value. + (warn_undefined): Make this a macro. + * variable.c (define_variable_in_set): Initialize it. + * expand.c (recursively_expand): If we detect recursive expansion + of a variable, check the exp_count field. If it's greater than 0 + allow the recursion and decrement the count. + (warn_undefined): Remove this (now a macro in variable.h). + * function.c (func_call): Before we expand the user-defined + function, modify its exp_count field to contain the maximum + number of recursive calls we'll allow. After the call, reset it + to 0. + +2002-04-21 Paul D. Smith + + Modified to use latest autoconf (2.53), automake (1.6.1), and + gettext (0.11.1). We're using gettext's new "external" support, + to avoid including libintl source with GNU make. + + * README.cvs: New file. Explain how to build GNU make from CVS. + + * configure.in: Modify checking for the system glob library. + Use AC_EGREP_CPP instead of AC_TRY_CPP. Remove the setting of + GLOBDIR (we will always put "glob" in SUBDIRS, so automake + etc. will manage it correctly). Set an automake conditional + USE_LOCAL_GLOB to decide whether to compile the glob library. + + * getloadavg.c (main): Include make.h in the "TEST" program to + avoid warnings. + + * Makefile.am: Remove special rules for loadavg. Replace them + with Automake capabilities for building extra programs. + + * signame.c: This file does nothing if the system provide + strsignal(). If not, it implements strsignal(). If the system + doesn't define sys_siglist, then we make our own; otherwise we use + the system version. + * signame.h: Removed. + + * main.c (main): No need to invoke signame_init(). Update copyright. + + * ABOUT-NLS: Removed. + * gettext.c: Removed. + * gettext.h: Get a simplified copy from the gettext package. + * po/*: Created. + * i18n/*.po: Moved to po/. + * i18n/: Removed. + + * config/*: Created. Contains package configuration helper files. + * config.guess, config.sub: Moved to config directory. + + * configure.in (AC_CONFIG_FILES): Add po/Makefile.in, config/Makefile. + Rework to use new-style autoconf features. Use the "external" + mode for gettext. Make the build.sh config file conditional on + whether build.sh.in exists, to avoid autoconf errors. + * acinclude.m4: Removed almost all macros as being obsolete. + Rewrote remaining macros to use AC_DEFINE. + * acconfig.h: Removed. + + * Makefile.am (EXTRA_DIST): Add config/config.rpath. Use a + conditional to handle customs support. Remove special handling + for i18n features. + +2002-04-20 Paul D. Smith + + * function.c (func_call): Don't mark the argument variables $1, + etc. as recursive. They've already been fully expanded so + there's no need to do it again, and doing so strips escaped $'s. + Reported by Sebastian Glita . + + * remake.c (notice_finished_file): Walk through double-colon + entries via the prev field, not the next field! + Reported by Greg McGary . + + * main.c (main): If the user specifies -q and asks for a specific + target which is a makefile, we got an assert. In that case it + turns out we should continue normally instead. + + * i18n/de.po, i18n/fr.po: Installed an updated translation. + + * i18n/he.po: Installed a new translation. + +2002-01-07 Paul D. Smith + + * i18n/es.po, i18n/ru.po: Installed an updated translation. + +2001-12-04 Paul D. Smith + + * i18n/ja.po: Installed an updated translation. + +2001-09-04 Paul D. Smith + + * i18n/da.po: Installed an updated translation. + +2001-08-03 Paul D. Smith + + * i18n/fr.po: Installed an updated translation. + Resolves Debian bug #106720. + +2001-06-13 Paul D. Smith + + * i18n/da.po, configure.in (ALL_LINGUAS): Installed a new + translation. + +2001-06-11 Paul D. Smith + + * i18n/ko.po: Installed a new translation. + +2001-05-06 Paul D. Smith + + Modify the EINTR handling. + + * job.c (new_job): Reorganize the jobserver algorithm. Reorder + the way in which we manage the file descriptor/signal handler race + trap to be more efficient. + +2001-05-06 Paul Eggert + + Restart almost all system calls that are interrupted, instead + of worrying about EINTR. The lone exception is the read() for + job tokens. + + * configure.in (HAVE_SA_RESTART): New macro. + (MAKE_JOBSERVER): Define to 1 only if HAVE_SA_RESTART. + * main.c (main): Use SA_RESTART instead of the old, + nonstandard SA_INTERRUPT. + + * configure.in (AC_CHECK_FUNCS): Add bsd_signal. + * main.c (bsd_signal): New function or macro, + if the implementation doesn't supply it. + (The bsd_signal function will be in POSIX 1003.1-200x.) + (HANDLESIG): Remove. + (main, FATAL_SIG): Use bsd_signal instead of signal or HANDLESIG. + + * make.h (EINTR_SET): Remove. + (SA_RESTART): New macro. + + * arscan.c (ar_member_touch): Don't worry about EINTR. + * function.c (func_shell): Likewise. + * job.c (reap_children, free_child, new_job): Likewise. + * main.c (main): Likewise. + * remake.c (touch_file, name_mtime): Likewise. + + * arscan.c (ar_member_touch): Fix bug uncovered by EINTR removal; + if fstat failed with errno!=EINTR, the error was ignored. + + * job.c (set_child_handler_action_flags): New function. + (new_job): Use it to temporarily clear the SIGCHLD action flags + while reading the token. + +2001-05-02 Paul D. Smith + + * job.c (start_job_command): Don't add define/endef per-line flags + to the top-level flags setting. + +2001-04-03 Paul D. Smith + + * arscan.c (VMS_get_member_info,ar_scan) [VMS]: VMS sets the low + bit on error, so check for odd return values, not non-0 return + values. + (VMS_get_member_info): Calculate the timezone differences correctly. + Reported by John Fowler . + + +2001-03-14 Paul D. Smith + + * variable.c (lookup_variable) [VMS]: Null-terminate the variable + value before invoking define_variable(). + Reported by John Fowler . + +2001-02-07 Paul D. Smith + + * read.c (record_target_var): If we reset the variable due to a + command-line variable setting overriding it, turn off the "append" + flag. + +2001-01-17 Paul D. Smith + + * variable.c (lookup_variable) [VMS]: When getting values from the + environment, allocate enough space for the _value_ plus escapes, + not enough space for the name plus escapes :-/. + Reported by John Fowler . + + * remake.c (f_mtime): Removed the "***" prefix from the mod time + warnings that make generates, so it doesn't look like an error. + Reported by Karl Berry . + + + Fix for PR/2020: Rework appended target-specific variables. I'm + fairly confident this algorithm is finally correct. + + * expand.c (allocated_variable_append): Rewrite. Instead of + expanding each appended variable then adding all the expanded + strings together, we append all the unexpanded values going up + through the variable set contexts, then expand the final result. + This behaves just like non-target-specific appended variable + values, while the old way didn't in various corner cases. + (variable_append): New function: recursively append the unexpanded + value of a variable, walking from the outermost variable scope to + the innermost. + * variable.c (lookup_variable): Remove the code that looked up the + variable set list if the found variable was "append". We don't + need this anymore. + (lookup_variable_in_set): Make this non-static so we can use it + elsewhere. + (try_variable_definition): Use lookup_variable_in_set() rather + than faking out current_variable_set_list by hand (cleanup). + * variable.h: Add a prototype for the now non-static + lookup_variable_in_set(). + +2000-11-17 Paul D. Smith + + * remake.c (f_mtime) [WINDOWS32]: On various advice, I changed the + WINDOWS32 port to assume timestamps can be up to 3 seconds away + before throwing a fit. + +2000-11-17 Paul D. Smith + + * read.c (readline): CRLF calculations had a hole, if you hit the + buffer grow scenario just right. Reworked the algorithm to avoid + the need for len or lastlen at all. Problem description with + sample code chages provided by Chris Faylor . + +2000-10-24 Paul D. Smith + + * gettext.c (SWAP): Declare this with the prototype, otherwise + some systems don't work (non-32-bit? Reported for Cray T3E). + Reported by Thorstein Thorsteinsson . + +2000-10-05 Paul D. Smith + + * acinclude.m4 (AM_LC_MESSAGES): Remove undefined macro + AM_LC_MESSAGES; it doesn't seem to do anything anyway?? + + * i18n/gl.po, configure.in (ALL_LINGUAS): New Galician translation. + +2000-09-22 Paul D. Smith + + * gettext.c: Don't #define _GETTEXT_H here; we only include some + parts of the real gettext.h here, and we expect to really include + the real gettext.h later. If we keep this #define, it's ignored. + +2000-09-21 Paul D. Smith + + * main.c (log_working_directory): Rework the text to use complete + sentences, to make life simpler for the translators. + +2000-08-29 Paul D. Smith + + * file.c (remove_intermediates): Print a debug message before we + remove intermediate files, so the user (if she uses -d) knows + what's going on. + +2000-08-21 Paul D. Smith + + * variable.c (try_variable_definition): Change how we handle + target-specific append variable defns: instead of just setting the + value, expand it as an append _but_ only within the current + target's context. Otherwise we lose all but the last value if the + variable is appended more than once within the current target + context. Fixes PR/1831. + +2000-08-16 Paul D. Smith + + * function.c (func_shell): Nul-terminate the buffer before + printing an exec error message (just in case it's not!). + Fixes PR/1860, reported by Joey Hess . + +2000-07-25 Paul D. Smith + + * job.c (construct_command_argv_internal): Add "~" to the list of + sh_chars[] which disallow optimizing out the shell call. + +2000-07-23 Paul Eggert + + * NEWS, make.texinfo: Document .LOW_RESOLUTION_TIME, which + supersedes --disable-nsec-timestamps. + * make.texinfo: Consistently use "time stamp" instead of "timestamp". + * README: Remove --disable-nsec-timestamps. + + * filedef.h (struct file.low_resolution_time): New member. + * file.c (snap_deps): Add support for .LOW_RESOLUTION_TIME. + * remake.c (update_file_1): + Avoid spurious rebuilds due to low resolution time stamps, + generalizing the earlier code that applied only to archive members. + (f_mtime): Archive members always have low resolution time stamps. + + * configure.in: Remove --disable-nsec-timestamps, as this has + been superseded by .LOW_RESOLUTION_TIME. + +2000-07-23 Paul Eggert + + * configure.in (enable_nsec_timestamps): Renamed from + make_cv_nsec_timestamps, since enable/disable options + shouldn't be cached. + +2000-07-23 Bruno Haible + and Paul Eggert + + * file.c (file_timestamp_now): + Use preprocessor-time check for FILE_TIMESTAMP_HI_RES + so that clock_gettime is not linked unless needed. + + * filedef.h (FILE_TIMESTAMP_HI_RES): + Remove definition; "configure" now does this. + + * configure.in (jm_AC_TYPE_UINTMAX_T): Move up, + to before high resolution file timestamp check, + since that check now uses uintmax_t. + (FILE_TIMESTAMP_HI_RES): Define to nonzero if the code should use + high resolution file timestamps. + (HAVE_CLOCK_GETTIME): Do not define if !FILE_TIMESTAMP_HI_RES, + so that we don't link in clock_gettime unnecessarily. + +2000-07-17 Paul D. Smith + + * i18n/ja.po: New version of the translation file. + +2000-07-07 Paul D. Smith + + * remake.c (f_mtime): If NO_FLOAT is defined, don't bother with + the offset calculation. + (name_mtime): Replace EINTR test with EINTR_SET macro. + +2000-07-07 Paul Eggert + + Fix for PR/1811: + + * remake.c (update_file_1): + Avoid spurious rebuilds of archive members due to their + timestamp resolution being only one second. + (f_mtime): Avoid spurious warnings of timestamps in the future due to + the clock's resolution being lower than file timestamps'. + When warning about future timestamps, report only the discrepancy, + not the absolute value of the timestamp and the current time. + + * file.c (file_timestamp_now): New arg RESOLUTION. + * filedef.h (file_timestamp_now): Likewise. + (FILE_TIMESTAMP_NS): Now returns int. All uses changed. + +2000-07-05 Paul D. Smith + + * variable.c (lookup_variable) [VMS]: Remove vestigial references + to listp. Fixes PR/1793. + +2000-06-26 Paul Eggert + + * Makefile.am (MAINTAINERCLEANFILES): New macro, with stamp-pot in it. + + * dir.c (vms_hash): Ensure ctype macro args are nonnegative. + + * remake.c (f_mtime): Remove unused var memtime. + +2000-06-25 Martin Buchholz + + * make.texinfo, NEWS, TODO.private: Minor spelling corrections. + Ran spell-check on make.texinfo. + + +See ChangeLog.2 for earlier changes. diff --git a/src/make-3.80/INSTALL b/src/make-3.80/INSTALL new file mode 100755 index 00000000..bca44d04 --- /dev/null +++ b/src/make-3.80/INSTALL @@ -0,0 +1,187 @@ +Basic Installation +================== + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + If you're building GNU make on a system which does not already have + a `make', you can use the build.sh shell script to compile. Run + `sh ./build.sh'. This should compile the program in the current + directory. Then you will have a Make program that you can use for + `make install', or whatever else. + + 3. Optionally, type `./make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/src/make-3.80/Makefile.DOS b/src/make-3.80/Makefile.DOS new file mode 100755 index 00000000..1d9568a0 --- /dev/null +++ b/src/make-3.80/Makefile.DOS @@ -0,0 +1,693 @@ +# -*-Makefile-*- template for DJGPP +# Makefile.in generated automatically by automake 1.2 from Makefile.am + +# Copyright (C) 1994, 1995-1998, 1999, 2002 Free Software Foundation, Inc. +# This Makefile.DOS is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + + +SHELL = /bin/sh + +srcdir = . +VPATH = $(srcdir) +# $DJDIR is defined automatically by DJGPP to point +# to the root of the DJGPP installation tree. +prefix = /dev/env/DJDIR +exec_prefix = ${prefix} + +bindir = /bin +datadir = /share +libdir = /lib +infodir = /info +mandir = /man +includedir = /include +oldincludedir = c:/djgpp/include + +DESTDIR = /dev/env/DJDIR + +pkgdatadir = $(datadir)/make +pkglibdir = $(libdir)/make +pkgincludedir = $(includedir)/make +localedir = $(datadir)/locale + +INSTALL = ${exec_prefix}/bin/ginstall -c +INSTALL_PROGRAM = ${exec_prefix}/bin/ginstall -c +INSTALL_DATA = ${exec_prefix}/bin/ginstall -c -m 644 +INSTALL_SCRIPT = ${exec_prefix}/bin/ginstall -c +transform = s,x,x, + +# This will fail even if they don't have a Unix-like shell (stock DOS +# shell doesn't know about `false'). The only difference is that they +# get "Error -1" instead of "Error 1". +EXIT_FAIL = false + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +EXEEXT = .exe +OBJEXT = o + +AR = ar +AWK = gawk +CC = gcc +CPP = gcc -E +LIBOBJS = +MAKEINFO = ${exec_prefix}/bin/makeinfo +PACKAGE = make +PERL = perl +RANLIB = ranlib +REMOTE = stub +VERSION = 3.80 + +AUTOMAKE_OPTIONS = 1.2 + +bin_PROGRAMS = make$(EXEEXT) + +make_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c function.c getopt.c getopt1.c implicit.c job.c main.c misc.c read.c remake.c rule.c signame.c variable.c version.c vpath.c hash.c remote-$(REMOTE).c +# This should include the glob/ prefix +libglob_a_SOURCES = glob/fnmatch.c glob/glob.c glob/fnmatch.h glob/glob.h +make_LDADD = glob/libglob.a + +info_TEXINFOS = make.texinfo +man_MANS = make.1 + +INCLUDES = -I$(srcdir)/glob -DLIBDIR=\"c:/djgpp/lib\" -DINCLUDEDIR=\"c:/djgpp/include\" -DLOCALEDIR=\"$(localedir)\" + +BUILT_SOURCES = README build.sh-in + +EXTRA_DIST = $(BUILT_SOURCES) $(man_MANS) README.customs remote-cstms.c make-stds.texi texinfo.tex SCOPTIONS SMakefile Makefile.ami README.Amiga config.ami amiga.c amiga.h NMakefile README.DOS configh.dos configure.bat makefile.com README.W32 build_w32.bat config.h-W32 subproc.bat make.lnk config.h-vms makefile.vms readme.vms vmsdir.h vmsfunctions.c vmsify.c + +SUBDIRS = glob +mkinstalldirs = ${exec_prefix}/bin/gmkdir -p +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = build.sh +PROGRAMS = $(bin_PROGRAMS) + +MAKE_HOST = i386-pc-msdosdjgpp + + +DEFS = -I. -I$(srcdir) -I. +CPPFLAGS = -DHAVE_CONFIG_H +LDFLAGS = +LIBS = +make_OBJECTS = ar.o arscan.o commands.o default.o dir.o expand.o file.o function.o getopt.o getopt1.o implicit.o job.o main.o misc.o read.o remake.o rule.o signame.o variable.o version.o vpath.o hash.o remote-$(REMOTE).o +make_DEPENDENCIES = glob/libglob.a +make_LDFLAGS = +libglob_a_LIBADD = +libglob_a_OBJECTS = fnmatch.o glob.o +noinst_LIBRARIES = glob/libglob.a +CFLAGS = -O2 -g +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) +LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ +TEXI2DVI = texi2dvi +TEXINFO_TEX = $(srcdir)/config/texinfo.tex +INFO_DEPS = make.info +DVIS = make.dvi +TEXINFOS = make.texinfo +man1dir = $(mandir)/man1 +MANS = $(man_MANS) + +NROFF = nroff +DIST_COMMON = README ABOUT-NLS AUTHORS COPYING ChangeLog INSTALL Makefile.am Makefile.in NEWS acconfig.h aclocal.m4 alloca.c build.sh-in config.h-in configure configure.in getloadavg.c + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP = --best +SOURCES = $(make_SOURCES) +OBJECTS = $(make_OBJECTS) +HEADERS = $(wildcard $(srcdir)/*.h) + +default: all + +.SUFFIXES: +.SUFFIXES: .c .dvi .info .o .obj .ps .texinfo .tex + +mostlyclean-hdr: + +clean-hdr: + +distclean-hdr: + -rm -f config.h + +maintainer-clean-hdr: + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do if test -f $$p; then echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p | sed '$(transform)'`"; $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p | sed '$(transform)'`; else :; fi; done + +uninstall-binPROGRAMS: + $(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do rm -f $(DESTDIR)$(bindir)/`echo $$p|sed '$(transform)'`.exe; done + +.c.o: + $(COMPILE) -c $< + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) *$(EXEEXT) make.new core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c *_tab.c + +maintainer-clean-compile: + +make$(EXEEXT): $(make_OBJECTS) $(make_DEPENDENCIES) + @command.com /c if exist make del make + @command.com /c if exist make.exe del make.exe + $(LINK) $(make_LDFLAGS) $(make_OBJECTS) $(make_LDADD) $(LIBS) + +make.info: make.texinfo +make.dvi: make.texinfo + + +DVIPS = dvips + +.texinfo.info: + @command.com /c if exist make.info* del make.info* + @command.com /c if exist make.i* del make.i* + $(MAKEINFO) -I$(srcdir) $< -o ./$@ + +.texinfo: + @command.com /c if exist make.info* del make.info* + @command.com /c if exist make.i* del make.i* + $(MAKEINFO) -I$(srcdir) $< -o ./$@ + +.texinfo.dvi: + TEXINPUTS="$(srcdir);$$TEXINPUTS" MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $< + + +.dvi.ps: + $(DVIPS) $< -o $@ + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(infodir) + @for file in $(INFO_DEPS) make.i; do d=$(srcdir); for ifile in `cd $$d && echo $$file $$file-[0-9] $$file-[0-9][0-9] $$file[0-9] $$file[0-9][0-9]`; do if test -f $$d/$$ifile; then echo " $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile"; $(INSTALL_DATA) $$d/$$ifile $(DESTDIR)$(infodir)/$$ifile; else : ; fi; done; done + @$(POST_INSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then for file in $(INFO_DEPS); do echo " install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file"; install-info --info-dir=$(DESTDIR)$(infodir) $(DESTDIR)$(infodir)/$$file || :; done; else : ; fi + +uninstall-info: + $(PRE_UNINSTALL) + @if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then ii=yes; else ii=; fi; for file in $(INFO_DEPS); do test -z $ii || install-info --info-dir=$(DESTDIR)$(infodir) --remove $$file; done + $(NORMAL_UNINSTALL) + for file in $(INFO_DEPS) make.i; do (cd $(DESTDIR)$(infodir) && rm -f $$file $$file-[0-9] $$file-[0-9][0-9] $$file[0-9] $$file[0-9][0-9]); done + +dist-info: $(INFO_DEPS) + for base in $(INFO_DEPS); do d=$(srcdir); for file in `cd $$d && eval echo $$base*`; do test -f $(distdir)/$$file || ln $$d/$$file $(distdir)/$$file 2> /dev/null || cp -p $$d/$$file $(distdir)/$$file; done; done + +mostlyclean-aminfo: + -rm -f make.aux make.cp make.cps make.dvi make.fn make.fns make.ky \ + make.kys make.ps make.log make.pg make.toc make.tp make.tps \ + make.vr make.vrs make.op make.tr make.cv make.cn + +clean-aminfo: + +distclean-aminfo: + +maintainer-clean-aminfo: + for i in $(INFO_DEPS) make.i; do rm -f `eval echo $$i*`; done + +install-man1: + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done + +uninstall-man1: + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done +install-man: $(MANS) + @$(NORMAL_INSTALL) + $(MAKE) install-man1 +uninstall-man: + @$(NORMAL_UNINSTALL) + $(MAKE) uninstall-man1 + +# Assume that the only thing to do in glob is to build libglob.a, +# but do a sanity check: if $SUBDIRS will ever have more than +# a single directory, yell bloody murder. +all-recursive: +ifeq ($(words $(SUBDIRS)), 1) + @command.com /c if not exist glob\\nul md glob + @echo Making all in $(SUBDIRS) + $(MAKE) -C $(SUBDIRS) -f ../Makefile INCLUDES='-I$(srcdir) -I$(srcdir)/glob' DEFS='-I.. -I$(srcdir)' VPATH=$(srcdir)/glob libglob.a +else + @echo FATAL: There is more than one directory in "($(SUBDIRS))" + @$(EXIT_FAIL) +endif + +$(SUBDIRS): + command.com /c md $@ + +libglob.a: $(libglob_a_OBJECTS) + command.com /c if exist libglob.a del libglob.a + $(AR) cru libglob.a $(libglob_a_OBJECTS) $(libglob_a_LIBADD) + $(RANLIB) libglob.a + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive check-recursive: +ifeq ($(words $(SUBDIRS)), 1) + @echo Making $(shell echo $@ | sed s/-recursive//) in $(SUBDIRS) + $(MAKE) -C $(SUBDIRS) -f ../Makefile $(shell echo $@ | sed s/-recursive//)-am +else + @echo FATAL: There is more than one directory in "($(SUBDIRS))" + @$(EXIT_FAIL) +endif + +tags-in-glob: $(libglob_a_SOURCES) + etags $(addprefix $(srcdir)/,$^) -o ./glob/TAGS + +tags-recursive: +ifeq ($(words $(SUBDIRS)), 1) + $(MAKE) tags-in-glob +else + @echo FATAL: There is more than one directory in "($(SUBDIRS))" + @$(EXIT_FAIL) +endif + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) + mkid $(srcdir)/$(SOURCES) $(srcdir)/$(libglob_a_SOURCES) ./config.h $(HEADERS) + +TAGS: tags-recursive $(HEADERS) $(srcdir)/$(SOURCES) config.h $(TAGS_DEPENDENCIES) + etags -i ./glob/TAGS $(ETAGS_ARGS) $(srcdir)/$(SOURCES) ./config.h $(HEADERS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + rm -rf $(distdir) + GZIP=$(GZIP) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; cd $(distdir)/=build && ../configure --srcdir=.. --prefix=$$dc_install_base && $(MAKE) && $(MAKE) dvi && $(MAKE) check && $(MAKE) install && $(MAKE) installcheck && $(MAKE) dist + rm -rf $(distdir) + @echo "========================"; echo "$(distdir).tar.gz is ready for distribution"; echo "========================" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) + rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP) $(TAR) chozf $(distdir).tar.gz $(distdir) + rm -rf $(distdir) +distdir: $(DISTFILES) + rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do d=$(srcdir); test -f $(distdir)/$$file || ln $$d/$$file $(distdir)/$$file 2> /dev/null || cp -p $$d/$$file $(distdir)/$$file; done; for subdir in $(SUBDIRS); do test -d $(distdir)/$$subdir || mkdir $(distdir)/$$subdir || exit 1; chmod 777 $(distdir)/$$subdir; (cd $$subdir && $(MAKE) top_distdir=../$(top_distdir)/$$subdir distdir=../$(distdir)/$$subdir distdir) || exit 1; done + $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-info + $(MAKE) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook + +info: $(INFO_DEPS) info-recursive +dvi: $(DVIS) dvi-recursive +check: all-am check-recursive check-local + @: +installcheck: installcheck-recursive +all-recursive-am: config.h + $(MAKE) all-recursive + +all-am: Makefile $(INFO_DEPS) $(PROGRAMS) config.h + +install-exec-am: install-binPROGRAMS + +install-data-am: install-info-am + +uninstall-am: uninstall-binPROGRAMS uninstall-info + +install-exec: install-exec-recursive install-exec-am + @$(NORMAL_INSTALL) + +install-data: install-data-recursive install-data-am + @$(NORMAL_INSTALL) + +install-recursive uninstall-recursive: + @: + +install: install-recursive install-exec-am install-data-am + @: + +uninstall: uninstall-recursive uninstall-am + +all: all-recursive-am all-am + +install-strip: + $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install +installdirs: installdirs-recursive + $(mkinstalldirs) $(bindir) $(infodir) + + +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -rm -f Makefile $(DISTCLEANFILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +mostlyclean-am: mostlyclean-hdr mostlyclean-binPROGRAMS mostlyclean-compile mostlyclean-aminfo mostlyclean-tags mostlyclean-generic + +clean-am: clean-hdr clean-binPROGRAMS clean-compile clean-aminfo clean-tags clean-generic mostlyclean-am + +distclean-am: distclean-hdr distclean-binPROGRAMS distclean-compile distclean-aminfo distclean-tags distclean-generic clean-am + +maintainer-clean-am: maintainer-clean-hdr maintainer-clean-binPROGRAMS maintainer-clean-compile maintainer-clean-aminfo maintainer-clean-tags maintainer-clean-generic distclean-am + +mostlyclean: mostlyclean-recursive mostlyclean-am + +clean: clean-noinstLIBRARIES clean-recursive clean-am + +distclean: distclean-recursive distclean-am + rm -f config.status + +maintainer-clean: maintainer-clean-recursive maintainer-clean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f config.status + +.PHONY: default mostlyclean-hdr distclean-hdr clean-hdr \ +maintainer-clean-hdr mostlyclean-binPROGRAMS distclean-binPROGRAMS \ +clean-binPROGRAMS maintainer-clean-binPROGRAMS uninstall-binPROGRAMS \ +install-binPROGRAMS mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile install-info-am uninstall-info \ +mostlyclean-aminfo distclean-aminfo clean-aminfo \ +maintainer-clean-aminfo install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive check-am \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir \ +mostlyclean-depend distclean-depend clean-depend \ +maintainer-clean-depend info dvi check-local installcheck \ +all-recursive-am all-am install-exec-am install-data-am uninstall-am \ +install-exec install-data install uninstall all installdirs \ +mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# --------------- Local DIST Section + +# Install the w32 subdirectory +# +dist-hook: + (cd $(srcdir); \ + w32=`find w32 -follow \( -name CVS -prune \) -o -type f -print`; \ + tar chf - $$w32) \ + | (cd $(distdir); tar xfBp -) + +# --------------- Local CHECK Section + +# Note: check-loadavg is NOT a prerequisite of check-local, since +# there's no uptime utility, and the test it does doesn't make sense +# on MSDOS anyway. +check-local: check-shell check-regression + @banner=" Regression PASSED: GNU Make $(VERSION) ($(MAKE_HOST)) built with $(CC) "; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + echo + +.PHONY: check-loadavg check-shell check-regression + +# > check-shell +# +# check-shell is designed to fail if they don't have a Unixy shell +# installed. The test suite requires such a shell. +check-shell: + @echo If Make says Error -1, you do not have Unix-style shell installed + @foo=bar.exe : + +# > check-loadavg +# +loadavg: loadavg.c config.h + @rm -f loadavg + $(LINK) -DTEST $(make_LDFLAGS) loadavg.c $(LIBS) +# We copy getloadavg.c into a different file rather than compiling it +# directly because some compilers clobber getloadavg.o in the process. +loadavg.c: getloadavg.c + ln $(srcdir)/getloadavg.c loadavg.c || \ + cp $(srcdir)/getloadavg.c loadavg.c +check-loadavg: loadavg + @echo The system uptime program believes the load average to be: + -uptime + @echo The GNU load average checking code believes: + -./loadavg + +# > check-regression +# +# Look for the make test suite, and run it if found. Look in MAKE_TEST if +# specified, or else in the srcdir or the distdir, their parents, and _their_ +# parents. +# +check-regression: + @if test -f "$(srcdir)/tests/run_make_tests"; then \ + if $(PERL) -v >/dev/null 2>&1; then \ + case `cd $(srcdir); pwd` in `pwd`) : ;; \ + *) test -d tests || mkdir tests; \ + for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \ + rm -rf tests/$$f; cp -pr $(srcdir)/tests/$$f tests; \ + done ;; \ + esac; \ + echo "cd tests && $(PERL) ./run_make_tests.pl -make ../make.exe $(MAKETESTFLAGS)"; \ + cd tests && $(PERL) ./run_make_tests.pl -make ../make.exe $(MAKETESTFLAGS); \ + else \ + echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \ + fi; \ + else \ + echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \ + fi + +# --------------- Maintainer's Section + +# Note this requires GNU make. Not to worry, since it will only be included +# in the Makefile if we're in the maintainer's environment. +#include $(srcdir)/maintMakefile + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: + +# --------------- DEPENDENCIES +ar.o: ar.c make.h config.h gettext.h filedef.h dep.h glob/fnmatch.h +arscan.o: arscan.c make.h config.h gettext.h +commands.o: commands.c make.h config.h gettext.h dep.h filedef.h \ + variable.h job.h commands.h +default.o: default.c make.h config.h gettext.h rule.h dep.h filedef.h \ + job.h commands.h variable.h +dir.o: dir.c make.h config.h gettext.h glob/glob.h +expand.o: expand.c make.h config.h gettext.h filedef.h job.h commands.h \ + variable.h rule.h +file.o: file.c make.h config.h gettext.h dep.h filedef.h job.h \ + commands.h variable.h debug.h +function.o: function.c make.h config.h gettext.h filedef.h variable.h \ + dep.h job.h commands.h debug.h +getopt.o: getopt.c config.h gettext.h getopt.h +getopt1.o: getopt1.c config.h getopt.h +implicit.o: implicit.c make.h config.h gettext.h rule.h dep.h filedef.h \ + debug.h +job.o: job.c make.h config.h gettext.h job.h debug.h filedef.h \ + commands.h variable.h +main.o: main.c make.h config.h gettext.h dep.h filedef.h variable.h \ + job.h commands.h rule.h debug.h getopt.h +misc.o: misc.c make.h config.h gettext.h dep.h debug.h +read.o: read.c make.h config.h gettext.h glob/glob.h dep.h filedef.h \ + job.h commands.h variable.h rule.h debug.h +remake.o: remake.c make.h config.h gettext.h filedef.h job.h commands.h \ + dep.h variable.h debug.h +remote-stub.o: remote-stub.c make.h config.h gettext.h filedef.h job.h \ + commands.h +rule.o: rule.c make.h config.h gettext.h dep.h filedef.h job.h \ + commands.h variable.h rule.h +signame.o: signame.c make.h config.h gettext.h +variable.o: variable.c make.h config.h gettext.h dep.h filedef.h job.h \ + commands.h variable.h rule.h +version.o: version.c config.h +vpath.o: vpath.c make.h config.h gettext.h filedef.h variable.h + +# --------------- DEPENDENCIES +# +# dummy +# dummy +ar.o : \ + ar.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h dep.h +arscan.o : \ + arscan.c make.h config.h \ + getopt.h \ + gettext.h \ + +commands.o : \ + commands.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + filedef.h hash.h variable.h job.h commands.h +default.o : \ + default.c make.h config.h \ + getopt.h \ + gettext.h rule.h \ + dep.h filedef.h hash.h job.h commands.h variable.h +dir.o : \ + dir.c make.h config.h \ + getopt.h \ + gettext.h hash.h \ + +expand.o : \ + expand.c make.h config.h \ + getopt.h \ + gettext.h \ + filedef.h hash.h job.h commands.h variable.h \ + rule.h +file.o : \ + file.c make.h config.h \ + getopt.h \ + gettext.h \ + dep.h filedef.h hash.h job.h commands.h \ + variable.h debug.h +function.o : \ + function.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h variable.h dep.h job.h commands.h debug.h +getopt.o : \ + getopt.c config.h \ + +getopt1.o : \ + getopt1.c config.h getopt.h \ + +hash.o : \ + hash.c make.h config.h \ + getopt.h \ + gettext.h hash.h +implicit.o : \ + implicit.c make.h config.h \ + getopt.h \ + gettext.h rule.h \ + dep.h filedef.h hash.h debug.h +job.o : \ + job.c make.h config.h \ + getopt.h \ + gettext.h \ + job.h debug.h filedef.h hash.h commands.h \ + variable.h \ + +loadavg-loadavg.o : \ + loadavg.c config.h \ + make.h \ + getopt.h \ + gettext.h \ + +main.o : \ + main.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + filedef.h hash.h variable.h job.h commands.h rule.h debug.h \ + +misc.o : \ + misc.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + debug.h +read.o : \ + read.c make.h config.h \ + getopt.h \ + gettext.h \ + dep.h filedef.h hash.h \ + job.h commands.h variable.h rule.h debug.h +remake.o : \ + remake.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h job.h commands.h dep.h variable.h debug.h \ + +# dummy +remote-stub.o : \ + remote-stub.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h job.h commands.h +rule.o : \ + rule.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + filedef.h hash.h job.h commands.h variable.h rule.h +signame.o : \ + signame.c make.h config.h \ + getopt.h \ + gettext.h +variable.o : \ + variable.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + filedef.h hash.h job.h commands.h variable.h rule.h +version.o : \ + version.c config.h +vpath.o : \ + vpath.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h variable.h diff --git a/src/make-3.80/Makefile.am b/src/make-3.80/Makefile.am new file mode 100755 index 00000000..33b498b5 --- /dev/null +++ b/src/make-3.80/Makefile.am @@ -0,0 +1,162 @@ +# This is a -*-Makefile-*-, or close enough + +AUTOMAKE_OPTIONS = 1.7 dist-bzip2 check-news +ACLOCAL_AMFLAGS = -I config + +SUBDIRS = glob config po doc + +bin_PROGRAMS = make + +if USE_CUSTOMS + remote = remote-cstms.c +else + remote = remote-stub.c +endif + +make_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \ + function.c getopt.c getopt1.c implicit.c job.c main.c \ + misc.c read.c remake.c $(remote) rule.c signame.c \ + variable.c version.c vpath.c hash.c + +EXTRA_make_SOURCES = remote-stub.c remote-cstms.c + +noinst_HEADERS = commands.h dep.h filedef.h job.h make.h rule.h variable.h \ + debug.h getopt.h gettext.h hash.h + +make_LDADD = @LIBOBJS@ @ALLOCA@ $(GLOBLIB) @GETLOADAVG_LIBS@ @LIBINTL@ + +man_MANS = make.1 + +DEFS = -DLOCALEDIR=\"$(localedir)\" -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\" @DEFS@ + +AM_CPPFLAGS = $(GLOBINC) + + +# Extra stuff to include in the distribution. +# Note we need all the glob stuff here, rather than in glob/Makefile.am, +# because often that directory isn't built on the systems used by the +# maintainers. + +EXTRA_DIST = README build.sh.in $(man_MANS)\ + README.customs\ + SCOPTIONS SMakefile\ + README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h\ + README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\ + README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat\ + readme.vms makefile.vms makefile.com config.h-vms \ + vmsdir.h vmsfunctions.c vmsify.c + +MAKE_HOST = @MAKE_HOST@ + + +# Forward targets + +html: + cd doc && $(MAKE) $(AM_MAKEFLAGS) $@ + +.PHONY: html + +# --------------- Internationalization Section + +localedir = $(datadir)/locale + +# --------------- Local INSTALL Section + +# If necessary, change the gid of the app and turn on the setgid flag. +# + +# Whether or not make needs to be installed setgid. +# The value should be either `true' or `false'. +# On many systems, the getloadavg function (used to implement the `-l' +# switch) will not work unless make is installed setgid kmem. +# +inst_setgid = @NEED_SETGID@ + +# Install make setgid to this group so it can get the load average. +# +inst_group = @KMEM_GROUP@ + +install-exec-local: + @if $(inst_setgid); then \ + app=$(DESTDIR)$(bindir)/`echo $(bin_PROGRAMS)|sed '$(transform)'`; \ + if chgrp $(inst_group) $$app && chmod g+s $$app; then \ + echo "chgrp $(inst_group) $$app && chmod g+s $$app"; \ + else \ + echo "$$app needs to be owned by group $(inst_group) and setgid;"; \ + echo "otherwise the \`-l' option will probably not work."; \ + echo "You may need special privileges to complete the installation"; \ + echo "of $$app."; \ + fi; \ + else true; fi + +# --------------- Local DIST Section + +# Install the w32 and tests subdirectories +# +dist-hook: + (cd $(srcdir); \ + sub=`find w32 tests -follow \( -name CVS -prune -o -name .cvsignore -o -name work -prune \) -o \( -name \*.orig -o -name \*.rej -o -name \*~ -prune \) -o -type f -print`; \ + tar chf - $$sub) \ + | (cd $(distdir); tar xfBp -) + + +# --------------- Local CHECK Section + +check-local: check-regression check-loadavg + @banner=" Regression PASSED: GNU Make $(VERSION) ($(MAKE_HOST)) built with $(CC) "; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + echo + +.PHONY: check-loadavg check-regression + +check-loadavg: loadavg + @echo The system uptime program believes the load average to be: + -uptime + @echo The GNU load average checking code thinks: + -./loadavg + +# The loadavg function is invoked during "make check" to test getloadavg. +noinst_PROGRAMS = loadavg +loadavg_SOURCES = loadavg.c +loadavg_CFLAGS = -DTEST +loadavg_LDADD = @GETLOADAVG_LIBS@ + +loadavg.c: $(srcdir)/getloadavg.c + cp $(srcdir)/getloadavg.c loadavg.c + +# > check-regression +# +# Look for the make test suite, and run it if found and we can find perl. +# If we're building outside the tree, we use symlinks to make a local copy of +# the test suite. Unfortunately the test suite itself isn't localizable yet. +# +MAKETESTFLAGS = + +check-regression: + @if test -f "$(srcdir)/tests/run_make_tests"; then \ + if $(PERL) -v >/dev/null 2>&1; then \ + case `cd $(srcdir); pwd` in `pwd`) : ;; \ + *) test -d tests || mkdir tests; \ + rm -f srctests; \ + if ln -s "$(srcdir)/tests" srctests; then \ + for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \ + rm -f tests/$$f; ln -s ../srctests/$$f tests; \ + done; fi ;; \ + esac; \ + echo "cd tests && $(PERL) ./run_make_tests.pl -make ../make $(MAKETESTFLAGS)"; \ + cd tests && $(PERL) ./run_make_tests.pl -make ../make $(MAKETESTFLAGS); \ + else \ + echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \ + fi; \ + else \ + echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \ + fi + + +# --------------- Maintainer's Section + +@MAINT_MAKEFILE@ diff --git a/src/make-3.80/Makefile.ami b/src/make-3.80/Makefile.ami new file mode 100755 index 00000000..8a71d690 --- /dev/null +++ b/src/make-3.80/Makefile.ami @@ -0,0 +1,305 @@ +# NOTE: If you have no `make' program at all to process this makefile, run +# `build.sh' instead. +# +# Copyright (C) 1988, 89, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. +# This file is part of GNU Make. +# +# GNU Make is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU Make 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Make; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# +# Makefile for GNU Make +# + +CC = sc +RM = delete + +CFLAGS = +CPPFLAGS = +LDFLAGS = + +# Define these for your system as follows: +# -DNO_ARCHIVES To disable `ar' archive support. +# -DNO_FLOAT To avoid using floating-point numbers. +# -DENUM_BITFIELDS If the compiler isn't GCC but groks enum foo:2. +# Some compilers apparently accept this +# without complaint but produce losing code, +# so beware. +# NeXT 1.0a uses an old version of GCC, which required -D__inline=inline. +# See also `config.h'. +defines = + +# Which flavor of remote job execution support to use. +# The code is found in `remote-$(REMOTE).c'. +REMOTE = stub + +# If you are using the GNU C library, or have the GNU getopt functions in +# your C library, you can comment these out. +GETOPT = getopt.o getopt1.o +GETOPT_SRC = $(srcdir)getopt.c $(srcdir)getopt1.c $(srcdir)getopt.h + +# If you are using the GNU C library, or have the GNU glob functions in +# your C library, you can comment this out. GNU make uses special hooks +# into the glob functions to be more efficient (by using make's directory +# cache for globbing), so you must use the GNU functions even if your +# system's C library has the 1003.2 glob functions already. Also, the glob +# functions in the AIX and HPUX C libraries are said to be buggy. +GLOB = glob/glob.lib + +# If your system doesn't have alloca, or the one provided is bad, define this. +ALLOCA = alloca.o +ALLOCA_SRC = $(srcdir)alloca.c + +# If your system needs extra libraries loaded in, define them here. +# System V probably need -lPW for alloca. HP-UX 7.0's alloca in +# libPW.a is broken on HP9000s300 and HP9000s400 machines. Use +# alloca.c instead on those machines. +LOADLIBES = + +# Any extra object files your system needs. +extras = amiga.o + +# Common prefix for machine-independent installed files. +prefix = +# Common prefix for machine-dependent installed files. +exec_prefix = + +# Directory to install `make' in. +bindir = sc:c +# Directory to find libraries in for `-lXXX'. +libdir = lib: +# Directory to search by default for included makefiles. +includedir = include: +# Directory to install the Info files in. +infodir = doc: +# Directory to install the man page in. +mandir = t: +# Number to put on the man page filename. +manext = 1 +# Prefix to put on installed `make' binary file name. +binprefix = +# Prefix to put on installed `make' man page file name. +manprefix = $(binprefix) + +# Whether or not make needs to be installed setgid. +# The value should be either `true' or `false'. +# On many systems, the getloadavg function (used to implement the `-l' +# switch) will not work unless make is installed setgid kmem. +install_setgid = false +# Install make setgid to this group so it can read /dev/kmem. +group = sys + +# Program to install `make'. +INSTALL_PROGRAM = copy +# Program to install the man page. +INSTALL_DATA = copy +# Generic install program. +INSTALL = copy + +# Program to format Texinfo source into Info files. +MAKEINFO = makeinfo +# Program to format Texinfo source into DVI files. +TEXI2DVI = texi2dvi + +# Programs to make tags files. +ETAGS = etags -w +CTAGS = ctags -w + +objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \ + rule.o implicit.o default.o variable.o expand.o function.o \ + vpath.o version.o ar.o arscan.o signame.o remote-$(REMOTE).o \ + $(GETOPT) $(ALLOCA) $(extras) +srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \ + $(srcdir)file.c $(srcdir)getloadavg.c $(srcdir)misc.c \ + $(srcdir)main.c $(srcdir)read.c $(srcdir)remake.c \ + $(srcdir)rule.c $(srcdir)implicit.c $(srcdir)default.c \ + $(srcdir)variable.c $(srcdir)expand.c $(srcdir)function.c \ + $(srcdir)vpath.c $(srcdir)version.c \ + $(srcdir)remote-$(REMOTE).c \ + $(srcdir)ar.c $(srcdir)arscan.c \ + $(srcdir)signame.c $(srcdir)signame.h $(GETOPT_SRC) \ + $(srcdir)commands.h $(srcdir)dep.h $(srcdir)filedep.h \ + $(srcdir)job.h $(srcdir)make.h $(srcdir)rule.h \ + $(srcdir)variable.h $(ALLOCA_SRC) $(srcdir)config.h.in + + +.SUFFIXES: +.SUFFIXES: .o .c .h .ps .dvi .info .texinfo + +all: make +info: make.info +dvi: make.dvi +# Some makes apparently use .PHONY as the default goal if it is before `all'. +.PHONY: all check info dvi + +make.info: make.texinfo + $(MAKEINFO) -I$(srcdir) $(srcdir)make.texinfo -o make.info + +make.dvi: make.texinfo + $(TEXI2DVI) $(srcdir)make.texinfo + +make.ps: make.dvi + dvi2ps make.dvi > make.ps + +make: $(objs) $(GLOB) + $(CC) Link $(LDFLAGS) $(objs) Lib $(GLOB) $(LOADLIBES) To make.new + -delete make + rename make.new make + +TMPFILE = t:Make$$ + +$(GLOB): + cd glob @@\ + $(MAKE) -$(MAKEFLAGS) -f Makefile + +# -I. is needed to find config.h in the build directory. +OUTPUT_OPTION = +.c.o: + $(CC) $(defines) IDir "" IDir glob \ + $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) + +# For some losing Unix makes. +SHELL = /bin/sh +#@SET_MAKE@ + +glob/libglob.a: FORCE config.h + cd glob; $(MAKE) libglob.a +FORCE: + +tagsrcs = $(srcs) $(srcdir)remote-*.c + +.PHONY: install installdirs +install: installdirs \ + $(bindir)$(binprefix)make $(infodir)make.info \ + $(mandir)$(manprefix)make.$(manext) + +installdirs: + $(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir) $(mandir) + +$(bindir)$(binprefix)make: make + $(INSTALL_PROGRAM) make $@.new + @if $(install_setgid); then \ + if chgrp $(group) $@.new && chmod g+s $@.new; then \ + echo "chgrp $(group) $@.new && chmod g+s $@.new"; \ + else \ + echo "$@ needs to be owned by group $(group) and setgid;"; \ + echo "otherwise the \`-l' option will probably not work."; \ + echo "You may need special privileges to install $@."; \ + fi; \ + else true; fi +# Some systems can't deal with renaming onto a running binary. + -$(RM) $@.old + -mv $@ $@.old + mv $@.new $@ + +$(infodir)make.info: make.info + if [ -r ./make.info ]; then dir=.; else dir=$(srcdir); fi; \ + for file in $${dir}/make.info*; do \ + name="`basename $$file`"; \ + $(INSTALL_DATA) $$file \ + `echo $@ | sed "s,make.info\$$,$$name,"`; \ + done +# Run install-info only if it exists. +# Use `if' instead of just prepending `-' to the +# line so we notice real errors from install-info. +# We use `$(SHELL) -c' because some shells do not +# fail gracefully when there is an unknown command. + if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \ + if [ -r ./make.info ]; then dir=.; else dir=$(srcdir); fi; \ + install-info --infodir=$(infodir) $$dir/make.info; \ + else true; fi + +$(mandir)$(manprefix)make.$(manext): make.man + $(INSTALL_DATA) $(srcdir)make.man $@ + + +loadavg: loadavg.c config.h + $(CC) $(defines) -DTEST -I. -I$(srcdir) $(CFLAGS) $(LDFLAGS) \ + loadavg.c $(LOADLIBES) -o $@ +# We copy getloadavg.c into a different file rather than compiling it +# directly because some compilers clobber getloadavg.o in the process. +loadavg.c: getloadavg.c + ln $(srcdir)getloadavg.c loadavg.c || \ + cp $(srcdir)getloadavg.c loadavg.c +check-loadavg: loadavg + @echo The system uptime program believes the load average to be: + -uptime + @echo The GNU load average checking code believes: + ./loadavg +check: check-loadavg + + +.PHONY: clean realclean distclean mostlyclean +clean: glob-clean + -$(RM) make loadavg "#?.o" core make.dvi + +distclean: clean glob-realclean + -$(RM) Makefile config.h config.status build.sh + -$(RM) config.log config.cache + -$(RM) TAGS tags + -$(RM) make.?? make.??s make.log make.toc make.*aux + -$(RM) loadavg.c + +realclean: distclean + -$(RM) make.info* +mostlyclean: clean + +.PHONY: glob-clean glob-realclean +glob-clean glob-realclean: + cd glob @@\ + $(MAKE) $@ + +# This tells versions [3.59,3.63) of GNU make not to export all variables. +.NOEXPORT: + +# The automatically generated dependencies below may omit config.h +# because it is included with ``#include '' rather than +# ``#include "config.h"''. So we add the explicit dependency to make sure. +$(objs): config.h + +# Automatically generated dependencies will be put at the end of the file. + +# Automatically generated dependencies. +commands.o: commands.c make.h dep.h filedef.h variable.h job.h \ + commands.h +job.o: job.c make.h job.h filedef.h commands.h variable.h +dir.o: dir.c make.h +file.o: file.c make.h dep.h filedef.h job.h commands.h variable.h +misc.o: misc.c make.h dep.h +main.o: main.c make.h dep.h filedef.h variable.h job.h commands.h \ + getopt.h +read.o: read.c make.h dep.h filedef.h job.h commands.h variable.h \ + glob/glob.h +remake.o: remake.c make.h filedef.h job.h commands.h dep.h +rule.o: rule.c make.h dep.h filedef.h job.h commands.h variable.h \ + rule.h +implicit.o: implicit.c make.h rule.h dep.h filedef.h +default.o: default.c make.h rule.h dep.h filedef.h job.h commands.h \ + variable.h +variable.o: variable.c make.h dep.h filedef.h job.h commands.h \ + variable.h +expand.o: expand.c make.h filedef.h job.h commands.h variable.h +function.o: function.c make.h filedef.h variable.h dep.h job.h \ + commands.h amiga.h +vpath.o: vpath.c make.h filedef.h variable.h +version.o: version.c +ar.o: ar.c make.h filedef.h dep.h +arscan.o: arscan.c make.h +signame.o: signame.c signame.h +remote-stub.o: remote-stub.c make.h filedef.h job.h commands.h +getopt.o: getopt.c +getopt1.o : getopt1.c getopt.h +getloadavg.o: getloadavg.c +amiga.o: amiga.c make.h variable.h amiga.h diff --git a/src/make-3.80/Makefile.in b/src/make-3.80/Makefile.in new file mode 100755 index 00000000..29b4ab50 --- /dev/null +++ b/src/make-3.80/Makefile.in @@ -0,0 +1,925 @@ +# Makefile.in generated by automake 1.7 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# This is a -*-Makefile-*-, or close enough + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ + +DEFS = -DLOCALEDIR=\"$(localedir)\" -DLIBDIR=\"$(libdir)\" -DINCLUDEDIR=\"$(includedir)\" @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ +GLOBINC = @GLOBINC@ +GLOBLIB = @GLOBLIB@ +GMSGFMT = @GMSGFMT@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +KMEM_GROUP = @KMEM_GROUP@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBS = @LIBS@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ + +MAKE_HOST = @MAKE_HOST@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +NEED_SETGID = @NEED_SETGID@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_CUSTOMS_FALSE = @USE_CUSTOMS_FALSE@ +USE_CUSTOMS_TRUE = @USE_CUSTOMS_TRUE@ +USE_LOCAL_GLOB_FALSE = @USE_LOCAL_GLOB_FALSE@ +USE_LOCAL_GLOB_TRUE = @USE_LOCAL_GLOB_TRUE@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ + +AUTOMAKE_OPTIONS = 1.7 dist-bzip2 check-news +ACLOCAL_AMFLAGS = -I config + +SUBDIRS = glob config po doc + +bin_PROGRAMS = make + +@USE_CUSTOMS_TRUE@remote = remote-cstms.c +@USE_CUSTOMS_FALSE@remote = remote-stub.c + +make_SOURCES = ar.c arscan.c commands.c default.c dir.c expand.c file.c \ + function.c getopt.c getopt1.c implicit.c job.c main.c \ + misc.c read.c remake.c $(remote) rule.c signame.c \ + variable.c version.c vpath.c hash.c + + +EXTRA_make_SOURCES = remote-stub.c remote-cstms.c + +noinst_HEADERS = commands.h dep.h filedef.h job.h make.h rule.h variable.h \ + debug.h getopt.h gettext.h hash.h + + +make_LDADD = @LIBOBJS@ @ALLOCA@ $(GLOBLIB) @GETLOADAVG_LIBS@ @LIBINTL@ + +man_MANS = make.1 + +AM_CPPFLAGS = $(GLOBINC) + + +# Extra stuff to include in the distribution. +# Note we need all the glob stuff here, rather than in glob/Makefile.am, +# because often that directory isn't built on the systems used by the +# maintainers. +EXTRA_DIST = README build.sh.in $(man_MANS)\ + README.customs\ + SCOPTIONS SMakefile\ + README.Amiga Makefile.ami config.ami make.lnk amiga.c amiga.h\ + README.DOS Makefile.DOS configure.bat dosbuild.bat configh.dos\ + README.W32 NMakefile config.h.W32 build_w32.bat subproc.bat\ + readme.vms makefile.vms makefile.com config.h-vms \ + vmsdir.h vmsfunctions.c vmsify.c + + + +# --------------- Internationalization Section +localedir = $(datadir)/locale + +# --------------- Local INSTALL Section + +# If necessary, change the gid of the app and turn on the setgid flag. +# + +# Whether or not make needs to be installed setgid. +# The value should be either `true' or `false'. +# On many systems, the getloadavg function (used to implement the `-l' +# switch) will not work unless make is installed setgid kmem. +# +inst_setgid = @NEED_SETGID@ + +# Install make setgid to this group so it can get the load average. +# +inst_group = @KMEM_GROUP@ + +# The loadavg function is invoked during "make check" to test getloadavg. +noinst_PROGRAMS = loadavg +loadavg_SOURCES = loadavg.c +loadavg_CFLAGS = -DTEST +loadavg_LDADD = @GETLOADAVG_LIBS@ + +# > check-regression +# +# Look for the make test suite, and run it if found and we can find perl. +# If we're building outside the tree, we use symlinks to make a local copy of +# the test suite. Unfortunately the test suite itself isn't localizable yet. +# +MAKETESTFLAGS = +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = build.sh +bin_PROGRAMS = make$(EXEEXT) +noinst_PROGRAMS = loadavg$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) + +am_loadavg_OBJECTS = loadavg-loadavg.$(OBJEXT) +loadavg_OBJECTS = $(am_loadavg_OBJECTS) +loadavg_DEPENDENCIES = +loadavg_LDFLAGS = +@USE_CUSTOMS_TRUE@am__objects_1 = remote-cstms.$(OBJEXT) +@USE_CUSTOMS_FALSE@am__objects_1 = remote-stub.$(OBJEXT) +am_make_OBJECTS = ar.$(OBJEXT) arscan.$(OBJEXT) commands.$(OBJEXT) \ + default.$(OBJEXT) dir.$(OBJEXT) expand.$(OBJEXT) file.$(OBJEXT) \ + function.$(OBJEXT) getopt.$(OBJEXT) getopt1.$(OBJEXT) \ + implicit.$(OBJEXT) job.$(OBJEXT) main.$(OBJEXT) misc.$(OBJEXT) \ + read.$(OBJEXT) remake.$(OBJEXT) $(am__objects_1) rule.$(OBJEXT) \ + signame.$(OBJEXT) variable.$(OBJEXT) version.$(OBJEXT) \ + vpath.$(OBJEXT) hash.$(OBJEXT) +make_OBJECTS = $(am_make_OBJECTS) +make_DEPENDENCIES = @LIBOBJS@ @ALLOCA@ +make_LDFLAGS = + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I. +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/alloca.Po $(DEPDIR)/getloadavg.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ar.Po ./$(DEPDIR)/arscan.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/commands.Po ./$(DEPDIR)/default.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/dir.Po ./$(DEPDIR)/expand.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/file.Po ./$(DEPDIR)/function.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/getopt.Po ./$(DEPDIR)/getopt1.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/hash.Po ./$(DEPDIR)/implicit.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/job.Po ./$(DEPDIR)/loadavg-loadavg.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/misc.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/read.Po ./$(DEPDIR)/remake.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/remote-cstms.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/remote-stub.Po ./$(DEPDIR)/rule.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/signame.Po ./$(DEPDIR)/variable.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/version.Po ./$(DEPDIR)/vpath.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(loadavg_SOURCES) $(make_SOURCES) $(EXTRA_make_SOURCES) + +NROFF = nroff +MANS = $(man_MANS) +HEADERS = $(noinst_HEADERS) + + +RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \ + ps-recursive install-info-recursive uninstall-info-recursive \ + all-recursive install-data-recursive install-exec-recursive \ + installdirs-recursive install-recursive uninstall-recursive \ + check-recursive installcheck-recursive +DIST_COMMON = README $(noinst_HEADERS) ABOUT-NLS AUTHORS COPYING \ + ChangeLog INSTALL Makefile.am Makefile.in NEWS acinclude.m4 \ + aclocal.m4 alloca.c build.sh.in config.h.in configure \ + configure.in getloadavg.c +DIST_SUBDIRS = $(SUBDIRS) +SOURCES = $(loadavg_SOURCES) $(make_SOURCES) $(EXTRA_make_SOURCES) + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .o .obj + +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe) + +$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +$(ACLOCAL_M4): configure.in acinclude.m4 config/codeset.m4 config/gettext.m4 config/glibc21.m4 config/iconv.m4 config/intdiv0.m4 config/inttypes-pri.m4 config/inttypes.m4 config/inttypes_h.m4 config/isc-posix.m4 config/lcmessage.m4 config/lib-ld.m4 config/lib-link.m4 config/lib-prefix.m4 config/progtest.m4 config/stdint_h.m4 config/uintmax_t.m4 config/ulonglong.m4 + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h + +$(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOHEADER) + touch $(srcdir)/config.h.in + +distclean-hdr: + -rm -f config.h stamp-h1 +build.sh: $(top_builddir)/config.status build.sh.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \ + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f $(DESTDIR)$(bindir)/$$f"; \ + rm -f $(DESTDIR)$(bindir)/$$f; \ + done + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +loadavg-loadavg.$(OBJEXT): loadavg.c +loadavg$(EXEEXT): $(loadavg_OBJECTS) $(loadavg_DEPENDENCIES) + @rm -f loadavg$(EXEEXT) + $(LINK) $(loadavg_LDFLAGS) $(loadavg_OBJECTS) $(loadavg_LDADD) $(LIBS) +make$(EXEEXT): $(make_OBJECTS) $(make_DEPENDENCIES) + @rm -f make$(EXEEXT) + $(LINK) $(make_LDFLAGS) $(make_OBJECTS) $(make_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/alloca.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getloadavg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ar.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arscan.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commands.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/default.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expand.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/function.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/implicit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/job.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loadavg-loadavg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remake.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remote-cstms.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remote-stub.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rule.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signame.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/variable.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vpath.Po@am__quote@ + +distclean-depend: + -rm -rf $(DEPDIR) ./$(DEPDIR) + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'` + +loadavg-loadavg.o: loadavg.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(loadavg_CFLAGS) $(CFLAGS) -MT loadavg-loadavg.o -MD -MP -MF "$(DEPDIR)/loadavg-loadavg.Tpo" \ +@am__fastdepCC_TRUE@ -c -o loadavg-loadavg.o `test -f 'loadavg.c' || echo '$(srcdir)/'`loadavg.c; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/loadavg-loadavg.Tpo" "$(DEPDIR)/loadavg-loadavg.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/loadavg-loadavg.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loadavg.c' object='loadavg-loadavg.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/loadavg-loadavg.Po' tmpdepfile='$(DEPDIR)/loadavg-loadavg.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(loadavg_CFLAGS) $(CFLAGS) -c -o loadavg-loadavg.o `test -f 'loadavg.c' || echo '$(srcdir)/'`loadavg.c + +loadavg-loadavg.obj: loadavg.c +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(loadavg_CFLAGS) $(CFLAGS) -MT loadavg-loadavg.obj -MD -MP -MF "$(DEPDIR)/loadavg-loadavg.Tpo" \ +@am__fastdepCC_TRUE@ -c -o loadavg-loadavg.obj `if test -f 'loadavg.c'; then $(CYGPATH_W) 'loadavg.c'; else $(CYGPATH_W) '$(srcdir)/loadavg.c'`; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/loadavg-loadavg.Tpo" "$(DEPDIR)/loadavg-loadavg.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/loadavg-loadavg.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='loadavg.c' object='loadavg-loadavg.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/loadavg-loadavg.Po' tmpdepfile='$(DEPDIR)/loadavg-loadavg.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(loadavg_CFLAGS) $(CFLAGS) -c -o loadavg-loadavg.obj `if test -f 'loadavg.c'; then $(CYGPATH_W) 'loadavg.c'; else $(CYGPATH_W) '$(srcdir)/loadavg.c'` +uninstall-info-am: + +man1dir = $(mandir)/man1 +install-man1: $(man1_MANS) $(man_MANS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(man1dir) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + case "$$ext" in \ + 1*) ;; \ + *) ext='1' ;; \ + esac; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \ + done +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ + l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ + for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed -e 's/^.*\///'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \ + rm -f $(DESTDIR)$(man1dir)/$$inst; \ + done + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $$MAKEFLAGS; amf=$$2; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = . +distdir = $(PACKAGE)-$(VERSION) + +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } + +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print + +distdir: $(DISTFILES) + @case `sed 15q $(srcdir)/NEWS` in \ + *"$(VERSION)"*) : ;; \ + *) \ + echo "NEWS not updated; not releasing" 1>&2; \ + exit 1;; \ + esac + $(am__remove_distdir) + mkdir $(distdir) + $(mkinstalldirs) $(distdir)/. $(distdir)/po + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + (cd $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" \ + distdir=../$(distdir)/$$subdir \ + distdir) \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist dist-all: distdir + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + $(am__remove_distdir) + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/=inst && pwd` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && $(mkinstalldirs) $$dc_destdir \ + && cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + --with-included-gettext \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \ + && rm -f $(distdir).tar.gz \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @echo "$(distdir).tar.gz is ready for distribution" | \ + sed 'h;s/./=/g;p;x;p;x' +distuninstallcheck: + cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-local +check: check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS) config.h +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(man1dir) + +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +info: info-recursive + +info-am: + +install-data-am: install-man + +install-exec-am: install-binPROGRAMS install-exec-local + +install-info: install-info-recursive + +install-man: install-man1 + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf autom4te.cache +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am uninstall-man + +uninstall-info: uninstall-info-recursive + +uninstall-man: uninstall-man1 + +.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \ + check-local clean clean-binPROGRAMS clean-generic \ + clean-noinstPROGRAMS clean-recursive ctags ctags-recursive dist \ + dist-all dist-bzip2 dist-gzip distcheck distclean \ + distclean-compile distclean-depend distclean-generic \ + distclean-hdr distclean-recursive distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am dvi-recursive info \ + info-am info-recursive install install-am install-binPROGRAMS \ + install-data install-data-am install-data-recursive \ + install-exec install-exec-am install-exec-local \ + install-exec-recursive install-info install-info-am \ + install-info-recursive install-man install-man1 \ + install-recursive install-strip installcheck installcheck-am \ + installdirs installdirs-am installdirs-recursive \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-recursive mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-recursive pdf pdf-am \ + pdf-recursive ps ps-am ps-recursive tags tags-recursive \ + uninstall uninstall-am uninstall-binPROGRAMS uninstall-info-am \ + uninstall-info-recursive uninstall-man uninstall-man1 \ + uninstall-recursive + + +# Forward targets + +html: + cd doc && $(MAKE) $(AM_MAKEFLAGS) $@ + +.PHONY: html + +install-exec-local: + @if $(inst_setgid); then \ + app=$(DESTDIR)$(bindir)/`echo $(bin_PROGRAMS)|sed '$(transform)'`; \ + if chgrp $(inst_group) $$app && chmod g+s $$app; then \ + echo "chgrp $(inst_group) $$app && chmod g+s $$app"; \ + else \ + echo "$$app needs to be owned by group $(inst_group) and setgid;"; \ + echo "otherwise the \`-l' option will probably not work."; \ + echo "You may need special privileges to complete the installation"; \ + echo "of $$app."; \ + fi; \ + else true; fi + +# --------------- Local DIST Section + +# Install the w32 and tests subdirectories +# +dist-hook: + (cd $(srcdir); \ + sub=`find w32 tests -follow \( -name CVS -prune -o -name .cvsignore -o -name work -prune \) -o \( -name \*.orig -o -name \*.rej -o -name \*~ -prune \) -o -type f -print`; \ + tar chf - $$sub) \ + | (cd $(distdir); tar xfBp -) + +# --------------- Local CHECK Section + +check-local: check-regression check-loadavg + @banner=" Regression PASSED: GNU Make $(VERSION) ($(MAKE_HOST)) built with $(CC) "; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + echo + +.PHONY: check-loadavg check-regression + +check-loadavg: loadavg + @echo The system uptime program believes the load average to be: + -uptime + @echo The GNU load average checking code thinks: + -./loadavg + +loadavg.c: $(srcdir)/getloadavg.c + cp $(srcdir)/getloadavg.c loadavg.c + +check-regression: + @if test -f "$(srcdir)/tests/run_make_tests"; then \ + if $(PERL) -v >/dev/null 2>&1; then \ + case `cd $(srcdir); pwd` in `pwd`) : ;; \ + *) test -d tests || mkdir tests; \ + rm -f srctests; \ + if ln -s "$(srcdir)/tests" srctests; then \ + for f in run_make_tests run_make_tests.pl test_driver.pl scripts; do \ + rm -f tests/$$f; ln -s ../srctests/$$f tests; \ + done; fi ;; \ + esac; \ + echo "cd tests && $(PERL) ./run_make_tests.pl -make ../make $(MAKETESTFLAGS)"; \ + cd tests && $(PERL) ./run_make_tests.pl -make ../make $(MAKETESTFLAGS); \ + else \ + echo "Can't find a working Perl ($(PERL)); the test suite requires Perl."; \ + fi; \ + else \ + echo "Can't find the GNU Make test suite ($(srcdir)/tests)."; \ + fi + +# --------------- Maintainer's Section + +@MAINT_MAKEFILE@ +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/make-3.80/NEWS b/src/make-3.80/NEWS new file mode 100755 index 00000000..8a200f58 --- /dev/null +++ b/src/make-3.80/NEWS @@ -0,0 +1,859 @@ +GNU make NEWS -*-indented-text-*- + History of user-visible changes. + 03 October 2002 + +Copyright (C) 2002 Free Software Foundation, Inc. +See the end for copying conditions. + +All changes mentioned here are more fully described in the GNU make +manual, which is contained in this distribution as the file make.texinfo. + +Please send GNU make bug reports to . +See the README file and the GNU make manual for details on sending bug +reports. + +Version 3.80 + +* A new feature exists: order-only prerequisites. These prerequisites + affect the order in which targets are built, but they do not impact + the rebuild/no-rebuild decision of their dependents. That is to say, + they allow you to require target B be built before target A, without + requiring that target A will always be rebuilt if target B is updated. + Patch for this feature provided by Greg McGary . + +* For compatibility with SysV make, GNU make now supports the peculiar + syntax $$@, $$(@D), and $$(@F) in the prerequisites list of a rule. + This syntax is only valid within explicit and static pattern rules: it + cannot be used in implicit (suffix or pattern) rules. Edouard G. Parmelan + provided a patch implementing this feature; however, I + decided to implement it in a different way. + +* The argument to the "ifdef" conditional is now expanded before it's + tested, so it can be a constructed variable name. + + Similarly, the arguments to "export" (when not used in a variable + definition context) and "unexport" are also now expanded. + +* A new function is defined: $(value ...). The argument to this + function is the _name_ of a variable. The result of the function is + the value of the variable, without having been expanded. + +* A new function is defined: $(eval ...). The arguments to this + function should expand to makefile commands, which will then be + evaluated as if they had appeared in the makefile. In combination + with define/endef multiline variable definitions this is an extremely + powerful capability. The $(value ...) function is also sometimes + useful here. + +* A new built-in variable is defined, $(MAKEFILE_LIST). It contains a + list of each makefile GNU make has read, or started to read, in the + order in which they were encountered. So, the last filename in the + list when a makefile is just being read (before any includes) is the + name of the current makefile. + +* A new built-in variable is defined: $(.VARIABLES). When it is + expanded it returns a complete list of variable names defined by all + makefiles at that moment. + +* A new command-line option is defined, -B or --always-make. If + specified GNU make will consider all targets out-of-date even if they + would otherwise not be. + +* The arguments to $(call ...) functions were being stored in $1, $2, + etc. as recursive variables, even though they are fully expanded + before assignment. This means that escaped dollar signs ($$ etc.) + were not behaving properly. Now the arguments are stored as simple + variables. This may mean that if you added extra escaping to your + $(call ...) function arguments you will need to undo it now. + +* The variable invoked by $(call ...) can now be recursive: unlike other + variables it can reference itself and this will not produce an error + when it is used as the first argument to $(call ...) (but only then). + +* New pseudo-target .LOW_RESOLUTION_TIME, superseding the configure + option --disable-nsec-timestamps. You might need this if your build + process depends on tools like "cp -p" preserving time stamps, since + "cp -p" (right now) doesn't preserve the subsecond portion of a time + stamp. + +* Updated translations for French, Galician, German, Japanese, Korean, + and Russian. New translations for Croatian, Danish, Hebrew, and + Turkish. + +* Updated internationalization support to Gettext 0.11.5. + GNU make now uses Gettext's "external" feature, and does not include + any internationalization code itself. Configure will search your + system for an existing implementation of GNU Gettext (only GNU Gettext + is acceptable) and use it if it exists. If not, NLS will be disabled. + See ABOUT-NLS for more information. + +* Updated to autoconf 2.54 and automake 1.7. Users should not be impacted. + +Version 3.79.1 + +* .SECONDARY with no prerequisites now prevents any target from being + removed because make thinks it's an intermediate file, not just those + listed in the makefile. + +* New configure option --disable-nsec-timestamps, but this was + superseded in later versions by the .LOW_RESOLUTION_TIME pseudo-target. + +Version 3.79 + +* GNU make optionally supports internationalization and locales via the + GNU gettext (or local gettext if suitable) package. See the ABOUT-NLS + file for more information on configuring GNU make for NLS. + +* Previously, GNU make quoted variables such as MAKEFLAGS and + MAKEOVERRIDES for proper parsing by the shell. This allowed them to + be used within make build scripts. However, using them there is not + proper behavior: they are meant to be passed to subshells via the + environment. Unfortunately the values were not quoted properly to be + passed through the environment. This meant that make didn't properly + pass some types of command line values to submakes. + + With this version we change that behavior: now these variables are + quoted properly for passing through the environment, which is the + correct way to do it. If you previously used these variables + explicitly within a make rule you may need to re-examine your use for + correctness given this change. + +* A new pseudo-target .NOTPARALLEL is available. If defined, the + current makefile is run serially regardless of the value of -j. + However, submakes are still eligible for parallel execution. + +* The --debug option has changed: it now allows optional flags + controlling the amount and type of debugging output. By default only + a minimal amount information is generated, displaying the names of + "normal" targets (not makefiles) that were deemed out of date and in + need of being rebuilt. + + Note that the -d option behaves as before: it takes no arguments and + all debugging information is generated. + +* The `-p' (print database) output now includes filename and linenumber + information for variable definitions, to aid debugging. + +* The wordlist function no longer reverses its arguments if the "start" + value is greater than the "end" value. If that's true, nothing is + returned. + +* Hartmut Becker provided many updates for the VMS port of GNU make. + See the readme.vms file for more details. + +Version 3.78 + +* Two new functions, $(error ...) and $(warning ...) are available. The + former will cause make to fail and exit immediately upon expansion of + the function, with the text provided as the error message. The latter + causes the text provided to be printed as a warning message, but make + proceeds normally. + +* A new function $(call ...) is available. This allows users to create + their own parameterized macros and invoke them later. Original + implementation of this function was provided by Han-Wen Nienhuys + . + +* A new function $(if ...) is available. It provides if-then-else + capabilities in a builtin function. Original implementation of this + function was provided by Han-Wen Nienhuys . + +* Make defines a new variable, .LIBPATTERNS. This variable controls how + library dependency expansion (dependencies like ``-lfoo'') is performed. + +* Make accepts CRLF sequences as well as traditional LF, for + compatibility with makefiles created on other operating systems. + +* Make accepts a new option: -R, or --no-builtin-variables. This option + disables the definition of the rule-specific builtin variables (CC, + LD, AR, etc.). Specifying this option forces -r (--no-builtin-rules) + as well. + +* A "job server" feature, suggested by Howard Chu . + + On systems that support POSIX pipe(2) semantics, GNU make can now pass + -jN options to submakes rather than forcing them all to use -j1. The + top make and all its sub-make processes use a pipe to communicate with + each other to ensure that no more than N jobs are started across all + makes. To get the old behavior of -j back, you can configure make + with the --disable-job-server option. + +* The confusing term "dependency" has been replaced by the more accurate + and standard term "prerequisite", both in the manual and in all GNU make + output. + +* GNU make supports the "big archive" library format introduced in AIX 4.3. + +* GNU make supports large files on AIX, HP-UX, and IRIX. These changes + were provided by Paul Eggert . (Large file + support for Solaris and Linux was introduced in 3.77, but the + configuration had issues: these have also been resolved). + +* The Windows 95/98/NT (W32) version of GNU make now has native support + for the Cygnus Cygwin release B20.1 shell (bash). + +* The GNU make regression test suite, long available separately "under + the table", has been integrated into the release. You can invoke it + by running "make check" in the distribution. Note that it requires + Perl (either Perl 4 or Perl 5) to run. + +Version 3.77 + +* Implement BSD make's "?=" variable assignment operator. The variable + is assigned the specified value only if that variable is not already + defined. + +* Make defines a new variable, "CURDIR", to contain the current working + directory (after the -C option, if any, has been processed). + Modifying this variable has no effect on the operation of make. + +* Make defines a new default RCS rule, for new-style master file + storage: ``% :: RCS/%'' (note no ``,v'' suffix). + + Make defines new default rules for DOS-style C++ file naming + conventions, with ``.cpp'' suffixes. All the same rules as for + ``.cc'' and ``.C'' suffixes are provided, along with LINK.cpp and + COMPILE.cpp macros (which default to the same value as LINK.cc and + COMPILE.cc). Note CPPFLAGS is still C preprocessor flags! You should + use CXXFLAGS to change C++ compiler flags. + +* A new feature, "target-specific variable values", has been added. + This is a large change so please see the appropriate sections of the + manual for full details. Briefly, syntax like this: + + TARGET: VARIABLE = VALUE + + defines VARIABLE as VALUE within the context of TARGET. This is + similar to SunOS make's "TARGET := VARIABLE = VALUE" feature. Note + that the assignment may be of any type, not just recursive, and that + the override keyword is available. + + COMPATIBILITY: This new syntax means that if you have any rules where + the first or second dependency has an equal sign (=) in its name, + you'll have to escape them with a backslash: "foo : bar\=baz". + Further, if you have any dependencies which already contain "\=", + you'll have to escape both of them: "foo : bar\\\=baz". + +* A new appendix listing the most common error and warning messages + generated by GNU make, with some explanation, has been added to the + GNU make User's Manual. + +* Updates to the GNU make Customs library support (see README.customs). + +* Updates to the Windows 95/NT port from Rob Tulloh (see README.W32), + and to the DOS port from Eli Zaretski (see README.DOS). + +Version 3.76.1 + +* Small (but serious) bug fix. Quick rollout to get into the GNU source CD. + +Version 3.76 + +* GNU make now uses automake to control Makefile.in generation. This + should make it more consistent with the GNU standards. + +* VPATH functionality has been changed to incorporate the VPATH+ patch, + previously maintained by Paul Smith . See the + manual. + +* Make defines a new variable, `MAKECMDGOALS', to contain the goals that + were specified on the command line, if any. Modifying this variable + has no effect on the operation of make. + +* A new function, `$(wordlist S,E,TEXT)', is available: it returns a + list of words from number S to number E (inclusive) of TEXT. + +* Instead of an error, detection of future modification times gives a + warning and continues. The warning is repeated just before GNU make + exits, so it is less likely to be lost. + +* Fix the $(basename) and $(suffix) functions so they only operate on + the last filename, not the entire string: + + Command Old Result New Result + ------- ---------- ---------- + $(basename a.b) a a + $(basename a.b/c) a a.b/c + $(suffix a.b) b b + $(suffix a.b/c) b/c + +* The $(strip) function now removes newlines as well as TABs and spaces. + +* The $(shell) function now changes CRLF (\r\n) pairs to a space as well + as newlines (\n). + +* Updates to the Windows 95/NT port from Rob Tulloh (see README.W32). + +* Eli Zaretskii has updated the port to 32-bit protected mode on MSDOS + and MS-Windows, building with the DJGPP v2 port of GNU C/C++ compiler + and utilities. See README.DOS for details, and direct all questions + concerning this port to Eli Zaretskii or DJ + Delorie . + +* John W. Eaton has updated the VMS port to support libraries and VPATH. + +Version 3.75 + +* The directory messages printed by `-w' and implicitly in sub-makes, + are now omitted if Make runs no commands and has no other messages to print. + +* Make now detects files that for whatever reason have modification times + in the future and gives an error. Files with such impossible timestamps + can result from unsynchronized clocks, or archived distributions + containing bogus timestamps; they confuse Make's dependency engine + thoroughly. + +* The new directive `sinclude' is now recognized as another name for + `-include', for compatibility with some other Makes. + +* Aaron Digulla has contributed a port to AmigaDOS. See README.Amiga for + details, and direct all Amiga-related questions to . + +* Rob Tulloh of Tivoli Systems has contributed a port to Windows NT or 95. + See README.W32 for details, and direct all Windows-related questions to + . + +Version 3.73 + +* Converted to use Autoconf version 2, so `configure' has some new options. + See INSTALL for details. + +* You can now send a SIGUSR1 signal to Make to toggle printing of debugging + output enabled by -d, at any time during the run. + +Version 3.72 + +* DJ Delorie has ported Make to MS-DOS using the GO32 extender. + He is maintaining the DOS port, not the GNU Make maintainer; + please direct bugs and questions for DOS to . + MS-DOS binaries are available for FTP from ftp.simtel.net in + /pub/simtelnet/gnu/djgpp/. + +* The `MAKEFLAGS' variable (in the environment or in a makefile) can now + contain variable definitions itself; these are treated just like + command-line variable definitions. Make will automatically insert any + variable definitions from the environment value of `MAKEFLAGS' or from + the command line, into the `MAKEFLAGS' value exported to children. The + `MAKEOVERRIDES' variable previously included in the value of `$(MAKE)' + for sub-makes is now included in `MAKEFLAGS' instead. As before, you can + reset `MAKEOVERRIDES' in your makefile to avoid putting all the variables + in the environment when its size is limited. + +* If `.DELETE_ON_ERROR' appears as a target, Make will delete the target of + a rule if it has changed when its commands exit with a nonzero status, + just as when the commands get a signal. + +* The automatic variable `$+' is new. It lists all the dependencies like + `$^', but preserves duplicates listed in the makefile. This is useful + for linking rules, where library files sometimes need to be listed twice + in the link order. + +* You can now specify the `.IGNORE' and `.SILENT' special targets with + dependencies to limit their effects to those files. If a file appears as + a dependency of `.IGNORE', then errors will be ignored while running the + commands to update that file. Likewise if a file appears as a dependency + of `.SILENT', then the commands to update that file will not be printed + before they are run. (This change was made to conform to POSIX.2.) + +Version 3.71 + +* The automatic variables `$(@D)', `$(%D)', `$(*D)', `$(. Please see the +section of the GNU make manual entitled `Problems and Bugs' for +information on submitting useful and complete bug reports. + +You can also use the online bug tracking system in the Savannah GNU Make +project to submit new problem reports or search for existing ones: + + http://savannah.gnu.org/bugs/?group_id=71 + +If you need help using GNU make, try these forums: + + help-make@gnu.org + help-utils@gnu.org + news:gnu.utils.help + news:gnu.utils.bug + + http://savannah.gnu.org/support/?group_id=71 + +You may also find interesting patches to GNU Make available here: + + http://savannah.gnu.org/patch/?group_id=71 + +Note these patches are provided by our users as a service and we make no +statements regarding their correctness. Please contact the authors +directly if you have a problem or suggestion for a patch available on +this page. + + +CVS Access +---------- + +The GNU make source repository is available via anonymous CVS from the +GNU Subversions CVS server; look here for details: + + http://savannah.gnu.org/cvs/?group_id=71 + +Please note: you won't be able to build GNU make from CVS without +installing appropriate maintainer's tools, such as GNU m4, automake, +autoconf, Perl, GNU make, and GCC. See the README.cvs file for hints on +how to build GNU make once these tools are available. We make no +guarantees about the contents or quality of the latest code in the CVS +repository: it is not unheard of for code that is known to be broken to +be checked in. Use at your own risk. + + +System-specific Notes +--------------------- + +It has been reported that the XLC 1.2 compiler on AIX 3.2 is buggy such +that if you compile make with `cc -O' on AIX 3.2, it will not work correctly. +It is said that using `cc' without `-O' does work. + +One area that is often a problem in configuration and porting is the code +to check the system's current load average. To make it easier to test and +debug this code, you can do `make check-loadavg' to see if it works +properly on your system. (You must run `configure' beforehand, but you +need not build Make itself to run this test.) + +Another potential source of porting problems is the support for large +files (LFS) in configure for those operating systems that provide it. +Please report any bugs that you find in this area. If you run into +difficulties, then as a workaround you should be able to disable LFS by +adding the `--disable-largefile' option to the `configure' script. + +On systems that support micro- and nano-second timestamp values and +where stat(2) provides this information, GNU make will use it when +comparing timestamps to get the most accurate possible result. However, +note that many current implementations of tools that *set* timestamps do +not preserve micro- or nano-second granularity. This means that "cp -p" +and other similar tools (tar, etc.) may not exactly duplicate timestamps +with micro- and nano-second granularity on some systems. If your build +system contains rules that depend on proper behavior of tools like "cp +-p", you should consider using the .LOW_RESOLUTION_TIME pseudo-target to +force make to treat them properly. See the manual for details. + + +Ports +----- + + - See README.customs for details on integrating GNU make with the + Customs distributed build environment from the Pmake distribution. + + - See readme.vms for details about GNU Make on OpenVMS. + + - See README.Amiga for details about GNU Make on AmigaDOS. + + - See README.W32 for details about GNU Make on Windows NT, 95, or 98. + + - See README.DOS for compilation instructions on MS-DOS and MS-Windows + using DJGPP tools. + + A precompiled binary of the MSDOS port of GNU Make is available as part + of DJGPP; see the WWW page http://www.delorie.com/djgpp/ for more + information. + +Please note there are two _separate_ ports of GNU make for Microsoft +systems: a native Windows tool built with (for example) MSVC or Cygwin, +and a DOS-based tool built with DJGPP. Please be sure you are looking +at the right README! diff --git a/src/make-3.80/README.Amiga b/src/make-3.80/README.Amiga new file mode 100755 index 00000000..6f08dd81 --- /dev/null +++ b/src/make-3.80/README.Amiga @@ -0,0 +1,61 @@ +Short: Port of GNU make with SAS/C (no ixemul.library required) +Author: GNU, Amiga port by Aaron "Optimizer" Digulla +Uploader: Aaron "Optimizer" Digulla (digulla@fh-konstanz.de) +Type: dev/c + +This is a pure Amiga port of GNU make. It needs no extra libraries or +anything. It has the following features (in addition to any features of +GNU make): + +- Runs Amiga-Commands with SystemTags() (Execute) +- Can run multi-line statements +- Allows to use Device-Names in targets: + + c:make : make.o + + is ok. To distinguish between device-names and target : or ::, MAKE + looks for spaces. If there are any around :, it's taken as a target + delimiter, if there are none, it's taken as the name of a device. Note + that "make:make.o" tries to create "make.o" on the device "make:". +- Replaces @@ by a newline in any command line: + + if exists make @@\ + delete make.bak quiet @@\ + rename make make.bak @@\ + endif @@\ + $(CC) Link Make.o To make + + works. Note that the @@ must stand alone (ie. "make@@\" is illegal). + Also be carefull that there is a space after the "\" (ie, at the + beginning of the next line). +- Can be made resident to save space and time +- Amiga specific wildcards can be used in $(wildcard ...) + +BUGS: +- The line + + dummy.h : src/*.c + +tries to make dummy.h from "src/*.c" (ie. no wildcard-expansion takes +place). You have to use "$(wildcard src/*.c)" instead. + +COMPILING FROM SCRATCH +---------------------- + +To recompile, you need SAS/C 6.51. make itself is not neccessary, there +is an smakefile. + +1. Copy config.ami to config.h +2. If you use make to compie, copy Makefile.ami to Makefile and + glob/Makefile.ami to glob/Makefile. Copy make into the current + directory. + +3. Run smake/make + +INSTALLATION + +Copy make somewhere in your search path (eg. sc:c or sc:bin). +If you plan to use recursive makes, install make resident: + + Resident make Add + diff --git a/src/make-3.80/README.DOS b/src/make-3.80/README.DOS new file mode 100755 index 00000000..b41ecede --- /dev/null +++ b/src/make-3.80/README.DOS @@ -0,0 +1,323 @@ +Port of GNU Make to 32-bit protected mode on MSDOS and MS-Windows. + +Builds with DJGPP v2 port of GNU C/C++ compiler and utilities. + + +New (since 3.74) DOS-specific features: + + 1. Supports long filenames when run from DOS box on Windows 9x. + + 2. Supports both stock DOS COMMAND.COM and Unix-style shells + (details in ``Notes'' below). + + 3. Supports DOS drive letters in dependencies and pattern rules. + + 4. Better support for DOS-style backslashes in pathnames (but see + ``Notes'' below). + + 5. The $(shell) built-in can run arbitrary complex commands, + including pipes and redirection, even when COMMAND.COM is your + shell. + + 6. Can be built without floating-point code (see below). + + 7. Supports signals in child programs and restores the original + directory if the child was interrupted. + + 8. Can be built without (a previous version of) Make. + + 9. The build process requires only standard tools. (Optional + targets like "install:" and "clean:" still need additional + programs, though, see below.) + + 10. Beginning with v3.78, the test suite works in the DJGPP + environment (requires Perl and auxiliary tools; see below). + + +To install a binary distribution: + + Simply unzip the makNNNb.zip file (where NNN is the version number) + preserving the directory structure (-d switch if you use PKUNZIP). + If you are installing Make on Windows 9X or Windows 2000, use an + unzip program that supports long filenames in zip files. After + unzipping, make sure the directory with make.exe is on your PATH, + and that's all you need to use Make. + + +To build from sources: + + 1. Unzip the archive, preserving the directory structure (-d switch + if you use PKUNZIP). If you build Make on Windows 9X or Windows + 2000, use an unzip program that supports long filenames in zip + files. + + If you are unpacking an official GNU source distribution, use + either DJTAR (which is part of the DJGPP development + environment), or the DJGPP port of GNU Tar. + + 2. Invoke the `configure.bat' batch file. + + If you are building Make in-place, i.e. in the same directory + where its sources are kept, just type "configure.bat" and press + [Enter]. Otherwise, you need to supply the path to the source + directory as an argument to the batch file, like this: + + c:\djgpp\gnu\make-3.80\configure.bat c:/djgpp/gnu/make-3.80 + + Note the forward slashes in the source path argument: you MUST + use them here. + + 3. If configure.bat doesn't find a working Make, it will suggest to + use the `dosbuild.bat' batch file to build Make. Either do as it + suggests or install another Make program (a pre-compiled binary + should be available from the usual DJGPP sites) and rerun + configure.bat. + + 4. If you will need to run Make on machines without an FPU, you + might consider building a version of Make which doesn't issue + floating-point instructions (they don't help much on MSDOS + anyway). To this end, edit the Makefile created by + configure.bat and add -DNO_FLOAT to the value of CPPFLAGS. + + 5. Invoke Make. + + If you are building from outside of the source directory, you + need to tell Make where the sources are, like this: + + make srcdir=c:/djgpp/gnu/make-3.80 + + (configure.bat will tell you this when it finishes). You MUST + use a full, not relative, name of the source directory here, or + else Make might fail. + + 6. After Make finishes, if you have a Unix-style shell installed, + you can use the `install' target to install the package. You + will also need GNU Fileutils and GNU Sed for this (they should + be available from the DJGPP sites). + + By default, GNU make will install into your DJGPP installation + area. If you wish to use a different directory, override the + DESTDIR variable when invoking "make install", like this: + + make install DESTDIR=c:/other/dir + + This causes the make executable to be placed in c:/other/dir/bin, + the man pages in c:/other/dir/man, etc. + + Without a Unix-style shell, you will have to install programs + and the docs manually. Copy make.exe to a directory on your + PATH, make.i* info files to your Info directory, and update the + file `dir' in your Info directory by adding the following item + to the main menu: + + * Make: (make.info). The GNU make utility. + + If you have the `install-info' program (from the GNU Texinfo + package), it will do that for you if you invoke it like this: + + install-info --info-dir=c:/djgpp/info c:/djgpp/info/make.info + + (If your Info directory is other than C:\DJGPP\INFO, change this + command accordingly.) + + 7. The `clean' targets also require Unix-style shell, and GNU Sed + and `rm' programs (the latter from Fileutils). + + 8. To run the test suite, type "make check". This requires a Unix + shell (I used the DJGPP port of Bash 2.03), Perl, Sed, Fileutils + and Sh-utils. + + +Notes: +----- + + 1. The shell issue. + + This is probably the most significant improvement, first + introduced in the port of GNU Make 3.75. + + The original behavior of GNU Make is to invoke commands + directly, as long as they don't include characters special to + the shell or internal shell commands, because that is faster. + When shell features like redirection or filename wildcards are + involved, Make calls the shell. + + This port supports both DOS shells (the stock COMMAND.COM and its + 4DOS/NDOS replacements), and Unix-style shells (tested with the + venerable Stewartson's `ms_sh' 2.3 and the DJGPP port of `bash' by + Daisuke Aoyama ). + + When the $SHELL variable points to a Unix-style shell, Make + works just like you'd expect on Unix, calling the shell for any + command that involves characters special to the shell or + internal shell commands. The only difference is that, since + there is no standard way to pass command lines longer than the + infamous DOS 126-character limit, this port of Make writes the + command line to a temporary disk file and then invokes the shell + on that file. + + If $SHELL points to a DOS-style shell, however, Make will not + call it automatically, as it does with Unix shells. Stock + COMMAND.COM is too dumb and would unnecessarily limit the + functionality of Make. For example, you would not be able to + use long command lines in commands that use redirection or + pipes. Therefore, when presented with a DOS shell, this port of + Make will emulate most of the shell functionality, like + redirection and pipes, and shall only call the shell when a + batch file or a command internal to the shell is invoked. (Even + when a command is an internal shell command, Make will first + search the $PATH for it, so that if a Makefile calls `mkdir', + you can install, say, a port of GNU `mkdir' and have it called + in that case.) + + The key to all this is the extended functionality of `spawn' and + `system' functions from the DJGPP library; this port just calls + `system' where it would invoke the shell on Unix. The most + important aspect of these functions is that they use a special + mechanism to pass long (up to 16KB) command lines to DJGPP + programs. In addition, `system' emulates some internal + commands, like `cd' (so that you can now use forward slashes + with it, and can also change the drive if the directory is on + another drive). Another aspect worth mentioning is that you can + call Unix shell scripts directly, provided that the shell whose + name is mentioned on the first line of the script is installed + anywhere along the $PATH. It is impossible to tell here + everything about these functions; refer to the DJGPP library + reference for more details. + + The $(shell) built-in is implemented in this port by calling + `popen'. Since `popen' calls `system', the above considerations + are valid for $(shell) as well. In particular, you can put + arbitrary complex commands, including pipes and redirection, + inside $(shell), which is in many cases a valid substitute for + the Unix-style command substitution (`command`) feature. + + + 2. "SHELL=/bin/sh" -- or is it? + + Many Unix Makefiles include a line which sets the SHELL, for + those versions of Make which don't have this as the default. + Since many DOS systems don't have `sh' installed (in fact, most + of them don't even have a `/bin' directory), this port takes + such directives with a grain of salt. It will only honor such a + directive if the basename of the shell name (like `sh' in the + above example) can indeed be found in the directory that is + mentioned in the SHELL= line (`/bin' in the above example), or + in the current working directory, or anywhere on the $PATH (in + that order). If the basename doesn't include a filename + extension, Make will look for any known extension that indicates + an executable file (.exe, .com, .bat, .btm, .sh, and even .sed + and .pl). If any such file is found, then $SHELL will be + defined to the exact pathname of that file, and that shell will + hence be used for the rest of processing. But if the named + shell is *not* found, the line which sets it will be effectively + ignored, leaving the value of $SHELL as it was before. Since a + lot of decisions that this port makes depend on the gender of + the shell, I feel it doesn't make any sense to tailor Make's + behavior to a shell which is nowhere to be found. + + Note that the above special handling of "SHELL=" only happens + for Makefiles; if you set $SHELL in the environment or on the + Make command line, you are expected to give the complete + pathname of the shell, including the filename extension. + + The default value of $SHELL is computed as on Unix (see the Make + manual for details), except that if $SHELL is not defined in the + environment, $COMSPEC is used. Also, if an environment variable + named $MAKESHELL is defined, it takes precedence over both + $COMSPEC and $SHELL. Note that, unlike Unix, $SHELL in the + environment *is* used to set the shell (since on MSDOS, it's + unlikely that the interactive shell will not be suitable for + Makefile processing). + + The bottom line is that you can now write Makefiles where some + of the targets require a real (i.e. Unix-like) shell, which will + nevertheless work when such shell is not available (provided, of + course, that the commands which should always work, don't + require such a shell). More important, you can convert Unix + Makefiles to MSDOS and leave the line which sets the shell + intact, so that people who do have Unixy shell could use it for + targets which aren't converted to DOS (like `install' and + `uninstall', for example). + + + 3. Default directories. + + GNU Make knows about standard directories where it searches for + library and include files mentioned in the Makefile. Since + MSDOS machines don't have standard places for these, this port + will search ${DJDIR}/lib and ${DJDIR}/include respectively. + $DJDIR is defined automatically by the DJGPP startup code as the + root of the DJGPP installation tree (unless you've tampered with + the DJGPP.ENV file). This should provide reasonable default + values, unless you moved parts of DJGPP to other directories. + + + 4. Letter-case in filenames. + + If you run Make on Windows 9x, you should be aware of the + letter-case issue. Make is internally case-sensitive, but all + file operations are case-insensitive on Windows 9x, so + e.g. files `FAQ', `faq' and `Faq' all refer to the same file, as + far as Windows is concerned. The underlying DJGPP C library + functions honor the letter-case of the filenames they get from + the OS, except that by default, they down-case 8+3 DOS filenames + which are stored in upper case in the directory and would break + many Makefiles otherwise. (The details of which filenames are + converted to lower case are explained in the DJGPP libc docs, + under the `_preserve_fncase' and `_lfn_gen_short_fname' + functions, but as a thumb rule, any filename that is stored in + upper case in the directory, is a valid DOS 8+3 filename and + doesn't include characters invalid on MSDOS FAT filesystems, + will be automatically down-cased.) User reports that I have + indicate that this default behavior is generally what you'd + expect; however, your input is most welcome. + + In any case, if you hit a situation where you must force Make to + get the 8+3 DOS filenames in upper case, set FNCASE=y in the + environment or in the Makefile. + + + 5. DOS-style pathnames. + + There are a lot of places throughout the program sources which + make implicit assumptions about the pathname syntax. In + particular, the directories are assumed to be separated by `/', + and any pathname which doesn't begin with a `/' is assumed to be + relative to the current directory. This port attempts to + support DOS-style pathnames which might include the drive letter + and use backslashes instead of forward slashes. However, this + support is not complete; I feel that pursuing this support too + far might break some more important features, particularly if + you use a Unix-style shell (where a backslash is a quote + character). I only consider support of backslashes desirable + because some Makefiles invoke non-DJGPP programs which don't + understand forward slashes. A notable example of such programs + is the standard programs which come with MSDOS. Otherwise, you + are advised to stay away from backslashes whenever possible. In + particular, filename globbing won't work on pathnames with + backslashes, because the GNU `glob' library doesn't support them + (backslash is special in filename wildcards, and I didn't want + to break that). + + One feature which *does* work with backslashes is the filename- + related built-in functions such as $(dir), $(notdir), etc. + Drive letters in pathnames are also fully supported. + + + +Bug reports: +----------- + + Bugs that are clearly related to the MSDOS/DJGPP port should be + reported first on the comp.os.msdos.djgpp news group (if you cannot + post to Usenet groups, write to the DJGPP mailing list, + , which is an email gateway into the above news + group). For other bugs, please follow the procedure explained in + the "Bugs" chapter of the Info docs. If you don't have an Info + reader, look up that chapter in the `make.i1' file with any text + browser/editor. + + + Enjoy, + Eli Zaretskii diff --git a/src/make-3.80/README.W32 b/src/make-3.80/README.W32 new file mode 100755 index 00000000..e605c0b4 --- /dev/null +++ b/src/make-3.80/README.W32 @@ -0,0 +1,241 @@ +Port of GNU make to Windows NT and Windows 95 +Builds natively with MSVC 2.x or MSVC 4.x compilers. +Should also build fine with MSVC 5.x and 6.x (though not confirmed). + +This Windows 32-bit port of GNU make is maintained primarily by Rob +Tulloh, who is also the author of this README. + +To build with nmake on Windows NT, Windows 95, or Windows 98: + + 1. Make sure cl.exe is in your %Path%. Example: + + set Path=%Path%;c:/msdev/bin + + 2. Make sure %include% is set to msvc include directory. Example: + + set include=c:/msdev/include + + 3. Make sure %lib% is set to msvc lib directory. Example: + + set lib=c:/msdev/lib + + 4. nmake /f NMakefile + + + A short cut to steps 1, 2, and 3 is to run VCVARS32.bat before + invoking namke. For example: + + c: + cd \msdev\bin + VCVARS32.bat + cd \path\to\make-3.80 + nmake /f NMakefile + +There is a bat file (build_w32.bat) for folks who have fear of nmake. + +Outputs: + + WinDebug/make.exe + WinRel/make.exe + + +-- Notes/Caveats -- + +GNU make on Windows 32-bit platforms: + + This version of make is ported natively to Windows32 platforms + (Windows NT 3.51, Windows NT 4.0, Windows 95, and Windows 98). It + does not rely on any 3rd party software or add-on packages for + building. The only thing needed is a version of Visual C++, + which is the predominant compiler used on Windows32 platforms. + + Do not confuse this port of GNU make with other Windows32 projects + which provide a GNU make binary. These are separate projects + and are not connected to this port effort. + +GNU make and sh.exe: + + This port prefers you have a working sh.exe somewhere on your + system. If you don't have sh.exe, the port falls back to + MSDOS mode for launching programs (via a batch file). + The MSDOS mode style execution has not been tested that + carefully though (The author uses GNU bash as sh.exe). + + There are very few true ports of Bourne shell for NT right now. + There is a version of GNU bash available from Cygnus "Cygwin" + porting effort (http://sourceware.cygnus.com/cygwin). + Other possibilities are the MKS version of sh.exe, or building + your own with a package like NutCracker (DataFocus) or Portage + (Consensys). + +GNU make and brain-dead shells (BATCH_MODE_ONLY_SHELL): + + Some versions of Bourne shell does not behave well when invoked + as 'sh -c' from CreateProcess(). The main problem is they seem + to have a hard time handling quoted strings correctly. This can + be circumvented by writing commands to be executed to a batch + file and then executing the command by calling 'sh file'. + + To work around this difficulty, this version of make supports + a batch mode. When BATCH_MODE_ONLY_SHELL is defined at compile + time, make forces all command lines to be executed via script + files instead of by command line. + + A native Windows32 system with no Bourne shell will also run + in batch mode. All command lines will be put into batch files + and executed via $(COMSPEC) (%COMSPEC%). + +GNU make and Cygnus GNU Windows32 tools: + + Good news! Make now has native support for Cygwin sh. To enable, + define the HAVE_CYGWIN_SHELL in config.h and rebuild make + from scratch. This version of make tested with B20.1 of Cygwin. + Do not define BATCH_MODE_ONLY_SHELL if you use HAVE_CYGWIN_SHELL. + +GNU make and the MKS shell: + + There is now semi-official support for the MKS shell. To turn this + support on, define HAVE_MKS_SHELL in the config.h.W32 before you + build make. Do not define BATCH_MODE_ONLY_SHELL if you turn + on HAVE_MKS_SHELL. + +GNU make handling of drive letters in pathnames (PATH, vpath, VPATH): + + There is a caveat that should be noted with respect to handling + single character pathnames on Windows systems. When colon is + used in PATH variables, make tries to be smart about knowing when + you are using colon as a separator versus colon as a drive + letter. Unfortunately, something as simple as the string 'x:/' + could be interpreted 2 ways: (x and /) or (x:/). + + Make chooses to interpret a letter plus colon (e.g. x:/) as a + drive letter pathname. If it is necessary to use single + character directories in paths (VPATH, vpath, Path, PATH), the + user must do one of two things: + + a. Use semicolon as the separator to disambiguate colon. For + example use 'x;/' if you want to say 'x' and '/' are + separate components. + + b. Qualify the directory name so that there is more than + one character in the path(s) used. For example, none + of these settings are ambiguous: + + ./x:./y + /some/path/x:/some/path/y + x:/some/path/x:x:/some/path/y + + Please note that you are free to mix colon and semi-colon in the + specification of paths. Make is able to figure out the intended + result and convert the paths internally to the format needed + when interacting with the operating system. + + You are encouraged to use colon as the separator character. + This should ease the pain of deciding how to handle various path + problems which exist between platforms. If colon is used on + both Unix and Windows systems, then no ifdef'ing will be + necessary in the makefile source. + +GNU make test suite: + + I verified all functionality with a slightly modified version + of make-test-3.80 (modifications to get test suite to run + on Windows NT). All tests pass in an environment that includes + sh.exe. Tests were performed on both Windows NT and Windows 95. + +Building GNU make on Windows NT and Windows 95/98 with Microsoft Visual C: + + I did not provide a Visual C project file with this port as + the project file would not be considered freely distributable + (or so I think). It is easy enough to create one, though, if + you know how to use Visual C. + + I build the program statically to avoid problems locating DLL's + on machines that may not have MSVC runtime installed. If you + prefer, you can change make to build with shared libraries by + changing /MT to /MD in the NMakefile (or in build_w32.bat). + + The program has not been built for non-Intel architectures (yet). + + I have not tried to build with any other compilers than MSVC. I + have heard that this is possible though so don't be afraid to + notify me of your successes! + +Pathnames and white space: + + Unlike Unix, Windows 95/NT systems encourage pathnames which + contain white space (e.g. C:\Program Files\). These sorts of pathnames + are legal under Unix too, but are never encouraged. There is + at least one place in make (VPATH/vpath handling) where paths + containing white space will simply not work. There may be others + too. I chose to not try and port make in such a way so that + these sorts of paths could be handled. I offer these suggestions + as workarounds: + + 1. Use 8.3 notation + 2. Rename the directory so it does not contain white space. + + If you are unhappy with this choice, this is free software + and you are free to take a crack at making this work. The code + in w32/pathstuff.c and vpath.c would be the places to start. + +Pathnames and Case insensitivity: + + Unlike Unix, Windows 95/NT systems are case insensitive but case + preserving. For example if you tell the file system to create a + file named "Target", it will preserve the case. Subsequent access to + the file with other case permutations will succeed (i.e. opening a + file named "target" or "TARGET" will open the file "Target"). + + By default, GNU make retains its case sensitivity when comparing + target names and existing files or directories. It can be + configured, however, into a case preserving and case insensitive + mode by adding a define for HAVE_CASE_INSENSITIVE_FS to + config.h.W32. + + For example, the following makefile will create a file named + Target in the directory subdir which will subsequently be used + to satisfy the dependency of SUBDIR/DepTarget on SubDir/TARGET. + Without HAVE_CASE_INSENSITIVE_FS configured, the dependency link + will not be made: + + subdir/Target: + touch $@ + + SUBDIR/DepTarget: SubDir/TARGET + cp $^ $@ + + Reliance on this behavior also eliminates the ability of GNU make + to use case in comparison of matching rules. For example, it is + not possible to set up a C++ rule using %.C that is different + than a C rule using %.c. GNU make will consider these to be the + same rule and will issue a warning. + +SAMBA/NTFS/VFAT: + + I have not had any success building the debug version of this + package using SAMBA as my file server. The reason seems to be + related to the way VC++ 4.0 changes the case name of the pdb + filename it is passed on the command line. It seems to change + the name always to to lower case. I contend that + the VC++ compiler should not change the casename of files that + are passed as arguments on the command line. I don't think this + was a problem in MSVC 2.x, but I know it is a problem in MSVC 4.x. + + The package builds fine on VFAT and NTFS filesystems. + + Most all of the development I have done to date has been using + NTFS and long file names. I have not done any considerable work + under VFAT. VFAT users may wish to be aware that this port + of make does respect case sensitivity. + +FAT: + + Version 3.76 added support for FAT filesystems. Make + works around some difficulties with stat'ing of + files and caching of filenames and directories internally. + +Bug reports: + + Please submit bugs via the normal bug reporting mechanism which + is described in the GNU make manual and the base README. diff --git a/src/make-3.80/README.customs b/src/make-3.80/README.customs new file mode 100755 index 00000000..1976943e --- /dev/null +++ b/src/make-3.80/README.customs @@ -0,0 +1,95 @@ + -*-indented-text-*- + +GNU make can utilize the Customs library, distributed with Pmake, to +provide builds distributed across multiple hosts. + +In order to utilize this capability, you must first download and build +the Customs library. It is contained in the Pmake distribution, which +can be obtained at: + + ftp://ftp.icsi.berkeley.edu/pub/ai/stolcke/software/ + +This integration was tested (superficially) with Pmake 2.1.33. + + +BUILDING CUSTOMS +---------------- + +First, build pmake and Customs. You need to build pmake first, because +Customs require pmake to build. Unfortunately, this is not trivial; +please see the pmake and Customs documentation for details. The best +place to look for instructions is in the pmake-2.1.33/INSTALL file. + +Note that the 2.1.33 Pmake distribution comes with a set of patches to +GNU make, distributed in the pmake-2.1.33/etc/gnumake/ directory. These +patches are based on GNU make 3.75 (there are patches for earlier +versions of GNU make, also). The parts of this patchfile which relate +directly to Customs support have already been incorporated into this +version of GNU make, so you should _NOT_ apply the patch file. + +However, there are a few non-Customs specific (as far as I could tell) +changes here which are not incorporated (for example, the modification +to try expanding -lfoo to libfoo.so). If you rely on these changes +you'll need to re-apply them by hand. + +Install the Customs library and header files according to the +documentation. You should also install the man pages (contrary to +comments in the documentation, they weren't installed automatically for +me; I had to cd to the ``pmake-2.1.33/doc'' directory and run ``pmake +install'' there directly). + + +BUILDING GNU MAKE +----------------- + +Once you've installed Customs, you can build GNU make to use it. When +configuring GNU make, merely use the ``--with-customs=DIR'' option. +Provide the directory containing the ``lib'' and ``include/customs'' +subdirectories as DIR. For example, if you installed the customs +library in /usr/local/lib and the headers in /usr/local/include/customs, +then you'd pass ``--with-customs=/usr/local'' as an option to configure. + +Run make (or use build.sh) normally to build GNU make as described in +the INSTALL file. + +See the documentation for Customs for information on starting and +configuring Customs. + + +INVOKING CUSTOMS-IZED GNU MAKE +----------------------------- + +One thing you should be aware of is that the default build environment +for Customs requires root permissions. Practically, this means that GNU +make must be installed setuid root to use Customs. + +If you don't want to do this, you can build Customs such that root +permissions are not necessary. Andreas Stolcke +writes: + + > pmake, gnumake or any other customs client program is not required to + > be suid root if customs was compiled WITHOUT the USE_RESERVED_PORTS + > option in customs/config.h. Make sure the "customs" service in + > /etc/services is defined accordingly (port 8231 instead of 1001). + + > Not using USE_RESERVED_PORTS means that a user with programming + > skills could impersonate another user by writing a fake customs + > client that pretends to be someone other than himself. See the + > discussion in etc/SECURITY. + + +PROBLEMS +-------- + +SunOS 4.1.x: + The customs/sprite.h header file #includes the header + files; this conflicts with GNU make's configuration so you'll get a + compile error if you use GCC (or any other ANSI-capable C compiler). + + I commented out the #include in sprite.h:107: + + #if defined(sun) || defined(ultrix) || defined(hpux) || defined(sgi) + /* #include */ + #else + + YMMV. diff --git a/src/make-3.80/SCOPTIONS b/src/make-3.80/SCOPTIONS new file mode 100755 index 00000000..f89daae1 --- /dev/null +++ b/src/make-3.80/SCOPTIONS @@ -0,0 +1,13 @@ +ERRORREXX +OPTIMIZE +NOVERSION +OPTIMIZERTIME +OPTIMIZERALIAS +DEFINE INCLUDEDIR="include:" +DEFINE LIBDIR="lib:" +DEFINE NO_ALLOCA +DEFINE NO_FLOAT +DEFINE NO_ARCHIVES +IGNORE=161 +IGNORE=100 +STARTUP=cres diff --git a/src/make-3.80/SMakefile b/src/make-3.80/SMakefile new file mode 100755 index 00000000..ea4c5037 --- /dev/null +++ b/src/make-3.80/SMakefile @@ -0,0 +1,338 @@ +# NOTE: If you have no `make' program at all to process this makefile, run +# `build.sh' instead. +# +# Copyright (C) 1988, 89, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. +# This file is part of GNU Make. +# +# GNU Make is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU Make 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Make; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# +# Makefile for GNU Make +# + +# Ultrix 2.2 make doesn't expand the value of VPATH. +VPATH = /make-3.80/ +# This must repeat the value, because configure will remove `VPATH = .'. +srcdir = /make-3.80/ + +CC = sc +RM = delete +MAKE = smake + +CFLAGS = +CPPFLAGS = +LDFLAGS = + +# Define these for your system as follows: +# -DNO_ARCHIVES To disable `ar' archive support. +# -DNO_FLOAT To avoid using floating-point numbers. +# -DENUM_BITFIELDS If the compiler isn't GCC but groks enum foo:2. +# Some compilers apparently accept this +# without complaint but produce losing code, +# so beware. +# NeXT 1.0a uses an old version of GCC, which required -D__inline=inline. +# See also `config.h'. +defines = + +# Which flavor of remote job execution support to use. +# The code is found in `remote-$(REMOTE).c'. +REMOTE = stub + +# If you are using the GNU C library, or have the GNU getopt functions in +# your C library, you can comment these out. +GETOPT = getopt.o getopt1.o +GETOPT_SRC = $(srcdir)getopt.c $(srcdir)getopt1.c $(srcdir)getopt.h + +# If you are using the GNU C library, or have the GNU glob functions in +# your C library, you can comment this out. GNU make uses special hooks +# into the glob functions to be more efficient (by using make's directory +# cache for globbing), so you must use the GNU functions even if your +# system's C library has the 1003.2 glob functions already. Also, the glob +# functions in the AIX and HPUX C libraries are said to be buggy. +GLOB = Lib glob/glob.lib + +# If your system doesn't have alloca, or the one provided is bad, define this. +ALLOCA = alloca.o +ALLOCA_SRC = $(srcdir)alloca.c + +# If your system needs extra libraries loaded in, define them here. +# System V probably need -lPW for alloca. HP-UX 7.0's alloca in +# libPW.a is broken on HP9000s300 and HP9000s400 machines. Use +# alloca.c instead on those machines. +LOADLIBES = + +# Any extra object files your system needs. +extras = amiga.o + +# Common prefix for machine-independent installed files. +prefix = +# Common prefix for machine-dependent installed files. +exec_prefix = + +# Directory to install `make' in. +bindir = sc:c +# Directory to find libraries in for `-lXXX'. +libdir = lib: +# Directory to search by default for included makefiles. +includedir = include: +# Directory to install the Info files in. +infodir = doc: +# Directory to install the man page in. +mandir = t: +# Number to put on the man page filename. +manext = 1 +# Prefix to put on installed `make' binary file name. +binprefix = +# Prefix to put on installed `make' man page file name. +manprefix = $(binprefix) + +# Whether or not make needs to be installed setgid. +# The value should be either `true' or `false'. +# On many systems, the getloadavg function (used to implement the `-l' +# switch) will not work unless make is installed setgid kmem. +install_setgid = false +# Install make setgid to this group so it can read /dev/kmem. +group = sys + +# Program to install `make'. +INSTALL_PROGRAM = copy +# Program to install the man page. +INSTALL_DATA = copy +# Generic install program. +INSTALL = copy + +# Program to format Texinfo source into Info files. +MAKEINFO = makeinfo +# Program to format Texinfo source into DVI files. +TEXI2DVI = texi2dvi + +# Programs to make tags files. +ETAGS = etags -w +CTAGS = ctags -w + +objs = commands.o job.o dir.o file.o misc.o main.o read.o remake.o \ + rule.o implicit.o default.o variable.o expand.o function.o \ + vpath.o version.o ar.o arscan.o signame.o remote-$(REMOTE).o \ + $(GLOB) $(GETOPT) $(ALLOCA) $(extras) +srcs = $(srcdir)commands.c $(srcdir)job.c $(srcdir)dir.c \ + $(srcdir)file.c $(srcdir)getloadavg.c $(srcdir)misc.c \ + $(srcdir)main.c $(srcdir)read.c $(srcdir)remake.c \ + $(srcdir)rule.c $(srcdir)implicit.c $(srcdir)default.c \ + $(srcdir)variable.c $(srcdir)expand.c $(srcdir)function.c \ + $(srcdir)vpath.c $(srcdir)version.c \ + $(srcdir)remote-$(REMOTE).c \ + $(srcdir)ar.c $(srcdir)arscan.c \ + $(srcdir)signame.c $(srcdir)signame.h $(GETOPT_SRC) \ + $(srcdir)commands.h $(srcdir)dep.h $(srcdir)file.h \ + $(srcdir)job.h $(srcdir)make.h $(srcdir)rule.h \ + $(srcdir)variable.h $(ALLOCA_SRC) $(srcdir)config.h.in + + +.SUFFIXES: +.SUFFIXES: .o .c .h .ps .dvi .info .texinfo + +all: make +info: make.info +dvi: make.dvi +# Some makes apparently use .PHONY as the default goal if it is before `all'. +.PHONY: all check info dvi + +make.info: make.texinfo + $(MAKEINFO) -I$(srcdir) $(srcdir)make.texinfo -o make.info + +make.dvi: make.texinfo + $(TEXI2DVI) $(srcdir)make.texinfo + +make.ps: make.dvi + dvi2ps make.dvi > make.ps + +make: $(objs) glob/glob.lib + $(CC) Link $(LDFLAGS) $(objs) $(LOADLIBES) To make.new + -delete quiet make + rename make.new make + +# -I. is needed to find config.h in the build directory. +.c.o: + $(CC) $(defines) IDir "" IDir $(srcdir)glob \ + $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) + +glob/glob.lib: + execute << + cd glob + smake +< + +tagsrcs = $(srcs) $(srcdir)remote-*.c +TAGS: $(tagsrcs) + $(ETAGS) $(tagsrcs) +tags: $(tagsrcs) + $(CTAGS) $(tagsrcs) + +.PHONY: install installdirs +install: + copy make sc:c + +loadavg: loadavg.c config.h + $(CC) $(defines) -DTEST -I. -I$(srcdir) $(CFLAGS) $(LDFLAGS) \ + loadavg.c $(LOADLIBES) -o $@ + +clean: glob-clean + -$(RM) -f make loadavg *.o core make.dvi + +distclean: clean glob-realclean + -$(RM) -f Makefile config.h config.status build.sh + -$(RM) -f config.log config.cache + -$(RM) -f TAGS tags + -$(RM) -f make.?? make.??s make.log make.toc make.*aux + -$(RM) -f loadavg.c + +realclean: distclean + -$(RM) -f make.info* + +mostlyclean: clean + +.PHONY: glob-clean glob-realclean + +glob-clean glob-realclean: + execute << + cd glob + smake $@ +< + +# --------------- DEPENDENCIES +# +# dummy +# dummy +ar.o : \ + ar.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h dep.h +arscan.o : \ + arscan.c make.h config.h \ + getopt.h \ + gettext.h \ + +commands.o : \ + commands.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + filedef.h hash.h variable.h job.h commands.h +default.o : \ + default.c make.h config.h \ + getopt.h \ + gettext.h rule.h \ + dep.h filedef.h hash.h job.h commands.h variable.h +dir.o : \ + dir.c make.h config.h \ + getopt.h \ + gettext.h hash.h \ + +expand.o : \ + expand.c make.h config.h \ + getopt.h \ + gettext.h \ + filedef.h hash.h job.h commands.h variable.h \ + rule.h +file.o : \ + file.c make.h config.h \ + getopt.h \ + gettext.h \ + dep.h filedef.h hash.h job.h commands.h \ + variable.h debug.h +function.o : \ + function.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h variable.h dep.h job.h commands.h debug.h +getopt.o : \ + getopt.c config.h \ + +getopt1.o : \ + getopt1.c config.h getopt.h \ + +hash.o : \ + hash.c make.h config.h \ + getopt.h \ + gettext.h hash.h +implicit.o : \ + implicit.c make.h config.h \ + getopt.h \ + gettext.h rule.h \ + dep.h filedef.h hash.h debug.h +job.o : \ + job.c make.h config.h \ + getopt.h \ + gettext.h \ + job.h debug.h filedef.h hash.h commands.h \ + variable.h \ + +loadavg-loadavg.o : \ + loadavg.c config.h \ + make.h \ + getopt.h \ + gettext.h \ + +main.o : \ + main.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + filedef.h hash.h variable.h job.h commands.h rule.h debug.h \ + +misc.o : \ + misc.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + debug.h +read.o : \ + read.c make.h config.h \ + getopt.h \ + gettext.h \ + dep.h filedef.h hash.h \ + job.h commands.h variable.h rule.h debug.h +remake.o : \ + remake.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h job.h commands.h dep.h variable.h debug.h \ + +# dummy +remote-stub.o : \ + remote-stub.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h job.h commands.h +rule.o : \ + rule.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + filedef.h hash.h job.h commands.h variable.h rule.h +signame.o : \ + signame.c make.h config.h \ + getopt.h \ + gettext.h +variable.o : \ + variable.c make.h config.h \ + getopt.h \ + gettext.h dep.h \ + filedef.h hash.h job.h commands.h variable.h rule.h +version.o : \ + version.c config.h +vpath.o : \ + vpath.c make.h config.h \ + getopt.h \ + gettext.h filedef.h \ + hash.h variable.h diff --git a/src/make-3.80/acinclude.m4 b/src/make-3.80/acinclude.m4 new file mode 100755 index 00000000..cd2b9037 --- /dev/null +++ b/src/make-3.80/acinclude.m4 @@ -0,0 +1,164 @@ +dnl acinclude.m4 -- Extra macros needed for GNU make. +dnl +dnl Automake will incorporate this into its generated aclocal.m4. + +dnl --------------------------------------------------------------------------- +dnl Got this from the lynx 2.8 distribution. +dnl by T.E.Dickey +dnl and Jim Spath +dnl and Philippe De Muyter +dnl +dnl Created: 1997/1/28 +dnl Updated: 1997/12/23 +dnl --------------------------------------------------------------------------- +dnl After checking for functions in the default $LIBS, make a further check +dnl for the functions that are netlib-related (these aren't always in the +dnl libc, etc., and have to be handled specially because there are conflicting +dnl and broken implementations. +dnl Common library requirements (in order): +dnl -lresolv -lsocket -lnsl +dnl -lnsl -lsocket +dnl -lsocket +dnl -lbsd +AC_DEFUN([CF_NETLIBS],[ +cf_test_netlibs=no +AC_MSG_CHECKING(for network libraries) +AC_CACHE_VAL(cf_cv_netlibs,[ +AC_MSG_RESULT(working...) +cf_cv_netlibs="" +cf_test_netlibs=yes +AC_CHECK_FUNCS(gethostname,,[ + CF_RECHECK_FUNC(gethostname,nsl,cf_cv_netlibs,[ + CF_RECHECK_FUNC(gethostname,socket,cf_cv_netlibs)])]) +# +# FIXME: sequent needs this library (i.e., -lsocket -linet -lnsl), but +# I don't know the entrypoints - 97/7/22 TD +AC_CHECK_LIB(inet,main,cf_cv_netlibs="-linet $cf_cv_netlibs") +# +if test "$ac_cv_func_lsocket" != no ; then +AC_CHECK_FUNCS(socket,,[ + CF_RECHECK_FUNC(socket,socket,cf_cv_netlibs,[ + CF_RECHECK_FUNC(socket,bsd,cf_cv_netlibs)])]) +fi +# +AC_CHECK_FUNCS(gethostbyname,,[ + CF_RECHECK_FUNC(gethostbyname,nsl,cf_cv_netlibs)]) +# +AC_CHECK_FUNCS(strcasecmp,,[ + CF_RECHECK_FUNC(strcasecmp,resolv,cf_cv_netlibs)]) +]) +LIBS="$LIBS $cf_cv_netlibs" +test $cf_test_netlibs = no && echo "$cf_cv_netlibs" >&AC_FD_MSG +])dnl +dnl --------------------------------------------------------------------------- +dnl Re-check on a function to see if we can pick it up by adding a library. +dnl $1 = function to check +dnl $2 = library to check in +dnl $3 = environment to update (e.g., $LIBS) +dnl $4 = what to do if this fails +dnl +dnl This uses 'unset' if the shell happens to support it, but leaves the +dnl configuration variable set to 'unknown' if not. This is a little better +dnl than the normal autoconf test, which gives misleading results if a test +dnl for the function is made (e.g., with AC_CHECK_FUNC) after this macro is +dnl used (autoconf does not distinguish between a null token and one that is +dnl set to 'no'). +AC_DEFUN([CF_RECHECK_FUNC],[ +AC_CHECK_LIB($2,$1,[ + CF_UPPER(cf_tr_func,$1) + AC_DEFINE_UNQUOTED(HAVE_$cf_tr_func,1,[Define if you have function $1]) + ac_cv_func_$1=yes + $3="-l$2 [$]$3"],[ + ac_cv_func_$1=unknown + unset ac_cv_func_$1 2>/dev/null + $4], + [[$]$3]) +])dnl +dnl --------------------------------------------------------------------------- +dnl Make an uppercase version of a variable +dnl $1=uppercase($2) +AC_DEFUN([CF_UPPER], +[ +changequote(,)dnl +$1=`echo $2 | tr '[a-z]' '[A-Z]'` +changequote([,])dnl +])dnl + + +dnl --------------------------------------------------------------------------- +dnl From Paul Eggert + +AC_DEFUN(AC_STRUCT_ST_MTIM_NSEC, + [AC_CACHE_CHECK([for nanoseconds field of struct stat.st_mtim], + ac_cv_struct_st_mtim_nsec, + [ac_save_CPPFLAGS="$CPPFLAGS" + ac_cv_struct_st_mtim_nsec=no + # tv_nsec -- the usual case + # _tv_nsec -- Solaris 2.6, if + # (defined _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1 + # && !defined __EXTENSIONS__) + # st__tim.tv_nsec -- UnixWare 2.1.2 + for ac_val in tv_nsec _tv_nsec st__tim.tv_nsec; do + CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val" + AC_TRY_COMPILE([#include +#include ], [struct stat s; s.st_mtim.ST_MTIM_NSEC;], + [ac_cv_struct_st_mtim_nsec=$ac_val; break]) + done + CPPFLAGS="$ac_save_CPPFLAGS"]) + + if test $ac_cv_struct_st_mtim_nsec != no; then + AC_DEFINE_UNQUOTED(ST_MTIM_NSEC, $ac_cv_struct_st_mtim_nsec, [Define if 'struct stat' contains a nanoseconds field]) + fi + ] +) + + +dnl --------------------------------------------------------------------------- +dnl This will be in the next version of autoconf; take this out then! + +# make_FUNC_SETVBUF_REVERSED +# ------------------------ +AC_DEFUN([make_FUNC_SETVBUF_REVERSED], +[AC_REQUIRE([AC_C_PROTOTYPES])dnl +AC_CACHE_CHECK(whether setvbuf arguments are reversed, + ac_cv_func_setvbuf_reversed, + [ac_cv_func_setvbuf_reversed=no + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include +# if PROTOTYPES + int (setvbuf) (FILE *, int, char *, size_t); +# endif]], + [[char buf; return setvbuf (stdout, _IOLBF, &buf, 1);]])], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include +# if PROTOTYPES + int (setvbuf) (FILE *, int, char *, size_t); +# endif]], + [[char buf; return setvbuf (stdout, &buf, _IOLBF, 1);]])], + [# It compiles and links either way, so it must not be declared + # with a prototype and most likely this is a K&R C compiler. + # Try running it. + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[/* This call has the arguments reversed. + A reversed system may check and see that the address of buf + is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ + char buf; + if (setvbuf (stdout, _IOLBF, &buf, 1) != 0) + exit (1); + putchar ('\r'); + exit (0); /* Non-reversed systems SEGV here. */]])], + ac_cv_func_setvbuf_reversed=yes, + rm -f core core.* *.core, + [[: # Assume setvbuf is not reversed when cross-compiling.]])] + ac_cv_func_setvbuf_reversed=yes)])]) +if test $ac_cv_func_setvbuf_reversed = yes; then + AC_DEFINE(SETVBUF_REVERSED, 1, + [Define to 1 if the `setvbuf' function takes the buffering type as + its second argument and the buffer pointer as the third, as on + System V before release 3.]) +fi +])# make_FUNC_SETVBUF_REVERSED diff --git a/src/make-3.80/aclocal.m4 b/src/make-3.80/aclocal.m4 new file mode 100755 index 00000000..45c431aa --- /dev/null +++ b/src/make-3.80/aclocal.m4 @@ -0,0 +1,3053 @@ +# generated automatically by aclocal 1.7 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +dnl acinclude.m4 -- Extra macros needed for GNU make. +dnl +dnl Automake will incorporate this into its generated aclocal.m4. + +dnl --------------------------------------------------------------------------- +dnl Got this from the lynx 2.8 distribution. +dnl by T.E.Dickey +dnl and Jim Spath +dnl and Philippe De Muyter +dnl +dnl Created: 1997/1/28 +dnl Updated: 1997/12/23 +dnl --------------------------------------------------------------------------- +dnl After checking for functions in the default $LIBS, make a further check +dnl for the functions that are netlib-related (these aren't always in the +dnl libc, etc., and have to be handled specially because there are conflicting +dnl and broken implementations. +dnl Common library requirements (in order): +dnl -lresolv -lsocket -lnsl +dnl -lnsl -lsocket +dnl -lsocket +dnl -lbsd +AC_DEFUN([CF_NETLIBS],[ +cf_test_netlibs=no +AC_MSG_CHECKING(for network libraries) +AC_CACHE_VAL(cf_cv_netlibs,[ +AC_MSG_RESULT(working...) +cf_cv_netlibs="" +cf_test_netlibs=yes +AC_CHECK_FUNCS(gethostname,,[ + CF_RECHECK_FUNC(gethostname,nsl,cf_cv_netlibs,[ + CF_RECHECK_FUNC(gethostname,socket,cf_cv_netlibs)])]) +# +# FIXME: sequent needs this library (i.e., -lsocket -linet -lnsl), but +# I don't know the entrypoints - 97/7/22 TD +AC_CHECK_LIB(inet,main,cf_cv_netlibs="-linet $cf_cv_netlibs") +# +if test "$ac_cv_func_lsocket" != no ; then +AC_CHECK_FUNCS(socket,,[ + CF_RECHECK_FUNC(socket,socket,cf_cv_netlibs,[ + CF_RECHECK_FUNC(socket,bsd,cf_cv_netlibs)])]) +fi +# +AC_CHECK_FUNCS(gethostbyname,,[ + CF_RECHECK_FUNC(gethostbyname,nsl,cf_cv_netlibs)]) +# +AC_CHECK_FUNCS(strcasecmp,,[ + CF_RECHECK_FUNC(strcasecmp,resolv,cf_cv_netlibs)]) +]) +LIBS="$LIBS $cf_cv_netlibs" +test $cf_test_netlibs = no && echo "$cf_cv_netlibs" >&AC_FD_MSG +])dnl +dnl --------------------------------------------------------------------------- +dnl Re-check on a function to see if we can pick it up by adding a library. +dnl $1 = function to check +dnl $2 = library to check in +dnl $3 = environment to update (e.g., $LIBS) +dnl $4 = what to do if this fails +dnl +dnl This uses 'unset' if the shell happens to support it, but leaves the +dnl configuration variable set to 'unknown' if not. This is a little better +dnl than the normal autoconf test, which gives misleading results if a test +dnl for the function is made (e.g., with AC_CHECK_FUNC) after this macro is +dnl used (autoconf does not distinguish between a null token and one that is +dnl set to 'no'). +AC_DEFUN([CF_RECHECK_FUNC],[ +AC_CHECK_LIB($2,$1,[ + CF_UPPER(cf_tr_func,$1) + AC_DEFINE_UNQUOTED(HAVE_$cf_tr_func,1,[Define if you have function $1]) + ac_cv_func_$1=yes + $3="-l$2 [$]$3"],[ + ac_cv_func_$1=unknown + unset ac_cv_func_$1 2>/dev/null + $4], + [[$]$3]) +])dnl +dnl --------------------------------------------------------------------------- +dnl Make an uppercase version of a variable +dnl $1=uppercase($2) +AC_DEFUN([CF_UPPER], +[ +changequote(,)dnl +$1=`echo $2 | tr '[a-z]' '[A-Z]'` +changequote([,])dnl +])dnl + + +dnl --------------------------------------------------------------------------- +dnl From Paul Eggert + +AC_DEFUN(AC_STRUCT_ST_MTIM_NSEC, + [AC_CACHE_CHECK([for nanoseconds field of struct stat.st_mtim], + ac_cv_struct_st_mtim_nsec, + [ac_save_CPPFLAGS="$CPPFLAGS" + ac_cv_struct_st_mtim_nsec=no + # tv_nsec -- the usual case + # _tv_nsec -- Solaris 2.6, if + # (defined _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1 + # && !defined __EXTENSIONS__) + # st__tim.tv_nsec -- UnixWare 2.1.2 + for ac_val in tv_nsec _tv_nsec st__tim.tv_nsec; do + CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val" + AC_TRY_COMPILE([#include +#include ], [struct stat s; s.st_mtim.ST_MTIM_NSEC;], + [ac_cv_struct_st_mtim_nsec=$ac_val; break]) + done + CPPFLAGS="$ac_save_CPPFLAGS"]) + + if test $ac_cv_struct_st_mtim_nsec != no; then + AC_DEFINE_UNQUOTED(ST_MTIM_NSEC, $ac_cv_struct_st_mtim_nsec, [Define if 'struct stat' contains a nanoseconds field]) + fi + ] +) + + +dnl --------------------------------------------------------------------------- +dnl This will be in the next version of autoconf; take this out then! + +# make_FUNC_SETVBUF_REVERSED +# ------------------------ +AC_DEFUN([make_FUNC_SETVBUF_REVERSED], +[AC_REQUIRE([AC_C_PROTOTYPES])dnl +AC_CACHE_CHECK(whether setvbuf arguments are reversed, + ac_cv_func_setvbuf_reversed, + [ac_cv_func_setvbuf_reversed=no + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include +# if PROTOTYPES + int (setvbuf) (FILE *, int, char *, size_t); +# endif]], + [[char buf; return setvbuf (stdout, _IOLBF, &buf, 1);]])], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include +# if PROTOTYPES + int (setvbuf) (FILE *, int, char *, size_t); +# endif]], + [[char buf; return setvbuf (stdout, &buf, _IOLBF, 1);]])], + [# It compiles and links either way, so it must not be declared + # with a prototype and most likely this is a K&R C compiler. + # Try running it. + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[/* This call has the arguments reversed. + A reversed system may check and see that the address of buf + is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ + char buf; + if (setvbuf (stdout, _IOLBF, &buf, 1) != 0) + exit (1); + putchar ('\r'); + exit (0); /* Non-reversed systems SEGV here. */]])], + ac_cv_func_setvbuf_reversed=yes, + rm -f core core.* *.core, + [[: # Assume setvbuf is not reversed when cross-compiling.]])] + ac_cv_func_setvbuf_reversed=yes)])]) +if test $ac_cv_func_setvbuf_reversed = yes; then + AC_DEFINE(SETVBUF_REVERSED, 1, + [Define to 1 if the `setvbuf' function takes the buffering type as + its second argument and the buffer pointer as the third, as on + System V before release 3.]) +fi +])# make_FUNC_SETVBUF_REVERSED + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 8 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +AC_PREREQ([2.54]) + +# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow +# the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], [AC_PACKAGE_TARNAME])dnl + AC_SUBST([VERSION], [AC_PACKAGE_VERSION])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG(AMTAR, tar) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl + +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[_am_stamp_count=`expr ${_am_stamp_count-0} + 1` +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.7])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# -*- Autoconf -*- + + +# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_AUX_DIR_EXPAND + +# Copyright 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +# Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50]) + +AC_DEFUN([AM_AUX_DIR_EXPAND], [ +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# serial 4 -*- Autoconf -*- + +# Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + echo '#include "conftest.h"' > conftest.c + echo 'int i;' > conftest.h + echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=conftest.c object=conftest.o \ + depfile=conftest.Po tmpdepfile=conftest.TPo \ + $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 && + grep conftest.h conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[rm -f .deps 2>/dev/null +mkdir .deps 2>/dev/null +if test -d .deps; then + DEPDIR=.deps +else + # MS-DOS does not allow filenames that begin with a dot. + DEPDIR=_deps +fi +rmdir .deps 2>/dev/null +AC_SUBST([DEPDIR]) +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +doit: + @echo done +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST(am__include) +AC_SUBST(am__quote) +AC_MSG_RESULT($_am_result) +rm -f confinc confmf +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 5 + +AC_PREREQ(2.52) + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]) +fi])]) + +# isc-posix.m4 serial 2 (gettext-0.11.2) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. + +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) + +# gettext.m4 serial 17 (gettext-0.11.5) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2002. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The +dnl default (if it is not specified or empty) is 'no-libtool'. +dnl INTLSYMBOL should be 'external' for packages with no intl directory, +dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library +dnl $(top_builddir)/intl/libintl.a will be created. +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value `$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define(gt_included_intl, ifelse([$1], [external], [no], [yes])) + define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not + dnl documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + dnl Add a version number to the cache macros. + define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) + define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) + define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) + + AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, + [AC_TRY_LINK([#include +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings;], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], + gt_cv_func_gnugettext_libc=yes, + gt_cv_func_gnugettext_libc=no)]) + + if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + gt_cv_func_gnugettext_libintl, + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_TRY_LINK([#include +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + gt_cv_func_gnugettext_libintl=yes, + gt_cv_func_gnugettext_libintl=no) + dnl Now see whether libintl exists and depends on libiconv. + if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + gt_cv_func_gnugettext_libintl=yes + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if test "$gt_cv_func_gnugettext_libc" = "yes" \ + || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ + && test "$PACKAGE" != gettext; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE(ENABLE_NLS, 1, + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if test "$gt_cv_func_gnugettext_libintl" = "yes"; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE(HAVE_GETTEXT, 1, + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE(HAVE_DCGETTEXT, 1, + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL + dnl to 'yes' because some of the testsuite requires it. + if test "$PACKAGE" = gettext; then + BUILD_INCLUDED_LIBINTL=yes + fi + + dnl Make all variables we use known to autoconf. + AC_SUBST(BUILD_INCLUDED_LIBINTL) + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATOBJEXT) + AC_SUBST(INTLOBJS) + + dnl For backward compatibility. Some configure.ins may be using this. + nls_cv_header_intl= + nls_cv_header_libgt= + + dnl For backward compatibility. Some Makefiles may be using this. + DATADIRNAME=share + AC_SUBST(DATADIRNAME) + + dnl For backward compatibility. Some Makefiles may be using this. + INSTOBJEXT=.mo + AC_SUBST(INSTOBJEXT) + + dnl For backward compatibility. Some Makefiles may be using this. + GENCAT=gencat + AC_SUBST(GENCAT) + + dnl Enable libtool support if the surrounding package wishes it. + INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix + AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST(INTLLIBS) + + dnl Make all documented variables known to autoconf. + AC_SUBST(LIBINTL) + AC_SUBST(LTLIBINTL) + AC_SUBST(POSUB) +]) + + +dnl Checks for all prerequisites of the po subdirectory, +dnl except for USE_NLS. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + + dnl Search for GNU xgettext 0.11 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU msgfmt. + if test "$GMSGFMT" != ":"; then + dnl If it is no GNU msgfmt we define it as : so that the + dnl Makefiles still can work. + if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && + (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` + AC_MSG_RESULT( + [found $GMSGFMT program is not GNU msgfmt; ignore it]) + GMSGFMT=":" + fi + fi + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && + (if $XGETTEXT --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + fi + + AC_OUTPUT_COMMANDS([ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + fi + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + GMOFILES= + UPDATEPOFILES= + DUMMYPOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it + # from automake. + eval 'ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + + +dnl Checks for all prerequisites of the intl subdirectory, +dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, +dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. +AC_DEFUN([AM_INTL_SUBDIR], +[ + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + AC_REQUIRE([jm_GLIBC21])dnl + AC_REQUIRE([gt_INTDIV0])dnl + AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl + AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl + AC_REQUIRE([gt_INTTYPES_PRI])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ +stdlib.h string.h unistd.h sys/param.h]) + AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ +geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ +strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next]) + + AM_ICONV + AM_LANGINFO_CODESET + if test $ac_cv_header_locale_h = yes; then + AM_LC_MESSAGES + fi + + dnl intl/plural.c is generated from intl/plural.y. It requires bison, + dnl because plural.y uses bison specific features. It requires at least + dnl bison-1.26 because earlier versions generate a plural.c that doesn't + dnl compile. + dnl bison is only needed for the maintainer (who touches plural.y). But in + dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put + dnl the rule in general Makefile. Now, some people carelessly touch the + dnl files or have a broken "make" program, hence the plural.c rule will + dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not + dnl present or too old. + AC_CHECK_PROGS([INTLBISON], [bison]) + if test -z "$INTLBISON"; then + ac_verc_fail=yes + else + dnl Found it, now check the version. + AC_MSG_CHECKING([version of bison]) +changequote(<<,>>)dnl + ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) +changequote([,])dnl + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + esac + AC_MSG_RESULT([$ac_prog_version]) + fi + if test $ac_verc_fail = yes; then + INTLBISON=: + fi +]) + + +AC_DEFUN([AM_MKINSTALLDIRS], +[ + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but $(top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) + +# lib-prefix.m4 serial 1 (gettext-0.11) +dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +# lib-link.m4 serial 3 (gettext-0.11.3) +dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + undefine([Name]) + undefine([NAME]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. If found, it +dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and +dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + define([Name],[translit([$1],[./-], [___])]) + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + LIBS="$LIBS $LIB[]NAME" + AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no]) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + undefine([Name]) + undefine([NAME]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl libext, shlibext, hardcode_libdir_flag_spec, hardcode_libdir_separator, +dnl hardcode_direct, hardcode_minus_L, +dnl sys_lib_search_path_spec, sys_lib_dlsearch_path_spec. +AC_DEFUN([AC_LIB_RPATH], +[ + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + libext="$acl_cv_libext" + shlibext="$acl_cv_shlibext" + hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + hardcode_direct="$acl_cv_hardcode_direct" + hardcode_minus_L="$acl_cv_hardcode_minus_L" + sys_lib_search_path_spec="$acl_cv_sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec="$acl_cv_sys_lib_dlsearch_path_spec" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE(rpath, + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH([lib$1-prefix], +[ --with-lib$1-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib + --without-lib$1-prefix don't search for lib$1 in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + else + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + else + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + dnl Note: hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +# lib-ld.m4 serial 1 (gettext-0.11) +dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + acl_cv_prog_gnu_ld=yes +else + acl_cv_prog_gnu_ld=no +fi]) +with_gnu_ld=$acl_cv_prog_gnu_ld +]) + +dnl From libtool-1.4. Sets the variable LD. +AC_DEFUN([AC_LIB_PROG_LD], +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(acl_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) + +# iconv.m4 serial AM4 (gettext-0.11.3) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_func_iconv=yes) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_lib_iconv=yes + am_cv_func_iconv=yes) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST(LIBICONV) + AC_SUBST(LTLIBICONV) +]) + +AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) + AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) + fi +]) + +# progtest.m4 serial 2 (gettext-0.10.40) +dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1996. + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# Test for the GNU C Library, version 2.1 or newer. +# From Bruno Haible. + +AC_DEFUN([jm_GLIBC21], + [ + AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, + ac_cv_gnu_library_2_1, + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) + Lucky GNU user + #endif +#endif + ], + ac_cv_gnu_library_2_1=yes, + ac_cv_gnu_library_2_1=no) + ] + ) + AC_SUBST(GLIBC21) + GLIBC21="$ac_cv_gnu_library_2_1" + ] +) + +# intdiv0.m4 serial 1 (gettext-0.11.3) +dnl Copyright (C) 2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([gt_INTDIV0], +[ + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + + AC_CACHE_CHECK([whether integer division by zero raises SIGFPE], + gt_cv_int_divbyzero_sigfpe, + [ + AC_TRY_RUN([ +#include +#include + +static void +#ifdef __cplusplus +sigfpe_handler (int sig) +#else +sigfpe_handler (sig) int sig; +#endif +{ + /* Exit with code 0 if SIGFPE, with code 1 if any other signal. */ + exit (sig != SIGFPE); +} + +int x = 1; +int y = 0; +int z; +int nan; + +int main () +{ + signal (SIGFPE, sigfpe_handler); +/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP. */ +#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP) + signal (SIGTRAP, sigfpe_handler); +#endif +/* Linux/SPARC yields signal SIGILL. */ +#if defined (__sparc__) && defined (__linux__) + signal (SIGILL, sigfpe_handler); +#endif + + z = x / y; + nan = y / y; + exit (1); +} +], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no, + [ + # Guess based on the CPU. + case "$host_cpu" in + alpha* | i[34567]86 | m68k | s390*) + gt_cv_int_divbyzero_sigfpe="guessing yes";; + *) + gt_cv_int_divbyzero_sigfpe="guessing no";; + esac + ]) + ]) + case "$gt_cv_int_divbyzero_sigfpe" in + *yes) value=1;; + *) value=0;; + esac + AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value, + [Define if integer division by zero raises signal SIGFPE.]) +]) + +# uintmax_t.m4 serial 6 (gettext-0.11) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +AC_PREREQ(2.13) + +# Define uintmax_t to `unsigned long' or `unsigned long long' +# if does not exist. + +AC_DEFUN([jm_AC_TYPE_UINTMAX_T], +[ + AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([jm_AC_HEADER_STDINT_H]) + if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then + AC_REQUIRE([jm_AC_TYPE_UNSIGNED_LONG_LONG]) + test $ac_cv_type_unsigned_long_long = yes \ + && ac_type='unsigned long long' \ + || ac_type='unsigned long' + AC_DEFINE_UNQUOTED(uintmax_t, $ac_type, + [Define to unsigned long or unsigned long long + if and don't define.]) + fi +]) + +# inttypes_h.m4 serial 4 (gettext-0.11.4) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([jm_AC_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1;], + jm_ac_cv_header_inttypes_h=yes, + jm_ac_cv_header_inttypes_h=no)]) + if test $jm_ac_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, +[Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) + +# stdint_h.m4 serial 2 (gettext-0.11.4) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_STDINT_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([jm_AC_HEADER_STDINT_H], +[ + AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1;], + jm_ac_cv_header_stdint_h=yes, + jm_ac_cv_header_stdint_h=no)]) + if test $jm_ac_cv_header_stdint_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, +[Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) + +# ulonglong.m4 serial 2 (fileutils-4.0.32, gettext-0.10.40) +dnl Copyright (C) 1999-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +AC_DEFUN([jm_AC_TYPE_UNSIGNED_LONG_LONG], +[ + AC_CACHE_CHECK([for unsigned long long], ac_cv_type_unsigned_long_long, + [AC_TRY_LINK([unsigned long long ull = 1; int i = 63;], + [unsigned long long ullmax = (unsigned long long) -1; + return ull << i | ull >> i | ullmax / ull | ullmax % ull;], + ac_cv_type_unsigned_long_long=yes, + ac_cv_type_unsigned_long_long=no)]) + if test $ac_cv_type_unsigned_long_long = yes; then + AC_DEFINE(HAVE_UNSIGNED_LONG_LONG, 1, + [Define if you have the unsigned long long type.]) + fi +]) + +# inttypes.m4 serial 1 (gettext-0.11.4) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H if exists and doesn't clash with +# . + +AC_DEFUN([gt_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], gt_cv_header_inttypes_h, + [ + AC_TRY_COMPILE( + [#include +#include ], + [], gt_cv_header_inttypes_h=yes, gt_cv_header_inttypes_h=no) + ]) + if test $gt_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H, 1, + [Define if exists and doesn't clash with .]) + fi +]) + +# inttypes-pri.m4 serial 1 (gettext-0.11.4) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +# Define PRI_MACROS_BROKEN if exists and defines the PRI* +# macros to non-string values. This is the case on AIX 4.3.3. + +AC_DEFUN([gt_INTTYPES_PRI], +[ + AC_REQUIRE([gt_HEADER_INTTYPES_H]) + if test $gt_cv_header_inttypes_h = yes; then + AC_CACHE_CHECK([whether the inttypes.h PRIxNN macros are broken], + gt_cv_inttypes_pri_broken, + [ + AC_TRY_COMPILE([#include +#ifdef PRId32 +char *p = PRId32; +#endif +], [], gt_cv_inttypes_pri_broken=no, gt_cv_inttypes_pri_broken=yes) + ]) + fi + if test "$gt_cv_inttypes_pri_broken" = yes; then + AC_DEFINE_UNQUOTED(PRI_MACROS_BROKEN, 1, + [Define if exists and defines unusable PRI* macros.]) + fi +]) + +# codeset.m4 serial AM1 (gettext-0.10.40) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([AM_LANGINFO_CODESET], +[ + AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, + [AC_TRY_LINK([#include ], + [char* cs = nl_langinfo(CODESET);], + am_cv_langinfo_codeset=yes, + am_cv_langinfo_codeset=no) + ]) + if test $am_cv_langinfo_codeset = yes; then + AC_DEFINE(HAVE_LANGINFO_CODESET, 1, + [Define if you have and nl_langinfo(CODESET).]) + fi +]) + +# lcmessage.m4 serial 3 (gettext-0.11.3) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995. + +# Check whether LC_MESSAGES is available in . + +AC_DEFUN([AM_LC_MESSAGES], +[ + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your file defines LC_MESSAGES.]) + fi +]) + +# serial 2 + +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. + +# Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +ac_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +]) + + +# Copyright 1996, 1997, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# @defmac AC_PROG_CC_STDC +# @maindex PROG_CC_STDC +# @ovindex CC +# If the C compiler in not in ANSI C mode by default, try to add an option +# to output variable @code{CC} to make it so. This macro tries various +# options that select ANSI C on some system or another. It considers the +# compiler to be in ANSI C mode if it handles function prototypes correctly. +# +# If you use this macro, you should check after calling it whether the C +# compiler has been set to accept ANSI C; if not, the shell variable +# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source +# code in ANSI C, you can make an un-ANSIfied copy of it by using the +# program @code{ansi2knr}, which comes with Ghostscript. +# @end defmac + +AC_DEFUN([AM_PROG_CC_STDC], +[AC_REQUIRE([AC_PROG_CC]) +AC_BEFORE([$0], [AC_C_INLINE]) +AC_BEFORE([$0], [AC_C_CONST]) +dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require +dnl a magic option to avoid problems with ANSI preprocessor commands +dnl like #elif. +dnl FIXME: can't do this because then AC_AIX won't work due to a +dnl circular dependency. +dnl AC_BEFORE([$0], [AC_PROG_CPP]) +AC_MSG_CHECKING([for ${CC-cc} option to accept ANSI C]) +AC_CACHE_VAL(am_cv_prog_cc_stdc, +[am_cv_prog_cc_stdc=no +ac_save_CC="$CC" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + AC_TRY_COMPILE( +[#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +], [ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; +], +[am_cv_prog_cc_stdc="$ac_arg"; break]) +done +CC="$ac_save_CC" +]) +if test -z "$am_cv_prog_cc_stdc"; then + AC_MSG_RESULT([none needed]) +else + AC_MSG_RESULT([$am_cv_prog_cc_stdc]) +fi +case "x$am_cv_prog_cc_stdc" in + x|xno) ;; + *) CC="$CC $am_cv_prog_cc_stdc" ;; +esac +]) + +AU_DEFUN([fp_PROG_CC_STDC], [AM_PROG_CC_STDC]) + + +# Copyright 1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +AC_DEFUN([AM_WITH_DMALLOC], +[AC_MSG_CHECKING([if malloc debugging is wanted]) +AC_ARG_WITH(dmalloc, +[ --with-dmalloc use dmalloc, as in + http://www.dmalloc.com/dmalloc.tar.gz], +[if test "$withval" = yes; then + AC_MSG_RESULT(yes) + AC_DEFINE(WITH_DMALLOC,1, + [Define if using the dmalloc debugging malloc package]) + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + AC_MSG_RESULT(no) +fi], [AC_MSG_RESULT(no)]) +]) + +AU_DEFUN([fp_WITH_DMALLOC], [AM_WITH_DMALLOC]) + diff --git a/src/make-3.80/alloca.c b/src/make-3.80/alloca.c new file mode 100755 index 00000000..8f98b73d --- /dev/null +++ b/src/make-3.80/alloca.c @@ -0,0 +1,504 @@ +/* alloca.c -- allocate automatically reclaimed memory + (Mostly) portable public-domain implementation -- D A Gwyn + + This implementation of the PWB library alloca function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + J.Otto Tennant contributed the Cray support. + + There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef emacs +#include "blockinput.h" +#endif + +/* If compiling with GCC 2, this file's not needed. */ +#if !defined (__GNUC__) || __GNUC__ < 2 + +/* If someone has defined alloca as a macro, + there must be some other way alloca is supposed to work. */ +#ifndef alloca + +#ifdef emacs +#ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +#ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +#endif /* STACK_DIRECTION undefined */ +#endif /* static */ +#endif /* emacs */ + +/* If your stack is a linked list of frames, you have to + provide an "address metric" ADDRESS_FUNCTION macro. */ + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) +long i00afunc (); +#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) +#else +#define ADDRESS_FUNCTION(arg) &(arg) +#endif + +#if __STDC__ +typedef void *pointer; +#else +typedef char *pointer; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* Different portions of Emacs need to call different versions of + malloc. The Emacs executable needs alloca to call xmalloc, because + ordinary malloc isn't protected from input signals. On the other + hand, the utilities in lib-src need alloca to call malloc; some of + them are very simple, and don't have an xmalloc routine. + + Non-Emacs programs expect this to call use xmalloc. + + Callers below should use malloc. */ + +#ifndef emacs +#define malloc xmalloc +#endif +extern pointer malloc (); + +/* Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ + +#ifndef STACK_DIRECTION +#define STACK_DIRECTION 0 /* Direction unknown. */ +#endif + +#if STACK_DIRECTION != 0 + +#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ + +#else /* STACK_DIRECTION == 0; need run-time code. */ + +static int stack_dir; /* 1 or -1 once known. */ +#define STACK_DIR stack_dir + +static void +find_stack_direction () +{ + static char *addr = NULL; /* Address of first `dummy', once known. */ + auto char dummy; /* To get stack address. */ + + if (addr == NULL) + { /* Initial entry. */ + addr = ADDRESS_FUNCTION (dummy); + + find_stack_direction (); /* Recurse once. */ + } + else + { + /* Second entry. */ + if (ADDRESS_FUNCTION (dummy) > addr) + stack_dir = 1; /* Stack grew upward. */ + else + stack_dir = -1; /* Stack grew downward. */ + } +} + +#endif /* STACK_DIRECTION == 0 */ + +/* An "alloca header" is used to: + (a) chain together all alloca'ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc + alignment chunk size. The following default should work okay. */ + +#ifndef ALIGN_SIZE +#define ALIGN_SIZE sizeof(double) +#endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* To force sizeof(header). */ + struct + { + union hdr *next; /* For chaining headers. */ + char *deep; /* For stack depth measure. */ + } h; +} header; + +static header *last_alloca_header = NULL; /* -> last alloca header. */ + +/* Return a pointer to at least SIZE bytes of storage, + which will be automatically reclaimed upon exit from + the procedure that called alloca. Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. */ + +pointer +alloca (size) + unsigned size; +{ + auto char probe; /* Probes stack depth: */ + register char *depth = ADDRESS_FUNCTION (probe); + +#if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* Unknown growth direction. */ + find_stack_direction (); +#endif + + /* Reclaim garbage, defined as all alloca'd storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* Traverses linked list. */ + +#ifdef emacs + BLOCK_INPUT; +#endif + + for (hp = last_alloca_header; hp != NULL;) + if ((STACK_DIR > 0 && hp->h.deep > depth) + || (STACK_DIR < 0 && hp->h.deep < depth)) + { + register header *np = hp->h.next; + + free ((pointer) hp); /* Collect garbage. */ + + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + last_alloca_header = hp; /* -> last valid storage. */ + +#ifdef emacs + UNBLOCK_INPUT; +#endif + } + + if (size == 0) + return NULL; /* No allocation required. */ + + /* Allocate combined header + user data storage. */ + + { + register pointer new = malloc (sizeof (header) + size); + /* Address of header. */ + + if (new == 0) + abort(); + + ((header *) new)->h.next = last_alloca_header; + ((header *) new)->h.deep = depth; + + last_alloca_header = (header *) new; + + /* User storage begins just after header. */ + + return (pointer) ((char *) new + sizeof (header)); + } +} + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) + +#ifdef DEBUG_I00AFUNC +#include +#endif + +#ifndef CRAY_STACK +#define CRAY_STACK +#ifndef CRAY2 +/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ +struct stack_control_header + { + long shgrow:32; /* Number of times stack has grown. */ + long shaseg:32; /* Size of increments to stack. */ + long shhwm:32; /* High water mark of stack. */ + long shsize:32; /* Current size of stack (all segments). */ + }; + +/* The stack segment linkage control information occurs at + the high-address end of a stack segment. (The stack + grows from low addresses to high addresses.) The initial + part of the stack segment linkage control information is + 0200 (octal) words. This provides for register storage + for the routine which overflows the stack. */ + +struct stack_segment_linkage + { + long ss[0200]; /* 0200 overflow words. */ + long sssize:32; /* Number of words in this segment. */ + long ssbase:32; /* Offset to stack base. */ + long:32; + long sspseg:32; /* Offset to linkage control of previous + segment of stack. */ + long:32; + long sstcpt:32; /* Pointer to task common address block. */ + long sscsnm; /* Private control structure number for + microtasking. */ + long ssusr1; /* Reserved for user. */ + long ssusr2; /* Reserved for user. */ + long sstpid; /* Process ID for pid based multi-tasking. */ + long ssgvup; /* Pointer to multitasking thread giveup. */ + long sscray[7]; /* Reserved for Cray Research. */ + long ssa0; + long ssa1; + long ssa2; + long ssa3; + long ssa4; + long ssa5; + long ssa6; + long ssa7; + long sss0; + long sss1; + long sss2; + long sss3; + long sss4; + long sss5; + long sss6; + long sss7; + }; + +#else /* CRAY2 */ +/* The following structure defines the vector of words + returned by the STKSTAT library routine. */ +struct stk_stat + { + long now; /* Current total stack size. */ + long maxc; /* Amount of contiguous space which would + be required to satisfy the maximum + stack demand to date. */ + long high_water; /* Stack high-water mark. */ + long overflows; /* Number of stack overflow ($STKOFEN) calls. */ + long hits; /* Number of internal buffer hits. */ + long extends; /* Number of block extensions. */ + long stko_mallocs; /* Block allocations by $STKOFEN. */ + long underflows; /* Number of stack underflow calls ($STKRETN). */ + long stko_free; /* Number of deallocations by $STKRETN. */ + long stkm_free; /* Number of deallocations by $STKMRET. */ + long segments; /* Current number of stack segments. */ + long maxs; /* Maximum number of stack segments so far. */ + long pad_size; /* Stack pad size. */ + long current_address; /* Current stack segment address. */ + long current_size; /* Current stack segment size. This + number is actually corrupted by STKSTAT to + include the fifteen word trailer area. */ + long initial_address; /* Address of initial segment. */ + long initial_size; /* Size of initial segment. */ + }; + +/* The following structure describes the data structure which trails + any stack segment. I think that the description in 'asdef' is + out of date. I only describe the parts that I am sure about. */ + +struct stk_trailer + { + long this_address; /* Address of this block. */ + long this_size; /* Size of this block (does not include + this trailer). */ + long unknown2; + long unknown3; + long link; /* Address of trailer block of previous + segment. */ + long unknown5; + long unknown6; + long unknown7; + long unknown8; + long unknown9; + long unknown10; + long unknown11; + long unknown12; + long unknown13; + long unknown14; + }; + +#endif /* CRAY2 */ +#endif /* not CRAY_STACK */ + +#ifdef CRAY2 +/* Determine a "stack measure" for an arbitrary ADDRESS. + I doubt that "lint" will like this much. */ + +static long +i00afunc (long *address) +{ + struct stk_stat status; + struct stk_trailer *trailer; + long *block, size; + long result = 0; + + /* We want to iterate through all of the segments. The first + step is to get the stack status structure. We could do this + more quickly and more directly, perhaps, by referencing the + $LM00 common block, but I know that this works. */ + + STKSTAT (&status); + + /* Set up the iteration. */ + + trailer = (struct stk_trailer *) (status.current_address + + status.current_size + - 15); + + /* There must be at least one stack segment. Therefore it is + a fatal error if "trailer" is null. */ + + if (trailer == 0) + abort (); + + /* Discard segments that do not contain our argument address. */ + + while (trailer != 0) + { + block = (long *) trailer->this_address; + size = trailer->this_size; + if (block == 0 || size == 0) + abort (); + trailer = (struct stk_trailer *) trailer->link; + if ((block <= address) && (address < (block + size))) + break; + } + + /* Set the result to the offset in this segment and add the sizes + of all predecessor segments. */ + + result = address - block; + + if (trailer == 0) + { + return result; + } + + do + { + if (trailer->this_size <= 0) + abort (); + result += trailer->this_size; + trailer = (struct stk_trailer *) trailer->link; + } + while (trailer != 0); + + /* We are done. Note that if you present a bogus address (one + not in any segment), you will get a different number back, formed + from subtracting the address of the first block. This is probably + not what you want. */ + + return (result); +} + +#else /* not CRAY2 */ +/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. + Determine the number of the cell within the stack, + given the address of the cell. The purpose of this + routine is to linearize, in some sense, stack addresses + for alloca. */ + +static long +i00afunc (long address) +{ + long stkl = 0; + + long size, pseg, this_segment, stack; + long result = 0; + + struct stack_segment_linkage *ssptr; + + /* Register B67 contains the address of the end of the + current stack segment. If you (as a subprogram) store + your registers on the stack and find that you are past + the contents of B67, you have overflowed the segment. + + B67 also points to the stack segment linkage control + area, which is what we are really interested in. */ + + stkl = CRAY_STACKSEG_END (); + ssptr = (struct stack_segment_linkage *) stkl; + + /* If one subtracts 'size' from the end of the segment, + one has the address of the first word of the segment. + + If this is not the first segment, 'pseg' will be + nonzero. */ + + pseg = ssptr->sspseg; + size = ssptr->sssize; + + this_segment = stkl - size; + + /* It is possible that calling this routine itself caused + a stack overflow. Discard stack segments which do not + contain the target address. */ + + while (!(this_segment <= address && address <= stkl)) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); +#endif + if (pseg == 0) + break; + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + this_segment = stkl - size; + } + + result = address - this_segment; + + /* If you subtract pseg from the current end of the stack, + you get the address of the previous stack segment's end. + This seems a little convoluted to me, but I'll bet you save + a cycle somewhere. */ + + while (pseg != 0) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o\n", pseg, size); +#endif + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + result += size; + } + return (result); +} + +#endif /* not CRAY2 */ +#endif /* CRAY */ + +#endif /* no alloca */ +#endif /* not GCC version 2 */ diff --git a/src/make-3.80/amiga.c b/src/make-3.80/amiga.c new file mode 100755 index 00000000..db8ef0df --- /dev/null +++ b/src/make-3.80/amiga.c @@ -0,0 +1,123 @@ +/* Running commands on Amiga +Copyright (C) 1995, 1996 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "make.h" +#include "variable.h" +#include "amiga.h" +#include +#include +#include +#include +#include + +static const char Amiga_version[] = "$VER: Make 3.74.3 (12.05.96) \n" + "Amiga Port by A. Digulla (digulla@home.lake.de)"; + +int +MyExecute (argv) +char ** argv; +{ + char * buffer, * ptr; + char ** aptr; + int len = 0; + int status; + + for (aptr=argv; *aptr; aptr++) + { + len += strlen (*aptr) + 4; + } + + buffer = AllocMem (len, MEMF_ANY); + + if (!buffer) + fatal (NILF, "MyExecute: Cannot allocate space for calling a command"); + + ptr = buffer; + + for (aptr=argv; *aptr; aptr++) + { + if (((*aptr)[0] == ';' && !(*aptr)[1])) + { + *ptr ++ = '"'; + strcpy (ptr, *aptr); + ptr += strlen (ptr); + *ptr ++ = '"'; + } + else if ((*aptr)[0] == '@' && (*aptr)[1] == '@' && !(*aptr)[2]) + { + *ptr ++ = '\n'; + continue; + } + else + { + strcpy (ptr, *aptr); + ptr += strlen (ptr); + } + *ptr ++ = ' '; + *ptr = 0; + } + + ptr[-1] = '\n'; + + status = SystemTags (buffer, + SYS_UserShell, TRUE, + TAG_END); + + FreeMem (buffer, len); + + if (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) + status = 20; + + /* Warnings don't count */ + if (status == 5) + status = 0; + + return status; +} + +char * +wildcard_expansion (wc, o) +char * wc, * o; +{ +# define PATH_SIZE 1024 + struct AnchorPath * apath; + + if ( (apath = AllocMem (sizeof (struct AnchorPath) + PATH_SIZE, + MEMF_CLEAR)) + ) + { + apath->ap_Strlen = PATH_SIZE; + + if (MatchFirst (wc, apath) == 0) + { + do + { + o = variable_buffer_output (o, apath->ap_Buf, + strlen (apath->ap_Buf)); + o = variable_buffer_output (o, " ",1); + } while (MatchNext (apath) == 0); + } + + MatchEnd (apath); + FreeMem (apath, sizeof (struct AnchorPath) + PATH_SIZE); + } + + return o; +} + diff --git a/src/make-3.80/amiga.h b/src/make-3.80/amiga.h new file mode 100755 index 00000000..99a1c598 --- /dev/null +++ b/src/make-3.80/amiga.h @@ -0,0 +1,22 @@ +/* Definitions for amiga specific things +Copyright (C) 1995, 1996 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +extern int MyExecute PARAMS ((char ** argv)); +extern char * wildcard_expansion PARAMS ((char * wc, char * o)); + diff --git a/src/make-3.80/ar.c b/src/make-3.80/ar.c new file mode 100755 index 00000000..286be55f --- /dev/null +++ b/src/make-3.80/ar.c @@ -0,0 +1,329 @@ +/* Interface to `ar' archives for GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1997, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" + +#ifndef NO_ARCHIVES + +#include "filedef.h" +#include "dep.h" +#include + +/* Defined in arscan.c. */ +extern long int ar_scan PARAMS ((char *archive, long int (*function) (), long int arg)); +extern int ar_name_equal PARAMS ((char *name, char *mem, int truncated)); +#ifndef VMS +extern int ar_member_touch PARAMS ((char *arname, char *memname)); +#endif + +/* Return nonzero if NAME is an archive-member reference, zero if not. + An archive-member reference is a name like `lib(member)'. + If a name like `lib((entry))' is used, a fatal error is signaled at + the attempt to use this unsupported feature. */ + +int +ar_name (name) + char *name; +{ + char *p = strchr (name, '('); + char *end; + + if (p == 0 || p == name) + return 0; + + end = p + strlen (p) - 1; + if (*end != ')') + return 0; + + if (p[1] == '(' && end[-1] == ')') + fatal (NILF, _("attempt to use unsupported feature: `%s'"), name); + + return 1; +} + + +/* Parse the archive-member reference NAME into the archive and member names. + Put the malloc'd archive name in *ARNAME_P if ARNAME_P is non-nil; + put the malloc'd member name in *MEMNAME_P if MEMNAME_P is non-nil. */ + +void +ar_parse_name (name, arname_p, memname_p) + char *name, **arname_p, **memname_p; +{ + char *p = strchr (name, '('), *end = name + strlen (name) - 1; + + if (arname_p != 0) + *arname_p = savestring (name, p - name); + + if (memname_p != 0) + *memname_p = savestring (p + 1, end - (p + 1)); +} + +static long int ar_member_date_1 PARAMS ((int desc, char *mem, int truncated, long int hdrpos, + long int datapos, long int size, long int date, int uid, int gid, int mode, char *name)); + +/* Return the modtime of NAME. */ + +time_t +ar_member_date (name) + char *name; +{ + char *arname; + int arname_used = 0; + char *memname; + long int val; + + ar_parse_name (name, &arname, &memname); + + /* Make sure we know the modtime of the archive itself because we are + likely to be called just before commands to remake a member are run, + and they will change the archive itself. + + But we must be careful not to enter_file the archive itself if it does + not exist, because pattern_search assumes that files found in the data + base exist or can be made. */ + { + struct file *arfile; + arfile = lookup_file (arname); + if (arfile == 0 && file_exists_p (arname)) + { + arfile = enter_file (arname); + arname_used = 1; + } + + if (arfile != 0) + (void) f_mtime (arfile, 0); + } + + val = ar_scan (arname, ar_member_date_1, (long int) memname); + + if (!arname_used) + free (arname); + free (memname); + + return (val <= 0 ? (time_t) -1 : (time_t) val); +} + +/* This function is called by `ar_scan' to find which member to look at. */ + +/* ARGSUSED */ +static long int +ar_member_date_1 (desc, mem, truncated, + hdrpos, datapos, size, date, uid, gid, mode, name) + int desc; + char *mem; + int truncated; + long int hdrpos, datapos, size, date; + int uid, gid, mode; + char *name; +{ + return ar_name_equal (name, mem, truncated) ? date : 0; +} + +/* Set the archive-member NAME's modtime to now. */ + +#ifdef VMS +int +ar_touch (name) + char *name; +{ + error (NILF, _("touch archive member is not available on VMS")); + return -1; +} +#else +int +ar_touch (name) + char *name; +{ + char *arname, *memname; + int arname_used = 0; + register int val; + + ar_parse_name (name, &arname, &memname); + + /* Make sure we know the modtime of the archive itself before we + touch the member, since this will change the archive itself. */ + { + struct file *arfile; + arfile = lookup_file (arname); + if (arfile == 0) + { + arfile = enter_file (arname); + arname_used = 1; + } + + (void) f_mtime (arfile, 0); + } + + val = 1; + switch (ar_member_touch (arname, memname)) + { + case -1: + error (NILF, _("touch: Archive `%s' does not exist"), arname); + break; + case -2: + error (NILF, _("touch: `%s' is not a valid archive"), arname); + break; + case -3: + perror_with_name ("touch: ", arname); + break; + case 1: + error (NILF, + _("touch: Member `%s' does not exist in `%s'"), memname, arname); + break; + case 0: + val = 0; + break; + default: + error (NILF, + _("touch: Bad return code from ar_member_touch on `%s'"), name); + } + + if (!arname_used) + free (arname); + free (memname); + + return val; +} +#endif /* !VMS */ + +/* State of an `ar_glob' run, passed to `ar_glob_match'. */ + +struct ar_glob_state + { + char *arname; + char *pattern; + unsigned int size; + struct nameseq *chain; + unsigned int n; + }; + +/* This function is called by `ar_scan' to match one archive + element against the pattern in STATE. */ + +static long int +ar_glob_match (desc, mem, truncated, + hdrpos, datapos, size, date, uid, gid, mode, + state) + int desc; + char *mem; + int truncated; + long int hdrpos, datapos, size, date; + int uid, gid, mode; + struct ar_glob_state *state; +{ + if (fnmatch (state->pattern, mem, FNM_PATHNAME|FNM_PERIOD) == 0) + { + /* We have a match. Add it to the chain. */ + struct nameseq *new = (struct nameseq *) xmalloc (state->size); + new->name = concat (state->arname, mem, ")"); + new->next = state->chain; + state->chain = new; + ++state->n; + } + + return 0L; +} + +/* Return nonzero if PATTERN contains any metacharacters. + Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ +static int +glob_pattern_p (pattern, quote) + const char *pattern; + const int quote; +{ + register const char *p; + int open = 0; + + for (p = pattern; *p != '\0'; ++p) + switch (*p) + { + case '?': + case '*': + return 1; + + case '\\': + if (quote) + ++p; + break; + + case '[': + open = 1; + break; + + case ']': + if (open) + return 1; + break; + } + + return 0; +} + +/* Glob for MEMBER_PATTERN in archive ARNAME. + Return a malloc'd chain of matching elements (or nil if none). */ + +struct nameseq * +ar_glob (arname, member_pattern, size) + char *arname, *member_pattern; + unsigned int size; +{ + struct ar_glob_state state; + char **names; + struct nameseq *n; + unsigned int i; + + if (! glob_pattern_p (member_pattern, 1)) + return 0; + + /* Scan the archive for matches. + ar_glob_match will accumulate them in STATE.chain. */ + i = strlen (arname); + state.arname = (char *) alloca (i + 2); + bcopy (arname, state.arname, i); + state.arname[i] = '('; + state.arname[i + 1] = '\0'; + state.pattern = member_pattern; + state.size = size; + state.chain = 0; + state.n = 0; + (void) ar_scan (arname, ar_glob_match, (long int) &state); + + if (state.chain == 0) + return 0; + + /* Now put the names into a vector for sorting. */ + names = (char **) alloca (state.n * sizeof (char *)); + i = 0; + for (n = state.chain; n != 0; n = n->next) + names[i++] = n->name; + + /* Sort them alphabetically. */ + qsort ((char *) names, i, sizeof (*names), alpha_compare); + + /* Put them back into the chain in the sorted order. */ + i = 0; + for (n = state.chain; n != 0; n = n->next) + n->name = names[i++]; + + return state.chain; +} + +#endif /* Not NO_ARCHIVES. */ diff --git a/src/make-3.80/arscan.c b/src/make-3.80/arscan.c new file mode 100755 index 00000000..fc003e99 --- /dev/null +++ b/src/make-3.80/arscan.c @@ -0,0 +1,861 @@ +/* Library function for scanning an archive file. +Copyright (C) 1987,89,91,92,93,94,95,97 Free Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +USA. */ + +#include "make.h" + +#ifdef HAVE_FCNTL_H +#include +#else +#include +#endif + +#ifndef NO_ARCHIVES + +#ifdef VMS +#include +#include +#include +#include +#include +#if __DECC +#include +#include +#endif + +static void *VMS_lib_idx; + +static char *VMS_saved_memname; + +static time_t VMS_member_date; + +static long int (*VMS_function) (); + +static int +VMS_get_member_info (module, rfa) + struct dsc$descriptor_s *module; + unsigned long *rfa; +{ + int status, i; + long int fnval; + + time_t val; + + static struct dsc$descriptor_s bufdesc = + { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL }; + + struct mhddef *mhd; + char filename[128]; + + bufdesc.dsc$a_pointer = filename; + bufdesc.dsc$w_length = sizeof (filename); + + status = lbr$set_module (&VMS_lib_idx, rfa, &bufdesc, + &bufdesc.dsc$w_length, 0); + if (! (status & 1)) + { + error (NILF, _("lbr$set_module failed to extract module info, status = %d"), + status); + + lbr$close (&VMS_lib_idx); + + return 0; + } + + mhd = (struct mhddef *) filename; + +#ifdef __DECC + /* John Fowler writes this is needed in his environment, + * but that decc$fix_time() isn't documented to work this way. Let me + * know if this causes problems in other VMS environments. + */ + val = decc$fix_time (&mhd->mhd$l_datim) + timezone - daylight*3600; +#endif + + for (i = 0; i < module->dsc$w_length; i++) + filename[i] = _tolower ((unsigned char)module->dsc$a_pointer[i]); + + filename[i] = '\0'; + + VMS_member_date = (time_t) -1; + + fnval = + (*VMS_function) (-1, filename, 0, 0, 0, 0, val, 0, 0, 0, + VMS_saved_memname); + + if (fnval) + { + VMS_member_date = fnval; + return 0; + } + else + return 1; +} + +/* Takes three arguments ARCHIVE, FUNCTION and ARG. + + Open the archive named ARCHIVE, find its members one by one, + and for each one call FUNCTION with the following arguments: + archive file descriptor for reading the data, + member name, + member name might be truncated flag, + member header position in file, + member data position in file, + member data size, + member date, + member uid, + member gid, + member protection mode, + ARG. + + NOTE: on VMS systems, only name, date, and arg are meaningful! + + The descriptor is poised to read the data of the member + when FUNCTION is called. It does not matter how much + data FUNCTION reads. + + If FUNCTION returns nonzero, we immediately return + what FUNCTION returned. + + Returns -1 if archive does not exist, + Returns -2 if archive has invalid format. + Returns 0 if have scanned successfully. */ + +long int +ar_scan (archive, function, arg) + char *archive; + long int (*function) (); + long int arg; +{ + char *p; + + static struct dsc$descriptor_s libdesc = + { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL }; + + unsigned long func = LBR$C_READ; + unsigned long type = LBR$C_TYP_UNK; + unsigned long index = 1; + + int status; + + status = lbr$ini_control (&VMS_lib_idx, &func, &type, 0); + + if (! (status & 1)) + { + error (NILF, _("lbr$ini_control failed with status = %d"),status); + return -2; + } + + libdesc.dsc$a_pointer = archive; + libdesc.dsc$w_length = strlen (archive); + + status = lbr$open (&VMS_lib_idx, &libdesc, 0, 0, 0, 0, 0); + + if (! (status & 1)) + { + error (NILF, _("unable to open library `%s' to lookup member `%s'"), + archive, (char *)arg); + return -1; + } + + VMS_saved_memname = (char *)arg; + + /* For comparison, delete .obj from arg name. */ + + p = strrchr (VMS_saved_memname, '.'); + if (p) + *p = '\0'; + + VMS_function = function; + + VMS_member_date = (time_t) -1; + lbr$get_index (&VMS_lib_idx, &index, VMS_get_member_info, 0); + + /* Undo the damage. */ + if (p) + *p = '.'; + + lbr$close (&VMS_lib_idx); + + return VMS_member_date > 0 ? VMS_member_date : 0; +} + +#else /* !VMS */ + +/* SCO Unix's compiler defines both of these. */ +#ifdef M_UNIX +#undef M_XENIX +#endif + +/* On the sun386i and in System V rel 3, ar.h defines two different archive + formats depending upon whether you have defined PORTAR (normal) or PORT5AR + (System V Release 1). There is no default, one or the other must be defined + to have a nonzero value. */ + +#if (!defined (PORTAR) || PORTAR == 0) && (!defined (PORT5AR) || PORT5AR == 0) +#undef PORTAR +#ifdef M_XENIX +/* According to Jim Sievert , for SCO XENIX defining + PORTAR to 1 gets the wrong archive format, and defining it to 0 gets the + right one. */ +#define PORTAR 0 +#else +#define PORTAR 1 +#endif +#endif + +/* On AIX, define these symbols to be sure to get both archive formats. + AIX 4.3 introduced the "big" archive format to support 64-bit object + files, so on AIX 4.3 systems we need to support both the "normal" and + "big" archive formats. An archive's format is indicated in the + "fl_magic" field of the "FL_HDR" structure. For a normal archive, + this field will be the string defined by the AIAMAG symbol. For a + "big" archive, it will be the string defined by the AIAMAGBIG symbol + (at least on AIX it works this way). + + Note: we'll define these symbols regardless of which AIX version + we're compiling on, but this is okay since we'll use the new symbols + only if they're present. */ +#ifdef _AIX +# define __AR_SMALL__ +# define __AR_BIG__ +#endif + +#ifndef WINDOWS32 +# ifndef __BEOS__ +# include +# else + /* BeOS 5 doesn't have but has archives in the same format + * as many other Unices. This was taken from GNU binutils for BeOS. + */ +# define ARMAG "!\n" /* String that begins an archive file. */ +# define SARMAG 8 /* Size of that string. */ +# define ARFMAG "`\n" /* String in ar_fmag at end of each header. */ +struct ar_hdr + { + char ar_name[16]; /* Member file name, sometimes / terminated. */ + char ar_date[12]; /* File date, decimal seconds since Epoch. */ + char ar_uid[6], ar_gid[6]; /* User and group IDs, in ASCII decimal. */ + char ar_mode[8]; /* File mode, in ASCII octal. */ + char ar_size[10]; /* File size, in ASCII decimal. */ + char ar_fmag[2]; /* Always contains ARFMAG. */ + }; +# endif +#else +/* These should allow us to read Windows (VC++) libraries (according to Frank + * Libbrecht ) + */ +# include +# include +# include +# define ARMAG IMAGE_ARCHIVE_START +# define SARMAG IMAGE_ARCHIVE_START_SIZE +# define ar_hdr _IMAGE_ARCHIVE_MEMBER_HEADER +# define ar_name Name +# define ar_mode Mode +# define ar_size Size +# define ar_date Date +# define ar_uid UserID +# define ar_gid GroupID +#endif + +/* Cray's apparently defines this. */ +#ifndef AR_HDR_SIZE +# define AR_HDR_SIZE (sizeof (struct ar_hdr)) +#endif + +/* Takes three arguments ARCHIVE, FUNCTION and ARG. + + Open the archive named ARCHIVE, find its members one by one, + and for each one call FUNCTION with the following arguments: + archive file descriptor for reading the data, + member name, + member name might be truncated flag, + member header position in file, + member data position in file, + member data size, + member date, + member uid, + member gid, + member protection mode, + ARG. + + The descriptor is poised to read the data of the member + when FUNCTION is called. It does not matter how much + data FUNCTION reads. + + If FUNCTION returns nonzero, we immediately return + what FUNCTION returned. + + Returns -1 if archive does not exist, + Returns -2 if archive has invalid format. + Returns 0 if have scanned successfully. */ + +long int +ar_scan (archive, function, arg) + char *archive; + long int (*function) (); + long int arg; +{ +#ifdef AIAMAG + FL_HDR fl_header; +#ifdef AIAMAGBIG + int big_archive = 0; + FL_HDR_BIG fl_header_big; +#endif +#else + int long_name = 0; +#endif + char *namemap = 0; + register int desc = open (archive, O_RDONLY, 0); + if (desc < 0) + return -1; +#ifdef SARMAG + { + char buf[SARMAG]; + register int nread = read (desc, buf, SARMAG); + if (nread != SARMAG || bcmp (buf, ARMAG, SARMAG)) + { + (void) close (desc); + return -2; + } + } +#else +#ifdef AIAMAG + { + register int nread = read (desc, (char *) &fl_header, FL_HSZ); + + if (nread != FL_HSZ) + { + (void) close (desc); + return -2; + } +#ifdef AIAMAGBIG + /* If this is a "big" archive, then set the flag and + re-read the header into the "big" structure. */ + if (!bcmp (fl_header.fl_magic, AIAMAGBIG, SAIAMAG)) + { + big_archive = 1; + + /* seek back to beginning of archive */ + if (lseek (desc, 0, 0) < 0) + { + (void) close (desc); + return -2; + } + + /* re-read the header into the "big" structure */ + nread = read (desc, (char *) &fl_header_big, FL_HSZ_BIG); + if (nread != FL_HSZ_BIG) + { + (void) close (desc); + return -2; + } + } + else +#endif + /* Check to make sure this is a "normal" archive. */ + if (bcmp (fl_header.fl_magic, AIAMAG, SAIAMAG)) + { + (void) close (desc); + return -2; + } + } +#else + { +#ifndef M_XENIX + int buf; +#else + unsigned short int buf; +#endif + register int nread = read(desc, &buf, sizeof (buf)); + if (nread != sizeof (buf) || buf != ARMAG) + { + (void) close (desc); + return -2; + } + } +#endif +#endif + + /* Now find the members one by one. */ + { +#ifdef SARMAG + register long int member_offset = SARMAG; +#else +#ifdef AIAMAG + long int member_offset; + long int last_member_offset; + +#ifdef AIAMAGBIG + if ( big_archive ) + { + sscanf (fl_header_big.fl_fstmoff, "%20ld", &member_offset); + sscanf (fl_header_big.fl_lstmoff, "%20ld", &last_member_offset); + } + else +#endif + { + sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset); + sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset); + } + + if (member_offset == 0) + { + /* Empty archive. */ + close (desc); + return 0; + } +#else +#ifndef M_XENIX + register long int member_offset = sizeof (int); +#else /* Xenix. */ + register long int member_offset = sizeof (unsigned short int); +#endif /* Not Xenix. */ +#endif +#endif + + while (1) + { + register int nread; + struct ar_hdr member_header; +#ifdef AIAMAGBIG + struct ar_hdr_big member_header_big; +#endif +#ifdef AIAMAG + char name[256]; + int name_len; + long int dateval; + int uidval, gidval; + long int data_offset; +#else + char namebuf[sizeof member_header.ar_name + 1]; + char *name; + int is_namemap; /* Nonzero if this entry maps long names. */ +#endif + long int eltsize; + int eltmode; + long int fnval; + + if (lseek (desc, member_offset, 0) < 0) + { + (void) close (desc); + return -2; + } + +#ifdef AIAMAG +#define AR_MEMHDR_SZ(x) (sizeof(x) - sizeof (x._ar_name)) + +#ifdef AIAMAGBIG + if (big_archive) + { + nread = read (desc, (char *) &member_header_big, + AR_MEMHDR_SZ(member_header_big) ); + + if (nread != AR_MEMHDR_SZ(member_header_big)) + { + (void) close (desc); + return -2; + } + + sscanf (member_header_big.ar_namlen, "%4d", &name_len); + nread = read (desc, name, name_len); + + if (nread != name_len) + { + (void) close (desc); + return -2; + } + + name[name_len] = 0; + + sscanf (member_header_big.ar_date, "%12ld", &dateval); + sscanf (member_header_big.ar_uid, "%12d", &uidval); + sscanf (member_header_big.ar_gid, "%12d", &gidval); + sscanf (member_header_big.ar_mode, "%12o", &eltmode); + sscanf (member_header_big.ar_size, "%20ld", &eltsize); + + data_offset = (member_offset + AR_MEMHDR_SZ(member_header_big) + + name_len + 2); + } + else +#endif + { + nread = read (desc, (char *) &member_header, + AR_MEMHDR_SZ(member_header) ); + + if (nread != AR_MEMHDR_SZ(member_header)) + { + (void) close (desc); + return -2; + } + + sscanf (member_header.ar_namlen, "%4d", &name_len); + nread = read (desc, name, name_len); + + if (nread != name_len) + { + (void) close (desc); + return -2; + } + + name[name_len] = 0; + + sscanf (member_header.ar_date, "%12ld", &dateval); + sscanf (member_header.ar_uid, "%12d", &uidval); + sscanf (member_header.ar_gid, "%12d", &gidval); + sscanf (member_header.ar_mode, "%12o", &eltmode); + sscanf (member_header.ar_size, "%12ld", &eltsize); + + data_offset = (member_offset + AR_MEMHDR_SZ(member_header) + + name_len + 2); + } + data_offset += data_offset % 2; + + fnval = + (*function) (desc, name, 0, + member_offset, data_offset, eltsize, + dateval, uidval, gidval, + eltmode, arg); + +#else /* Not AIAMAG. */ + nread = read (desc, (char *) &member_header, AR_HDR_SIZE); + if (nread == 0) + /* No data left means end of file; that is OK. */ + break; + + if (nread != AR_HDR_SIZE +#if defined(ARFMAG) || defined(ARFZMAG) + || ( +# ifdef ARFMAG + bcmp (member_header.ar_fmag, ARFMAG, 2) +# else + 1 +# endif + && +# ifdef ARFZMAG + bcmp (member_header.ar_fmag, ARFZMAG, 2) +# else + 1 +# endif + ) +#endif + ) + { + (void) close (desc); + return -2; + } + + name = namebuf; + bcopy (member_header.ar_name, name, sizeof member_header.ar_name); + { + register char *p = name + sizeof member_header.ar_name; + do + *p = '\0'; + while (p > name && *--p == ' '); + +#ifndef AIAMAG + /* If the member name is "//" or "ARFILENAMES/" this may be + a list of file name mappings. The maximum file name + length supported by the standard archive format is 14 + characters. This member will actually always be the + first or second entry in the archive, but we don't check + that. */ + is_namemap = (!strcmp (name, "//") + || !strcmp (name, "ARFILENAMES/")); +#endif /* Not AIAMAG. */ + /* On some systems, there is a slash after each member name. */ + if (*p == '/') + *p = '\0'; + +#ifndef AIAMAG + /* If the member name starts with a space or a slash, this + is an index into the file name mappings (used by GNU ar). + Otherwise if the member name looks like #1/NUMBER the + real member name appears in the element data (used by + 4.4BSD). */ + if (! is_namemap + && (name[0] == ' ' || name[0] == '/') + && namemap != 0) + { + name = namemap + atoi (name + 1); + long_name = 1; + } + else if (name[0] == '#' + && name[1] == '1' + && name[2] == '/') + { + int namesize = atoi (name + 3); + + name = (char *) alloca (namesize + 1); + nread = read (desc, name, namesize); + if (nread != namesize) + { + close (desc); + return -2; + } + name[namesize] = '\0'; + + long_name = 1; + } +#endif /* Not AIAMAG. */ + } + +#ifndef M_XENIX + sscanf (member_header.ar_mode, "%o", &eltmode); + eltsize = atol (member_header.ar_size); +#else /* Xenix. */ + eltmode = (unsigned short int) member_header.ar_mode; + eltsize = member_header.ar_size; +#endif /* Not Xenix. */ + + fnval = + (*function) (desc, name, ! long_name, member_offset, + member_offset + AR_HDR_SIZE, eltsize, +#ifndef M_XENIX + atol (member_header.ar_date), + atoi (member_header.ar_uid), + atoi (member_header.ar_gid), +#else /* Xenix. */ + member_header.ar_date, + member_header.ar_uid, + member_header.ar_gid, +#endif /* Not Xenix. */ + eltmode, arg); + +#endif /* AIAMAG. */ + + if (fnval) + { + (void) close (desc); + return fnval; + } + +#ifdef AIAMAG + if (member_offset == last_member_offset) + /* End of the chain. */ + break; + +#ifdef AIAMAGBIG + if (big_archive) + sscanf (member_header_big.ar_nxtmem, "%20ld", &member_offset); + else +#endif + sscanf (member_header.ar_nxtmem, "%12ld", &member_offset); + + if (lseek (desc, member_offset, 0) != member_offset) + { + (void) close (desc); + return -2; + } +#else + + /* If this member maps archive names, we must read it in. The + name map will always precede any members whose names must + be mapped. */ + if (is_namemap) + { + char *clear; + char *limit; + + namemap = (char *) alloca (eltsize); + nread = read (desc, namemap, eltsize); + if (nread != eltsize) + { + (void) close (desc); + return -2; + } + + /* The names are separated by newlines. Some formats have + a trailing slash. Null terminate the strings for + convenience. */ + limit = namemap + eltsize; + for (clear = namemap; clear < limit; clear++) + { + if (*clear == '\n') + { + *clear = '\0'; + if (clear[-1] == '/') + clear[-1] = '\0'; + } + } + + is_namemap = 0; + } + + member_offset += AR_HDR_SIZE + eltsize; + if (member_offset % 2 != 0) + member_offset++; +#endif + } + } + + close (desc); + return 0; +} +#endif /* !VMS */ + +/* Return nonzero iff NAME matches MEM. + If TRUNCATED is nonzero, MEM may be truncated to + sizeof (struct ar_hdr.ar_name) - 1. */ + +int +ar_name_equal (name, mem, truncated) + char *name, *mem; + int truncated; +{ + char *p; + + p = strrchr (name, '/'); + if (p != 0) + name = p + 1; + +#ifndef VMS + if (truncated) + { +#ifdef AIAMAG + /* TRUNCATED should never be set on this system. */ + abort (); +#else + struct ar_hdr hdr; +#if !defined (__hpux) && !defined (cray) + return strneq (name, mem, sizeof(hdr.ar_name) - 1); +#else + return strneq (name, mem, sizeof(hdr.ar_name) - 2); +#endif /* !__hpux && !cray */ +#endif /* !AIAMAG */ + } +#endif /* !VMS */ + + return !strcmp (name, mem); +} + +#ifndef VMS +/* ARGSUSED */ +static long int +ar_member_pos (desc, mem, truncated, + hdrpos, datapos, size, date, uid, gid, mode, name) + int desc; + char *mem; + int truncated; + long int hdrpos, datapos, size, date; + int uid, gid, mode; + char *name; +{ + if (!ar_name_equal (name, mem, truncated)) + return 0; + return hdrpos; +} + +/* Set date of member MEMNAME in archive ARNAME to current time. + Returns 0 if successful, + -1 if file ARNAME does not exist, + -2 if not a valid archive, + -3 if other random system call error (including file read-only), + 1 if valid but member MEMNAME does not exist. */ + +int +ar_member_touch (arname, memname) + char *arname, *memname; +{ + register long int pos = ar_scan (arname, ar_member_pos, (long int) memname); + register int fd; + struct ar_hdr ar_hdr; + register int i; + struct stat statbuf; + + if (pos < 0) + return (int) pos; + if (!pos) + return 1; + + fd = open (arname, O_RDWR, 0666); + if (fd < 0) + return -3; + /* Read in this member's header */ + if (lseek (fd, pos, 0) < 0) + goto lose; + if (AR_HDR_SIZE != read (fd, (char *) &ar_hdr, AR_HDR_SIZE)) + goto lose; + /* Write back the header, thus touching the archive file. */ + if (lseek (fd, pos, 0) < 0) + goto lose; + if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE)) + goto lose; + /* The file's mtime is the time we we want. */ + if (fstat (fd, &statbuf) < 0) + goto lose; +#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32) + /* Advance member's time to that time */ + for (i = 0; i < sizeof ar_hdr.ar_date; i++) + ar_hdr.ar_date[i] = ' '; + sprintf (ar_hdr.ar_date, "%ld", (long int) statbuf.st_mtime); +#ifdef AIAMAG + ar_hdr.ar_date[strlen(ar_hdr.ar_date)] = ' '; +#endif +#else + ar_hdr.ar_date = statbuf.st_mtime; +#endif + /* Write back this member's header */ + if (lseek (fd, pos, 0) < 0) + goto lose; + if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE)) + goto lose; + close (fd); + return 0; + + lose: + i = errno; + close (fd); + errno = i; + return -3; +} +#endif + +#ifdef TEST + +long int +describe_member (desc, name, truncated, + hdrpos, datapos, size, date, uid, gid, mode) + int desc; + char *name; + int truncated; + long int hdrpos, datapos, size, date; + int uid, gid, mode; +{ + extern char *ctime (); + + printf (_("Member `%s'%s: %ld bytes at %ld (%ld).\n"), + name, truncated ? _(" (name might be truncated)") : "", + size, hdrpos, datapos); + printf (_(" Date %s"), ctime (&date)); + printf (_(" uid = %d, gid = %d, mode = 0%o.\n"), uid, gid, mode); + + return 0; +} + +main (argc, argv) + int argc; + char **argv; +{ + ar_scan (argv[1], describe_member); + return 0; +} + +#endif /* TEST. */ + +#endif /* NO_ARCHIVES. */ diff --git a/src/make-3.80/build.sh.in b/src/make-3.80/build.sh.in new file mode 100755 index 00000000..b8a925f8 --- /dev/null +++ b/src/make-3.80/build.sh.in @@ -0,0 +1,80 @@ +#!/bin/sh +# Shell script to build GNU Make in the absence of any `make' program. +# @configure_input@ + +# Copyright (C) 1993, 1994, 1997 Free Software Foundation, Inc. +# This file is part of GNU Make. +# +# GNU Make is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU Make 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Make; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# See Makefile.in for comments describing these variables. + +srcdir='@srcdir@' +CC='@CC@' +CFLAGS='@CFLAGS@' +CPPFLAGS='@CPPFLAGS@' +LDFLAGS='@LDFLAGS@' +ALLOCA='@ALLOCA@' +LOADLIBES='@LIBS@' +extras='@LIBOBJS@' +REMOTE='@REMOTE@' +GLOBLIB='@GLOBLIB@' + +# Common prefix for machine-independent installed files. +prefix='@prefix@' +# Common prefix for machine-dependent installed files. +exec_prefix=`eval echo @exec_prefix@` +# Directory to find libraries in for `-lXXX'. +libdir=${exec_prefix}/lib +# Directory to search by default for included makefiles. +includedir=${prefix}/include + +localedir=${prefix}/share/locale +aliaspath=${localedir}:. + +defines="-DALIASPATH=\"${aliaspath}\" -DLOCALEDIR=\"${localedir}\" -DLIBDIR=\"${libdir}\" -DINCLUDEDIR=\"${includedir}\""' @DEFS@' + +# Exit as soon as any command fails. +set -e + +# These are all the objects we need to link together. +objs="ar.o arscan.o commands.o default.o dir.o expand.o file.o function.o getopt.o getopt1.o implicit.o job.o main.o misc.o read.o remake.o rule.o signame.o variable.o version.o vpath.o hash.o remote-${REMOTE}.o ${extras} ${ALLOCA}" + +if [ x"$GLOBLIB" != x ]; then + objs="$objs glob/fnmatch.o glob/glob.o" + globinc=-I${srcdir}/glob +fi + +# Compile the source files into those objects. +for file in `echo ${objs} | sed 's/\.o/.c/g'`; do + echo compiling ${file}... + $CC $defines $CPPFLAGS $CFLAGS \ + -c -I. -I${srcdir} ${globinc} ${srcdir}/$file +done + +# The object files were actually all put in the current directory. +# Remove the source directory names from the list. +srcobjs="$objs" +objs= +for obj in $srcobjs; do + objs="$objs `basename $obj`" +done + +# Link all the objects together. +echo linking make... +$CC $LDFLAGS $objs $LOADLIBES -o make.new +echo done +mv -f make.new make diff --git a/src/make-3.80/build_w32.bat b/src/make-3.80/build_w32.bat new file mode 100755 index 00000000..559fe8d3 --- /dev/null +++ b/src/make-3.80/build_w32.bat @@ -0,0 +1,138 @@ +set make=gnumake ++if not exist config.h copy config.h.W32 config.h +cd w32\subproc +echo "Creating the subproc library" +%ComSpec% /c build.bat +cd ..\.. +del link.dbg link.rel +del config.h +copy config.h.W32 config.h +echo off +echo "Creating GNU make for Windows 95/NT" +echo on +if not exist .\WinDebug\nul mkdir .\WinDebug +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D TIVOLI /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c variable.c +echo WinDebug\variable.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c rule.c +echo WinDebug\rule.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c remote-stub.c +echo WinDebug\remote-stub.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c commands.c +echo WinDebug\commands.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c file.c +echo WinDebug\file.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getloadavg.c +echo WinDebug\getloadavg.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c default.c +echo WinDebug\default.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c signame.c +echo WinDebug\signame.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c expand.c +echo WinDebug\expand.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c dir.c +echo WinDebug\dir.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c main.c +echo WinDebug\main.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getopt1.c +echo WinDebug\getopt1.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c job.c +echo WinDebug\job.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c read.c +echo WinDebug\read.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c version.c +echo WinDebug\version.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c getopt.c +echo WinDebug\getopt.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c arscan.c +echo WinDebug\arscan.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c remake.c +echo WinDebug\remake.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c misc.c +echo WinDebug\misc.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c ar.c +echo WinDebug\ar.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c function.c +echo WinDebug\function.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c vpath.c +echo WinDebug\vpath.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c implicit.c +echo WinDebug\implicit.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\compat\dirent.c +echo WinDebug\dirent.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\glob.c +echo WinDebug\glob.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\glob\fnmatch.c +echo WinDebug\fnmatch.obj >>link.dbg +cl.exe /nologo /MT /W3 /GX /Zi /YX /Od /I . /I glob /I w32/include /D _DEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinDebug/ /Fp.\WinDebug/%make%.pch /Fo.\WinDebug/ /Fd.\WinDebug/%make%.pdb /c .\w32\pathstuff.c +echo WinDebug\pathstuff.obj >>link.dbg +echo off +echo "Linking WinDebug/%make%.exe" +rem link.exe kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /MACHINE:I386 /OUT:.\WinDebug/%make%.exe .\WinDebug/variable.obj .\WinDebug/rule.obj .\WinDebug/remote-stub.obj .\WinDebug/commands.obj .\WinDebug/file.obj .\WinDebug/getloadavg.obj .\WinDebug/default.obj .\WinDebug/signame.obj .\WinDebug/expand.obj .\WinDebug/dir.obj .\WinDebug/main.obj .\WinDebug/getopt1.obj .\WinDebug/job.obj .\WinDebug/read.obj .\WinDebug/version.obj .\WinDebug/getopt.obj .\WinDebug/arscan.obj .\WinDebug/remake.obj .\WinDebug/misc.obj .\WinDebug/ar.obj .\WinDebug/function.obj .\WinDebug/vpath.obj .\WinDebug/implicit.obj .\WinDebug/dirent.obj .\WinDebug/glob.obj .\WinDebug/fnmatch.obj .\WinDebug/pathstuff.obj +echo kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib >>link.dbg +link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:.\WinDebug/%make%.pdb /DEBUG /MACHINE:I386 /OUT:.\WinDebug/%make%.exe @link.dbg +if not exist .\WinDebug/%make%.exe echo "WinDebug build failed" +if exist .\WinDebug/%make%.exe echo "WinDebug build succeeded!" +if not exist .\WinRel\nul mkdir .\WinRel +echo on +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /D TIVOLI /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c variable.c +echo WinRel\variable.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c rule.c +echo WinRel\rule.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c remote-stub.c +echo WinRel\remote-stub.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c commands.c +echo WinRel\commands.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c file.c +echo WinRel\file.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getloadavg.c +echo WinRel\getloadavg.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c default.c +echo WinRel\default.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c signame.c +echo WinRel\signame.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c expand.c +echo WinRel\expand.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c dir.c +echo WinRel\dir.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c main.c +echo WinRel\main.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getopt1.c +echo WinRel\getopt1.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c job.c +echo WinRel\job.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c read.c +echo WinRel\read.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c version.c +echo WinRel\version.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c getopt.c +echo WinRel\getopt.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c arscan.c +echo WinRel\arscan.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c remake.c +echo WinRel\remake.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c misc.c +echo WinRel\misc.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c ar.c +echo WinRel\ar.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c function.c +echo WinRel\function.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c vpath.c +echo WinRel\vpath.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c implicit.c +echo WinRel\implicit.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\compat\dirent.c +echo WinRel\dirent.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\glob.c +echo WinRel\glob.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\glob\fnmatch.c +echo WinRel\fnmatch.obj >>link.rel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I . /I glob /I w32/include /D NDEBUG /D WINDOWS32 /D WIN32 /D _CONSOLE /D HAVE_CONFIG_H /FR.\WinRel/ /Fp.\WinRel/%make%.pch /Fo.\WinRel/ /c .\w32\pathstuff.c +echo WinRel\pathstuff.obj >>link.rel +echo off +echo "Linking WinRel/%make%.exe" +rem link.exe kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /MACHINE:I386 /OUT:.\WinRel/%make%.exe .\WinRel/variable.obj .\WinRel/rule.obj .\WinRel/remote-stub.obj .\WinRel/commands.obj .\WinRel/file.obj .\WinRel/getloadavg.obj .\WinRel/default.obj .\WinRel/signame.obj .\WinRel/expand.obj .\WinRel/dir.obj .\WinRel/main.obj .\WinRel/getopt1.obj .\WinRel/job.obj .\WinRel/read.obj .\WinRel/version.obj .\WinRel/getopt.obj .\WinRel/arscan.obj .\WinRel/remake.obj .\WinRel/misc.obj .\WinRel/ar.obj .\WinRel/function.obj .\WinRel/vpath.obj .\WinRel/implicit.obj .\WinRel/dirent.obj .\WinRel/glob.obj .\WinRel/fnmatch.obj .\WinRel/pathstuff.obj +echo kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\winrel\subproc.lib >>link.rel +link.exe /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:.\WinRel/%make%.pdb /MACHINE:I386 /OUT:.\WinRel/%make%.exe @link.rel +if not exist .\WinRel/%make%.exe echo "WinRel build failed" +if exist .\WinRel/%make%.exe echo "WinRel build succeeded!" +echo on diff --git a/src/make-3.80/commands.c b/src/make-3.80/commands.c new file mode 100755 index 00000000..84b58de5 --- /dev/null +++ b/src/make-3.80/commands.c @@ -0,0 +1,584 @@ +/* Command processing for GNU Make. +Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "dep.h" +#include "filedef.h" +#include "variable.h" +#include "job.h" +#include "commands.h" + +#if VMS +# define FILE_LIST_SEPARATOR ',' +#else +# define FILE_LIST_SEPARATOR ' ' +#endif + +extern int remote_kill PARAMS ((int id, int sig)); + +#ifndef HAVE_UNISTD_H +extern int getpid (); +#endif + +/* Set FILE's automatic variables up. */ + +static void +set_file_variables (file) + register struct file *file; +{ + char *at, *percent, *star, *less; + +#ifndef NO_ARCHIVES + /* If the target is an archive member `lib(member)', + then $@ is `lib' and $% is `member'. */ + + if (ar_name (file->name)) + { + unsigned int len; + char *p; + + p = strchr (file->name, '('); + at = (char *) alloca (p - file->name + 1); + bcopy (file->name, at, p - file->name); + at[p - file->name] = '\0'; + len = strlen (p + 1); + percent = (char *) alloca (len); + bcopy (p + 1, percent, len - 1); + percent[len - 1] = '\0'; + } + else +#endif /* NO_ARCHIVES. */ + { + at = file->name; + percent = ""; + } + + /* $* is the stem from an implicit or static pattern rule. */ + if (file->stem == 0) + { + /* In Unix make, $* is set to the target name with + any suffix in the .SUFFIXES list stripped off for + explicit rules. We store this in the `stem' member. */ + register struct dep *d; + char *name; + unsigned int len; + +#ifndef NO_ARCHIVES + if (ar_name (file->name)) + { + name = strchr (file->name, '(') + 1; + len = strlen (name) - 1; + } + else +#endif + { + name = file->name; + len = strlen (name); + } + + for (d = enter_file (".SUFFIXES")->deps; d != 0; d = d->next) + { + unsigned int slen = strlen (dep_name (d)); + if (len > slen && strneq (dep_name (d), name + (len - slen), slen)) + { + file->stem = savestring (name, len - slen); + break; + } + } + if (d == 0) + file->stem = ""; + } + star = file->stem; + + /* $< is the first dependency. */ + less = file->deps != 0 ? dep_name (file->deps) : ""; + + if (file->cmds == default_file->cmds) + /* This file got its commands from .DEFAULT. + In this case $< is the same as $@. */ + less = at; + +#define DEFINE_VARIABLE(name, len, value) \ + (void) define_variable_for_file (name,len,value,o_automatic,0,file) + + /* Define the variables. */ + + DEFINE_VARIABLE ("<", 1, less); + DEFINE_VARIABLE ("*", 1, star); + DEFINE_VARIABLE ("@", 1, at); + DEFINE_VARIABLE ("%", 1, percent); + + /* Compute the values for $^, $+, $?, and $|. */ + + { + unsigned int qmark_len, plus_len, bar_len; + char *caret_value, *plus_value; + char *cp; + char *qmark_value; + char *bar_value; + char *qp; + char *bp; + struct dep *d; + unsigned int len; + + /* Compute first the value for $+, which is supposed to contain + duplicate dependencies as they were listed in the makefile. */ + + plus_len = 0; + for (d = file->deps; d != 0; d = d->next) + if (! d->ignore_mtime) + plus_len += strlen (dep_name (d)) + 1; + if (plus_len == 0) + plus_len++; + + cp = plus_value = (char *) alloca (plus_len); + + qmark_len = plus_len + 1; /* Will be this or less. */ + for (d = file->deps; d != 0; d = d->next) + if (! d->ignore_mtime) + { + char *c = dep_name (d); + +#ifndef NO_ARCHIVES + if (ar_name (c)) + { + c = strchr (c, '(') + 1; + len = strlen (c) - 1; + } + else +#endif + len = strlen (c); + + bcopy (c, cp, len); + cp += len; + *cp++ = FILE_LIST_SEPARATOR; + if (! d->changed) + qmark_len -= len + 1; /* Don't space in $? for this one. */ + } + + /* Kill the last space and define the variable. */ + + cp[cp > plus_value ? -1 : 0] = '\0'; + DEFINE_VARIABLE ("+", 1, plus_value); + + /* Make sure that no dependencies are repeated. This does not + really matter for the purpose of updating targets, but it + might make some names be listed twice for $^ and $?. */ + + uniquize_deps (file->deps); + + bar_len = 0; + for (d = file->deps; d != 0; d = d->next) + if (d->ignore_mtime) + bar_len += strlen (dep_name (d)) + 1; + if (bar_len == 0) + bar_len++; + + /* Compute the values for $^, $?, and $|. */ + + cp = caret_value = plus_value; /* Reuse the buffer; it's big enough. */ + qp = qmark_value = (char *) alloca (qmark_len); + bp = bar_value = (char *) alloca (bar_len); + + for (d = file->deps; d != 0; d = d->next) + { + char *c = dep_name (d); + +#ifndef NO_ARCHIVES + if (ar_name (c)) + { + c = strchr (c, '(') + 1; + len = strlen (c) - 1; + } + else +#endif + len = strlen (c); + + if (d->ignore_mtime) + { + bcopy (c, bp, len); + bp += len; + *bp++ = FILE_LIST_SEPARATOR; + } + else + { + bcopy (c, cp, len); + cp += len; + *cp++ = FILE_LIST_SEPARATOR; + if (d->changed) + { + bcopy (c, qp, len); + qp += len; + *qp++ = FILE_LIST_SEPARATOR; + } + } + } + + /* Kill the last spaces and define the variables. */ + + cp[cp > caret_value ? -1 : 0] = '\0'; + DEFINE_VARIABLE ("^", 1, caret_value); + + qp[qp > qmark_value ? -1 : 0] = '\0'; + DEFINE_VARIABLE ("?", 1, qmark_value); + + bp[bp > bar_value ? -1 : 0] = '\0'; + DEFINE_VARIABLE ("|", 1, bar_value); + } + +#undef DEFINE_VARIABLE +} + +/* Chop CMDS up into individual command lines if necessary. + Also set the `lines_flags' and `any_recurse' members. */ + +void +chop_commands (cmds) + register struct commands *cmds; +{ + register char *p; + unsigned int nlines, idx; + char **lines; + + /* If we don't have any commands, + or we already parsed them, never mind. */ + + if (!cmds || cmds->command_lines != 0) + return; + + /* Chop CMDS->commands up into lines in CMDS->command_lines. + Also set the corresponding CMDS->lines_flags elements, + and the CMDS->any_recurse flag. */ + + nlines = 5; + lines = (char **) xmalloc (5 * sizeof (char *)); + idx = 0; + p = cmds->commands; + while (*p != '\0') + { + char *end = p; + find_end:; + end = strchr (end, '\n'); + if (end == 0) + end = p + strlen (p); + else if (end > p && end[-1] == '\\') + { + int backslash = 1; + register char *b; + for (b = end - 2; b >= p && *b == '\\'; --b) + backslash = !backslash; + if (backslash) + { + ++end; + goto find_end; + } + } + + if (idx == nlines) + { + nlines += 2; + lines = (char **) xrealloc ((char *) lines, + nlines * sizeof (char *)); + } + lines[idx++] = savestring (p, end - p); + p = end; + if (*p != '\0') + ++p; + } + + if (idx != nlines) + { + nlines = idx; + lines = (char **) xrealloc ((char *) lines, + nlines * sizeof (char *)); + } + + cmds->ncommand_lines = nlines; + cmds->command_lines = lines; + + cmds->any_recurse = 0; + cmds->lines_flags = (char *) xmalloc (nlines); + for (idx = 0; idx < nlines; ++idx) + { + int flags = 0; + + for (p = lines[idx]; + isblank ((unsigned char)*p) || *p == '-' || *p == '@' || *p == '+'; + ++p) + switch (*p) + { + case '+': + flags |= COMMANDS_RECURSE; + break; + case '@': + flags |= COMMANDS_SILENT; + break; + case '-': + flags |= COMMANDS_NOERROR; + break; + } + if (!(flags & COMMANDS_RECURSE)) + { + unsigned int len = strlen (p); + if (sindex (p, len, "$(MAKE)", 7) != 0 + || sindex (p, len, "${MAKE}", 7) != 0) + flags |= COMMANDS_RECURSE; + } + + cmds->lines_flags[idx] = flags; + cmds->any_recurse |= flags & COMMANDS_RECURSE; + } +} + +/* Execute the commands to remake FILE. If they are currently executing, + return or have already finished executing, just return. Otherwise, + fork off a child process to run the first command line in the sequence. */ + +void +execute_file_commands (file) + struct file *file; +{ + register char *p; + + /* Don't go through all the preparations if + the commands are nothing but whitespace. */ + + for (p = file->cmds->commands; *p != '\0'; ++p) + if (!isspace ((unsigned char)*p) && *p != '-' && *p != '@') + break; + if (*p == '\0') + { + /* If there are no commands, assume everything worked. */ + set_command_state (file, cs_running); + file->update_status = 0; + notice_finished_file (file); + return; + } + + /* First set the automatic variables according to this file. */ + + initialize_file_variables (file, 0); + + set_file_variables (file); + + /* Start the commands running. */ + new_job (file); +} + +/* This is set while we are inside fatal_error_signal, + so things can avoid nonreentrant operations. */ + +int handling_fatal_signal = 0; + +/* Handle fatal signals. */ + +RETSIGTYPE +fatal_error_signal (sig) + int sig; +{ +#ifdef __MSDOS__ + extern int dos_status, dos_command_running; + + if (dos_command_running) + { + /* That was the child who got the signal, not us. */ + dos_status |= (sig << 8); + return; + } + remove_intermediates (1); + exit (EXIT_FAILURE); +#else /* not __MSDOS__ */ +#ifdef _AMIGA + remove_intermediates (1); + if (sig == SIGINT) + fputs (_("*** Break.\n"), stderr); + + exit (10); +#else /* not Amiga */ + handling_fatal_signal = 1; + + /* Set the handling for this signal to the default. + It is blocked now while we run this handler. */ + signal (sig, SIG_DFL); + + /* A termination signal won't be sent to the entire + process group, but it means we want to kill the children. */ + + if (sig == SIGTERM) + { + register struct child *c; + for (c = children; c != 0; c = c->next) + if (!c->remote) + (void) kill (c->pid, SIGTERM); + } + + /* If we got a signal that means the user + wanted to kill make, remove pending targets. */ + + if (sig == SIGTERM || sig == SIGINT +#ifdef SIGHUP + || sig == SIGHUP +#endif +#ifdef SIGQUIT + || sig == SIGQUIT +#endif + ) + { + register struct child *c; + + /* Remote children won't automatically get signals sent + to the process group, so we must send them. */ + for (c = children; c != 0; c = c->next) + if (c->remote) + (void) remote_kill (c->pid, sig); + + for (c = children; c != 0; c = c->next) + delete_child_targets (c); + + /* Clean up the children. We don't just use the call below because + we don't want to print the "Waiting for children" message. */ + while (job_slots_used > 0) + reap_children (1, 0); + } + else + /* Wait for our children to die. */ + while (job_slots_used > 0) + reap_children (1, 1); + + /* Delete any non-precious intermediate files that were made. */ + + remove_intermediates (1); + +#ifdef SIGQUIT + if (sig == SIGQUIT) + /* We don't want to send ourselves SIGQUIT, because it will + cause a core dump. Just exit instead. */ + exit (EXIT_FAILURE); +#endif + + /* Signal the same code; this time it will really be fatal. The signal + will be unblocked when we return and arrive then to kill us. */ + if (kill (getpid (), sig) < 0) + pfatal_with_name ("kill"); +#endif /* not Amiga */ +#endif /* not __MSDOS__ */ +} + +/* Delete FILE unless it's precious or not actually a file (phony), + and it has changed on disk since we last stat'd it. */ + +static void +delete_target (file, on_behalf_of) + struct file *file; + char *on_behalf_of; +{ + struct stat st; + + if (file->precious || file->phony) + return; + +#ifndef NO_ARCHIVES + if (ar_name (file->name)) + { + time_t file_date = (file->last_mtime == NONEXISTENT_MTIME + ? (time_t) -1 + : (time_t) FILE_TIMESTAMP_S (file->last_mtime)); + if (ar_member_date (file->name) != file_date) + { + if (on_behalf_of) + error (NILF, _("*** [%s] Archive member `%s' may be bogus; not deleted"), + on_behalf_of, file->name); + else + error (NILF, _("*** Archive member `%s' may be bogus; not deleted"), + file->name); + } + return; + } +#endif + + if (stat (file->name, &st) == 0 + && S_ISREG (st.st_mode) + && FILE_TIMESTAMP_STAT_MODTIME (file->name, st) != file->last_mtime) + { + if (on_behalf_of) + error (NILF, _("*** [%s] Deleting file `%s'"), on_behalf_of, file->name); + else + error (NILF, _("*** Deleting file `%s'"), file->name); + if (unlink (file->name) < 0 + && errno != ENOENT) /* It disappeared; so what. */ + perror_with_name ("unlink: ", file->name); + } +} + + +/* Delete all non-precious targets of CHILD unless they were already deleted. + Set the flag in CHILD to say they've been deleted. */ + +void +delete_child_targets (child) + struct child *child; +{ + struct dep *d; + + if (child->deleted) + return; + + /* Delete the target file if it changed. */ + delete_target (child->file, (char *) 0); + + /* Also remove any non-precious targets listed in the `also_make' member. */ + for (d = child->file->also_make; d != 0; d = d->next) + delete_target (d->file, child->file->name); + + child->deleted = 1; +} + +/* Print out the commands in CMDS. */ + +void +print_commands (cmds) + register struct commands *cmds; +{ + register char *s; + + fputs (_("# commands to execute"), stdout); + + if (cmds->fileinfo.filenm == 0) + puts (_(" (built-in):")); + else + printf (_(" (from `%s', line %lu):\n"), + cmds->fileinfo.filenm, cmds->fileinfo.lineno); + + s = cmds->commands; + while (*s != '\0') + { + char *end; + + while (isspace ((unsigned char)*s)) + ++s; + + end = strchr (s, '\n'); + if (end == 0) + end = s + strlen (s); + + printf ("\t%.*s\n", (int) (end - s), s); + + s = end; + } +} diff --git a/src/make-3.80/commands.h b/src/make-3.80/commands.h new file mode 100755 index 00000000..edec9103 --- /dev/null +++ b/src/make-3.80/commands.h @@ -0,0 +1,42 @@ +/* Definition of data structures describing shell commands for GNU Make. +Copyright (C) 1988, 1989, 1991, 1993 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Structure that gives the commands to make a file + and information about where these commands came from. */ + +struct commands + { + struct floc fileinfo; /* Where commands were defined. */ + char *commands; /* Commands text. */ + unsigned int ncommand_lines;/* Number of command lines. */ + char **command_lines; /* Commands chopped up into lines. */ + char *lines_flags; /* One set of flag bits for each line. */ + int any_recurse; /* Nonzero if any `lines_recurse' elt has */ + /* the COMMANDS_RECURSE bit set. */ + }; + +/* Bits in `lines_flags'. */ +#define COMMANDS_RECURSE 1 /* Recurses: + or $(MAKE). */ +#define COMMANDS_SILENT 2 /* Silent: @. */ +#define COMMANDS_NOERROR 4 /* No errors: -. */ + +extern void execute_file_commands PARAMS ((struct file *file)); +extern void print_commands PARAMS ((struct commands *cmds)); +extern void delete_child_targets PARAMS ((struct child *child)); +extern void chop_commands PARAMS ((struct commands *cmds)); diff --git a/src/make-3.80/config.ami b/src/make-3.80/config.ami new file mode 100755 index 00000000..3431794a --- /dev/null +++ b/src/make-3.80/config.ami @@ -0,0 +1,317 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define if using alloca.c. */ +#define C_ALLOCA + +/* Define if the closedir function returns void instead of int. */ +/* #undef CLOSEDIR_VOID */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define for DGUX with . */ +/* #undef DGUX */ + +/* Define if the `getloadavg' function needs to be run setuid or setgid. */ +/* #undef GETLOADAVG_PRIVILEGED */ + +/* Define to `unsigned long' or `unsigned long long' + if doesn't define. */ +#define uintmax_t unsigned long + +/* Define to `int' if doesn't define. */ +#define gid_t int + +/* Define if you have alloca, as a function or macro. */ +/* #undef HAVE_ALLOCA */ + +/* Define if you have and it should be used (not on Ultrix). */ +/* #undef HAVE_ALLOCA_H */ + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if your system has a working fnmatch function. */ +/* #undef HAVE_FNMATCH */ + +/* Define if your system has its own `getloadavg' function. */ +/* #undef HAVE_GETLOADAVG */ + +/* Define if you have the getmntent function. */ +/* #undef HAVE_GETMNTENT */ + +/* Define if the `long double' type works. */ +/* #undef HAVE_LONG_DOUBLE */ + +/* Define if you support file names longer than 14 characters. */ +#define HAVE_LONG_FILE_NAMES 1 + +/* Define if you have a working `mmap' system call. */ +/* #undef HAVE_MMAP */ + +/* Define if system calls automatically restart after interruption + by a signal. */ +/* #undef HAVE_RESTARTABLE_SYSCALLS */ + +/* Define if your struct stat has st_blksize. */ +/* #undef HAVE_ST_BLKSIZE */ + +/* Define if your struct stat has st_blocks. */ +/* #undef HAVE_ST_BLOCKS */ + +/* Define if you have the strcoll function and it is properly defined. */ +#define HAVE_STRCOLL 1 + +/* Define if your struct stat has st_rdev. */ +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define if your struct tm has tm_zone. */ +/* #undef HAVE_TM_ZONE */ + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#define HAVE_TZNAME 1 + +/* Define if you have . */ +#define HAVE_UNISTD_H 1 + +/* Define if utime(file, NULL) sets file's timestamp to the present. */ +/* #undef HAVE_UTIME_NULL */ + +/* Define if you have . */ +/* #undef HAVE_VFORK_H */ + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define if you have the wait3 system call. */ +/* #undef HAVE_WAIT3 */ + +/* Define if on MINIX. */ +/* #undef _MINIX */ + +/* Define if your struct nlist has an n_un member. */ +/* #undef NLIST_NAME_UNION */ + +/* Define if you have . */ +/* #undef NLIST_STRUCT */ + +/* Define if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Define to `int' if doesn't define. */ +#define pid_t int + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if the setvbuf function takes the buffering type as its second + argument and the buffer pointer as the third, as on System V + before release 3. */ +/* #undef SETVBUF_REVERSED */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +#define STACK_DIRECTION -1 + +/* Define if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS + +/* Define on System V Release 4. */ +/* #undef SVR4 */ + +/* Define if `sys_siglist' is declared by . */ +/* #undef SYS_SIGLIST_DECLARED */ + +/* Define to `int' if doesn't define. */ +#define uid_t int + +/* Define for Encore UMAX. */ +/* #undef UMAX */ + +/* Define for Encore UMAX 4.3 that has + instead of . */ +/* #undef UMAX4_3 */ + +/* Define vfork as fork if vfork does not work. */ +/* #undef vfork */ + +/* Name of this package (needed by automake) */ +#define PACKAGE "make" + +/* Version of this package (needed by automake) */ +#define VERSION "3.80" + +/* Define to the name of the SCCS `get' command. */ +#define SCCS_GET "get" + +/* Define this if the SCCS `get' command understands the `-G' option. */ +/* #undef SCCS_GET_MINUS_G */ + +/* Define this to enable job server support in GNU make. */ +/* #undef MAKE_JOBSERVER */ + +/* Define to be the nanoseconds member of struct stat's st_mtim, + if it exists. */ +/* #undef ST_MTIM_NSEC */ + +/* Define this if the C library defines the variable `sys_siglist'. */ +/* #undef HAVE_SYS_SIGLIST */ + +/* Define this if the C library defines the variable `_sys_siglist'. */ +/* #undef HAVE__SYS_SIGLIST */ + +/* Define this if you have the `union wait' type in . */ +/* #undef HAVE_UNION_WAIT */ + +/* Define if you have the dup2 function. */ +/* #undef HAVE_DUP2 */ + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getgroups function. */ +/* #undef HAVE_GETGROUPS */ + +/* Define if you have the gethostbyname function. */ +/* #undef HAVE_GETHOSTBYNAME */ + +/* Define if you have the gethostname function. */ +/* #undef HAVE_GETHOSTNAME */ + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the mktemp function. */ +#define HAVE_MKTEMP 1 + +/* Define if you have the psignal function. */ +/* #undef HAVE_PSIGNAL */ + +/* Define if you have the pstat_getdynamic function. */ +/* #undef HAVE_PSTAT_GETDYNAMIC */ + +/* Define if you have the setegid function. */ +/* #undef HAVE_SETEGID */ + +/* Define if you have the seteuid function. */ +/* #undef HAVE_SETEUID */ + +/* Define if you have the setlinebuf function. */ +/* #undef HAVE_SETLINEBUF */ + +/* Define if you have the setregid function. */ +/* #undef HAVE_SETREGID */ + +/* Define if you have the setreuid function. */ +/* #undef HAVE_SETREUID */ + +/* Define if you have the sigsetmask function. */ +/* #undef HAVE_SIGSETMASK */ + +/* Define if you have the socket function. */ +/* #undef HAVE_SOCKET */ + +/* Define if you have the strcasecmp function. */ +/* #undef HAVE_STRCASECMP */ + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strsignal function. */ +/* #undef HAVE_STRSIGNAL */ + +/* Define if you have the wait3 function. */ +/* #undef HAVE_WAIT3 */ + +/* Define if you have the waitpid function. */ +/* #undef HAVE_WAITPID */ + +/* Define if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_MACH_MACH_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_MEMORY_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_STDLIB_H */ + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_DIR_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PARAM_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_TIMEB_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the dgc library (-ldgc). */ +/* #undef HAVE_LIBDGC */ + +/* Define if you have the kstat library (-lkstat). */ +/* #undef HAVE_LIBKSTAT */ + +/* Define if you have the sun library (-lsun). */ +/* #undef HAVE_LIBSUN */ + +/* Define for Case Insensitve behavior */ +#define HAVE_CASE_INSENSITIVE_FS + +/* Build host information. */ +#define MAKE_HOST "Amiga" diff --git a/src/make-3.80/config.h b/src/make-3.80/config.h new file mode 100755 index 00000000..1ba9b87e --- /dev/null +++ b/src/make-3.80/config.h @@ -0,0 +1,399 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define if the closedir function returns void instead of int. */ +/* #undef CLOSEDIR_VOID */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define for DGUX with . */ +/* #undef DGUX */ + +/* Define if the `getloadavg' function needs to be run setuid or setgid. */ +/* #undef GETLOADAVG_PRIVILEGED */ + +/* Define to `unsigned long' or `unsigned long long' + if doesn't define. */ +#define uintmax_t unsigned long + +/* Define to `int' if doesn't define. */ +#undef gid_t +#define gid_t int + +/* Define if you have alloca, as a function or macro. */ +#undef HAVE_ALLOCA +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +/* #undef HAVE_ALLOCA_H */ + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if your system has a working fnmatch function. */ +/* #undef HAVE_FNMATCH */ + +/* Define if your system has its own `getloadavg' function. */ +/* #undef HAVE_GETLOADAVG */ + +/* Define if you have the getmntent function. */ +/* #undef HAVE_GETMNTENT */ + +/* Define if the `long double' type works. */ +/* #undef HAVE_LONG_DOUBLE */ + +/* Define if you support file names longer than 14 characters. */ +#undef HAVE_LONG_FILE_NAMES +#define HAVE_LONG_FILE_NAMES 1 + +/* Define if you have a working `mmap' system call. */ +/* #undef HAVE_MMAP */ + +/* Define if system calls automatically restart after interruption + by a signal. */ +/* #undef HAVE_RESTARTABLE_SYSCALLS */ + +/* Define if your struct stat has st_blksize. */ +/* #undef HAVE_ST_BLKSIZE */ + +/* Define if your struct stat has st_blocks. */ +/* #undef HAVE_ST_BLOCKS */ + +/* Define if you have the strcoll function and it is properly defined. */ +#undef HAVE_STRCOLL +#define HAVE_STRCOLL 1 + +/* Define if your struct stat has st_rdev. */ +#undef HAVE_ST_RDEV +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#undef HAVE_STRFTIME +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define if your struct tm has tm_zone. */ +/* #undef HAVE_TM_ZONE */ + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#undef HAVE_TZNAME +#define HAVE_TZNAME 1 + +/* Define if you have . */ +/* #undef HAVE_UNISTD_H */ + +/* Define if utime(file, NULL) sets file's timestamp to the present. */ +#undef HAVE_UTIME_NULL +#define HAVE_UTIME_NULL 1 + +/* Define if you have . */ +/* #undef HAVE_VFORK_H */ + +/* Define if you have the vprintf function. */ +#undef HAVE_VPRINTF +#define HAVE_VPRINTF 1 + +/* Define if you have the wait3 system call. */ +/* #undef HAVE_WAIT3 */ + +/* Define if on MINIX. */ +/* #undef _MINIX */ + +/* Define if your struct nlist has an n_un member. */ +/* #undef NLIST_NAME_UNION */ + +/* Define if you have . */ +/* #undef NLIST_STRUCT */ + +/* Define if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Define to `int' if doesn't define. */ +#undef pid_t +#define pid_t int + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +#undef _POSIX_SOURCE +#define _POSIX_SOURCE 1 + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE +#define RETSIGTYPE void + +/* Define if the setvbuf function takes the buffering type as its second + argument and the buffer pointer as the third, as on System V + before release 3. */ +/* #undef SETVBUF_REVERSED */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS +#define STDC_HEADERS 1 + +/* Define on System V Release 4. */ +/* #undef SVR4 */ + +/* Define if `sys_siglist' is declared by . */ +/* #undef SYS_SIGLIST_DECLARED */ + +/* Define to `int' if doesn't define. */ +#undef uid_t +#define uid_t int + +/* Define for Encore UMAX. */ +/* #undef UMAX */ + +/* Define for Encore UMAX 4.3 that has + instead of . */ +/* #undef UMAX4_3 */ + +/* Define vfork as fork if vfork does not work. */ +/* #undef vfork */ + +/* Name of this package (needed by automake) */ +#define PACKAGE "make" + +/* Version of this package (needed by automake) */ +#define VERSION "3.80" + +/* Define to the name of the SCCS `get' command. */ +#undef SCCS_GET +#define SCCS_GET "echo no sccs get" + +/* Define to 1 if NLS is requested. */ +/* #undef ENABLE_NLS */ + +/* Define as 1 if you have dcgettext. */ +/* #undef HAVE_DCGETTEXT */ + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +/* #undef HAVE_GETTEXT */ + +/* Define if your locale.h file contains LC_MESSAGES. */ +/* #undef HAVE_LC_MESSAGES */ + +/* Define to the installation directory for locales. */ +#define LOCALEDIR "" + +/* Define this if the SCCS `get' command understands the `-G' option. */ +/* #undef SCCS_GET_MINUS_G */ + +/* Define this to enable job server support in GNU make. */ +/* #undef MAKE_JOBSERVER */ + +/* Define to be the nanoseconds member of struct stat's st_mtim, + if it exists. */ +/* #undef ST_MTIM_NSEC */ + +/* Define this if the C library defines the variable `sys_siglist'. */ +/* #undef HAVE_SYS_SIGLIST */ + +/* Define this if the C library defines the variable `_sys_siglist'. */ +/* #undef HAVE__SYS_SIGLIST */ + +/* Define this if you have the `union wait' type in . */ +/* #undef HAVE_UNION_WAIT */ + +/* Define if you have the dup2 function. */ +#undef HAVE_DUP2 +#define HAVE_DUP2 1 + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD +#define HAVE_GETCWD 1 + +/* Define if you have the getgroups function. */ +/* #undef HAVE_GETGROUPS */ + +/* Define if you have the gethostbyname function. */ +/* #undef HAVE_GETHOSTBYNAME */ + +/* Define if you have the gethostname function. */ +/* #undef HAVE_GETHOSTNAME */ + +/* Define if you have the getloadavg function. */ +/* #undef HAVE_GETLOADAVG */ + +/* Define if you have the memmove function. */ +#undef HAVE_MEMMOVE +#define HAVE_MEMMOVE 1 + +/* Define if you have the mktemp function. */ +#undef HAVE_MKTEMP +#define HAVE_MKTEMP 1 + +/* Define if you have the psignal function. */ +/* #undef HAVE_PSIGNAL */ + +/* Define if you have the pstat_getdynamic function. */ +/* #undef HAVE_PSTAT_GETDYNAMIC */ + +/* Define if you have the setegid function. */ +/* #undef HAVE_SETEGID */ + +/* Define if you have the seteuid function. */ +/* #undef HAVE_SETEUID */ + +/* Define if you have the setlinebuf function. */ +/* #undef HAVE_SETLINEBUF */ + +/* Define if you have the setregid function. */ +/* #undef HAVE_SETREGID */ + +/* Define if you have the setreuid function. */ +/* #undef HAVE_SETREUID */ + +/* Define if you have the sigsetmask function. */ +/* #undef HAVE_SIGSETMASK */ + +/* Define if you have the socket function. */ +/* #undef HAVE_SOCKET */ + +/* Define if you have the strcasecmp function. */ +/* #undef HAVE_STRCASECMP */ + +/* Define if you have the strerror function. */ +#undef HAVE_STRERROR +#define HAVE_STRERROR 1 + +/* Define if you have the strsignal function. */ +/* #undef HAVE_STRSIGNAL */ + +/* Define if you have the wait3 function. */ +/* #undef HAVE_WAIT3 */ + +/* Define if you have the waitpid function. */ +/* #undef HAVE_WAITPID */ + +/* Define if you have the header file. */ +#undef HAVE_DIRENT_H +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_MACH_MACH_H */ + +/* Define if you have the header file. */ +#undef HAVE_MEMORY_H +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the header file. */ +#undef HAVE_STRING_H +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PARAM_H */ + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIMEB_H +#define HAVE_SYS_TIMEB_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_UNISTD_H */ + +/* Define if you have the dgc library (-ldgc). */ +/* #undef HAVE_LIBDGC */ + +/* Define if you have the kstat library (-lkstat). */ +/* #undef HAVE_LIBKSTAT */ + +/* Define if you have the sun library (-lsun). */ +/* #undef HAVE_LIBSUN */ + +/* Use high resolution file timestamps if nonzero. */ +#define FILE_TIMESTAMP_HI_RES 0 + +/* Build host information. */ +#define MAKE_HOST "Windows32" + +/* Grok DOS paths (drive specs and backslash path element separators) */ +#define HAVE_DOS_PATHS + +/* + * Refer to README.W32 for info on the following settings + */ + +/* + * If you have a shell that does not grok 'sh -c quoted-command-line' + * correctly, you need this setting. Please see below for specific + * shell support. + */ +#undef BATCH_MODE_ONLY_SHELL +#define BATCH_MODE_ONLY_SHELL 1 + +/* + * Define if you have the Cygnus "Cygwin" GNU Windows32 tool set. + * Do NOT define BATCH_MODE_ONLY_SHELL if you define HAVE_CYGWIN_SHELL + */ +#undef HAVE_CYGWIN_SHELL + +/* + * Define if you have the MKS tool set or shell. Do NOT define + * BATCH_MODE_ONLY_SHELL if you define HAVE_MKS_SHELL + */ +#undef HAVE_MKS_SHELL + +/* + * Enforce the mutual exclusivity restriction. + */ +#ifdef HAVE_MKS_SHELL +#undef BATCH_MODE_ONLY_SHELL +#endif + +#ifdef HAVE_CYGWIN_SHELL +#undef BATCH_MODE_ONLY_SHELL +#endif + +/* Define if you prefer Case Insensitive behavior */ +#undef HAVE_CASE_INSENSITIVE_FS diff --git a/src/make-3.80/config.h-vms b/src/make-3.80/config.h-vms new file mode 100755 index 00000000..19f80765 --- /dev/null +++ b/src/make-3.80/config.h-vms @@ -0,0 +1,403 @@ +/* config.h-vms. Generated by hand by Klaus Kämpf */ +/* config.h. Generated automatically by configure. */ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define to 1 if NLS is requested. */ +/* #undef ENABLE_NLS */ + +/* Define as 1 if you have dcgettext. */ +/* #undef HAVE_DCGETTEXT */ + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +/* #undef HAVE_GETTEXT */ + +/* Define if your locale.h file contains LC_MESSAGES. */ +/* #undef HAVE_LC_MESSAGES */ + +/* Define to the installation directory for locales. */ +#define LOCALEDIR "" + +/* Define as 1 if you have the stpcpy function. */ +/* #undef HAVE_STPCPY */ + +/* Define if the closedir function returns void instead of int. */ +/* #undef CLOSEDIR_VOID */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define for DGUX with . */ +/* #undef DGUX */ + +/* Define if the `getloadavg' function needs to be run setuid or setgid. */ +/* #undef GETLOADAVG_PRIVILEGED */ + +/* Define to `unsigned long' or `unsigned long long' + if doesn't define. */ +#define uintmax_t unsigned long + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +/* #undef HAVE_ALLOCA_H */ + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if your system has a working fnmatch function. */ +/* #undef HAVE_FNMATCH */ + +/* Define if your system has its own `getloadavg' function. */ +/* #undef HAVE_GETLOADAVG */ + +/* Define if you have the getmntent function. */ +/* #undef HAVE_GETMNTENT */ + +/* Define if the `long double' type works. */ +/* #undef HAVE_LONG_DOUBLE */ + +/* Define if you support file names longer than 14 characters. */ +#define HAVE_LONG_FILE_NAMES 1 + +/* Define if you have a working `mmap' system call. */ +/* #undef HAVE_MMAP */ + +/* Define if system calls automatically restart after interruption + by a signal. */ +/* #undef HAVE_RESTARTABLE_SYSCALLS */ + +/* Define if your struct stat has st_blksize. */ +/* #undef HAVE_ST_BLKSIZE */ + +/* Define if your struct stat has st_blocks. */ +/* #undef HAVE_ST_BLOCKS */ + +/* Define if you have the strcoll function and it is properly defined. */ +/* #undef HAVE_STRCOLL */ + +/* Define if your struct stat has st_rdev. */ +/* #undef HAVE_ST_RDEV */ + +/* Define if you have the strftime function. */ +/* #undef HAVE_STRFTIME */ + +/* Define if you have that is POSIX.1 compatible. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define if your struct tm has tm_zone. */ +/* #undef HAVE_TM_ZONE */ + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +/* #undef HAVE_TZNAME */ + +/* Define if you have . */ +#ifdef __DECC +#define HAVE_UNISTD_H 1 +#endif + +/* Define if utime(file, NULL) sets file's timestamp to the present. */ +/* #undef HAVE_UTIME_NULL */ + +/* Define if you have . */ +/* #undef HAVE_VFORK_H */ + +/* Define if you have the vprintf function. */ +#define HAVE_VPRINTF 1 + +/* Define if you have the wait3 system call. */ +/* #undef HAVE_WAIT3 */ + +/* Define if on MINIX. */ +/* #undef _MINIX */ + +/* Define if your struct nlist has an n_un member. */ +/* #undef NLIST_NAME_UNION */ + +/* Define if you have . */ +/* #undef NLIST_STRUCT */ + +/* Define if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Define to `int' if doesn't define. */ +/* I assume types.h is available for all 5.0 cc/cxx compilers */ +#if __DECC_VER < 50090000 +#define pid_t int +#endif + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define if the setvbuf function takes the buffering type as its second + argument and the buffer pointer as the third, as on System V + before release 3. */ +/* #undef SETVBUF_REVERSED */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define if you have the ANSI C header files. */ +/* #undef STDC_HEADERS */ + +/* Define on System V Release 4. */ +/* #undef SVR4 */ + +/* Define if `sys_siglist' is declared by . */ +/* #undef SYS_SIGLIST_DECLARED */ + +/* Define to `int' if doesn't define. */ +#if __DECC_VER < 50090000 +#define uid_t int +#endif + +/* Define for Encore UMAX. */ +/* #undef UMAX */ + +/* Define for Encore UMAX 4.3 that has + instead of . */ +/* #undef UMAX4_3 */ + +/* Define vfork as fork if vfork does not work. */ +/* #undef vfork */ + +/* Name of this package (needed by automake) */ +#define PACKAGE "make" + +/* Version of this package (needed by automake) */ +#define VERSION "3.80" + +/* Define to the name of the SCCS `get' command. */ +/* #undef SCCS_GET */ + +/* Define this if the SCCS `get' command understands the `-G' option. */ +/* #undef SCCS_GET_MINUS_G */ + +/* Define this to enable job server support in GNU make. */ +/* #undef MAKE_JOBSERVER */ + +/* Define to be the nanoseconds member of struct stat's st_mtim, + if it exists. */ +/* #undef ST_MTIM_NSEC */ + +/* Define this if the C library defines the variable `sys_siglist'. */ +/* #undefine HAVE_SYS_SIGLIST */ + +/* Define this if the C library defines the variable `_sys_siglist'. */ +/* #undef HAVE__SYS_SIGLIST */ + +/* Define this if you have the `union wait' type in . */ +/* #undef HAVE_UNION_WAIT */ + +/* Define if you have the dup2 function. */ +#define HAVE_DUP2 1 + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getgroups function. */ +/* #undef HAVE_GETGROUPS */ + +/* Define if you have the gethostbyname function. */ +/* #undef HAVE_GETHOSTBYNAME */ + +/* Define if you have the gethostname function. */ +/* #undef HAVE_GETHOSTNAME */ + +/* Define if you have the getloadavg function. */ +/* #undef HAVE_GETLOADAVG */ + +/* Define if you have the memmove function. */ +#define HAVE_MEMMOVE 1 + +/* Define if you have the mktemp function. */ +#define HAVE_MKTEMP 1 + +/* Define if you have the psignal function. */ +/* #undef HAVE_PSIGNAL */ + +/* Define if you have the pstat_getdynamic function. */ +/* #undef HAVE_PSTAT_GETDYNAMIC */ + +/* Define if you have the setegid function. */ +/* #undef HAVE_SETEGID */ + +/* Define if you have the seteuid function. */ +/* #undef HAVE_SETEUID */ + +/* Define if you have the setlinebuf function. */ +/* #undef HAVE_SETLINEBUF */ + +/* Define if you have the setregid function. */ +/* #undefine HAVE_SETREGID */ + +/* Define if you have the setreuid function. */ +/* #define HAVE_SETREUID */ + +/* Define if you have the sigsetmask function. */ +#define HAVE_SIGSETMASK 1 + +/* Define if you have the socket function. */ +/* #undef HAVE_SOCKET */ + +/* Define if you have the strcasecmp function. */ +/* #undef HAVE_STRCASECMP */ + +/* Define if you have the strerror function. */ +#define HAVE_STRERROR 1 + +/* Define if you have the strsignal function. */ +/* #undef HAVE_STRSIGNAL */ + +/* Define if you have the wait3 function. */ +/* #undef HAVE_WAIT3 */ + +/* Define if you have the waitpid function. */ +/* #undef HAVE_WAITPID */ + +/* Define if you have the header file. */ +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +#ifdef __DECC +#define HAVE_FCNTL_H 1 +#endif + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_MACH_MACH_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_MEMORY_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PARAM_H */ + +/* Define if you have the header file. */ +#ifndef __GNUC__ +#define HAVE_SYS_TIMEB_H 1 +#endif + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define if you have the dgc library (-ldgc). */ +/* #undef HAVE_LIBDGC */ + +/* Define if you have the kstat library (-lkstat). */ +/* #undef HAVE_LIBKSTAT * + +/* Define if you have the sun library (-lsun). */ +/* #undef HAVE_LIBSUN */ + +/* Use high resolution file timestamps if nonzero. */ +#define FILE_TIMESTAMP_HI_RES 0 + +/* Define for case insensitve filenames */ +#define HAVE_CASE_INSENSITIVE_FS 1 + +/* VMS specific, define it if you want to use case sensitve targets */ +/* #undef WANT_CASE_SENSITIVE_TARGETS */ + +/* VMS specific, V7.0 has opendir() and friends, so it's undefined */ +/* If you want to use non-VMS code for opendir() etc. on V7.0 and greater + define the first or both macros AND change the compile command to get the + non-VMS versions linked: (prefix=(all,except=(opendir,... */ +/* #undef HAVE_VMSDIR_H */ +/* #undef _DIRENT_HAVE_D_NAMLEN */ + +/* On older systems without 7.0 backport of CRTL the first one is defined */ +#ifdef __CRTL_VER +# if __CRTL_VER < 70000000 +# define HAVE_VMSDIR_H 1 +# endif +#else +# if __VMS_VER < 70000000 +# define HAVE_VMSDIR_H 1 +# endif +#endif + +#if defined(HAVE_VMSDIR_H) && defined(HAVE_DIRENT_H) +#undef HAVE_DIRENT_H +#endif + +#define HAVE_STDLIB_H 1 +#define INCLUDEDIR "sys$sysroot:[syslib]" +#define LIBDIR "sys$sysroot:[syslib]" + +/* Don't use RTL functions of OpenVMS */ +#ifdef __DECC +#include +#include +#define getopt gnu_getopt +#define optarg gnu_optarg +#define optopt gnu_optopt +#define optind gnu_optind +#define opterr gnu_opterr +#endif + +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +#undef PARAMS +#define PARAMS(protos) protos +#else /* Not C++ or ANSI C. */ +#undef PARAMS +#define PARAMS(protos) () +#endif /* C++ or ANSI C. */ + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ +/* maybe this should be placed into make.h */ +#if defined(__VAX) && defined(__DECC) +#define alloca(n) __ALLOCA(n) +#endif + +/* Build host information. */ +#define MAKE_HOST "VMS" diff --git a/src/make-3.80/config.h.W32 b/src/make-3.80/config.h.W32 new file mode 100755 index 00000000..1ba9b87e --- /dev/null +++ b/src/make-3.80/config.h.W32 @@ -0,0 +1,399 @@ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define if the closedir function returns void instead of int. */ +/* #undef CLOSEDIR_VOID */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define for DGUX with . */ +/* #undef DGUX */ + +/* Define if the `getloadavg' function needs to be run setuid or setgid. */ +/* #undef GETLOADAVG_PRIVILEGED */ + +/* Define to `unsigned long' or `unsigned long long' + if doesn't define. */ +#define uintmax_t unsigned long + +/* Define to `int' if doesn't define. */ +#undef gid_t +#define gid_t int + +/* Define if you have alloca, as a function or macro. */ +#undef HAVE_ALLOCA +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +/* #undef HAVE_ALLOCA_H */ + +/* Define if you don't have vprintf but do have _doprnt. */ +/* #undef HAVE_DOPRNT */ + +/* Define if your system has a working fnmatch function. */ +/* #undef HAVE_FNMATCH */ + +/* Define if your system has its own `getloadavg' function. */ +/* #undef HAVE_GETLOADAVG */ + +/* Define if you have the getmntent function. */ +/* #undef HAVE_GETMNTENT */ + +/* Define if the `long double' type works. */ +/* #undef HAVE_LONG_DOUBLE */ + +/* Define if you support file names longer than 14 characters. */ +#undef HAVE_LONG_FILE_NAMES +#define HAVE_LONG_FILE_NAMES 1 + +/* Define if you have a working `mmap' system call. */ +/* #undef HAVE_MMAP */ + +/* Define if system calls automatically restart after interruption + by a signal. */ +/* #undef HAVE_RESTARTABLE_SYSCALLS */ + +/* Define if your struct stat has st_blksize. */ +/* #undef HAVE_ST_BLKSIZE */ + +/* Define if your struct stat has st_blocks. */ +/* #undef HAVE_ST_BLOCKS */ + +/* Define if you have the strcoll function and it is properly defined. */ +#undef HAVE_STRCOLL +#define HAVE_STRCOLL 1 + +/* Define if your struct stat has st_rdev. */ +#undef HAVE_ST_RDEV +#define HAVE_ST_RDEV 1 + +/* Define if you have the strftime function. */ +#undef HAVE_STRFTIME +#define HAVE_STRFTIME 1 + +/* Define if you have that is POSIX.1 compatible. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define if your struct tm has tm_zone. */ +/* #undef HAVE_TM_ZONE */ + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#undef HAVE_TZNAME +#define HAVE_TZNAME 1 + +/* Define if you have . */ +/* #undef HAVE_UNISTD_H */ + +/* Define if utime(file, NULL) sets file's timestamp to the present. */ +#undef HAVE_UTIME_NULL +#define HAVE_UTIME_NULL 1 + +/* Define if you have . */ +/* #undef HAVE_VFORK_H */ + +/* Define if you have the vprintf function. */ +#undef HAVE_VPRINTF +#define HAVE_VPRINTF 1 + +/* Define if you have the wait3 system call. */ +/* #undef HAVE_WAIT3 */ + +/* Define if on MINIX. */ +/* #undef _MINIX */ + +/* Define if your struct nlist has an n_un member. */ +/* #undef NLIST_NAME_UNION */ + +/* Define if you have . */ +/* #undef NLIST_STRUCT */ + +/* Define if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Define to `int' if doesn't define. */ +#undef pid_t +#define pid_t int + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +#undef _POSIX_SOURCE +#define _POSIX_SOURCE 1 + +/* Define as the return type of signal handlers (int or void). */ +#undef RETSIGTYPE +#define RETSIGTYPE void + +/* Define if the setvbuf function takes the buffering type as its second + argument and the buffer pointer as the third, as on System V + before release 3. */ +/* #undef SETVBUF_REVERSED */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define if you have the ANSI C header files. */ +#undef STDC_HEADERS +#define STDC_HEADERS 1 + +/* Define on System V Release 4. */ +/* #undef SVR4 */ + +/* Define if `sys_siglist' is declared by . */ +/* #undef SYS_SIGLIST_DECLARED */ + +/* Define to `int' if doesn't define. */ +#undef uid_t +#define uid_t int + +/* Define for Encore UMAX. */ +/* #undef UMAX */ + +/* Define for Encore UMAX 4.3 that has + instead of . */ +/* #undef UMAX4_3 */ + +/* Define vfork as fork if vfork does not work. */ +/* #undef vfork */ + +/* Name of this package (needed by automake) */ +#define PACKAGE "make" + +/* Version of this package (needed by automake) */ +#define VERSION "3.80" + +/* Define to the name of the SCCS `get' command. */ +#undef SCCS_GET +#define SCCS_GET "echo no sccs get" + +/* Define to 1 if NLS is requested. */ +/* #undef ENABLE_NLS */ + +/* Define as 1 if you have dcgettext. */ +/* #undef HAVE_DCGETTEXT */ + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +/* #undef HAVE_GETTEXT */ + +/* Define if your locale.h file contains LC_MESSAGES. */ +/* #undef HAVE_LC_MESSAGES */ + +/* Define to the installation directory for locales. */ +#define LOCALEDIR "" + +/* Define this if the SCCS `get' command understands the `-G' option. */ +/* #undef SCCS_GET_MINUS_G */ + +/* Define this to enable job server support in GNU make. */ +/* #undef MAKE_JOBSERVER */ + +/* Define to be the nanoseconds member of struct stat's st_mtim, + if it exists. */ +/* #undef ST_MTIM_NSEC */ + +/* Define this if the C library defines the variable `sys_siglist'. */ +/* #undef HAVE_SYS_SIGLIST */ + +/* Define this if the C library defines the variable `_sys_siglist'. */ +/* #undef HAVE__SYS_SIGLIST */ + +/* Define this if you have the `union wait' type in . */ +/* #undef HAVE_UNION_WAIT */ + +/* Define if you have the dup2 function. */ +#undef HAVE_DUP2 +#define HAVE_DUP2 1 + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD +#define HAVE_GETCWD 1 + +/* Define if you have the getgroups function. */ +/* #undef HAVE_GETGROUPS */ + +/* Define if you have the gethostbyname function. */ +/* #undef HAVE_GETHOSTBYNAME */ + +/* Define if you have the gethostname function. */ +/* #undef HAVE_GETHOSTNAME */ + +/* Define if you have the getloadavg function. */ +/* #undef HAVE_GETLOADAVG */ + +/* Define if you have the memmove function. */ +#undef HAVE_MEMMOVE +#define HAVE_MEMMOVE 1 + +/* Define if you have the mktemp function. */ +#undef HAVE_MKTEMP +#define HAVE_MKTEMP 1 + +/* Define if you have the psignal function. */ +/* #undef HAVE_PSIGNAL */ + +/* Define if you have the pstat_getdynamic function. */ +/* #undef HAVE_PSTAT_GETDYNAMIC */ + +/* Define if you have the setegid function. */ +/* #undef HAVE_SETEGID */ + +/* Define if you have the seteuid function. */ +/* #undef HAVE_SETEUID */ + +/* Define if you have the setlinebuf function. */ +/* #undef HAVE_SETLINEBUF */ + +/* Define if you have the setregid function. */ +/* #undef HAVE_SETREGID */ + +/* Define if you have the setreuid function. */ +/* #undef HAVE_SETREUID */ + +/* Define if you have the sigsetmask function. */ +/* #undef HAVE_SIGSETMASK */ + +/* Define if you have the socket function. */ +/* #undef HAVE_SOCKET */ + +/* Define if you have the strcasecmp function. */ +/* #undef HAVE_STRCASECMP */ + +/* Define if you have the strerror function. */ +#undef HAVE_STRERROR +#define HAVE_STRERROR 1 + +/* Define if you have the strsignal function. */ +/* #undef HAVE_STRSIGNAL */ + +/* Define if you have the wait3 function. */ +/* #undef HAVE_WAIT3 */ + +/* Define if you have the waitpid function. */ +/* #undef HAVE_WAITPID */ + +/* Define if you have the header file. */ +#undef HAVE_DIRENT_H +#define HAVE_DIRENT_H 1 + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#undef HAVE_LIMITS_H +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_MACH_MACH_H */ + +/* Define if you have the header file. */ +#undef HAVE_MEMORY_H +#define HAVE_MEMORY_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NDIR_H */ + +/* Define if you have the header file. */ +#undef HAVE_STRING_H +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_PARAM_H */ + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIMEB_H +#define HAVE_SYS_TIMEB_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_WAIT_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_UNISTD_H */ + +/* Define if you have the dgc library (-ldgc). */ +/* #undef HAVE_LIBDGC */ + +/* Define if you have the kstat library (-lkstat). */ +/* #undef HAVE_LIBKSTAT */ + +/* Define if you have the sun library (-lsun). */ +/* #undef HAVE_LIBSUN */ + +/* Use high resolution file timestamps if nonzero. */ +#define FILE_TIMESTAMP_HI_RES 0 + +/* Build host information. */ +#define MAKE_HOST "Windows32" + +/* Grok DOS paths (drive specs and backslash path element separators) */ +#define HAVE_DOS_PATHS + +/* + * Refer to README.W32 for info on the following settings + */ + +/* + * If you have a shell that does not grok 'sh -c quoted-command-line' + * correctly, you need this setting. Please see below for specific + * shell support. + */ +#undef BATCH_MODE_ONLY_SHELL +#define BATCH_MODE_ONLY_SHELL 1 + +/* + * Define if you have the Cygnus "Cygwin" GNU Windows32 tool set. + * Do NOT define BATCH_MODE_ONLY_SHELL if you define HAVE_CYGWIN_SHELL + */ +#undef HAVE_CYGWIN_SHELL + +/* + * Define if you have the MKS tool set or shell. Do NOT define + * BATCH_MODE_ONLY_SHELL if you define HAVE_MKS_SHELL + */ +#undef HAVE_MKS_SHELL + +/* + * Enforce the mutual exclusivity restriction. + */ +#ifdef HAVE_MKS_SHELL +#undef BATCH_MODE_ONLY_SHELL +#endif + +#ifdef HAVE_CYGWIN_SHELL +#undef BATCH_MODE_ONLY_SHELL +#endif + +/* Define if you prefer Case Insensitive behavior */ +#undef HAVE_CASE_INSENSITIVE_FS diff --git a/src/make-3.80/config.h.in b/src/make-3.80/config.h.in new file mode 100755 index 00000000..d33b8d32 --- /dev/null +++ b/src/make-3.80/config.h.in @@ -0,0 +1,391 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if the `closedir' function returns void instead of `int'. */ +#undef CLOSEDIR_VOID + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to 1 if using `getloadavg.c'. */ +#undef C_GETLOADAVG + +/* Define to 1 for DGUX with . */ +#undef DGUX + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Use high resolution file timestamps if nonzero. */ +#undef FILE_TIMESTAMP_HI_RES + +/* Define to 1 if the `getloadavg' function needs to be run setuid or setgid. + */ +#undef GETLOADAVG_PRIVILEGED + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* This system has SA_RESTART, but it doesn't work properly. */ +#undef HAVE_BROKEN_RESTART + +/* Define to 1 if you have the `bsd_signal' function. */ +#undef HAVE_BSD_SIGNAL + +/* Define if you have the clock_gettime function. */ +#undef HAVE_CLOCK_GETTIME + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +#undef HAVE_DCGETTEXT + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the `dup2' function. */ +#undef HAVE_DUP2 + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fdopen' function. */ +#undef HAVE_FDOPEN + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the `getcwd' function. */ +#undef HAVE_GETCWD + +/* Define to 1 if you have the `getgroups' function. */ +#undef HAVE_GETGROUPS + +/* Define to 1 if you have the `gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the `gethostname' function. */ +#undef HAVE_GETHOSTNAME + +/* Define to 1 if you have the `getloadavg' function. */ +#undef HAVE_GETLOADAVG + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define if you have a standard gettimeofday function */ +#undef HAVE_GETTIMEOFDAY + +/* Define if you have the iconv() function. */ +#undef HAVE_ICONV + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `dgc' library (-ldgc). */ +#undef HAVE_LIBDGC + +/* Define to 1 if you have the `kstat' library (-lkstat). */ +#undef HAVE_LIBKSTAT + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MACH_MACH_H + +/* Define to 1 if you have the `memcpy' function. */ +#undef HAVE_MEMCPY + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mkstemp' function. */ +#undef HAVE_MKSTEMP + +/* Define to 1 if you have the `mktemp' function. */ +#undef HAVE_MKTEMP + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NLIST_H + +/* Define to 1 if you have the `pipe' function. */ +#undef HAVE_PIPE + +/* Define to 1 if you have the `pstat_getdynamic' function. */ +#undef HAVE_PSTAT_GETDYNAMIC + +/* Define if defines the SA_RESTART constant. */ +#undef HAVE_SA_RESTART + +/* Define to 1 if you have the `setegid' function. */ +#undef HAVE_SETEGID + +/* Define to 1 if you have the `seteuid' function. */ +#undef HAVE_SETEUID + +/* Define to 1 if you have the `setlinebuf' function. */ +#undef HAVE_SETLINEBUF + +/* Define to 1 if you have the `setlocale' function. */ +#undef HAVE_SETLOCALE + +/* Define to 1 if you have the `setregid' function. */ +#undef HAVE_SETREGID + +/* Define to 1 if you have the `setreuid' function. */ +#undef HAVE_SETREUID + +/* Define to 1 if you have the `setvbuf' function. */ +#undef HAVE_SETVBUF + +/* Define to 1 if you have the `sigaction' function. */ +#undef HAVE_SIGACTION + +/* Define to 1 if you have the `sigsetmask' function. */ +#undef HAVE_SIGSETMASK + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strcoll' function and it is properly defined. + */ +#undef HAVE_STRCOLL + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strsignal' function. */ +#undef HAVE_STRSIGNAL + +/* Define to 1 if `n_un.n_name' is member of `struct nlist'. */ +#undef HAVE_STRUCT_NLIST_N_UN_N_NAME + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIMEB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define this if you have the `union wait' type in . */ +#undef HAVE_UNION_WAIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if you have the `wait3' function. */ +#undef HAVE_WAIT3 + +/* Define to 1 if you have the `waitpid' function. */ +#undef HAVE_WAITPID + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Build host information. */ +#undef MAKE_HOST + +/* Define this to enable job server support in GNU make. */ +#undef MAKE_JOBSERVER + +/* Define to 1 if your `struct nlist' has an `n_un' member. Obsolete, depend + on `HAVE_STRUCT_NLIST_N_UN_N_NAME */ +#undef NLIST_NAME_UNION + +/* Define if struct nlist.n_name is a pointer rather than an array. */ +#undef NLIST_STRUCT + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if the C compiler supports function prototypes. */ +#undef PROTOTYPES + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to the name of the SCCS 'get' command. */ +#undef SCCS_GET + +/* Define this if the SCCS 'get' command understands the '-G' option. */ +#undef SCCS_GET_MINUS_G + +/* Define to 1 if the `setvbuf' function takes the buffering type as its + second argument and the buffer pointer as the third, as on System V before + release 3. */ +#undef SETVBUF_REVERSED + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if the `S_IS*' macros in do not work properly. */ +#undef STAT_MACROS_BROKEN + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define if 'struct stat' contains a nanoseconds field */ +#undef ST_MTIM_NSEC + +/* Define to 1 on System V Release 4. */ +#undef SVR4 + +/* Define to 1 if `sys_siglist' is declared by or . */ +#undef SYS_SIGLIST_DECLARED + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 for Encore UMAX. */ +#undef UMAX + +/* Define to 1 for Encore UMAX 4.3 that has instead of + . */ +#undef UMAX4_3 + +/* Version number of package */ +#undef VERSION + +/* Define if using the dmalloc debugging malloc package */ +#undef WITH_DMALLOC + +/* Define to 1 if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define like PROTOTYPES; this can be used by system headers. */ +#undef __PROTOTYPES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if doesn't define. */ +#undef gid_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `int' if doesn't define. */ +#undef uid_t + +/* Define uintmax_t if not defined in or . */ +#undef uintmax_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork diff --git a/src/make-3.80/configh.dos b/src/make-3.80/configh.dos new file mode 100755 index 00000000..c8184af8 --- /dev/null +++ b/src/make-3.80/configh.dos @@ -0,0 +1,94 @@ + +/* Many things are defined already by a system header. */ +#include + +#if __DJGPP__ > 2 || __DJGPP_MINOR__ > 1 + +/* Define if `sys_siglist' is declared by . */ +# define SYS_SIGLIST_DECLARED 1 + +/* Define this if the C library defines the variable `_sys_siglist'. */ +# define HAVE_SYS_SIGLIST 1 + +#else + +/* Define NSIG. */ +# define NSIG SIGMAX + +#endif + +/* Use high resolution file timestamps if nonzero. */ +#define FILE_TIMESTAMP_HI_RES 0 + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have the fdopen function. */ +#define HAVE_FDOPEN 1 + +/* Define to 1 if you have the `getgroups' function. */ +#define HAVE_GETGROUPS 1 + +/* Define if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if you have the mkstemp function. */ +#define HAVE_MKSTEMP 1 + +/* Define to 1 if you have the `mktemp' function. */ +#define HAVE_MKTEMP 1 + +/* Define to 1 if you have the `setlinebuf' function. */ +#define HAVE_SETLINEBUF 1 + +/* Define to 1 if you have the `setvbuf' function. */ +#define HAVE_SETVBUF 1 + +#define SCCS_GET "get" + +/* Define to `unsigned long' or `unsigned long long' + if doesn't define. */ +#define uintmax_t unsigned long long + +/* Define the type of the first arg to select(). */ +#define fd_set_size_t int + +/* Define if you have the select function. */ +#define HAVE_SELECT 1 + +/* Define if you have the vprintf library function. */ +#undef HAVE_VPRINTF +#define HAVE_VPRINTF 1 + +/* Name of the package */ +#define PACKAGE "make" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "bug-make@gnu.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "GNU make" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "GNU make 3.80" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "make" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "3.80" + +/* Define to 1 if the C compiler supports function prototypes. */ +#define PROTOTYPES 1 + +/* Define to 1 if `sys_siglist' is declared by or . */ +#define SYS_SIGLIST_DECLARED 1 + +/* Version number of package */ +#define VERSION "3.80" + +/* Build host information. */ +#define MAKE_HOST "i386-pc-msdosdjgpp" + +/* Grok DOS paths (drive specs and backslash path element separators) */ +#define HAVE_DOS_PATHS diff --git a/src/make-3.80/configure b/src/make-3.80/configure new file mode 100755 index 00000000..e2332983 --- /dev/null +++ b/src/make-3.80/configure @@ -0,0 +1,12603 @@ +#! /bin/sh +# From configure.in Id: configure.in,v 1.114 2002/10/03 05:46:12 psmith Exp . +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.54 for GNU make 3.80. +# +# Report bugs to . +# +# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME='GNU make' +PACKAGE_TARNAME='make' +PACKAGE_VERSION='3.80' +PACKAGE_STRING='GNU make 3.80' +PACKAGE_BUGREPORT='bug-make@gnu.org' + +ac_unique_file="vpath.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE RANLIB ac_ct_RANLIB CPP AR PERL build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP MKINSTALLDIRS MSGFMT GMSGFMT XGETTEXT MSGMERGE USE_NLS LIBICONV LTLIBICONV INTLLIBS LIBINTL LTLIBINTL POSUB ALLOCA LIBOBJS NEED_SETGID KMEM_GROUP GETLOADAVG_LIBS USE_CUSTOMS_TRUE USE_CUSTOMS_FALSE GLOBINC GLOBLIB USE_LOCAL_GLOB_TRUE USE_LOCAL_GLOB_FALSE MAKE_HOST LTLIBOBJS' +ac_subst_files='MAINT_MAKEFILE' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures GNU make 3.80 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of GNU make 3.80:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors + --disable-rpath do not hardcode runtime library paths + --disable-nls do not use Native Language Support + --disable-largefile omit support for large files + --disable-job-server disallow recursive make communication during -jN + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld default=no + --with-libiconv-prefix=DIR search for libiconv in DIR/include and DIR/lib + --without-libiconv-prefix don't search for libiconv in includedir and libdir + --with-libintl-prefix=DIR search for libintl in DIR/include and DIR/lib + --without-libintl-prefix don't search for libintl in includedir and libdir + --with-customs=DIR enable remote jobs via Customs--see README.customs + --with-dmalloc use dmalloc, as in + http://www.dmalloc.com/dmalloc.tar.gz + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF +GNU make configure 3.80 +generated by GNU Autoconf 2.54 + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 +Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by GNU make $as_me 3.80, which was +generated by GNU Autoconf 2.54. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell meta-characters. +ac_configure_args= +ac_sep= +for ac_arg +do + case $ac_arg in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n ) continue ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " +done + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core core.* *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# Autoconf setup +ac_aux_dir= +for ac_dir in config $srcdir/config; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in config $srcdir/config" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in config $srcdir/config" >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + + + ac_config_headers="$ac_config_headers config.h" + + +# Automake setup +am__api_version="1.7" +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +test "$program_prefix" != NONE && + program_transform_name="s,^,$program_prefix,;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$,$program_suffix,;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="${MAKE}"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + # test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=make + VERSION=3.80 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. + + + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \${MAKE}... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="${MAKE}"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output" >&5 +echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + a.out ) # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool --akim. + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +check \`config.log' for details." >&5 +echo "$as_me: error: C compiler cannot create executables +check \`config.log' for details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_compiler_gnu=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_prog_cc_g=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + ''\ + '#include ' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +continue +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +rm -f .deps 2>/dev/null +mkdir .deps 2>/dev/null +if test -d .deps; then + DEPDIR=.deps +else + # MS-DOS does not allow filenames that begin with a dot. + DEPDIR=_deps +fi +rmdir .deps 2>/dev/null + + + ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +doit: + @echo done +END +# If we don't find an include directive, just comment out the code. +echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6 +rm -f confinc confmf + +# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval="$enable_dependency_tracking" + +fi; +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + + +depcc="$CC" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + echo '#include "conftest.h"' > conftest.c + echo 'int i;' > conftest.h + echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=conftest.c object=conftest.o \ + depfile=conftest.Po tmpdepfile=conftest.TPo \ + $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 && + grep conftest.h conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + RANLIB=$ac_ct_RANLIB +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +# Extract the first word of "ar", so it can be a program name with args. +set dummy ar; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="ar" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_AR" && ac_cv_prog_AR="ar" +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +# Perl is needed for the test suite (only) +# Extract the first word of "perl", so it can be a program name with args. +set dummy perl; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_PERL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$PERL"; then + ac_cv_prog_PERL="$PERL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_PERL="perl" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_PERL" && ac_cv_prog_PERL="perl" +fi +fi +PERL=$ac_cv_prog_PERL +if test -n "$PERL"; then + echo "$as_me:$LINENO: result: $PERL" >&5 +echo "${ECHO_T}$PERL" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + +# Specialized system macros +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + + +echo "$as_me:$LINENO: checking for AIX" >&5 +echo $ECHO_N "checking for AIX... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#ifdef _AIX + yes +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "yes" >/dev/null 2>&1; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +cat >>confdefs.h <<\_ACEOF +#define _ALL_SOURCE 1 +_ACEOF + +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +rm -f conftest* + + + + echo "$as_me:$LINENO: checking for strerror in -lcposix" >&5 +echo $ECHO_N "checking for strerror in -lcposix... $ECHO_C" >&6 +if test "${ac_cv_lib_cposix_strerror+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcposix $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strerror (); +int +main () +{ +strerror (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_cposix_strerror=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_cposix_strerror=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_cposix_strerror" >&5 +echo "${ECHO_T}$ac_cv_lib_cposix_strerror" >&6 +if test $ac_cv_lib_cposix_strerror = yes; then + LIBS="$LIBS -lcposix" +fi + + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include +#include + +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +if test "${ac_cv_header_minix_config_h+set}" = set; then + echo "$as_me:$LINENO: checking for minix/config.h" >&5 +echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6 +if test "${ac_cv_header_minix_config_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 +echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking minix/config.h usability" >&5 +echo $ECHO_N "checking minix/config.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking minix/config.h presence" >&5 +echo $ECHO_N "checking minix/config.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: minix/config.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: minix/config.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: minix/config.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: minix/config.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: minix/config.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: minix/config.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: minix/config.h: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for minix/config.h" >&5 +echo $ECHO_N "checking for minix/config.h... $ECHO_C" >&6 +if test "${ac_cv_header_minix_config_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_minix_config_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_minix_config_h" >&5 +echo "${ECHO_T}$ac_cv_header_minix_config_h" >&6 + +fi +if test $ac_cv_header_minix_config_h = yes; then + MINIX=yes +else + MINIX= +fi + + +if test "$MINIX" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_SOURCE 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_1_SOURCE 2 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _MINIX 1 +_ACEOF + +fi + + +# Enable gettext, in "external" mode. + + + + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + + + + + + # Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_MSGFMT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case "$MSGFMT" in + /*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if $ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + ac_cv_path_MSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test "$MSGFMT" != ":"; then + echo "$as_me:$LINENO: result: $MSGFMT" >&5 +echo "${ECHO_T}$MSGFMT" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_GMSGFMT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $GMSGFMT in + [\\/]* | ?:[\\/]*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT=$ac_cv_path_GMSGFMT + +if test -n "$GMSGFMT"; then + echo "$as_me:$LINENO: result: $GMSGFMT" >&5 +echo "${ECHO_T}$GMSGFMT" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + + # Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_XGETTEXT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case "$XGETTEXT" in + /*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test "$XGETTEXT" != ":"; then + echo "$as_me:$LINENO: result: $XGETTEXT" >&5 +echo "${ECHO_T}$XGETTEXT" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + rm -f messages.po + + # Extract the first word of "msgmerge", so it can be a program name with args. +set dummy msgmerge; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_MSGMERGE+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case "$MSGMERGE" in + /*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if $ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1; then + ac_cv_path_MSGMERGE="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" + ;; +esac +fi +MSGMERGE="$ac_cv_path_MSGMERGE" +if test "$MSGMERGE" != ":"; then + echo "$as_me:$LINENO: result: $MSGMERGE" >&5 +echo "${ECHO_T}$MSGMERGE" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + + if test "$GMSGFMT" != ":"; then + if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && + (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` + echo "$as_me:$LINENO: result: found $GMSGFMT program is not GNU msgfmt; ignore it" >&5 +echo "${ECHO_T}found $GMSGFMT program is not GNU msgfmt; ignore it" >&6 + GMSGFMT=":" + fi + fi + + if test "$XGETTEXT" != ":"; then + if $XGETTEXT --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && + (if $XGETTEXT --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + echo "$as_me:$LINENO: result: found xgettext program is not GNU xgettext; ignore it" >&5 +echo "${ECHO_T}found xgettext program is not GNU xgettext; ignore it" >&6 + XGETTEXT=":" + fi + rm -f messages.po + fi + + ac_config_commands="$ac_config_commands default-1" + + + + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" + + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi; +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo "$as_me:$LINENO: checking for ld used by GCC" >&5 +echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6 + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo "$as_me:$LINENO: checking for GNU ld" >&5 +echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking for non-GNU ld" >&5 +echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 +fi +if test "${acl_cv_path_LD+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$acl_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$acl_cv_path_LD" +if test -n "$LD"; then + echo "$as_me:$LINENO: result: $LD" >&5 +echo "${ECHO_T}$LD" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 +echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} + { (exit 1); exit 1; }; } +echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 +echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 +if test "${acl_cv_prog_gnu_ld+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + acl_cv_prog_gnu_ld=yes +else + acl_cv_prog_gnu_ld=no +fi +fi +echo "$as_me:$LINENO: result: $acl_cv_prog_gnu_ld" >&5 +echo "${ECHO_T}$acl_cv_prog_gnu_ld" >&6 +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + echo "$as_me:$LINENO: checking for shared library run path origin" >&5 +echo $ECHO_N "checking for shared library run path origin... $ECHO_C" >&6 +if test "${acl_cv_rpath+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + +fi +echo "$as_me:$LINENO: result: $acl_cv_rpath" >&5 +echo "${ECHO_T}$acl_cv_rpath" >&6 + wl="$acl_cv_wl" + libext="$acl_cv_libext" + shlibext="$acl_cv_shlibext" + hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + hardcode_direct="$acl_cv_hardcode_direct" + hardcode_minus_L="$acl_cv_hardcode_minus_L" + sys_lib_search_path_spec="$acl_cv_sys_lib_search_path_spec" + sys_lib_dlsearch_path_spec="$acl_cv_sys_lib_dlsearch_path_spec" + # Check whether --enable-rpath or --disable-rpath was given. +if test "${enable_rpath+set}" = set; then + enableval="$enable_rpath" + : +else + enable_rpath=yes +fi; + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libiconv-prefix or --without-libiconv-prefix was given. +if test "${with_libiconv_prefix+set}" = set; then + withval="$with_libiconv_prefix" + + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi + +fi; + LIBICONV= + LTLIBICONV= + INCICONV= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='iconv ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + else + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + else + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$hardcode_direct" = yes; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" + ;; + esac + done + fi + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" + done + fi + + + + + + + + + + + + + + + + + + echo "$as_me:$LINENO: checking whether NLS is requested" >&5 +echo $ECHO_N "checking whether NLS is requested... $ECHO_C" >&6 + # Check whether --enable-nls or --disable-nls was given. +if test "${enable_nls+set}" = set; then + enableval="$enable_nls" + USE_NLS=$enableval +else + USE_NLS=yes +fi; + echo "$as_me:$LINENO: result: $USE_NLS" >&5 +echo "${ECHO_T}$USE_NLS" >&6 + + + + LIBINTL= + LTLIBINTL= + POSUB= + + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + + + + + + + echo "$as_me:$LINENO: checking for GNU gettext in libc" >&5 +echo $ECHO_N "checking for GNU gettext in libc... $ECHO_C" >&6 +if test "${gt_cv_func_gnugettext1_libc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; +int +main () +{ +bindtextdomain ("", ""); +return (int) gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + gt_cv_func_gnugettext1_libc=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +gt_cv_func_gnugettext1_libc=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $gt_cv_func_gnugettext1_libc" >&5 +echo "${ECHO_T}$gt_cv_func_gnugettext1_libc" >&6 + + if test "$gt_cv_func_gnugettext1_libc" != "yes"; then + + + + + + am_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCICONV; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + echo "$as_me:$LINENO: checking for iconv" >&5 +echo $ECHO_N "checking for iconv... $ECHO_C" >&6 +if test "${am_cv_func_iconv+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + am_cv_func_iconv=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + LIBS="$am_save_LIBS" + fi + +fi +echo "$as_me:$LINENO: result: $am_cv_func_iconv" >&5 +echo "${ECHO_T}$am_cv_func_iconv" >&6 + if test "$am_cv_func_iconv" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ICONV 1 +_ACEOF + + fi + if test "$am_cv_lib_iconv" = yes; then + echo "$as_me:$LINENO: checking how to link with libiconv" >&5 +echo $ECHO_N "checking how to link with libiconv... $ECHO_C" >&6 + echo "$as_me:$LINENO: result: $LIBICONV" >&5 +echo "${ECHO_T}$LIBICONV" >&6 + else + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libintl-prefix or --without-libintl-prefix was given. +if test "${with_libintl_prefix+set}" = set; then + withval="$with_libintl_prefix" + + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/lib" + fi + fi + +fi; + LIBINTL= + LTLIBINTL= + INCINTL= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='intl ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + if test $use_additional = yes; then + if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then + found_dir="$additional_libdir" + found_so="$additional_libdir/lib$name.$shlibext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + else + if test -f "$additional_libdir/lib$name.$libext"; then + found_dir="$additional_libdir" + found_a="$additional_libdir/lib$name.$libext" + if test -f "$additional_libdir/lib$name.la"; then + found_la="$additional_libdir/lib$name.la" + fi + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then + found_dir="$dir" + found_so="$dir/lib$name.$shlibext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + else + if test -f "$dir/lib$name.$libext"; then + found_dir="$dir" + found_a="$dir/lib$name.$libext" + if test -f "$dir/lib$name.la"; then + found_la="$dir/lib$name.la" + fi + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$hardcode_direct" = yes; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" + fi + if test "$hardcode_minus_L" != no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */lib | */lib/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/lib"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/lib"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" + ;; + esac + done + fi + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" + done + fi + + echo "$as_me:$LINENO: checking for GNU gettext in libintl" >&5 +echo $ECHO_N "checking for GNU gettext in libintl... $ECHO_C" >&6 +if test "${gt_cv_func_gnugettext1_libintl+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (); +int +main () +{ +bindtextdomain ("", ""); +return (int) gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias (0) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + gt_cv_func_gnugettext1_libintl=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +gt_cv_func_gnugettext1_libintl=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + if test "$gt_cv_func_gnugettext1_libintl" != yes && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (); +int +main () +{ +bindtextdomain ("", ""); +return (int) gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias (0) + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + gt_cv_func_gnugettext1_libintl=yes + +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS" +fi +echo "$as_me:$LINENO: result: $gt_cv_func_gnugettext1_libintl" >&5 +echo "${ECHO_T}$gt_cv_func_gnugettext1_libintl" >&6 + fi + + if test "$gt_cv_func_gnugettext1_libc" = "yes" \ + || { test "$gt_cv_func_gnugettext1_libintl" = "yes" \ + && test "$PACKAGE" != gettext; }; then + gt_use_preinstalled_gnugettext=yes + else + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define ENABLE_NLS 1 +_ACEOF + + else + USE_NLS=no + fi + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then + echo "$as_me:$LINENO: checking how to link with libintl" >&5 +echo $ECHO_N "checking how to link with libintl... $ECHO_C" >&6 + echo "$as_me:$LINENO: result: $LIBINTL" >&5 +echo "${ECHO_T}$LIBINTL" >&6 + + for element in $INCINTL; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + fi + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETTEXT 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DCGETTEXT 1 +_ACEOF + + fi + + POSUB=po + fi + + + + INTLLIBS="$LIBINTL" + + + + + + + +# This test must come as early as possible after the compiler configuration +# tests, because the choice of the file model can (in principle) affect +# whether functions and headers are available, whether they work, etc. +# Check whether --enable-largefile or --disable-largefile was given. +if test "${enable_largefile+set}" = set; then + enableval="$enable_largefile" + +fi; +if test "$enable_largefile" != no; then + + echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 +echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6 +if test "${ac_cv_sys_largefile_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_sys_largefile_CC=no + if test "$GCC" != yes; then + ac_save_CC=$CC + while :; do + # IRIX 6.2 and later do not support large files by default, + # so use the C compiler's -n32 option if that helps. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext + CC="$CC -n32" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_largefile_CC=' -n32'; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext + break + done + CC=$ac_save_CC + rm -f conftest.$ac_ext + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 +echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6 + if test "$ac_cv_sys_largefile_CC" != no; then + CC=$CC$ac_cv_sys_largefile_CC + fi + + echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6 +if test "${ac_cv_sys_file_offset_bits+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + ac_cv_sys_file_offset_bits=no + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#define _FILE_OFFSET_BITS 64 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_file_offset_bits=64; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + break +done +fi +echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 +echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6 +if test "$ac_cv_sys_file_offset_bits" != no; then + +cat >>confdefs.h <<_ACEOF +#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits +_ACEOF + +fi +rm -f conftest* + echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 +echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6 +if test "${ac_cv_sys_large_files+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + while :; do + ac_cv_sys_large_files=no + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#define _LARGE_FILES 1 +#include + /* Check that off_t can represent 2**63 - 1 correctly. + We can't simply define LARGE_OFF_T to be 9223372036854775807, + since some C++ compilers masquerading as C compilers + incorrectly reject 9223372036854775807. */ +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) + int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 + && LARGE_OFF_T % 2147483647 == 1) + ? 1 : -1]; +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_sys_large_files=1; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + break +done +fi +echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 +echo "${ECHO_T}$ac_cv_sys_large_files" >&6 +if test "$ac_cv_sys_large_files" != no; then + +cat >>confdefs.h <<_ACEOF +#define _LARGE_FILES $ac_cv_sys_large_files +_ACEOF + +fi +rm -f conftest* +fi + + +# Checks for libraries. +echo "$as_me:$LINENO: checking for library containing getpwnam" >&5 +echo $ECHO_N "checking for library containing getpwnam... $ECHO_C" >&6 +if test "${ac_cv_search_getpwnam+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_getpwnam=no +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getpwnam (); +int +main () +{ +getpwnam (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_getpwnam="none required" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_getpwnam" = no; then + for ac_lib in sun; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getpwnam (); +int +main () +{ +getpwnam (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_getpwnam="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_getpwnam" >&5 +echo "${ECHO_T}$ac_cv_search_getpwnam" >&6 +if test "$ac_cv_search_getpwnam" != no; then + test "$ac_cv_search_getpwnam" = "none required" || LIBS="$ac_cv_search_getpwnam $LIBS" + +fi + + +# Checks for header files. +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include +#include + +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + + + + + + +ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 +echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_Header=no" +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_opendir=no +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char opendir (); +int +main () +{ +opendir (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_opendir="none required" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_opendir" = no; then + for ac_lib in dir; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char opendir (); +int +main () +{ +opendir (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_opendir="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6 +if test "$ac_cv_search_opendir" != no; then + test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" + +fi + +else + echo "$as_me:$LINENO: checking for library containing opendir" >&5 +echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6 +if test "${ac_cv_search_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_opendir=no +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char opendir (); +int +main () +{ +opendir (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_opendir="none required" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_opendir" = no; then + for ac_lib in x; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char opendir (); +int +main () +{ +opendir (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_opendir="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 +echo "${ECHO_T}$ac_cv_search_opendir" >&6 +if test "$ac_cv_search_opendir" != no; then + test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS" + +fi + +fi + +echo "$as_me:$LINENO: checking whether stat file-mode macros are broken" >&5 +echo $ECHO_N "checking whether stat file-mode macros are broken... $ECHO_C" >&6 +if test "${ac_cv_header_stat_broken+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include + +#if defined(S_ISBLK) && defined(S_IFDIR) +# if S_ISBLK (S_IFDIR) +You lose. +# endif +#endif + +#if defined(S_ISBLK) && defined(S_IFCHR) +# if S_ISBLK (S_IFCHR) +You lose. +# endif +#endif + +#if defined(S_ISLNK) && defined(S_IFREG) +# if S_ISLNK (S_IFREG) +You lose. +# endif +#endif + +#if defined(S_ISSOCK) && defined(S_IFREG) +# if S_ISSOCK (S_IFREG) +You lose. +# endif +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "You lose" >/dev/null 2>&1; then + ac_cv_header_stat_broken=yes +else + ac_cv_header_stat_broken=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stat_broken" >&5 +echo "${ECHO_T}$ac_cv_header_stat_broken" >&6 +if test $ac_cv_header_stat_broken = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STAT_MACROS_BROKEN 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_header_time=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6 +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + + + + + + + + + + + +for ac_header in stdlib.h locale.h unistd.h limits.h fcntl.h string.h \ + memory.h sys/param.h sys/time.h sys/timeb.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +if test "x$CC" != xcc; then + echo "$as_me:$LINENO: checking whether $CC and cc understand -c and -o together" >&5 +echo $ECHO_N "checking whether $CC and cc understand -c and -o together... $ECHO_C" >&6 +else + echo "$as_me:$LINENO: checking whether cc understands -c and -o together" >&5 +echo $ECHO_N "checking whether cc understands -c and -o together... $ECHO_C" >&6 +fi +set dummy $CC; ac_cc=`echo $2 | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval "test \"\${ac_cv_prog_cc_${ac_cc}_c_o+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest.$ac_objext >&5' +if { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + test -f conftest.$ac_objext && { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest.$ac_objext >&5' + if { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + test -f conftest.$ac_objext && { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f conftest* + +fi +if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + +cat >>confdefs.h <<\_ACEOF +#define NO_MINUS_C_MINUS_O 1 +_ACEOF + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +ac_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" != yes"; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + + + +echo "$as_me:$LINENO: checking for ${CC-cc} option to accept ANSI C" >&5 +echo $ECHO_N "checking for ${CC-cc} option to accept ANSI C... $ECHO_C" >&6 +if test "${am_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + am_cv_prog_cc_stdc=no +ac_save_CC="$CC" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; + +int +main () +{ + +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + am_cv_prog_cc_stdc="$ac_arg"; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext +done +CC="$ac_save_CC" + +fi + +if test -z "$am_cv_prog_cc_stdc"; then + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 +else + echo "$as_me:$LINENO: result: $am_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$am_cv_prog_cc_stdc" >&6 +fi +case "x$am_cv_prog_cc_stdc" in + x|xno) ;; + *) CC="$CC $am_cv_prog_cc_stdc" ;; +esac + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_c_const=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +#ifdef signal +# undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_signal=void +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_signal=int +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6 + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + +echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 +echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6 +if test "${ac_cv_type_uid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 +echo "${ECHO_T}$ac_cv_type_uid_t" >&6 +if test $ac_cv_type_uid_t = no; then + +cat >>confdefs.h <<\_ACEOF +#define uid_t int +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define gid_t int +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((pid_t *) 0) + return 0; +if (sizeof (pid_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_pid_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6 +if test $ac_cv_type_pid_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + + +# Find some definition for uintmax_t + +echo "$as_me:$LINENO: checking for uintmax_t" >&5 +echo $ECHO_N "checking for uintmax_t... $ECHO_C" >&6 +if test "${ac_cv_type_uintmax_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((uintmax_t *) 0) + return 0; +if (sizeof (uintmax_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uintmax_t=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_uintmax_t=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uintmax_t" >&5 +echo "${ECHO_T}$ac_cv_type_uintmax_t" >&6 +if test $ac_cv_type_uintmax_t = yes; then + : +else + + uintmax_t="unsigned long" + echo "$as_me:$LINENO: checking for unsigned long long" >&5 +echo $ECHO_N "checking for unsigned long long... $ECHO_C" >&6 +if test "${ac_cv_type_unsigned_long_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +if ((unsigned long long *) 0) + return 0; +if (sizeof (unsigned long long)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_unsigned_long_long=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_type_unsigned_long_long=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long_long" >&5 +echo "${ECHO_T}$ac_cv_type_unsigned_long_long" >&6 +if test $ac_cv_type_unsigned_long_long = yes; then + uintmax_t="unsigned long long" +fi + + +cat >>confdefs.h <<_ACEOF +#define uintmax_t $uintmax_t +_ACEOF + +fi + + +# Find out whether our struct stat returns nanosecond resolution timestamps. + +echo "$as_me:$LINENO: checking for nanoseconds field of struct stat.st_mtim" >&5 +echo $ECHO_N "checking for nanoseconds field of struct stat.st_mtim... $ECHO_C" >&6 +if test "${ac_cv_struct_st_mtim_nsec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_save_CPPFLAGS="$CPPFLAGS" + ac_cv_struct_st_mtim_nsec=no + # tv_nsec -- the usual case + # _tv_nsec -- Solaris 2.6, if + # (defined _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED == 1 + # && !defined __EXTENSIONS__) + # st__tim.tv_nsec -- UnixWare 2.1.2 + for ac_val in tv_nsec _tv_nsec st__tim.tv_nsec; do + CPPFLAGS="$ac_save_CPPFLAGS -DST_MTIM_NSEC=$ac_val" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +int +main () +{ +struct stat s; s.st_mtim.ST_MTIM_NSEC; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_struct_st_mtim_nsec=$ac_val; break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + done + CPPFLAGS="$ac_save_CPPFLAGS" +fi +echo "$as_me:$LINENO: result: $ac_cv_struct_st_mtim_nsec" >&5 +echo "${ECHO_T}$ac_cv_struct_st_mtim_nsec" >&6 + + if test $ac_cv_struct_st_mtim_nsec != no; then + +cat >>confdefs.h <<_ACEOF +#define ST_MTIM_NSEC $ac_cv_struct_st_mtim_nsec +_ACEOF + + fi + + +echo "$as_me:$LINENO: checking whether to use high resolution file timestamps" >&5 +echo $ECHO_N "checking whether to use high resolution file timestamps... $ECHO_C" >&6 +if test "${make_cv_file_timestamp_hi_res+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + make_cv_file_timestamp_hi_res=no + if test "$ac_cv_struct_st_mtim_nsec" != no; then + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +# if HAVE_INTTYPES_H +# include +# endif +int +main () +{ +char a[0x7fffffff < (uintmax_t) -1 >> 30 ? 1 : -1]; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + make_cv_file_timestamp_hi_res=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest.$ac_ext + fi +fi + +echo "$as_me:$LINENO: result: $make_cv_file_timestamp_hi_res" >&5 +echo "${ECHO_T}$make_cv_file_timestamp_hi_res" >&6 +if test "$make_cv_file_timestamp_hi_res" = yes; then + val=1 +else + val=0 +fi + +cat >>confdefs.h <<_ACEOF +#define FILE_TIMESTAMP_HI_RES $val +_ACEOF + + +if test "$make_cv_file_timestamp_hi_res" = yes; then + # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function. + # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4. + echo "$as_me:$LINENO: checking for library containing clock_gettime" >&5 +echo $ECHO_N "checking for library containing clock_gettime... $ECHO_C" >&6 +if test "${ac_cv_search_clock_gettime+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_clock_gettime=no +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char clock_gettime (); +int +main () +{ +clock_gettime (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_clock_gettime="none required" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_clock_gettime" = no; then + for ac_lib in rt posix4; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char clock_gettime (); +int +main () +{ +clock_gettime (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_clock_gettime="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_clock_gettime" >&5 +echo "${ECHO_T}$ac_cv_search_clock_gettime" >&6 +if test "$ac_cv_search_clock_gettime" != no; then + test "$ac_cv_search_clock_gettime" = "none required" || LIBS="$ac_cv_search_clock_gettime $LIBS" + +fi + + if test "$ac_cv_search_clock_gettime" != no; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_CLOCK_GETTIME 1 +_ACEOF + + fi +fi + + +# See if we have a standard version of gettimeofday(). Since actual +# implementations can differ, just make sure we have the most common +# one. +echo "$as_me:$LINENO: checking for standard gettimeofday" >&5 +echo $ECHO_N "checking for standard gettimeofday... $ECHO_C" >&6 +if test "${ac_cv_func_gettimeofday+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_func_gettimeofday=no + if test "$cross_compiling" = yes; then + ac_cv_func_gettimeofday="no (cross-compiling)" +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + int main () + { + struct timeval t; t.tv_sec = -1; t.tv_usec = -1; + exit (gettimeofday (&t, 0) != 0 + || t.tv_sec < 0 || t.tv_usec < 0); + } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gettimeofday=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_func_gettimeofday=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_gettimeofday" >&5 +echo "${ECHO_T}$ac_cv_func_gettimeofday" >&6 +if test "$ac_cv_func_gettimeofday" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETTIMEOFDAY 1 +_ACEOF + +fi + + + + + + + + + + + + + + + + + + + + + + + +for ac_func in memcpy memmove strchr strdup mkstemp mktemp fdopen \ + bsd_signal dup2 getcwd sigsetmask sigaction getgroups \ + seteuid setegid setlinebuf setreuid setregid setvbuf pipe \ + strerror strsignal +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +echo "$as_me:$LINENO: checking for function prototypes" >&5 +echo $ECHO_N "checking for function prototypes... $ECHO_C" >&6 +if test "$ac_cv_prog_cc_stdc" != no; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define PROTOTYPES 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define __PROTOTYPES 1 +_ACEOF + +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +echo "$as_me:$LINENO: checking whether setvbuf arguments are reversed" >&5 +echo $ECHO_N "checking whether setvbuf arguments are reversed... $ECHO_C" >&6 +if test "${ac_cv_func_setvbuf_reversed+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_func_setvbuf_reversed=no + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +# if PROTOTYPES + int (setvbuf) (FILE *, int, char *, size_t); +# endif +int +main () +{ +char buf; return setvbuf (stdout, _IOLBF, &buf, 1); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +# if PROTOTYPES + int (setvbuf) (FILE *, int, char *, size_t); +# endif +int +main () +{ +char buf; return setvbuf (stdout, &buf, _IOLBF, 1); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + # It compiles and links either way, so it must not be declared + # with a prototype and most likely this is a K&R C compiler. + # Try running it. + if test "$cross_compiling" = yes; then + : # Assume setvbuf is not reversed when cross-compiling. +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +int +main () +{ +/* This call has the arguments reversed. + A reversed system may check and see that the address of buf + is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ + char buf; + if (setvbuf (stdout, _IOLBF, &buf, 1) != 0) + exit (1); + putchar ('\r'); + exit (0); /* Non-reversed systems SEGV here. */ + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_setvbuf_reversed=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +rm -f core core.* *.core +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + ac_cv_func_setvbuf_reversed=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_setvbuf_reversed" >&5 +echo "${ECHO_T}$ac_cv_func_setvbuf_reversed" >&6 +if test $ac_cv_func_setvbuf_reversed = yes; then + +cat >>confdefs.h <<\_ACEOF +#define SETVBUF_REVERSED 1 +_ACEOF + +fi + + +# strcoll() is used by the GNU glob library +echo "$as_me:$LINENO: checking for working strcoll" >&5 +echo $ECHO_N "checking for working strcoll... $ECHO_C" >&6 +if test "${ac_cv_func_strcoll_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_strcoll_works=no +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +int +main () +{ +exit (strcoll ("abc", "def") >= 0 || + strcoll ("ABC", "DEF") >= 0 || + strcoll ("123", "456") >= 0) + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strcoll_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_func_strcoll_works=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_strcoll_works" >&5 +echo "${ECHO_T}$ac_cv_func_strcoll_works" >&6 +if test $ac_cv_func_strcoll_works = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STRCOLL 1 +_ACEOF + +fi + + +# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works +# for constant arguments. Useless! +echo "$as_me:$LINENO: checking for working alloca.h" >&5 +echo $ECHO_N "checking for working alloca.h... $ECHO_C" >&6 +if test "${ac_cv_working_alloca_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +int +main () +{ +char *p = (char *) alloca (2 * sizeof (int)); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_working_alloca_h=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_working_alloca_h=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 +echo "${ECHO_T}$ac_cv_working_alloca_h" >&6 +if test $ac_cv_working_alloca_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA_H 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for alloca" >&5 +echo $ECHO_N "checking for alloca... $ECHO_C" >&6 +if test "${ac_cv_func_alloca_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#ifdef __GNUC__ +# define alloca __builtin_alloca +#else +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +# endif +#endif + +int +main () +{ +char *p = (char *) alloca (1); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_alloca_works=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_alloca_works=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 +echo "${ECHO_T}$ac_cv_func_alloca_works" >&6 + +if test $ac_cv_func_alloca_works = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ALLOCA 1 +_ACEOF + +else + # The SVR3 libPW and SVR4 libucb both contain incompatible functions +# that cause trouble. Some versions do not even contain alloca or +# contain a buggy version. If you still want to use their alloca, +# use ar to extract alloca.o from them instead of compiling alloca.c. + +ALLOCA=alloca.$ac_objext + +cat >>confdefs.h <<\_ACEOF +#define C_ALLOCA 1 +_ACEOF + + +echo "$as_me:$LINENO: checking whether \`alloca.c' needs Cray hooks" >&5 +echo $ECHO_N "checking whether \`alloca.c' needs Cray hooks... $ECHO_C" >&6 +if test "${ac_cv_os_cray+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#if defined(CRAY) && ! defined(CRAY2) +webecray +#else +wenotbecray +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "webecray" >/dev/null 2>&1; then + ac_cv_os_cray=yes +else + ac_cv_os_cray=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_os_cray" >&5 +echo "${ECHO_T}$ac_cv_os_cray" >&6 +if test $ac_cv_os_cray = yes; then + for ac_func in _getb67 GETB67 getb67; do + as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + +cat >>confdefs.h <<_ACEOF +#define CRAY_STACKSEG_END $ac_func +_ACEOF + + break +fi + + done +fi + +echo "$as_me:$LINENO: checking stack direction for C alloca" >&5 +echo $ECHO_N "checking stack direction for C alloca... $ECHO_C" >&6 +if test "${ac_cv_c_stack_direction+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_c_stack_direction=0 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +int +find_stack_direction () +{ + static char *addr = 0; + auto char dummy; + if (addr == 0) + { + addr = &dummy; + return find_stack_direction (); + } + else + return (&dummy > addr) ? 1 : -1; +} + +int +main () +{ + exit (find_stack_direction () < 0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_stack_direction=1 +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_c_stack_direction=-1 +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_c_stack_direction" >&5 +echo "${ECHO_T}$ac_cv_c_stack_direction" >&6 + +cat >>confdefs.h <<_ACEOF +#define STACK_DIRECTION $ac_cv_c_stack_direction +_ACEOF + + +fi + + + +for ac_header in unistd.h vfork.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_func in fork vfork +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + echo "$as_me:$LINENO: checking for working fork" >&5 +echo $ECHO_N "checking for working fork... $ECHO_C" >&6 +if test "${ac_cv_func_fork_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_fork_works=cross +else + cat >conftest.$ac_ext <<_ACEOF +/* By Ruediger Kuhlmann. */ + #include + #if HAVE_UNISTD_H + # include + #endif + /* Some systems only have a dummy stub for fork() */ + int main () + { + if (fork() < 0) + exit (1); + exit (0); + } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_fork_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_func_fork_works=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5 +echo "${ECHO_T}$ac_cv_func_fork_works" >&6 + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + echo "$as_me:$LINENO: checking for working vfork" >&5 +echo $ECHO_N "checking for working vfork... $ECHO_C" >&6 +if test "${ac_cv_func_vfork_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_vfork_works=cross +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* Thanks to Paul Eggert for this test. */ +#include +#include +#include +#if HAVE_UNISTD_H +# include +#endif +#if HAVE_VFORK_H +# include +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include , but some compilers + (e.g. gcc -O) don't grok . Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + exit( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_vfork_works=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_func_vfork_works=no +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5 +echo "${ECHO_T}$ac_cv_func_vfork_works" >&6 + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=ac_cv_func_vfork + { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WORKING_VFORK 1 +_ACEOF + +else + +cat >>confdefs.h <<\_ACEOF +#define vfork fork +_ACEOF + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WORKING_FORK 1 +_ACEOF + +fi + + +for ac_func in vprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +echo "$as_me:$LINENO: checking for _doprnt" >&5 +echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6 +if test "${ac_cv_func__doprnt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _doprnt (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char _doprnt (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub__doprnt) || defined (__stub____doprnt) +choke me +#else +f = _doprnt; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func__doprnt=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func__doprnt=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 +echo "${ECHO_T}$ac_cv_func__doprnt" >&6 +if test $ac_cv_func__doprnt = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOPRNT 1 +_ACEOF + +fi + +fi +done + + +echo "$as_me:$LINENO: checking whether closedir returns void" >&5 +echo $ECHO_N "checking whether closedir returns void... $ECHO_C" >&6 +if test "${ac_cv_func_closedir_void+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_closedir_void=yes +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header_dirent> +#ifndef __cplusplus +int closedir (); +#endif + +int +main () +{ +exit (closedir (opendir (".")) != 0); + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_closedir_void=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +( exit $ac_status ) +ac_cv_func_closedir_void=yes +fi +rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_closedir_void" >&5 +echo "${ECHO_T}$ac_cv_func_closedir_void" >&6 +if test $ac_cv_func_closedir_void = yes; then + +cat >>confdefs.h <<\_ACEOF +#define CLOSEDIR_VOID 1 +_ACEOF + +fi + + +ac_have_func=no # yes means we've found a way to get the load average. + +# Make sure getloadavg.c is where it belongs, at configure-time. +test -f "$srcdir/$ac_config_libobj_dir/getloadavg.c" || + { { echo "$as_me:$LINENO: error: $srcdir/$ac_config_libobj_dir/getloadavg.c is missing" >&5 +echo "$as_me: error: $srcdir/$ac_config_libobj_dir/getloadavg.c is missing" >&2;} + { (exit 1); exit 1; }; } + +ac_save_LIBS=$LIBS + +# Check for getloadavg, but be sure not to touch the cache variable. +(echo "$as_me:$LINENO: checking for getloadavg" >&5 +echo $ECHO_N "checking for getloadavg... $ECHO_C" >&6 +if test "${ac_cv_func_getloadavg+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getloadavg (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getloadavg (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getloadavg) || defined (__stub___getloadavg) +choke me +#else +f = getloadavg; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_getloadavg=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_func_getloadavg=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_getloadavg" >&5 +echo "${ECHO_T}$ac_cv_func_getloadavg" >&6 +if test $ac_cv_func_getloadavg = yes; then + exit 0 +else + exit 1 +fi +) && ac_have_func=yes + +# On HPUX9, an unprivileged user can get load averages through this function. + +for ac_func in pstat_getdynamic +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# Solaris has libkstat which does not require root. + +echo "$as_me:$LINENO: checking for kstat_open in -lkstat" >&5 +echo $ECHO_N "checking for kstat_open in -lkstat... $ECHO_C" >&6 +if test "${ac_cv_lib_kstat_kstat_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkstat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char kstat_open (); +int +main () +{ +kstat_open (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_kstat_kstat_open=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_kstat_kstat_open=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_kstat_kstat_open" >&5 +echo "${ECHO_T}$ac_cv_lib_kstat_kstat_open" >&6 +if test $ac_cv_lib_kstat_kstat_open = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBKSTAT 1 +_ACEOF + + LIBS="-lkstat $LIBS" + +fi + +test $ac_cv_lib_kstat_kstat_open = yes && ac_have_func=yes + +# Some systems with -lutil have (and need) -lkvm as well, some do not. +# On Solaris, -lkvm requires nlist from -lelf, so check that first +# to get the right answer into the cache. +# For kstat on solaris, we need libelf to force the definition of SVR4 below. +if test $ac_have_func = no; then + echo "$as_me:$LINENO: checking for elf_begin in -lelf" >&5 +echo $ECHO_N "checking for elf_begin in -lelf... $ECHO_C" >&6 +if test "${ac_cv_lib_elf_elf_begin+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lelf $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char elf_begin (); +int +main () +{ +elf_begin (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_elf_elf_begin=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_elf_elf_begin=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_elf_elf_begin" >&5 +echo "${ECHO_T}$ac_cv_lib_elf_elf_begin" >&6 +if test $ac_cv_lib_elf_elf_begin = yes; then + LIBS="-lelf $LIBS" +fi + +fi +if test $ac_have_func = no; then + echo "$as_me:$LINENO: checking for kvm_open in -lkvm" >&5 +echo $ECHO_N "checking for kvm_open in -lkvm... $ECHO_C" >&6 +if test "${ac_cv_lib_kvm_kvm_open+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lkvm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char kvm_open (); +int +main () +{ +kvm_open (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_kvm_kvm_open=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_kvm_kvm_open=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_kvm_kvm_open" >&5 +echo "${ECHO_T}$ac_cv_lib_kvm_kvm_open" >&6 +if test $ac_cv_lib_kvm_kvm_open = yes; then + LIBS="-lkvm $LIBS" +fi + + # Check for the 4.4BSD definition of getloadavg. + echo "$as_me:$LINENO: checking for getloadavg in -lutil" >&5 +echo $ECHO_N "checking for getloadavg in -lutil... $ECHO_C" >&6 +if test "${ac_cv_lib_util_getloadavg+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lutil $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getloadavg (); +int +main () +{ +getloadavg (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_util_getloadavg=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_util_getloadavg=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_util_getloadavg" >&5 +echo "${ECHO_T}$ac_cv_lib_util_getloadavg" >&6 +if test $ac_cv_lib_util_getloadavg = yes; then + LIBS="-lutil $LIBS" ac_have_func=yes ac_cv_func_getloadavg_setgid=yes +fi + +fi + +if test $ac_have_func = no; then + # There is a commonly available library for RS/6000 AIX. + # Since it is not a standard part of AIX, it might be installed locally. + ac_getloadavg_LIBS=$LIBS + LIBS="-L/usr/local/lib $LIBS" + echo "$as_me:$LINENO: checking for getloadavg in -lgetloadavg" >&5 +echo $ECHO_N "checking for getloadavg in -lgetloadavg... $ECHO_C" >&6 +if test "${ac_cv_lib_getloadavg_getloadavg+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgetloadavg $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getloadavg (); +int +main () +{ +getloadavg (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_getloadavg_getloadavg=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_getloadavg_getloadavg=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_getloadavg_getloadavg" >&5 +echo "${ECHO_T}$ac_cv_lib_getloadavg_getloadavg" >&6 +if test $ac_cv_lib_getloadavg_getloadavg = yes; then + LIBS="-lgetloadavg $LIBS" +else + LIBS=$ac_getloadavg_LIBS +fi + +fi + +# Make sure it is really in the library, if we think we found it, +# otherwise set up the replacement function. + +for ac_func in getloadavg +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + LIBOBJS="$LIBOBJS getloadavg.$ac_objext" + +cat >>confdefs.h <<\_ACEOF +#define C_GETLOADAVG 1 +_ACEOF + +# Figure out what our getloadavg.c needs. +ac_have_func=no +if test "${ac_cv_header_sys_dg_sys_info_h+set}" = set; then + echo "$as_me:$LINENO: checking for sys/dg_sys_info.h" >&5 +echo $ECHO_N "checking for sys/dg_sys_info.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_dg_sys_info_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_dg_sys_info_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_dg_sys_info_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking sys/dg_sys_info.h usability" >&5 +echo $ECHO_N "checking sys/dg_sys_info.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking sys/dg_sys_info.h presence" >&5 +echo $ECHO_N "checking sys/dg_sys_info.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/dg_sys_info.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/dg_sys_info.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/dg_sys_info.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/dg_sys_info.h: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for sys/dg_sys_info.h" >&5 +echo $ECHO_N "checking for sys/dg_sys_info.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_dg_sys_info_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_dg_sys_info_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_dg_sys_info_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_dg_sys_info_h" >&6 + +fi +if test $ac_cv_header_sys_dg_sys_info_h = yes; then + ac_have_func=yes + +cat >>confdefs.h <<\_ACEOF +#define DGUX 1 +_ACEOF + + +echo "$as_me:$LINENO: checking for dg_sys_info in -ldgc" >&5 +echo $ECHO_N "checking for dg_sys_info in -ldgc... $ECHO_C" >&6 +if test "${ac_cv_lib_dgc_dg_sys_info+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldgc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dg_sys_info (); +int +main () +{ +dg_sys_info (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_dgc_dg_sys_info=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_dgc_dg_sys_info=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_dgc_dg_sys_info" >&5 +echo "${ECHO_T}$ac_cv_lib_dgc_dg_sys_info" >&6 +if test $ac_cv_lib_dgc_dg_sys_info = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBDGC 1 +_ACEOF + + LIBS="-ldgc $LIBS" + +fi + +fi + + + +if test "${ac_cv_header_locale_h+set}" = set; then + echo "$as_me:$LINENO: checking for locale.h" >&5 +echo $ECHO_N "checking for locale.h... $ECHO_C" >&6 +if test "${ac_cv_header_locale_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5 +echo "${ECHO_T}$ac_cv_header_locale_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking locale.h usability" >&5 +echo $ECHO_N "checking locale.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking locale.h presence" >&5 +echo $ECHO_N "checking locale.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: locale.h: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: locale.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: locale.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: locale.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: locale.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: locale.h: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for locale.h" >&5 +echo $ECHO_N "checking for locale.h... $ECHO_C" >&6 +if test "${ac_cv_header_locale_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_locale_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5 +echo "${ECHO_T}$ac_cv_header_locale_h" >&6 + +fi + + + +for ac_func in setlocale +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# We cannot check for , because Solaris 2 does not use dwarf (it +# uses stabs), but it is still SVR4. We cannot check for because +# Irix 4.0.5F has the header but not the library. +if test $ac_have_func = no && test "$ac_cv_lib_elf_elf_begin" = yes; then + ac_have_func=yes + +cat >>confdefs.h <<\_ACEOF +#define SVR4 1 +_ACEOF + +fi + +if test $ac_have_func = no; then + if test "${ac_cv_header_inq_stats_cpustats_h+set}" = set; then + echo "$as_me:$LINENO: checking for inq_stats/cpustats.h" >&5 +echo $ECHO_N "checking for inq_stats/cpustats.h... $ECHO_C" >&6 +if test "${ac_cv_header_inq_stats_cpustats_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_inq_stats_cpustats_h" >&5 +echo "${ECHO_T}$ac_cv_header_inq_stats_cpustats_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking inq_stats/cpustats.h usability" >&5 +echo $ECHO_N "checking inq_stats/cpustats.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking inq_stats/cpustats.h presence" >&5 +echo $ECHO_N "checking inq_stats/cpustats.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: inq_stats/cpustats.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: inq_stats/cpustats.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: inq_stats/cpustats.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: inq_stats/cpustats.h: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: inq_stats/cpustats.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: inq_stats/cpustats.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: inq_stats/cpustats.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: inq_stats/cpustats.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: inq_stats/cpustats.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: inq_stats/cpustats.h: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for inq_stats/cpustats.h" >&5 +echo $ECHO_N "checking for inq_stats/cpustats.h... $ECHO_C" >&6 +if test "${ac_cv_header_inq_stats_cpustats_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_inq_stats_cpustats_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_inq_stats_cpustats_h" >&5 +echo "${ECHO_T}$ac_cv_header_inq_stats_cpustats_h" >&6 + +fi +if test $ac_cv_header_inq_stats_cpustats_h = yes; then + ac_have_func=yes + +cat >>confdefs.h <<\_ACEOF +#define UMAX 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define UMAX4_3 1 +_ACEOF + +fi + + +fi + +if test $ac_have_func = no; then + if test "${ac_cv_header_sys_cpustats_h+set}" = set; then + echo "$as_me:$LINENO: checking for sys/cpustats.h" >&5 +echo $ECHO_N "checking for sys/cpustats.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_cpustats_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_cpustats_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_cpustats_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking sys/cpustats.h usability" >&5 +echo $ECHO_N "checking sys/cpustats.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking sys/cpustats.h presence" >&5 +echo $ECHO_N "checking sys/cpustats.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: sys/cpustats.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/cpustats.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/cpustats.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/cpustats.h: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: sys/cpustats.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/cpustats.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/cpustats.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/cpustats.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/cpustats.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/cpustats.h: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for sys/cpustats.h" >&5 +echo $ECHO_N "checking for sys/cpustats.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_cpustats_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_cpustats_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_cpustats_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_cpustats_h" >&6 + +fi +if test $ac_cv_header_sys_cpustats_h = yes; then + ac_have_func=yes; cat >>confdefs.h <<\_ACEOF +#define UMAX 1 +_ACEOF + +fi + + +fi + +if test $ac_have_func = no; then + +for ac_header in mach/mach.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + +fi + + +for ac_header in nlist.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + echo "$as_me:$LINENO: checking for struct nlist.n_un.n_name" >&5 +echo $ECHO_N "checking for struct nlist.n_un.n_name... $ECHO_C" >&6 +if test "${ac_cv_member_struct_nlist_n_un_n_name+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +int +main () +{ +static struct nlist ac_aggr; +if (ac_aggr.n_un.n_name) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_nlist_n_un_n_name=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include + +int +main () +{ +static struct nlist ac_aggr; +if (sizeof ac_aggr.n_un.n_name) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_nlist_n_un_n_name=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_member_struct_nlist_n_un_n_name=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_nlist_n_un_n_name" >&5 +echo "${ECHO_T}$ac_cv_member_struct_nlist_n_un_n_name" >&6 +if test $ac_cv_member_struct_nlist_n_un_n_name = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_NLIST_N_UN_N_NAME 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define NLIST_NAME_UNION 1 +_ACEOF + +fi + + +fi + +done + +fi +done + + +# Some definitions of getloadavg require that the program be installed setgid. +echo "$as_me:$LINENO: checking whether getloadavg requires setgid" >&5 +echo $ECHO_N "checking whether getloadavg requires setgid... $ECHO_C" >&6 +if test "${ac_cv_func_getloadavg_setgid+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include "$srcdir/$ac_config_libobj_dir/getloadavg.c" +#ifdef LDAV_PRIVILEGED +Yowza Am I SETGID yet +#endif +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "Yowza Am I SETGID yet" >/dev/null 2>&1; then + ac_cv_func_getloadavg_setgid=yes +else + ac_cv_func_getloadavg_setgid=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_func_getloadavg_setgid" >&5 +echo "${ECHO_T}$ac_cv_func_getloadavg_setgid" >&6 +if test $ac_cv_func_getloadavg_setgid = yes; then + NEED_SETGID=true + +cat >>confdefs.h <<\_ACEOF +#define GETLOADAVG_PRIVILEGED 1 +_ACEOF + +else + NEED_SETGID=false +fi + +if test $ac_cv_func_getloadavg_setgid = yes; then + echo "$as_me:$LINENO: checking group of /dev/kmem" >&5 +echo $ECHO_N "checking group of /dev/kmem... $ECHO_C" >&6 +if test "${ac_cv_group_kmem+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # On Solaris, /dev/kmem is a symlink. Get info on the real file. + ac_ls_output=`ls -lgL /dev/kmem 2>/dev/null` + # If we got an error (system does not support symlinks), try without -L. + test -z "$ac_ls_output" && ac_ls_output=`ls -lg /dev/kmem` + ac_cv_group_kmem=`echo $ac_ls_output \ + | sed -ne 's/[ ][ ]*/ /g; + s/^.[sSrwx-]* *[0-9]* *\([^0-9]*\) *.*/\1/; + / /s/.* //;p;'` + +fi +echo "$as_me:$LINENO: result: $ac_cv_group_kmem" >&5 +echo "${ECHO_T}$ac_cv_group_kmem" >&6 + KMEM_GROUP=$ac_cv_group_kmem +fi +if test "x$ac_save_LIBS" = x; then + GETLOADAVG_LIBS=$LIBS +else + GETLOADAVG_LIBS=`echo "$LIBS" | sed "s!$ac_save_LIBS!!"` +fi +LIBS=$ac_save_LIBS + + + +# AC_FUNC_GETLOADAVG is documented to set the NLIST_STRUCT value, but it +# doesn't. So, we will. + +if test "$ac_cv_header_nlist_h" = yes; then + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +int +main () +{ +struct nlist nl; + nl.n_name = "string"; + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + make_cv_nlist_struct=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +make_cv_nlist_struct=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext + if test "$make_cv_nlist_struct" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define NLIST_STRUCT 1 +_ACEOF + + fi +fi + +echo "$as_me:$LINENO: checking for sys_siglist declaration in signal.h or unistd.h" >&5 +echo $ECHO_N "checking for sys_siglist declaration in signal.h or unistd.h... $ECHO_C" >&6 +if test "${ac_cv_decl_sys_siglist+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +/* NetBSD declares sys_siglist in unistd.h. */ +#if HAVE_UNISTD_H +# include +#endif + +int +main () +{ +char *msg = *(sys_siglist + 1); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_decl_sys_siglist=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_decl_sys_siglist=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_decl_sys_siglist" >&5 +echo "${ECHO_T}$ac_cv_decl_sys_siglist" >&6 +if test $ac_cv_decl_sys_siglist = yes; then + +cat >>confdefs.h <<\_ACEOF +#define SYS_SIGLIST_DECLARED 1 +_ACEOF + +fi + + +# Check out the wait reality. + +for ac_header in sys/wait.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +for ac_func in waitpid wait3 +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +echo "$as_me:$LINENO: checking for union wait" >&5 +echo $ECHO_N "checking for union wait... $ECHO_C" >&6 +if test "${make_cv_union_wait+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +#include +int +main () +{ +union wait status; int pid; pid = wait (&status); +#ifdef WEXITSTATUS +/* Some POSIXoid systems have both the new-style macros and the old + union wait type, and they do not work together. If union wait + conflicts with WEXITSTATUS et al, we don't want to use it at all. */ +if (WEXITSTATUS (status) != 0) pid = -1; +#ifdef WTERMSIG +/* If we have WEXITSTATUS and WTERMSIG, just use them on ints. */ +-- blow chunks here -- +#endif +#endif +#ifdef HAVE_WAITPID +/* Make sure union wait works with waitpid. */ +pid = waitpid (-1, &status, 0); +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + make_cv_union_wait=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +make_cv_union_wait=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi + +if test "$make_cv_union_wait" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_UNION_WAIT 1 +_ACEOF + +fi +echo "$as_me:$LINENO: result: $make_cv_union_wait" >&5 +echo "${ECHO_T}$make_cv_union_wait" >&6 + + +# See if the user wants to use pmake's "customs" distributed build capability + +use_customs=false + +# Check whether --with-customs or --without-customs was given. +if test "${with_customs+set}" = set; then + withval="$with_customs" + case $withval in + n|no) : ;; + *) make_cppflags="$CPPFLAGS" + case $withval in + y|ye|yes) : ;; + *) CPPFLAGS="$CPPFLAGS -I$with_customs/include/customs" + make_ldflags="$LDFLAGS -L$with_customs/lib" ;; + esac + +cf_test_netlibs=no +echo "$as_me:$LINENO: checking for network libraries" >&5 +echo $ECHO_N "checking for network libraries... $ECHO_C" >&6 +if test "${cf_cv_netlibs+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +echo "$as_me:$LINENO: result: working..." >&5 +echo "${ECHO_T}working..." >&6 +cf_cv_netlibs="" +cf_test_netlibs=yes + +for ac_func in gethostname +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + + +echo "$as_me:$LINENO: checking for gethostname in -lnsl" >&5 +echo $ECHO_N "checking for gethostname in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_gethostname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $cf_cv_netlibs $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostname (); +int +main () +{ +gethostname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_gethostname=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_nsl_gethostname=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostname" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_gethostname" >&6 +if test $ac_cv_lib_nsl_gethostname = yes; then + + +cf_tr_func=`echo gethostname | tr '[a-z]' '[A-Z]'` + + +cat >>confdefs.h <<_ACEOF +#define HAVE_$cf_tr_func 1 +_ACEOF + + ac_cv_func_gethostname=yes + cf_cv_netlibs="-lnsl $cf_cv_netlibs" +else + + ac_cv_func_gethostname=unknown + unset ac_cv_func_gethostname 2>/dev/null + + +echo "$as_me:$LINENO: checking for gethostname in -lsocket" >&5 +echo $ECHO_N "checking for gethostname in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_gethostname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $cf_cv_netlibs $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostname (); +int +main () +{ +gethostname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_gethostname=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_socket_gethostname=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_gethostname" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_gethostname" >&6 +if test $ac_cv_lib_socket_gethostname = yes; then + + +cf_tr_func=`echo gethostname | tr '[a-z]' '[A-Z]'` + + +cat >>confdefs.h <<_ACEOF +#define HAVE_$cf_tr_func 1 +_ACEOF + + ac_cv_func_gethostname=yes + cf_cv_netlibs="-lsocket $cf_cv_netlibs" +else + + ac_cv_func_gethostname=unknown + unset ac_cv_func_gethostname 2>/dev/null + +fi + + +fi + + +fi +done + +# +# FIXME: sequent needs this library (i.e., -lsocket -linet -lnsl), but +# I don't know the entrypoints - 97/7/22 TD +echo "$as_me:$LINENO: checking for main in -linet" >&5 +echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6 +if test "${ac_cv_lib_inet_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-linet $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_inet_main=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_inet_main=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5 +echo "${ECHO_T}$ac_cv_lib_inet_main" >&6 +if test $ac_cv_lib_inet_main = yes; then + cf_cv_netlibs="-linet $cf_cv_netlibs" +fi + +# +if test "$ac_cv_func_lsocket" != no ; then + +for ac_func in socket +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + + +echo "$as_me:$LINENO: checking for socket in -lsocket" >&5 +echo $ECHO_N "checking for socket in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $cf_cv_netlibs $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_socket=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_socket_socket=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_socket" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_socket" >&6 +if test $ac_cv_lib_socket_socket = yes; then + + +cf_tr_func=`echo socket | tr '[a-z]' '[A-Z]'` + + +cat >>confdefs.h <<_ACEOF +#define HAVE_$cf_tr_func 1 +_ACEOF + + ac_cv_func_socket=yes + cf_cv_netlibs="-lsocket $cf_cv_netlibs" +else + + ac_cv_func_socket=unknown + unset ac_cv_func_socket 2>/dev/null + + +echo "$as_me:$LINENO: checking for socket in -lbsd" >&5 +echo $ECHO_N "checking for socket in -lbsd... $ECHO_C" >&6 +if test "${ac_cv_lib_bsd_socket+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $cf_cv_netlibs $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char socket (); +int +main () +{ +socket (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_bsd_socket=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_bsd_socket=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_socket" >&5 +echo "${ECHO_T}$ac_cv_lib_bsd_socket" >&6 +if test $ac_cv_lib_bsd_socket = yes; then + + +cf_tr_func=`echo socket | tr '[a-z]' '[A-Z]'` + + +cat >>confdefs.h <<_ACEOF +#define HAVE_$cf_tr_func 1 +_ACEOF + + ac_cv_func_socket=yes + cf_cv_netlibs="-lbsd $cf_cv_netlibs" +else + + ac_cv_func_socket=unknown + unset ac_cv_func_socket 2>/dev/null + +fi + + +fi + + +fi +done + +fi +# + +for ac_func in gethostbyname +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + + +echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 +echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $cf_cv_netlibs $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_nsl_gethostbyname=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 +if test $ac_cv_lib_nsl_gethostbyname = yes; then + + +cf_tr_func=`echo gethostbyname | tr '[a-z]' '[A-Z]'` + + +cat >>confdefs.h <<_ACEOF +#define HAVE_$cf_tr_func 1 +_ACEOF + + ac_cv_func_gethostbyname=yes + cf_cv_netlibs="-lnsl $cf_cv_netlibs" +else + + ac_cv_func_gethostbyname=unknown + unset ac_cv_func_gethostbyname 2>/dev/null + +fi + + +fi +done + +# + +for ac_func in strcasecmp +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. */ +#include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +char (*f) (); + +int +main () +{ +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +f = $ac_func; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +eval "$as_ac_var=no" +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else + + +echo "$as_me:$LINENO: checking for strcasecmp in -lresolv" >&5 +echo $ECHO_N "checking for strcasecmp in -lresolv... $ECHO_C" >&6 +if test "${ac_cv_lib_resolv_strcasecmp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lresolv $cf_cv_netlibs $LIBS" +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strcasecmp (); +int +main () +{ +strcasecmp (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_resolv_strcasecmp=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_cv_lib_resolv_strcasecmp=no +fi +rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_strcasecmp" >&5 +echo "${ECHO_T}$ac_cv_lib_resolv_strcasecmp" >&6 +if test $ac_cv_lib_resolv_strcasecmp = yes; then + + +cf_tr_func=`echo strcasecmp | tr '[a-z]' '[A-Z]'` + + +cat >>confdefs.h <<_ACEOF +#define HAVE_$cf_tr_func 1 +_ACEOF + + ac_cv_func_strcasecmp=yes + cf_cv_netlibs="-lresolv $cf_cv_netlibs" +else + + ac_cv_func_strcasecmp=unknown + unset ac_cv_func_strcasecmp 2>/dev/null + +fi + + +fi +done + + +fi + +LIBS="$LIBS $cf_cv_netlibs" +test $cf_test_netlibs = no && echo "$cf_cv_netlibs" >&6 + + if test "${ac_cv_header_customs_h+set}" = set; then + echo "$as_me:$LINENO: checking for customs.h" >&5 +echo $ECHO_N "checking for customs.h... $ECHO_C" >&6 +if test "${ac_cv_header_customs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_customs_h" >&5 +echo "${ECHO_T}$ac_cv_header_customs_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking customs.h usability" >&5 +echo $ECHO_N "checking customs.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +ac_header_compiler=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking customs.h presence" >&5 +echo $ECHO_N "checking customs.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: customs.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: customs.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: customs.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: customs.h: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: customs.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: customs.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: customs.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: customs.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: customs.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: customs.h: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for customs.h" >&5 +echo $ECHO_N "checking for customs.h... $ECHO_C" >&6 +if test "${ac_cv_header_customs_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_customs_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_customs_h" >&5 +echo "${ECHO_T}$ac_cv_header_customs_h" >&6 + +fi +if test $ac_cv_header_customs_h = yes; then + use_customs=true + LIBS="$LIBS -lcustoms" LDFLAGS="$make_ldflags" +else + with_customs=no + CPPFLAGS="$make_cppflags" make_badcust=yes +fi + + + ;; + esac +fi; +# Tell automake about this, so it can include the right .c files. + + +if test "$use_customs" = true; then + USE_CUSTOMS_TRUE= + USE_CUSTOMS_FALSE='#' +else + USE_CUSTOMS_TRUE='#' + USE_CUSTOMS_FALSE= +fi + + +# See if we can handle the job server feature, and if the user wants it. + +# Check whether --enable-job-server or --disable-job-server was given. +if test "${enable_job_server+set}" = set; then + enableval="$enable_job_server" + make_cv_job_server="$enableval" user_job_server="$enableval" +else + make_cv_job_server="yes" +fi; + +has_wait_nohang=yes +case "$ac_cv_func_waitpid/$ac_cv_func_wait3" in + no/no) has_wait_nohang=no ;; +esac + +echo "$as_me:$LINENO: checking for SA_RESTART" >&5 +echo $ECHO_N "checking for SA_RESTART... $ECHO_C" >&6 +if test "${make_cv_sa_restart+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include +int +main () +{ +return SA_RESTART; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + make_cv_sa_restart=yes +else + echo "$as_me: failed program was:" >&5 +cat conftest.$ac_ext >&5 +make_cv_sa_restart=no +fi +rm -f conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $make_cv_sa_restart" >&5 +echo "${ECHO_T}$make_cv_sa_restart" >&6 +if test "$make_cv_sa_restart" != no; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SA_RESTART 1 +_ACEOF + +fi + +case "$ac_cv_func_pipe/$ac_cv_func_sigaction/$make_cv_sa_restart/$has_wait_nohang/$make_cv_job_server" in + yes/yes/yes/yes/yes) + +cat >>confdefs.h <<\_ACEOF +#define MAKE_JOBSERVER 1 +_ACEOF +;; +esac + +# Find the SCCS commands, so we can include them in our default rules. + +echo "$as_me:$LINENO: checking for location of SCCS get command" >&5 +echo $ECHO_N "checking for location of SCCS get command... $ECHO_C" >&6 +if test "${make_cv_path_sccs_get+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + +if test -f /usr/sccs/get; then + make_cv_path_sccs_get=/usr/sccs/get +else + make_cv_path_sccs_get=get +fi +fi +echo "$as_me:$LINENO: result: $make_cv_path_sccs_get" >&5 +echo "${ECHO_T}$make_cv_path_sccs_get" >&6 + +cat >>confdefs.h <<_ACEOF +#define SCCS_GET "$make_cv_path_sccs_get" +_ACEOF + + +ac_clean_files="$ac_clean_files s.conftest conftoast" # Remove these later. +if ( /usr/sccs/admin -n s.conftest || admin -n s.conftest ) >/dev/null 2>&1 && + test -f s.conftest; then + # We successfully created an SCCS file. + echo "$as_me:$LINENO: checking if SCCS get command understands -G" >&5 +echo $ECHO_N "checking if SCCS get command understands -G... $ECHO_C" >&6 +if test "${make_cv_sys_get_minus_G+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + if $make_cv_path_sccs_get -Gconftoast s.conftest >/dev/null 2>&1 && + test -f conftoast; then + make_cv_sys_get_minus_G=yes + else + make_cv_sys_get_minus_G=no + fi +fi +echo "$as_me:$LINENO: result: $make_cv_sys_get_minus_G" >&5 +echo "${ECHO_T}$make_cv_sys_get_minus_G" >&6 + case "$make_cv_sys_get_minus_G" in + yes) +cat >>confdefs.h <<\_ACEOF +#define SCCS_GET_MINUS_G 1 +_ACEOF +;; + esac +fi +rm -f s.conftest conftoast + +# Check the system to see if it provides GNU glob. If not, use our +# local version. + +echo "$as_me:$LINENO: checking if system libc has GNU glob" >&5 +echo $ECHO_N "checking if system libc has GNU glob... $ECHO_C" >&6 +if test "${make_cv_sys_gnu_glob+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" + +#include +#include +#include + +#define GLOB_INTERFACE_VERSION 1 +#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 +# include +# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION + gnu glob +# endif +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "gnu glob" >/dev/null 2>&1; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +make_cv_sys_gnu_glob=yes +else + echo "$as_me:$LINENO: result: no; using local copy" >&5 +echo "${ECHO_T}no; using local copy" >&6 + GLOBINC='-I$(srcdir)/glob' + GLOBLIB=glob/libglob.a +make_cv_sys_gnu_glob=no +fi +rm -f conftest* + +fi + +# Tell automake about this, so it can build the right .c files. + + +if test "$make_cv_sys_gnu_glob" = no; then + USE_LOCAL_GLOB_TRUE= + USE_LOCAL_GLOB_FALSE='#' +else + USE_LOCAL_GLOB_TRUE='#' + USE_LOCAL_GLOB_FALSE= +fi + + +# PTX systems have a broken implementation of SA_RESTART. I know of +# no way to test for this behavior, so I'll just test for PTX + +case "$host" in + i386-sequent-sysv4) + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BROKEN_RESTART 1 +_ACEOF + + echo "" + echo "WARNING: The SA_RESTART sigaction() flag does not work on PTX." + echo " This causes 'make -j' to fail at random times." + echo " I am installing a workaround, which is mostly but not 100%" + echo " effective. If you see random failures during 'make -j'" + echo " you should either contact the bug list, or not use -j." + echo "" ;; +esac + +# Let the makefile know what our build host is + + +cat >>confdefs.h <<_ACEOF +#define MAKE_HOST "$host" +_ACEOF + +MAKE_HOST="$host" + + +# Include the Maintainer's Makefile section, if it's here. + +MAINT_MAKEFILE=/dev/null +if test -r "$srcdir/maintMakefile"; then + MAINT_MAKEFILE="$srcdir/maintMakefile" +fi + + +# Allow building with dmalloc +echo "$as_me:$LINENO: checking if malloc debugging is wanted" >&5 +echo $ECHO_N "checking if malloc debugging is wanted... $ECHO_C" >&6 + +# Check whether --with-dmalloc or --without-dmalloc was given. +if test "${with_dmalloc+set}" = set; then + withval="$with_dmalloc" + if test "$withval" = yes; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +cat >>confdefs.h <<\_ACEOF +#define WITH_DMALLOC 1 +_ACEOF + + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi; + + + +# Sanity check and inform the user of what we found + +case "$make_badcust" in + yes) echo + echo "WARNING: --with-customs specified but no customs.h could be found;" + echo " disabling Customs support." + echo ;; +esac + +case "$with_customs" in + ""|n|no|y|ye|yes) ;; + *) if test -f "$with_customs/lib/libcustoms.a"; then + : + else + echo + echo "WARNING: '$with_customs/lib' does not appear to contain the" + echo " Customs library. You must build and install Customs" + echo " before compiling GNU make." + echo + fi ;; +esac + +case "$has_wait_nohang" in + no) echo + echo "WARNING: Your system has neither waitpid() nor wait3()." + echo " Without one of these, signal handling is unreliable." + echo " You should be aware that running GNU make with -j" + echo " could result in erratic behavior." + echo ;; +esac + +case "$make_cv_job_server/$user_job_server" in + no/yes) echo + echo "WARNING: Make job server requires a POSIX-ish system that" + echo " supports the pipe(), sigaction(), and either" + echo " waitpid() or wait3() functions. Your system doesn't" + echo " appear to provide one or more of those." + echo " Disabling job server support." + echo ;; +esac + + +# Specify what files are to be created. +# We only generate the build.sh if we have a build.sh.in; we won't have +# one before we've created a distribution. + + ac_config_files="$ac_config_files Makefile glob/Makefile po/Makefile.in config/Makefile doc/Makefile" + + +if test -f $srcdir/build.sh.in; then + ac_config_files="$ac_config_files build.sh" + +fi + + +# OK, do it! + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if cmp -s $cache_file confcache; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${USE_CUSTOMS_TRUE}" && test -z "${USE_CUSTOMS_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"USE_CUSTOMS\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"USE_CUSTOMS\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${USE_LOCAL_GLOB_TRUE}" && test -z "${USE_LOCAL_GLOB_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"USE_LOCAL_GLOB\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"USE_LOCAL_GLOB\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi + +# Support unset when possible. +if (FOO=FOO; unset FOO) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME +do + if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conftest.sh + echo "exit 0" >>conftest.sh + chmod +x conftest.sh + if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conftest.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by GNU make $as_me 3.80, which was +generated by GNU Autoconf 2.54. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +GNU make config.status 3.80 +configured by $0, generated by GNU Autoconf 2.54, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion" + exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;; +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it + # from automake. + eval 'ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "glob/Makefile" ) CONFIG_FILES="$CONFIG_FILES glob/Makefile" ;; + "po/Makefile.in" ) CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; + "config/Makefile" ) CONFIG_FILES="$CONFIG_FILES config/Makefile" ;; + "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "build.sh" ) CONFIG_FILES="$CONFIG_FILES build.sh" ;; + "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "default-1" ) CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. +: ${TMPDIR=/tmp} +{ + tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=$TMPDIR/cs$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in $TMPDIR" >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CYGPATH_W@,$CYGPATH_W,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@AMTAR@,$AMTAR,;t t +s,@install_sh@,$install_sh,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t +s,@AWK@,$AWK,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@DEPDIR@,$DEPDIR,;t t +s,@am__include@,$am__include,;t t +s,@am__quote@,$am__quote,;t t +s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t +s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t +s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t +s,@CCDEPMODE@,$CCDEPMODE,;t t +s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t +s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@CPP@,$CPP,;t t +s,@AR@,$AR,;t t +s,@PERL@,$PERL,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t +s,@EGREP@,$EGREP,;t t +s,@MKINSTALLDIRS@,$MKINSTALLDIRS,;t t +s,@MSGFMT@,$MSGFMT,;t t +s,@GMSGFMT@,$GMSGFMT,;t t +s,@XGETTEXT@,$XGETTEXT,;t t +s,@MSGMERGE@,$MSGMERGE,;t t +s,@USE_NLS@,$USE_NLS,;t t +s,@LIBICONV@,$LIBICONV,;t t +s,@LTLIBICONV@,$LTLIBICONV,;t t +s,@INTLLIBS@,$INTLLIBS,;t t +s,@LIBINTL@,$LIBINTL,;t t +s,@LTLIBINTL@,$LTLIBINTL,;t t +s,@POSUB@,$POSUB,;t t +s,@ALLOCA@,$ALLOCA,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@NEED_SETGID@,$NEED_SETGID,;t t +s,@KMEM_GROUP@,$KMEM_GROUP,;t t +s,@GETLOADAVG_LIBS@,$GETLOADAVG_LIBS,;t t +s,@USE_CUSTOMS_TRUE@,$USE_CUSTOMS_TRUE,;t t +s,@USE_CUSTOMS_FALSE@,$USE_CUSTOMS_FALSE,;t t +s,@GLOBINC@,$GLOBINC,;t t +s,@GLOBLIB@,$GLOBLIB,;t t +s,@USE_LOCAL_GLOB_TRUE@,$USE_LOCAL_GLOB_TRUE,;t t +s,@USE_LOCAL_GLOB_FALSE@,$USE_LOCAL_GLOB_FALSE,;t t +s,@MAKE_HOST@,$MAKE_HOST,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +/@MAINT_MAKEFILE@/r $MAINT_MAKEFILE +s,@MAINT_MAKEFILE@,,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo $f;; + *) # Relative + if test -f "$f"; then + # Build tree + echo $f + elif test -f "$srcdir/$f"; then + # Source tree + echo $srcdir/$f + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if cmp -s $ac_file $tmp/config.h 2>/dev/null; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +_am_stamp_count=`expr ${_am_stamp_count-0} + 1` +echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'`/stamp-h$_am_stamp_count +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac +# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be +# absolute. +ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` +ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` +ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` +ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`(dirname "$mf") 2>/dev/null || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + else + continue + fi + grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`(dirname "$file") 2>/dev/null || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 +echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + { (exit 1); exit 1; }; }; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + default-1 ) + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + fi + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + GMOFILES= + UPDATEPOFILES= + DUMMYPOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + exec 5>/dev/null + $SHELL $CONFIG_STATUS || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + + + diff --git a/src/make-3.80/configure.bat b/src/make-3.80/configure.bat new file mode 100755 index 00000000..a3579239 --- /dev/null +++ b/src/make-3.80/configure.bat @@ -0,0 +1,44 @@ +@echo off +echo Configuring MAKE for DJGPP + +rem The SmallEnv trick protects against too small environment block, +rem in which case the values will be truncated and the whole thing +rem goes awry. COMMAND.COM will say "Out of environment space", but +rem many people don't care, so we force them to care by refusing to go. + +rem Where is the srcdir? +set XSRC=. +if not "%XSRC%"=="." goto SmallEnv +if "%1%"=="" goto SrcDone +set XSRC=%1 +if not "%XSRC%"=="%1" goto SmallEnv + +:SrcDone + +update %XSRC%/configh.dos ./config.h + +rem Do they have Make? +redir -o junk.$$$ -eo make -n -f NUL +rem REDIR will return 1 if it cannot run Make. +rem If it can run Make, it will usually return 2, +rem but 0 is also OK with us. +if errorlevel 2 goto MakeOk +if not errorlevel 1 goto MakeOk +if exist junk.$$$ del junk.$$$ +echo No Make program found--use DOSBUILD.BAT to build Make. +goto End + +rem They do have Make. Generate the Makefile. + +:MakeOk +del junk.$$$ +update %XSRC%/Makefile.DOS ./Makefile +echo Done. +if not "%XSRC%"=="." echo Invoke Make thus: "make srcdir=%XSRC%" +goto End + +:SmallEnv +echo Your environment is too small. Please enlarge it and run me again. + +:End +set XRSC= diff --git a/src/make-3.80/configure.in b/src/make-3.80/configure.in new file mode 100755 index 00000000..bca2bd38 --- /dev/null +++ b/src/make-3.80/configure.in @@ -0,0 +1,390 @@ +# Process this file with autoconf to produce a configure script. + +AC_INIT(GNU make,3.80,bug-make@gnu.org) + +AC_PREREQ(2.54) + +AC_REVISION([[$Id: configure.in,v 1.114 2002/10/03 05:46:12 psmith Exp $]]) + +# Autoconf setup +AC_CONFIG_AUX_DIR(config) +AC_CONFIG_SRCDIR(vpath.c) +AC_CONFIG_HEADERS(config.h) + +# Automake setup +AM_INIT_AUTOMAKE +AC_PROG_MAKE_SET + +# Checks for programs. +AC_PROG_CC +AC_PROG_INSTALL +AC_PROG_RANLIB +AC_PROG_CPP +AC_CHECK_PROG(AR, ar, ar, ar) +# Perl is needed for the test suite (only) +AC_CHECK_PROG(PERL, perl, perl, perl) + +# Specialized system macros +AC_CANONICAL_HOST +AC_AIX +AC_ISC_POSIX +AC_MINIX + +# Enable gettext, in "external" mode. + +AM_GNU_GETTEXT_VERSION(0.11.5) +AM_GNU_GETTEXT([external]) + +# This test must come as early as possible after the compiler configuration +# tests, because the choice of the file model can (in principle) affect +# whether functions and headers are available, whether they work, etc. +AC_SYS_LARGEFILE + +# Checks for libraries. +AC_SEARCH_LIBS(getpwnam, [sun]) + +# Checks for header files. +AC_HEADER_STDC +AC_HEADER_DIRENT +AC_HEADER_STAT +AC_HEADER_TIME +AC_CHECK_HEADERS(stdlib.h locale.h unistd.h limits.h fcntl.h string.h \ + memory.h sys/param.h sys/time.h sys/timeb.h) + +AM_PROG_CC_C_O +AM_PROG_CC_STDC +AC_C_CONST +AC_TYPE_SIGNAL +AC_TYPE_UID_T +AC_TYPE_PID_T + +# Find some definition for uintmax_t + +AC_CHECK_TYPE(uintmax_t,,[ + uintmax_t="unsigned long" + AC_CHECK_TYPE(unsigned long long,[uintmax_t="unsigned long long"]) + AC_DEFINE_UNQUOTED(uintmax_t,$uintmax_t,[Define uintmax_t if not defined in or .])]) + +# Find out whether our struct stat returns nanosecond resolution timestamps. + +AC_STRUCT_ST_MTIM_NSEC +AC_MSG_CHECKING([whether to use high resolution file timestamps]) +AC_CACHE_VAL(make_cv_file_timestamp_hi_res, [ + make_cv_file_timestamp_hi_res=no + if test "$ac_cv_struct_st_mtim_nsec" != no; then + AC_TRY_COMPILE([ +# if HAVE_INTTYPES_H +# include +# endif], + [char a[0x7fffffff < (uintmax_t) -1 >> 30 ? 1 : -1];], + make_cv_file_timestamp_hi_res=yes) + fi]) +AC_MSG_RESULT($make_cv_file_timestamp_hi_res) +if test "$make_cv_file_timestamp_hi_res" = yes; then + val=1 +else + val=0 +fi +AC_DEFINE_UNQUOTED(FILE_TIMESTAMP_HI_RES, $val, + [Use high resolution file timestamps if nonzero.]) + +if test "$make_cv_file_timestamp_hi_res" = yes; then + # Solaris 2.5.1 needs -lposix4 to get the clock_gettime function. + # Solaris 7 prefers the library name -lrt to the obsolescent name -lposix4. + AC_SEARCH_LIBS(clock_gettime, [rt posix4]) + if test "$ac_cv_search_clock_gettime" != no; then + AC_DEFINE(HAVE_CLOCK_GETTIME, 1, + [Define if you have the clock_gettime function.]) + fi +fi + + +# See if we have a standard version of gettimeofday(). Since actual +# implementations can differ, just make sure we have the most common +# one. +AC_CACHE_CHECK([for standard gettimeofday], ac_cv_func_gettimeofday, + [ac_cv_func_gettimeofday=no + AC_TRY_RUN([#include + int main () + { + struct timeval t; t.tv_sec = -1; t.tv_usec = -1; + exit (gettimeofday (&t, 0) != 0 + || t.tv_sec < 0 || t.tv_usec < 0); + }], + ac_cv_func_gettimeofday=yes, + ac_cv_func_gettimeofday=no, + ac_cv_func_gettimeofday="no (cross-compiling)")]) +if test "$ac_cv_func_gettimeofday" = yes; then + AC_DEFINE(HAVE_GETTIMEOFDAY, 1, + [Define if you have a standard gettimeofday function]) +fi + +AC_CHECK_FUNCS( memcpy memmove strchr strdup mkstemp mktemp fdopen \ + bsd_signal dup2 getcwd sigsetmask sigaction getgroups \ + seteuid setegid setlinebuf setreuid setregid setvbuf pipe \ + strerror strsignal) + +make_FUNC_SETVBUF_REVERSED + +# strcoll() is used by the GNU glob library +AC_FUNC_STRCOLL + +AC_FUNC_ALLOCA +AC_FUNC_VFORK +AC_FUNC_VPRINTF +AC_FUNC_CLOSEDIR_VOID + +AC_FUNC_GETLOADAVG + +# AC_FUNC_GETLOADAVG is documented to set the NLIST_STRUCT value, but it +# doesn't. So, we will. + +if test "$ac_cv_header_nlist_h" = yes; then + AC_TRY_COMPILE([#include ], + [struct nlist nl; + nl.n_name = "string"; + return 0;], + make_cv_nlist_struct=yes, + make_cv_nlist_struct=no) + if test "$make_cv_nlist_struct" = yes; then + AC_DEFINE(NLIST_STRUCT, 1, + [Define if struct nlist.n_name is a pointer rather than an array.]) + fi +fi + +AC_DECL_SYS_SIGLIST + +# Check out the wait reality. +AC_CHECK_HEADERS(sys/wait.h) +AC_CHECK_FUNCS(waitpid wait3) +AC_MSG_CHECKING(for union wait) +AC_CACHE_VAL(make_cv_union_wait, [dnl +AC_TRY_LINK([#include +#include ], + [union wait status; int pid; pid = wait (&status); +#ifdef WEXITSTATUS +/* Some POSIXoid systems have both the new-style macros and the old + union wait type, and they do not work together. If union wait + conflicts with WEXITSTATUS et al, we don't want to use it at all. */ +if (WEXITSTATUS (status) != 0) pid = -1; +#ifdef WTERMSIG +/* If we have WEXITSTATUS and WTERMSIG, just use them on ints. */ +-- blow chunks here -- +#endif +#endif +#ifdef HAVE_WAITPID +/* Make sure union wait works with waitpid. */ +pid = waitpid (-1, &status, 0); +#endif +], + [make_cv_union_wait=yes], [make_cv_union_wait=no])]) +if test "$make_cv_union_wait" = yes; then + AC_DEFINE(HAVE_UNION_WAIT, 1, [Define this if you have the \`union wait' type in .]) +fi +AC_MSG_RESULT($make_cv_union_wait) + + +# See if the user wants to use pmake's "customs" distributed build capability + +use_customs=false +AC_ARG_WITH(customs, + AC_HELP_STRING([--with-customs=DIR], + [enable remote jobs via Customs--see README.customs]), + [case $withval in + n|no) : ;; + *) make_cppflags="$CPPFLAGS" + case $withval in + y|ye|yes) : ;; + *) CPPFLAGS="$CPPFLAGS -I$with_customs/include/customs" + make_ldflags="$LDFLAGS -L$with_customs/lib" ;; + esac + CF_NETLIBS + AC_CHECK_HEADER(customs.h, + [use_customs=true + LIBS="$LIBS -lcustoms" LDFLAGS="$make_ldflags"], + [with_customs=no + CPPFLAGS="$make_cppflags" make_badcust=yes]) + ;; + esac]) +# Tell automake about this, so it can include the right .c files. +AM_CONDITIONAL(USE_CUSTOMS, test "$use_customs" = true) + +# See if we can handle the job server feature, and if the user wants it. + +AC_ARG_ENABLE(job-server, + AC_HELP_STRING([--disable-job-server], + [disallow recursive make communication during -jN]), + [make_cv_job_server="$enableval" user_job_server="$enableval"], + [make_cv_job_server="yes"]) + +has_wait_nohang=yes +case "$ac_cv_func_waitpid/$ac_cv_func_wait3" in + no/no) has_wait_nohang=no ;; +esac + +AC_CACHE_CHECK(for SA_RESTART, make_cv_sa_restart, [ + AC_TRY_COMPILE([#include ], + [return SA_RESTART;], + make_cv_sa_restart=yes, + make_cv_sa_restart=no)]) +if test "$make_cv_sa_restart" != no; then + AC_DEFINE(HAVE_SA_RESTART, 1, + [Define if defines the SA_RESTART constant.]) +fi + +case "$ac_cv_func_pipe/$ac_cv_func_sigaction/$make_cv_sa_restart/$has_wait_nohang/$make_cv_job_server" in + yes/yes/yes/yes/yes) + AC_DEFINE(MAKE_JOBSERVER, 1, + [Define this to enable job server support in GNU make.]);; +esac + +# Find the SCCS commands, so we can include them in our default rules. + +AC_CACHE_CHECK(for location of SCCS get command, make_cv_path_sccs_get, [ +if test -f /usr/sccs/get; then + make_cv_path_sccs_get=/usr/sccs/get +else + make_cv_path_sccs_get=get +fi]) +AC_DEFINE_UNQUOTED(SCCS_GET, ["$make_cv_path_sccs_get"], [Define to the name of the SCCS 'get' command.]) + +ac_clean_files="$ac_clean_files s.conftest conftoast" # Remove these later. +if ( /usr/sccs/admin -n s.conftest || admin -n s.conftest ) >/dev/null 2>&1 && + test -f s.conftest; then + # We successfully created an SCCS file. + AC_CACHE_CHECK(if SCCS get command understands -G, make_cv_sys_get_minus_G, [ + if $make_cv_path_sccs_get -Gconftoast s.conftest >/dev/null 2>&1 && + test -f conftoast; then + make_cv_sys_get_minus_G=yes + else + make_cv_sys_get_minus_G=no + fi]) + case "$make_cv_sys_get_minus_G" in + yes) AC_DEFINE(SCCS_GET_MINUS_G, 1, + [Define this if the SCCS 'get' command understands the '-G' option.]);; + esac +fi +rm -f s.conftest conftoast + +# Check the system to see if it provides GNU glob. If not, use our +# local version. + +AC_MSG_CHECKING(if system libc has GNU glob) +AC_CACHE_VAL(make_cv_sys_gnu_glob, [ + AC_EGREP_CPP(gnu glob,[ +#include +#include +#include + +#define GLOB_INTERFACE_VERSION 1 +#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 +# include +# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION + gnu glob +# endif +#endif + ], [AC_MSG_RESULT(yes) +make_cv_sys_gnu_glob=yes], [AC_MSG_RESULT([no; using local copy]) +AC_SUBST(GLOBINC) GLOBINC='-I$(srcdir)/glob' +AC_SUBST(GLOBLIB) GLOBLIB=glob/libglob.a +make_cv_sys_gnu_glob=no])]) +# Tell automake about this, so it can build the right .c files. +AM_CONDITIONAL(USE_LOCAL_GLOB, test "$make_cv_sys_gnu_glob" = no) + +# PTX systems have a broken implementation of SA_RESTART. I know of +# no way to test for this behavior, so I'll just test for PTX + +case "$host" in + i386-sequent-sysv4) + AC_DEFINE(HAVE_BROKEN_RESTART, 1, [This system has SA_RESTART, but it doesn't work properly.]) + echo "" + echo "WARNING: The SA_RESTART sigaction() flag does not work on PTX." + echo " This causes 'make -j' to fail at random times." + echo " I am installing a workaround, which is mostly but not 100%" + echo " effective. If you see random failures during 'make -j'" + echo " you should either contact the bug list, or not use -j." + echo "" ;; +esac + +# Let the makefile know what our build host is + +AC_DEFINE_UNQUOTED(MAKE_HOST,"$host",[Build host information.]) +MAKE_HOST="$host" +AC_SUBST(MAKE_HOST) + +# Include the Maintainer's Makefile section, if it's here. + +MAINT_MAKEFILE=/dev/null +if test -r "$srcdir/maintMakefile"; then + MAINT_MAKEFILE="$srcdir/maintMakefile" +fi +AC_SUBST_FILE(MAINT_MAKEFILE) + +# Allow building with dmalloc +AM_WITH_DMALLOC + + +# Sanity check and inform the user of what we found + +case "$make_badcust" in + yes) echo + echo "WARNING: --with-customs specified but no customs.h could be found;" + echo " disabling Customs support." + echo ;; +esac + +case "$with_customs" in + ""|n|no|y|ye|yes) ;; + *) if test -f "$with_customs/lib/libcustoms.a"; then + : + else + echo + echo "WARNING: '$with_customs/lib' does not appear to contain the" + echo " Customs library. You must build and install Customs" + echo " before compiling GNU make." + echo + fi ;; +esac + +case "$has_wait_nohang" in + no) echo + echo "WARNING: Your system has neither waitpid() nor wait3()." + echo " Without one of these, signal handling is unreliable." + echo " You should be aware that running GNU make with -j" + echo " could result in erratic behavior." + echo ;; +esac + +case "$make_cv_job_server/$user_job_server" in + no/yes) echo + echo "WARNING: Make job server requires a POSIX-ish system that" + echo " supports the pipe(), sigaction(), and either" + echo " waitpid() or wait3() functions. Your system doesn't" + echo " appear to provide one or more of those." + echo " Disabling job server support." + echo ;; +esac + + +# Specify what files are to be created. +# We only generate the build.sh if we have a build.sh.in; we won't have +# one before we've created a distribution. + +AC_CONFIG_FILES(Makefile glob/Makefile po/Makefile.in config/Makefile doc/Makefile) + +if test -f $srcdir/build.sh.in; then + AC_CONFIG_FILES(build.sh) +fi + + +# OK, do it! + +AC_OUTPUT + + +dnl Local Variables: +dnl comment-start: "dnl " +dnl comment-end: "" +dnl comment-start-skip: "\\bdnl\\b\\s *" +dnl compile-command: "make configure config.h.in" +dnl End: diff --git a/src/make-3.80/debug.h b/src/make-3.80/debug.h new file mode 100755 index 00000000..30c2d627 --- /dev/null +++ b/src/make-3.80/debug.h @@ -0,0 +1,41 @@ +/* Debugging macros and interface. +Copyright (C) 1999 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +#define DB_NONE (0x000) +#define DB_BASIC (0x001) +#define DB_VERBOSE (0x002) +#define DB_JOBS (0x004) +#define DB_IMPLICIT (0x008) +#define DB_MAKEFILES (0x100) + +#define DB_ALL (0xfff) + +extern int db_level; + +#define ISDB(_l) ((_l)&db_level) + +#define DBS(_l,_x) do{ if(ISDB(_l)) {print_spaces (depth); \ + printf _x; fflush (stdout);} }while(0) + +#define DBF(_l,_x) do{ if(ISDB(_l)) {print_spaces (depth); \ + printf (_x, file->name); \ + fflush (stdout);} }while(0) + +#define DB(_l,_x) do{ if(ISDB(_l)) {printf _x; fflush (stdout);} }while(0) diff --git a/src/make-3.80/default.c b/src/make-3.80/default.c new file mode 100755 index 00000000..5d981b98 --- /dev/null +++ b/src/make-3.80/default.c @@ -0,0 +1,585 @@ +/* Data base of default implicit rules for GNU Make. +Copyright (C) 1988,89,90,91,92,93,94,95,96 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "rule.h" +#include "dep.h" +#include "filedef.h" +#include "job.h" +#include "commands.h" +#include "variable.h" + +/* Define GCC_IS_NATIVE if gcc is the native development environment on + your system (gcc/bison/flex vs cc/yacc/lex). */ +#ifdef __MSDOS__ +#define GCC_IS_NATIVE +#endif + + +/* This is the default list of suffixes for suffix rules. + `.s' must come last, so that a `.o' file will be made from + a `.c' or `.p' or ... file rather than from a .s file. */ + +static char default_suffixes[] +#ifdef VMS + = ".exe .olb .ln .obj .c .cxx .cc .pas .p .for .f .r .y .l .mar \ +.s .ss .i .ii .mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \ +.w .ch .cweb .web .com .sh .elc .el"; +#else + = ".out .a .ln .o .c .cc .C .cpp .p .f .F .r .y .l .s .S \ +.mod .sym .def .h .info .dvi .tex .texinfo .texi .txinfo \ +.w .ch .web .sh .elc .el"; +#endif + +static struct pspec default_pattern_rules[] = + { + { "(%)", "%", + "$(AR) $(ARFLAGS) $@ $<" }, + + /* The X.out rules are only in BSD's default set because + BSD Make has no null-suffix rules, so `foo.out' and + `foo' are the same thing. */ +#ifdef VMS + { "%.exe", "%", + "copy $< $@" }, +#else + { "%.out", "%", + "@rm -f $@ \n cp $< $@" }, +#endif + /* Syntax is "ctangle foo.w foo.ch foo.c". */ + { "%.c", "%.w %.ch", + "$(CTANGLE) $^ $@" }, + { "%.tex", "%.w %.ch", + "$(CWEAVE) $^ $@" }, + + { 0, 0, 0 } + }; + +static struct pspec default_terminal_rules[] = + { +#ifdef VMS + /* RCS. */ + { "%", "%$$5lv", /* Multinet style */ + "if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" }, + { "%", "[.$$rcs]%$$5lv", /* Multinet style */ + "if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" }, + { "%", "%_v", /* Normal style */ + "if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" }, + { "%", "[.rcs]%_v", /* Normal style */ + "if f$$search($@) .nes. \"\" then +$(CHECKOUT,v)" }, + + /* SCCS. */ + /* ain't no SCCS on vms */ +#else + /* RCS. */ + { "%", "%,v", + "$(CHECKOUT,v)" }, + { "%", "RCS/%,v", + "$(CHECKOUT,v)" }, + { "%", "RCS/%", + "$(CHECKOUT,v)" }, + + /* SCCS. */ + { "%", "s.%", + "$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" }, + { "%", "SCCS/s.%", + "$(GET) $(GFLAGS) $(SCCS_OUTPUT_OPTION) $<" }, +#endif /* !VMS */ + { 0, 0, 0 } + }; + +static char *default_suffix_rules[] = + { +#ifdef VMS + ".obj.exe", + "$(LINK.obj) $^ $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@", + ".mar.exe", + "$(COMPILE.mar) $^ \n $(LINK.obj) $(subst .mar,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@", + ".s.exe", + "$(COMPILE.s) $^ \n $(LINK.obj) $(subst .s,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@", + ".c.exe", + "$(COMPILE.c) $^ \n $(LINK.obj) $(subst .c,.obj,$^) $(LOADLIBES) $(LDLIBS) $(CRT0) /exe=$@", + ".cc.exe", +#ifdef GCC_IS_NATIVE + "$(COMPILE.cc) $^ \n $(LINK.obj) $(CXXSTARTUP),sys$$disk:[]$(subst .cc,.obj,$^) $(LOADLIBES) $(LXLIBS) $(LDLIBS) $(CXXRT0) /exe=$@", +#else + "$(COMPILE.cc) $^ \n $(CXXLINK.obj) $(subst .cc,.obj,$^) $(LOADLIBES) $(LXLIBS) $(LDLIBS) $(CXXRT0) /exe=$@", + ".cxx.exe", + "$(COMPILE.cxx) $^ \n $(CXXLINK.obj) $(subst .cxx,.obj,$^) $(LOADLIBES) $(LXLIBS) $(LDLIBS) $(CXXRT0) /exe=$@", +#endif + ".for.exe", + "$(COMPILE.for) $^ \n $(LINK.obj) $(subst .for,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@", + ".pas.exe", + "$(COMPILE.pas) $^ \n $(LINK.obj) $(subst .pas,.obj,$^) $(LOADLIBES) $(LDLIBS) /exe=$@", + + ".com", + "copy $< >$@", + + ".mar.obj", + "$(COMPILE.mar) /obj=$@ $<", + ".s.obj", + "$(COMPILE.s) /obj=$@ $<", + ".ss.obj", + "$(COMPILE.s) /obj=$@ $<", + ".c.i", + "$(COMPILE.c)/prep /list=$@ $<", + ".c.s", + "$(COMPILE.c)/noobj/machine /list=$@ $<", + ".i.s", + "$(COMPILE.c)/noprep/noobj/machine /list=$@ $<", + ".c.obj", + "$(COMPILE.c) /obj=$@ $<", + ".cc.ii", + "$(COMPILE.cc)/prep /list=$@ $<", + ".cc.ss", + "$(COMPILE.cc)/noobj/machine /list=$@ $<", + ".ii.ss", + "$(COMPILE.cc)/noprep/noobj/machine /list=$@ $<", + ".cc.obj", + "$(COMPILE.cc) /obj=$@ $<", + ".for.obj", + "$(COMPILE.for) /obj=$@ $<", + ".pas.obj", + "$(COMPILE.pas) /obj=$@ $<", + + ".y.c", + "$(YACC.y) $< \n rename y_tab.c $@", + ".l.c", + "$(LEX.l) $< \n rename lexyy.c $@", + + ".texinfo.info", + "$(MAKEINFO) $<", + + ".tex.dvi", + "$(TEX) $<", + +#else /* ! VMS */ + + ".o", + "$(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".s", + "$(LINK.s) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".S", + "$(LINK.S) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".c", + "$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".cc", + "$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".C", + "$(LINK.C) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".cpp", + "$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".f", + "$(LINK.f) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".p", + "$(LINK.p) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".F", + "$(LINK.F) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".r", + "$(LINK.r) $^ $(LOADLIBES) $(LDLIBS) -o $@", + ".mod", + "$(COMPILE.mod) -o $@ -e $@ $^", + + ".def.sym", + "$(COMPILE.def) -o $@ $<", + + ".sh", + "cat $< >$@ \n chmod a+x $@", + + ".s.o", + "$(COMPILE.s) -o $@ $<", + ".S.o", + "$(COMPILE.S) -o $@ $<", + ".c.o", + "$(COMPILE.c) $(OUTPUT_OPTION) $<", + ".cc.o", + "$(COMPILE.cc) $(OUTPUT_OPTION) $<", + ".C.o", + "$(COMPILE.C) $(OUTPUT_OPTION) $<", + ".cpp.o", + "$(COMPILE.cpp) $(OUTPUT_OPTION) $<", + ".f.o", + "$(COMPILE.f) $(OUTPUT_OPTION) $<", + ".p.o", + "$(COMPILE.p) $(OUTPUT_OPTION) $<", + ".F.o", + "$(COMPILE.F) $(OUTPUT_OPTION) $<", + ".r.o", + "$(COMPILE.r) $(OUTPUT_OPTION) $<", + ".mod.o", + "$(COMPILE.mod) -o $@ $<", + + ".c.ln", + "$(LINT.c) -C$* $<", + ".y.ln", +#ifndef __MSDOS__ + "$(YACC.y) $< \n $(LINT.c) -C$* y.tab.c \n $(RM) y.tab.c", +#else + "$(YACC.y) $< \n $(LINT.c) -C$* y_tab.c \n $(RM) y_tab.c", +#endif + ".l.ln", + "@$(RM) $*.c\n $(LEX.l) $< > $*.c\n$(LINT.c) -i $*.c -o $@\n $(RM) $*.c", + + ".y.c", +#ifndef __MSDOS__ + "$(YACC.y) $< \n mv -f y.tab.c $@", +#else + "$(YACC.y) $< \n mv -f y_tab.c $@", +#endif + ".l.c", + "@$(RM) $@ \n $(LEX.l) $< > $@", + + ".F.f", + "$(PREPROCESS.F) $(OUTPUT_OPTION) $<", + ".r.f", + "$(PREPROCESS.r) $(OUTPUT_OPTION) $<", + + /* This might actually make lex.yy.c if there's no %R% + directive in $*.l, but in that case why were you + trying to make $*.r anyway? */ + ".l.r", + "$(LEX.l) $< > $@ \n mv -f lex.yy.r $@", + + ".S.s", + "$(PREPROCESS.S) $< > $@", + + ".texinfo.info", + "$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@", + + ".texi.info", + "$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@", + + ".txinfo.info", + "$(MAKEINFO) $(MAKEINFO_FLAGS) $< -o $@", + + ".tex.dvi", + "$(TEX) $<", + + ".texinfo.dvi", + "$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<", + + ".texi.dvi", + "$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<", + + ".txinfo.dvi", + "$(TEXI2DVI) $(TEXI2DVI_FLAGS) $<", + + ".w.c", + "$(CTANGLE) $< - $@", /* The `-' says there is no `.ch' file. */ + + ".web.p", + "$(TANGLE) $<", + + ".w.tex", + "$(CWEAVE) $< - $@", /* The `-' says there is no `.ch' file. */ + + ".web.tex", + "$(WEAVE) $<", + +#endif /* !VMS */ + + 0, 0, + }; + +static char *default_variables[] = + { +#ifdef VMS +#ifdef __ALPHA + "ARCH", "ALPHA", +#else + "ARCH", "VAX", +#endif + "AR", "library/obj", + "ARFLAGS", "/replace", + "AS", "macro", + "MACRO", "macro", +#ifdef GCC_IS_NATIVE + "CC", "gcc", +#else + "CC", "cc", +#endif + "CD", "builtin_cd", + "MAKE", "make", + "ECHO", "write sys$$output \"", +#ifdef GCC_IS_NATIVE + "C++", "gcc/plus", + "CXX", "gcc/plus", +#else + "C++", "cxx", + "CXX", "cxx", + "CXXLD", "cxxlink", +#endif + "CO", "co", + "CPP", "$(CC) /preprocess_only", + "FC", "fortran", + /* System V uses these, so explicit rules using them should work. + However, there is no way to make implicit rules use them and FC. */ + "F77", "$(FC)", + "F77FLAGS", "$(FFLAGS)", + "LD", "link", + "LEX", "lex", + "PC", "pascal", + "YACC", "bison/yacc", + "YFLAGS", "/Define/Verbose", + "BISON", "bison", + "MAKEINFO", "makeinfo", + "TEX", "tex", + "TEXINDEX", "texindex", + + "RM", "delete/nolog", + + "CSTARTUP", "", +#ifdef GCC_IS_NATIVE + "CRT0", ",sys$$library:vaxcrtl.olb/lib,gnu_cc_library:crt0.obj", + "CXXSTARTUP", "gnu_cc_library:crtbegin.obj", + "CXXRT0", ",sys$$library:vaxcrtl.olb/lib,gnu_cc_library:crtend.obj,gnu_cc_library:gxx_main.obj", + "LXLIBS", ",gnu_cc_library:libstdcxx.olb/lib,gnu_cc_library:libgccplus.olb/lib", + "LDLIBS", ",gnu_cc_library:libgcc.olb/lib", +#else + "CRT0", "", + "CXXSTARTUP", "", + "CXXRT0", "", + "LXLIBS", "", + "LDLIBS", "", +#endif + + "LINK.obj", "$(LD) $(LDFLAGS)", +#ifndef GCC_IS_NATIVE + "CXXLINK.obj", "$(CXXLD) $(LDFLAGS)", + "COMPILE.cxx", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", +#endif + "COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", + "COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", + "YACC.y", "$(YACC) $(YFLAGS)", + "LEX.l", "$(LEX) $(LFLAGS)", + "COMPILE.for", "$(FC) $(FFLAGS) $(TARGET_ARCH)", + "COMPILE.pas", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", + "COMPILE.mar", "$(MACRO) $(MACROFLAGS)", + "COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)", + "LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", + + "MV", "rename/new_version", + "CP", "copy", + +#else /* !VMS */ + + "AR", "ar", + "ARFLAGS", "rv", + "AS", "as", +#ifdef GCC_IS_NATIVE + "CC", "gcc", +# ifdef __MSDOS__ + "CXX", "gpp", /* g++ is an invalid name on MSDOS */ +# else + "CXX", "gcc", +# endif /* __MSDOS__ */ +#else + "CC", "cc", + "CXX", "g++", +#endif + + /* This expands to $(CO) $(COFLAGS) $< $@ if $@ does not exist, + and to the empty string if $@ does exist. */ + "CHECKOUT,v", "+$(if $(wildcard $@),,$(CO) $(COFLAGS) $< $@)", + "CO", "co", + "COFLAGS", "", + + "CPP", "$(CC) -E", +#ifdef CRAY + "CF77PPFLAGS", "-P", + "CF77PP", "/lib/cpp", + "CFT", "cft77", + "CF", "cf77", + "FC", "$(CF)", +#else /* Not CRAY. */ +#ifdef _IBMR2 + "FC", "xlf", +#else +#ifdef __convex__ + "FC", "fc", +#else + "FC", "f77", +#endif /* __convex__ */ +#endif /* _IBMR2 */ + /* System V uses these, so explicit rules using them should work. + However, there is no way to make implicit rules use them and FC. */ + "F77", "$(FC)", + "F77FLAGS", "$(FFLAGS)", +#endif /* Cray. */ + "GET", SCCS_GET, + "LD", "ld", +#ifdef GCC_IS_NATIVE + "LEX", "flex", +#else + "LEX", "lex", +#endif + "LINT", "lint", + "M2C", "m2c", +#ifdef pyr + "PC", "pascal", +#else +#ifdef CRAY + "PC", "PASCAL", + "SEGLDR", "segldr", +#else + "PC", "pc", +#endif /* CRAY. */ +#endif /* pyr. */ +#ifdef GCC_IS_NATIVE + "YACC", "bison -y", +#else + "YACC", "yacc", /* Or "bison -y" */ +#endif + "MAKEINFO", "makeinfo", + "TEX", "tex", + "TEXI2DVI", "texi2dvi", + "WEAVE", "weave", + "CWEAVE", "cweave", + "TANGLE", "tangle", + "CTANGLE", "ctangle", + + "RM", "rm -f", + + "LINK.o", "$(CC) $(LDFLAGS) $(TARGET_ARCH)", + "COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", + "LINK.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", + "COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", + "COMPILE.C", "$(COMPILE.cc)", + "COMPILE.cpp", "$(COMPILE.cc)", + "LINK.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", + "LINK.C", "$(LINK.cc)", + "LINK.cpp", "$(LINK.cc)", + "YACC.y", "$(YACC) $(YFLAGS)", + "LEX.l", "$(LEX) $(LFLAGS) -t", + "COMPILE.f", "$(FC) $(FFLAGS) $(TARGET_ARCH) -c", + "LINK.f", "$(FC) $(FFLAGS) $(LDFLAGS) $(TARGET_ARCH)", + "COMPILE.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", + "LINK.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", + "COMPILE.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -c", + "LINK.r", "$(FC) $(FFLAGS) $(RFLAGS) $(LDFLAGS) $(TARGET_ARCH)", + "COMPILE.def", "$(M2C) $(M2FLAGS) $(DEFFLAGS) $(TARGET_ARCH)", + "COMPILE.mod", "$(M2C) $(M2FLAGS) $(MODFLAGS) $(TARGET_ARCH)", + "COMPILE.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c", + "LINK.p", "$(PC) $(PFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)", + "LINK.s", "$(CC) $(ASFLAGS) $(LDFLAGS) $(TARGET_MACH)", + "COMPILE.s", "$(AS) $(ASFLAGS) $(TARGET_MACH)", + "LINK.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_MACH)", + "COMPILE.S", "$(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) -c", + "PREPROCESS.S", "$(CC) -E $(CPPFLAGS)", + "PREPROCESS.F", "$(FC) $(FFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -F", + "PREPROCESS.r", "$(FC) $(FFLAGS) $(RFLAGS) $(TARGET_ARCH) -F", + "LINT.c", "$(LINT) $(LINTFLAGS) $(CPPFLAGS) $(TARGET_ARCH)", + +#ifndef NO_MINUS_C_MINUS_O + "OUTPUT_OPTION", "-o $@", +#endif + +#ifdef SCCS_GET_MINUS_G + "SCCS_OUTPUT_OPTION", "-G$@", +#endif + +#ifdef _AMIGA + ".LIBPATTERNS", "%.lib", +#else +#ifdef __MSDOS__ + ".LIBPATTERNS", "lib%.a $(DJDIR)/lib/lib%.a", +#else + ".LIBPATTERNS", "lib%.so lib%.a", +#endif +#endif + +#endif /* !VMS */ + 0, 0 + }; + +/* Set up the default .SUFFIXES list. */ + +void +set_default_suffixes () +{ + suffix_file = enter_file (".SUFFIXES"); + + if (no_builtin_rules_flag) + (void) define_variable ("SUFFIXES", 8, "", o_default, 0); + else + { + char *p = default_suffixes; + suffix_file->deps = (struct dep *) + multi_glob (parse_file_seq (&p, '\0', sizeof (struct dep), 1), + sizeof (struct dep)); + (void) define_variable ("SUFFIXES", 8, default_suffixes, o_default, 0); + } +} + +/* Enter the default suffix rules as file rules. This used to be done in + install_default_implicit_rules, but that loses because we want the + suffix rules installed before reading makefiles, and thee pattern rules + installed after. */ + +void +install_default_suffix_rules () +{ + register char **s; + + if (no_builtin_rules_flag) + return; + + for (s = default_suffix_rules; *s != 0; s += 2) + { + register struct file *f = enter_file (s[0]); + /* Don't clobber cmds given in a makefile if there were any. */ + if (f->cmds == 0) + { + f->cmds = (struct commands *) xmalloc (sizeof (struct commands)); + f->cmds->fileinfo.filenm = 0; + f->cmds->commands = s[1]; + f->cmds->command_lines = 0; + } + } +} + + +/* Install the default pattern rules. */ + +void +install_default_implicit_rules () +{ + register struct pspec *p; + + if (no_builtin_rules_flag) + return; + + for (p = default_pattern_rules; p->target != 0; ++p) + install_pattern_rule (p, 0); + + for (p = default_terminal_rules; p->target != 0; ++p) + install_pattern_rule (p, 1); +} + +void +define_default_variables () +{ + register char **s; + + if (no_builtin_variables_flag) + return; + + for (s = default_variables; *s != 0; s += 2) + (void) define_variable (s[0], strlen (s[0]), s[1], o_default, 1); +} diff --git a/src/make-3.80/dep.h b/src/make-3.80/dep.h new file mode 100755 index 00000000..7f4380b7 --- /dev/null +++ b/src/make-3.80/dep.h @@ -0,0 +1,78 @@ +/* Definitions of dependency data structures for GNU Make. +Copyright (C) 1988, 1989, 1991, 1992, 1993, 1996 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Flag bits for the second argument to `read_makefile'. + These flags are saved in the `changed' field of each + `struct dep' in the chain returned by `read_all_makefiles'. */ + +#define RM_NO_DEFAULT_GOAL (1 << 0) /* Do not set default goal. */ +#define RM_INCLUDED (1 << 1) /* Search makefile search path. */ +#define RM_DONTCARE (1 << 2) /* No error if it doesn't exist. */ +#define RM_NO_TILDE (1 << 3) /* Don't expand ~ in file name. */ +#define RM_NOFLAG 0 + +/* Structure representing one dependency of a file. + Each struct file's `deps' points to a chain of these, + chained through the `next'. + + Note that the first two words of this match a struct nameseq. */ + +struct dep + { + struct dep *next; + char *name; + struct file *file; + unsigned int changed : 8; + unsigned int ignore_mtime : 1; + }; + + +/* Structure used in chains of names, for parsing and globbing. */ + +struct nameseq + { + struct nameseq *next; + char *name; + }; + + +extern struct nameseq *multi_glob PARAMS ((struct nameseq *chain, unsigned int size)); +#ifdef VMS +extern struct nameseq *parse_file_seq (); +#else +extern struct nameseq *parse_file_seq PARAMS ((char **stringp, int stopchar, unsigned int size, int strip)); +#endif +extern char *tilde_expand PARAMS ((char *name)); + +#ifndef NO_ARCHIVES +extern struct nameseq *ar_glob PARAMS ((char *arname, char *member_pattern, unsigned int size)); +#endif + +#ifndef iAPX286 +#define dep_name(d) ((d)->name == 0 ? (d)->file->name : (d)->name) +#else +/* Buggy compiler can't hack this. */ +extern char *dep_name (); +#endif + +extern struct dep *copy_dep_chain PARAMS ((struct dep *d)); +extern struct dep *read_all_makefiles PARAMS ((char **makefiles)); +extern int eval_buffer PARAMS ((char *buffer)); +extern int update_goal_chain PARAMS ((struct dep *goals, int makefiles)); +extern void uniquize_deps PARAMS ((struct dep *)); diff --git a/src/make-3.80/dir.c b/src/make-3.80/dir.c new file mode 100755 index 00000000..e862b9d0 --- /dev/null +++ b/src/make-3.80/dir.c @@ -0,0 +1,1212 @@ +/* Directory hashing for GNU Make. +Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "hash.h" + +#ifdef HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +# ifdef VMS +extern char *vmsify PARAMS ((char *name, int type)); +# endif +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +# ifdef HAVE_VMSDIR_H +# include "vmsdir.h" +# endif /* HAVE_VMSDIR_H */ +#endif + +/* In GNU systems, defines this macro for us. */ +#ifdef _D_NAMLEN +# undef NAMLEN +# define NAMLEN(d) _D_NAMLEN(d) +#endif + +#if (defined (POSIX) || defined (VMS) || defined (WINDOWS32)) && !defined (__GNU_LIBRARY__) +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +# define REAL_DIR_ENTRY(dp) 1 +# define FAKE_DIR_ENTRY(dp) +#else +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +# define FAKE_DIR_ENTRY(dp) (dp->d_ino = 1) +#endif /* POSIX */ + +#ifdef __MSDOS__ +#include +#include + +/* If it's MSDOS that doesn't have _USE_LFN, disable LFN support. */ +#ifndef _USE_LFN +#define _USE_LFN 0 +#endif + +static char * +dosify (filename) + char *filename; +{ + static char dos_filename[14]; + char *df; + int i; + + if (filename == 0 || _USE_LFN) + return filename; + + /* FIXME: what about filenames which violate + 8+3 constraints, like "config.h.in", or ".emacs"? */ + if (strpbrk (filename, "\"*+,;<=>?[\\]|") != 0) + return filename; + + df = dos_filename; + + /* First, transform the name part. */ + for (i = 0; *filename != '\0' && i < 8 && *filename != '.'; ++i) + *df++ = tolower ((unsigned char)*filename++); + + /* Now skip to the next dot. */ + while (*filename != '\0' && *filename != '.') + ++filename; + if (*filename != '\0') + { + *df++ = *filename++; + for (i = 0; *filename != '\0' && i < 3 && *filename != '.'; ++i) + *df++ = tolower ((unsigned char)*filename++); + } + + /* Look for more dots. */ + while (*filename != '\0' && *filename != '.') + ++filename; + if (*filename == '.') + return filename; + *df = 0; + return dos_filename; +} +#endif /* __MSDOS__ */ + +#ifdef WINDOWS32 +#include "pathstuff.h" +#endif + +#ifdef _AMIGA +#include +#endif + +#ifdef HAVE_CASE_INSENSITIVE_FS +static char * +downcase (filename) + char *filename; +{ +#ifdef _AMIGA + static char new_filename[136]; +#else + static char new_filename[PATH_MAX]; +#endif + char *df; + int i; + + if (filename == 0) + return 0; + + df = new_filename; + + /* First, transform the name part. */ + for (i = 0; *filename != '\0'; ++i) + { + *df++ = tolower ((unsigned char)*filename); + ++filename; + } + + *df = 0; + + return new_filename; +} +#endif /* HAVE_CASE_INSENSITIVE_FS */ + +#ifdef VMS + +static int +vms_hash (name) + char *name; +{ + int h = 0; + int g; + + while (*name) + { + unsigned char uc = *name; + h = (h << 4) + (isupper (uc) ? tolower (uc) : uc); + name++; + g = h & 0xf0000000; + if (g) + { + h = h ^ (g >> 24); + h = h ^ g; + } + } + return h; +} + +/* fake stat entry for a directory */ +static int +vmsstat_dir (name, st) + char *name; + struct stat *st; +{ + char *s; + int h; + DIR *dir; + + dir = opendir (name); + if (dir == 0) + return -1; + closedir (dir); + s = strchr (name, ':'); /* find device */ + if (s) + { + *s++ = 0; + st->st_dev = (char *)vms_hash (name); + h = vms_hash (s); + *(s-1) = ':'; + } + else + { + st->st_dev = 0; + s = name; + h = vms_hash (s); + } + + st->st_ino[0] = h & 0xff; + st->st_ino[1] = h & 0xff00; + st->st_ino[2] = h >> 16; + + return 0; +} +#endif /* VMS */ + +/* Hash table of directories. */ + +#ifndef DIRECTORY_BUCKETS +#define DIRECTORY_BUCKETS 199 +#endif + +struct directory_contents + { + dev_t dev; /* Device and inode numbers of this dir. */ +#ifdef WINDOWS32 + /* + * Inode means nothing on WINDOWS32. Even file key information is + * unreliable because it is random per file open and undefined + * for remote filesystems. The most unique attribute I can + * come up with is the fully qualified name of the directory. Beware + * though, this is also unreliable. I'm open to suggestion on a better + * way to emulate inode. + */ + char *path_key; + int ctime; + int mtime; /* controls check for stale directory cache */ + int fs_flags; /* FS_FAT, FS_NTFS, ... */ +#define FS_FAT 0x1 +#define FS_NTFS 0x2 +#define FS_UNKNOWN 0x4 +#else +#ifdef VMS + ino_t ino[3]; +#else + ino_t ino; +#endif +#endif /* WINDOWS32 */ + struct hash_table dirfiles; /* Files in this directory. */ + DIR *dirstream; /* Stream reading this directory. */ + }; + +static unsigned long +directory_contents_hash_1 (key_0) + const void *key_0; +{ + struct directory_contents const *key = (struct directory_contents const *) key_0; + unsigned long hash; + +#ifdef WINDOWS32 + ISTRING_HASH_1 (key->path_key, hash); + hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) key->ctime; +#else +# ifdef VMS + hash = (((unsigned int) key->dev << 4) + ^ ((unsigned int) key->ino[0] + + (unsigned int) key->ino[1] + + (unsigned int) key->ino[2])); +# else + hash = ((unsigned int) key->dev << 4) ^ (unsigned int) key->ino; +# endif +#endif /* WINDOWS32 */ + return hash; +} + +static unsigned long +directory_contents_hash_2 (key_0) + const void *key_0; +{ + struct directory_contents const *key = (struct directory_contents const *) key_0; + unsigned long hash; + +#ifdef WINDOWS32 + ISTRING_HASH_2 (key->path_key, hash); + hash ^= ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ctime; +#else +# ifdef VMS + hash = (((unsigned int) key->dev << 4) + ^ ~((unsigned int) key->ino[0] + + (unsigned int) key->ino[1] + + (unsigned int) key->ino[2])); +# else + hash = ((unsigned int) key->dev << 4) ^ (unsigned int) ~key->ino; +# endif +#endif /* WINDOWS32 */ + + return hash; +} + +static int +directory_contents_hash_cmp (xv, yv) + const void *xv; + const void *yv; +{ + struct directory_contents const *x = (struct directory_contents const *) xv; + struct directory_contents const *y = (struct directory_contents const *) yv; + int result; + +#ifdef WINDOWS32 + ISTRING_COMPARE (x->path_key, y->path_key, result); + if (result) + return result; + result = x->ctime - y->ctime; + if (result) + return result; +#else +# ifdef VMS + result = x->ino[0] - y->ino[0]; + if (result) + return result; + result = x->ino[1] - y->ino[1]; + if (result) + return result; + result = x->ino[2] - y->ino[2]; + if (result) + return result; +# else + result = x->ino - y->ino; + if (result) + return result; +# endif +#endif /* WINDOWS32 */ + + return x->dev - y->dev; +} + +/* Table of directory contents hashed by device and inode number. */ +static struct hash_table directory_contents; + +struct directory + { + char *name; /* Name of the directory. */ + + /* The directory's contents. This data may be shared by several + entries in the hash table, which refer to the same directory + (identified uniquely by `dev' and `ino') under different names. */ + struct directory_contents *contents; + }; + +static unsigned long +directory_hash_1 (key) + const void *key; +{ + return_ISTRING_HASH_1 (((struct directory const *) key)->name); +} + +static unsigned long +directory_hash_2 (key) + const void *key; +{ + return_ISTRING_HASH_2 (((struct directory const *) key)->name); +} + +static int +directory_hash_cmp (x, y) + const void *x; + const void *y; +{ + return_ISTRING_COMPARE (((struct directory const *) x)->name, + ((struct directory const *) y)->name); +} + +/* Table of directories hashed by name. */ +static struct hash_table directories; + +/* Never have more than this many directories open at once. */ + +#define MAX_OPEN_DIRECTORIES 10 + +static unsigned int open_directories = 0; + + +/* Hash table of files in each directory. */ + +struct dirfile + { + char *name; /* Name of the file. */ + short length; + short impossible; /* This file is impossible. */ + }; + +static unsigned long +dirfile_hash_1 (key) + const void *key; +{ + return_ISTRING_HASH_1 (((struct dirfile const *) key)->name); +} + +static unsigned long +dirfile_hash_2 (key) + const void *key; +{ + return_ISTRING_HASH_2 (((struct dirfile const *) key)->name); +} + +static int +dirfile_hash_cmp (xv, yv) + const void *xv; + const void *yv; +{ + struct dirfile const *x = ((struct dirfile const *) xv); + struct dirfile const *y = ((struct dirfile const *) yv); + int result = x->length - y->length; + if (result) + return result; + return_ISTRING_COMPARE (x->name, y->name); +} + +#ifndef DIRFILE_BUCKETS +#define DIRFILE_BUCKETS 107 +#endif + +static int dir_contents_file_exists_p PARAMS ((struct directory_contents *dir, char *filename)); +static struct directory *find_directory PARAMS ((char *name)); + +/* Find the directory named NAME and return its `struct directory'. */ + +static struct directory * +find_directory (name) + register char *name; +{ + register char *p; + register struct directory *dir; + register struct directory **dir_slot; + struct directory dir_key; + int r; +#ifdef WINDOWS32 + char* w32_path; + char fs_label[BUFSIZ]; + char fs_type[BUFSIZ]; + long fs_serno; + long fs_flags; + long fs_len; +#endif +#ifdef VMS + if ((*name == '.') && (*(name+1) == 0)) + name = "[]"; + else + name = vmsify (name,1); +#endif + + dir_key.name = name; + dir_slot = (struct directory **) hash_find_slot (&directories, &dir_key); + dir = *dir_slot; + + if (HASH_VACANT (dir)) + { + struct stat st; + + /* The directory was not found. Create a new entry for it. */ + + p = name + strlen (name); + dir = (struct directory *) xmalloc (sizeof (struct directory)); + dir->name = savestring (name, p - name); + hash_insert_at (&directories, dir, dir_slot); + /* The directory is not in the name hash table. + Find its device and inode numbers, and look it up by them. */ + +#ifdef WINDOWS32 + /* Remove any trailing '\'. Windows32 stat fails even on valid + directories if they end in '\'. */ + if (p[-1] == '\\') + p[-1] = '\0'; +#endif + +#ifdef VMS + r = vmsstat_dir (name, &st); +#else + r = stat (name, &st); +#endif + +#ifdef WINDOWS32 + /* Put back the trailing '\'. If we don't, we're permanently + truncating the value! */ + if (p[-1] == '\0') + p[-1] = '\\'; +#endif + + if (r < 0) + { + /* Couldn't stat the directory. Mark this by + setting the `contents' member to a nil pointer. */ + dir->contents = 0; + } + else + { + /* Search the contents hash table; device and inode are the key. */ + + struct directory_contents *dc; + struct directory_contents **dc_slot; + struct directory_contents dc_key; + + dc_key.dev = st.st_dev; +#ifdef WINDOWS32 + dc_key.path_key = w32_path = w32ify (name, 1); + dc_key.ctime = st.st_ctime; +#else +# ifdef VMS + dc_key.ino[0] = st.st_ino[0]; + dc_key.ino[1] = st.st_ino[1]; + dc_key.ino[2] = st.st_ino[2]; +# else + dc_key.ino = st.st_ino; +# endif +#endif + dc_slot = (struct directory_contents **) hash_find_slot (&directory_contents, &dc_key); + dc = *dc_slot; + + if (HASH_VACANT (dc)) + { + /* Nope; this really is a directory we haven't seen before. */ + + dc = (struct directory_contents *) + xmalloc (sizeof (struct directory_contents)); + + /* Enter it in the contents hash table. */ + dc->dev = st.st_dev; +#ifdef WINDOWS32 + dc->path_key = xstrdup (w32_path); + dc->ctime = st.st_ctime; + dc->mtime = st.st_mtime; + + /* + * NTFS is the only WINDOWS32 filesystem that bumps mtime + * on a directory when files are added/deleted from + * a directory. + */ + w32_path[3] = '\0'; + if (GetVolumeInformation(w32_path, + fs_label, sizeof (fs_label), + &fs_serno, &fs_len, + &fs_flags, fs_type, sizeof (fs_type)) == FALSE) + dc->fs_flags = FS_UNKNOWN; + else if (!strcmp(fs_type, "FAT")) + dc->fs_flags = FS_FAT; + else if (!strcmp(fs_type, "NTFS")) + dc->fs_flags = FS_NTFS; + else + dc->fs_flags = FS_UNKNOWN; +#else +# ifdef VMS + dc->ino[0] = st.st_ino[0]; + dc->ino[1] = st.st_ino[1]; + dc->ino[2] = st.st_ino[2]; +# else + dc->ino = st.st_ino; +# endif +#endif /* WINDOWS32 */ + hash_insert_at (&directory_contents, dc, dc_slot); + dc->dirstream = opendir (name); + if (dc->dirstream == 0) + /* Couldn't open the directory. Mark this by + setting the `files' member to a nil pointer. */ + dc->dirfiles.ht_vec = 0; + else + { + hash_init (&dc->dirfiles, DIRFILE_BUCKETS, + dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp); + /* Keep track of how many directories are open. */ + ++open_directories; + if (open_directories == MAX_OPEN_DIRECTORIES) + /* We have too many directories open already. + Read the entire directory and then close it. */ + (void) dir_contents_file_exists_p (dc, (char *) 0); + } + } + + /* Point the name-hashed entry for DIR at its contents data. */ + dir->contents = dc; + } + } + + return dir; +} + +/* Return 1 if the name FILENAME is entered in DIR's hash table. + FILENAME must contain no slashes. */ + +static int +dir_contents_file_exists_p (dir, filename) + register struct directory_contents *dir; + register char *filename; +{ + unsigned int hash; + struct dirfile *df; + struct dirent *d; +#ifdef WINDOWS32 + struct stat st; + int rehash = 0; +#endif + + if (dir == 0 || dir->dirfiles.ht_vec == 0) + { + /* The directory could not be stat'd or opened. */ + return 0; + } +#ifdef __MSDOS__ + filename = dosify (filename); +#endif + +#ifdef HAVE_CASE_INSENSITIVE_FS + filename = downcase (filename); +#endif + +#ifdef VMS + filename = vmsify (filename,0); +#endif + + hash = 0; + if (filename != 0) + { + struct dirfile dirfile_key; + + if (*filename == '\0') + { + /* Checking if the directory exists. */ + return 1; + } + dirfile_key.name = filename; + dirfile_key.length = strlen (filename); + df = (struct dirfile *) hash_find_item (&dir->dirfiles, &dirfile_key); + if (df) + { + return !df->impossible; + } + } + + /* The file was not found in the hashed list. + Try to read the directory further. */ + + if (dir->dirstream == 0) + { +#ifdef WINDOWS32 + /* + * Check to see if directory has changed since last read. FAT + * filesystems force a rehash always as mtime does not change + * on directories (ugh!). + */ + if (dir->path_key + && (dir->fs_flags & FS_FAT + || (stat(dir->path_key, &st) == 0 + && st.st_mtime > dir->mtime))) + { + /* reset date stamp to show most recent re-process */ + dir->mtime = st.st_mtime; + + /* make sure directory can still be opened */ + dir->dirstream = opendir(dir->path_key); + + if (dir->dirstream) + rehash = 1; + else + return 0; /* couldn't re-read - fail */ + } + else +#endif + /* The directory has been all read in. */ + return 0; + } + + while ((d = readdir (dir->dirstream)) != 0) + { + /* Enter the file in the hash table. */ + unsigned int len; + struct dirfile dirfile_key; + struct dirfile **dirfile_slot; + +#if defined(VMS) && defined(HAVE_DIRENT_H) + /* In VMS we get file versions too, which have to be stripped off */ + { + char *p = strrchr (d->d_name, ';'); + if (p) + *p = '\0'; + } +#endif + if (!REAL_DIR_ENTRY (d)) + continue; + + len = NAMLEN (d); + dirfile_key.name = d->d_name; + dirfile_key.length = len; + dirfile_slot = (struct dirfile **) hash_find_slot (&dir->dirfiles, &dirfile_key); +#ifdef WINDOWS32 + /* + * If re-reading a directory, don't cache files that have + * already been discovered. + */ + if (! rehash || HASH_VACANT (*dirfile_slot)) +#endif + { + df = (struct dirfile *) xmalloc (sizeof (struct dirfile)); + df->name = savestring (d->d_name, len); + df->length = len; + df->impossible = 0; + hash_insert_at (&dir->dirfiles, df, dirfile_slot); + } + /* Check if the name matches the one we're searching for. */ + if (filename != 0 && strieq (d->d_name, filename)) + { + return 1; + } + } + + /* If the directory has been completely read in, + close the stream and reset the pointer to nil. */ + if (d == 0) + { + --open_directories; + closedir (dir->dirstream); + dir->dirstream = 0; + } + return 0; +} + +/* Return 1 if the name FILENAME in directory DIRNAME + is entered in the dir hash table. + FILENAME must contain no slashes. */ + +int +dir_file_exists_p (dirname, filename) + register char *dirname; + register char *filename; +{ + return dir_contents_file_exists_p (find_directory (dirname)->contents, + filename); +} + +/* Return 1 if the file named NAME exists. */ + +int +file_exists_p (name) + register char *name; +{ + char *dirend; + char *dirname; + char *slash; + +#ifndef NO_ARCHIVES + if (ar_name (name)) + return ar_member_date (name) != (time_t) -1; +#endif + +#ifdef VMS + dirend = strrchr (name, ']'); + if (dirend == 0) + dirend = strrchr (name, ':'); + dirend++; + if (dirend == (char *)1) + return dir_file_exists_p ("[]", name); +#else /* !VMS */ + dirend = strrchr (name, '/'); +#ifdef HAVE_DOS_PATHS + /* Forward and backslashes might be mixed. We need the rightmost one. */ + { + char *bslash = strrchr(name, '\\'); + if (!dirend || bslash > dirend) + dirend = bslash; + /* The case of "d:file". */ + if (!dirend && name[0] && name[1] == ':') + dirend = name + 1; + } +#endif /* HAVE_DOS_PATHS */ + if (dirend == 0) +#ifndef _AMIGA + return dir_file_exists_p (".", name); +#else /* !VMS && !AMIGA */ + return dir_file_exists_p ("", name); +#endif /* AMIGA */ +#endif /* VMS */ + + slash = dirend; + if (dirend == name) + dirname = "/"; + else + { +#ifdef HAVE_DOS_PATHS + /* d:/ and d: are *very* different... */ + if (dirend < name + 3 && name[1] == ':' && + (*dirend == '/' || *dirend == '\\' || *dirend == ':')) + dirend++; +#endif + dirname = (char *) alloca (dirend - name + 1); + bcopy (name, dirname, dirend - name); + dirname[dirend - name] = '\0'; + } + return dir_file_exists_p (dirname, slash + 1); +} + +/* Mark FILENAME as `impossible' for `file_impossible_p'. + This means an attempt has been made to search for FILENAME + as an intermediate file, and it has failed. */ + +void +file_impossible (filename) + register char *filename; +{ + char *dirend; + register char *p = filename; + register struct directory *dir; + register struct dirfile *new; + +#ifdef VMS + dirend = strrchr (p, ']'); + if (dirend == 0) + dirend = strrchr (p, ':'); + dirend++; + if (dirend == (char *)1) + dir = find_directory ("[]"); +#else + dirend = strrchr (p, '/'); +# ifdef HAVE_DOS_PATHS + /* Forward and backslashes might be mixed. We need the rightmost one. */ + { + char *bslash = strrchr(p, '\\'); + if (!dirend || bslash > dirend) + dirend = bslash; + /* The case of "d:file". */ + if (!dirend && p[0] && p[1] == ':') + dirend = p + 1; + } +# endif /* HAVE_DOS_PATHS */ + if (dirend == 0) +# ifdef _AMIGA + dir = find_directory (""); +# else /* !VMS && !AMIGA */ + dir = find_directory ("."); +# endif /* AMIGA */ +#endif /* VMS */ + else + { + char *dirname; + char *slash = dirend; + if (dirend == p) + dirname = "/"; + else + { +#ifdef HAVE_DOS_PATHS + /* d:/ and d: are *very* different... */ + if (dirend < p + 3 && p[1] == ':' && + (*dirend == '/' || *dirend == '\\' || *dirend == ':')) + dirend++; +#endif + dirname = (char *) alloca (dirend - p + 1); + bcopy (p, dirname, dirend - p); + dirname[dirend - p] = '\0'; + } + dir = find_directory (dirname); + filename = p = slash + 1; + } + + if (dir->contents == 0) + { + /* The directory could not be stat'd. We allocate a contents + structure for it, but leave it out of the contents hash table. */ + dir->contents = (struct directory_contents *) + xmalloc (sizeof (struct directory_contents)); + bzero ((char *) dir->contents, sizeof (struct directory_contents)); + } + + if (dir->contents->dirfiles.ht_vec == 0) + { + hash_init (&dir->contents->dirfiles, DIRFILE_BUCKETS, + dirfile_hash_1, dirfile_hash_2, dirfile_hash_cmp); + } + + /* Make a new entry and put it in the table. */ + + new = (struct dirfile *) xmalloc (sizeof (struct dirfile)); + new->name = xstrdup (filename); + new->length = strlen (filename); + new->impossible = 1; + hash_insert (&dir->contents->dirfiles, new); +} + +/* Return nonzero if FILENAME has been marked impossible. */ + +int +file_impossible_p (filename) + char *filename; +{ + char *dirend; + register char *p = filename; + register struct directory_contents *dir; + register struct dirfile *dirfile; + struct dirfile dirfile_key; + +#ifdef VMS + dirend = strrchr (filename, ']'); + if (dirend == 0) + dir = find_directory ("[]")->contents; +#else + dirend = strrchr (filename, '/'); +#ifdef HAVE_DOS_PATHS + /* Forward and backslashes might be mixed. We need the rightmost one. */ + { + char *bslash = strrchr(filename, '\\'); + if (!dirend || bslash > dirend) + dirend = bslash; + /* The case of "d:file". */ + if (!dirend && filename[0] && filename[1] == ':') + dirend = filename + 1; + } +#endif /* HAVE_DOS_PATHS */ + if (dirend == 0) +#ifdef _AMIGA + dir = find_directory ("")->contents; +#else /* !VMS && !AMIGA */ + dir = find_directory (".")->contents; +#endif /* AMIGA */ +#endif /* VMS */ + else + { + char *dirname; + char *slash = dirend; + if (dirend == filename) + dirname = "/"; + else + { +#ifdef HAVE_DOS_PATHS + /* d:/ and d: are *very* different... */ + if (dirend < filename + 3 && filename[1] == ':' && + (*dirend == '/' || *dirend == '\\' || *dirend == ':')) + dirend++; +#endif + dirname = (char *) alloca (dirend - filename + 1); + bcopy (p, dirname, dirend - p); + dirname[dirend - p] = '\0'; + } + dir = find_directory (dirname)->contents; + p = filename = slash + 1; + } + + if (dir == 0 || dir->dirfiles.ht_vec == 0) + /* There are no files entered for this directory. */ + return 0; + +#ifdef __MSDOS__ + filename = dosify (p); +#endif +#ifdef HAVE_CASE_INSENSITIVE_FS + filename = downcase (p); +#endif +#ifdef VMS + filename = vmsify (p, 1); +#endif + + dirfile_key.name = filename; + dirfile_key.length = strlen (filename); + dirfile = (struct dirfile *) hash_find_item (&dir->dirfiles, &dirfile_key); + if (dirfile) + return dirfile->impossible; + + return 0; +} + +/* Return the already allocated name in the + directory hash table that matches DIR. */ + +char * +dir_name (dir) + char *dir; +{ + return find_directory (dir)->name; +} + +/* Print the data base of directories. */ + +void +print_dir_data_base () +{ + register unsigned int files; + register unsigned int impossible; + register struct directory **dir_slot; + register struct directory **dir_end; + + puts (_("\n# Directories\n")); + + files = impossible = 0; + + dir_slot = (struct directory **) directories.ht_vec; + dir_end = dir_slot + directories.ht_size; + for ( ; dir_slot < dir_end; dir_slot++) + { + register struct directory *dir = *dir_slot; + if (! HASH_VACANT (dir)) + { + if (dir->contents == 0) + printf (_("# %s: could not be stat'd.\n"), dir->name); + else if (dir->contents->dirfiles.ht_vec == 0) + { +#ifdef WINDOWS32 + printf (_("# %s (key %s, mtime %d): could not be opened.\n"), + dir->name, dir->contents->path_key,dir->contents->mtime); +#else /* WINDOWS32 */ +#ifdef VMS + printf (_("# %s (device %d, inode [%d,%d,%d]): could not be opened.\n"), + dir->name, dir->contents->dev, + dir->contents->ino[0], dir->contents->ino[1], + dir->contents->ino[2]); +#else + printf (_("# %s (device %ld, inode %ld): could not be opened.\n"), + dir->name, (long int) dir->contents->dev, + (long int) dir->contents->ino); +#endif +#endif /* WINDOWS32 */ + } + else + { + register unsigned int f = 0; + register unsigned int im = 0; + register struct dirfile **files_slot; + register struct dirfile **files_end; + + files_slot = (struct dirfile **) dir->contents->dirfiles.ht_vec; + files_end = files_slot + dir->contents->dirfiles.ht_size; + for ( ; files_slot < files_end; files_slot++) + { + register struct dirfile *df = *files_slot; + if (! HASH_VACANT (df)) + { + if (df->impossible) + ++im; + else + ++f; + } + } +#ifdef WINDOWS32 + printf (_("# %s (key %s, mtime %d): "), + dir->name, dir->contents->path_key, dir->contents->mtime); +#else /* WINDOWS32 */ +#ifdef VMS + printf (_("# %s (device %d, inode [%d,%d,%d]): "), + dir->name, dir->contents->dev, + dir->contents->ino[0], dir->contents->ino[1], + dir->contents->ino[2]); +#else + printf (_("# %s (device %ld, inode %ld): "), + dir->name, + (long)dir->contents->dev, (long)dir->contents->ino); +#endif +#endif /* WINDOWS32 */ + if (f == 0) + fputs (_("No"), stdout); + else + printf ("%u", f); + fputs (_(" files, "), stdout); + if (im == 0) + fputs (_("no"), stdout); + else + printf ("%u", im); + fputs (_(" impossibilities"), stdout); + if (dir->contents->dirstream == 0) + puts ("."); + else + puts (_(" so far.")); + files += f; + impossible += im; + } + } + } + + fputs ("\n# ", stdout); + if (files == 0) + fputs (_("No"), stdout); + else + printf ("%u", files); + fputs (_(" files, "), stdout); + if (impossible == 0) + fputs (_("no"), stdout); + else + printf ("%u", impossible); + printf (_(" impossibilities in %lu directories.\n"), directories.ht_fill); +} + +/* Hooks for globbing. */ + +#include + +/* Structure describing state of iterating through a directory hash table. */ + +struct dirstream + { + struct directory_contents *contents; /* The directory being read. */ + struct dirfile **dirfile_slot; /* Current slot in table. */ + }; + +/* Forward declarations. */ +static __ptr_t open_dirstream PARAMS ((const char *)); +static struct dirent *read_dirstream PARAMS ((__ptr_t)); + +static __ptr_t +open_dirstream (directory) + const char *directory; +{ + struct dirstream *new; + struct directory *dir = find_directory ((char *)directory); + + if (dir->contents == 0 || dir->contents->dirfiles.ht_vec == 0) + /* DIR->contents is nil if the directory could not be stat'd. + DIR->contents->dirfiles is nil if it could not be opened. */ + return 0; + + /* Read all the contents of the directory now. There is no benefit + in being lazy, since glob will want to see every file anyway. */ + + (void) dir_contents_file_exists_p (dir->contents, (char *) 0); + + new = (struct dirstream *) xmalloc (sizeof (struct dirstream)); + new->contents = dir->contents; + new->dirfile_slot = (struct dirfile **) new->contents->dirfiles.ht_vec; + + return (__ptr_t) new; +} + +static struct dirent * +read_dirstream (stream) + __ptr_t stream; +{ + struct dirstream *const ds = (struct dirstream *) stream; + struct directory_contents *dc = ds->contents; + struct dirfile **dirfile_end = (struct dirfile **) dc->dirfiles.ht_vec + dc->dirfiles.ht_size; + static char *buf; + static unsigned int bufsz; + + while (ds->dirfile_slot < dirfile_end) + { + register struct dirfile *df = *ds->dirfile_slot++; + if (! HASH_VACANT (df) && !df->impossible) + { + /* The glob interface wants a `struct dirent', + so mock one up. */ + struct dirent *d; + unsigned int len = df->length + 1; + if (sizeof *d - sizeof d->d_name + len > bufsz) + { + if (buf != 0) + free (buf); + bufsz *= 2; + if (sizeof *d - sizeof d->d_name + len > bufsz) + bufsz = sizeof *d - sizeof d->d_name + len; + buf = xmalloc (bufsz); + } + d = (struct dirent *) buf; + FAKE_DIR_ENTRY (d); +#ifdef _DIRENT_HAVE_D_NAMLEN + d->d_namlen = len - 1; +#endif +#ifdef _DIRENT_HAVE_D_TYPE + d->d_type = DT_UNKNOWN; +#endif + memcpy (d->d_name, df->name, len); + return d; + } + } + + return 0; +} + +static void +ansi_free(p) + void *p; +{ + if (p) + free(p); +} + +/* On 64 bit ReliantUNIX (5.44 and above) in LFS mode, stat() is actually a + * macro for stat64(). If stat is a macro, make a local wrapper function to + * invoke it. + */ +#ifndef stat +# ifndef VMS +extern int stat (); +# endif +# define local_stat stat +#else +static int local_stat (path, buf) + char *path; + struct stat *buf; +{ + return stat (path, buf); +} +#endif + +void +dir_setup_glob (gl) + glob_t *gl; +{ + /* Bogus sunos4 compiler complains (!) about & before functions. */ + gl->gl_opendir = open_dirstream; + gl->gl_readdir = read_dirstream; + gl->gl_closedir = ansi_free; + gl->gl_stat = local_stat; + /* We don't bother setting gl_lstat, since glob never calls it. + The slot is only there for compatibility with 4.4 BSD. */ +} + +void +hash_init_directories () +{ + hash_init (&directories, DIRECTORY_BUCKETS, + directory_hash_1, directory_hash_2, directory_hash_cmp); + hash_init (&directory_contents, DIRECTORY_BUCKETS, + directory_contents_hash_1, directory_contents_hash_2, directory_contents_hash_cmp); +} diff --git a/src/make-3.80/dosbuild.bat b/src/make-3.80/dosbuild.bat new file mode 100755 index 00000000..ac1e6cd6 --- /dev/null +++ b/src/make-3.80/dosbuild.bat @@ -0,0 +1,42 @@ +@echo Building Make for MSDOS +@rem Echo ON so they will see what is going on. +@echo on +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g commands.c -o commands.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g job.c -o job.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g dir.c -o dir.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g file.c -o file.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g misc.c -o misc.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g main.c -o main.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -DINCLUDEDIR=\"c:/djgpp/include\" -O2 -g read.c -o read.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -DLIBDIR=\"c:/djgpp/lib\" -O2 -g remake.c -o remake.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g rule.c -o rule.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g implicit.c -o implicit.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g default.c -o default.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g variable.c -o variable.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g expand.c -o expand.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g function.c -o function.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g vpath.c -o vpath.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g version.c -o version.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g ar.c -o ar.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g arscan.c -o arscan.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g signame.c -o signame.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g remote-stub.c -o remote-stub.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g getopt.c -o getopt.o +gcc -c -I. -I./glob -DHAVE_CONFIG_H -O2 -g getopt1.c -o getopt1.o +@cd glob +@if exist libglob.a del libglob.a +gcc -I. -c -DHAVE_CONFIG_H -I.. -O2 -g glob.c -o glob.o +gcc -I. -c -DHAVE_CONFIG_H -I.. -O2 -g fnmatch.c -o fnmatch.o +ar rv libglob.a glob.o fnmatch.o +@echo off +cd .. +echo commands.o > respf.$$$ +for %%f in (job dir file misc main read remake rule implicit default variable) do echo %%f.o >> respf.$$$ +for %%f in (expand function vpath version ar arscan signame remote-stub getopt getopt1) do echo %%f.o >> respf.$$$ +echo glob/libglob.a >> respf.$$$ +@echo Linking... +@echo on +gcc -o make.new @respf.$$$ +@if exist make.exe echo Make.exe is now built! +@if not exist make.exe echo Make.exe build failed... +@if exist make.exe del respf.$$$ diff --git a/src/make-3.80/expand.c b/src/make-3.80/expand.c new file mode 100755 index 00000000..6722e1b3 --- /dev/null +++ b/src/make-3.80/expand.c @@ -0,0 +1,566 @@ +/* Variable expansion functions for GNU Make. +Copyright (C) 1988, 89, 91, 92, 93, 95 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" + +#include + +#include "filedef.h" +#include "job.h" +#include "commands.h" +#include "variable.h" +#include "rule.h" + +/* The next two describe the variable output buffer. + This buffer is used to hold the variable-expansion of a line of the + makefile. It is made bigger with realloc whenever it is too small. + variable_buffer_length is the size currently allocated. + variable_buffer is the address of the buffer. + + For efficiency, it's guaranteed that the buffer will always have + VARIABLE_BUFFER_ZONE extra bytes allocated. This allows you to add a few + extra chars without having to call a function. Note you should never use + these bytes unless you're _sure_ you have room (you know when the buffer + length was last checked. */ + +#define VARIABLE_BUFFER_ZONE 5 + +static unsigned int variable_buffer_length; +char *variable_buffer; + +/* Subroutine of variable_expand and friends: + The text to add is LENGTH chars starting at STRING to the variable_buffer. + The text is added to the buffer at PTR, and the updated pointer into + the buffer is returned as the value. Thus, the value returned by + each call to variable_buffer_output should be the first argument to + the following call. */ + +char * +variable_buffer_output (ptr, string, length) + char *ptr, *string; + unsigned int length; +{ + register unsigned int newlen = length + (ptr - variable_buffer); + + if ((newlen + VARIABLE_BUFFER_ZONE) > variable_buffer_length) + { + unsigned int offset = ptr - variable_buffer; + variable_buffer_length = (newlen + 100 > 2 * variable_buffer_length + ? newlen + 100 + : 2 * variable_buffer_length); + variable_buffer = (char *) xrealloc (variable_buffer, + variable_buffer_length); + ptr = variable_buffer + offset; + } + + bcopy (string, ptr, length); + return ptr + length; +} + +/* Return a pointer to the beginning of the variable buffer. */ + +static char * +initialize_variable_output () +{ + /* If we don't have a variable output buffer yet, get one. */ + + if (variable_buffer == 0) + { + variable_buffer_length = 200; + variable_buffer = (char *) xmalloc (variable_buffer_length); + variable_buffer[0] = '\0'; + } + + return variable_buffer; +} + +/* Recursively expand V. The returned string is malloc'd. */ + +static char *allocated_variable_append PARAMS ((const struct variable *v)); + +char * +recursively_expand_for_file (v, file) + struct variable *v; + struct file *file; +{ + char *value; + struct variable_set_list *save = 0; + + if (v->expanding) + { + if (!v->exp_count) + /* Expanding V causes infinite recursion. Lose. */ + fatal (reading_file, + _("Recursive variable `%s' references itself (eventually)"), + v->name); + --v->exp_count; + } + + if (file) + { + save = current_variable_set_list; + current_variable_set_list = file->variables; + } + + v->expanding = 1; + if (v->append) + value = allocated_variable_append (v); + else + value = allocated_variable_expand (v->value); + v->expanding = 0; + + if (file) + current_variable_set_list = save; + + return value; +} + +/* Expand a simple reference to variable NAME, which is LENGTH chars long. */ + +#ifdef __GNUC__ +__inline +#endif +static char * +reference_variable (o, name, length) + char *o; + char *name; + unsigned int length; +{ + register struct variable *v; + char *value; + + v = lookup_variable (name, length); + + if (v == 0) + warn_undefined (name, length); + + if (v == 0 || *v->value == '\0') + return o; + + value = (v->recursive ? recursively_expand (v) : v->value); + + o = variable_buffer_output (o, value, strlen (value)); + + if (v->recursive) + free (value); + + return o; +} + +/* Scan STRING for variable references and expansion-function calls. Only + LENGTH bytes of STRING are actually scanned. If LENGTH is -1, scan until + a null byte is found. + + Write the results to LINE, which must point into `variable_buffer'. If + LINE is NULL, start at the beginning of the buffer. + Return a pointer to LINE, or to the beginning of the buffer if LINE is + NULL. */ + +char * +variable_expand_string (line, string, length) + register char *line; + char *string; + long length; +{ + register struct variable *v; + register char *p, *o, *p1; + char save_char = '\0'; + unsigned int line_offset; + + if (!line) + line = initialize_variable_output(); + + p = string; + o = line; + line_offset = line - variable_buffer; + + if (length >= 0) + { + save_char = string[length]; + string[length] = '\0'; + } + + while (1) + { + /* Copy all following uninteresting chars all at once to the + variable output buffer, and skip them. Uninteresting chars end + at the next $ or the end of the input. */ + + p1 = strchr (p, '$'); + + o = variable_buffer_output (o, p, p1 != 0 ? p1 - p : strlen (p) + 1); + + if (p1 == 0) + break; + p = p1 + 1; + + /* Dispatch on the char that follows the $. */ + + switch (*p) + { + case '$': + /* $$ seen means output one $ to the variable output buffer. */ + o = variable_buffer_output (o, p, 1); + break; + + case '(': + case '{': + /* $(...) or ${...} is the general case of substitution. */ + { + char openparen = *p; + char closeparen = (openparen == '(') ? ')' : '}'; + register char *beg = p + 1; + int free_beg = 0; + char *op, *begp; + char *end, *colon; + + op = o; + begp = p; + if (handle_function (&op, &begp)) + { + o = op; + p = begp; + break; + } + + /* Is there a variable reference inside the parens or braces? + If so, expand it before expanding the entire reference. */ + + end = strchr (beg, closeparen); + if (end == 0) + /* Unterminated variable reference. */ + fatal (reading_file, _("unterminated variable reference")); + p1 = lindex (beg, end, '$'); + if (p1 != 0) + { + /* BEG now points past the opening paren or brace. + Count parens or braces until it is matched. */ + int count = 0; + for (p = beg; *p != '\0'; ++p) + { + if (*p == openparen) + ++count; + else if (*p == closeparen && --count < 0) + break; + } + /* If COUNT is >= 0, there were unmatched opening parens + or braces, so we go to the simple case of a variable name + such as `$($(a)'. */ + if (count < 0) + { + beg = expand_argument (beg, p); /* Expand the name. */ + free_beg = 1; /* Remember to free BEG when finished. */ + end = strchr (beg, '\0'); + } + } + else + /* Advance P to the end of this reference. After we are + finished expanding this one, P will be incremented to + continue the scan. */ + p = end; + + /* This is not a reference to a built-in function and + any variable references inside are now expanded. + Is the resultant text a substitution reference? */ + + colon = lindex (beg, end, ':'); + if (colon) + { + /* This looks like a substitution reference: $(FOO:A=B). */ + char *subst_beg, *subst_end, *replace_beg, *replace_end; + + subst_beg = colon + 1; + subst_end = strchr (subst_beg, '='); + if (subst_end == 0) + /* There is no = in sight. Punt on the substitution + reference and treat this as a variable name containing + a colon, in the code below. */ + colon = 0; + else + { + replace_beg = subst_end + 1; + replace_end = end; + + /* Extract the variable name before the colon + and look up that variable. */ + v = lookup_variable (beg, colon - beg); + if (v == 0) + warn_undefined (beg, colon - beg); + + if (v != 0 && *v->value != '\0') + { + char *value = (v->recursive ? recursively_expand (v) + : v->value); + char *pattern, *percent; + if (free_beg) + { + *subst_end = '\0'; + pattern = subst_beg; + } + else + { + pattern = (char *) alloca (subst_end - subst_beg + + 1); + bcopy (subst_beg, pattern, subst_end - subst_beg); + pattern[subst_end - subst_beg] = '\0'; + } + percent = find_percent (pattern); + if (percent != 0) + { + char *replace; + if (free_beg) + { + *replace_end = '\0'; + replace = replace_beg; + } + else + { + replace = (char *) alloca (replace_end + - replace_beg + + 1); + bcopy (replace_beg, replace, + replace_end - replace_beg); + replace[replace_end - replace_beg] = '\0'; + } + + o = patsubst_expand (o, value, pattern, replace, + percent, (char *) 0); + } + else + o = subst_expand (o, value, + pattern, replace_beg, + strlen (pattern), + end - replace_beg, + 0, 1); + if (v->recursive) + free (value); + } + } + } + + if (colon == 0) + /* This is an ordinary variable reference. + Look up the value of the variable. */ + o = reference_variable (o, beg, end - beg); + + if (free_beg) + free (beg); + } + break; + + case '\0': + break; + + default: + if (isblank ((unsigned char)p[-1])) + break; + + /* A $ followed by a random char is a variable reference: + $a is equivalent to $(a). */ + { + /* We could do the expanding here, but this way + avoids code repetition at a small performance cost. */ + char name[5]; + name[0] = '$'; + name[1] = '('; + name[2] = *p; + name[3] = ')'; + name[4] = '\0'; + p1 = allocated_variable_expand (name); + o = variable_buffer_output (o, p1, strlen (p1)); + free (p1); + } + + break; + } + + if (*p == '\0') + break; + else + ++p; + } + + if (save_char) + string[length] = save_char; + + (void)variable_buffer_output (o, "", 1); + return (variable_buffer + line_offset); +} + +/* Scan LINE for variable references and expansion-function calls. + Build in `variable_buffer' the result of expanding the references and calls. + Return the address of the resulting string, which is null-terminated + and is valid only until the next time this function is called. */ + +char * +variable_expand (line) + char *line; +{ + return variable_expand_string(NULL, line, (long)-1); +} + +/* Expand an argument for an expansion function. + The text starting at STR and ending at END is variable-expanded + into a null-terminated string that is returned as the value. + This is done without clobbering `variable_buffer' or the current + variable-expansion that is in progress. */ + +char * +expand_argument (str, end) + char *str, *end; +{ + char *tmp; + + if (str == end) + return xstrdup(""); + + if (!end || *end == '\0') + tmp = str; + else + { + tmp = (char *) alloca (end - str + 1); + bcopy (str, tmp, end - str); + tmp[end - str] = '\0'; + } + + return allocated_variable_expand (tmp); +} + +/* Expand LINE for FILE. Error messages refer to the file and line where + FILE's commands were found. Expansion uses FILE's variable set list. */ + +static char * +variable_expand_for_file (line, file) + char *line; + register struct file *file; +{ + char *result; + struct variable_set_list *save; + + if (file == 0) + return variable_expand (line); + + save = current_variable_set_list; + current_variable_set_list = file->variables; + if (file->cmds && file->cmds->fileinfo.filenm) + reading_file = &file->cmds->fileinfo; + else + reading_file = 0; + result = variable_expand (line); + current_variable_set_list = save; + reading_file = 0; + + return result; +} + +/* Like allocated_variable_expand, but for += target-specific variables. + First recursively construct the variable value from its appended parts in + any upper variable sets. Then expand the resulting value. */ + +static char * +variable_append (name, length, set) + const char *name; + unsigned int length; + const struct variable_set_list *set; +{ + const struct variable *v; + char *buf = 0; + + /* If there's nothing left to check, return the empty buffer. */ + if (!set) + return initialize_variable_output (); + + /* Try to find the variable in this variable set. */ + v = lookup_variable_in_set (name, length, set->set); + + /* If there isn't one, look to see if there's one in a set above us. */ + if (!v) + return variable_append (name, length, set->next); + + /* If this variable type is append, first get any upper values. + If not, initialize the buffer. */ + if (v->append) + buf = variable_append (name, length, set->next); + else + buf = initialize_variable_output (); + + /* Append this value to the buffer, and return it. + If we already have a value, first add a space. */ + if (buf > variable_buffer) + buf = variable_buffer_output (buf, " ", 1); + + return variable_buffer_output (buf, v->value, strlen (v->value)); +} + + +static char * +allocated_variable_append (v) + const struct variable *v; +{ + char *val, *retval; + + /* Construct the appended variable value. */ + + char *obuf = variable_buffer; + unsigned int olen = variable_buffer_length; + + variable_buffer = 0; + + val = variable_append (v->name, strlen (v->name), current_variable_set_list); + variable_buffer_output (val, "", 1); + val = variable_buffer; + + variable_buffer = obuf; + variable_buffer_length = olen; + + /* Now expand it and return that. */ + + retval = allocated_variable_expand (val); + + free (val); + return retval; +} + +/* Like variable_expand_for_file, but the returned string is malloc'd. + This function is called a lot. It wants to be efficient. */ + +char * +allocated_variable_expand_for_file (line, file) + char *line; + struct file *file; +{ + char *value; + + char *obuf = variable_buffer; + unsigned int olen = variable_buffer_length; + + variable_buffer = 0; + + value = variable_expand_for_file (line, file); + +#if 0 + /* Waste a little memory and save time. */ + value = xrealloc (value, strlen (value)) +#endif + + variable_buffer = obuf; + variable_buffer_length = olen; + + return value; +} diff --git a/src/make-3.80/file.c b/src/make-3.80/file.c new file mode 100755 index 00000000..ce1a0f9f --- /dev/null +++ b/src/make-3.80/file.c @@ -0,0 +1,827 @@ +/* Target file hash table management for GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" + +#include + +#include "dep.h" +#include "filedef.h" +#include "job.h" +#include "commands.h" +#include "variable.h" +#include "debug.h" +#include "hash.h" + + +/* Hash table of files the makefile knows how to make. */ + +static unsigned long +file_hash_1 (key) + const void *key; +{ + return_ISTRING_HASH_1 (((struct file const *) key)->hname); +} + +static unsigned long +file_hash_2 (key) + const void *key; +{ + return_ISTRING_HASH_2 (((struct file const *) key)->hname); +} + +static int +file_hash_cmp (x, y) + const void *x; + const void *y; +{ + return_ISTRING_COMPARE (((struct file const *) x)->hname, + ((struct file const *) y)->hname); +} + +#ifndef FILE_BUCKETS +#define FILE_BUCKETS 1007 +#endif +static struct hash_table files; + +/* Whether or not .SECONDARY with no prerequisites was given. */ +static int all_secondary = 0; + +/* Access the hash table of all file records. + lookup_file given a name, return the struct file * for that name, + or nil if there is none. + enter_file similar, but create one if there is none. */ + +struct file * +lookup_file (name) + char *name; +{ + register struct file *f; + struct file file_key; +#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) + register char *lname, *ln; +#endif + + assert (*name != '\0'); + + /* This is also done in parse_file_seq, so this is redundant + for names read from makefiles. It is here for names passed + on the command line. */ +#ifdef VMS +# ifndef WANT_CASE_SENSITIVE_TARGETS + { + register char *n; + lname = (char *) malloc (strlen (name) + 1); + for (n = name, ln = lname; *n != '\0'; ++n, ++ln) + *ln = isupper ((unsigned char)*n) ? tolower ((unsigned char)*n) : *n; + *ln = '\0'; + name = lname; + } +# endif + + while (name[0] == '[' && name[1] == ']' && name[2] != '\0') + name += 2; +#endif + while (name[0] == '.' && name[1] == '/' && name[2] != '\0') + { + name += 2; + while (*name == '/') + /* Skip following slashes: ".//foo" is "foo", not "/foo". */ + ++name; + } + + if (*name == '\0') + /* It was all slashes after a dot. */ +#ifdef VMS + name = "[]"; +#else +#ifdef _AMIGA + name = ""; +#else + name = "./"; +#endif /* AMIGA */ +#endif /* VMS */ + + file_key.hname = name; + f = (struct file *) hash_find_item (&files, &file_key); +#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) + free (lname); +#endif + return f; +} + +struct file * +enter_file (name) + char *name; +{ + register struct file *f; + register struct file *new; + register struct file **file_slot; + struct file file_key; +#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) + char *lname, *ln; +#endif + + assert (*name != '\0'); + +#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) + { + register char *n; + lname = (char *) malloc (strlen (name) + 1); + for (n = name, ln = lname; *n != '\0'; ++n, ++ln) + { + if (isupper ((unsigned char)*n)) + *ln = tolower ((unsigned char)*n); + else + *ln = *n; + } + + *ln = 0; + /* Creates a possible leak, old value of name is unreachable, but I + currently don't know how to fix it. */ + name = lname; + } +#endif + + file_key.hname = name; + file_slot = (struct file **) hash_find_slot (&files, &file_key); + f = *file_slot; + if (! HASH_VACANT (f) && !f->double_colon) + { +#if defined(VMS) && !defined(WANT_CASE_SENSITIVE_TARGETS) + free(lname); +#endif + return f; + } + + new = (struct file *) xmalloc (sizeof (struct file)); + bzero ((char *) new, sizeof (struct file)); + new->name = new->hname = name; + new->update_status = -1; + + if (HASH_VACANT (f)) + hash_insert_at (&files, new, file_slot); + else + { + /* There is already a double-colon entry for this file. */ + new->double_colon = f; + while (f->prev != 0) + f = f->prev; + f->prev = new; + } + + return new; +} + +/* Rename FILE to NAME. This is not as simple as resetting + the `name' member, since it must be put in a new hash bucket, + and possibly merged with an existing file called NAME. */ + +void +rename_file (from_file, to_hname) + register struct file *from_file; + char *to_hname; +{ + rehash_file (from_file, to_hname); + while (from_file) + { + from_file->name = from_file->hname; + from_file = from_file->prev; + } +} + +/* Rehash FILE to NAME. This is not as simple as resetting + the `hname' member, since it must be put in a new hash bucket, + and possibly merged with an existing file called NAME. */ + +void +rehash_file (from_file, to_hname) + register struct file *from_file; + char *to_hname; +{ + struct file file_key; + struct file **file_slot; + struct file *to_file; + struct file *deleted_file; + struct file *f; + + file_key.hname = to_hname; + if (0 == file_hash_cmp (from_file, &file_key)) + return; + + file_key.hname = from_file->hname; + while (from_file->renamed != 0) + from_file = from_file->renamed; + if (file_hash_cmp (from_file, &file_key)) + /* hname changed unexpectedly */ + abort (); + + deleted_file = hash_delete (&files, from_file); + if (deleted_file != from_file) + /* from_file isn't the one stored in files */ + abort (); + + file_key.hname = to_hname; + file_slot = (struct file **) hash_find_slot (&files, &file_key); + to_file = *file_slot; + + from_file->hname = to_hname; + for (f = from_file->double_colon; f != 0; f = f->prev) + f->hname = to_hname; + + if (HASH_VACANT (to_file)) + hash_insert_at (&files, from_file, file_slot); + else + { + /* TO_FILE already exists under TO_HNAME. + We must retain TO_FILE and merge FROM_FILE into it. */ + + if (from_file->cmds != 0) + { + if (to_file->cmds == 0) + to_file->cmds = from_file->cmds; + else if (from_file->cmds != to_file->cmds) + { + /* We have two sets of commands. We will go with the + one given in the rule explicitly mentioning this name, + but give a message to let the user know what's going on. */ + if (to_file->cmds->fileinfo.filenm != 0) + error (&from_file->cmds->fileinfo, + _("Commands were specified for file `%s' at %s:%lu,"), + from_file->name, to_file->cmds->fileinfo.filenm, + to_file->cmds->fileinfo.lineno); + else + error (&from_file->cmds->fileinfo, + _("Commands for file `%s' were found by implicit rule search,"), + from_file->name); + error (&from_file->cmds->fileinfo, + _("but `%s' is now considered the same file as `%s'."), + from_file->name, to_hname); + error (&from_file->cmds->fileinfo, + _("Commands for `%s' will be ignored in favor of those for `%s'."), + to_hname, from_file->name); + } + } + + /* Merge the dependencies of the two files. */ + + if (to_file->deps == 0) + to_file->deps = from_file->deps; + else + { + register struct dep *deps = to_file->deps; + while (deps->next != 0) + deps = deps->next; + deps->next = from_file->deps; + } + + merge_variable_set_lists (&to_file->variables, from_file->variables); + + if (to_file->double_colon && from_file->is_target && !from_file->double_colon) + fatal (NILF, _("can't rename single-colon `%s' to double-colon `%s'"), + from_file->name, to_hname); + if (!to_file->double_colon && from_file->double_colon) + { + if (to_file->is_target) + fatal (NILF, _("can't rename double-colon `%s' to single-colon `%s'"), + from_file->name, to_hname); + else + to_file->double_colon = from_file->double_colon; + } + + if (from_file->last_mtime > to_file->last_mtime) + /* %%% Kludge so -W wins on a file that gets vpathized. */ + to_file->last_mtime = from_file->last_mtime; + + to_file->mtime_before_update = from_file->mtime_before_update; + +#define MERGE(field) to_file->field |= from_file->field + MERGE (precious); + MERGE (tried_implicit); + MERGE (updating); + MERGE (updated); + MERGE (is_target); + MERGE (cmd_target); + MERGE (phony); + MERGE (ignore_vpath); +#undef MERGE + + from_file->renamed = to_file; + } +} + +/* Remove all nonprecious intermediate files. + If SIG is nonzero, this was caused by a fatal signal, + meaning that a different message will be printed, and + the message will go to stderr rather than stdout. */ + +void +remove_intermediates (sig) + int sig; +{ + register struct file **file_slot; + register struct file **file_end; + int doneany = 0; + + /* If there's no way we will ever remove anything anyway, punt early. */ + if (question_flag || touch_flag || all_secondary) + return; + + if (sig && just_print_flag) + return; + + file_slot = (struct file **) files.ht_vec; + file_end = file_slot + files.ht_size; + for ( ; file_slot < file_end; file_slot++) + if (! HASH_VACANT (*file_slot)) + { + register struct file *f = *file_slot; + if (f->intermediate && (f->dontcare || !f->precious) + && !f->secondary && !f->cmd_target) + { + int status; + if (f->update_status == -1) + /* If nothing would have created this file yet, + don't print an "rm" command for it. */ + continue; + if (just_print_flag) + status = 0; + else + { + status = unlink (f->name); + if (status < 0 && errno == ENOENT) + continue; + } + if (!f->dontcare) + { + if (sig) + error (NILF, _("*** Deleting intermediate file `%s'"), f->name); + else + { + if (! doneany) + DB (DB_BASIC, (_("Removing intermediate files...\n"))); + if (!silent_flag) + { + if (! doneany) + { + fputs ("rm ", stdout); + doneany = 1; + } + else + putchar (' '); + fputs (f->name, stdout); + fflush (stdout); + } + } + if (status < 0) + perror_with_name ("unlink: ", f->name); + } + } + } + + if (doneany && !sig) + { + putchar ('\n'); + fflush (stdout); + } +} + +/* For each dependency of each file, make the `struct dep' point + at the appropriate `struct file' (which may have to be created). + + Also mark the files depended on by .PRECIOUS, .PHONY, .SILENT, + and various other special targets. */ + +void +snap_deps () +{ + register struct file *f; + register struct file *f2; + register struct dep *d; + register struct file **file_slot_0; + register struct file **file_slot; + register struct file **file_end; + + /* Enter each dependency name as a file. */ + /* We must use hash_dump (), because within this loop + we might add new files to the table, possibly causing + an in-situ table expansion. */ + file_slot_0 = (struct file **) hash_dump (&files, 0, 0); + file_end = file_slot_0 + files.ht_fill; + for (file_slot = file_slot_0; file_slot < file_end; file_slot++) + for (f2 = *file_slot; f2 != 0; f2 = f2->prev) + for (d = f2->deps; d != 0; d = d->next) + if (d->name != 0) + { + d->file = lookup_file (d->name); + if (d->file == 0) + d->file = enter_file (d->name); + else + free (d->name); + d->name = 0; + } + free (file_slot_0); + + for (f = lookup_file (".PRECIOUS"); f != 0; f = f->prev) + for (d = f->deps; d != 0; d = d->next) + for (f2 = d->file; f2 != 0; f2 = f2->prev) + f2->precious = 1; + + for (f = lookup_file (".LOW_RESOLUTION_TIME"); f != 0; f = f->prev) + for (d = f->deps; d != 0; d = d->next) + for (f2 = d->file; f2 != 0; f2 = f2->prev) + f2->low_resolution_time = 1; + + for (f = lookup_file (".PHONY"); f != 0; f = f->prev) + for (d = f->deps; d != 0; d = d->next) + for (f2 = d->file; f2 != 0; f2 = f2->prev) + { + /* Mark this file as phony and nonexistent. */ + f2->phony = 1; + f2->last_mtime = NONEXISTENT_MTIME; + f2->mtime_before_update = NONEXISTENT_MTIME; + } + + for (f = lookup_file (".INTERMEDIATE"); f != 0; f = f->prev) + { + /* .INTERMEDIATE with deps listed + marks those deps as intermediate files. */ + for (d = f->deps; d != 0; d = d->next) + for (f2 = d->file; f2 != 0; f2 = f2->prev) + f2->intermediate = 1; + /* .INTERMEDIATE with no deps does nothing. + Marking all files as intermediates is useless + since the goal targets would be deleted after they are built. */ + } + + for (f = lookup_file (".SECONDARY"); f != 0; f = f->prev) + { + /* .SECONDARY with deps listed + marks those deps as intermediate files + in that they don't get rebuilt if not actually needed; + but unlike real intermediate files, + these are not deleted after make finishes. */ + if (f->deps) + for (d = f->deps; d != 0; d = d->next) + for (f2 = d->file; f2 != 0; f2 = f2->prev) + f2->intermediate = f2->secondary = 1; + /* .SECONDARY with no deps listed marks *all* files that way. */ + else + all_secondary = 1; + } + + f = lookup_file (".EXPORT_ALL_VARIABLES"); + if (f != 0 && f->is_target) + export_all_variables = 1; + + f = lookup_file (".IGNORE"); + if (f != 0 && f->is_target) + { + if (f->deps == 0) + ignore_errors_flag = 1; + else + for (d = f->deps; d != 0; d = d->next) + for (f2 = d->file; f2 != 0; f2 = f2->prev) + f2->command_flags |= COMMANDS_NOERROR; + } + + f = lookup_file (".SILENT"); + if (f != 0 && f->is_target) + { + if (f->deps == 0) + silent_flag = 1; + else + for (d = f->deps; d != 0; d = d->next) + for (f2 = d->file; f2 != 0; f2 = f2->prev) + f2->command_flags |= COMMANDS_SILENT; + } + + f = lookup_file (".POSIX"); + if (f != 0 && f->is_target) + posix_pedantic = 1; + + f = lookup_file (".NOTPARALLEL"); + if (f != 0 && f->is_target) + not_parallel = 1; +} + +/* Set the `command_state' member of FILE and all its `also_make's. */ + +void +set_command_state (file, state) + struct file *file; + int state; +{ + struct dep *d; + + file->command_state = state; + + for (d = file->also_make; d != 0; d = d->next) + d->file->command_state = state; +} + +/* Convert an external file timestamp to internal form. */ + +FILE_TIMESTAMP +file_timestamp_cons (fname, s, ns) + char const *fname; + time_t s; + int ns; +{ + int offset = ORDINARY_MTIME_MIN + (FILE_TIMESTAMP_HI_RES ? ns : 0); + FILE_TIMESTAMP product = (FILE_TIMESTAMP) s << FILE_TIMESTAMP_LO_BITS; + FILE_TIMESTAMP ts = product + offset; + + if (! (s <= FILE_TIMESTAMP_S (ORDINARY_MTIME_MAX) + && product <= ts && ts <= ORDINARY_MTIME_MAX)) + { + char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; + ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX; + file_timestamp_sprintf (buf, ts); + error (NILF, _("%s: Timestamp out of range; substituting %s"), + fname ? fname : _("Current time"), buf); + } + + return ts; +} + +/* Return the current time as a file timestamp, setting *RESOLUTION to + its resolution. */ +FILE_TIMESTAMP +file_timestamp_now (resolution) + int *resolution; +{ + int r; + time_t s; + int ns; + + /* Don't bother with high-resolution clocks if file timestamps have + only one-second resolution. The code below should work, but it's + not worth the hassle of debugging it on hosts where it fails. */ +#if FILE_TIMESTAMP_HI_RES +# if HAVE_CLOCK_GETTIME && defined CLOCK_REALTIME + { + struct timespec timespec; + if (clock_gettime (CLOCK_REALTIME, ×pec) == 0) + { + r = 1; + s = timespec.tv_sec; + ns = timespec.tv_nsec; + goto got_time; + } + } +# endif +# if HAVE_GETTIMEOFDAY + { + struct timeval timeval; + if (gettimeofday (&timeval, 0) == 0) + { + r = 1000; + s = timeval.tv_sec; + ns = timeval.tv_usec * 1000; + goto got_time; + } + } +# endif +#endif + + r = 1000000000; + s = time ((time_t *) 0); + ns = 0; + + got_time: + *resolution = r; + return file_timestamp_cons (0, s, ns); +} + +/* Place into the buffer P a printable representation of the file + timestamp TS. */ +void +file_timestamp_sprintf (p, ts) + char *p; + FILE_TIMESTAMP ts; +{ + time_t t = FILE_TIMESTAMP_S (ts); + struct tm *tm = localtime (&t); + + if (tm) + sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (t < 0) + sprintf (p, "%ld", (long) t); + else + sprintf (p, "%lu", (unsigned long) t); + p += strlen (p); + + /* Append nanoseconds as a fraction, but remove trailing zeros. + We don't know the actual timestamp resolution, since clock_getres + applies only to local times, whereas this timestamp might come + from a remote filesystem. So removing trailing zeros is the + best guess that we can do. */ + sprintf (p, ".%09d", FILE_TIMESTAMP_NS (ts)); + p += strlen (p) - 1; + while (*p == '0') + p--; + p += *p != '.'; + + *p = '\0'; +} + +/* Print the data base of files. */ + +static void +print_file (f) + struct file *f; +{ + struct dep *d; + struct dep *ood = 0; + + putchar ('\n'); + if (!f->is_target) + puts (_("# Not a target:")); + printf ("%s:%s", f->name, f->double_colon ? ":" : ""); + + /* Print all normal dependencies; note any order-only deps. */ + for (d = f->deps; d != 0; d = d->next) + if (! d->ignore_mtime) + printf (" %s", dep_name (d)); + else if (! ood) + ood = d; + + /* Print order-only deps, if we have any. */ + if (ood) + { + printf (" | %s", dep_name (ood)); + for (d = ood->next; d != 0; d = d->next) + if (d->ignore_mtime) + printf (" %s", dep_name (d)); + } + + putchar ('\n'); + + if (f->precious) + puts (_("# Precious file (prerequisite of .PRECIOUS).")); + if (f->phony) + puts (_("# Phony target (prerequisite of .PHONY).")); + if (f->cmd_target) + puts (_("# Command-line target.")); + if (f->dontcare) + puts (_("# A default or MAKEFILES makefile.")); + puts (f->tried_implicit + ? _("# Implicit rule search has been done.") + : _("# Implicit rule search has not been done.")); + if (f->stem != 0) + printf (_("# Implicit/static pattern stem: `%s'\n"), f->stem); + if (f->intermediate) + puts (_("# File is an intermediate prerequisite.")); + if (f->also_make != 0) + { + fputs (_("# Also makes:"), stdout); + for (d = f->also_make; d != 0; d = d->next) + printf (" %s", dep_name (d)); + putchar ('\n'); + } + if (f->last_mtime == UNKNOWN_MTIME) + puts (_("# Modification time never checked.")); + else if (f->last_mtime == NONEXISTENT_MTIME) + puts (_("# File does not exist.")); + else if (f->last_mtime == OLD_MTIME) + puts (_("# File is very old.")); + else + { + char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; + file_timestamp_sprintf (buf, f->last_mtime); + printf (_("# Last modified %s\n"), buf); + } + puts (f->updated + ? _("# File has been updated.") : _("# File has not been updated.")); + switch (f->command_state) + { + case cs_running: + puts (_("# Commands currently running (THIS IS A BUG).")); + break; + case cs_deps_running: + puts (_("# Dependencies commands running (THIS IS A BUG).")); + break; + case cs_not_started: + case cs_finished: + switch (f->update_status) + { + case -1: + break; + case 0: + puts (_("# Successfully updated.")); + break; + case 1: + assert (question_flag); + puts (_("# Needs to be updated (-q is set).")); + break; + case 2: + puts (_("# Failed to be updated.")); + break; + default: + puts (_("# Invalid value in `update_status' member!")); + fflush (stdout); + fflush (stderr); + abort (); + } + break; + default: + puts (_("# Invalid value in `command_state' member!")); + fflush (stdout); + fflush (stderr); + abort (); + } + + if (f->variables != 0) + print_file_variables (f); + + if (f->cmds != 0) + print_commands (f->cmds); +} + +void +print_file_data_base () +{ + puts (_("\n# Files")); + + hash_map (&files, print_file); + + fputs (_("\n# files hash-table stats:\n# "), stdout); + hash_print_stats (&files, stdout); +} + +#define EXPANSION_INCREMENT(_l) ((((_l) / 500) + 1) * 500) + +char * +build_target_list (value) + char *value; +{ + static unsigned long last_targ_count = 0; + + if (files.ht_fill != last_targ_count) + { + unsigned long max = EXPANSION_INCREMENT (strlen (value)); + unsigned long len; + char *p; + struct file **fp = (struct file **) files.ht_vec; + struct file **end = &fp[files.ht_size]; + + /* Make sure we have at least MAX bytes in the allocated buffer. */ + value = xrealloc (value, max); + + p = value; + len = 0; + for (; fp < end; ++fp) + if (!HASH_VACANT (*fp) && (*fp)->is_target) + { + struct file *f = *fp; + int l = strlen (f->name); + + len += l + 1; + if (len > max) + { + unsigned long off = p - value; + + max += EXPANSION_INCREMENT (l + 1); + value = xrealloc (value, max); + p = &value[off]; + } + + bcopy (f->name, p, l); + p += l; + *(p++) = ' '; + } + *(p-1) = '\0'; + + last_targ_count = files.ht_fill; + } + + return value; +} + +void +init_hash_files () +{ + hash_init (&files, 1000, file_hash_1, file_hash_2, file_hash_cmp); +} + +/* EOF */ diff --git a/src/make-3.80/filedef.h b/src/make-3.80/filedef.h new file mode 100755 index 00000000..b7d6e676 --- /dev/null +++ b/src/make-3.80/filedef.h @@ -0,0 +1,199 @@ +/* Definition of target file data structures for GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1997, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + + +/* Structure that represents the info on one file + that the makefile says how to make. + All of these are chained together through `next'. */ + +#include "hash.h" + +struct file + { + char *name; + char *hname; /* Hashed filename */ + char *vpath; /* VPATH/vpath pathname */ + struct dep *deps; /* all dependencies, including duplicates */ + struct commands *cmds; /* Commands to execute for this target. */ + int command_flags; /* Flags OR'd in for cmds; see commands.h. */ + char *stem; /* Implicit stem, if an implicit + rule has been used */ + struct dep *also_make; /* Targets that are made by making this. */ + FILE_TIMESTAMP last_mtime; /* File's modtime, if already known. */ + FILE_TIMESTAMP mtime_before_update; /* File's modtime before any updating + has been performed. */ + struct file *prev; /* Previous entry for same file name; + used when there are multiple double-colon + entries for the same file. */ + + /* File that this file was renamed to. After any time that a + file could be renamed, call `check_renamed' (below). */ + struct file *renamed; + + /* List of variable sets used for this file. */ + struct variable_set_list *variables; + + /* Pattern-specific variable reference for this target, or null if there + isn't one. Also see the pat_searched flag, below. */ + struct variable_set_list *pat_variables; + + /* Immediate dependent that caused this target to be remade, + or nil if there isn't one. */ + struct file *parent; + + /* For a double-colon entry, this is the first double-colon entry for + the same file. Otherwise this is null. */ + struct file *double_colon; + + short int update_status; /* Status of the last attempt to update, + or -1 if none has been made. */ + + enum /* State of the commands. */ + { /* Note: It is important that cs_not_started be zero. */ + cs_not_started, /* Not yet started. */ + cs_deps_running, /* Dep commands running. */ + cs_running, /* Commands running. */ + cs_finished /* Commands finished. */ + } command_state ENUM_BITFIELD (2); + + unsigned int precious:1; /* Non-0 means don't delete file on quit */ + unsigned int low_resolution_time:1; /* Nonzero if this file's time stamp + has only one-second resolution. */ + unsigned int tried_implicit:1; /* Nonzero if have searched + for implicit rule for making + this file; don't search again. */ + unsigned int updating:1; /* Nonzero while updating deps of this file */ + unsigned int updated:1; /* Nonzero if this file has been remade. */ + unsigned int is_target:1; /* Nonzero if file is described as target. */ + unsigned int cmd_target:1; /* Nonzero if file was given on cmd line. */ + unsigned int phony:1; /* Nonzero if this is a phony file + i.e., a dependency of .PHONY. */ + unsigned int intermediate:1;/* Nonzero if this is an intermediate file. */ + /* Nonzero, for an intermediate file, + means remove_intermediates should not delete it. */ + unsigned int secondary:1; + unsigned int dontcare:1; /* Nonzero if no complaint is to be made if + this target cannot be remade. */ + unsigned int ignore_vpath:1;/* Nonzero if we threw out VPATH name. */ + unsigned int pat_searched:1;/* Nonzero if we already searched for + pattern-specific variables. */ + unsigned int considered:1; /* equal to `considered' if file has been + considered on current scan of goal chain */ + }; + + +extern struct file *default_goal_file, *suffix_file, *default_file; + + +extern struct file *lookup_file PARAMS ((char *name)); +extern struct file *enter_file PARAMS ((char *name)); +extern void remove_intermediates PARAMS ((int sig)); +extern void snap_deps PARAMS ((void)); +extern void rename_file PARAMS ((struct file *file, char *name)); +extern void rehash_file PARAMS ((struct file *file, char *name)); +extern void set_command_state PARAMS ((struct file *file, int state)); +extern void notice_finished_file PARAMS ((struct file *file)); +extern void init_hash_files PARAMS ((void)); +extern char *build_target_list PARAMS ((char *old_list)); + +#if FILE_TIMESTAMP_HI_RES +# define FILE_TIMESTAMP_STAT_MODTIME(fname, st) \ + file_timestamp_cons (fname, (st).st_mtime, (st).st_mtim.ST_MTIM_NSEC) +#else +# define FILE_TIMESTAMP_STAT_MODTIME(fname, st) \ + file_timestamp_cons (fname, (st).st_mtime, 0) +#endif + +/* If FILE_TIMESTAMP is 64 bits (or more), use nanosecond resolution. + (Multiply by 2**30 instead of by 10**9 to save time at the cost of + slightly decreasing the number of available timestamps.) With + 64-bit FILE_TIMESTAMP, this stops working on 2514-05-30 01:53:04 + UTC, but by then uintmax_t should be larger than 64 bits. */ +#define FILE_TIMESTAMPS_PER_S (FILE_TIMESTAMP_HI_RES ? 1000000000 : 1) +#define FILE_TIMESTAMP_LO_BITS (FILE_TIMESTAMP_HI_RES ? 30 : 0) + +#define FILE_TIMESTAMP_S(ts) (((ts) - ORDINARY_MTIME_MIN) \ + >> FILE_TIMESTAMP_LO_BITS) +#define FILE_TIMESTAMP_NS(ts) ((int) (((ts) - ORDINARY_MTIME_MIN) \ + & ((1 << FILE_TIMESTAMP_LO_BITS) - 1))) + +/* Upper bound on length of string "YYYY-MM-DD HH:MM:SS.NNNNNNNNN" + representing a file timestamp. The upper bound is not necessarily 19, + since the year might be less than -999 or greater than 9999. + + Subtract one for the sign bit if in case file timestamps can be negative; + subtract FLOOR_LOG2_SECONDS_PER_YEAR to yield an upper bound on how many + file timestamp bits might affect the year; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if file timestamps can be negative; + add 4 to allow for any 4-digit epoch year (e.g. 1970); + add 25 to allow for "-MM-DD HH:MM:SS.NNNNNNNNN". */ +#define FLOOR_LOG2_SECONDS_PER_YEAR 24 +#define FILE_TIMESTAMP_PRINT_LEN_BOUND \ + (((sizeof (FILE_TIMESTAMP) * CHAR_BIT - 1 - FLOOR_LOG2_SECONDS_PER_YEAR) \ + * 302 / 1000) \ + + 1 + 1 + 4 + 25) + +extern FILE_TIMESTAMP file_timestamp_cons PARAMS ((char const *, + time_t, int)); +extern FILE_TIMESTAMP file_timestamp_now PARAMS ((int *)); +extern void file_timestamp_sprintf PARAMS ((char *p, FILE_TIMESTAMP ts)); + +/* Return the mtime of file F (a struct file *), caching it. + The value is NONEXISTENT_MTIME if the file does not exist. */ +#define file_mtime(f) file_mtime_1 ((f), 1) +/* Return the mtime of file F (a struct file *), caching it. + Don't search using vpath for the file--if it doesn't actually exist, + we don't find it. + The value is NONEXISTENT_MTIME if the file does not exist. */ +#define file_mtime_no_search(f) file_mtime_1 ((f), 0) +extern FILE_TIMESTAMP f_mtime PARAMS ((struct file *file, int search)); +#define file_mtime_1(f, v) \ + ((f)->last_mtime == UNKNOWN_MTIME ? f_mtime ((f), v) : (f)->last_mtime) + +/* Special timestamp values. */ + +/* The file's timestamp is not yet known. */ +#define UNKNOWN_MTIME 0 + +/* The file does not exist. */ +#define NONEXISTENT_MTIME 1 + +/* The file does not exist, and we assume that it is older than any + actual file. */ +#define OLD_MTIME 2 + +/* The smallest and largest ordinary timestamps. */ +#define ORDINARY_MTIME_MIN (OLD_MTIME + 1) +#define ORDINARY_MTIME_MAX ((FILE_TIMESTAMP_S (NEW_MTIME) \ + << FILE_TIMESTAMP_LO_BITS) \ + + ORDINARY_MTIME_MIN + FILE_TIMESTAMPS_PER_S - 1) + +/* Modtime value to use for `infinitely new'. We used to get the current time + from the system and use that whenever we wanted `new'. But that causes + trouble when the machine running make and the machine holding a file have + different ideas about what time it is; and can also lose for `force' + targets, which need to be considered newer than anything that depends on + them, even if said dependents' modtimes are in the future. */ +#define NEW_MTIME INTEGER_TYPE_MAXIMUM (FILE_TIMESTAMP) + +#define check_renamed(file) \ + while ((file)->renamed != 0) (file) = (file)->renamed /* No ; here. */ diff --git a/src/make-3.80/function.c b/src/make-3.80/function.c new file mode 100755 index 00000000..cf646d6f --- /dev/null +++ b/src/make-3.80/function.c @@ -0,0 +1,2076 @@ +/* Builtin function expansion for GNU Make. +Copyright (C) 1988, 1989, 1991-1997, 1999, 2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "filedef.h" +#include "variable.h" +#include "dep.h" +#include "job.h" +#include "commands.h" +#include "debug.h" + +#ifdef _AMIGA +#include "amiga.h" +#endif + + +struct function_table_entry + { + const char *name; + unsigned char len; + unsigned char minimum_args; + unsigned char maximum_args; + char expand_args; + char *(*func_ptr) PARAMS ((char *output, char **argv, const char *fname)); + }; + +static unsigned long +function_table_entry_hash_1 (keyv) + const void *keyv; +{ + struct function_table_entry const *key = (struct function_table_entry const *) keyv; + return_STRING_N_HASH_1 (key->name, key->len); +} + +static unsigned long +function_table_entry_hash_2 (keyv) + const void *keyv; +{ + struct function_table_entry const *key = (struct function_table_entry const *) keyv; + return_STRING_N_HASH_2 (key->name, key->len); +} + +static int +function_table_entry_hash_cmp (xv, yv) + const void *xv; + const void *yv; +{ + struct function_table_entry const *x = (struct function_table_entry const *) xv; + struct function_table_entry const *y = (struct function_table_entry const *) yv; + int result = x->len - y->len; + if (result) + return result; + return_STRING_N_COMPARE (x->name, y->name, x->len); +} + +static struct hash_table function_table; + + +/* Store into VARIABLE_BUFFER at O the result of scanning TEXT and replacing + each occurrence of SUBST with REPLACE. TEXT is null-terminated. SLEN is + the length of SUBST and RLEN is the length of REPLACE. If BY_WORD is + nonzero, substitutions are done only on matches which are complete + whitespace-delimited words. If SUFFIX_ONLY is nonzero, substitutions are + done only at the ends of whitespace-delimited words. */ + +char * +subst_expand (o, text, subst, replace, slen, rlen, by_word, suffix_only) + char *o; + char *text; + char *subst, *replace; + unsigned int slen, rlen; + int by_word, suffix_only; +{ + register char *t = text; + register char *p; + + if (slen == 0 && !by_word && !suffix_only) + { + /* The first occurrence of "" in any string is its end. */ + o = variable_buffer_output (o, t, strlen (t)); + if (rlen > 0) + o = variable_buffer_output (o, replace, rlen); + return o; + } + + do + { + if ((by_word | suffix_only) && slen == 0) + /* When matching by words, the empty string should match + the end of each word, rather than the end of the whole text. */ + p = end_of_token (next_token (t)); + else + { + p = sindex (t, 0, subst, slen); + if (p == 0) + { + /* No more matches. Output everything left on the end. */ + o = variable_buffer_output (o, t, strlen (t)); + return o; + } + } + + /* Output everything before this occurrence of the string to replace. */ + if (p > t) + o = variable_buffer_output (o, t, p - t); + + /* If we're substituting only by fully matched words, + or only at the ends of words, check that this case qualifies. */ + if ((by_word + && ((p > t && !isblank ((unsigned char)p[-1])) + || (p[slen] != '\0' && !isblank ((unsigned char)p[slen])))) + || (suffix_only + && (p[slen] != '\0' && !isblank ((unsigned char)p[slen])))) + /* Struck out. Output the rest of the string that is + no longer to be replaced. */ + o = variable_buffer_output (o, subst, slen); + else if (rlen > 0) + /* Output the replacement string. */ + o = variable_buffer_output (o, replace, rlen); + + /* Advance T past the string to be replaced. */ + t = p + slen; + } while (*t != '\0'); + + return o; +} + + +/* Store into VARIABLE_BUFFER at O the result of scanning TEXT + and replacing strings matching PATTERN with REPLACE. + If PATTERN_PERCENT is not nil, PATTERN has already been + run through find_percent, and PATTERN_PERCENT is the result. + If REPLACE_PERCENT is not nil, REPLACE has already been + run through find_percent, and REPLACE_PERCENT is the result. */ + +char * +patsubst_expand (o, text, pattern, replace, pattern_percent, replace_percent) + char *o; + char *text; + register char *pattern, *replace; + register char *pattern_percent, *replace_percent; +{ + unsigned int pattern_prepercent_len, pattern_postpercent_len; + unsigned int replace_prepercent_len, replace_postpercent_len = 0; + char *t; + unsigned int len; + int doneany = 0; + + /* We call find_percent on REPLACE before checking PATTERN so that REPLACE + will be collapsed before we call subst_expand if PATTERN has no %. */ + if (replace_percent == 0) + replace_percent = find_percent (replace); + if (replace_percent != 0) + { + /* Record the length of REPLACE before and after the % so + we don't have to compute these lengths more than once. */ + replace_prepercent_len = replace_percent - replace; + replace_postpercent_len = strlen (replace_percent + 1); + } + else + /* We store the length of the replacement + so we only need to compute it once. */ + replace_prepercent_len = strlen (replace); + + if (pattern_percent == 0) + pattern_percent = find_percent (pattern); + if (pattern_percent == 0) + /* With no % in the pattern, this is just a simple substitution. */ + return subst_expand (o, text, pattern, replace, + strlen (pattern), strlen (replace), 1, 0); + + /* Record the length of PATTERN before and after the % + so we don't have to compute it more than once. */ + pattern_prepercent_len = pattern_percent - pattern; + pattern_postpercent_len = strlen (pattern_percent + 1); + + while ((t = find_next_token (&text, &len)) != 0) + { + int fail = 0; + + /* Is it big enough to match? */ + if (len < pattern_prepercent_len + pattern_postpercent_len) + fail = 1; + + /* Does the prefix match? */ + if (!fail && pattern_prepercent_len > 0 + && (*t != *pattern + || t[pattern_prepercent_len - 1] != pattern_percent[-1] + || !strneq (t + 1, pattern + 1, pattern_prepercent_len - 1))) + fail = 1; + + /* Does the suffix match? */ + if (!fail && pattern_postpercent_len > 0 + && (t[len - 1] != pattern_percent[pattern_postpercent_len] + || t[len - pattern_postpercent_len] != pattern_percent[1] + || !strneq (&t[len - pattern_postpercent_len], + &pattern_percent[1], pattern_postpercent_len - 1))) + fail = 1; + + if (fail) + /* It didn't match. Output the string. */ + o = variable_buffer_output (o, t, len); + else + { + /* It matched. Output the replacement. */ + + /* Output the part of the replacement before the %. */ + o = variable_buffer_output (o, replace, replace_prepercent_len); + + if (replace_percent != 0) + { + /* Output the part of the matched string that + matched the % in the pattern. */ + o = variable_buffer_output (o, t + pattern_prepercent_len, + len - (pattern_prepercent_len + + pattern_postpercent_len)); + /* Output the part of the replacement after the %. */ + o = variable_buffer_output (o, replace_percent + 1, + replace_postpercent_len); + } + } + + /* Output a space, but not if the replacement is "". */ + if (fail || replace_prepercent_len > 0 + || (replace_percent != 0 && len + replace_postpercent_len > 0)) + { + o = variable_buffer_output (o, " ", 1); + doneany = 1; + } + } + if (doneany) + /* Kill the last space. */ + --o; + + return o; +} + + +/* Look up a function by name. */ + +static const struct function_table_entry * +lookup_function (s) + const char *s; +{ + const char *e = s; + + while (*e && ( (*e >= 'a' && *e <= 'z') || *e == '-')) + e++; + if (*e == '\0' || isblank ((unsigned char) *e)) + { + struct function_table_entry function_table_entry_key; + function_table_entry_key.name = s; + function_table_entry_key.len = e - s; + + return hash_find_item (&function_table, &function_table_entry_key); + } + return 0; +} + + +/* Return 1 if PATTERN matches STR, 0 if not. */ + +int +pattern_matches (pattern, percent, str) + register char *pattern, *percent, *str; +{ + unsigned int sfxlen, strlength; + + if (percent == 0) + { + unsigned int len = strlen (pattern) + 1; + char *new_chars = (char *) alloca (len); + bcopy (pattern, new_chars, len); + pattern = new_chars; + percent = find_percent (pattern); + if (percent == 0) + return streq (pattern, str); + } + + sfxlen = strlen (percent + 1); + strlength = strlen (str); + + if (strlength < (percent - pattern) + sfxlen + || !strneq (pattern, str, percent - pattern)) + return 0; + + return !strcmp (percent + 1, str + (strlength - sfxlen)); +} + + +/* Find the next comma or ENDPAREN (counting nested STARTPAREN and + ENDPARENtheses), starting at PTR before END. Return a pointer to + next character. + + If no next argument is found, return NULL. +*/ + +static char * +find_next_argument (startparen, endparen, ptr, end) + char startparen; + char endparen; + const char *ptr; + const char *end; +{ + int count = 0; + + for (; ptr < end; ++ptr) + if (*ptr == startparen) + ++count; + + else if (*ptr == endparen) + { + --count; + if (count < 0) + return NULL; + } + + else if (*ptr == ',' && !count) + return (char *)ptr; + + /* We didn't find anything. */ + return NULL; +} + + +/* Glob-expand LINE. The returned pointer is + only good until the next call to string_glob. */ + +static char * +string_glob (line) + char *line; +{ + static char *result = 0; + static unsigned int length; + register struct nameseq *chain; + register unsigned int idx; + + chain = multi_glob (parse_file_seq + (&line, '\0', sizeof (struct nameseq), + /* We do not want parse_file_seq to strip `./'s. + That would break examples like: + $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)). */ + 0), + sizeof (struct nameseq)); + + if (result == 0) + { + length = 100; + result = (char *) xmalloc (100); + } + + idx = 0; + while (chain != 0) + { + register char *name = chain->name; + unsigned int len = strlen (name); + + struct nameseq *next = chain->next; + free ((char *) chain); + chain = next; + + /* multi_glob will pass names without globbing metacharacters + through as is, but we want only files that actually exist. */ + if (file_exists_p (name)) + { + if (idx + len + 1 > length) + { + length += (len + 1) * 2; + result = (char *) xrealloc (result, length); + } + bcopy (name, &result[idx], len); + idx += len; + result[idx++] = ' '; + } + + free (name); + } + + /* Kill the last space and terminate the string. */ + if (idx == 0) + result[0] = '\0'; + else + result[idx - 1] = '\0'; + + return result; +} + +/* + Builtin functions + */ + +static char * +func_patsubst (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + o = patsubst_expand (o, argv[2], argv[0], argv[1], (char *) 0, (char *) 0); + return o; +} + + +static char * +func_join (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + int doneany = 0; + + /* Write each word of the first argument directly followed + by the corresponding word of the second argument. + If the two arguments have a different number of words, + the excess words are just output separated by blanks. */ + register char *tp; + register char *pp; + char *list1_iterator = argv[0]; + char *list2_iterator = argv[1]; + do + { + unsigned int len1, len2; + + tp = find_next_token (&list1_iterator, &len1); + if (tp != 0) + o = variable_buffer_output (o, tp, len1); + + pp = find_next_token (&list2_iterator, &len2); + if (pp != 0) + o = variable_buffer_output (o, pp, len2); + + if (tp != 0 || pp != 0) + { + o = variable_buffer_output (o, " ", 1); + doneany = 1; + } + } + while (tp != 0 || pp != 0); + if (doneany) + /* Kill the last blank. */ + --o; + + return o; +} + + +static char * +func_origin (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + /* Expand the argument. */ + register struct variable *v = lookup_variable (argv[0], strlen (argv[0])); + if (v == 0) + o = variable_buffer_output (o, "undefined", 9); + else + switch (v->origin) + { + default: + case o_invalid: + abort (); + break; + case o_default: + o = variable_buffer_output (o, "default", 7); + break; + case o_env: + o = variable_buffer_output (o, "environment", 11); + break; + case o_file: + o = variable_buffer_output (o, "file", 4); + break; + case o_env_override: + o = variable_buffer_output (o, "environment override", 20); + break; + case o_command: + o = variable_buffer_output (o, "command line", 12); + break; + case o_override: + o = variable_buffer_output (o, "override", 8); + break; + case o_automatic: + o = variable_buffer_output (o, "automatic", 9); + break; + } + + return o; +} + +#ifdef VMS +# define IS_PATHSEP(c) ((c) == ']') +#else +# ifdef HAVE_DOS_PATHS +# define IS_PATHSEP(c) ((c) == '/' || (c) == '\\') +# else +# define IS_PATHSEP(c) ((c) == '/') +# endif +#endif + + +static char * +func_notdir_suffix (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + /* Expand the argument. */ + char *list_iterator = argv[0]; + char *p2 =0; + int doneany =0; + unsigned int len=0; + + int is_suffix = streq (funcname, "suffix"); + int is_notdir = !is_suffix; + while ((p2 = find_next_token (&list_iterator, &len)) != 0) + { + char *p = p2 + len; + + + while (p >= p2 && (!is_suffix || *p != '.')) + { + if (IS_PATHSEP (*p)) + break; + --p; + } + + if (p >= p2) + { + if (is_notdir) + ++p; + else if (*p != '.') + continue; + o = variable_buffer_output (o, p, len - (p - p2)); + } +#ifdef HAVE_DOS_PATHS + /* Handle the case of "d:foo/bar". */ + else if (streq (funcname, "notdir") && p2[0] && p2[1] == ':') + { + p = p2 + 2; + o = variable_buffer_output (o, p, len - (p - p2)); + } +#endif + else if (is_notdir) + o = variable_buffer_output (o, p2, len); + + if (is_notdir || p >= p2) + { + o = variable_buffer_output (o, " ", 1); + doneany = 1; + } + } + if (doneany) + /* Kill last space. */ + --o; + + + return o; + +} + + +static char * +func_basename_dir (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + /* Expand the argument. */ + char *p3 = argv[0]; + char *p2=0; + int doneany=0; + unsigned int len=0; + char *p=0; + int is_basename= streq (funcname, "basename"); + int is_dir= !is_basename; + + while ((p2 = find_next_token (&p3, &len)) != 0) + { + p = p2 + len; + while (p >= p2 && (!is_basename || *p != '.')) + { + if (IS_PATHSEP (*p)) + break; + --p; + } + + if (p >= p2 && (is_dir)) + o = variable_buffer_output (o, p2, ++p - p2); + else if (p >= p2 && (*p == '.')) + o = variable_buffer_output (o, p2, p - p2); +#ifdef HAVE_DOS_PATHS + /* Handle the "d:foobar" case */ + else if (p2[0] && p2[1] == ':' && is_dir) + o = variable_buffer_output (o, p2, 2); +#endif + else if (is_dir) +#ifdef VMS + o = variable_buffer_output (o, "[]", 2); +#else +#ifndef _AMIGA + o = variable_buffer_output (o, "./", 2); +#else + ; /* Just a nop... */ +#endif /* AMIGA */ +#endif /* !VMS */ + else + /* The entire name is the basename. */ + o = variable_buffer_output (o, p2, len); + + o = variable_buffer_output (o, " ", 1); + doneany = 1; + } + if (doneany) + /* Kill last space. */ + --o; + + + return o; +} + +static char * +func_addsuffix_addprefix (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + int fixlen = strlen (argv[0]); + char *list_iterator = argv[1]; + int is_addprefix = streq (funcname, "addprefix"); + int is_addsuffix = !is_addprefix; + + int doneany = 0; + char *p; + unsigned int len; + + while ((p = find_next_token (&list_iterator, &len)) != 0) + { + if (is_addprefix) + o = variable_buffer_output (o, argv[0], fixlen); + o = variable_buffer_output (o, p, len); + if (is_addsuffix) + o = variable_buffer_output (o, argv[0], fixlen); + o = variable_buffer_output (o, " ", 1); + doneany = 1; + } + + if (doneany) + /* Kill last space. */ + --o; + + return o; +} + +static char * +func_subst (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + o = subst_expand (o, argv[2], argv[0], argv[1], strlen (argv[0]), + strlen (argv[1]), 0, 0); + + return o; +} + + +static char * +func_firstword (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + unsigned int i; + char *words = argv[0]; /* Use a temp variable for find_next_token */ + char *p = find_next_token (&words, &i); + + if (p != 0) + o = variable_buffer_output (o, p, i); + + return o; +} + + +static char * +func_words (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + int i = 0; + char *word_iterator = argv[0]; + char buf[20]; + + while (find_next_token (&word_iterator, (unsigned int *) 0) != 0) + ++i; + + sprintf (buf, "%d", i); + o = variable_buffer_output (o, buf, strlen (buf)); + + + return o; +} + +char * +strip_whitespace (begpp, endpp) + char **begpp; + char **endpp; +{ + while (isspace ((unsigned char)**begpp) && *begpp <= *endpp) + (*begpp) ++; + while (isspace ((unsigned char)**endpp) && *endpp >= *begpp) + (*endpp) --; + return *begpp; +} + +int +is_numeric (p) + char *p; +{ + char *end = p + strlen (p) - 1; + char *beg = p; + strip_whitespace (&p, &end); + + while (p <= end) + if (!ISDIGIT (*(p++))) /* ISDIGIT only evals its arg once: see make.h. */ + return 0; + + return (end - beg >= 0); +} + +void +check_numeric (s, message) + char *s; + char *message; +{ + if (!is_numeric (s)) + fatal (reading_file, message); +} + + + +static char * +func_word (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + char *end_p=0; + int i=0; + char *p=0; + + /* Check the first argument. */ + check_numeric (argv[0], _("non-numeric first argument to `word' function")); + i = atoi (argv[0]); + + if (i == 0) + fatal (reading_file, _("first argument to `word' function must be greater than 0")); + + + end_p = argv[1]; + while ((p = find_next_token (&end_p, 0)) != 0) + if (--i == 0) + break; + + if (i == 0) + o = variable_buffer_output (o, p, end_p - p); + + return o; +} + +static char * +func_wordlist (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + int start, count; + + /* Check the arguments. */ + check_numeric (argv[0], + _("non-numeric first argument to `wordlist' function")); + check_numeric (argv[1], + _("non-numeric second argument to `wordlist' function")); + + start = atoi (argv[0]); + count = atoi (argv[1]) - start + 1; + + if (count > 0) + { + char *p; + char *end_p = argv[2]; + + /* Find the beginning of the "start"th word. */ + while (((p = find_next_token (&end_p, 0)) != 0) && --start) + ; + + if (p) + { + /* Find the end of the "count"th word from start. */ + while (--count && (find_next_token (&end_p, 0) != 0)) + ; + + /* Return the stuff in the middle. */ + o = variable_buffer_output (o, p, end_p - p); + } + } + + return o; +} + +static char* +func_findstring (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + /* Find the first occurrence of the first string in the second. */ + int i = strlen (argv[0]); + if (sindex (argv[1], 0, argv[0], i) != 0) + o = variable_buffer_output (o, argv[0], i); + + return o; +} + +static char * +func_foreach (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + /* expand only the first two. */ + char *varname = expand_argument (argv[0], NULL); + char *list = expand_argument (argv[1], NULL); + char *body = argv[2]; + + int doneany = 0; + char *list_iterator = list; + char *p; + unsigned int len; + register struct variable *var; + + push_new_variable_scope (); + var = define_variable (varname, strlen (varname), "", o_automatic, 0); + + /* loop through LIST, put the value in VAR and expand BODY */ + while ((p = find_next_token (&list_iterator, &len)) != 0) + { + char *result = 0; + + { + char save = p[len]; + + p[len] = '\0'; + free (var->value); + var->value = (char *) xstrdup ((char*) p); + p[len] = save; + } + + result = allocated_variable_expand (body); + + o = variable_buffer_output (o, result, strlen (result)); + o = variable_buffer_output (o, " ", 1); + doneany = 1; + free (result); + } + + if (doneany) + /* Kill the last space. */ + --o; + + pop_variable_scope (); + free (varname); + free (list); + + return o; +} + +struct a_word +{ + struct a_word *next; + struct a_word *chain; + char *str; + int length; + int matched; +}; + +static unsigned long +a_word_hash_1 (key) + const void *key; +{ + return_STRING_HASH_1 (((struct a_word const *) key)->str); +} + +static unsigned long +a_word_hash_2 (key) + const void *key; +{ + return_STRING_HASH_2 (((struct a_word const *) key)->str); +} + +static int +a_word_hash_cmp (x, y) + const void *x; + const void *y; +{ + int result = ((struct a_word const *) x)->length - ((struct a_word const *) y)->length; + if (result) + return result; + return_STRING_COMPARE (((struct a_word const *) x)->str, + ((struct a_word const *) y)->str); +} + +struct a_pattern +{ + struct a_pattern *next; + char *str; + char *percent; + int length; + int save_c; +}; + +static char * +func_filter_filterout (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + struct a_word *wordhead; + struct a_word **wordtail; + struct a_word *wp; + struct a_pattern *pathead; + struct a_pattern **pattail; + struct a_pattern *pp; + + struct hash_table a_word_table; + int is_filter = streq (funcname, "filter"); + char *pat_iterator = argv[0]; + char *word_iterator = argv[1]; + int literals = 0; + int words = 0; + int hashing = 0; + char *p; + unsigned int len; + + /* Chop ARGV[0] up into patterns to match against the words. */ + + pattail = &pathead; + while ((p = find_next_token (&pat_iterator, &len)) != 0) + { + struct a_pattern *pat = (struct a_pattern *) alloca (sizeof (struct a_pattern)); + + *pattail = pat; + pattail = &pat->next; + + if (*pat_iterator != '\0') + ++pat_iterator; + + pat->str = p; + pat->length = len; + pat->save_c = p[len]; + p[len] = '\0'; + pat->percent = find_percent (p); + if (pat->percent == 0) + literals++; + } + *pattail = 0; + + /* Chop ARGV[1] up into words to match against the patterns. */ + + wordtail = &wordhead; + while ((p = find_next_token (&word_iterator, &len)) != 0) + { + struct a_word *word = (struct a_word *) alloca (sizeof (struct a_word)); + + *wordtail = word; + wordtail = &word->next; + + if (*word_iterator != '\0') + ++word_iterator; + + p[len] = '\0'; + word->str = p; + word->length = len; + word->matched = 0; + word->chain = 0; + words++; + } + *wordtail = 0; + + /* Only use a hash table if arg list lengths justifies the cost. */ + hashing = (literals >= 2 && (literals * words) >= 10); + if (hashing) + { + hash_init (&a_word_table, words, a_word_hash_1, a_word_hash_2, a_word_hash_cmp); + for (wp = wordhead; wp != 0; wp = wp->next) + { + struct a_word *owp = hash_insert (&a_word_table, wp); + if (owp) + wp->chain = owp; + } + } + + if (words) + { + int doneany = 0; + + /* Run each pattern through the words, killing words. */ + for (pp = pathead; pp != 0; pp = pp->next) + { + if (pp->percent) + for (wp = wordhead; wp != 0; wp = wp->next) + wp->matched |= pattern_matches (pp->str, pp->percent, wp->str); + else if (hashing) + { + struct a_word a_word_key; + a_word_key.str = pp->str; + a_word_key.length = pp->length; + wp = (struct a_word *) hash_find_item (&a_word_table, &a_word_key); + while (wp) + { + wp->matched |= 1; + wp = wp->chain; + } + } + else + for (wp = wordhead; wp != 0; wp = wp->next) + wp->matched |= (wp->length == pp->length + && strneq (pp->str, wp->str, wp->length)); + } + + /* Output the words that matched (or didn't, for filter-out). */ + for (wp = wordhead; wp != 0; wp = wp->next) + if (is_filter ? wp->matched : !wp->matched) + { + o = variable_buffer_output (o, wp->str, strlen (wp->str)); + o = variable_buffer_output (o, " ", 1); + doneany = 1; + } + + if (doneany) + /* Kill the last space. */ + --o; + } + + for (pp = pathead; pp != 0; pp = pp->next) + pp->str[pp->length] = pp->save_c; + + if (hashing) + hash_free (&a_word_table, 0); + + return o; +} + + +static char * +func_strip (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + char *p = argv[0]; + int doneany =0; + + while (*p != '\0') + { + int i=0; + char *word_start=0; + + while (isspace ((unsigned char)*p)) + ++p; + word_start = p; + for (i=0; *p != '\0' && !isspace ((unsigned char)*p); ++p, ++i) + {} + if (!i) + break; + o = variable_buffer_output (o, word_start, i); + o = variable_buffer_output (o, " ", 1); + doneany = 1; + } + + if (doneany) + /* Kill the last space. */ + --o; + return o; +} + +/* + Print a warning or fatal message. +*/ +static char * +func_error (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + char **argvp; + char *msg, *p; + int len; + + /* The arguments will be broken on commas. Rather than create yet + another special case where function arguments aren't broken up, + just create a format string that puts them back together. */ + for (len=0, argvp=argv; *argvp != 0; ++argvp) + len += strlen (*argvp) + 2; + + p = msg = (char *) alloca (len + 1); + + for (argvp=argv; argvp[1] != 0; ++argvp) + { + strcpy (p, *argvp); + p += strlen (*argvp); + *(p++) = ','; + *(p++) = ' '; + } + strcpy (p, *argvp); + + if (*funcname == 'e') + fatal (reading_file, "%s", msg); + + /* The warning function expands to the empty string. */ + error (reading_file, "%s", msg); + + return o; +} + + +/* + chop argv[0] into words, and sort them. + */ +static char * +func_sort (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + char **words = 0; + int nwords = 0; + register int wordi = 0; + + /* Chop ARGV[0] into words and put them in WORDS. */ + char *t = argv[0]; + char *p; + unsigned int len; + int i; + + while ((p = find_next_token (&t, &len)) != 0) + { + if (wordi >= nwords - 1) + { + nwords = (2 * nwords) + 5; + words = (char **) xrealloc ((char *) words, + nwords * sizeof (char *)); + } + words[wordi++] = savestring (p, len); + } + + if (!wordi) + return o; + + /* Now sort the list of words. */ + qsort ((char *) words, wordi, sizeof (char *), alpha_compare); + + /* Now write the sorted list. */ + for (i = 0; i < wordi; ++i) + { + len = strlen (words[i]); + if (i == wordi - 1 || strlen (words[i + 1]) != len + || strcmp (words[i], words[i + 1])) + { + o = variable_buffer_output (o, words[i], len); + o = variable_buffer_output (o, " ", 1); + } + free (words[i]); + } + /* Kill the last space. */ + --o; + + free (words); + + return o; +} + +/* + $(if condition,true-part[,false-part]) + + CONDITION is false iff it evaluates to an empty string. White + space before and after condition are stripped before evaluation. + + If CONDITION is true, then TRUE-PART is evaluated, otherwise FALSE-PART is + evaluated (if it exists). Because only one of the two PARTs is evaluated, + you can use $(if ...) to create side-effects (with $(shell ...), for + example). +*/ + +static char * +func_if (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + char *begp = argv[0]; + char *endp = begp + strlen (argv[0]); + int result = 0; + + /* Find the result of the condition: if we have a value, and it's not + empty, the condition is true. If we don't have a value, or it's the + empty string, then it's false. */ + + strip_whitespace (&begp, &endp); + + if (begp < endp) + { + char *expansion = expand_argument (begp, NULL); + + result = strlen (expansion); + free (expansion); + } + + /* If the result is true (1) we want to eval the first argument, and if + it's false (0) we want to eval the second. If the argument doesn't + exist we do nothing, otherwise expand it and add to the buffer. */ + + argv += 1 + !result; + + if (argv[0]) + { + char *expansion; + + expansion = expand_argument (argv[0], NULL); + + o = variable_buffer_output (o, expansion, strlen (expansion)); + + free (expansion); + } + + return o; +} + +static char * +func_wildcard (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + +#ifdef _AMIGA + o = wildcard_expansion (argv[0], o); +#else + char *p = string_glob (argv[0]); + o = variable_buffer_output (o, p, strlen (p)); +#endif + return o; +} + +/* + $(eval ) + + Always resolves to the empty string. + + Treat the arguments as a segment of makefile, and parse them. +*/ + +static char * +func_eval (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + eval_buffer (argv[0]); + + return o; +} + + +static char * +func_value (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + /* Look up the variable. */ + struct variable *v = lookup_variable (argv[0], strlen (argv[0])); + + /* Copy its value into the output buffer without expanding it. */ + if (v) + o = variable_buffer_output (o, v->value, strlen(v->value)); + + return o; +} + +/* + \r is replaced on UNIX as well. Is this desirable? + */ +void +fold_newlines (buffer, length) + char *buffer; + int *length; +{ + char *dst = buffer; + char *src = buffer; + char *last_nonnl = buffer -1; + src[*length] = 0; + for (; *src != '\0'; ++src) + { + if (src[0] == '\r' && src[1] == '\n') + continue; + if (*src == '\n') + { + *dst++ = ' '; + } + else + { + last_nonnl = dst; + *dst++ = *src; + } + } + *(++last_nonnl) = '\0'; + *length = last_nonnl - buffer; +} + + + +int shell_function_pid = 0, shell_function_completed; + + +#ifdef WINDOWS32 +/*untested*/ + +#include +#include +#include "sub_proc.h" + + +void +windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp) +{ + SECURITY_ATTRIBUTES saAttr; + HANDLE hIn; + HANDLE hErr; + HANDLE hChildOutRd; + HANDLE hChildOutWr; + HANDLE hProcess; + + + saAttr.nLength = sizeof (SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + + if (DuplicateHandle (GetCurrentProcess(), + GetStdHandle(STD_INPUT_HANDLE), + GetCurrentProcess(), + &hIn, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) { + fatal (NILF, _("create_child_process: DuplicateHandle(In) failed (e=%d)\n"), + GetLastError()); + + } + if (DuplicateHandle(GetCurrentProcess(), + GetStdHandle(STD_ERROR_HANDLE), + GetCurrentProcess(), + &hErr, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) { + fatal (NILF, _("create_child_process: DuplicateHandle(Err) failed (e=%d)\n"), + GetLastError()); + } + + if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0)) + fatal (NILF, _("CreatePipe() failed (e=%d)\n"), GetLastError()); + + hProcess = process_init_fd(hIn, hChildOutWr, hErr); + + if (!hProcess) + fatal (NILF, _("windows32_openpipe (): process_init_fd() failed\n")); + + /* make sure that CreateProcess() has Path it needs */ + sync_Path_environment(); + + if (!process_begin(hProcess, command_argv, envp, command_argv[0], NULL)) { + /* register process for wait */ + process_register(hProcess); + + /* set the pid for returning to caller */ + *pid_p = (int) hProcess; + + /* set up to read data from child */ + pipedes[0] = _open_osfhandle((long) hChildOutRd, O_RDONLY); + + /* this will be closed almost right away */ + pipedes[1] = _open_osfhandle((long) hChildOutWr, O_APPEND); + } else { + /* reap/cleanup the failed process */ + process_cleanup(hProcess); + + /* close handles which were duplicated, they weren't used */ + CloseHandle(hIn); + CloseHandle(hErr); + + /* close pipe handles, they won't be used */ + CloseHandle(hChildOutRd); + CloseHandle(hChildOutWr); + + /* set status for return */ + pipedes[0] = pipedes[1] = -1; + *pid_p = -1; + } +} +#endif + + +#ifdef __MSDOS__ +FILE * +msdos_openpipe (int* pipedes, int *pidp, char *text) +{ + FILE *fpipe=0; + /* MSDOS can't fork, but it has `popen'. */ + struct variable *sh = lookup_variable ("SHELL", 5); + int e; + extern int dos_command_running, dos_status; + + /* Make sure not to bother processing an empty line. */ + while (isblank ((unsigned char)*text)) + ++text; + if (*text == '\0') + return 0; + + if (sh) + { + char buf[PATH_MAX + 7]; + /* This makes sure $SHELL value is used by $(shell), even + though the target environment is not passed to it. */ + sprintf (buf, "SHELL=%s", sh->value); + putenv (buf); + } + + e = errno; + errno = 0; + dos_command_running = 1; + dos_status = 0; + /* If dos_status becomes non-zero, it means the child process + was interrupted by a signal, like SIGINT or SIGQUIT. See + fatal_error_signal in commands.c. */ + fpipe = popen (text, "rt"); + dos_command_running = 0; + if (!fpipe || dos_status) + { + pipedes[0] = -1; + *pidp = -1; + if (dos_status) + errno = EINTR; + else if (errno == 0) + errno = ENOMEM; + shell_function_completed = -1; + } + else + { + pipedes[0] = fileno (fpipe); + *pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */ + errno = e; + shell_function_completed = 1; + } + return fpipe; +} +#endif + +/* + Do shell spawning, with the naughty bits for different OSes. + */ + +#ifdef VMS + +/* VMS can't do $(shell ...) */ +#define func_shell 0 + +#else +#ifndef _AMIGA +static char * +func_shell (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + char* batch_filename = NULL; + int i; + +#ifdef __MSDOS__ + FILE *fpipe; +#endif + char **command_argv; + char *error_prefix; + char **envp; + int pipedes[2]; + int pid; + +#ifndef __MSDOS__ + /* Construct the argument list. */ + command_argv = construct_command_argv (argv[0], + (char **) NULL, (struct file *) 0, + &batch_filename); + if (command_argv == 0) + return o; +#endif + + /* Using a target environment for `shell' loses in cases like: + export var = $(shell echo foobie) + because target_environment hits a loop trying to expand $(var) + to put it in the environment. This is even more confusing when + var was not explicitly exported, but just appeared in the + calling environment. */ + + envp = environ; + + /* For error messages. */ + if (reading_file != 0) + { + error_prefix = (char *) alloca (strlen (reading_file->filenm)+11+4); + sprintf (error_prefix, + "%s:%lu: ", reading_file->filenm, reading_file->lineno); + } + else + error_prefix = ""; + +#ifdef WINDOWS32 + windows32_openpipe (pipedes, &pid, command_argv, envp); + + if (pipedes[0] < 0) { + /* open of the pipe failed, mark as failed execution */ + shell_function_completed = -1; + + return o; + } else +#else /* WINDOWS32 */ + +# ifdef __MSDOS__ + fpipe = msdos_openpipe (pipedes, &pid, argv[0]); + if (pipedes[0] < 0) + { + perror_with_name (error_prefix, "pipe"); + return o; + } +# else + if (pipe (pipedes) < 0) + { + perror_with_name (error_prefix, "pipe"); + return o; + } + + pid = vfork (); + if (pid < 0) + perror_with_name (error_prefix, "fork"); + else if (pid == 0) + child_execute_job (0, pipedes[1], command_argv, envp); + else +# endif /* ! __MSDOS__ */ + +#endif /* WINDOWS32 */ + { + /* We are the parent. */ + + char *buffer; + unsigned int maxlen; + int cc; + + /* Record the PID for reap_children. */ + shell_function_pid = pid; +#ifndef __MSDOS__ + shell_function_completed = 0; + + /* Free the storage only the child needed. */ + free (command_argv[0]); + free ((char *) command_argv); + + /* Close the write side of the pipe. */ + (void) close (pipedes[1]); +#endif + + /* Set up and read from the pipe. */ + + maxlen = 200; + buffer = (char *) xmalloc (maxlen + 1); + + /* Read from the pipe until it gets EOF. */ + for (i = 0; ; i += cc) + { + if (i == maxlen) + { + maxlen += 512; + buffer = (char *) xrealloc (buffer, maxlen + 1); + } + + cc = read (pipedes[0], &buffer[i], maxlen - i); + if (cc <= 0) + break; + } + buffer[i] = '\0'; + + /* Close the read side of the pipe. */ +#ifdef __MSDOS__ + if (fpipe) + (void) pclose (fpipe); +#else + (void) close (pipedes[0]); +#endif + + /* Loop until child_handler sets shell_function_completed + to the status of our child shell. */ + while (shell_function_completed == 0) + reap_children (1, 0); + + if (batch_filename) { + DB (DB_VERBOSE, (_("Cleaning up temporary batch file %s\n"), + batch_filename)); + remove (batch_filename); + free (batch_filename); + } + shell_function_pid = 0; + + /* The child_handler function will set shell_function_completed + to 1 when the child dies normally, or to -1 if it + dies with status 127, which is most likely an exec fail. */ + + if (shell_function_completed == -1) + { + /* This most likely means that the execvp failed, + so we should just write out the error message + that came in over the pipe from the child. */ + fputs (buffer, stderr); + fflush (stderr); + } + else + { + /* The child finished normally. Replace all + newlines in its output with spaces, and put + that in the variable output buffer. */ + fold_newlines (buffer, &i); + o = variable_buffer_output (o, buffer, i); + } + + free (buffer); + } + + return o; +} + +#else /* _AMIGA */ + +/* Do the Amiga version of func_shell. */ + +static char * +func_shell (char *o, char **argv, const char *funcname) +{ + /* Amiga can't fork nor spawn, but I can start a program with + redirection of my choice. However, this means that we + don't have an opportunity to reopen stdout to trap it. Thus, + we save our own stdout onto a new descriptor and dup a temp + file's descriptor onto our stdout temporarily. After we + spawn the shell program, we dup our own stdout back to the + stdout descriptor. The buffer reading is the same as above, + except that we're now reading from a file. */ + +#include +#include + + BPTR child_stdout; + char tmp_output[FILENAME_MAX]; + unsigned int maxlen = 200; + int cc, i; + char * buffer, * ptr; + char ** aptr; + int len = 0; + char* batch_filename = NULL; + + /* Construct the argument list. */ + command_argv = construct_command_argv (argv[0], (char **) NULL, + (struct file *) 0, &batch_filename); + if (command_argv == 0) + return o; + + /* Note the mktemp() is a security hole, but this only runs on Amiga. + Ideally we would use main.c:open_tmpfile(), but this uses a special + Open(), not fopen(), and I'm not familiar enough with the code to mess + with it. */ + strcpy (tmp_output, "t:MakeshXXXXXXXX"); + mktemp (tmp_output); + child_stdout = Open (tmp_output, MODE_NEWFILE); + + for (aptr=command_argv; *aptr; aptr++) + len += strlen (*aptr) + 1; + + buffer = xmalloc (len + 1); + ptr = buffer; + + for (aptr=command_argv; *aptr; aptr++) + { + strcpy (ptr, *aptr); + ptr += strlen (ptr) + 1; + *ptr ++ = ' '; + *ptr = 0; + } + + ptr[-1] = '\n'; + + Execute (buffer, NULL, child_stdout); + free (buffer); + + Close (child_stdout); + + child_stdout = Open (tmp_output, MODE_OLDFILE); + + buffer = xmalloc (maxlen); + i = 0; + do + { + if (i == maxlen) + { + maxlen += 512; + buffer = (char *) xrealloc (buffer, maxlen + 1); + } + + cc = Read (child_stdout, &buffer[i], maxlen - i); + if (cc > 0) + i += cc; + } while (cc > 0); + + Close (child_stdout); + + fold_newlines (buffer, &i); + o = variable_buffer_output (o, buffer, i); + free (buffer); + return o; +} +#endif /* _AMIGA */ +#endif /* !VMS */ + +#ifdef EXPERIMENTAL + +/* + equality. Return is string-boolean, ie, the empty string is false. + */ +static char * +func_eq (char* o, char **argv, char *funcname) +{ + int result = ! strcmp (argv[0], argv[1]); + o = variable_buffer_output (o, result ? "1" : "", result); + return o; +} + + +/* + string-boolean not operator. + */ +static char * +func_not (char* o, char **argv, char *funcname) +{ + char * s = argv[0]; + int result = 0; + while (isspace ((unsigned char)*s)) + s++; + result = ! (*s); + o = variable_buffer_output (o, result ? "1" : "", result); + return o; +} +#endif + + +/* Lookup table for builtin functions. + + This doesn't have to be sorted; we use a straight lookup. We might gain + some efficiency by moving most often used functions to the start of the + table. + + If MAXIMUM_ARGS is 0, that means there is no maximum and all + comma-separated values are treated as arguments. + + EXPAND_ARGS means that all arguments should be expanded before invocation. + Functions that do namespace tricks (foreach) don't automatically expand. */ + +static char *func_call PARAMS ((char *o, char **argv, const char *funcname)); + + +static struct function_table_entry function_table_init[] = +{ + /* Name/size */ /* MIN MAX EXP? Function */ + { STRING_SIZE_TUPLE("addprefix"), 2, 2, 1, func_addsuffix_addprefix}, + { STRING_SIZE_TUPLE("addsuffix"), 2, 2, 1, func_addsuffix_addprefix}, + { STRING_SIZE_TUPLE("basename"), 0, 1, 1, func_basename_dir}, + { STRING_SIZE_TUPLE("dir"), 0, 1, 1, func_basename_dir}, + { STRING_SIZE_TUPLE("notdir"), 0, 1, 1, func_notdir_suffix}, + { STRING_SIZE_TUPLE("subst"), 3, 3, 1, func_subst}, + { STRING_SIZE_TUPLE("suffix"), 0, 1, 1, func_notdir_suffix}, + { STRING_SIZE_TUPLE("filter"), 2, 2, 1, func_filter_filterout}, + { STRING_SIZE_TUPLE("filter-out"), 2, 2, 1, func_filter_filterout}, + { STRING_SIZE_TUPLE("findstring"), 2, 2, 1, func_findstring}, + { STRING_SIZE_TUPLE("firstword"), 0, 1, 1, func_firstword}, + { STRING_SIZE_TUPLE("join"), 2, 2, 1, func_join}, + { STRING_SIZE_TUPLE("patsubst"), 3, 3, 1, func_patsubst}, + { STRING_SIZE_TUPLE("shell"), 0, 1, 1, func_shell}, + { STRING_SIZE_TUPLE("sort"), 0, 1, 1, func_sort}, + { STRING_SIZE_TUPLE("strip"), 0, 1, 1, func_strip}, + { STRING_SIZE_TUPLE("wildcard"), 0, 1, 1, func_wildcard}, + { STRING_SIZE_TUPLE("word"), 2, 2, 1, func_word}, + { STRING_SIZE_TUPLE("wordlist"), 3, 3, 1, func_wordlist}, + { STRING_SIZE_TUPLE("words"), 0, 1, 1, func_words}, + { STRING_SIZE_TUPLE("origin"), 0, 1, 1, func_origin}, + { STRING_SIZE_TUPLE("foreach"), 3, 3, 0, func_foreach}, + { STRING_SIZE_TUPLE("call"), 1, 0, 1, func_call}, + { STRING_SIZE_TUPLE("error"), 0, 1, 1, func_error}, + { STRING_SIZE_TUPLE("warning"), 0, 1, 1, func_error}, + { STRING_SIZE_TUPLE("if"), 2, 3, 0, func_if}, + { STRING_SIZE_TUPLE("value"), 0, 1, 1, func_value}, + { STRING_SIZE_TUPLE("eval"), 0, 1, 1, func_eval}, +#ifdef EXPERIMENTAL + { STRING_SIZE_TUPLE("eq"), 2, 2, 1, func_eq}, + { STRING_SIZE_TUPLE("not"), 0, 1, 1, func_not}, +#endif +}; + +#define FUNCTION_TABLE_ENTRIES (sizeof (function_table_init) / sizeof (struct function_table_entry)) + + +/* These must come after the definition of function_table. */ + +static char * +expand_builtin_function (o, argc, argv, entry_p) + char *o; + int argc; + char **argv; + struct function_table_entry *entry_p; +{ + if (argc < (int)entry_p->minimum_args) + fatal (reading_file, + _("Insufficient number of arguments (%d) to function `%s'"), + argc, entry_p->name); + + /* I suppose technically some function could do something with no + arguments, but so far none do, so just test it for all functions here + rather than in each one. We can change it later if necessary. */ + + if (!argc) + return o; + + if (!entry_p->func_ptr) + fatal (reading_file, _("Unimplemented on this platform: function `%s'"), + entry_p->name); + + return entry_p->func_ptr (o, argv, entry_p->name); +} + +/* Check for a function invocation in *STRINGP. *STRINGP points at the + opening ( or { and is not null-terminated. If a function invocation + is found, expand it into the buffer at *OP, updating *OP, incrementing + *STRINGP past the reference and returning nonzero. If not, return zero. */ + +int +handle_function (op, stringp) + char **op; + char **stringp; +{ + const struct function_table_entry *entry_p; + char openparen = (*stringp)[0]; + char closeparen = openparen == '(' ? ')' : '}'; + char *beg; + char *end; + int count = 0; + register char *p; + char **argv, **argvp; + int nargs; + + beg = *stringp + 1; + + entry_p = lookup_function (beg); + + if (!entry_p) + return 0; + + /* We found a builtin function. Find the beginning of its arguments (skip + whitespace after the name). */ + + beg = next_token (beg + entry_p->len); + + /* Find the end of the function invocation, counting nested use of + whichever kind of parens we use. Since we're looking, count commas + to get a rough estimate of how many arguments we might have. The + count might be high, but it'll never be low. */ + + for (nargs=1, end=beg; *end != '\0'; ++end) + if (*end == ',') + ++nargs; + else if (*end == openparen) + ++count; + else if (*end == closeparen && --count < 0) + break; + + if (count >= 0) + fatal (reading_file, + _("unterminated call to function `%s': missing `%c'"), + entry_p->name, closeparen); + + *stringp = end; + + /* Get some memory to store the arg pointers. */ + argvp = argv = (char **) alloca (sizeof (char *) * (nargs + 2)); + + /* Chop the string into arguments, then a nul. As soon as we hit + MAXIMUM_ARGS (if it's >0) assume the rest of the string is part of the + last argument. + + If we're expanding, store pointers to the expansion of each one. If + not, make a duplicate of the string and point into that, nul-terminating + each argument. */ + + if (!entry_p->expand_args) + { + int len = end - beg; + + p = xmalloc (len+1); + memcpy (p, beg, len); + p[len] = '\0'; + beg = p; + end = beg + len; + } + + for (p=beg, nargs=0; p <= end; ++argvp) + { + char *next; + + ++nargs; + + if (nargs == entry_p->maximum_args + || (! (next = find_next_argument (openparen, closeparen, p, end)))) + next = end; + + if (entry_p->expand_args) + *argvp = expand_argument (p, next); + else + { + *argvp = p; + *next = '\0'; + } + + p = next + 1; + } + *argvp = NULL; + + /* Finally! Run the function... */ + *op = expand_builtin_function (*op, nargs, argv, entry_p); + + /* Free memory. */ + if (entry_p->expand_args) + for (argvp=argv; *argvp != 0; ++argvp) + free (*argvp); + else + free (beg); + + return 1; +} + + +/* User-defined functions. Expand the first argument as either a builtin + function or a make variable, in the context of the rest of the arguments + assigned to $1, $2, ... $N. $0 is the name of the function. */ + +static char * +func_call (o, argv, funcname) + char *o; + char **argv; + const char *funcname; +{ + char *fname; + char *cp; + char *body; + int flen; + int i; + const struct function_table_entry *entry_p; + struct variable *v; + + /* There is no way to define a variable with a space in the name, so strip + leading and trailing whitespace as a favor to the user. */ + fname = argv[0]; + while (*fname != '\0' && isspace ((unsigned char)*fname)) + ++fname; + + cp = fname + strlen (fname) - 1; + while (cp > fname && isspace ((unsigned char)*cp)) + --cp; + cp[1] = '\0'; + + /* Calling nothing is a no-op */ + if (*fname == '\0') + return o; + + /* Are we invoking a builtin function? */ + + entry_p = lookup_function (fname); + + if (entry_p) + { + /* How many arguments do we have? */ + for (i=0; argv[i+1]; ++i) + ; + + return expand_builtin_function (o, i, argv+1, entry_p); + } + + /* Not a builtin, so the first argument is the name of a variable to be + expanded and interpreted as a function. Find it. */ + flen = strlen (fname); + + v = lookup_variable (fname, flen); + + if (v == 0) + warn_undefined (fname, flen); + + if (v == 0 || *v->value == '\0') + return o; + + body = (char *) alloca (flen + 4); + body[0] = '$'; + body[1] = '('; + memcpy (body + 2, fname, flen); + body[flen+2] = ')'; + body[flen+3] = '\0'; + + /* Set up arguments $(1) .. $(N). $(0) is the function name. */ + + push_new_variable_scope (); + + for (i=0; *argv; ++i, ++argv) + { + char num[11]; + + sprintf (num, "%d", i); + define_variable (num, strlen (num), *argv, o_automatic, 0); + } + + /* Expand the body in the context of the arguments, adding the result to + the variable buffer. */ + + v->exp_count = EXP_COUNT_MAX; + + o = variable_expand_string (o, body, flen+3); + + v->exp_count = 0; + + pop_variable_scope (); + + return o + strlen (o); +} + +void +hash_init_function_table () +{ + hash_init (&function_table, FUNCTION_TABLE_ENTRIES * 2, + function_table_entry_hash_1, function_table_entry_hash_2, + function_table_entry_hash_cmp); + hash_load (&function_table, function_table_init, + FUNCTION_TABLE_ENTRIES, sizeof (struct function_table_entry)); +} diff --git a/src/make-3.80/getloadavg.c b/src/make-3.80/getloadavg.c new file mode 100755 index 00000000..7d575cd6 --- /dev/null +++ b/src/make-3.80/getloadavg.c @@ -0,0 +1,1034 @@ +/* Get the system load averages. + Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994, 1995, 1997 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* Compile-time symbols that this file uses: + + HAVE_PSTAT_GETDYNAMIC Define this if your system has the + pstat_getdynamic function. I think it + is unique to HPUX9. The best way to get the + definition is through the AC_FUNC_GETLOADAVG + macro that comes with autoconf 2.13 or newer. + If that isn't an option, then just put + AC_CHECK_FUNCS(pstat_getdynamic) in your + configure.in file. + FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. + KERNEL_FILE Pathname of the kernel to nlist. + LDAV_CVT() Scale the load average from the kernel. + Returns a double. + LDAV_SYMBOL Name of kernel symbol giving load average. + LOAD_AVE_TYPE Type of the load average array in the kernel. + Must be defined unless one of + apollo, DGUX, NeXT, or UMAX is defined; + or we have libkstat; + otherwise, no load average is available. + NLIST_STRUCT Include nlist.h, not a.out.h, and + the nlist n_name element is a pointer, + not an array. + HAVE_STRUCT_NLIST_N_UN_N_NAME struct nlist has an n_un member, not n_name. + LINUX_LDAV_FILE [__linux__]: File containing load averages. + + Specific system predefines this file uses, aside from setting + default values if not emacs: + + apollo + BSD Real BSD, not just BSD-like. + convex + DGUX + eunice UNIX emulator under VMS. + hpux + __MSDOS__ No-op for MSDOS. + NeXT + sgi + sequent Sequent Dynix 3.x.x (BSD) + _SEQUENT_ Sequent DYNIX/ptx 1.x.x (SYSV) + sony_news NEWS-OS (works at least for 4.1C) + UMAX + UMAX4_3 + VMS + WINDOWS32 No-op for Windows95/NT. + __linux__ Linux: assumes /proc filesystem mounted. + Support from Michael K. Johnson. + __NetBSD__ NetBSD: assumes /kern filesystem mounted. + + In addition, to avoid nesting many #ifdefs, we internally set + LDAV_DONE to indicate that the load average has been computed. + + We also #define LDAV_PRIVILEGED if a program will require + special installation to be able to call getloadavg. */ + +/* This should always be first. */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* Both the Emacs and non-Emacs sections want this. Some + configuration files' definitions for the LOAD_AVE_CVT macro (like + sparc.h's) use macros like FSCALE, defined here. */ +#if defined (unix) || defined (__unix) +# include +#endif + + +/* Exclude all the code except the test program at the end + if the system has its own `getloadavg' function. + + The declaration of `errno' is needed by the test program + as well as the function itself, so it comes first. */ + +#include + +#ifndef errno +extern int errno; +#endif + +#if HAVE_LOCALE_H +# include +#endif +#if !HAVE_SETLOCALE +# define setlocale(Category, Locale) /* empty */ +#endif + +#ifndef HAVE_GETLOADAVG + + +/* The existing Emacs configuration files define a macro called + LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and + returns the load average multiplied by 100. What we actually want + is a macro called LDAV_CVT, which returns the load average as an + unmultiplied double. + + For backwards compatibility, we'll define LDAV_CVT in terms of + LOAD_AVE_CVT, but future machine config files should just define + LDAV_CVT directly. */ + +# if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT) +# define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0) +# endif + +# if !defined (BSD) && defined (ultrix) +/* Ultrix behaves like BSD on Vaxen. */ +# define BSD +# endif + +# ifdef NeXT +/* NeXT in the 2.{0,1,2} releases defines BSD in , which + conflicts with the definition understood in this file, that this + really is BSD. */ +# undef BSD + +/* NeXT defines FSCALE in . However, we take FSCALE being + defined to mean that the nlist method should be used, which is not true. */ +# undef FSCALE +# endif + +/* Same issues as for NeXT apply to the HURD-based GNU system. */ +# ifdef __GNU__ +# undef BSD +# undef FSCALE +# endif /* __GNU__ */ + +/* Set values that are different from the defaults, which are + set a little farther down with #ifndef. */ + + +/* Some shorthands. */ + +# if defined (HPUX) && !defined (hpux) +# define hpux +# endif + +# if defined (__hpux) && !defined (hpux) +# define hpux +# endif + +# if defined (__sun) && !defined (sun) +# define sun +# endif + +# if defined(hp300) && !defined(hpux) +# define MORE_BSD +# endif + +# if defined(ultrix) && defined(mips) +# define decstation +# endif + +# if defined (__SVR4) && !defined (SVR4) +# define SVR4 +# endif + +# if (defined(sun) && defined(SVR4)) || defined (SOLARIS2) +# define SUNOS_5 +# endif + +# if defined (__osf__) && (defined (__alpha) || defined (__alpha__)) +# define OSF_ALPHA +# include +# include +# include +# include +# endif + +# if defined (__osf__) && (defined (mips) || defined (__mips__)) +# define OSF_MIPS +# include +# endif + +/* UTek's /bin/cc on the 4300 has no architecture specific cpp define by + default, but _MACH_IND_SYS_TYPES is defined in . Combine + that with a couple of other things and we'll have a unique match. */ +# if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES) +# define tek4300 /* Define by emacs, but not by other users. */ +# endif + +/* AC_FUNC_GETLOADAVG thinks QNX is SVR4, but it isn't. */ +# if defined(__QNX__) +# undef SVR4 +# endif + +/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */ +# ifndef LOAD_AVE_TYPE + +# ifdef MORE_BSD +# define LOAD_AVE_TYPE long +# endif + +# ifdef sun +# define LOAD_AVE_TYPE long +# endif + +# ifdef decstation +# define LOAD_AVE_TYPE long +# endif + +# ifdef _SEQUENT_ +# define LOAD_AVE_TYPE long +# endif + +# ifdef sgi +# define LOAD_AVE_TYPE long +# endif + +# ifdef SVR4 +# define LOAD_AVE_TYPE long +# endif + +# ifdef sony_news +# define LOAD_AVE_TYPE long +# endif + +# ifdef sequent +# define LOAD_AVE_TYPE long +# endif + +# ifdef OSF_ALPHA +# define LOAD_AVE_TYPE long +# endif + +# if defined (ardent) && defined (titan) +# define LOAD_AVE_TYPE long +# endif + +# ifdef tek4300 +# define LOAD_AVE_TYPE long +# endif + +# if defined(alliant) && defined(i860) /* Alliant FX/2800 */ +# define LOAD_AVE_TYPE long +# endif + +# ifdef _AIX +# define LOAD_AVE_TYPE long +# endif + +# ifdef convex +# define LOAD_AVE_TYPE double +# ifndef LDAV_CVT +# define LDAV_CVT(n) (n) +# endif +# endif + +# endif /* No LOAD_AVE_TYPE. */ + +# ifdef OSF_ALPHA +/* defines an incorrect value for FSCALE on Alpha OSF/1, + according to ghazi@noc.rutgers.edu. */ +# undef FSCALE +# define FSCALE 1024.0 +# endif + +# if defined(alliant) && defined(i860) /* Alliant FX/2800 */ +/* defines an incorrect value for FSCALE on an + Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */ +# undef FSCALE +# define FSCALE 100.0 +# endif + + +# ifndef FSCALE + +/* SunOS and some others define FSCALE in sys/param.h. */ + +# ifdef MORE_BSD +# define FSCALE 2048.0 +# endif + +# if defined(MIPS) || defined(SVR4) || defined(decstation) +# define FSCALE 256 +# endif + +# if defined (sgi) || defined (sequent) +/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined + above under #ifdef MIPS. But we want the sgi value. */ +# undef FSCALE +# define FSCALE 1000.0 +# endif + +# if defined (ardent) && defined (titan) +# define FSCALE 65536.0 +# endif + +# ifdef tek4300 +# define FSCALE 100.0 +# endif + +# ifdef _AIX +# define FSCALE 65536.0 +# endif + +# endif /* Not FSCALE. */ + +# if !defined (LDAV_CVT) && defined (FSCALE) +# define LDAV_CVT(n) (((double) (n)) / FSCALE) +# endif + + +# if defined(sgi) || (defined(mips) && !defined(BSD)) +# define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31)) +# endif + + +# if !defined (KERNEL_FILE) && defined (sequent) +# define KERNEL_FILE "/dynix" +# endif + +# if !defined (KERNEL_FILE) && defined (hpux) +# define KERNEL_FILE "/hp-ux" +# endif + +# if !defined(KERNEL_FILE) && (defined(_SEQUENT_) || defined(MIPS) || defined(SVR4) || defined(ISC) || defined (sgi) || (defined (ardent) && defined (titan))) +# define KERNEL_FILE "/unix" +# endif + + +# if !defined (LDAV_SYMBOL) && defined (alliant) +# define LDAV_SYMBOL "_Loadavg" +# endif + +# if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX)) +# define LDAV_SYMBOL "avenrun" +# endif + +# ifdef HAVE_UNISTD_H +# include +# endif + +# include + +/* LOAD_AVE_TYPE should only get defined if we're going to use the + nlist method. */ +# if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL)) +# define LOAD_AVE_TYPE double +# endif + +# ifdef LOAD_AVE_TYPE + +# ifndef VMS +# ifndef __linux__ +# ifdef HAVE_NLIST_H +# include +# else +# include +# endif + +# ifdef SUNOS_5 +# include +# include +# include +# endif + +# if defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) +# include +# endif + +# ifndef KERNEL_FILE +# define KERNEL_FILE "/vmunix" +# endif /* KERNEL_FILE */ + +# ifndef LDAV_SYMBOL +# define LDAV_SYMBOL "_avenrun" +# endif /* LDAV_SYMBOL */ +# endif /* __linux__ */ + +# else /* VMS */ + +# ifndef eunice +# include +# include +# else /* eunice */ +# include +# endif /* eunice */ +# endif /* VMS */ + +# ifndef LDAV_CVT +# define LDAV_CVT(n) ((double) (n)) +# endif /* !LDAV_CVT */ + +# endif /* LOAD_AVE_TYPE */ + +# if defined(__GNU__) && !defined (NeXT) +/* Note that NeXT Openstep defines __GNU__ even though it should not. */ +/* GNU system acts much like NeXT, for load average purposes, + but not exactly. */ +# define NeXT +# define host_self mach_host_self +# endif + +# ifdef NeXT +# ifdef HAVE_MACH_MACH_H +# include +# else +# include +# endif +# endif /* NeXT */ + +# ifdef sgi +# include +# endif /* sgi */ + +# ifdef UMAX +# include +# include +# include +# include +# include + +# ifdef UMAX_43 +# include +# include +# include +# include +# include +# else /* Not UMAX_43. */ +# include +# include +# include +# include +# include +# include +# endif /* Not UMAX_43. */ +# endif /* UMAX */ + +# ifdef DGUX +# include +# endif + +# if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION) +# include +# else +# include +# endif + + +/* Avoid static vars inside a function since in HPUX they dump as pure. */ + +# ifdef NeXT +static processor_set_t default_set; +static int getloadavg_initialized; +# endif /* NeXT */ + +# ifdef UMAX +static unsigned int cpus = 0; +static unsigned int samples; +# endif /* UMAX */ + +# ifdef DGUX +static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */ +# endif /* DGUX */ + +#if !defined(HAVE_LIBKSTAT) && defined(LOAD_AVE_TYPE) +/* File descriptor open to /dev/kmem or VMS load ave driver. */ +static int channel; +/* Nonzero iff channel is valid. */ +static int getloadavg_initialized; +/* Offset in kmem to seek to read load average, or 0 means invalid. */ +static long offset; + +#if !defined(VMS) && !defined(sgi) && !defined(__linux__) +static struct nlist nl[2]; +#endif /* Not VMS or sgi */ + +#ifdef SUNOS_5 +static kvm_t *kd; +#endif /* SUNOS_5 */ + +#endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */ + +/* Put the 1 minute, 5 minute and 15 minute load averages + into the first NELEM elements of LOADAVG. + Return the number written (never more than 3, but may be less than NELEM), + or -1 if an error occurred. */ + +int +getloadavg (loadavg, nelem) + double loadavg[]; + int nelem; +{ + int elem = 0; /* Return value. */ + +# ifdef NO_GET_LOAD_AVG +# define LDAV_DONE + /* Set errno to zero to indicate that there was no particular error; + this function just can't work at all on this system. */ + errno = 0; + elem = -1; +# endif + +# if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) +/* Use libkstat because we don't have to be root. */ +# define LDAV_DONE + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *kn; + + kc = kstat_open (); + if (kc == 0) + return -1; + ksp = kstat_lookup (kc, "unix", 0, "system_misc"); + if (ksp == 0 ) + return -1; + if (kstat_read (kc, ksp, 0) == -1) + return -1; + + + kn = kstat_data_lookup (ksp, "avenrun_1min"); + if (kn == 0) + { + /* Return -1 if no load average information is available. */ + nelem = 0; + elem = -1; + } + + if (nelem >= 1) + loadavg[elem++] = (double) kn->value.ul/FSCALE; + + if (nelem >= 2) + { + kn = kstat_data_lookup (ksp, "avenrun_5min"); + if (kn != 0) + { + loadavg[elem++] = (double) kn->value.ul/FSCALE; + + if (nelem >= 3) + { + kn = kstat_data_lookup (ksp, "avenrun_15min"); + if (kn != 0) + loadavg[elem++] = (double) kn->value.ul/FSCALE; + } + } + } + + kstat_close (kc); +# endif /* HAVE_LIBKSTAT */ + +# if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) +/* Use pstat_getdynamic() because we don't have to be root. */ +# define LDAV_DONE +# undef LOAD_AVE_TYPE + + struct pst_dynamic dyn_info; + if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0) + return -1; + if (nelem > 0) + loadavg[elem++] = dyn_info.psd_avg_1_min; + if (nelem > 1) + loadavg[elem++] = dyn_info.psd_avg_5_min; + if (nelem > 2) + loadavg[elem++] = dyn_info.psd_avg_15_min; + +# endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ + +# if !defined (LDAV_DONE) && defined (__linux__) +# define LDAV_DONE +# undef LOAD_AVE_TYPE + +# ifndef LINUX_LDAV_FILE +# define LINUX_LDAV_FILE "/proc/loadavg" +# endif + + char ldavgbuf[40]; + double load_ave[3]; + int fd, count; + + fd = open (LINUX_LDAV_FILE, O_RDONLY); + if (fd == -1) + return -1; + count = read (fd, ldavgbuf, 40); + (void) close (fd); + if (count <= 0) + return -1; + + /* The following sscanf must use the C locale. */ + setlocale (LC_NUMERIC, "C"); + count = sscanf (ldavgbuf, "%lf %lf %lf", + &load_ave[0], &load_ave[1], &load_ave[2]); + setlocale (LC_NUMERIC, ""); + if (count < 1) + return -1; + + for (elem = 0; elem < nelem && elem < count; elem++) + loadavg[elem] = load_ave[elem]; + + return elem; + +# endif /* __linux__ */ + +# if !defined (LDAV_DONE) && defined (__NetBSD__) +# define LDAV_DONE +# undef LOAD_AVE_TYPE + +# ifndef NETBSD_LDAV_FILE +# define NETBSD_LDAV_FILE "/kern/loadavg" +# endif + + unsigned long int load_ave[3], scale; + int count; + FILE *fp; + + fp = fopen (NETBSD_LDAV_FILE, "r"); + if (fp == NULL) + return -1; + count = fscanf (fp, "%lu %lu %lu %lu\n", + &load_ave[0], &load_ave[1], &load_ave[2], + &scale); + (void) fclose (fp); + if (count != 4) + return -1; + + for (elem = 0; elem < nelem; elem++) + loadavg[elem] = (double) load_ave[elem] / (double) scale; + + return elem; + +# endif /* __NetBSD__ */ + +# if !defined (LDAV_DONE) && defined (NeXT) +# define LDAV_DONE + /* The NeXT code was adapted from iscreen 3.2. */ + + host_t host; + struct processor_set_basic_info info; + unsigned info_count; + + /* We only know how to get the 1-minute average for this system, + so even if the caller asks for more than 1, we only return 1. */ + + if (!getloadavg_initialized) + { + if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) + getloadavg_initialized = 1; + } + + if (getloadavg_initialized) + { + info_count = PROCESSOR_SET_BASIC_INFO_COUNT; + if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, + (processor_set_info_t) &info, &info_count) + != KERN_SUCCESS) + getloadavg_initialized = 0; + else + { + if (nelem > 0) + loadavg[elem++] = (double) info.load_average / LOAD_SCALE; + } + } + + if (!getloadavg_initialized) + return -1; +# endif /* NeXT */ + +# if !defined (LDAV_DONE) && defined (UMAX) +# define LDAV_DONE +/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not + have a /dev/kmem. Information about the workings of the running kernel + can be gathered with inq_stats system calls. + We only know how to get the 1-minute average for this system. */ + + struct proc_summary proc_sum_data; + struct stat_descr proc_info; + double load; + register unsigned int i, j; + + if (cpus == 0) + { + register unsigned int c, i; + struct cpu_config conf; + struct stat_descr desc; + + desc.sd_next = 0; + desc.sd_subsys = SUBSYS_CPU; + desc.sd_type = CPUTYPE_CONFIG; + desc.sd_addr = (char *) &conf; + desc.sd_size = sizeof conf; + + if (inq_stats (1, &desc)) + return -1; + + c = 0; + for (i = 0; i < conf.config_maxclass; ++i) + { + struct class_stats stats; + bzero ((char *) &stats, sizeof stats); + + desc.sd_type = CPUTYPE_CLASS; + desc.sd_objid = i; + desc.sd_addr = (char *) &stats; + desc.sd_size = sizeof stats; + + if (inq_stats (1, &desc)) + return -1; + + c += stats.class_numcpus; + } + cpus = c; + samples = cpus < 2 ? 3 : (2 * cpus / 3); + } + + proc_info.sd_next = 0; + proc_info.sd_subsys = SUBSYS_PROC; + proc_info.sd_type = PROCTYPE_SUMMARY; + proc_info.sd_addr = (char *) &proc_sum_data; + proc_info.sd_size = sizeof (struct proc_summary); + proc_info.sd_sizeused = 0; + + if (inq_stats (1, &proc_info) != 0) + return -1; + + load = proc_sum_data.ps_nrunnable; + j = 0; + for (i = samples - 1; i > 0; --i) + { + load += proc_sum_data.ps_nrun[j]; + if (j++ == PS_NRUNSIZE) + j = 0; + } + + if (nelem > 0) + loadavg[elem++] = load / samples / cpus; +# endif /* UMAX */ + +# if !defined (LDAV_DONE) && defined (DGUX) +# define LDAV_DONE + /* This call can return -1 for an error, but with good args + it's not supposed to fail. The first argument is for no + apparent reason of type `long int *'. */ + dg_sys_info ((long int *) &load_info, + DG_SYS_INFO_LOAD_INFO_TYPE, + DG_SYS_INFO_LOAD_VERSION_0); + + if (nelem > 0) + loadavg[elem++] = load_info.one_minute; + if (nelem > 1) + loadavg[elem++] = load_info.five_minute; + if (nelem > 2) + loadavg[elem++] = load_info.fifteen_minute; +# endif /* DGUX */ + +# if !defined (LDAV_DONE) && defined (apollo) +# define LDAV_DONE +/* Apollo code from lisch@mentorg.com (Ray Lischner). + + This system call is not documented. The load average is obtained as + three long integers, for the load average over the past minute, + five minutes, and fifteen minutes. Each value is a scaled integer, + with 16 bits of integer part and 16 bits of fraction part. + + I'm not sure which operating system first supported this system call, + but I know that SR10.2 supports it. */ + + extern void proc1_$get_loadav (); + unsigned long load_ave[3]; + + proc1_$get_loadav (load_ave); + + if (nelem > 0) + loadavg[elem++] = load_ave[0] / 65536.0; + if (nelem > 1) + loadavg[elem++] = load_ave[1] / 65536.0; + if (nelem > 2) + loadavg[elem++] = load_ave[2] / 65536.0; +# endif /* apollo */ + +# if !defined (LDAV_DONE) && defined (OSF_MIPS) +# define LDAV_DONE + + struct tbl_loadavg load_ave; + table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); + loadavg[elem++] + = (load_ave.tl_lscale == 0 + ? load_ave.tl_avenrun.d[0] + : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale)); +# endif /* OSF_MIPS */ + +# if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32)) +# define LDAV_DONE + + /* A faithful emulation is going to have to be saved for a rainy day. */ + for ( ; elem < nelem; elem++) + { + loadavg[elem] = 0.0; + } +# endif /* __MSDOS__ || WINDOWS32 */ + +# if !defined (LDAV_DONE) && defined (OSF_ALPHA) +# define LDAV_DONE + + struct tbl_loadavg load_ave; + table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); + for (elem = 0; elem < nelem; elem++) + loadavg[elem] + = (load_ave.tl_lscale == 0 + ? load_ave.tl_avenrun.d[elem] + : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); +# endif /* OSF_ALPHA */ + +# if !defined (LDAV_DONE) && defined (VMS) + /* VMS specific code -- read from the Load Ave driver. */ + + LOAD_AVE_TYPE load_ave[3]; + static int getloadavg_initialized = 0; +# ifdef eunice + struct + { + int dsc$w_length; + char *dsc$a_pointer; + } descriptor; +# endif + + /* Ensure that there is a channel open to the load ave device. */ + if (!getloadavg_initialized) + { + /* Attempt to open the channel. */ +# ifdef eunice + descriptor.dsc$w_length = 18; + descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE"; +# else + $DESCRIPTOR (descriptor, "LAV0:"); +# endif + if (sys$assign (&descriptor, &channel, 0, 0) & 1) + getloadavg_initialized = 1; + } + + /* Read the load average vector. */ + if (getloadavg_initialized + && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0, + load_ave, 12, 0, 0, 0, 0) & 1)) + { + sys$dassgn (channel); + getloadavg_initialized = 0; + } + + if (!getloadavg_initialized) + return -1; +# endif /* VMS */ + +# if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS) + + /* UNIX-specific code -- read the average from /dev/kmem. */ + +# define LDAV_PRIVILEGED /* This code requires special installation. */ + + LOAD_AVE_TYPE load_ave[3]; + + /* Get the address of LDAV_SYMBOL. */ + if (offset == 0) + { +# ifndef sgi +# ifndef NLIST_STRUCT + strcpy (nl[0].n_name, LDAV_SYMBOL); + strcpy (nl[1].n_name, ""); +# else /* NLIST_STRUCT */ +# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME + nl[0].n_un.n_name = LDAV_SYMBOL; + nl[1].n_un.n_name = 0; +# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ + nl[0].n_name = LDAV_SYMBOL; + nl[1].n_name = 0; +# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ +# endif /* NLIST_STRUCT */ + +# ifndef SUNOS_5 + if ( +# if !(defined (_AIX) && !defined (ps2)) + nlist (KERNEL_FILE, nl) +# else /* _AIX */ + knlist (nl, 1, sizeof (nl[0])) +# endif + >= 0) + /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i. */ + { +# ifdef FIXUP_KERNEL_SYMBOL_ADDR + FIXUP_KERNEL_SYMBOL_ADDR (nl); +# endif + offset = nl[0].n_value; + } +# endif /* !SUNOS_5 */ +# else /* sgi */ + int ldav_off; + + ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); + if (ldav_off != -1) + offset = (long) ldav_off & 0x7fffffff; +# endif /* sgi */ + } + + /* Make sure we have /dev/kmem open. */ + if (!getloadavg_initialized) + { +# ifndef SUNOS_5 + channel = open ("/dev/kmem", 0); + if (channel >= 0) + { + /* Set the channel to close on exec, so it does not + litter any child's descriptor table. */ +# ifdef F_SETFD +# ifndef FD_CLOEXEC +# define FD_CLOEXEC 1 +# endif + (void) fcntl (channel, F_SETFD, FD_CLOEXEC); +# endif + getloadavg_initialized = 1; + } +# else /* SUNOS_5 */ + /* We pass 0 for the kernel, corefile, and swapfile names + to use the currently running kernel. */ + kd = kvm_open (0, 0, 0, O_RDONLY, 0); + if (kd != 0) + { + /* nlist the currently running kernel. */ + kvm_nlist (kd, nl); + offset = nl[0].n_value; + getloadavg_initialized = 1; + } +# endif /* SUNOS_5 */ + } + + /* If we can, get the load average values. */ + if (offset && getloadavg_initialized) + { + /* Try to read the load. */ +# ifndef SUNOS_5 + if (lseek (channel, offset, 0) == -1L + || read (channel, (char *) load_ave, sizeof (load_ave)) + != sizeof (load_ave)) + { + close (channel); + getloadavg_initialized = 0; + } +# else /* SUNOS_5 */ + if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) + != sizeof (load_ave)) + { + kvm_close (kd); + getloadavg_initialized = 0; + } +# endif /* SUNOS_5 */ + } + + if (offset == 0 || !getloadavg_initialized) + return -1; +# endif /* LOAD_AVE_TYPE and not VMS */ + +# if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */ + if (nelem > 0) + loadavg[elem++] = LDAV_CVT (load_ave[0]); + if (nelem > 1) + loadavg[elem++] = LDAV_CVT (load_ave[1]); + if (nelem > 2) + loadavg[elem++] = LDAV_CVT (load_ave[2]); + +# define LDAV_DONE +# endif /* !LDAV_DONE && LOAD_AVE_TYPE */ + +# ifdef LDAV_DONE + return elem; +# else + /* Set errno to zero to indicate that there was no particular error; + this function just can't work at all on this system. */ + errno = 0; + return -1; +# endif +} + +#endif /* ! HAVE_GETLOADAVG */ + +#ifdef TEST +#include "make.h" + +int +main (argc, argv) + int argc; + char **argv; +{ + int naptime = 0; + + if (argc > 1) + naptime = atoi (argv[1]); + + while (1) + { + double avg[3]; + int loads; + + errno = 0; /* Don't be misled if it doesn't set errno. */ + loads = getloadavg (avg, 3); + if (loads == -1) + { + perror ("Error getting load average"); + exit (1); + } + if (loads > 0) + printf ("1-minute: %f ", avg[0]); + if (loads > 1) + printf ("5-minute: %f ", avg[1]); + if (loads > 2) + printf ("15-minute: %f ", avg[2]); + if (loads > 0) + putchar ('\n'); + + if (naptime == 0) + break; + sleep (naptime); + } + + exit (0); +} +#endif /* TEST */ diff --git a/src/make-3.80/getopt.c b/src/make-3.80/getopt.c new file mode 100755 index 00000000..cd774190 --- /dev/null +++ b/src/make-3.80/getopt.c @@ -0,0 +1,1047 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 + Free Software Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +#include "gettext.h" +#define _(msgid) gettext (msgid) + + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +# if HAVE_STRING_H +# include +# else +# include +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (__mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/src/make-3.80/getopt.h b/src/make-3.80/getopt.h new file mode 100755 index 00000000..fb30719a --- /dev/null +++ b/src/make-3.80/getopt.h @@ -0,0 +1,133 @@ +/* Declarations for getopt. + Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if defined (__STDC__) && __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if defined (__STDC__) && __STDC__ +#ifdef __GNU_LIBRARY__ +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else /* not __GNU_LIBRARY__ */ +extern int getopt (); +#endif /* __GNU_LIBRARY__ */ +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* getopt.h */ diff --git a/src/make-3.80/getopt1.c b/src/make-3.80/getopt1.c new file mode 100755 index 00000000..ff257374 --- /dev/null +++ b/src/make-3.80/getopt1.c @@ -0,0 +1,190 @@ +/* getopt_long and getopt_long_only entry points for GNU getopt. + Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 + Free Software Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "getopt.h" + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +#ifndef const +#define const +#endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +#include +#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +#define ELIDE_CODE +#endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +#include +#endif + +#ifndef NULL +#define NULL 0 +#endif + +int +getopt_long (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 0); +} + +/* Like getopt_long, but '-' as well as '--' can indicate a long option. + If an option that starts with '-' (not '--') doesn't match a long option, + but does match a short option, it is parsed as a short option + instead. */ + +int +getopt_long_only (argc, argv, options, long_options, opt_index) + int argc; + char *const *argv; + const char *options; + const struct option *long_options; + int *opt_index; +{ + return _getopt_internal (argc, argv, options, long_options, opt_index, 1); +} + + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +#include + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + int option_index = 0; + static struct option long_options[] = + { + {"add", 1, 0, 0}, + {"append", 0, 0, 0}, + {"delete", 1, 0, 0}, + {"verbose", 0, 0, 0}, + {"create", 0, 0, 0}, + {"file", 1, 0, 0}, + {0, 0, 0, 0} + }; + + c = getopt_long (argc, argv, "abc:d:0123456789", + long_options, &option_index); + if (c == -1) + break; + + switch (c) + { + case 0: + printf ("option %s", long_options[option_index].name); + if (optarg) + printf (" with arg %s", optarg); + printf ("\n"); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case 'd': + printf ("option d with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/src/make-3.80/gettext.h b/src/make-3.80/gettext.h new file mode 100755 index 00000000..ea67f308 --- /dev/null +++ b/src/make-3.80/gettext.h @@ -0,0 +1,59 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc. + + This program is free software; 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, or (at your option) + any later version. + + This program 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 this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option. */ +#if ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +#else + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# define gettext(Msgid) ((const char *) (Msgid)) +# define dgettext(Domainname, Msgid) ((const char *) (Msgid)) +# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid)) +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2)) +# define textdomain(Domainname) ((const char *) (Domainname)) +# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname)) +# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset)) + +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +#endif /* _LIBGETTEXT_H */ diff --git a/src/make-3.80/glob/COPYING.LIB b/src/make-3.80/glob/COPYING.LIB new file mode 100755 index 00000000..bbe3fe19 --- /dev/null +++ b/src/make-3.80/glob/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; 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. + + This library 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 this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/src/make-3.80/glob/ChangeLog b/src/make-3.80/glob/ChangeLog new file mode 100755 index 00000000..1ebf879b --- /dev/null +++ b/src/make-3.80/glob/ChangeLog @@ -0,0 +1,136 @@ +2002-04-22 Paul D. Smith + + * Makefile.am: Use automake 1.6. + Use new automake condition USE_LOCAL_GLOB to decide whether or not + to build the local GNU glob library or use the system one. + +1999-09-12 Paul D. Smith + + * fnmatch.c: Last GLIBC version wouldn't compile outside of GLIBC + (undefined reference to internal_function). Update to the latest + version + +1999-09-11 Paul Eggert + + * glob.h (glob): If #defining to glob64, do this before + declaring it, so that all declarations and uses match, and + do not declare glob64, to avoid a declaration clash. + (globfree): Likewise with globfree64. + +1999-09-08 Eli Zaretskii + + * glob.c (prefix_array) [__MSDOS__,WINDOWS32]: Keep the trailing + slash unless DIRNAME is just "x:/". + +1999-09-06 Paul D. Smith + + * fnmatch.c: Update to latest version from GLIBC. + +1999-07-21 Paul D. Smith + + * glob.c, glob.h, fnmatch.c, fnmatch.h: Update to latest version + from GLIBC. + + * fnmatch.c (internal_fnmatch): Use K&R definition syntax, not ANSI. + (__strchrnul): This won't exist outside GLIBC, so create one. + + * glob.c: Move getlogin{,_r} prototypes below glob.h to get __P() + macro. + +1998-08-05 Paul D. Smith + + * configure.in: Remove; configuration for glob is handled by the + make configure.in. + +1998-07-29 Paul D. Smith + + * glob.c, fnmatch.c: New versions from the GLIBC folks (Ulrich + Drepper). Fixes a bug reported by Eli Zaretski. Integrates + DOS/Windows32 support. + +1998-07-27 Kaveh R. Ghazi + + * glob.c (glob): Cast away const on assignment of pattern to dirname. + Cast the return type of __alloca() for traditional C compilers. + +1998-07-23 Paul D. Smith + + * glob.c, fnmatch.c: New versions of these files from the GLIBC + folks (Ulrich Drepper). Had to re-integrate some DOS/Windows + code. + +1998-07-10 Paul D. Smith + + * glob.c (glob_in_dir): If no meta chars exist in PATTERN and + GLOB_NOCHECK is present, don't look for the file--whether it's + found or not, we'll always return it, so why bother searching? + + Also, if we are searching and there are no meta chars, don't + bother trying fnmatch() if the strcmp() fails. + +1998-05-30 Eli Zaretskii + + * glob.c (glob) [__MSDOS__, WINDOWS32]: Compute the directory and + filename parts of the pattern correctly when it includes a drive + spec. Disallow wildcards in the drive spec. Prevent recursion + when dirname is of the form "d:/" or "d:". + (prefix_array) [__MSDOS__, WINDOWS32]: Don't append a slash to + "d:/" and "d:". + +1998-05-13 Paul D. Smith + + * SMakefile, Makefile.ami, glob.c, glob.h, fnmatch.c: Updated from + the latest glibc version. + +1998-04-17 Paul D. Smith + + * configure.in: Create a config.h file instead of setting things + on the compile line. This is because when build.sh runs it merely + passes -DHAVE_CONFIG_H to the glob files, just as it does to the + make files. + * config.h.in: Created by autoheader. + +Tue Aug 12 10:52:34 1997 Paul D. Smith + + * configure.in: Require autoconf 2.12. + + * glob: Updates from latest GNU libc glob code. + + * glob.c,glob.h,fnmatch.h: Change all WIN32 references to WINDOWS32. + + * glob.h: OSF4 defines macros in such a way that GLOB_ALTDIRFUNC + is not defined. Added a test to the #if which defines it if + _GNU_SOURCE is defined; that's set by both glob.c and GNU make. + + * glob.c: SunOS4 w/ cc needs #include , since assert.h + requires stderr but doesn't include stdio.h :-/. + (next_brace_sub): De-protoize function definition. + (glob): Cast __alloca(); on SunOS4 it uses the default return type + of int. + (glob): Irix defines getlogin_r() to return a char*; move the + extern for that into the _LIBC area since it isn't used except in + LIBC anyway. Likewise, move extern getlogin() into the "else". + +Sat Jul 20 21:55:31 1996 Roland McGrath + + Win32 hacks from . + * posix/glob.c [WIN32]: Don't include ; don't use d_ino; + use void * for my_realloc; include for alloca. + (glob) [WIN32]: Use "c:/users/default" for ~ if no HOME variable. + * posix/fnmatch.h [WIN32]: Use prototypes even if [!__STDC__]. + * posix/glob.h: Likewise. + +Fri Jul 19 16:56:41 1996 Roland McGrath + + * posix/glob.h [!_AMIGA && !VMS]: Check this instead of just [!_AMIGA] + for `struct stat;' forward decl. + +Sat Jun 22 10:44:09 1996 Roland McGrath + + * posix/glob.c: Include only [HAVE_ALLOCA_H], not [sparc]. + +Fri Jun 21 00:27:51 1996 Roland McGrath + + * posix/fnmatch.c (fnmatch): Fix \*[*?]+ case to increment name ptr + only for ?s, not for *s. Fix from Chet Ramey. + diff --git a/src/make-3.80/glob/Makefile.am b/src/make-3.80/glob/Makefile.am new file mode 100755 index 00000000..7623ffe7 --- /dev/null +++ b/src/make-3.80/glob/Makefile.am @@ -0,0 +1,14 @@ +# -*-Makefile-*-, or close enough + +AUTOMAKE_OPTIONS = 1.7 foreign + +# Only build the library when the system doesn't already have GNU glob. +if USE_LOCAL_GLOB + noinst_LIBRARIES = libglob.a +endif + +libglob_a_SOURCES = glob.c glob.h fnmatch.c fnmatch.h + + +EXTRA_DIST = COPYING.LIB Makefile.ami SCOPTIONS SMakefile \ + configure.bat diff --git a/src/make-3.80/glob/Makefile.ami b/src/make-3.80/glob/Makefile.ami new file mode 100755 index 00000000..d3e3d40c --- /dev/null +++ b/src/make-3.80/glob/Makefile.ami @@ -0,0 +1,69 @@ +# Makefile for standalone distribution of libglob.a (fnmatch, glob). + +# Copyright (C) 1991, 92, 93, 94, 95, 97, 98 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# This library is free software; 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. + +# This library 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 this library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Ultrix 2.2 make doesn't expand the value of VPATH. +VPATH = /glob/ +# This must repeat the value, because configure will remove `VPATH = .'. +srcdir = /glob/ + +CC = sc +RM = delete +CPPFLAGS = +CFLAGS = + +# Information determined by configure. +DEFS = Define HAVE_HEADER_STDC Define HAVE_UNISTD_H Define HAVE_STRING_H \ + Define HAVE_DIRENT_H + +# How to invoke ar. +AR = join +ARFLAGS = as + +# How to invoke ranlib. +RANLIB = ; + +.PHONY: all +all: glob.lib + +glob.lib : glob.o fnmatch.o + $(AR) $(ARFLAGS) $@ glob.o fnmatch.o + $(RANLIB) $@ + +# For some reason, Unix make wants the dependencies on the source files. +# Otherwise it refuses to use an implicit rule! +# And, get this: it doesn't work to use $(srcdir)foo.c!! +glob.o: $(srcdir)glob.h $(srcdir)fnmatch.h glob.c +fnmatch.o: $(srcdir)fnmatch.h fnmatch.c + +OUTPUT_OPTION = +.c.o: + $(CC) IDir "" \ + $(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) + +.PHONY: clean realclean glob-clean glob-realclean distclean +clean glob-clean: + -$(RM) glob.lib "#?.o" core +distclean glob-realclean: clean + -$(RM) TAGS tags Makefile config.status config.h config.log +realcean: distclean + +# For inside the C library. +glob.tar glob.tar.Z: + $(MAKE) -C .. $@ diff --git a/src/make-3.80/glob/Makefile.in b/src/make-3.80/glob/Makefile.in new file mode 100755 index 00000000..8ab6ce2f --- /dev/null +++ b/src/make-3.80/glob/Makefile.in @@ -0,0 +1,399 @@ +# Makefile.in generated by automake 1.7 from Makefile.am. +# @configure_input@ + +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*-Makefile-*-, or close enough + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = .. + +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_triplet = @host@ +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GETLOADAVG_LIBS = @GETLOADAVG_LIBS@ +GLOBINC = @GLOBINC@ +GLOBLIB = @GLOBLIB@ +GMSGFMT = @GMSGFMT@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +KMEM_GROUP = @KMEM_GROUP@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBS = @LIBS@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MAKE_HOST = @MAKE_HOST@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGMERGE = @MSGMERGE@ +NEED_SETGID = @NEED_SETGID@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +USE_CUSTOMS_FALSE = @USE_CUSTOMS_FALSE@ +USE_CUSTOMS_TRUE = @USE_CUSTOMS_TRUE@ +USE_LOCAL_GLOB_FALSE = @USE_LOCAL_GLOB_FALSE@ +USE_LOCAL_GLOB_TRUE = @USE_LOCAL_GLOB_TRUE@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_RANLIB = @ac_ct_RANLIB@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__quote = @am__quote@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ + +AUTOMAKE_OPTIONS = 1.7 foreign + +# Only build the library when the system doesn't already have GNU glob. +@USE_LOCAL_GLOB_TRUE@noinst_LIBRARIES = libglob.a + +libglob_a_SOURCES = glob.c glob.h fnmatch.c fnmatch.h + +EXTRA_DIST = COPYING.LIB Makefile.ami SCOPTIONS SMakefile \ + configure.bat + +subdir = glob +mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + +libglob_a_AR = $(AR) cru +libglob_a_LIBADD = +am_libglob_a_OBJECTS = glob.$(OBJEXT) fnmatch.$(OBJEXT) +libglob_a_OBJECTS = $(am_libglob_a_OBJECTS) + +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/fnmatch.Po ./$(DEPDIR)/glob.Po +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DIST_SOURCES = $(libglob_a_SOURCES) +DIST_COMMON = COPYING.LIB ChangeLog Makefile.am Makefile.in +SOURCES = $(libglob_a_SOURCES) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign glob/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe) + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libglob.a: $(libglob_a_OBJECTS) $(libglob_a_DEPENDENCIES) + -rm -f libglob.a + $(libglob_a_AR) libglob.a $(libglob_a_OBJECTS) $(libglob_a_LIBADD) + $(RANLIB) libglob.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) core *.core + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fnmatch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glob.Po@am__quote@ + +distclean-depend: + -rm -rf ./$(DEPDIR) + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \ +@am__fastdepCC_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'`; \ +@am__fastdepCC_TRUE@ then mv "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \ +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \ +@am__fastdepCC_TRUE@ fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'` +uninstall-info-am: + +ETAGS = etags +ETAGSFLAGS = + +CTAGS = ctags +CTAGSFLAGS = + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$tags$$unique" \ + || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique + +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) + +top_distdir = .. +distdir = $(top_distdir)/$(PACKAGE)-$(VERSION) + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkinstalldirs) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) + +installdirs: + +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + +distclean-am: clean-am distclean-compile distclean-depend \ + distclean-generic distclean-tags + +dvi: dvi-am + +dvi-am: + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-info-am + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-noinstLIBRARIES ctags distclean distclean-compile \ + distclean-depend distclean-generic distclean-tags distdir dvi \ + dvi-am info info-am install install-am install-data \ + install-data-am install-exec install-exec-am install-info \ + install-info-am install-man install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-info-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/make-3.80/glob/SCOPTIONS b/src/make-3.80/glob/SCOPTIONS new file mode 100755 index 00000000..f89daae1 --- /dev/null +++ b/src/make-3.80/glob/SCOPTIONS @@ -0,0 +1,13 @@ +ERRORREXX +OPTIMIZE +NOVERSION +OPTIMIZERTIME +OPTIMIZERALIAS +DEFINE INCLUDEDIR="include:" +DEFINE LIBDIR="lib:" +DEFINE NO_ALLOCA +DEFINE NO_FLOAT +DEFINE NO_ARCHIVES +IGNORE=161 +IGNORE=100 +STARTUP=cres diff --git a/src/make-3.80/glob/SMakefile b/src/make-3.80/glob/SMakefile new file mode 100755 index 00000000..9dcb90b3 --- /dev/null +++ b/src/make-3.80/glob/SMakefile @@ -0,0 +1,69 @@ +# Makefile for standalone distribution of libglob.a (fnmatch, glob). + +# Copyright (C) 1991, 92, 93, 94, 95, 97, 98 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# This library is free software; 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. + +# This library 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 this library; see the file COPYING.LIB. If +# not, write to the Free Software Foundation, Inc., +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Ultrix 2.2 make doesn't expand the value of VPATH. +VPATH = /glob/ +# This must repeat the value, because configure will remove `VPATH = .'. +srcdir = /glob/ + +CC = sc +CPPFLAGS = +CFLAGS = +MAKE = smake +RM = delete + +# Information determined by configure. +DEFS = Define HAVE_HEADER_STDC Define HAVE_UNISTD_H Define HAVE_STRING_H \ + Define HAVE_DIRENT_H + +# How to invoke ar. +AR = join +ARFLAGS = as + +# How to invoke ranlib. +RANLIB = ; + +.PHONY: all +all: glob.lib + +glob.lib : glob.o fnmatch.o + $(AR) $(ARFLAGS) $@ glob.o fnmatch.o + $(RANLIB) $@ + +# For some reason, Unix make wants the dependencies on the source files. +# Otherwise it refuses to use an implicit rule! +# And, get this: it doesn't work to use $(srcdir)foo.c!! +glob.o: $(srcdir)glob.h $(srcdir)fnmatch.h glob.c +fnmatch.o: $(srcdir)fnmatch.h fnmatch.c + +.c.o: + $(CC) IDir "" \ + $(DEFS) $(CPPFLAGS) $(CFLAGS) $< $(OUTPUT_OPTION) + +.PHONY: clean realclean glob-clean glob-realclean distclean +clean glob-clean: + -$(RM) -f glob.lib *.o core +distclean glob-realclean: clean + -$(RM) -f TAGS tags Makefile config.status config.h config.log +realcean: distclean + +# For inside the C library. +glob.tar glob.tar.Z: + $(MAKE) -C .. $@ diff --git a/src/make-3.80/glob/configure.bat b/src/make-3.80/glob/configure.bat new file mode 100755 index 00000000..b6104e13 --- /dev/null +++ b/src/make-3.80/glob/configure.bat @@ -0,0 +1,26 @@ +@echo off +echo Configuring glob for DJGPP +rem This batch file assumes a unix-type "sed" program + +echo # Makefile generated by "configure.bat"> Makefile + +if exist config.sed del config.sed + +echo "s/@srcdir@/./ ">> config.sed +echo "s/@CC@/gcc/ ">> config.sed +echo "s/@CFLAGS@/-O2 -g/ ">> config.sed +echo "s/@CPPFLAGS@/-DHAVE_CONFIG_H -I../ ">> config.sed +echo "s/@AR@/ar/ ">> config.sed +echo "s/@RANLIB@/ranlib/ ">> config.sed +echo "s/@LDFLAGS@// ">> config.sed +echo "s/@DEFS@// ">> config.sed +echo "s/@ALLOCA@// ">> config.sed +echo "s/@LIBS@// ">> config.sed +echo "s/@LIBOBJS@// ">> config.sed +echo "s/^Makefile *:/_Makefile:/ ">> config.sed +echo "s/^config.h *:/_config.h:/ ">> config.sed + +sed -e "s/^\"//" -e "s/\"$//" -e "s/[ ]*$//" config.sed > config2.sed +sed -f config2.sed Makefile.in >> Makefile +del config.sed +del config2.sed diff --git a/src/make-3.80/glob/fnmatch.c b/src/make-3.80/glob/fnmatch.c new file mode 100755 index 00000000..1f4ead5f --- /dev/null +++ b/src/make-3.80/glob/fnmatch.c @@ -0,0 +1,488 @@ +/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + This library is free software; 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. + + This library 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 this library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#if HAVE_CONFIG_H +# include +#endif + +/* Enable GNU extensions in fnmatch.h. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#include +#include +#include + +#if HAVE_STRING_H || defined _LIBC +# include +#else +# include +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +/* For platform which support the ISO C amendement 1 functionality we + support user defined character classes. */ +#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) +/* Solaris 2.5 has a bug: must be included before . */ +# include +# include +#endif + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#if defined _LIBC || !defined __GNU_LIBRARY__ + + +# if defined STDC_HEADERS || !defined isascii +# define ISASCII(c) 1 +# else +# define ISASCII(c) isascii(c) +# endif + +# ifdef isblank +# define ISBLANK(c) (ISASCII (c) && isblank (c)) +# else +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') +# endif +# ifdef isgraph +# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) +# else +# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) +# endif + +# define ISPRINT(c) (ISASCII (c) && isprint (c)) +# define ISDIGIT(c) (ISASCII (c) && isdigit (c)) +# define ISALNUM(c) (ISASCII (c) && isalnum (c)) +# define ISALPHA(c) (ISASCII (c) && isalpha (c)) +# define ISCNTRL(c) (ISASCII (c) && iscntrl (c)) +# define ISLOWER(c) (ISASCII (c) && islower (c)) +# define ISPUNCT(c) (ISASCII (c) && ispunct (c)) +# define ISSPACE(c) (ISASCII (c) && isspace (c)) +# define ISUPPER(c) (ISASCII (c) && isupper (c)) +# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c)) + +# define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) + +# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) +/* The GNU C library provides support for user-defined character classes + and the functions from ISO C amendement 1. */ +# ifdef CHARCLASS_NAME_MAX +# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX +# else +/* This shouldn't happen but some implementation might still have this + problem. Use a reasonable default value. */ +# define CHAR_CLASS_MAX_LENGTH 256 +# endif + +# ifdef _LIBC +# define IS_CHAR_CLASS(string) __wctype (string) +# else +# define IS_CHAR_CLASS(string) wctype (string) +# endif +# else +# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ + +# define IS_CHAR_CLASS(string) \ + (STREQ (string, "alpha") || STREQ (string, "upper") \ + || STREQ (string, "lower") || STREQ (string, "digit") \ + || STREQ (string, "alnum") || STREQ (string, "xdigit") \ + || STREQ (string, "space") || STREQ (string, "print") \ + || STREQ (string, "punct") || STREQ (string, "graph") \ + || STREQ (string, "cntrl") || STREQ (string, "blank")) +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +# if !defined _LIBC && !defined getenv +extern char *getenv (); +# endif + +# ifndef errno +extern int errno; +# endif + +/* This function doesn't exist on most systems. */ + +# if !defined HAVE___STRCHRNUL && !defined _LIBC +static char * +__strchrnul (s, c) + const char *s; + int c; +{ + char *result = strchr (s, c); + if (result == NULL) + result = strchr (s, '\0'); + return result; +} +# endif + +# ifndef internal_function +/* Inside GNU libc we mark some function in a special way. In other + environments simply ignore the marking. */ +# define internal_function +# endif + +/* Match STRING against the filename pattern PATTERN, returning zero if + it matches, nonzero if not. */ +static int internal_fnmatch __P ((const char *pattern, const char *string, + int no_leading_period, int flags)) + internal_function; +static int +internal_function +internal_fnmatch (pattern, string, no_leading_period, flags) + const char *pattern; + const char *string; + int no_leading_period; + int flags; +{ + register const char *p = pattern, *n = string; + register unsigned char c; + +/* Note that this evaluates C many times. */ +# ifdef _LIBC +# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c)) +# else +# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c)) +# endif + + while ((c = *p++) != '\0') + { + c = FOLD (c); + + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if (*n == '/' && (flags & FNM_FILE_NAME)) + return FNM_NOMATCH; + else if (*n == '.' && no_leading_period + && (n == string + || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + { + c = *p++; + if (c == '\0') + /* Trailing \ loses. */ + return FNM_NOMATCH; + c = FOLD (c); + } + if (FOLD ((unsigned char) *n) != c) + return FNM_NOMATCH; + break; + + case '*': + if (*n == '.' && no_leading_period + && (n == string + || (n[-1] == '/' && (flags & FNM_FILE_NAME)))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++) + { + if (*n == '/' && (flags & FNM_FILE_NAME)) + /* A slash does not match a wildcard under FNM_FILE_NAME. */ + return FNM_NOMATCH; + else if (c == '?') + { + /* A ? needs to match one character. */ + if (*n == '\0') + /* There isn't another character; no match. */ + return FNM_NOMATCH; + else + /* One character of the string is consumed in matching + this ? wildcard, so *??? won't match if there are + less than three characters. */ + ++n; + } + } + + if (c == '\0') + /* The wildcard(s) is/are the last element of the pattern. + If the name is a file name and contains another slash + this does mean it cannot match. */ + return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL + ? FNM_NOMATCH : 0); + else + { + const char *endp; + + endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0'); + + if (c == '[') + { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + + for (--p; n < endp; ++n) + if (internal_fnmatch (p, n, + (no_leading_period + && (n == string + || (n[-1] == '/' + && (flags + & FNM_FILE_NAME)))), + flags2) + == 0) + return 0; + } + else if (c == '/' && (flags & FNM_FILE_NAME)) + { + while (*n != '\0' && *n != '/') + ++n; + if (*n == '/' + && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD, + flags) == 0)) + return 0; + } + else + { + int flags2 = ((flags & FNM_FILE_NAME) + ? flags : (flags & ~FNM_PERIOD)); + + if (c == '\\' && !(flags & FNM_NOESCAPE)) + c = *p; + c = FOLD (c); + for (--p; n < endp; ++n) + if (FOLD ((unsigned char) *n) == c + && (internal_fnmatch (p, n, + (no_leading_period + && (n == string + || (n[-1] == '/' + && (flags + & FNM_FILE_NAME)))), + flags2) == 0)) + return 0; + } + } + + /* If we come here no match is possible with the wildcard. */ + return FNM_NOMATCH; + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + static int posixly_correct; + register int not; + char cold; + + if (posixly_correct == 0) + posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1; + + if (*n == '\0') + return FNM_NOMATCH; + + if (*n == '.' && no_leading_period && (n == string + || (n[-1] == '/' + && (flags + & FNM_FILE_NAME)))) + return FNM_NOMATCH; + + if (*n == '/' && (flags & FNM_FILE_NAME)) + /* `/' cannot be matched. */ + return FNM_NOMATCH; + + not = (*p == '!' || (posixly_correct < 0 && *p == '^')); + if (not) + ++p; + + c = *p++; + for (;;) + { + unsigned char fn = FOLD ((unsigned char) *n); + + if (!(flags & FNM_NOESCAPE) && c == '\\') + { + if (*p == '\0') + return FNM_NOMATCH; + c = FOLD ((unsigned char) *p); + ++p; + + if (c == fn) + goto matched; + } + else if (c == '[' && *p == ':') + { + /* Leave room for the null. */ + char str[CHAR_CLASS_MAX_LENGTH + 1]; + size_t c1 = 0; +# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) + wctype_t wt; +# endif + const char *startp = p; + + for (;;) + { + if (c1 == CHAR_CLASS_MAX_LENGTH) + /* The name is too long and therefore the pattern + is ill-formed. */ + return FNM_NOMATCH; + + c = *++p; + if (c == ':' && p[1] == ']') + { + p += 2; + break; + } + if (c < 'a' || c >= 'z') + { + /* This cannot possibly be a character class name. + Match it as a normal range. */ + p = startp; + c = '['; + goto normal_bracket; + } + str[c1++] = c; + } + str[c1] = '\0'; + +# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H) + wt = IS_CHAR_CLASS (str); + if (wt == 0) + /* Invalid character class name. */ + return FNM_NOMATCH; + + if (__iswctype (__btowc ((unsigned char) *n), wt)) + goto matched; +# else + if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n)) + || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n)) + || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n)) + || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n)) + || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n)) + || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n)) + || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n)) + || (STREQ (str, "print") && ISPRINT ((unsigned char) *n)) + || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n)) + || (STREQ (str, "space") && ISSPACE ((unsigned char) *n)) + || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n)) + || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n))) + goto matched; +# endif + } + else if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + else + { + normal_bracket: + if (FOLD (c) == fn) + goto matched; + + cold = c; + c = *p++; + + if (c == '-' && *p != ']') + { + /* It is a range. */ + unsigned char cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + + if (cold <= fn && fn <= FOLD (cend)) + goto matched; + + c = *p++; + } + } + + if (c == ']') + break; + } + + if (!not) + return FNM_NOMATCH; + break; + + matched: + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + { + if (*p == '\0') + return FNM_NOMATCH; + /* XXX 1003.2d11 is unclear if this is right. */ + ++p; + } + else if (c == '[' && *p == ':') + { + do + if (*++p == '\0') + return FNM_NOMATCH; + while (*p != ':' || p[1] == ']'); + p += 2; + c = *p; + } + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != FOLD ((unsigned char) *n)) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0') + return 0; + + if ((flags & FNM_LEADING_DIR) && *n == '/') + /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */ + return 0; + + return FNM_NOMATCH; + +# undef FOLD +} + + +int +fnmatch (pattern, string, flags) + const char *pattern; + const char *string; + int flags; +{ + return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags); +} + +#endif /* _LIBC or not __GNU_LIBRARY__. */ diff --git a/src/make-3.80/glob/fnmatch.h b/src/make-3.80/glob/fnmatch.h new file mode 100755 index 00000000..cc3ec379 --- /dev/null +++ b/src/make-3.80/glob/fnmatch.h @@ -0,0 +1,84 @@ +/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; 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 GNU C Library 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 GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _FNMATCH_H +#define _FNMATCH_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32 +# if !defined __GLIBC__ || !defined __P +# undef __P +# define __P(protos) protos +# endif +#else /* Not C++ or ANSI C. */ +# undef __P +# define __P(protos) () +/* We can get away without defining `const' here only because in this file + it is used only inside the prototype for `fnmatch', which is elided in + non-ANSI C where `const' is problematical. */ +#endif /* C++ or ANSI C. */ + +#ifndef const +# if (defined __STDC__ && __STDC__) || defined __cplusplus +# define __const const +# else +# define __const +# endif +#endif + +/* We #undef these before defining them because some losing systems + (HP-UX A.08.07 for example) define these in . */ +#undef FNM_PATHNAME +#undef FNM_NOESCAPE +#undef FNM_PERIOD + +/* Bits set in the FLAGS argument to `fnmatch'. */ +#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */ +#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */ +#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */ + +#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE +# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */ +# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */ +# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */ +#endif + +/* Value returned by `fnmatch' if STRING does not match PATTERN. */ +#define FNM_NOMATCH 1 + +/* This value is returned if the implementation does not support + `fnmatch'. Since this is not the case here it will never be + returned but the conformance test suites still require the symbol + to be defined. */ +#ifdef _XOPEN_SOURCE +# define FNM_NOSYS (-1) +#endif + +/* Match NAME against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ +extern int fnmatch __P ((__const char *__pattern, __const char *__name, + int __flags)); + +#ifdef __cplusplus +} +#endif + +#endif /* fnmatch.h */ diff --git a/src/make-3.80/glob/glob.c b/src/make-3.80/glob/glob.c new file mode 100755 index 00000000..4bbf7bb0 --- /dev/null +++ b/src/make-3.80/glob/glob.c @@ -0,0 +1,1428 @@ +/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc. + + This library is free software; 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. + + This library 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 this library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* AIX requires this to be the first thing in the file. */ +#if defined _AIX && !defined __GNUC__ + #pragma alloca +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* Enable GNU extensions in glob.h. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#include +#include +#include + +/* Outcomment the following line for production quality code. */ +/* #define NDEBUG 1 */ +#include + +#include /* Needed on stupid SunOS for assert. */ + + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GLOB_INTERFACE_VERSION 1 +#if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1 +# include +# if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + +#if defined STDC_HEADERS || defined __GNU_LIBRARY__ +# include +#endif + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +# ifndef POSIX +# ifdef _POSIX_VERSION +# define POSIX +# endif +# endif +#endif + +#if !defined _AMIGA && !defined VMS && !defined WINDOWS32 +# include +#endif + +#if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(val) errno = (val) +#endif + +#ifndef NULL +# define NULL 0 +#endif + + +#if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__ +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +# ifdef HAVE_VMSDIR_H +# include "vmsdir.h" +# endif /* HAVE_VMSDIR_H */ +#endif + + +/* In GNU systems, defines this macro for us. */ +#ifdef _D_NAMLEN +# undef NAMLEN +# define NAMLEN(d) _D_NAMLEN(d) +#endif + +/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available + if the `d_type' member for `struct dirent' is available. */ +#ifdef _DIRENT_HAVE_D_TYPE +# define HAVE_D_TYPE 1 +#endif + + +#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__ +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +# define REAL_DIR_ENTRY(dp) 1 +#else +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* POSIX */ + +#if defined STDC_HEADERS || defined __GNU_LIBRARY__ +# include +# include +# define ANSI_STRING +#else /* No standard headers. */ + +extern char *getenv (); + +# ifdef HAVE_STRING_H +# include +# define ANSI_STRING +# else +# include +# endif +# ifdef HAVE_MEMORY_H +# include +# endif + +extern char *malloc (), *realloc (); +extern void free (); + +extern void qsort (); +extern void abort (), exit (); + +#endif /* Standard headers. */ + +#ifndef ANSI_STRING + +# ifndef bzero +extern void bzero (); +# endif +# ifndef bcopy +extern void bcopy (); +# endif + +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# define strrchr rindex +/* memset is only used for zero here, but let's be paranoid. */ +# define memset(s, better_be_zero, n) \ + ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0))) +#endif /* Not ANSI_STRING. */ + +#if !defined HAVE_STRCOLL && !defined _LIBC +# define strcoll strcmp +#endif + +#if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1 +# define HAVE_MEMPCPY 1 +# undef mempcpy +# define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len) +#endif + +#ifndef __GNU_LIBRARY__ +# ifdef __GNUC__ +__inline +# endif +# ifndef __SASC +# ifdef WINDOWS32 +static void * +# else +static char * +# endif +my_realloc (p, n) + char *p; + unsigned int n; +{ + /* These casts are the for sake of the broken Ultrix compiler, + which warns of illegal pointer combinations otherwise. */ + if (p == NULL) + return (char *) malloc (n); + return (char *) realloc (p, n); +} +# define realloc my_realloc +# endif /* __SASC */ +#endif /* __GNU_LIBRARY__ */ + + +#if !defined __alloca && !defined __GNU_LIBRARY__ + +# ifdef __GNUC__ +# undef alloca +# define alloca(n) __builtin_alloca (n) +# else /* Not GCC. */ +# ifdef HAVE_ALLOCA_H +# include +# else /* Not HAVE_ALLOCA_H. */ +# ifndef _AIX +# ifdef WINDOWS32 +# include +# else +extern char *alloca (); +# endif /* WINDOWS32 */ +# endif /* Not _AIX. */ +# endif /* sparc or HAVE_ALLOCA_H. */ +# endif /* GCC. */ + +# define __alloca alloca + +#endif + +#ifndef __GNU_LIBRARY__ +# define __stat stat +# ifdef STAT_MACROS_BROKEN +# undef S_ISDIR +# endif +# ifndef S_ISDIR +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +# endif +#endif + +#ifdef _LIBC +# undef strdup +# define strdup(str) __strdup (str) +# define sysconf(id) __sysconf (id) +# define closedir(dir) __closedir (dir) +# define opendir(name) __opendir (name) +# define readdir(str) __readdir (str) +# define getpwnam_r(name, bufp, buf, len, res) \ + __getpwnam_r (name, bufp, buf, len, res) +# ifndef __stat +# define __stat(fname, buf) __xstat (_STAT_VER, fname, buf) +# endif +#endif + +#if !(defined STDC_HEADERS || defined __GNU_LIBRARY__) +# undef size_t +# define size_t unsigned int +#endif + +/* Some system header files erroneously define these. + We want our own definitions from to take precedence. */ +#ifndef __GNU_LIBRARY__ +# undef FNM_PATHNAME +# undef FNM_NOESCAPE +# undef FNM_PERIOD +#endif +#include + +/* Some system header files erroneously define these. + We want our own definitions from to take precedence. */ +#ifndef __GNU_LIBRARY__ +# undef GLOB_ERR +# undef GLOB_MARK +# undef GLOB_NOSORT +# undef GLOB_DOOFFS +# undef GLOB_NOCHECK +# undef GLOB_APPEND +# undef GLOB_NOESCAPE +# undef GLOB_PERIOD +#endif +#include + +#ifdef HAVE_GETLOGIN_R +extern int getlogin_r __P ((char *, size_t)); +#else +extern char *getlogin __P ((void)); +#endif + +static +#if __GNUC__ - 0 >= 2 +inline +#endif +const char *next_brace_sub __P ((const char *begin)); +static int glob_in_dir __P ((const char *pattern, const char *directory, + int flags, + int (*errfunc) (const char *, int), + glob_t *pglob)); +static int prefix_array __P ((const char *prefix, char **array, size_t n)); +static int collated_compare __P ((const __ptr_t, const __ptr_t)); + +#ifdef VMS +/* these compilers like prototypes */ +#if !defined _LIBC || !defined NO_GLOB_PATTERN_P +int __glob_pattern_p (const char *pattern, int quote); +#endif +#endif + +/* Find the end of the sub-pattern in a brace expression. We define + this as an inline function if the compiler permits. */ +static +#if __GNUC__ - 0 >= 2 +inline +#endif +const char * +next_brace_sub (begin) + const char *begin; +{ + unsigned int depth = 0; + const char *cp = begin; + + while (1) + { + if (depth == 0) + { + if (*cp != ',' && *cp != '}' && *cp != '\0') + { + if (*cp == '{') + ++depth; + ++cp; + continue; + } + } + else + { + while (*cp != '\0' && (*cp != '}' || depth > 0)) + { + if (*cp == '}') + --depth; + ++cp; + } + if (*cp == '\0') + /* An incorrectly terminated brace expression. */ + return NULL; + + continue; + } + break; + } + + return cp; +} + +/* Do glob searching for PATTERN, placing results in PGLOB. + The bits defined above may be set in FLAGS. + If a directory cannot be opened or read and ERRFUNC is not nil, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored. + If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. + Otherwise, `glob' returns zero. */ +int +glob (pattern, flags, errfunc, pglob) + const char *pattern; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + const char *filename; + const char *dirname; + size_t dirlen; + int status; + int oldcount; + + if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) + { + __set_errno (EINVAL); + return -1; + } + + if (flags & GLOB_BRACE) + { + const char *begin = strchr (pattern, '{'); + if (begin != NULL) + { + /* Allocate working buffer large enough for our work. Note that + we have at least an opening and closing brace. */ + int firstc; + char *alt_start; + const char *p; + const char *next; + const char *rest; + size_t rest_len; +#ifdef __GNUC__ + char onealt[strlen (pattern) - 1]; +#else + char *onealt = (char *) malloc (strlen (pattern) - 1); + if (onealt == NULL) + { + if (!(flags & GLOB_APPEND)) + globfree (pglob); + return GLOB_NOSPACE; + } +#endif + + /* We know the prefix for all sub-patterns. */ +#ifdef HAVE_MEMPCPY + alt_start = mempcpy (onealt, pattern, begin - pattern); +#else + memcpy (onealt, pattern, begin - pattern); + alt_start = &onealt[begin - pattern]; +#endif + + /* Find the first sub-pattern and at the same time find the + rest after the closing brace. */ + next = next_brace_sub (begin + 1); + if (next == NULL) + { + /* It is an illegal expression. */ +#ifndef __GNUC__ + free (onealt); +#endif + return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); + } + + /* Now find the end of the whole brace expression. */ + rest = next; + while (*rest != '}') + { + rest = next_brace_sub (rest + 1); + if (rest == NULL) + { + /* It is an illegal expression. */ +#ifndef __GNUC__ + free (onealt); +#endif + return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob); + } + } + /* Please note that we now can be sure the brace expression + is well-formed. */ + rest_len = strlen (++rest) + 1; + + /* We have a brace expression. BEGIN points to the opening {, + NEXT points past the terminator of the first element, and END + points past the final }. We will accumulate result names from + recursive runs for each brace alternative in the buffer using + GLOB_APPEND. */ + + if (!(flags & GLOB_APPEND)) + { + /* This call is to set a new vector, so clear out the + vector so we can append to it. */ + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } + firstc = pglob->gl_pathc; + + p = begin + 1; + while (1) + { + int result; + + /* Construct the new glob expression. */ +#ifdef HAVE_MEMPCPY + mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len); +#else + memcpy (alt_start, p, next - p); + memcpy (&alt_start[next - p], rest, rest_len); +#endif + + result = glob (onealt, + ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC)) + | GLOB_APPEND), errfunc, pglob); + + /* If we got an error, return it. */ + if (result && result != GLOB_NOMATCH) + { +#ifndef __GNUC__ + free (onealt); +#endif + if (!(flags & GLOB_APPEND)) + globfree (pglob); + return result; + } + + if (*next == '}') + /* We saw the last entry. */ + break; + + p = next + 1; + next = next_brace_sub (p); + assert (next != NULL); + } + +#ifndef __GNUC__ + free (onealt); +#endif + + if (pglob->gl_pathc != firstc) + /* We found some entries. */ + return 0; + else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) + return GLOB_NOMATCH; + } + } + + /* Find the filename. */ + filename = strrchr (pattern, '/'); +#if defined __MSDOS__ || defined WINDOWS32 + /* The case of "d:pattern". Since `:' is not allowed in + file names, we can safely assume that wherever it + happens in pattern, it signals the filename part. This + is so we could some day support patterns like "[a-z]:foo". */ + if (filename == NULL) + filename = strchr (pattern, ':'); +#endif /* __MSDOS__ || WINDOWS32 */ + if (filename == NULL) + { + /* This can mean two things: a simple name or "~name". The later + case is nothing but a notation for a directory. */ + if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~') + { + dirname = pattern; + dirlen = strlen (pattern); + + /* Set FILENAME to NULL as a special flag. This is ugly but + other solutions would require much more code. We test for + this special case below. */ + filename = NULL; + } + else + { + filename = pattern; +#ifdef _AMIGA + dirname = ""; +#else + dirname = "."; +#endif + dirlen = 0; + } + } + else if (filename == pattern) + { + /* "/pattern". */ + dirname = "/"; + dirlen = 1; + ++filename; + } + else + { + char *newp; + dirlen = filename - pattern; +#if defined __MSDOS__ || defined WINDOWS32 + if (*filename == ':' + || (filename > pattern + 1 && filename[-1] == ':')) + { + char *drive_spec; + + ++dirlen; + drive_spec = (char *) __alloca (dirlen + 1); +#ifdef HAVE_MEMPCPY + *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0'; +#else + memcpy (drive_spec, pattern, dirlen); + drive_spec[dirlen] = '\0'; +#endif + /* For now, disallow wildcards in the drive spec, to + prevent infinite recursion in glob. */ + if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE))) + return GLOB_NOMATCH; + /* If this is "d:pattern", we need to copy `:' to DIRNAME + as well. If it's "d:/pattern", don't remove the slash + from "d:/", since "d:" and "d:/" are not the same.*/ + } +#endif + newp = (char *) __alloca (dirlen + 1); +#ifdef HAVE_MEMPCPY + *((char *) mempcpy (newp, pattern, dirlen)) = '\0'; +#else + memcpy (newp, pattern, dirlen); + newp[dirlen] = '\0'; +#endif + dirname = newp; + ++filename; + + if (filename[0] == '\0' +#if defined __MSDOS__ || defined WINDOWS32 + && dirname[dirlen - 1] != ':' + && (dirlen < 3 || dirname[dirlen - 2] != ':' + || dirname[dirlen - 1] != '/') +#endif + && dirlen > 1) + /* "pattern/". Expand "pattern", appending slashes. */ + { + int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob); + if (val == 0) + pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK) + | (flags & GLOB_MARK)); + return val; + } + } + + if (!(flags & GLOB_APPEND)) + { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } + + oldcount = pglob->gl_pathc; + +#ifndef VMS + if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~') + { + if (dirname[1] == '\0' || dirname[1] == '/') + { + /* Look up home directory. */ +#ifdef VMS +/* This isn't obvious, RTLs of DECC and VAXC know about "HOME" */ + const char *home_dir = getenv ("SYS$LOGIN"); +#else + const char *home_dir = getenv ("HOME"); +#endif +# ifdef _AMIGA + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = "SYS:"; +# else +# ifdef WINDOWS32 + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = "c:/users/default"; /* poor default */ +# else +# ifdef VMS +/* Again, this isn't obvious, if "HOME" isn't known "SYS$LOGIN" should be set */ + if (home_dir == NULL || home_dir[0] == '\0') + home_dir = "SYS$DISK:[]"; +# else + if (home_dir == NULL || home_dir[0] == '\0') + { + int success; + char *name; +# if defined HAVE_GETLOGIN_R || defined _LIBC + size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1; + + if (buflen == 0) + /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try + a moderate value. */ + buflen = 20; + name = (char *) __alloca (buflen); + + success = getlogin_r (name, buflen) >= 0; +# else + success = (name = getlogin ()) != NULL; +# endif + if (success) + { + struct passwd *p; +# if defined HAVE_GETPWNAM_R || defined _LIBC + size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX); + char *pwtmpbuf; + struct passwd pwbuf; + int save = errno; + + if (pwbuflen == -1) + /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. + Try a moderate value. */ + pwbuflen = 1024; + pwtmpbuf = (char *) __alloca (pwbuflen); + + while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) + != 0) + { + if (errno != ERANGE) + { + p = NULL; + break; + } + pwbuflen *= 2; + pwtmpbuf = (char *) __alloca (pwbuflen); + __set_errno (save); + } +# else + p = getpwnam (name); +# endif + if (p != NULL) + home_dir = p->pw_dir; + } + } + if (home_dir == NULL || home_dir[0] == '\0') + { + if (flags & GLOB_TILDE_CHECK) + return GLOB_NOMATCH; + else + home_dir = "~"; /* No luck. */ + } +# endif /* VMS */ +# endif /* WINDOWS32 */ +# endif + /* Now construct the full directory. */ + if (dirname[1] == '\0') + dirname = home_dir; + else + { + char *newp; + size_t home_len = strlen (home_dir); + newp = (char *) __alloca (home_len + dirlen); +# ifdef HAVE_MEMPCPY + mempcpy (mempcpy (newp, home_dir, home_len), + &dirname[1], dirlen); +# else + memcpy (newp, home_dir, home_len); + memcpy (&newp[home_len], &dirname[1], dirlen); +# endif + dirname = newp; + } + } +# if !defined _AMIGA && !defined WINDOWS32 && !defined VMS + else + { + char *end_name = strchr (dirname, '/'); + const char *user_name; + const char *home_dir; + + if (end_name == NULL) + user_name = dirname + 1; + else + { + char *newp; + newp = (char *) __alloca (end_name - dirname); +# ifdef HAVE_MEMPCPY + *((char *) mempcpy (newp, dirname + 1, end_name - dirname)) + = '\0'; +# else + memcpy (newp, dirname + 1, end_name - dirname); + newp[end_name - dirname - 1] = '\0'; +# endif + user_name = newp; + } + + /* Look up specific user's home directory. */ + { + struct passwd *p; +# if defined HAVE_GETPWNAM_R || defined _LIBC + size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX); + char *pwtmpbuf; + struct passwd pwbuf; + int save = errno; + + if (buflen == -1) + /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a + moderate value. */ + buflen = 1024; + pwtmpbuf = (char *) __alloca (buflen); + + while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0) + { + if (errno != ERANGE) + { + p = NULL; + break; + } + buflen *= 2; + pwtmpbuf = __alloca (buflen); + __set_errno (save); + } +# else + p = getpwnam (user_name); +# endif + if (p != NULL) + home_dir = p->pw_dir; + else + home_dir = NULL; + } + /* If we found a home directory use this. */ + if (home_dir != NULL) + { + char *newp; + size_t home_len = strlen (home_dir); + size_t rest_len = end_name == NULL ? 0 : strlen (end_name); + newp = (char *) __alloca (home_len + rest_len + 1); +# ifdef HAVE_MEMPCPY + *((char *) mempcpy (mempcpy (newp, home_dir, home_len), + end_name, rest_len)) = '\0'; +# else + memcpy (newp, home_dir, home_len); + memcpy (&newp[home_len], end_name, rest_len); + newp[home_len + rest_len] = '\0'; +# endif + dirname = newp; + } + else + if (flags & GLOB_TILDE_CHECK) + /* We have to regard it as an error if we cannot find the + home directory. */ + return GLOB_NOMATCH; + } +# endif /* Not Amiga && not WINDOWS32 && not VMS. */ + } +#endif /* Not VMS. */ + + /* Now test whether we looked for "~" or "~NAME". In this case we + can give the answer now. */ + if (filename == NULL) + { + struct stat st; + + /* Return the directory if we don't check for error or if it exists. */ + if ((flags & GLOB_NOCHECK) + || (((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (dirname, &st) + : __stat (dirname, &st)) == 0 + && S_ISDIR (st.st_mode))) + { + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? + pglob->gl_offs : 0) + + 1 + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + return GLOB_NOSPACE; + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + +#if defined HAVE_STRDUP || defined _LIBC + pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname); +#else + { + size_t len = strlen (dirname) + 1; + char *dircopy = malloc (len); + if (dircopy != NULL) + pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname, + len); + } +#endif + if (pglob->gl_pathv[pglob->gl_pathc] == NULL) + { + free (pglob->gl_pathv); + return GLOB_NOSPACE; + } + pglob->gl_pathv[++pglob->gl_pathc] = NULL; + pglob->gl_flags = flags; + + return 0; + } + + /* Not found. */ + return GLOB_NOMATCH; + } + + if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE))) + { + /* The directory name contains metacharacters, so we + have to glob for the directory, and then glob for + the pattern in each directory found. */ + glob_t dirs; + register int i; + + status = glob (dirname, + ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) + | GLOB_NOSORT | GLOB_ONLYDIR), + errfunc, &dirs); + if (status != 0) + return status; + + /* We have successfully globbed the preceding directory name. + For each name we found, call glob_in_dir on it and FILENAME, + appending the results to PGLOB. */ + for (i = 0; i < dirs.gl_pathc; ++i) + { + int old_pathc; + +#ifdef SHELL + { + /* Make globbing interruptible in the bash shell. */ + extern int interrupt_state; + + if (interrupt_state) + { + globfree (&dirs); + globfree (&files); + return GLOB_ABORTED; + } + } +#endif /* SHELL. */ + + old_pathc = pglob->gl_pathc; + status = glob_in_dir (filename, dirs.gl_pathv[i], + ((flags | GLOB_APPEND) + & ~(GLOB_NOCHECK | GLOB_ERR)), + errfunc, pglob); + if (status == GLOB_NOMATCH) + /* No matches in this directory. Try the next. */ + continue; + + if (status != 0) + { + globfree (&dirs); + globfree (pglob); + return status; + } + + /* Stick the directory on the front of each name. */ + if (prefix_array (dirs.gl_pathv[i], + &pglob->gl_pathv[old_pathc], + pglob->gl_pathc - old_pathc)) + { + globfree (&dirs); + globfree (pglob); + return GLOB_NOSPACE; + } + } + + flags |= GLOB_MAGCHAR; + + /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls. + But if we have not found any matching entry and thie GLOB_NOCHECK + flag was set we must return the list consisting of the disrectory + names followed by the filename. */ + if (pglob->gl_pathc == oldcount) + { + /* No matches. */ + if (flags & GLOB_NOCHECK) + { + size_t filename_len = strlen (filename) + 1; + char **new_pathv; + struct stat st; + + /* This is an pessimistic guess about the size. */ + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? + pglob->gl_offs : 0) + + dirs.gl_pathc + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + { + globfree (&dirs); + return GLOB_NOSPACE; + } + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + for (i = 0; i < dirs.gl_pathc; ++i) + { + const char *dir = dirs.gl_pathv[i]; + size_t dir_len = strlen (dir); + + /* First check whether this really is a directory. */ + if (((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0 + || !S_ISDIR (st.st_mode)) + /* No directory, ignore this entry. */ + continue; + + pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1 + + filename_len); + if (pglob->gl_pathv[pglob->gl_pathc] == NULL) + { + globfree (&dirs); + globfree (pglob); + return GLOB_NOSPACE; + } + +#ifdef HAVE_MEMPCPY + mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc], + dir, dir_len), + "/", 1), + filename, filename_len); +#else + memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len); + pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/'; + memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1], + filename, filename_len); +#endif + ++pglob->gl_pathc; + } + + pglob->gl_pathv[pglob->gl_pathc] = NULL; + pglob->gl_flags = flags; + + /* Now we know how large the gl_pathv vector must be. */ + new_pathv = (char **) realloc (pglob->gl_pathv, + ((pglob->gl_pathc + 1) + * sizeof (char *))); + if (new_pathv != NULL) + pglob->gl_pathv = new_pathv; + } + else + return GLOB_NOMATCH; + } + + globfree (&dirs); + } + else + { + status = glob_in_dir (filename, dirname, flags, errfunc, pglob); + if (status != 0) + return status; + + if (dirlen > 0) + { + /* Stick the directory on the front of each name. */ + int ignore = oldcount; + + if ((flags & GLOB_DOOFFS) && ignore < pglob->gl_offs) + ignore = pglob->gl_offs; + + if (prefix_array (dirname, + &pglob->gl_pathv[ignore], + pglob->gl_pathc - ignore)) + { + globfree (pglob); + return GLOB_NOSPACE; + } + } + } + + if (flags & GLOB_MARK) + { + /* Append slashes to directory names. */ + int i; + struct stat st; + for (i = oldcount; i < pglob->gl_pathc; ++i) + if (((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st) + : __stat (pglob->gl_pathv[i], &st)) == 0 + && S_ISDIR (st.st_mode)) + { + size_t len = strlen (pglob->gl_pathv[i]) + 2; + char *new = realloc (pglob->gl_pathv[i], len); + if (new == NULL) + { + globfree (pglob); + return GLOB_NOSPACE; + } + strcpy (&new[len - 2], "/"); + pglob->gl_pathv[i] = new; + } + } + + if (!(flags & GLOB_NOSORT)) + { + /* Sort the vector. */ + int non_sort = oldcount; + + if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount) + non_sort = pglob->gl_offs; + + qsort ((__ptr_t) &pglob->gl_pathv[non_sort], + pglob->gl_pathc - non_sort, + sizeof (char *), collated_compare); + } + + return 0; +} + + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +void +globfree (pglob) + register glob_t *pglob; +{ + if (pglob->gl_pathv != NULL) + { + register int i; + for (i = 0; i < pglob->gl_pathc; ++i) + if (pglob->gl_pathv[i] != NULL) + free ((__ptr_t) pglob->gl_pathv[i]); + free ((__ptr_t) pglob->gl_pathv); + } +} + + +/* Do a collated comparison of A and B. */ +static int +collated_compare (a, b) + const __ptr_t a; + const __ptr_t b; +{ + const char *const s1 = *(const char *const * const) a; + const char *const s2 = *(const char *const * const) b; + + if (s1 == s2) + return 0; + if (s1 == NULL) + return 1; + if (s2 == NULL) + return -1; + return strcoll (s1, s2); +} + + +/* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's + elements in place. Return nonzero if out of memory, zero if successful. + A slash is inserted between DIRNAME and each elt of ARRAY, + unless DIRNAME is just "/". Each old element of ARRAY is freed. */ +static int +prefix_array (dirname, array, n) + const char *dirname; + char **array; + size_t n; +{ + register size_t i; + size_t dirlen = strlen (dirname); +#if defined __MSDOS__ || defined WINDOWS32 + int sep_char = '/'; +# define DIRSEP_CHAR sep_char +#else +# define DIRSEP_CHAR '/' +#endif + + if (dirlen == 1 && dirname[0] == '/') + /* DIRNAME is just "/", so normal prepending would get us "//foo". + We want "/foo" instead, so don't prepend any chars from DIRNAME. */ + dirlen = 0; +#if defined __MSDOS__ || defined WINDOWS32 + else if (dirlen > 1) + { + if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':') + /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */ + --dirlen; + else if (dirname[dirlen - 1] == ':') + { + /* DIRNAME is "d:". Use `:' instead of `/'. */ + --dirlen; + sep_char = ':'; + } + } +#endif + + for (i = 0; i < n; ++i) + { + size_t eltlen = strlen (array[i]) + 1; + char *new = (char *) malloc (dirlen + 1 + eltlen); + if (new == NULL) + { + while (i > 0) + free ((__ptr_t) array[--i]); + return 1; + } + +#ifdef HAVE_MEMPCPY + { + char *endp = (char *) mempcpy (new, dirname, dirlen); + *endp++ = DIRSEP_CHAR; + mempcpy (endp, array[i], eltlen); + } +#else + memcpy (new, dirname, dirlen); + new[dirlen] = DIRSEP_CHAR; + memcpy (&new[dirlen + 1], array[i], eltlen); +#endif + free ((__ptr_t) array[i]); + array[i] = new; + } + + return 0; +} + + +/* We must not compile this function twice. */ +#if !defined _LIBC || !defined NO_GLOB_PATTERN_P +/* Return nonzero if PATTERN contains any metacharacters. + Metacharacters can be quoted with backslashes if QUOTE is nonzero. */ +int +__glob_pattern_p (pattern, quote) + const char *pattern; + int quote; +{ + register const char *p; + int open = 0; + + for (p = pattern; *p != '\0'; ++p) + switch (*p) + { + case '?': + case '*': + return 1; + + case '\\': + if (quote && p[1] != '\0') + ++p; + break; + + case '[': + open = 1; + break; + + case ']': + if (open) + return 1; + break; + } + + return 0; +} +# ifdef _LIBC +weak_alias (__glob_pattern_p, glob_pattern_p) +# endif +#endif + + +/* Like `glob', but PATTERN is a final pathname component, + and matches are searched for in DIRECTORY. + The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. + The GLOB_APPEND flag is assumed to be set (always appends). */ +static int +glob_in_dir (pattern, directory, flags, errfunc, pglob) + const char *pattern; + const char *directory; + int flags; + int (*errfunc) __P ((const char *, int)); + glob_t *pglob; +{ + __ptr_t stream = NULL; + + struct globlink + { + struct globlink *next; + char *name; + }; + struct globlink *names = NULL; + size_t nfound; + int meta; + int save; + +#ifdef VMS + if (*directory == 0) + directory = "[]"; +#endif + meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE)); + if (meta == 0) + { + if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)) + /* We need not do any tests. The PATTERN contains no meta + characters and we must not return an error therefore the + result will always contain exactly one name. */ + flags |= GLOB_NOCHECK; + else + { + /* Since we use the normal file functions we can also use stat() + to verify the file is there. */ + struct stat st; + size_t patlen = strlen (pattern); + size_t dirlen = strlen (directory); + char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1); + +# ifdef HAVE_MEMPCPY + mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), + "/", 1), + pattern, patlen + 1); +# else + memcpy (fullname, directory, dirlen); + fullname[dirlen] = '/'; + memcpy (&fullname[dirlen + 1], pattern, patlen + 1); +# endif + if (((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_stat) (fullname, &st) + : __stat (fullname, &st)) == 0) + /* We found this file to be existing. Now tell the rest + of the function to copy this name into the result. */ + flags |= GLOB_NOCHECK; + } + + nfound = 0; + } + else + { + if (pattern[0] == '\0') + { + /* This is a special case for matching directories like in + "*a/". */ + names = (struct globlink *) __alloca (sizeof (struct globlink)); + names->name = (char *) malloc (1); + if (names->name == NULL) + goto memory_error; + names->name[0] = '\0'; + names->next = NULL; + nfound = 1; + meta = 0; + } + else + { + stream = ((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_opendir) (directory) + : (__ptr_t) opendir (directory)); + if (stream == NULL) + { + if (errno != ENOTDIR + && ((errfunc != NULL && (*errfunc) (directory, errno)) + || (flags & GLOB_ERR))) + return GLOB_ABORTED; + nfound = 0; + meta = 0; + } + else + { + int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) + | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) +#if defined _AMIGA || defined VMS + | FNM_CASEFOLD +#endif + ); + nfound = 0; + flags |= GLOB_MAGCHAR; + + while (1) + { + const char *name; + size_t len; + struct dirent *d = ((flags & GLOB_ALTDIRFUNC) + ? (*pglob->gl_readdir) (stream) + : readdir ((DIR *) stream)); + if (d == NULL) + break; + if (! REAL_DIR_ENTRY (d)) + continue; + +#ifdef HAVE_D_TYPE + /* If we shall match only directories use the information + provided by the dirent call if possible. */ + if ((flags & GLOB_ONLYDIR) + && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR) + continue; +#endif + + name = d->d_name; + + if (fnmatch (pattern, name, fnm_flags) == 0) + { + struct globlink *new = (struct globlink *) + __alloca (sizeof (struct globlink)); + len = NAMLEN (d); + new->name = (char *) malloc (len + 1); + if (new->name == NULL) + goto memory_error; +#ifdef HAVE_MEMPCPY + *((char *) mempcpy ((__ptr_t) new->name, name, len)) + = '\0'; +#else + memcpy ((__ptr_t) new->name, name, len); + new->name[len] = '\0'; +#endif + new->next = names; + names = new; + ++nfound; + } + } + } + } + } + + if (nfound == 0 && (flags & GLOB_NOCHECK)) + { + size_t len = strlen (pattern); + nfound = 1; + names = (struct globlink *) __alloca (sizeof (struct globlink)); + names->next = NULL; + names->name = (char *) malloc (len + 1); + if (names->name == NULL) + goto memory_error; +#ifdef HAVE_MEMPCPY + *((char *) mempcpy (names->name, pattern, len)) = '\0'; +#else + memcpy (names->name, pattern, len); + names->name[len] = '\0'; +#endif + } + + if (nfound != 0) + { + pglob->gl_pathv + = (char **) realloc (pglob->gl_pathv, + (pglob->gl_pathc + + ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) + + nfound + 1) * + sizeof (char *)); + if (pglob->gl_pathv == NULL) + goto memory_error; + + if (flags & GLOB_DOOFFS) + while (pglob->gl_pathc < pglob->gl_offs) + pglob->gl_pathv[pglob->gl_pathc++] = NULL; + + for (; names != NULL; names = names->next) + pglob->gl_pathv[pglob->gl_pathc++] = names->name; + pglob->gl_pathv[pglob->gl_pathc] = NULL; + + pglob->gl_flags = flags; + } + + save = errno; + if (stream != NULL) + { + if (flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir) (stream); + else + closedir ((DIR *) stream); + } + __set_errno (save); + + return nfound == 0 ? GLOB_NOMATCH : 0; + + memory_error: + { + int save = errno; + if (flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir) (stream); + else + closedir ((DIR *) stream); + __set_errno (save); + } + while (names != NULL) + { + if (names->name != NULL) + free ((__ptr_t) names->name); + names = names->next; + } + return GLOB_NOSPACE; +} + +#endif /* Not ELIDE_CODE. */ diff --git a/src/make-3.80/glob/glob.h b/src/make-3.80/glob/glob.h new file mode 100755 index 00000000..9f735fe8 --- /dev/null +++ b/src/make-3.80/glob/glob.h @@ -0,0 +1,205 @@ +/* Copyright (C) 1991, 92, 95, 96, 97, 98 Free Software Foundation, Inc. + + The GNU C Library is free software; 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 GNU C Library 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 GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GLOB_H +#define _GLOB_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#undef __ptr_t +#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32 +# if !defined __GLIBC__ || !defined __P +# undef __P +# undef __PMT +# define __P(protos) protos +# define __PMT(protos) protos +# if !defined __GNUC__ || __GNUC__ < 2 +# undef __const +# define __const const +# endif +# endif +# define __ptr_t void * +#else /* Not C++ or ANSI C. */ +# undef __P +# undef __PMT +# define __P(protos) () +# define __PMT(protos) () +# undef __const +# define __const +# define __ptr_t char * +#endif /* C++ or ANSI C. */ + +/* We need `size_t' for the following definitions. */ +#ifndef __size_t +# if defined __GNUC__ && __GNUC__ >= 2 +typedef __SIZE_TYPE__ __size_t; +# else +/* This is a guess. */ +/*hb + * Conflicts with DECCs aready defined type __size_t. + * Defining an own type with a name beginning with '__' is no good. + * Anyway if DECC is used and __SIZE_T is defined then __size_t is + * already defined (and I hope it's exactly the one we need here). + */ +#if !(defined __DECC && defined __SIZE_T) +typedef unsigned long int __size_t; +#endif +# endif +#else +/* The GNU CC stddef.h version defines __size_t as empty. We need a real + definition. */ +# undef __size_t +# define __size_t size_t +#endif + +/* Bits set in the FLAGS argument to `glob'. */ +#define GLOB_ERR (1 << 0)/* Return on read errors. */ +#define GLOB_MARK (1 << 1)/* Append a slash to each name. */ +#define GLOB_NOSORT (1 << 2)/* Don't sort the names. */ +#define GLOB_DOOFFS (1 << 3)/* Insert PGLOB->gl_offs NULLs. */ +#define GLOB_NOCHECK (1 << 4)/* If nothing matches, return the pattern. */ +#define GLOB_APPEND (1 << 5)/* Append to results of a previous call. */ +#define GLOB_NOESCAPE (1 << 6)/* Backslashes don't quote metacharacters. */ +#define GLOB_PERIOD (1 << 7)/* Leading `.' can be matched by metachars. */ + +#if (!defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _BSD_SOURCE \ + || defined _GNU_SOURCE) +# define GLOB_MAGCHAR (1 << 8)/* Set in gl_flags if any metachars seen. */ +# define GLOB_ALTDIRFUNC (1 << 9)/* Use gl_opendir et al functions. */ +# define GLOB_BRACE (1 << 10)/* Expand "{a,b}" to "a" "b". */ +# define GLOB_NOMAGIC (1 << 11)/* If no magic chars, return the pattern. */ +# define GLOB_TILDE (1 << 12)/* Expand ~user and ~ to home directories. */ +# define GLOB_ONLYDIR (1 << 13)/* Match only directories. */ +# define GLOB_TILDE_CHECK (1 << 14)/* Like GLOB_TILDE but return an error + if the user name is not available. */ +# define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ + GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \ + GLOB_PERIOD|GLOB_ALTDIRFUNC|GLOB_BRACE| \ + GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR|GLOB_TILDE_CHECK) +#else +# define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ + GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \ + GLOB_PERIOD) +#endif + +/* Error returns from `glob'. */ +#define GLOB_NOSPACE 1 /* Ran out of memory. */ +#define GLOB_ABORTED 2 /* Read error. */ +#define GLOB_NOMATCH 3 /* No matches found. */ +#define GLOB_NOSYS 4 /* Not implemented. */ +#ifdef _GNU_SOURCE +/* Previous versions of this file defined GLOB_ABEND instead of + GLOB_ABORTED. Provide a compatibility definition here. */ +# define GLOB_ABEND GLOB_ABORTED +#endif + +/* Structure describing a globbing run. */ +#if !defined _AMIGA && !defined VMS /* Buggy compiler. */ +struct stat; +#endif +typedef struct + { + __size_t gl_pathc; /* Count of paths matched by the pattern. */ + char **gl_pathv; /* List of matched pathnames. */ + __size_t gl_offs; /* Slots to reserve in `gl_pathv'. */ + int gl_flags; /* Set to FLAGS, maybe | GLOB_MAGCHAR. */ + + /* If the GLOB_ALTDIRFUNC flag is set, the following functions + are used instead of the normal file access functions. */ + void (*gl_closedir) __PMT ((void *)); + struct dirent *(*gl_readdir) __PMT ((void *)); + __ptr_t (*gl_opendir) __PMT ((__const char *)); + int (*gl_lstat) __PMT ((__const char *, struct stat *)); +#if defined(VMS) && defined(__DECC) && !defined(_POSIX_C_SOURCE) + int (*gl_stat) __PMT ((__const char *, struct stat *, ...)); +#else + int (*gl_stat) __PMT ((__const char *, struct stat *)); +#endif + } glob_t; + +#ifdef _LARGEFILE64_SOURCE +struct stat64; +typedef struct + { + __size_t gl_pathc; + char **gl_pathv; + __size_t gl_offs; + int gl_flags; + + /* If the GLOB_ALTDIRFUNC flag is set, the following functions + are used instead of the normal file access functions. */ + void (*gl_closedir) __PMT ((void *)); + struct dirent64 *(*gl_readdir) __PMT ((void *)); + __ptr_t (*gl_opendir) __PMT ((__const char *)); + int (*gl_lstat) __PMT ((__const char *, struct stat64 *)); + int (*gl_stat) __PMT ((__const char *, struct stat64 *)); + } glob64_t; +#endif + +#if _FILE_OFFSET_BITS == 64 && __GNUC__ < 2 +# define glob glob64 +# define globfree globfree64 +#else +# ifdef _LARGEFILE64_SOURCE +extern int glob64 __P ((__const char *__pattern, int __flags, + int (*__errfunc) (__const char *, int), + glob64_t *__pglob)); + +extern void globfree64 __P ((glob64_t *__pglob)); +# endif +#endif + +/* Do glob searching for PATTERN, placing results in PGLOB. + The bits defined above may be set in FLAGS. + If a directory cannot be opened or read and ERRFUNC is not nil, + it is called with the pathname that caused the error, and the + `errno' value from the failing call; if it returns non-zero + `glob' returns GLOB_ABEND; if it returns zero, the error is ignored. + If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned. + Otherwise, `glob' returns zero. */ +#if _FILE_OFFSET_BITS != 64 || __GNUC__ < 2 +extern int glob __P ((__const char *__pattern, int __flags, + int (*__errfunc) (__const char *, int), + glob_t *__pglob)); + +/* Free storage allocated in PGLOB by a previous `glob' call. */ +extern void globfree __P ((glob_t *__pglob)); +#else +extern int glob __P ((__const char *__pattern, int __flags, + int (*__errfunc) (__const char *, int), + glob_t *__pglob)) __asm__ ("glob64"); + +extern void globfree __P ((glob_t *__pglob)) __asm__ ("globfree64"); +#endif + + +#ifdef _GNU_SOURCE +/* Return nonzero if PATTERN contains any metacharacters. + Metacharacters can be quoted with backslashes if QUOTE is nonzero. + + This function is not part of the interface specified by POSIX.2 + but several programs want to use it. */ +extern int glob_pattern_p __P ((__const char *__pattern, int __quote)); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* glob.h */ diff --git a/src/make-3.80/hash.c b/src/make-3.80/hash.c new file mode 100755 index 00000000..9083b60a --- /dev/null +++ b/src/make-3.80/hash.c @@ -0,0 +1,369 @@ +/* hash.c -- hash table maintenance + Copyright (C) 1995, 1999, 2002 Free Software Foundation, Inc. + Written by Greg McGary + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "make.h" +#include "hash.h" + +#define CALLOC(t, n) ((t *) calloc (sizeof (t), (n))) +#define MALLOC(t, n) ((t *) xmalloc (sizeof (t) * (n))) +#define REALLOC(o, t, n) ((t *) xrealloc ((o), sizeof (t) * (n))) +#define CLONE(o, t, n) ((t *) memcpy (MALLOC (t, (n)), (o), sizeof (t) * (n))) + +static void hash_rehash __P((struct hash_table* ht)); +static unsigned long round_up_2 __P((unsigned long rough)); + +/* Implement double hashing with open addressing. The table size is + always a power of two. The secondary (`increment') hash function + is forced to return an odd-value, in order to be relatively prime + to the table size. This guarantees that the increment can + potentially hit every slot in the table during collision + resolution. */ + +void *hash_deleted_item = &hash_deleted_item; + +/* Force the table size to be a power of two, possibly rounding up the + given size. */ + +void +hash_init (ht, size, hash_1, hash_2, hash_cmp) + struct hash_table* ht; + unsigned long size; + hash_func_t hash_1; + hash_func_t hash_2; + hash_cmp_func_t hash_cmp; +{ + ht->ht_size = round_up_2 (size); + ht->ht_empty_slots = ht->ht_size; + ht->ht_vec = (void**) CALLOC (struct token *, ht->ht_size); + if (ht->ht_vec == 0) + { + fprintf (stderr, _("can't allocate %ld bytes for hash table: memory exhausted"), + ht->ht_size * sizeof(struct token *)); + exit (1); + } + + ht->ht_capacity = ht->ht_size - (ht->ht_size / 16); /* 93.75% loading factor */ + ht->ht_fill = 0; + ht->ht_collisions = 0; + ht->ht_lookups = 0; + ht->ht_rehashes = 0; + ht->ht_hash_1 = hash_1; + ht->ht_hash_2 = hash_2; + ht->ht_compare = hash_cmp; +} + +/* Load an array of items into `ht'. */ + +void +hash_load (ht, item_table, cardinality, size) + struct hash_table* ht; + void *item_table; + unsigned long cardinality; + unsigned long size; +{ + char *items = (char *) item_table; + while (cardinality--) + { + hash_insert (ht, items); + items += size; + } +} + +/* Returns the address of the table slot matching `key'. If `key' is + not found, return the address of an empty slot suitable for + inserting `key'. The caller is responsible for incrementing + ht_fill on insertion. */ + +void ** +hash_find_slot (ht, key) + struct hash_table* ht; + void const *key; +{ + void **slot; + void **deleted_slot = 0; + unsigned int hash_2 = 0; + unsigned int hash_1 = (*ht->ht_hash_1) (key); + + ht->ht_lookups++; + for (;;) + { + hash_1 &= (ht->ht_size - 1); + slot = &ht->ht_vec[hash_1]; + + if (*slot == 0) + return (deleted_slot ? deleted_slot : slot); + if (*slot == hash_deleted_item) + { + if (deleted_slot == 0) + deleted_slot = slot; + } + else + { + if (key == *slot) + return slot; + if ((*ht->ht_compare) (key, *slot) == 0) + return slot; + ht->ht_collisions++; + } + if (!hash_2) + hash_2 = (*ht->ht_hash_2) (key) | 1; + hash_1 += hash_2; + } +} + +void * +hash_find_item (ht, key) + struct hash_table* ht; + void const *key; +{ + void **slot = hash_find_slot (ht, key); + return ((HASH_VACANT (*slot)) ? 0 : *slot); +} + +void * +hash_insert (ht, item) + struct hash_table* ht; + void *item; +{ + void **slot = hash_find_slot (ht, item); + void *old_item = slot ? *slot : 0; + hash_insert_at (ht, item, slot); + return ((HASH_VACANT (old_item)) ? 0 : old_item); +} + +void * +hash_insert_at (ht, item, slot) + struct hash_table* ht; + void *item; + void const *slot; +{ + void *old_item = *(void **) slot; + if (HASH_VACANT (old_item)) + { + ht->ht_fill++; + if (old_item == 0) + ht->ht_empty_slots--; + old_item = item; + } + *(void const **) slot = item; + if (ht->ht_empty_slots < ht->ht_size - ht->ht_capacity) + { + hash_rehash (ht); + return (void *) hash_find_slot (ht, item); + } + else + return (void *) slot; +} + +void * +hash_delete (ht, item) + struct hash_table* ht; + void const *item; +{ + void **slot = hash_find_slot (ht, item); + return hash_delete_at (ht, slot); +} + +void * +hash_delete_at (ht, slot) + struct hash_table* ht; + void const *slot; +{ + void *item = *(void **) slot; + if (!HASH_VACANT (item)) + { + *(void const **) slot = hash_deleted_item; + ht->ht_fill--; + return item; + } + else + return 0; +} + +void +hash_free_items (ht) + struct hash_table* ht; +{ + void **vec = ht->ht_vec; + void **end = &vec[ht->ht_size]; + for (; vec < end; vec++) + { + void *item = *vec; + if (!HASH_VACANT (item)) + free (item); + *vec = 0; + } + ht->ht_fill = 0; + ht->ht_empty_slots = ht->ht_size; +} + +void +hash_delete_items (ht) + struct hash_table* ht; +{ + void **vec = ht->ht_vec; + void **end = &vec[ht->ht_size]; + for (; vec < end; vec++) + *vec = 0; + ht->ht_fill = 0; + ht->ht_collisions = 0; + ht->ht_lookups = 0; + ht->ht_rehashes = 0; + ht->ht_empty_slots = ht->ht_size; +} + +void +hash_free (ht, free_items) + struct hash_table* ht; + int free_items; +{ + if (free_items) + hash_free_items (ht); + else + { + ht->ht_fill = 0; + ht->ht_empty_slots = ht->ht_size; + } + free (ht->ht_vec); + ht->ht_vec = 0; + ht->ht_capacity = 0; +} + +void +hash_map (ht, map) + struct hash_table *ht; + hash_map_func_t map; +{ + void **slot; + void **end = &ht->ht_vec[ht->ht_size]; + + for (slot = ht->ht_vec; slot < end; slot++) + { + if (!HASH_VACANT (*slot)) + (*map) (*slot); + } +} + +void +hash_map_arg (ht, map, arg) + struct hash_table *ht; + hash_map_arg_func_t map; + void *arg; +{ + void **slot; + void **end = &ht->ht_vec[ht->ht_size]; + + for (slot = ht->ht_vec; slot < end; slot++) + { + if (!HASH_VACANT (*slot)) + (*map) (*slot, arg); + } +} + +/* Double the size of the hash table in the event of overflow... */ + +static void +hash_rehash (ht) + struct hash_table* ht; +{ + unsigned long old_ht_size = ht->ht_size; + void **old_vec = ht->ht_vec; + void **ovp; + + if (ht->ht_fill >= ht->ht_capacity) + { + ht->ht_size *= 2; + ht->ht_capacity = ht->ht_size - (ht->ht_size >> 4); + } + ht->ht_rehashes++; + ht->ht_vec = (void **) CALLOC (struct token *, ht->ht_size); + + for (ovp = old_vec; ovp < &old_vec[old_ht_size]; ovp++) + { + if (! HASH_VACANT (*ovp)) + { + void **slot = hash_find_slot (ht, *ovp); + *slot = *ovp; + } + } + ht->ht_empty_slots = ht->ht_size - ht->ht_fill; + free (old_vec); +} + +void +hash_print_stats (ht, out_FILE) + struct hash_table *ht; + FILE *out_FILE; +{ + /* GKM FIXME: honor NO_FLOAT */ + fprintf (out_FILE, _("Load=%ld/%ld=%.0f%%, "), ht->ht_fill, ht->ht_size, + 100.0 * (double) ht->ht_fill / (double) ht->ht_size); + fprintf (out_FILE, _("Rehash=%d, "), ht->ht_rehashes); + fprintf (out_FILE, _("Collisions=%ld/%ld=%.0f%%"), ht->ht_collisions, ht->ht_lookups, + (ht->ht_lookups + ? (100.0 * (double) ht->ht_collisions / (double) ht->ht_lookups) + : 0)); +} + +/* Dump all items into a NULL-terminated vector. Use the + user-supplied vector, or malloc one. */ + +void ** +hash_dump (ht, vector_0, compare) + struct hash_table *ht; + void **vector_0; + qsort_cmp_t compare; +{ + void **vector; + void **slot; + void **end = &ht->ht_vec[ht->ht_size]; + + if (vector_0 == 0) + vector_0 = MALLOC (void *, ht->ht_fill + 1); + vector = vector_0; + + for (slot = ht->ht_vec; slot < end; slot++) + if (!HASH_VACANT (*slot)) + *vector++ = *slot; + *vector = 0; + + if (compare) + qsort (vector_0, ht->ht_fill, sizeof (void *), compare); + return vector_0; +} + +/* Round a given number up to the nearest power of 2. */ + +static unsigned long +round_up_2 (n) + unsigned long n; +{ + n |= (n >> 1); + n |= (n >> 2); + n |= (n >> 4); + n |= (n >> 8); + n |= (n >> 16); + +#if !defined(HAVE_LIMITS_H) || ULONG_MAX > 4294967295 + /* We only need this on systems where unsigned long is >32 bits. */ + n |= (n >> 32); +#endif + + return n + 1; +} diff --git a/src/make-3.80/hash.h b/src/make-3.80/hash.h new file mode 100755 index 00000000..405f1dab --- /dev/null +++ b/src/make-3.80/hash.h @@ -0,0 +1,233 @@ +/* hash.h -- decls for hash table + Copyright (C) 1995, 1999, 2002 Free Software Foundation, Inc. + Written by Greg McGary + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _hash_h_ +#define _hash_h_ + +#include +#include + +#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32 +# if !defined __GLIBC__ || !defined __P +# undef __P +# define __P(protos) protos +# endif +#else /* Not C++ or ANSI C. */ +# undef __P +# define __P(protos) () +/* We can get away without defining `const' here only because in this file + it is used only inside the prototype for `fnmatch', which is elided in + non-ANSI C where `const' is problematical. */ +#endif /* C++ or ANSI C. */ + +typedef unsigned long (*hash_func_t) __P((void const *key)); +typedef int (*hash_cmp_func_t) __P((void const *x, void const *y)); +typedef void (*hash_map_func_t) __P((void const *item)); +typedef void (*hash_map_arg_func_t) __P((void const *item, void *arg)); + +struct hash_table +{ + void **ht_vec; + unsigned long ht_size; /* total number of slots (power of 2) */ + unsigned long ht_capacity; /* usable slots, limited by loading-factor */ + unsigned long ht_fill; /* items in table */ + unsigned long ht_empty_slots; /* empty slots not including deleted slots */ + unsigned long ht_collisions; /* # of failed calls to comparison function */ + unsigned long ht_lookups; /* # of queries */ + unsigned int ht_rehashes; /* # of times we've expanded table */ + hash_func_t ht_hash_1; /* primary hash function */ + hash_func_t ht_hash_2; /* secondary hash function */ + hash_cmp_func_t ht_compare; /* comparison function */ +}; + +typedef int (*qsort_cmp_t) __P((void const *, void const *)); + +void hash_init __P((struct hash_table *ht, unsigned long size, + hash_func_t hash_1, hash_func_t hash_2, hash_cmp_func_t hash_cmp)); +void hash_load __P((struct hash_table *ht, void *item_table, + unsigned long cardinality, unsigned long size)); +void **hash_find_slot __P((struct hash_table *ht, void const *key)); +void *hash_find_item __P((struct hash_table *ht, void const *key)); +void *hash_insert __P((struct hash_table *ht, void *item)); +void *hash_insert_at __P((struct hash_table *ht, void *item, void const *slot)); +void *hash_delete __P((struct hash_table *ht, void const *item)); +void *hash_delete_at __P((struct hash_table *ht, void const *slot)); +void hash_delete_items __P((struct hash_table *ht)); +void hash_free_items __P((struct hash_table *ht)); +void hash_free __P((struct hash_table *ht, int free_items)); +void hash_map __P((struct hash_table *ht, hash_map_func_t map)); +void hash_map_arg __P((struct hash_table *ht, hash_map_arg_func_t map, void *arg)); +void hash_print_stats __P((struct hash_table *ht, FILE *out_FILE)); +void **hash_dump __P((struct hash_table *ht, void **vector_0, qsort_cmp_t compare)); + +extern void *hash_deleted_item; +#define HASH_VACANT(item) ((item) == 0 || (void *) (item) == hash_deleted_item) + + +/* hash and comparison macros for case-sensitive string keys. */ + +#define STRING_HASH_1(KEY, RESULT) do { \ + unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \ + while (*++_key_) \ + (RESULT) += (*_key_ << (_key_[1] & 0xf)); \ +} while (0) +#define return_STRING_HASH_1(KEY) do { \ + unsigned long _result_ = 0; \ + STRING_HASH_1 ((KEY), _result_); \ + return _result_; \ +} while (0) + +#define STRING_HASH_2(KEY, RESULT) do { \ + unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \ + while (*++_key_) \ + (RESULT) += (*_key_ << (_key_[1] & 0x7)); \ +} while (0) +#define return_STRING_HASH_2(KEY) do { \ + unsigned long _result_ = 0; \ + STRING_HASH_2 ((KEY), _result_); \ + return _result_; \ +} while (0) + +#define STRING_COMPARE(X, Y, RESULT) do { \ + RESULT = strcmp ((X), (Y)); \ +} while (0) +#define return_STRING_COMPARE(X, Y) do { \ + return strcmp ((X), (Y)); \ +} while (0) + + +#define STRING_N_HASH_1(KEY, N, RESULT) do { \ + unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \ + int _n_ = (N); \ + if (_n_) \ + while (--_n_ && *++_key_) \ + (RESULT) += (*_key_ << (_key_[1] & 0xf)); \ + (RESULT) += *++_key_; \ +} while (0) +#define return_STRING_N_HASH_1(KEY, N) do { \ + unsigned long _result_ = 0; \ + STRING_N_HASH_1 ((KEY), (N), _result_); \ + return _result_; \ +} while (0) + +#define STRING_N_HASH_2(KEY, N, RESULT) do { \ + unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \ + int _n_ = (N); \ + if (_n_) \ + while (--_n_ && *++_key_) \ + (RESULT) += (*_key_ << (_key_[1] & 0x7)); \ + (RESULT) += *++_key_; \ +} while (0) +#define return_STRING_N_HASH_2(KEY, N) do { \ + unsigned long _result_ = 0; \ + STRING_N_HASH_2 ((KEY), (N), _result_); \ + return _result_; \ +} while (0) + +#define STRING_N_COMPARE(X, Y, N, RESULT) do { \ + RESULT = strncmp ((X), (Y), (N)); \ +} while (0) +#define return_STRING_N_COMPARE(X, Y, N) do { \ + return strncmp ((X), (Y), (N)); \ +} while (0) + +#ifdef HAVE_CASE_INSENSITIVE_FS + +/* hash and comparison macros for case-insensitive string _key_s. */ + +#define ISTRING_HASH_1(KEY, RESULT) do { \ + unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \ + while (*++_key_) \ + (RESULT) += ((isupper (*_key_) ? tolower (*_key_) : *_key_) << (_key_[1] & 0xf)); \ +} while (0) +#define return_ISTRING_HASH_1(KEY) do { \ + unsigned long _result_ = 0; \ + ISTRING_HASH_1 ((KEY), _result_); \ + return _result_; \ +} while (0) + +#define ISTRING_HASH_2(KEY, RESULT) do { \ + unsigned char const *_key_ = (unsigned char const *) (KEY) - 1; \ + while (*++_key_) \ + (RESULT) += ((isupper (*_key_) ? tolower (*_key_) : *_key_) << (_key_[1] & 0x7)); \ +} while (0) +#define return_ISTRING_HASH_2(KEY) do { \ + unsigned long _result_ = 0; \ + ISTRING_HASH_2 ((KEY), _result_); \ + return _result_; \ +} while (0) + +#define ISTRING_COMPARE(X, Y, RESULT) do { \ + RESULT = strcmpi ((X), (Y)); \ +} while (0) +#define return_ISTRING_COMPARE(X, Y) do { \ + return strcmpi ((X), (Y)); \ +} while (0) + +#else + +#define ISTRING_HASH_1(KEY, RESULT) STRING_HASH_1 ((KEY), (RESULT)) +#define return_ISTRING_HASH_1(KEY) return_STRING_HASH_1 (KEY) + +#define ISTRING_HASH_2(KEY, RESULT) STRING_HASH_2 ((KEY), (RESULT)) +#define return_ISTRING_HASH_2(KEY) return_STRING_HASH_2 (KEY) + +#define ISTRING_COMPARE(X, Y, RESULT) STRING_COMPARE ((X), (Y), (RESULT)) +#define return_ISTRING_COMPARE(X, Y) return_STRING_COMPARE ((X), (Y)) + +#endif + +/* hash and comparison macros for integer _key_s. */ + +#define INTEGER_HASH_1(KEY, RESULT) do { \ + (RESULT) += ((unsigned long)(KEY)); \ +} while (0) +#define return_INTEGER_HASH_1(KEY) do { \ + unsigned long _result_ = 0; \ + INTEGER_HASH_1 ((KEY), _result_); \ + return _result_; \ +} while (0) + +#define INTEGER_HASH_2(KEY, RESULT) do { \ + (RESULT) += ~((unsigned long)(KEY)); \ +} while (0) +#define return_INTEGER_HASH_2(KEY) do { \ + unsigned long _result_ = 0; \ + INTEGER_HASH_2 ((KEY), _result_); \ + return _result_; \ +} while (0) + +#define INTEGER_COMPARE(X, Y, RESULT) do { \ + (RESULT) = X - Y; \ +} while (0) +#define return_INTEGER_COMPARE(X, Y) do { \ + int _result_; \ + INTEGER_COMPARE (X, Y, _result_); \ + return _result_; \ +} while (0) + +/* hash and comparison macros for address keys. */ + +#define ADDRESS_HASH_1(KEY, RESULT) INTEGER_HASH_1 (((unsigned long)(KEY)) >> 3, (RESULT)) +#define ADDRESS_HASH_2(KEY, RESULT) INTEGER_HASH_2 (((unsigned long)(KEY)) >> 3, (RESULT)) +#define ADDRESS_COMPARE(X, Y, RESULT) INTEGER_COMPARE ((X), (Y), (RESULT)) +#define return_ADDRESS_HASH_1(KEY) return_INTEGER_HASH_1 (((unsigned long)(KEY)) >> 3) +#define return_ADDRESS_HASH_2(KEY) return_INTEGER_HASH_2 (((unsigned long)(KEY)) >> 3) +#define return_ADDRESS_COMPARE(X, Y) return_INTEGER_COMPARE ((X), (Y)) + +#endif /* not _hash_h_ */ diff --git a/src/make-3.80/implicit.c b/src/make-3.80/implicit.c new file mode 100755 index 00000000..857895d7 --- /dev/null +++ b/src/make-3.80/implicit.c @@ -0,0 +1,635 @@ +/* Implicit rule searching for GNU Make. +Copyright (C) 1988,89,90,91,92,93,94,97,2000 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "rule.h" +#include "dep.h" +#include "filedef.h" +#include "debug.h" + +static int pattern_search PARAMS ((struct file *file, int archive, unsigned int depth, + unsigned int recursions)); + +/* For a FILE which has no commands specified, try to figure out some + from the implicit pattern rules. + Returns 1 if a suitable implicit rule was found, + after modifying FILE to contain the appropriate commands and deps, + or returns 0 if no implicit rule was found. */ + +int +try_implicit_rule (file, depth) + struct file *file; + unsigned int depth; +{ + DBF (DB_IMPLICIT, _("Looking for an implicit rule for `%s'.\n")); + + /* The order of these searches was previously reversed. My logic now is + that since the non-archive search uses more information in the target + (the archive search omits the archive name), it is more specific and + should come first. */ + + if (pattern_search (file, 0, depth, 0)) + return 1; + +#ifndef NO_ARCHIVES + /* If this is an archive member reference, use just the + archive member name to search for implicit rules. */ + if (ar_name (file->name)) + { + DBF (DB_IMPLICIT, + _("Looking for archive-member implicit rule for `%s'.\n")); + if (pattern_search (file, 1, depth, 0)) + return 1; + } +#endif + + return 0; +} + + +/* Search the pattern rules for a rule with an existing dependency to make + FILE. If a rule is found, the appropriate commands and deps are put in FILE + and 1 is returned. If not, 0 is returned. + + If ARCHIVE is nonzero, FILE->name is of the form "LIB(MEMBER)". A rule for + "(MEMBER)" will be searched for, and "(MEMBER)" will not be chopped up into + directory and filename parts. + + If an intermediate file is found by pattern search, the intermediate file + is set up as a target by the recursive call and is also made a dependency + of FILE. + + DEPTH is used for debugging messages. */ + +static int +pattern_search (file, archive, depth, recursions) + struct file *file; + int archive; + unsigned int depth; + unsigned int recursions; +{ + /* Filename we are searching for a rule for. */ + char *filename = archive ? strchr (file->name, '(') : file->name; + + /* Length of FILENAME. */ + unsigned int namelen = strlen (filename); + + /* The last slash in FILENAME (or nil if there is none). */ + char *lastslash; + + /* This is a file-object used as an argument in + recursive calls. It never contains any data + except during a recursive call. */ + struct file *intermediate_file = 0; + + /* List of dependencies found recursively. */ + struct file **intermediate_files + = (struct file **) xmalloc (max_pattern_deps * sizeof (struct file *)); + + /* List of the patterns used to find intermediate files. */ + char **intermediate_patterns + = (char **) alloca (max_pattern_deps * sizeof (char *)); + + /* This buffer records all the dependencies actually found for a rule. */ + char **found_files = (char **) alloca (max_pattern_deps * sizeof (char *)); + /* Number of dep names now in FOUND_FILES. */ + unsigned int deps_found = 0; + + /* Names of possible dependencies are constructed in this buffer. */ + register char *depname = (char *) alloca (namelen + max_pattern_dep_length); + + /* The start and length of the stem of FILENAME for the current rule. */ + register char *stem = 0; + register unsigned int stemlen = 0; + register unsigned int fullstemlen = 0; + + /* Buffer in which we store all the rules that are possibly applicable. */ + struct rule **tryrules + = (struct rule **) xmalloc (num_pattern_rules * max_pattern_targets + * sizeof (struct rule *)); + + /* Number of valid elements in TRYRULES. */ + unsigned int nrules; + + /* The numbers of the rule targets of each rule + in TRYRULES that matched the target file. */ + unsigned int *matches + = (unsigned int *) alloca (num_pattern_rules * sizeof (unsigned int)); + + /* Each element is nonzero if LASTSLASH was used in + matching the corresponding element of TRYRULES. */ + char *checked_lastslash + = (char *) alloca (num_pattern_rules * sizeof (char)); + + /* The index in TRYRULES of the rule we found. */ + unsigned int foundrule; + + /* Nonzero if should consider intermediate files as dependencies. */ + int intermed_ok; + + /* Nonzero if we have matched a pattern-rule target + that is not just `%'. */ + int specific_rule_matched = 0; + + register unsigned int i = 0; /* uninit checks OK */ + register struct rule *rule; + register struct dep *dep; + + char *p, *vp; + +#ifndef NO_ARCHIVES + if (archive || ar_name (filename)) + lastslash = 0; + else +#endif + { + /* Set LASTSLASH to point at the last slash in FILENAME + but not counting any slash at the end. (foo/bar/ counts as + bar/ in directory foo/, not empty in directory foo/bar/.) */ +#ifdef VMS + lastslash = strrchr (filename, ']'); + if (lastslash == 0) + lastslash = strrchr (filename, ':'); +#else + lastslash = strrchr (filename, '/'); +#ifdef HAVE_DOS_PATHS + /* Handle backslashes (possibly mixed with forward slashes) + and the case of "d:file". */ + { + char *bslash = strrchr (filename, '\\'); + if (lastslash == 0 || bslash > lastslash) + lastslash = bslash; + if (lastslash == 0 && filename[0] && filename[1] == ':') + lastslash = filename + 1; + } +#endif +#endif + if (lastslash != 0 && lastslash[1] == '\0') + lastslash = 0; + } + + /* First see which pattern rules match this target + and may be considered. Put them in TRYRULES. */ + + nrules = 0; + for (rule = pattern_rules; rule != 0; rule = rule->next) + { + /* If the pattern rule has deps but no commands, ignore it. + Users cancel built-in rules by redefining them without commands. */ + if (rule->deps != 0 && rule->cmds == 0) + continue; + + /* If this rule is in use by a parent pattern_search, + don't use it here. */ + if (rule->in_use) + { + DBS (DB_IMPLICIT, (_("Avoiding implicit rule recursion.\n"))); + continue; + } + + for (i = 0; rule->targets[i] != 0; ++i) + { + char *target = rule->targets[i]; + char *suffix = rule->suffixes[i]; + int check_lastslash; + + /* Rules that can match any filename and are not terminal + are ignored if we're recursing, so that they cannot be + intermediate files. */ + if (recursions > 0 && target[1] == '\0' && !rule->terminal) + continue; + + if (rule->lens[i] > namelen) + /* It can't possibly match. */ + continue; + + /* From the lengths of the filename and the pattern parts, + find the stem: the part of the filename that matches the %. */ + stem = filename + (suffix - target - 1); + stemlen = namelen - rule->lens[i] + 1; + + /* Set CHECK_LASTSLASH if FILENAME contains a directory + prefix and the target pattern does not contain a slash. */ + +#ifdef VMS + check_lastslash = lastslash != 0 + && ((strchr (target, ']') == 0) + && (strchr (target, ':') == 0)); +#else + check_lastslash = lastslash != 0 && strchr (target, '/') == 0; +#endif + if (check_lastslash) + { + /* In that case, don't include the + directory prefix in STEM here. */ + unsigned int difference = lastslash - filename + 1; + if (difference > stemlen) + continue; + stemlen -= difference; + stem += difference; + } + + /* Check that the rule pattern matches the text before the stem. */ + if (check_lastslash) + { + if (stem > (lastslash + 1) + && !strneq (target, lastslash + 1, stem - lastslash - 1)) + continue; + } + else if (stem > filename + && !strneq (target, filename, stem - filename)) + continue; + + /* Check that the rule pattern matches the text after the stem. + We could test simply use streq, but this way we compare the + first two characters immediately. This saves time in the very + common case where the first character matches because it is a + period. */ + if (*suffix != stem[stemlen] + || (*suffix != '\0' && !streq (&suffix[1], &stem[stemlen + 1]))) + continue; + + /* Record if we match a rule that not all filenames will match. */ + if (target[1] != '\0') + specific_rule_matched = 1; + + /* A rule with no dependencies and no commands exists solely to set + specific_rule_matched when it matches. Don't try to use it. */ + if (rule->deps == 0 && rule->cmds == 0) + continue; + + /* Record this rule in TRYRULES and the index of the matching + target in MATCHES. If several targets of the same rule match, + that rule will be in TRYRULES more than once. */ + tryrules[nrules] = rule; + matches[nrules] = i; + checked_lastslash[nrules] = check_lastslash; + ++nrules; + } + } + + /* If we have found a matching rule that won't match all filenames, + retroactively reject any non-"terminal" rules that do always match. */ + if (specific_rule_matched) + for (i = 0; i < nrules; ++i) + if (!tryrules[i]->terminal) + { + register unsigned int j; + for (j = 0; tryrules[i]->targets[j] != 0; ++j) + if (tryrules[i]->targets[j][1] == '\0') + break; + if (tryrules[i]->targets[j] != 0) + tryrules[i] = 0; + } + + /* Try each rule once without intermediate files, then once with them. */ + for (intermed_ok = 0; intermed_ok == !!intermed_ok; ++intermed_ok) + { + /* Try each pattern rule till we find one that applies. + If it does, copy the names of its dependencies (as substituted) + and store them in FOUND_FILES. DEPS_FOUND is the number of them. */ + + for (i = 0; i < nrules; i++) + { + int check_lastslash; + + rule = tryrules[i]; + + /* RULE is nil when we discover that a rule, + already placed in TRYRULES, should not be applied. */ + if (rule == 0) + continue; + + /* Reject any terminal rules if we're + looking to make intermediate files. */ + if (intermed_ok && rule->terminal) + continue; + + /* Mark this rule as in use so a recursive + pattern_search won't try to use it. */ + rule->in_use = 1; + + /* From the lengths of the filename and the matching pattern parts, + find the stem: the part of the filename that matches the %. */ + stem = filename + + (rule->suffixes[matches[i]] - rule->targets[matches[i]]) - 1; + stemlen = namelen - rule->lens[matches[i]] + 1; + check_lastslash = checked_lastslash[i]; + if (check_lastslash) + { + stem += lastslash - filename + 1; + stemlen -= (lastslash - filename) + 1; + } + + DBS (DB_IMPLICIT, (_("Trying pattern rule with stem `%.*s'.\n"), + (int) stemlen, stem)); + + /* Try each dependency; see if it "exists". */ + + deps_found = 0; + for (dep = rule->deps; dep != 0; dep = dep->next) + { + /* If the dependency name has a %, substitute the stem. */ + p = strchr (dep_name (dep), '%'); + if (p != 0) + { + register unsigned int i; + if (check_lastslash) + { + /* Copy directory name from the original FILENAME. */ + i = lastslash - filename + 1; + bcopy (filename, depname, i); + } + else + i = 0; + bcopy (dep_name (dep), depname + i, p - dep_name (dep)); + i += p - dep_name (dep); + bcopy (stem, depname + i, stemlen); + i += stemlen; + strcpy (depname + i, p + 1); + p = depname; + } + else + p = dep_name (dep); + + /* P is now the actual dependency name as substituted. */ + + if (file_impossible_p (p)) + { + /* If this dependency has already been ruled + "impossible", then the rule fails and don't + bother trying it on the second pass either + since we know that will fail too. */ + DBS (DB_IMPLICIT, + (p == depname + ? _("Rejecting impossible implicit prerequisite `%s'.\n") + : _("Rejecting impossible rule prerequisite `%s'.\n"), + p)); + tryrules[i] = 0; + break; + } + + intermediate_files[deps_found] = 0; + + DBS (DB_IMPLICIT, + (p == depname + ? _("Trying implicit prerequisite `%s'.\n") + : _("Trying rule prerequisite `%s'.\n"), p)); + + /* The DEP->changed flag says that this dependency resides in a + nonexistent directory. So we normally can skip looking for + the file. However, if CHECK_LASTSLASH is set, then the + dependency file we are actually looking for is in a different + directory (the one gotten by prepending FILENAME's directory), + so it might actually exist. */ + + if (lookup_file (p) != 0 + || ((!dep->changed || check_lastslash) && file_exists_p (p))) + { + found_files[deps_found++] = xstrdup (p); + continue; + } + /* This code, given FILENAME = "lib/foo.o", dependency name + "lib/foo.c", and VPATH=src, searches for "src/lib/foo.c". */ + vp = p; + if (vpath_search (&vp, (FILE_TIMESTAMP *) 0)) + { + DBS (DB_IMPLICIT, + (_("Found prerequisite `%s' as VPATH `%s'\n"), p, vp)); + strcpy (vp, p); + found_files[deps_found++] = vp; + continue; + } + + /* We could not find the file in any place we should look. + Try to make this dependency as an intermediate file, + but only on the second pass. */ + + if (intermed_ok) + { + if (intermediate_file == 0) + intermediate_file + = (struct file *) alloca (sizeof (struct file)); + + DBS (DB_IMPLICIT, + (_("Looking for a rule with intermediate file `%s'.\n"), + p)); + + bzero ((char *) intermediate_file, sizeof (struct file)); + intermediate_file->name = p; + if (pattern_search (intermediate_file, 0, depth + 1, + recursions + 1)) + { + p = xstrdup (p); + intermediate_patterns[deps_found] + = intermediate_file->name; + intermediate_file->name = p; + intermediate_files[deps_found] = intermediate_file; + intermediate_file = 0; + /* Allocate an extra copy to go in FOUND_FILES, + because every elt of FOUND_FILES is consumed + or freed later. */ + found_files[deps_found] = xstrdup (p); + ++deps_found; + continue; + } + + /* If we have tried to find P as an intermediate + file and failed, mark that name as impossible + so we won't go through the search again later. */ + file_impossible (p); + } + + /* A dependency of this rule does not exist. + Therefore, this rule fails. */ + break; + } + + /* This rule is no longer `in use' for recursive searches. */ + rule->in_use = 0; + + if (dep != 0) + { + /* This pattern rule does not apply. + If some of its dependencies succeeded, + free the data structure describing them. */ + while (deps_found-- > 0) + { + register struct file *f = intermediate_files[deps_found]; + free (found_files[deps_found]); + if (f != 0 + && (f->stem < f->name + || f->stem > f->name + strlen (f->name))) + free (f->stem); + } + } + else + /* This pattern rule does apply. Stop looking for one. */ + break; + } + + /* If we found an applicable rule without + intermediate files, don't try with them. */ + if (i < nrules) + break; + + rule = 0; + } + + /* RULE is nil if the loop went all the way + through the list and everything failed. */ + if (rule == 0) + goto done; + + foundrule = i; + + /* If we are recursing, store the pattern that matched + FILENAME in FILE->name for use in upper levels. */ + + if (recursions > 0) + /* Kludge-o-matic */ + file->name = rule->targets[matches[foundrule]]; + + /* FOUND_FILES lists the dependencies for the rule we found. + This includes the intermediate files, if any. + Convert them into entries on the deps-chain of FILE. */ + + while (deps_found-- > 0) + { + register char *s; + + if (intermediate_files[deps_found] != 0) + { + /* If we need to use an intermediate file, + make sure it is entered as a target, with the info that was + found for it in the recursive pattern_search call. + We know that the intermediate file did not already exist as + a target; therefore we can assume that the deps and cmds + of F below are null before we change them. */ + + struct file *imf = intermediate_files[deps_found]; + register struct file *f = enter_file (imf->name); + f->deps = imf->deps; + f->cmds = imf->cmds; + f->stem = imf->stem; + f->also_make = imf->also_make; + imf = lookup_file (intermediate_patterns[deps_found]); + if (imf != 0 && imf->precious) + f->precious = 1; + f->intermediate = 1; + f->tried_implicit = 1; + for (dep = f->deps; dep != 0; dep = dep->next) + { + dep->file = enter_file (dep->name); + /* enter_file uses dep->name _if_ we created a new file. */ + if (dep->name != dep->file->name) + free (dep->name); + dep->name = 0; + dep->file->tried_implicit |= dep->changed; + } + } + + dep = (struct dep *) xmalloc (sizeof (struct dep)); + dep->ignore_mtime = 0; + s = found_files[deps_found]; + if (recursions == 0) + { + dep->name = 0; + dep->file = lookup_file (s); + if (dep->file == 0) + /* enter_file consumes S's storage. */ + dep->file = enter_file (s); + else + /* A copy of S is already allocated in DEP->file->name. + So we can free S. */ + free (s); + } + else + { + dep->name = s; + dep->file = 0; + dep->changed = 0; + } + if (intermediate_files[deps_found] == 0 && tryrules[foundrule]->terminal) + { + /* If the file actually existed (was not an intermediate file), + and the rule that found it was a terminal one, then we want + to mark the found file so that it will not have implicit rule + search done for it. If we are not entering a `struct file' for + it now, we indicate this with the `changed' flag. */ + if (dep->file == 0) + dep->changed = 1; + else + dep->file->tried_implicit = 1; + } + dep->next = file->deps; + file->deps = dep; + } + + if (!checked_lastslash[foundrule]) + { + /* Always allocate new storage, since STEM might be + on the stack for an intermediate file. */ + file->stem = savestring (stem, stemlen); + fullstemlen = stemlen; + } + else + { + int dirlen = (lastslash + 1) - filename; + + /* We want to prepend the directory from + the original FILENAME onto the stem. */ + fullstemlen = dirlen + stemlen; + file->stem = (char *) xmalloc (fullstemlen + 1); + bcopy (filename, file->stem, dirlen); + bcopy (stem, file->stem + dirlen, stemlen); + file->stem[fullstemlen] = '\0'; + } + + file->cmds = rule->cmds; + + /* If this rule builds other targets, too, put the others into FILE's + `also_make' member. */ + + if (rule->targets[1] != 0) + for (i = 0; rule->targets[i] != 0; ++i) + if (i != matches[foundrule]) + { + struct dep *new = (struct dep *) xmalloc (sizeof (struct dep)); + /* GKM FIMXE: handle '|' here too */ + new->ignore_mtime = 0; + new->name = p = (char *) xmalloc (rule->lens[i] + fullstemlen + 1); + bcopy (rule->targets[i], p, + rule->suffixes[i] - rule->targets[i] - 1); + p += rule->suffixes[i] - rule->targets[i] - 1; + bcopy (file->stem, p, fullstemlen); + p += fullstemlen; + bcopy (rule->suffixes[i], p, + rule->lens[i] - (rule->suffixes[i] - rule->targets[i]) + 1); + new->file = enter_file (new->name); + new->next = file->also_make; + file->also_make = new; + } + + done: + free (intermediate_files); + free (tryrules); + + return rule != 0; +} diff --git a/src/make-3.80/job.c b/src/make-3.80/job.c new file mode 100755 index 00000000..63456a7a --- /dev/null +++ b/src/make-3.80/job.c @@ -0,0 +1,3110 @@ +/* Job execution and handling for GNU Make. +Copyright (C) 1988,89,90,91,92,93,94,95,96,97,99 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" + +#include + +#include "job.h" +#include "debug.h" +#include "filedef.h" +#include "commands.h" +#include "variable.h" +#include "debug.h" + +#include + +/* Default shell to use. */ +#ifdef WINDOWS32 +char *default_shell = "sh.exe"; +int no_default_sh_exe = 1; +int batch_mode_shell = 1; +#else /* WINDOWS32 */ +# ifdef _AMIGA +char default_shell[] = ""; +extern int MyExecute (char **); +# else /* _AMIGA */ +# ifdef __MSDOS__ +/* The default shell is a pointer so we can change it if Makefile + says so. It is without an explicit path so we get a chance + to search the $PATH for it (since MSDOS doesn't have standard + directories we could trust). */ +char *default_shell = "command.com"; +# else /* __MSDOS__ */ +# ifdef VMS +# include +char default_shell[] = ""; +# else +char default_shell[] = "/bin/sh"; +# endif /* VMS */ +# endif /* __MSDOS__ */ +int batch_mode_shell = 0; +# endif /* _AMIGA */ +#endif /* WINDOWS32 */ + +#ifdef __MSDOS__ +# include +static int execute_by_shell; +static int dos_pid = 123; +int dos_status; +int dos_command_running; +#endif /* __MSDOS__ */ + +#ifdef _AMIGA +# include +static int amiga_pid = 123; +static int amiga_status; +static char amiga_bname[32]; +static int amiga_batch_file; +#endif /* Amiga. */ + +#ifdef VMS +# ifndef __GNUC__ +# include +# endif +# include +# include +#endif + +#ifdef WINDOWS32 +# include +# include +# include +# include "sub_proc.h" +# include "w32err.h" +# include "pathstuff.h" +#endif /* WINDOWS32 */ + +#ifdef HAVE_FCNTL_H +# include +#else +# include +#endif + +#if defined (HAVE_SYS_WAIT_H) || defined (HAVE_UNION_WAIT) +# include +#endif + +#ifdef HAVE_WAITPID +# define WAIT_NOHANG(status) waitpid (-1, (status), WNOHANG) +#else /* Don't have waitpid. */ +# ifdef HAVE_WAIT3 +# ifndef wait3 +extern int wait3 (); +# endif +# define WAIT_NOHANG(status) wait3 ((status), WNOHANG, (struct rusage *) 0) +# endif /* Have wait3. */ +#endif /* Have waitpid. */ + +#if !defined (wait) && !defined (POSIX) +extern int wait (); +#endif + +#ifndef HAVE_UNION_WAIT + +# define WAIT_T int + +# ifndef WTERMSIG +# define WTERMSIG(x) ((x) & 0x7f) +# endif +# ifndef WCOREDUMP +# define WCOREDUMP(x) ((x) & 0x80) +# endif +# ifndef WEXITSTATUS +# define WEXITSTATUS(x) (((x) >> 8) & 0xff) +# endif +# ifndef WIFSIGNALED +# define WIFSIGNALED(x) (WTERMSIG (x) != 0) +# endif +# ifndef WIFEXITED +# define WIFEXITED(x) (WTERMSIG (x) == 0) +# endif + +#else /* Have `union wait'. */ + +# define WAIT_T union wait +# ifndef WTERMSIG +# define WTERMSIG(x) ((x).w_termsig) +# endif +# ifndef WCOREDUMP +# define WCOREDUMP(x) ((x).w_coredump) +# endif +# ifndef WEXITSTATUS +# define WEXITSTATUS(x) ((x).w_retcode) +# endif +# ifndef WIFSIGNALED +# define WIFSIGNALED(x) (WTERMSIG(x) != 0) +# endif +# ifndef WIFEXITED +# define WIFEXITED(x) (WTERMSIG(x) == 0) +# endif + +#endif /* Don't have `union wait'. */ + +/* How to set close-on-exec for a file descriptor. */ + +#if !defined F_SETFD +# define CLOSE_ON_EXEC(_d) +#else +# ifndef FD_CLOEXEC +# define FD_CLOEXEC 1 +# endif +# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC) +#endif + +#ifdef VMS +static int vms_jobsefnmask = 0; +#endif /* !VMS */ + +#ifndef HAVE_UNISTD_H +extern int dup2 (); +extern int execve (); +extern void _exit (); +# ifndef VMS +extern int geteuid (); +extern int getegid (); +extern int setgid (); +extern int getgid (); +# endif +#endif + +extern char *allocated_variable_expand_for_file PARAMS ((char *line, struct file *file)); + +extern int getloadavg PARAMS ((double loadavg[], int nelem)); +extern int start_remote_job PARAMS ((char **argv, char **envp, int stdin_fd, + int *is_remote, int *id_ptr, int *used_stdin)); +extern int start_remote_job_p PARAMS ((int)); +extern int remote_status PARAMS ((int *exit_code_ptr, int *signal_ptr, + int *coredump_ptr, int block)); + +RETSIGTYPE child_handler PARAMS ((int)); +static void free_child PARAMS ((struct child *)); +static void start_job_command PARAMS ((struct child *child)); +static int load_too_high PARAMS ((void)); +static int job_next_command PARAMS ((struct child *)); +static int start_waiting_job PARAMS ((struct child *)); +#ifdef VMS +static void vmsWaitForChildren PARAMS ((int *)); +#endif + +/* Chain of all live (or recently deceased) children. */ + +struct child *children = 0; + +/* Number of children currently running. */ + +unsigned int job_slots_used = 0; + +/* Nonzero if the `good' standard input is in use. */ + +static int good_stdin_used = 0; + +/* Chain of children waiting to run until the load average goes down. */ + +static struct child *waiting_jobs = 0; + +/* Non-zero if we use a *real* shell (always so on Unix). */ + +int unixy_shell = 1; + + +#ifdef WINDOWS32 +/* + * The macro which references this function is defined in make.h. + */ +int w32_kill(int pid, int sig) +{ + return ((process_kill(pid, sig) == TRUE) ? 0 : -1); +} +#endif /* WINDOWS32 */ + +/* Write an error message describing the exit status given in + EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME. + Append "(ignored)" if IGNORED is nonzero. */ + +static void +child_error (target_name, exit_code, exit_sig, coredump, ignored) + char *target_name; + int exit_code, exit_sig, coredump; + int ignored; +{ + if (ignored && silent_flag) + return; + +#ifdef VMS + if (!(exit_code & 1)) + error (NILF, + (ignored ? _("*** [%s] Error 0x%x (ignored)") + : _("*** [%s] Error 0x%x")), + target_name, exit_code); +#else + if (exit_sig == 0) + error (NILF, ignored ? _("[%s] Error %d (ignored)") : + _("*** [%s] Error %d"), + target_name, exit_code); + else + error (NILF, "*** [%s] %s%s", + target_name, strsignal (exit_sig), + coredump ? _(" (core dumped)") : ""); +#endif /* VMS */ +} + +#ifdef VMS +/* Wait for nchildren children to terminate */ +static void +vmsWaitForChildren(int *status) +{ + while (1) + { + if (!vms_jobsefnmask) + { + *status = 0; + return; + } + + *status = sys$wflor (32, vms_jobsefnmask); + } + return; +} + +/* Set up IO redirection. */ + +char * +vms_redirect (desc, fname, ibuf) + struct dsc$descriptor_s *desc; + char *fname; + char *ibuf; +{ + char *fptr; + extern char *vmsify (); + + ibuf++; + while (isspace ((unsigned char)*ibuf)) + ibuf++; + fptr = ibuf; + while (*ibuf && !isspace ((unsigned char)*ibuf)) + ibuf++; + *ibuf = 0; + if (strcmp (fptr, "/dev/null") != 0) + { + strcpy (fname, vmsify (fptr, 0)); + if (strchr (fname, '.') == 0) + strcat (fname, "."); + } + desc->dsc$w_length = strlen(fname); + desc->dsc$a_pointer = fname; + desc->dsc$b_dtype = DSC$K_DTYPE_T; + desc->dsc$b_class = DSC$K_CLASS_S; + + if (*fname == 0) + printf (_("Warning: Empty redirection\n")); + return ibuf; +} + + +/* + found apostrophe at (p-1) + + inc p until after closing apostrophe. */ + +static char * +handle_apos (char *p) +{ + int alast; + int inside; + +#define SEPCHARS ",/()= " + + inside = 0; + + while (*p != 0) + { + if (*p == '"') + { + if (inside) + { + while ((alast > 0) + && (*p == '"')) + { + p++; + alast--; + } + if (alast == 0) + inside = 0; + else + { + fprintf (stderr, _("Syntax error, still inside '\"'\n")); + exit (3); + } + } + else + { + p++; + if (strchr (SEPCHARS, *p)) + break; + inside = 1; + alast = 1; + while (*p == '"') + { + alast++; + p++; + } + } + } + else + p++; + } + + return p; +} + +#endif + + +/* Handle a dead child. This handler may or may not ever be installed. + + If we're using the jobserver feature, we need it. First, installing it + ensures the read will interrupt on SIGCHLD. Second, we close the dup'd + read FD to ensure we don't enter another blocking read without reaping all + the dead children. In this case we don't need the dead_children count. + + If we don't have either waitpid or wait3, then make is unreliable, but we + use the dead_children count to reap children as best we can. */ + +static unsigned int dead_children = 0; + +RETSIGTYPE +child_handler (sig) + int sig; +{ + ++dead_children; + + if (job_rfd >= 0) + { + close (job_rfd); + job_rfd = -1; + } + + DB (DB_JOBS, (_("Got a SIGCHLD; %u unreaped children.\n"), dead_children)); +} + + +extern int shell_function_pid, shell_function_completed; + +/* Reap all dead children, storing the returned status and the new command + state (`cs_finished') in the `file' member of the `struct child' for the + dead child, and removing the child from the chain. In addition, if BLOCK + nonzero, we block in this function until we've reaped at least one + complete child, waiting for it to die if necessary. If ERR is nonzero, + print an error message first. */ + +void +reap_children (block, err) + int block, err; +{ + WAIT_T status; + /* Initially, assume we have some. */ + int reap_more = 1; + +#ifdef WAIT_NOHANG +# define REAP_MORE reap_more +#else +# define REAP_MORE dead_children +#endif + + /* As long as: + + We have at least one child outstanding OR a shell function in progress, + AND + We're blocking for a complete child OR there are more children to reap + + we'll keep reaping children. */ + + while ((children != 0 || shell_function_pid != 0) + && (block || REAP_MORE)) + { + int remote = 0; + register int pid; + int exit_code, exit_sig, coredump; + register struct child *lastc, *c; + int child_failed; + int any_remote, any_local; + + if (err && block) + { + /* We might block for a while, so let the user know why. */ + fflush (stdout); + error (NILF, _("*** Waiting for unfinished jobs....")); + } + + /* We have one less dead child to reap. As noted in + child_handler() above, this count is completely unimportant for + all modern, POSIX-y systems that support wait3() or waitpid(). + The rest of this comment below applies only to early, broken + pre-POSIX systems. We keep the count only because... it's there... + + The test and decrement are not atomic; if it is compiled into: + register = dead_children - 1; + dead_children = register; + a SIGCHLD could come between the two instructions. + child_handler increments dead_children. + The second instruction here would lose that increment. But the + only effect of dead_children being wrong is that we might wait + longer than necessary to reap a child, and lose some parallelism; + and we might print the "Waiting for unfinished jobs" message above + when not necessary. */ + + if (dead_children > 0) + --dead_children; + + any_remote = 0; + any_local = shell_function_pid != 0; + for (c = children; c != 0; c = c->next) + { + any_remote |= c->remote; + any_local |= ! c->remote; + DB (DB_JOBS, (_("Live child 0x%08lx (%s) PID %ld %s\n"), + (unsigned long int) c, c->file->name, + (long) c->pid, c->remote ? _(" (remote)") : "")); +#ifdef VMS + break; +#endif + } + + /* First, check for remote children. */ + if (any_remote) + pid = remote_status (&exit_code, &exit_sig, &coredump, 0); + else + pid = 0; + + if (pid > 0) + /* We got a remote child. */ + remote = 1; + else if (pid < 0) + { + /* A remote status command failed miserably. Punt. */ + remote_status_lose: + pfatal_with_name ("remote_status"); + } + else + { + /* No remote children. Check for local children. */ +#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32) + if (any_local) + { +#ifdef VMS + vmsWaitForChildren (&status); + pid = c->pid; +#else +#ifdef WAIT_NOHANG + if (!block) + pid = WAIT_NOHANG (&status); + else +#endif + pid = wait (&status); +#endif /* !VMS */ + } + else + pid = 0; + + if (pid < 0) + { + /* The wait*() failed miserably. Punt. */ + pfatal_with_name ("wait"); + } + else if (pid > 0) + { + /* We got a child exit; chop the status word up. */ + exit_code = WEXITSTATUS (status); + exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; + coredump = WCOREDUMP (status); + } + else + { + /* No local children are dead. */ + reap_more = 0; + + if (!block || !any_remote) + break; + + /* Now try a blocking wait for a remote child. */ + pid = remote_status (&exit_code, &exit_sig, &coredump, 1); + if (pid < 0) + goto remote_status_lose; + else if (pid == 0) + /* No remote children either. Finally give up. */ + break; + + /* We got a remote child. */ + remote = 1; + } +#endif /* !__MSDOS__, !Amiga, !WINDOWS32. */ + +#ifdef __MSDOS__ + /* Life is very different on MSDOS. */ + pid = dos_pid - 1; + status = dos_status; + exit_code = WEXITSTATUS (status); + if (exit_code == 0xff) + exit_code = -1; + exit_sig = WIFSIGNALED (status) ? WTERMSIG (status) : 0; + coredump = 0; +#endif /* __MSDOS__ */ +#ifdef _AMIGA + /* Same on Amiga */ + pid = amiga_pid - 1; + status = amiga_status; + exit_code = amiga_status; + exit_sig = 0; + coredump = 0; +#endif /* _AMIGA */ +#ifdef WINDOWS32 + { + HANDLE hPID; + int err; + + /* wait for anything to finish */ + if (hPID = process_wait_for_any()) { + + /* was an error found on this process? */ + err = process_last_err(hPID); + + /* get exit data */ + exit_code = process_exit_code(hPID); + + if (err) + fprintf(stderr, "make (e=%d): %s", + exit_code, map_windows32_error_to_string(exit_code)); + + /* signal */ + exit_sig = process_signal(hPID); + + /* cleanup process */ + process_cleanup(hPID); + + coredump = 0; + } + pid = (int) hPID; + } +#endif /* WINDOWS32 */ + } + + /* Check if this is the child of the `shell' function. */ + if (!remote && pid == shell_function_pid) + { + /* It is. Leave an indicator for the `shell' function. */ + if (exit_sig == 0 && exit_code == 127) + shell_function_completed = -1; + else + shell_function_completed = 1; + break; + } + + child_failed = exit_sig != 0 || exit_code != 0; + + /* Search for a child matching the deceased one. */ + lastc = 0; + for (c = children; c != 0; lastc = c, c = c->next) + if (c->remote == remote && c->pid == pid) + break; + + if (c == 0) + /* An unknown child died. + Ignore it; it was inherited from our invoker. */ + continue; + + DB (DB_JOBS, (child_failed + ? _("Reaping losing child 0x%08lx PID %ld %s\n") + : _("Reaping winning child 0x%08lx PID %ld %s\n"), + (unsigned long int) c, (long) c->pid, + c->remote ? _(" (remote)") : "")); + + if (c->sh_batch_file) { + DB (DB_JOBS, (_("Cleaning up temp batch file %s\n"), + c->sh_batch_file)); + + /* just try and remove, don't care if this fails */ + remove (c->sh_batch_file); + + /* all done with memory */ + free (c->sh_batch_file); + c->sh_batch_file = NULL; + } + + /* If this child had the good stdin, say it is now free. */ + if (c->good_stdin) + good_stdin_used = 0; + + if (child_failed && !c->noerror && !ignore_errors_flag) + { + /* The commands failed. Write an error message, + delete non-precious targets, and abort. */ + static int delete_on_error = -1; + child_error (c->file->name, exit_code, exit_sig, coredump, 0); + c->file->update_status = 2; + if (delete_on_error == -1) + { + struct file *f = lookup_file (".DELETE_ON_ERROR"); + delete_on_error = f != 0 && f->is_target; + } + if (exit_sig != 0 || delete_on_error) + delete_child_targets (c); + } + else + { + if (child_failed) + { + /* The commands failed, but we don't care. */ + child_error (c->file->name, + exit_code, exit_sig, coredump, 1); + child_failed = 0; + } + + /* If there are more commands to run, try to start them. */ + if (job_next_command (c)) + { + if (handling_fatal_signal) + { + /* Never start new commands while we are dying. + Since there are more commands that wanted to be run, + the target was not completely remade. So we treat + this as if a command had failed. */ + c->file->update_status = 2; + } + else + { + /* Check again whether to start remotely. + Whether or not we want to changes over time. + Also, start_remote_job may need state set up + by start_remote_job_p. */ + c->remote = start_remote_job_p (0); + start_job_command (c); + /* Fatal signals are left blocked in case we were + about to put that child on the chain. But it is + already there, so it is safe for a fatal signal to + arrive now; it will clean up this child's targets. */ + unblock_sigs (); + if (c->file->command_state == cs_running) + /* We successfully started the new command. + Loop to reap more children. */ + continue; + } + + if (c->file->update_status != 0) + /* We failed to start the commands. */ + delete_child_targets (c); + } + else + /* There are no more commands. We got through them all + without an unignored error. Now the target has been + successfully updated. */ + c->file->update_status = 0; + } + + /* When we get here, all the commands for C->file are finished + (or aborted) and C->file->update_status contains 0 or 2. But + C->file->command_state is still cs_running if all the commands + ran; notice_finish_file looks for cs_running to tell it that + it's interesting to check the file's modtime again now. */ + + if (! handling_fatal_signal) + /* Notice if the target of the commands has been changed. + This also propagates its values for command_state and + update_status to its also_make files. */ + notice_finished_file (c->file); + + DB (DB_JOBS, (_("Removing child 0x%08lx PID %ld%s from chain.\n"), + (unsigned long int) c, (long) c->pid, + c->remote ? _(" (remote)") : "")); + + /* Block fatal signals while frobnicating the list, so that + children and job_slots_used are always consistent. Otherwise + a fatal signal arriving after the child is off the chain and + before job_slots_used is decremented would believe a child was + live and call reap_children again. */ + block_sigs (); + + /* There is now another slot open. */ + if (job_slots_used > 0) + --job_slots_used; + + /* Remove the child from the chain and free it. */ + if (lastc == 0) + children = c->next; + else + lastc->next = c->next; + + free_child (c); + + unblock_sigs (); + + /* If the job failed, and the -k flag was not given, die, + unless we are already in the process of dying. */ + if (!err && child_failed && !keep_going_flag && + /* fatal_error_signal will die with the right signal. */ + !handling_fatal_signal) + die (2); + + /* Only block for one child. */ + block = 0; + } + + return; +} + +/* Free the storage allocated for CHILD. */ + +static void +free_child (child) + register struct child *child; +{ + /* If this child is the only one it was our "free" job, so don't put a + token back for it. This child has already been removed from the list, + so if there any left this wasn't the last one. */ + + if (job_fds[1] >= 0 && children) + { + char token = '+'; + + /* Write a job token back to the pipe. */ + + if (write (job_fds[1], &token, 1) != 1) + pfatal_with_name (_("write jobserver")); + + DB (DB_JOBS, (_("Released token for child 0x%08lx (%s).\n"), + (unsigned long int) child, child->file->name)); + } + + if (handling_fatal_signal) /* Don't bother free'ing if about to die. */ + return; + + if (child->command_lines != 0) + { + register unsigned int i; + for (i = 0; i < child->file->cmds->ncommand_lines; ++i) + free (child->command_lines[i]); + free ((char *) child->command_lines); + } + + if (child->environment != 0) + { + register char **ep = child->environment; + while (*ep != 0) + free (*ep++); + free ((char *) child->environment); + } + + free ((char *) child); +} + +#ifdef POSIX +extern sigset_t fatal_signal_set; +#endif + +void +block_sigs () +{ +#ifdef POSIX + (void) sigprocmask (SIG_BLOCK, &fatal_signal_set, (sigset_t *) 0); +#else +# ifdef HAVE_SIGSETMASK + (void) sigblock (fatal_signal_mask); +# endif +#endif +} + +#ifdef POSIX +void +unblock_sigs () +{ + sigset_t empty; + sigemptyset (&empty); + sigprocmask (SIG_SETMASK, &empty, (sigset_t *) 0); +} +#endif + +#ifdef MAKE_JOBSERVER +/* Set the child handler action flags to FLAGS. */ +static void +set_child_handler_action_flags (flags) + int flags; +{ + struct sigaction sa; + bzero ((char *) &sa, sizeof sa); + sa.sa_handler = child_handler; + sa.sa_flags = flags; +#if defined SIGCHLD + sigaction (SIGCHLD, &sa, NULL); +#endif +#if defined SIGCLD && SIGCLD != SIGCHLD + sigaction (SIGCLD, &sa, NULL); +#endif +} +#endif + + +/* Start a job to run the commands specified in CHILD. + CHILD is updated to reflect the commands and ID of the child process. + + NOTE: On return fatal signals are blocked! The caller is responsible + for calling `unblock_sigs', once the new child is safely on the chain so + it can be cleaned up in the event of a fatal signal. */ + +static void +start_job_command (child) + register struct child *child; +{ +#ifndef _AMIGA + static int bad_stdin = -1; +#endif + register char *p; + int flags; +#ifdef VMS + char *argv; +#else + char **argv; +#endif + + /* If we have a completely empty commandset, stop now. */ + if (!child->command_ptr) + goto next_command; + + /* Combine the flags parsed for the line itself with + the flags specified globally for this target. */ + flags = (child->file->command_flags + | child->file->cmds->lines_flags[child->command_line - 1]); + + p = child->command_ptr; + child->noerror = flags & COMMANDS_NOERROR; + + while (*p != '\0') + { + if (*p == '@') + flags |= COMMANDS_SILENT; + else if (*p == '+') + flags |= COMMANDS_RECURSE; + else if (*p == '-') + child->noerror = 1; + else if (!isblank ((unsigned char)*p)) + break; + ++p; + } + + /* Update the file's command flags with any new ones we found. We only + keep the COMMANDS_RECURSE setting. Even this isn't 100% correct; we are + now marking more commands recursive than should be in the case of + multiline define/endef scripts where only one line is marked "+". In + order to really fix this, we'll have to keep a lines_flags for every + actual line, after expansion. */ + child->file->cmds->lines_flags[child->command_line - 1] + |= flags & COMMANDS_RECURSE; + + /* Figure out an argument list from this command line. */ + + { + char *end = 0; +#ifdef VMS + argv = p; +#else + argv = construct_command_argv (p, &end, child->file, &child->sh_batch_file); +#endif + if (end == NULL) + child->command_ptr = NULL; + else + { + *end++ = '\0'; + child->command_ptr = end; + } + } + + /* If -q was given, say that updating `failed' if there was any text on the + command line, or `succeeded' otherwise. The exit status of 1 tells the + user that -q is saying `something to do'; the exit status for a random + error is 2. */ + if (argv != 0 && question_flag && !(flags & COMMANDS_RECURSE)) + { +#ifndef VMS + free (argv[0]); + free ((char *) argv); +#endif + child->file->update_status = 1; + notice_finished_file (child->file); + return; + } + + if (touch_flag && !(flags & COMMANDS_RECURSE)) + { + /* Go on to the next command. It might be the recursive one. + We construct ARGV only to find the end of the command line. */ +#ifndef VMS + if (argv) + { + free (argv[0]); + free ((char *) argv); + } +#endif + argv = 0; + } + + if (argv == 0) + { + next_command: +#ifdef __MSDOS__ + execute_by_shell = 0; /* in case construct_command_argv sets it */ +#endif + /* This line has no commands. Go to the next. */ + if (job_next_command (child)) + start_job_command (child); + else + { + /* No more commands. Make sure we're "running"; we might not be if + (e.g.) all commands were skipped due to -n. */ + set_command_state (child->file, cs_running); + child->file->update_status = 0; + notice_finished_file (child->file); + } + return; + } + + /* Print out the command. If silent, we call `message' with null so it + can log the working directory before the command's own error messages + appear. */ + + message (0, (just_print_flag || (!(flags & COMMANDS_SILENT) && !silent_flag)) + ? "%s" : (char *) 0, p); + + /* Tell update_goal_chain that a command has been started on behalf of + this target. It is important that this happens here and not in + reap_children (where we used to do it), because reap_children might be + reaping children from a different target. We want this increment to + guaranteedly indicate that a command was started for the dependency + chain (i.e., update_file recursion chain) we are processing. */ + + ++commands_started; + + /* Optimize an empty command. People use this for timestamp rules, + so avoid forking a useless shell. Do this after we increment + commands_started so make still treats this special case as if it + performed some action (makes a difference as to what messages are + printed, etc. */ + +#if !defined(VMS) && !defined(_AMIGA) + if ( +#ifdef __MSDOS__ + unixy_shell /* the test is complicated and we already did it */ +#else + (argv[0] && !strcmp (argv[0], "/bin/sh")) +#endif + && (argv[1] + && argv[1][0] == '-' && argv[1][1] == 'c' && argv[1][2] == '\0') + && (argv[2] && argv[2][0] == ':' && argv[2][1] == '\0') + && argv[3] == NULL) + { + free (argv[0]); + free ((char *) argv); + goto next_command; + } +#endif /* !VMS && !_AMIGA */ + + /* If -n was given, recurse to get the next line in the sequence. */ + + if (just_print_flag && !(flags & COMMANDS_RECURSE)) + { +#ifndef VMS + free (argv[0]); + free ((char *) argv); +#endif + goto next_command; + } + + /* Flush the output streams so they won't have things written twice. */ + + fflush (stdout); + fflush (stderr); + +#ifndef VMS +#if !defined(WINDOWS32) && !defined(_AMIGA) && !defined(__MSDOS__) + + /* Set up a bad standard input that reads from a broken pipe. */ + + if (bad_stdin == -1) + { + /* Make a file descriptor that is the read end of a broken pipe. + This will be used for some children's standard inputs. */ + int pd[2]; + if (pipe (pd) == 0) + { + /* Close the write side. */ + (void) close (pd[1]); + /* Save the read side. */ + bad_stdin = pd[0]; + + /* Set the descriptor to close on exec, so it does not litter any + child's descriptor table. When it is dup2'd onto descriptor 0, + that descriptor will not close on exec. */ + CLOSE_ON_EXEC (bad_stdin); + } + } + +#endif /* !WINDOWS32 && !_AMIGA && !__MSDOS__ */ + + /* Decide whether to give this child the `good' standard input + (one that points to the terminal or whatever), or the `bad' one + that points to the read side of a broken pipe. */ + + child->good_stdin = !good_stdin_used; + if (child->good_stdin) + good_stdin_used = 1; + +#endif /* !VMS */ + + child->deleted = 0; + +#ifndef _AMIGA + /* Set up the environment for the child. */ + if (child->environment == 0) + child->environment = target_environment (child->file); +#endif + +#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32) + +#ifndef VMS + /* start_waiting_job has set CHILD->remote if we can start a remote job. */ + if (child->remote) + { + int is_remote, id, used_stdin; + if (start_remote_job (argv, child->environment, + child->good_stdin ? 0 : bad_stdin, + &is_remote, &id, &used_stdin)) + /* Don't give up; remote execution may fail for various reasons. If + so, simply run the job locally. */ + goto run_local; + else + { + if (child->good_stdin && !used_stdin) + { + child->good_stdin = 0; + good_stdin_used = 0; + } + child->remote = is_remote; + child->pid = id; + } + } + else +#endif /* !VMS */ + { + /* Fork the child process. */ + + char **parent_environ; + + run_local: + block_sigs (); + + child->remote = 0; + +#ifdef VMS + + if (!child_execute_job (argv, child)) { + /* Fork failed! */ + perror_with_name ("vfork", ""); + goto error; + } + +#else + + parent_environ = environ; + child->pid = vfork (); + environ = parent_environ; /* Restore value child may have clobbered. */ + if (child->pid == 0) + { + /* We are the child side. */ + unblock_sigs (); + + /* If we aren't running a recursive command and we have a jobserver + pipe, close it before exec'ing. */ + if (!(flags & COMMANDS_RECURSE) && job_fds[0] >= 0) + { + close (job_fds[0]); + close (job_fds[1]); + } + if (job_rfd >= 0) + close (job_rfd); + + child_execute_job (child->good_stdin ? 0 : bad_stdin, 1, + argv, child->environment); + } + else if (child->pid < 0) + { + /* Fork failed! */ + unblock_sigs (); + perror_with_name ("vfork", ""); + goto error; + } +#endif /* !VMS */ + } + +#else /* __MSDOS__ or Amiga or WINDOWS32 */ +#ifdef __MSDOS__ + { + int proc_return; + + block_sigs (); + dos_status = 0; + + /* We call `system' to do the job of the SHELL, since stock DOS + shell is too dumb. Our `system' knows how to handle long + command lines even if pipes/redirection is needed; it will only + call COMMAND.COM when its internal commands are used. */ + if (execute_by_shell) + { + char *cmdline = argv[0]; + /* We don't have a way to pass environment to `system', + so we need to save and restore ours, sigh... */ + char **parent_environ = environ; + + environ = child->environment; + + /* If we have a *real* shell, tell `system' to call + it to do everything for us. */ + if (unixy_shell) + { + /* A *real* shell on MSDOS may not support long + command lines the DJGPP way, so we must use `system'. */ + cmdline = argv[2]; /* get past "shell -c" */ + } + + dos_command_running = 1; + proc_return = system (cmdline); + environ = parent_environ; + execute_by_shell = 0; /* for the next time */ + } + else + { + dos_command_running = 1; + proc_return = spawnvpe (P_WAIT, argv[0], argv, child->environment); + } + + /* Need to unblock signals before turning off + dos_command_running, so that child's signals + will be treated as such (see fatal_error_signal). */ + unblock_sigs (); + dos_command_running = 0; + + /* If the child got a signal, dos_status has its + high 8 bits set, so be careful not to alter them. */ + if (proc_return == -1) + dos_status |= 0xff; + else + dos_status |= (proc_return & 0xff); + ++dead_children; + child->pid = dos_pid++; + } +#endif /* __MSDOS__ */ +#ifdef _AMIGA + amiga_status = MyExecute (argv); + + ++dead_children; + child->pid = amiga_pid++; + if (amiga_batch_file) + { + amiga_batch_file = 0; + DeleteFile (amiga_bname); /* Ignore errors. */ + } +#endif /* Amiga */ +#ifdef WINDOWS32 + { + HANDLE hPID; + char* arg0; + + /* make UNC paths safe for CreateProcess -- backslash format */ + arg0 = argv[0]; + if (arg0 && arg0[0] == '/' && arg0[1] == '/') + for ( ; arg0 && *arg0; arg0++) + if (*arg0 == '/') + *arg0 = '\\'; + + /* make sure CreateProcess() has Path it needs */ + sync_Path_environment(); + + hPID = process_easy(argv, child->environment); + + if (hPID != INVALID_HANDLE_VALUE) + child->pid = (int) hPID; + else { + int i; + unblock_sigs(); + fprintf(stderr, + _("process_easy() failed failed to launch process (e=%d)\n"), + process_last_err(hPID)); + for (i = 0; argv[i]; i++) + fprintf(stderr, "%s ", argv[i]); + fprintf(stderr, _("\nCounted %d args in failed launch\n"), i); + } + } +#endif /* WINDOWS32 */ +#endif /* __MSDOS__ or Amiga or WINDOWS32 */ + + /* We are the parent side. Set the state to + say the commands are running and return. */ + + set_command_state (child->file, cs_running); + + /* Free the storage used by the child's argument list. */ +#ifndef VMS + free (argv[0]); + free ((char *) argv); +#endif + + return; + + error: + child->file->update_status = 2; + notice_finished_file (child->file); + return; +} + +/* Try to start a child running. + Returns nonzero if the child was started (and maybe finished), or zero if + the load was too high and the child was put on the `waiting_jobs' chain. */ + +static int +start_waiting_job (c) + struct child *c; +{ + struct file *f = c->file; + + /* If we can start a job remotely, we always want to, and don't care about + the local load average. We record that the job should be started + remotely in C->remote for start_job_command to test. */ + + c->remote = start_remote_job_p (1); + + /* If we are running at least one job already and the load average + is too high, make this one wait. */ + if (!c->remote && job_slots_used > 0 && load_too_high ()) + { + /* Put this child on the chain of children waiting for the load average + to go down. */ + set_command_state (f, cs_running); + c->next = waiting_jobs; + waiting_jobs = c; + return 0; + } + + /* Start the first command; reap_children will run later command lines. */ + start_job_command (c); + + switch (f->command_state) + { + case cs_running: + c->next = children; + DB (DB_JOBS, (_("Putting child 0x%08lx (%s) PID %ld%s on the chain.\n"), + (unsigned long int) c, c->file->name, + (long) c->pid, c->remote ? _(" (remote)") : "")); + children = c; + /* One more job slot is in use. */ + ++job_slots_used; + unblock_sigs (); + break; + + case cs_not_started: + /* All the command lines turned out to be empty. */ + f->update_status = 0; + /* FALLTHROUGH */ + + case cs_finished: + notice_finished_file (f); + free_child (c); + break; + + default: + assert (f->command_state == cs_finished); + break; + } + + return 1; +} + +/* Create a `struct child' for FILE and start its commands running. */ + +void +new_job (file) + register struct file *file; +{ + register struct commands *cmds = file->cmds; + register struct child *c; + char **lines; + register unsigned int i; + + /* Let any previously decided-upon jobs that are waiting + for the load to go down start before this new one. */ + start_waiting_jobs (); + + /* Reap any children that might have finished recently. */ + reap_children (0, 0); + + /* Chop the commands up into lines if they aren't already. */ + chop_commands (cmds); + + /* Expand the command lines and store the results in LINES. */ + lines = (char **) xmalloc (cmds->ncommand_lines * sizeof (char *)); + for (i = 0; i < cmds->ncommand_lines; ++i) + { + /* Collapse backslash-newline combinations that are inside variable + or function references. These are left alone by the parser so + that they will appear in the echoing of commands (where they look + nice); and collapsed by construct_command_argv when it tokenizes. + But letting them survive inside function invocations loses because + we don't want the functions to see them as part of the text. */ + + char *in, *out, *ref; + + /* IN points to where in the line we are scanning. + OUT points to where in the line we are writing. + When we collapse a backslash-newline combination, + IN gets ahead of OUT. */ + + in = out = cmds->command_lines[i]; + while ((ref = strchr (in, '$')) != 0) + { + ++ref; /* Move past the $. */ + + if (out != in) + /* Copy the text between the end of the last chunk + we processed (where IN points) and the new chunk + we are about to process (where REF points). */ + bcopy (in, out, ref - in); + + /* Move both pointers past the boring stuff. */ + out += ref - in; + in = ref; + + if (*ref == '(' || *ref == '{') + { + char openparen = *ref; + char closeparen = openparen == '(' ? ')' : '}'; + int count; + char *p; + + *out++ = *in++; /* Copy OPENPAREN. */ + /* IN now points past the opening paren or brace. + Count parens or braces until it is matched. */ + count = 0; + while (*in != '\0') + { + if (*in == closeparen && --count < 0) + break; + else if (*in == '\\' && in[1] == '\n') + { + /* We have found a backslash-newline inside a + variable or function reference. Eat it and + any following whitespace. */ + + int quoted = 0; + for (p = in - 1; p > ref && *p == '\\'; --p) + quoted = !quoted; + + if (quoted) + /* There were two or more backslashes, so this is + not really a continuation line. We don't collapse + the quoting backslashes here as is done in + collapse_continuations, because the line will + be collapsed again after expansion. */ + *out++ = *in++; + else + { + /* Skip the backslash, newline and + any following whitespace. */ + in = next_token (in + 2); + + /* Discard any preceding whitespace that has + already been written to the output. */ + while (out > ref + && isblank ((unsigned char)out[-1])) + --out; + + /* Replace it all with a single space. */ + *out++ = ' '; + } + } + else + { + if (*in == openparen) + ++count; + + *out++ = *in++; + } + } + } + } + + /* There are no more references in this line to worry about. + Copy the remaining uninteresting text to the output. */ + if (out != in) + strcpy (out, in); + + /* Finally, expand the line. */ + lines[i] = allocated_variable_expand_for_file (cmds->command_lines[i], + file); + } + + /* Start the command sequence, record it in a new + `struct child', and add that to the chain. */ + + c = (struct child *) xmalloc (sizeof (struct child)); + bzero ((char *)c, sizeof (struct child)); + c->file = file; + c->command_lines = lines; + c->sh_batch_file = NULL; + + /* Fetch the first command line to be run. */ + job_next_command (c); + + /* Wait for a job slot to be freed up. If we allow an infinite number + don't bother; also job_slots will == 0 if we're using the jobserver. */ + + if (job_slots != 0) + while (job_slots_used == job_slots) + reap_children (1, 0); + +#ifdef MAKE_JOBSERVER + /* If we are controlling multiple jobs make sure we have a token before + starting the child. */ + + /* This can be inefficient. There's a decent chance that this job won't + actually have to run any subprocesses: the command script may be empty + or otherwise optimized away. It would be nice if we could defer + obtaining a token until just before we need it, in start_job_command. + To do that we'd need to keep track of whether we'd already obtained a + token (since start_job_command is called for each line of the job, not + just once). Also more thought needs to go into the entire algorithm; + this is where the old parallel job code waits, so... */ + + else if (job_fds[0] >= 0) + while (1) + { + char token; + int got_token; + int saved_errno; + + DB (DB_JOBS, ("Need a job token; we %shave children\n", + children ? "" : "don't ")); + + /* If we don't already have a job started, use our "free" token. */ + if (!children) + break; + + /* Read a token. As long as there's no token available we'll block. + We enable interruptible system calls before the read(2) so that if + we get a SIGCHLD while we're waiting, we'll return with EINTR and + we can process the death(s) and return tokens to the free pool. + + Once we return from the read, we immediately reinstate restartable + system calls. This allows us to not worry about checking for + EINTR on all the other system calls in the program. + + There is one other twist: there is a span between the time + reap_children() does its last check for dead children and the time + the read(2) call is entered, below, where if a child dies we won't + notice. This is extremely serious as it could cause us to + deadlock, given the right set of events. + + To avoid this, we do the following: before we reap_children(), we + dup(2) the read FD on the jobserver pipe. The read(2) call below + uses that new FD. In the signal handler, we close that FD. That + way, if a child dies during the section mentioned above, the + read(2) will be invoked with an invalid FD and will return + immediately with EBADF. */ + + /* Make sure we have a dup'd FD. */ + if (job_rfd < 0) + { + DB (DB_JOBS, ("Duplicate the job FD\n")); + job_rfd = dup (job_fds[0]); + } + + /* Reap anything that's currently waiting. */ + reap_children (0, 0); + + /* If our "free" token has become available, use it. */ + if (!children) + break; + + /* Set interruptible system calls, and read() for a job token. */ + set_child_handler_action_flags (0); + got_token = read (job_rfd, &token, 1); + saved_errno = errno; + set_child_handler_action_flags (SA_RESTART); + + /* If we got one, we're done here. */ + if (got_token == 1) + { + DB (DB_JOBS, (_("Obtained token for child 0x%08lx (%s).\n"), + (unsigned long int) c, c->file->name)); + break; + } + + /* If the error _wasn't_ expected (EINTR or EBADF), punt. Otherwise, + go back and reap_children(), and try again. */ + errno = saved_errno; + if (errno != EINTR && errno != EBADF) + pfatal_with_name (_("read jobs pipe")); + if (errno == EBADF) + DB (DB_JOBS, ("Read returned EBADF.\n")); + } +#endif + + /* The job is now primed. Start it running. + (This will notice if there are in fact no commands.) */ + (void) start_waiting_job (c); + + if (job_slots == 1 || not_parallel) + /* Since there is only one job slot, make things run linearly. + Wait for the child to die, setting the state to `cs_finished'. */ + while (file->command_state == cs_running) + reap_children (1, 0); + + return; +} + +/* Move CHILD's pointers to the next command for it to execute. + Returns nonzero if there is another command. */ + +static int +job_next_command (child) + struct child *child; +{ + while (child->command_ptr == 0 || *child->command_ptr == '\0') + { + /* There are no more lines in the expansion of this line. */ + if (child->command_line == child->file->cmds->ncommand_lines) + { + /* There are no more lines to be expanded. */ + child->command_ptr = 0; + return 0; + } + else + /* Get the next line to run. */ + child->command_ptr = child->command_lines[child->command_line++]; + } + return 1; +} + +static int +load_too_high () +{ +#if defined(__MSDOS__) || defined(VMS) || defined(_AMIGA) + return 1; +#else + double load; + + if (max_load_average < 0) + return 0; + + make_access (); + if (getloadavg (&load, 1) != 1) + { + static int lossage = -1; + /* Complain only once for the same error. */ + if (lossage == -1 || errno != lossage) + { + if (errno == 0) + /* An errno value of zero means getloadavg is just unsupported. */ + error (NILF, + _("cannot enforce load limits on this operating system")); + else + perror_with_name (_("cannot enforce load limit: "), "getloadavg"); + } + lossage = errno; + load = 0; + } + user_access (); + + DB (DB_JOBS, ("Current system load = %f (max requested = %f)\n", + load, max_load_average)); + return load >= max_load_average; +#endif +} + +/* Start jobs that are waiting for the load to be lower. */ + +void +start_waiting_jobs () +{ + struct child *job; + + if (waiting_jobs == 0) + return; + + do + { + /* Check for recently deceased descendants. */ + reap_children (0, 0); + + /* Take a job off the waiting list. */ + job = waiting_jobs; + waiting_jobs = job->next; + + /* Try to start that job. We break out of the loop as soon + as start_waiting_job puts one back on the waiting list. */ + } + while (start_waiting_job (job) && waiting_jobs != 0); + + return; +} + +#ifndef WINDOWS32 +#ifdef VMS +#include +#include + +/* This is called as an AST when a child process dies (it won't get + interrupted by anything except a higher level AST). +*/ +int vmsHandleChildTerm(struct child *child) +{ + int status; + register struct child *lastc, *c; + int child_failed; + + vms_jobsefnmask &= ~(1 << (child->efn - 32)); + + lib$free_ef(&child->efn); + + (void) sigblock (fatal_signal_mask); + + child_failed = !(child->cstatus & 1 || ((child->cstatus & 7) == 0)); + + /* Search for a child matching the deceased one. */ + lastc = 0; +#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */ + for (c = children; c != 0 && c != child; lastc = c, c = c->next); +#else + c = child; +#endif + + if (child_failed && !c->noerror && !ignore_errors_flag) + { + /* The commands failed. Write an error message, + delete non-precious targets, and abort. */ + child_error (c->file->name, c->cstatus, 0, 0, 0); + c->file->update_status = 1; + delete_child_targets (c); + } + else + { + if (child_failed) + { + /* The commands failed, but we don't care. */ + child_error (c->file->name, c->cstatus, 0, 0, 1); + child_failed = 0; + } + +#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */ + /* If there are more commands to run, try to start them. */ + start_job (c); + + switch (c->file->command_state) + { + case cs_running: + /* Successfully started. */ + break; + + case cs_finished: + if (c->file->update_status != 0) { + /* We failed to start the commands. */ + delete_child_targets (c); + } + break; + + default: + error (NILF, _("internal error: `%s' command_state"), + c->file->name); + abort (); + break; + } +#endif /* RECURSIVEJOBS */ + } + + /* Set the state flag to say the commands have finished. */ + c->file->command_state = cs_finished; + notice_finished_file (c->file); + +#if defined(RECURSIVEJOBS) /* I've had problems with recursive stuff and process handling */ + /* Remove the child from the chain and free it. */ + if (lastc == 0) + children = c->next; + else + lastc->next = c->next; + free_child (c); +#endif /* RECURSIVEJOBS */ + + /* There is now another slot open. */ + if (job_slots_used > 0) + --job_slots_used; + + /* If the job failed, and the -k flag was not given, die. */ + if (child_failed && !keep_going_flag) + die (EXIT_FAILURE); + + (void) sigsetmask (sigblock (0) & ~(fatal_signal_mask)); + + return 1; +} + +/* VMS: + Spawn a process executing the command in ARGV and return its pid. */ + +#define MAXCMDLEN 200 + +/* local helpers to make ctrl+c and ctrl+y working, see below */ +#include +#include +#include + +static int ctrlMask= LIB$M_CLI_CTRLY; +static int oldCtrlMask; +static int setupYAstTried= 0; +static int pidToAbort= 0; +static int chan= 0; + +static void reEnableAst(void) { + lib$enable_ctrl (&oldCtrlMask,0); +} + +static astHandler (void) { + if (pidToAbort) { + sys$forcex (&pidToAbort, 0, SS$_ABORT); + pidToAbort= 0; + } + kill (getpid(),SIGQUIT); +} + +static void tryToSetupYAst(void) { + $DESCRIPTOR(inputDsc,"SYS$COMMAND"); + int status; + struct { + short int status, count; + int dvi; + } iosb; + + setupYAstTried++; + + if (!chan) { + status= sys$assign(&inputDsc,&chan,0,0); + if (!(status&SS$_NORMAL)) { + lib$signal(status); + return; + } + } + status= sys$qiow (0, chan, IO$_SETMODE|IO$M_CTRLYAST,&iosb,0,0, + astHandler,0,0,0,0,0); + if (status==SS$_ILLIOFUNC) { + sys$dassgn(chan); +#ifdef CTRLY_ENABLED_ANYWAY + fprintf (stderr, + _("-warning, CTRL-Y will leave sub-process(es) around.\n")); +#else + return; +#endif + } + if (status==SS$_NORMAL) + status= iosb.status; + if (!(status&SS$_NORMAL)) { + lib$signal(status); + return; + } + + /* called from AST handler ? */ + if (setupYAstTried>1) + return; + if (atexit(reEnableAst)) + fprintf (stderr, + _("-warning, you may have to re-enable CTRL-Y handling from DCL.\n")); + status= lib$disable_ctrl (&ctrlMask, &oldCtrlMask); + if (!(status&SS$_NORMAL)) { + lib$signal(status); + return; + } +} +int +child_execute_job (argv, child) + char *argv; + struct child *child; +{ + int i; + static struct dsc$descriptor_s cmddsc; + static struct dsc$descriptor_s pnamedsc; + static struct dsc$descriptor_s ifiledsc; + static struct dsc$descriptor_s ofiledsc; + static struct dsc$descriptor_s efiledsc; + int have_redirection = 0; + int have_newline = 0; + + int spflags = CLI$M_NOWAIT; + int status; + char *cmd = alloca (strlen (argv) + 512), *p, *q; + char ifile[256], ofile[256], efile[256]; + char *comname = 0; + char procname[100]; + + /* Parse IO redirection. */ + + ifile[0] = 0; + ofile[0] = 0; + efile[0] = 0; + + DB (DB_JOBS, ("child_execute_job (%s)\n", argv)); + + while (isspace ((unsigned char)*argv)) + argv++; + + if (*argv == 0) + return 0; + + sprintf (procname, "GMAKE_%05x", getpid () & 0xfffff); + pnamedsc.dsc$w_length = strlen(procname); + pnamedsc.dsc$a_pointer = procname; + pnamedsc.dsc$b_dtype = DSC$K_DTYPE_T; + pnamedsc.dsc$b_class = DSC$K_CLASS_S; + + /* Handle comments and redirection. */ + for (p = argv, q = cmd; *p; p++, q++) + { + switch (*p) + { + case '#': + *p-- = 0; + *q-- = 0; + break; + case '\\': + p++; + if (*p == '\n') + p++; + if (isspace ((unsigned char)*p)) + { + do { p++; } while (isspace ((unsigned char)*p)); + p--; + } + *q = *p; + break; + case '<': + p = vms_redirect (&ifiledsc, ifile, p); + *q = ' '; + have_redirection = 1; + break; + case '>': + have_redirection = 1; + if (*(p-1) == '2') + { + q--; + if (strncmp (p, ">&1", 3) == 0) + { + p += 3; + strcpy (efile, "sys$output"); + efiledsc.dsc$w_length = strlen(efile); + efiledsc.dsc$a_pointer = efile; + efiledsc.dsc$b_dtype = DSC$K_DTYPE_T; + efiledsc.dsc$b_class = DSC$K_CLASS_S; + } + else + { + p = vms_redirect (&efiledsc, efile, p); + } + } + else + { + p = vms_redirect (&ofiledsc, ofile, p); + } + *q = ' '; + break; + case '\n': + have_newline = 1; + default: + *q = *p; + break; + } + } + *q = *p; + + if (strncmp (cmd, "builtin_", 8) == 0) + { + child->pid = 270163; + child->efn = 0; + child->cstatus = 1; + + DB (DB_JOBS, (_("BUILTIN [%s][%s]\n"), cmd, cmd+8)); + + p = cmd + 8; + + if ((*(p) == 'c') + && (*(p+1) == 'd') + && ((*(p+2) == ' ') || (*(p+2) == '\t'))) + { + p += 3; + while ((*p == ' ') || (*p == '\t')) + p++; + DB (DB_JOBS, (_("BUILTIN CD %s\n"), p)); + if (chdir (p)) + return 0; + else + return 1; + } + else if ((*(p) == 'r') + && (*(p+1) == 'm') + && ((*(p+2) == ' ') || (*(p+2) == '\t'))) + { + int in_arg; + + /* rm */ + p += 3; + while ((*p == ' ') || (*p == '\t')) + p++; + in_arg = 1; + + DB (DB_JOBS, (_("BUILTIN RM %s\n"), p)); + while (*p) + { + switch (*p) + { + case ' ': + case '\t': + if (in_arg) + { + *p++ = ';'; + in_arg = 0; + } + break; + default: + break; + } + p++; + } + } + else + { + printf(_("Unknown builtin command '%s'\n"), cmd); + fflush(stdout); + return 0; + } + } + + /* Create a *.com file if either the command is too long for + lib$spawn, or the command contains a newline, or if redirection + is desired. Forcing commands with newlines into DCLs allows to + store search lists on user mode logicals. */ + + if (strlen (cmd) > MAXCMDLEN + || (have_redirection != 0) + || (have_newline != 0)) + { + FILE *outfile; + char c; + char *sep; + int alevel = 0; /* apostrophe level */ + + if (strlen (cmd) == 0) + { + printf (_("Error, empty command\n")); + fflush (stdout); + return 0; + } + + outfile = open_tmpfile (&comname, "sys$scratch:CMDXXXXXX.COM"); + if (outfile == 0) + pfatal_with_name (_("fopen (temporary file)")); + + if (ifile[0]) + { + fprintf (outfile, "$ assign/user %s sys$input\n", ifile); + DB (DB_JOBS, (_("Redirected input from %s\n"), ifile)); + ifiledsc.dsc$w_length = 0; + } + + if (efile[0]) + { + fprintf (outfile, "$ define sys$error %s\n", efile); + DB (DB_JOBS, (_("Redirected error to %s\n"), efile)); + efiledsc.dsc$w_length = 0; + } + + if (ofile[0]) + { + fprintf (outfile, "$ define sys$output %s\n", ofile); + DB (DB_JOBS, (_("Redirected output to %s\n"), ofile)); + ofiledsc.dsc$w_length = 0; + } + + p = sep = q = cmd; + for (c = '\n'; c; c = *q++) + { + switch (c) + { + case '\n': + /* At a newline, skip any whitespace around a leading $ + from the command and issue exactly one $ into the DCL. */ + while (isspace ((unsigned char)*p)) + p++; + if (*p == '$') + p++; + while (isspace ((unsigned char)*p)) + p++; + fwrite (p, 1, q - p, outfile); + fputc ('$', outfile); + fputc (' ', outfile); + /* Reset variables. */ + p = sep = q; + break; + + /* Nice places for line breaks are after strings, after + comma or space and before slash. */ + case '"': + q = handle_apos (q + 1); + sep = q; + break; + case ',': + case ' ': + sep = q; + break; + case '/': + case '\0': + sep = q - 1; + break; + default: + break; + } + if (sep - p > 78) + { + /* Enough stuff for a line. */ + fwrite (p, 1, sep - p, outfile); + p = sep; + if (*sep) + { + /* The command continues. */ + fputc ('-', outfile); + } + fputc ('\n', outfile); + } + } + + fwrite (p, 1, q - p, outfile); + fputc ('\n', outfile); + + fclose (outfile); + + sprintf (cmd, "$ @%s", comname); + + DB (DB_JOBS, (_("Executing %s instead\n"), cmd)); + } + + cmddsc.dsc$w_length = strlen(cmd); + cmddsc.dsc$a_pointer = cmd; + cmddsc.dsc$b_dtype = DSC$K_DTYPE_T; + cmddsc.dsc$b_class = DSC$K_CLASS_S; + + child->efn = 0; + while (child->efn < 32 || child->efn > 63) + { + status = lib$get_ef ((unsigned long *)&child->efn); + if (!(status & 1)) + return 0; + } + + sys$clref (child->efn); + + vms_jobsefnmask |= (1 << (child->efn - 32)); + +/* + LIB$SPAWN [command-string] + [,input-file] + [,output-file] + [,flags] + [,process-name] + [,process-id] [,completion-status-address] [,byte-integer-event-flag-num] + [,AST-address] [,varying-AST-argument] + [,prompt-string] [,cli] [,table] +*/ + +#ifndef DONTWAITFORCHILD +/* + * Code to make ctrl+c and ctrl+y working. + * The problem starts with the synchronous case where after lib$spawn is + * called any input will go to the child. But with input re-directed, + * both control characters won't make it to any of the programs, neither + * the spawning nor to the spawned one. Hence the caller needs to spawn + * with CLI$M_NOWAIT to NOT give up the input focus. A sys$waitfr + * has to follow to simulate the wanted synchronous behaviour. + * The next problem is ctrl+y which isn't caught by the crtl and + * therefore isn't converted to SIGQUIT (for a signal handler which is + * already established). The only way to catch ctrl+y, is an AST + * assigned to the input channel. But ctrl+y handling of DCL needs to be + * disabled, otherwise it will handle it. Not to mention the previous + * ctrl+y handling of DCL needs to be re-established before make exits. + * One more: At the time of LIB$SPAWN signals are blocked. SIGQUIT will + * make it to the signal handler after the child "normally" terminates. + * This isn't enough. It seems reasonable for simple command lines like + * a 'cc foobar.c' spawned in a subprocess but it is unacceptable for + * spawning make. Therefore we need to abort the process in the AST. + * + * Prior to the spawn it is checked if an AST is already set up for + * ctrl+y, if not one is set up for a channel to SYS$COMMAND. In general + * this will work except if make is run in a batch environment, but there + * nobody can press ctrl+y. During the setup the DCL handling of ctrl+y + * is disabled and an exit handler is established to re-enable it. + * If the user interrupts with ctrl+y, the assigned AST will fire, force + * an abort to the subprocess and signal SIGQUIT, which will be caught by + * the already established handler and will bring us back to common code. + * After the spawn (now /nowait) a sys$waitfr simulates the /wait and + * enables the ctrl+y be delivered to this code. And the ctrl+c too, + * which the crtl converts to SIGINT and which is caught by the common + * signal handler. Because signals were blocked before entering this code + * sys$waitfr will always complete and the SIGQUIT will be processed after + * it (after termination of the current block, somewhere in common code). + * And SIGINT too will be delayed. That is ctrl+c can only abort when the + * current command completes. Anyway it's better than nothing :-) + */ + + if (!setupYAstTried) + tryToSetupYAst(); + status = lib$spawn (&cmddsc, /* cmd-string */ + (ifiledsc.dsc$w_length == 0)?0:&ifiledsc, /* input-file */ + (ofiledsc.dsc$w_length == 0)?0:&ofiledsc, /* output-file */ + &spflags, /* flags */ + &pnamedsc, /* proc name */ + &child->pid, &child->cstatus, &child->efn, + 0, 0, + 0, 0, 0); + pidToAbort= child->pid; + status= sys$waitfr (child->efn); + pidToAbort= 0; + vmsHandleChildTerm(child); +#else + status = lib$spawn (&cmddsc, + (ifiledsc.dsc$w_length == 0)?0:&ifiledsc, + (ofiledsc.dsc$w_length == 0)?0:&ofiledsc, + &spflags, + &pnamedsc, + &child->pid, &child->cstatus, &child->efn, + vmsHandleChildTerm, child, + 0, 0, 0); +#endif + + if (!(status & 1)) + { + printf (_("Error spawning, %d\n") ,status); + fflush (stdout); + } + + if (comname && !ISDB (DB_JOBS)) + unlink (comname); + + return (status & 1); +} + +#else /* !VMS */ + +#if !defined (_AMIGA) && !defined (__MSDOS__) +/* UNIX: + Replace the current process with one executing the command in ARGV. + STDIN_FD and STDOUT_FD are used as the process's stdin and stdout; ENVP is + the environment of the new program. This function does not return. */ + +void +child_execute_job (stdin_fd, stdout_fd, argv, envp) + int stdin_fd, stdout_fd; + char **argv, **envp; +{ + if (stdin_fd != 0) + (void) dup2 (stdin_fd, 0); + if (stdout_fd != 1) + (void) dup2 (stdout_fd, 1); + if (stdin_fd != 0) + (void) close (stdin_fd); + if (stdout_fd != 1) + (void) close (stdout_fd); + + /* Run the command. */ + exec_command (argv, envp); +} +#endif /* !AMIGA && !__MSDOS__ */ +#endif /* !VMS */ +#endif /* !WINDOWS32 */ + +#ifndef _AMIGA +/* Replace the current process with one running the command in ARGV, + with environment ENVP. This function does not return. */ + +void +exec_command (argv, envp) + char **argv, **envp; +{ +#ifdef VMS + /* to work around a problem with signals and execve: ignore them */ +#ifdef SIGCHLD + signal (SIGCHLD,SIG_IGN); +#endif + /* Run the program. */ + execve (argv[0], argv, envp); + perror_with_name ("execve: ", argv[0]); + _exit (EXIT_FAILURE); +#else +#ifdef WINDOWS32 + HANDLE hPID; + HANDLE hWaitPID; + int err = 0; + int exit_code = EXIT_FAILURE; + + /* make sure CreateProcess() has Path it needs */ + sync_Path_environment(); + + /* launch command */ + hPID = process_easy(argv, envp); + + /* make sure launch ok */ + if (hPID == INVALID_HANDLE_VALUE) + { + int i; + fprintf(stderr, + _("process_easy() failed failed to launch process (e=%d)\n"), + process_last_err(hPID)); + for (i = 0; argv[i]; i++) + fprintf(stderr, "%s ", argv[i]); + fprintf(stderr, _("\nCounted %d args in failed launch\n"), i); + exit(EXIT_FAILURE); + } + + /* wait and reap last child */ + while (hWaitPID = process_wait_for_any()) + { + /* was an error found on this process? */ + err = process_last_err(hWaitPID); + + /* get exit data */ + exit_code = process_exit_code(hWaitPID); + + if (err) + fprintf(stderr, "make (e=%d, rc=%d): %s", + err, exit_code, map_windows32_error_to_string(err)); + + /* cleanup process */ + process_cleanup(hWaitPID); + + /* expect to find only last pid, warn about other pids reaped */ + if (hWaitPID == hPID) + break; + else + fprintf(stderr, + _("make reaped child pid %d, still waiting for pid %d\n"), + hWaitPID, hPID); + } + + /* return child's exit code as our exit code */ + exit(exit_code); + +#else /* !WINDOWS32 */ + + /* Be the user, permanently. */ + child_access (); + + /* Run the program. */ + environ = envp; + execvp (argv[0], argv); + + switch (errno) + { + case ENOENT: + error (NILF, _("%s: Command not found"), argv[0]); + break; + case ENOEXEC: + { + /* The file is not executable. Try it as a shell script. */ + extern char *getenv (); + char *shell; + char **new_argv; + int argc; + + shell = getenv ("SHELL"); + if (shell == 0) + shell = default_shell; + + argc = 1; + while (argv[argc] != 0) + ++argc; + + new_argv = (char **) alloca ((1 + argc + 1) * sizeof (char *)); + new_argv[0] = shell; + new_argv[1] = argv[0]; + while (argc > 0) + { + new_argv[1 + argc] = argv[argc]; + --argc; + } + + execvp (shell, new_argv); + if (errno == ENOENT) + error (NILF, _("%s: Shell program not found"), shell); + else + perror_with_name ("execvp: ", shell); + break; + } + + default: + perror_with_name ("execvp: ", argv[0]); + break; + } + + _exit (127); +#endif /* !WINDOWS32 */ +#endif /* !VMS */ +} +#else /* On Amiga */ +void exec_command (argv) + char **argv; +{ + MyExecute (argv); +} + +void clean_tmp (void) +{ + DeleteFile (amiga_bname); +} + +#endif /* On Amiga */ + +#ifndef VMS +/* Figure out the argument list necessary to run LINE as a command. Try to + avoid using a shell. This routine handles only ' quoting, and " quoting + when no backslash, $ or ` characters are seen in the quotes. Starting + quotes may be escaped with a backslash. If any of the characters in + sh_chars[] is seen, or any of the builtin commands listed in sh_cmds[] + is the first word of a line, the shell is used. + + If RESTP is not NULL, *RESTP is set to point to the first newline in LINE. + If *RESTP is NULL, newlines will be ignored. + + SHELL is the shell to use, or nil to use the default shell. + IFS is the value of $IFS, or nil (meaning the default). */ + +static char ** +construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr) + char *line, **restp; + char *shell, *ifs; + char **batch_filename_ptr; +{ +#ifdef __MSDOS__ + /* MSDOS supports both the stock DOS shell and ports of Unixy shells. + We call `system' for anything that requires ``slow'' processing, + because DOS shells are too dumb. When $SHELL points to a real + (unix-style) shell, `system' just calls it to do everything. When + $SHELL points to a DOS shell, `system' does most of the work + internally, calling the shell only for its internal commands. + However, it looks on the $PATH first, so you can e.g. have an + external command named `mkdir'. + + Since we call `system', certain characters and commands below are + actually not specific to COMMAND.COM, but to the DJGPP implementation + of `system'. In particular: + + The shell wildcard characters are in DOS_CHARS because they will + not be expanded if we call the child via `spawnXX'. + + The `;' is in DOS_CHARS, because our `system' knows how to run + multiple commands on a single line. + + DOS_CHARS also include characters special to 4DOS/NDOS, so we + won't have to tell one from another and have one more set of + commands and special characters. */ + static char sh_chars_dos[] = "*?[];|<>%^&()"; + static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls", + "copy", "ctty", "date", "del", "dir", "echo", + "erase", "exit", "for", "goto", "if", "md", + "mkdir", "path", "pause", "prompt", "rd", + "rmdir", "rem", "ren", "rename", "set", + "shift", "time", "type", "ver", "verify", + "vol", ":", 0 }; + + static char sh_chars_sh[] = "#;\"*?[]&|<>(){}$`^"; + static char *sh_cmds_sh[] = { "cd", "echo", "eval", "exec", "exit", "login", + "logout", "set", "umask", "wait", "while", + "for", "case", "if", ":", ".", "break", + "continue", "export", "read", "readonly", + "shift", "times", "trap", "switch", "unset", + 0 }; + + char *sh_chars; + char **sh_cmds; +#else +#ifdef _AMIGA + static char sh_chars[] = "#;\"|<>()?*$`"; + static char *sh_cmds[] = { "cd", "eval", "if", "delete", "echo", "copy", + "rename", "set", "setenv", "date", "makedir", + "skip", "else", "endif", "path", "prompt", + "unset", "unsetenv", "version", + 0 }; +#else +#ifdef WINDOWS32 + static char sh_chars_dos[] = "\"|&<>"; + static char *sh_cmds_dos[] = { "break", "call", "cd", "chcp", "chdir", "cls", + "copy", "ctty", "date", "del", "dir", "echo", + "erase", "exit", "for", "goto", "if", "if", "md", + "mkdir", "path", "pause", "prompt", "rd", "rem", + "ren", "rename", "rmdir", "set", "shift", "time", + "type", "ver", "verify", "vol", ":", 0 }; + static char sh_chars_sh[] = "#;\"*?[]&|<>(){}$`^"; + static char *sh_cmds_sh[] = { "cd", "eval", "exec", "exit", "login", + "logout", "set", "umask", "wait", "while", "for", + "case", "if", ":", ".", "break", "continue", + "export", "read", "readonly", "shift", "times", + "trap", "switch", "test", +#ifdef BATCH_MODE_ONLY_SHELL + "echo", +#endif + 0 }; + char* sh_chars; + char** sh_cmds; +#else /* must be UNIX-ish */ + static char sh_chars[] = "#;\"*?[]&|<>(){}$`^~"; + static char *sh_cmds[] = { "cd", "eval", "exec", "exit", "login", + "logout", "set", "umask", "wait", "while", "for", + "case", "if", ":", ".", "break", "continue", + "export", "read", "readonly", "shift", "times", + "trap", "switch", 0 }; +#endif /* WINDOWS32 */ +#endif /* Amiga */ +#endif /* __MSDOS__ */ + register int i; + register char *p; + register char *ap; + char *end; + int instring, word_has_equals, seen_nonequals, last_argument_was_empty; + char **new_argv = 0; +#ifdef WINDOWS32 + int slow_flag = 0; + + if (no_default_sh_exe) { + sh_cmds = sh_cmds_dos; + sh_chars = sh_chars_dos; + } else { + sh_cmds = sh_cmds_sh; + sh_chars = sh_chars_sh; + } +#endif /* WINDOWS32 */ + + if (restp != NULL) + *restp = NULL; + + /* Make sure not to bother processing an empty line. */ + while (isblank ((unsigned char)*line)) + ++line; + if (*line == '\0') + return 0; + + /* See if it is safe to parse commands internally. */ + if (shell == 0) + shell = default_shell; +#ifdef WINDOWS32 + else if (strcmp (shell, default_shell)) + { + char *s1 = _fullpath(NULL, shell, 0); + char *s2 = _fullpath(NULL, default_shell, 0); + + slow_flag = strcmp((s1 ? s1 : ""), (s2 ? s2 : "")); + + if (s1) + free (s1); + if (s2) + free (s2); + } + if (slow_flag) + goto slow; +#else /* not WINDOWS32 */ +#ifdef __MSDOS__ + else if (stricmp (shell, default_shell)) + { + extern int _is_unixy_shell (const char *_path); + + message (1, _("$SHELL changed (was `%s', now `%s')"), default_shell, shell); + unixy_shell = _is_unixy_shell (shell); + default_shell = shell; + } + if (unixy_shell) + { + sh_chars = sh_chars_sh; + sh_cmds = sh_cmds_sh; + } + else + { + sh_chars = sh_chars_dos; + sh_cmds = sh_cmds_dos; + } +#else /* not __MSDOS__ */ + else if (strcmp (shell, default_shell)) + goto slow; +#endif /* not __MSDOS__ */ +#endif /* not WINDOWS32 */ + + if (ifs != 0) + for (ap = ifs; *ap != '\0'; ++ap) + if (*ap != ' ' && *ap != '\t' && *ap != '\n') + goto slow; + + i = strlen (line) + 1; + + /* More than 1 arg per character is impossible. */ + new_argv = (char **) xmalloc (i * sizeof (char *)); + + /* All the args can fit in a buffer as big as LINE is. */ + ap = new_argv[0] = (char *) xmalloc (i); + end = ap + i; + + /* I is how many complete arguments have been found. */ + i = 0; + instring = word_has_equals = seen_nonequals = last_argument_was_empty = 0; + for (p = line; *p != '\0'; ++p) + { + if (ap > end) + abort (); + + if (instring) + { + string_char: + /* Inside a string, just copy any char except a closing quote + or a backslash-newline combination. */ + if (*p == instring) + { + instring = 0; + if (ap == new_argv[0] || *(ap-1) == '\0') + last_argument_was_empty = 1; + } + else if (*p == '\\' && p[1] == '\n') + goto swallow_escaped_newline; + else if (*p == '\n' && restp != NULL) + { + /* End of the command line. */ + *restp = p; + goto end_of_line; + } + /* Backslash, $, and ` are special inside double quotes. + If we see any of those, punt. + But on MSDOS, if we use COMMAND.COM, double and single + quotes have the same effect. */ + else if (instring == '"' && strchr ("\\$`", *p) != 0 && unixy_shell) + goto slow; + else + *ap++ = *p; + } + else if (strchr (sh_chars, *p) != 0) + /* Not inside a string, but it's a special char. */ + goto slow; +#ifdef __MSDOS__ + else if (*p == '.' && p[1] == '.' && p[2] == '.' && p[3] != '.') + /* `...' is a wildcard in DJGPP. */ + goto slow; +#endif + else + /* Not a special char. */ + switch (*p) + { + case '=': + /* Equals is a special character in leading words before the + first word with no equals sign in it. This is not the case + with sh -k, but we never get here when using nonstandard + shell flags. */ + if (! seen_nonequals && unixy_shell) + goto slow; + word_has_equals = 1; + *ap++ = '='; + break; + + case '\\': + /* Backslash-newline combinations are eaten. */ + if (p[1] == '\n') + { + swallow_escaped_newline: + + /* Eat the backslash, the newline, and following whitespace, + replacing it all with a single space. */ + p += 2; + + /* If there is a tab after a backslash-newline, + remove it from the source line which will be echoed, + since it was most likely used to line + up the continued line with the previous one. */ + if (*p == '\t') + /* Note these overlap and strcpy() is undefined for + overlapping objects in ANSI C. The strlen() _IS_ right, + since we need to copy the nul byte too. */ + bcopy (p + 1, p, strlen (p)); + + if (instring) + goto string_char; + else + { + if (ap != new_argv[i]) + /* Treat this as a space, ending the arg. + But if it's at the beginning of the arg, it should + just get eaten, rather than becoming an empty arg. */ + goto end_of_arg; + else + p = next_token (p) - 1; + } + } + else if (p[1] != '\0') + { +#ifdef HAVE_DOS_PATHS + /* Only remove backslashes before characters special + to Unixy shells. All other backslashes are copied + verbatim, since they are probably DOS-style + directory separators. This still leaves a small + window for problems, but at least it should work + for the vast majority of naive users. */ + +#ifdef __MSDOS__ + /* A dot is only special as part of the "..." + wildcard. */ + if (strneq (p + 1, ".\\.\\.", 5)) + { + *ap++ = '.'; + *ap++ = '.'; + p += 4; + } + else +#endif + if (p[1] != '\\' && p[1] != '\'' + && !isspace ((unsigned char)p[1]) + && (strchr (sh_chars_sh, p[1]) == 0)) + /* back up one notch, to copy the backslash */ + --p; +#endif /* HAVE_DOS_PATHS */ + + /* Copy and skip the following char. */ + *ap++ = *++p; + } + break; + + case '\'': + case '"': + instring = *p; + break; + + case '\n': + if (restp != NULL) + { + /* End of the command line. */ + *restp = p; + goto end_of_line; + } + else + /* Newlines are not special. */ + *ap++ = '\n'; + break; + + case ' ': + case '\t': + end_of_arg: + /* We have the end of an argument. + Terminate the text of the argument. */ + *ap++ = '\0'; + new_argv[++i] = ap; + last_argument_was_empty = 0; + + /* Update SEEN_NONEQUALS, which tells us if every word + heretofore has contained an `='. */ + seen_nonequals |= ! word_has_equals; + if (word_has_equals && ! seen_nonequals) + /* An `=' in a word before the first + word without one is magical. */ + goto slow; + word_has_equals = 0; /* Prepare for the next word. */ + + /* If this argument is the command name, + see if it is a built-in shell command. + If so, have the shell handle it. */ + if (i == 1) + { + register int j; + for (j = 0; sh_cmds[j] != 0; ++j) + if (streq (sh_cmds[j], new_argv[0])) + goto slow; + } + + /* Ignore multiple whitespace chars. */ + p = next_token (p); + /* Next iteration should examine the first nonwhite char. */ + --p; + break; + + default: + *ap++ = *p; + break; + } + } + end_of_line: + + if (instring) + /* Let the shell deal with an unterminated quote. */ + goto slow; + + /* Terminate the last argument and the argument list. */ + + *ap = '\0'; + if (new_argv[i][0] != '\0' || last_argument_was_empty) + ++i; + new_argv[i] = 0; + + if (i == 1) + { + register int j; + for (j = 0; sh_cmds[j] != 0; ++j) + if (streq (sh_cmds[j], new_argv[0])) + goto slow; + } + + if (new_argv[0] == 0) + /* Line was empty. */ + return 0; + else + return new_argv; + + slow:; + /* We must use the shell. */ + + if (new_argv != 0) + { + /* Free the old argument list we were working on. */ + free (new_argv[0]); + free ((void *)new_argv); + } + +#ifdef __MSDOS__ + execute_by_shell = 1; /* actually, call `system' if shell isn't unixy */ +#endif + +#ifdef _AMIGA + { + char *ptr; + char *buffer; + char *dptr; + + buffer = (char *)xmalloc (strlen (line)+1); + + ptr = line; + for (dptr=buffer; *ptr; ) + { + if (*ptr == '\\' && ptr[1] == '\n') + ptr += 2; + else if (*ptr == '@') /* Kludge: multiline commands */ + { + ptr += 2; + *dptr++ = '\n'; + } + else + *dptr++ = *ptr++; + } + *dptr = 0; + + new_argv = (char **) xmalloc (2 * sizeof (char *)); + new_argv[0] = buffer; + new_argv[1] = 0; + } +#else /* Not Amiga */ +#ifdef WINDOWS32 + /* + * Not eating this whitespace caused things like + * + * sh -c "\n" + * + * which gave the shell fits. I think we have to eat + * whitespace here, but this code should be considered + * suspicious if things start failing.... + */ + + /* Make sure not to bother processing an empty line. */ + while (isspace ((unsigned char)*line)) + ++line; + if (*line == '\0') + return 0; +#endif /* WINDOWS32 */ + { + /* SHELL may be a multi-word command. Construct a command line + "SHELL -c LINE", with all special chars in LINE escaped. + Then recurse, expanding this command line to get the final + argument list. */ + + unsigned int shell_len = strlen (shell); +#ifndef VMS + static char minus_c[] = " -c "; +#else + static char minus_c[] = ""; +#endif + unsigned int line_len = strlen (line); + + char *new_line = (char *) alloca (shell_len + (sizeof (minus_c) - 1) + + (line_len * 2) + 1); + char *command_ptr = NULL; /* used for batch_mode_shell mode */ + + ap = new_line; + bcopy (shell, ap, shell_len); + ap += shell_len; + bcopy (minus_c, ap, sizeof (minus_c) - 1); + ap += sizeof (minus_c) - 1; + command_ptr = ap; + for (p = line; *p != '\0'; ++p) + { + if (restp != NULL && *p == '\n') + { + *restp = p; + break; + } + else if (*p == '\\' && p[1] == '\n') + { + /* Eat the backslash, the newline, and following whitespace, + replacing it all with a single space (which is escaped + from the shell). */ + p += 2; + + /* If there is a tab after a backslash-newline, + remove it from the source line which will be echoed, + since it was most likely used to line + up the continued line with the previous one. */ + if (*p == '\t') + bcopy (p + 1, p, strlen (p)); + + p = next_token (p); + --p; + if (unixy_shell && !batch_mode_shell) + *ap++ = '\\'; + *ap++ = ' '; + continue; + } + + /* DOS shells don't know about backslash-escaping. */ + if (unixy_shell && !batch_mode_shell && + (*p == '\\' || *p == '\'' || *p == '"' + || isspace ((unsigned char)*p) + || strchr (sh_chars, *p) != 0)) + *ap++ = '\\'; +#ifdef __MSDOS__ + else if (unixy_shell && strneq (p, "...", 3)) + { + /* The case of `...' wildcard again. */ + strcpy (ap, "\\.\\.\\"); + ap += 5; + p += 2; + } +#endif + *ap++ = *p; + } + if (ap == new_line + shell_len + sizeof (minus_c) - 1) + /* Line was empty. */ + return 0; + *ap = '\0'; + +#ifdef WINDOWS32 + /* Some shells do not work well when invoked as 'sh -c xxx' to run a + command line (e.g. Cygnus GNUWIN32 sh.exe on WIN32 systems). In these + cases, run commands via a script file. */ + if ((no_default_sh_exe || batch_mode_shell) && batch_filename_ptr) { + FILE* batch = NULL; + int id = GetCurrentProcessId(); + PATH_VAR(fbuf); + char* fname = NULL; + + /* create a file name */ + sprintf(fbuf, "make%d", id); + fname = tempnam(".", fbuf); + + /* create batch file name */ + *batch_filename_ptr = xmalloc(strlen(fname) + 5); + strcpy(*batch_filename_ptr, fname); + + /* make sure path name is in DOS backslash format */ + if (!unixy_shell) { + fname = *batch_filename_ptr; + for (i = 0; fname[i] != '\0'; ++i) + if (fname[i] == '/') + fname[i] = '\\'; + strcat(*batch_filename_ptr, ".bat"); + } else { + strcat(*batch_filename_ptr, ".sh"); + } + + DB (DB_JOBS, (_("Creating temporary batch file %s\n"), + *batch_filename_ptr)); + + /* create batch file to execute command */ + batch = fopen (*batch_filename_ptr, "w"); + if (!unixy_shell) + fputs ("@echo off\n", batch); + fputs (command_ptr, batch); + fputc ('\n', batch); + fclose (batch); + + /* create argv */ + new_argv = (char **) xmalloc(3 * sizeof (char *)); + if (unixy_shell) { + new_argv[0] = xstrdup (shell); + new_argv[1] = *batch_filename_ptr; /* only argv[0] gets freed later */ + } else { + new_argv[0] = xstrdup (*batch_filename_ptr); + new_argv[1] = NULL; + } + new_argv[2] = NULL; + } else +#endif /* WINDOWS32 */ + if (unixy_shell) + new_argv = construct_command_argv_internal (new_line, (char **) NULL, + (char *) 0, (char *) 0, + (char **) 0); +#ifdef __MSDOS__ + else + { + /* With MSDOS shells, we must construct the command line here + instead of recursively calling ourselves, because we + cannot backslash-escape the special characters (see above). */ + new_argv = (char **) xmalloc (sizeof (char *)); + line_len = strlen (new_line) - shell_len - sizeof (minus_c) + 1; + new_argv[0] = xmalloc (line_len + 1); + strncpy (new_argv[0], + new_line + shell_len + sizeof (minus_c) - 1, line_len); + new_argv[0][line_len] = '\0'; + } +#else + else + fatal (NILF, _("%s (line %d) Bad shell context (!unixy && !batch_mode_shell)\n"), + __FILE__, __LINE__); +#endif + } +#endif /* ! AMIGA */ + + return new_argv; +} +#endif /* !VMS */ + +/* Figure out the argument list necessary to run LINE as a command. Try to + avoid using a shell. This routine handles only ' quoting, and " quoting + when no backslash, $ or ` characters are seen in the quotes. Starting + quotes may be escaped with a backslash. If any of the characters in + sh_chars[] is seen, or any of the builtin commands listed in sh_cmds[] + is the first word of a line, the shell is used. + + If RESTP is not NULL, *RESTP is set to point to the first newline in LINE. + If *RESTP is NULL, newlines will be ignored. + + FILE is the target whose commands these are. It is used for + variable expansion for $(SHELL) and $(IFS). */ + +char ** +construct_command_argv (line, restp, file, batch_filename_ptr) + char *line, **restp; + struct file *file; + char** batch_filename_ptr; +{ + char *shell, *ifs; + char **argv; + +#ifdef VMS + char *cptr; + int argc; + + argc = 0; + cptr = line; + for (;;) + { + while ((*cptr != 0) + && (isspace ((unsigned char)*cptr))) + cptr++; + if (*cptr == 0) + break; + while ((*cptr != 0) + && (!isspace((unsigned char)*cptr))) + cptr++; + argc++; + } + + argv = (char **)malloc (argc * sizeof (char *)); + if (argv == 0) + abort (); + + cptr = line; + argc = 0; + for (;;) + { + while ((*cptr != 0) + && (isspace ((unsigned char)*cptr))) + cptr++; + if (*cptr == 0) + break; + DB (DB_JOBS, ("argv[%d] = [%s]\n", argc, cptr)); + argv[argc++] = cptr; + while ((*cptr != 0) + && (!isspace((unsigned char)*cptr))) + cptr++; + if (*cptr != 0) + *cptr++ = 0; + } +#else + { + /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */ + int save = warn_undefined_variables_flag; + warn_undefined_variables_flag = 0; + + shell = allocated_variable_expand_for_file ("$(SHELL)", file); +#ifdef WINDOWS32 + /* + * Convert to forward slashes so that construct_command_argv_internal() + * is not confused. + */ + if (shell) { + char *p = w32ify(shell, 0); + strcpy(shell, p); + } +#endif + ifs = allocated_variable_expand_for_file ("$(IFS)", file); + + warn_undefined_variables_flag = save; + } + + argv = construct_command_argv_internal (line, restp, shell, ifs, batch_filename_ptr); + + free (shell); + free (ifs); +#endif /* !VMS */ + return argv; +} + +#if !defined(HAVE_DUP2) && !defined(_AMIGA) +int +dup2 (old, new) + int old, new; +{ + int fd; + + (void) close (new); + fd = dup (old); + if (fd != new) + { + (void) close (fd); + errno = EMFILE; + return -1; + } + + return fd; +} +#endif /* !HAPE_DUP2 && !_AMIGA */ diff --git a/src/make-3.80/job.h b/src/make-3.80/job.h new file mode 100755 index 00000000..00e9599c --- /dev/null +++ b/src/make-3.80/job.h @@ -0,0 +1,83 @@ +/* Definitions for managing subprocesses in GNU Make. +Copyright (C) 1992, 1993, 1996, 1999 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#ifndef SEEN_JOB_H +#define SEEN_JOB_H + +/* Structure describing a running or dead child process. */ + +struct child + { + struct child *next; /* Link in the chain. */ + + struct file *file; /* File being remade. */ + + char **environment; /* Environment for commands. */ + + char **command_lines; /* Array of variable-expanded cmd lines. */ + unsigned int command_line; /* Index into above. */ + char *command_ptr; /* Ptr into command_lines[command_line]. */ + + pid_t pid; /* Child process's ID number. */ +#ifdef VMS + int efn; /* Completion event flag number */ + int cstatus; /* Completion status */ +#endif + char *sh_batch_file; /* Script file for shell commands */ + unsigned int remote:1; /* Nonzero if executing remotely. */ + + unsigned int noerror:1; /* Nonzero if commands contained a `-'. */ + + unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */ + unsigned int deleted:1; /* Nonzero if targets have been deleted. */ + }; + +extern struct child *children; + +extern void new_job PARAMS ((struct file *file)); +extern void reap_children PARAMS ((int block, int err)); +extern void start_waiting_jobs PARAMS ((void)); + +extern char **construct_command_argv PARAMS ((char *line, char **restp, struct file *file, char** batch_file)); +#ifdef VMS +extern int child_execute_job PARAMS ((char *argv, struct child *child)); +#else +extern void child_execute_job PARAMS ((int stdin_fd, int stdout_fd, char **argv, char **envp)); +#endif +#ifdef _AMIGA +extern void exec_command PARAMS ((char **argv)); +#else +extern void exec_command PARAMS ((char **argv, char **envp)); +#endif + +extern unsigned int job_slots_used; + +extern void block_sigs PARAMS ((void)); +#ifdef POSIX +extern void unblock_sigs PARAMS ((void)); +#else +#ifdef HAVE_SIGSETMASK +extern int fatal_signal_mask; +#define unblock_sigs() sigsetmask (0) +#else +#define unblock_sigs() +#endif +#endif + +#endif /* SEEN_JOB_H */ diff --git a/src/make-3.80/link.dbg b/src/make-3.80/link.dbg new file mode 100755 index 00000000..98bcbc25 --- /dev/null +++ b/src/make-3.80/link.dbg @@ -0,0 +1,28 @@ +WinDebug\variable.obj +WinDebug\rule.obj +WinDebug\remote-stub.obj +WinDebug\commands.obj +WinDebug\file.obj +WinDebug\getloadavg.obj +WinDebug\default.obj +WinDebug\signame.obj +WinDebug\expand.obj +WinDebug\dir.obj +WinDebug\main.obj +WinDebug\getopt1.obj +WinDebug\job.obj +WinDebug\read.obj +WinDebug\version.obj +WinDebug\getopt.obj +WinDebug\arscan.obj +WinDebug\remake.obj +WinDebug\misc.obj +WinDebug\ar.obj +WinDebug\function.obj +WinDebug\vpath.obj +WinDebug\implicit.obj +WinDebug\dirent.obj +WinDebug\glob.obj +WinDebug\fnmatch.obj +WinDebug\pathstuff.obj +kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib w32\subproc\windebug\subproc.lib diff --git a/src/make-3.80/loadavg.c b/src/make-3.80/loadavg.c new file mode 100755 index 00000000..7d575cd6 --- /dev/null +++ b/src/make-3.80/loadavg.c @@ -0,0 +1,1034 @@ +/* Get the system load averages. + Copyright (C) 1985, 86, 87, 88, 89, 91, 92, 93, 1994, 1995, 1997 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* Compile-time symbols that this file uses: + + HAVE_PSTAT_GETDYNAMIC Define this if your system has the + pstat_getdynamic function. I think it + is unique to HPUX9. The best way to get the + definition is through the AC_FUNC_GETLOADAVG + macro that comes with autoconf 2.13 or newer. + If that isn't an option, then just put + AC_CHECK_FUNCS(pstat_getdynamic) in your + configure.in file. + FIXUP_KERNEL_SYMBOL_ADDR() Adjust address in returned struct nlist. + KERNEL_FILE Pathname of the kernel to nlist. + LDAV_CVT() Scale the load average from the kernel. + Returns a double. + LDAV_SYMBOL Name of kernel symbol giving load average. + LOAD_AVE_TYPE Type of the load average array in the kernel. + Must be defined unless one of + apollo, DGUX, NeXT, or UMAX is defined; + or we have libkstat; + otherwise, no load average is available. + NLIST_STRUCT Include nlist.h, not a.out.h, and + the nlist n_name element is a pointer, + not an array. + HAVE_STRUCT_NLIST_N_UN_N_NAME struct nlist has an n_un member, not n_name. + LINUX_LDAV_FILE [__linux__]: File containing load averages. + + Specific system predefines this file uses, aside from setting + default values if not emacs: + + apollo + BSD Real BSD, not just BSD-like. + convex + DGUX + eunice UNIX emulator under VMS. + hpux + __MSDOS__ No-op for MSDOS. + NeXT + sgi + sequent Sequent Dynix 3.x.x (BSD) + _SEQUENT_ Sequent DYNIX/ptx 1.x.x (SYSV) + sony_news NEWS-OS (works at least for 4.1C) + UMAX + UMAX4_3 + VMS + WINDOWS32 No-op for Windows95/NT. + __linux__ Linux: assumes /proc filesystem mounted. + Support from Michael K. Johnson. + __NetBSD__ NetBSD: assumes /kern filesystem mounted. + + In addition, to avoid nesting many #ifdefs, we internally set + LDAV_DONE to indicate that the load average has been computed. + + We also #define LDAV_PRIVILEGED if a program will require + special installation to be able to call getloadavg. */ + +/* This should always be first. */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* Both the Emacs and non-Emacs sections want this. Some + configuration files' definitions for the LOAD_AVE_CVT macro (like + sparc.h's) use macros like FSCALE, defined here. */ +#if defined (unix) || defined (__unix) +# include +#endif + + +/* Exclude all the code except the test program at the end + if the system has its own `getloadavg' function. + + The declaration of `errno' is needed by the test program + as well as the function itself, so it comes first. */ + +#include + +#ifndef errno +extern int errno; +#endif + +#if HAVE_LOCALE_H +# include +#endif +#if !HAVE_SETLOCALE +# define setlocale(Category, Locale) /* empty */ +#endif + +#ifndef HAVE_GETLOADAVG + + +/* The existing Emacs configuration files define a macro called + LOAD_AVE_CVT, which accepts a value of type LOAD_AVE_TYPE, and + returns the load average multiplied by 100. What we actually want + is a macro called LDAV_CVT, which returns the load average as an + unmultiplied double. + + For backwards compatibility, we'll define LDAV_CVT in terms of + LOAD_AVE_CVT, but future machine config files should just define + LDAV_CVT directly. */ + +# if !defined(LDAV_CVT) && defined(LOAD_AVE_CVT) +# define LDAV_CVT(n) (LOAD_AVE_CVT (n) / 100.0) +# endif + +# if !defined (BSD) && defined (ultrix) +/* Ultrix behaves like BSD on Vaxen. */ +# define BSD +# endif + +# ifdef NeXT +/* NeXT in the 2.{0,1,2} releases defines BSD in , which + conflicts with the definition understood in this file, that this + really is BSD. */ +# undef BSD + +/* NeXT defines FSCALE in . However, we take FSCALE being + defined to mean that the nlist method should be used, which is not true. */ +# undef FSCALE +# endif + +/* Same issues as for NeXT apply to the HURD-based GNU system. */ +# ifdef __GNU__ +# undef BSD +# undef FSCALE +# endif /* __GNU__ */ + +/* Set values that are different from the defaults, which are + set a little farther down with #ifndef. */ + + +/* Some shorthands. */ + +# if defined (HPUX) && !defined (hpux) +# define hpux +# endif + +# if defined (__hpux) && !defined (hpux) +# define hpux +# endif + +# if defined (__sun) && !defined (sun) +# define sun +# endif + +# if defined(hp300) && !defined(hpux) +# define MORE_BSD +# endif + +# if defined(ultrix) && defined(mips) +# define decstation +# endif + +# if defined (__SVR4) && !defined (SVR4) +# define SVR4 +# endif + +# if (defined(sun) && defined(SVR4)) || defined (SOLARIS2) +# define SUNOS_5 +# endif + +# if defined (__osf__) && (defined (__alpha) || defined (__alpha__)) +# define OSF_ALPHA +# include +# include +# include +# include +# endif + +# if defined (__osf__) && (defined (mips) || defined (__mips__)) +# define OSF_MIPS +# include +# endif + +/* UTek's /bin/cc on the 4300 has no architecture specific cpp define by + default, but _MACH_IND_SYS_TYPES is defined in . Combine + that with a couple of other things and we'll have a unique match. */ +# if !defined (tek4300) && defined (unix) && defined (m68k) && defined (mc68000) && defined (mc68020) && defined (_MACH_IND_SYS_TYPES) +# define tek4300 /* Define by emacs, but not by other users. */ +# endif + +/* AC_FUNC_GETLOADAVG thinks QNX is SVR4, but it isn't. */ +# if defined(__QNX__) +# undef SVR4 +# endif + +/* VAX C can't handle multi-line #ifs, or lines longer than 256 chars. */ +# ifndef LOAD_AVE_TYPE + +# ifdef MORE_BSD +# define LOAD_AVE_TYPE long +# endif + +# ifdef sun +# define LOAD_AVE_TYPE long +# endif + +# ifdef decstation +# define LOAD_AVE_TYPE long +# endif + +# ifdef _SEQUENT_ +# define LOAD_AVE_TYPE long +# endif + +# ifdef sgi +# define LOAD_AVE_TYPE long +# endif + +# ifdef SVR4 +# define LOAD_AVE_TYPE long +# endif + +# ifdef sony_news +# define LOAD_AVE_TYPE long +# endif + +# ifdef sequent +# define LOAD_AVE_TYPE long +# endif + +# ifdef OSF_ALPHA +# define LOAD_AVE_TYPE long +# endif + +# if defined (ardent) && defined (titan) +# define LOAD_AVE_TYPE long +# endif + +# ifdef tek4300 +# define LOAD_AVE_TYPE long +# endif + +# if defined(alliant) && defined(i860) /* Alliant FX/2800 */ +# define LOAD_AVE_TYPE long +# endif + +# ifdef _AIX +# define LOAD_AVE_TYPE long +# endif + +# ifdef convex +# define LOAD_AVE_TYPE double +# ifndef LDAV_CVT +# define LDAV_CVT(n) (n) +# endif +# endif + +# endif /* No LOAD_AVE_TYPE. */ + +# ifdef OSF_ALPHA +/* defines an incorrect value for FSCALE on Alpha OSF/1, + according to ghazi@noc.rutgers.edu. */ +# undef FSCALE +# define FSCALE 1024.0 +# endif + +# if defined(alliant) && defined(i860) /* Alliant FX/2800 */ +/* defines an incorrect value for FSCALE on an + Alliant FX/2800 Concentrix 2.2, according to ghazi@noc.rutgers.edu. */ +# undef FSCALE +# define FSCALE 100.0 +# endif + + +# ifndef FSCALE + +/* SunOS and some others define FSCALE in sys/param.h. */ + +# ifdef MORE_BSD +# define FSCALE 2048.0 +# endif + +# if defined(MIPS) || defined(SVR4) || defined(decstation) +# define FSCALE 256 +# endif + +# if defined (sgi) || defined (sequent) +/* Sometimes both MIPS and sgi are defined, so FSCALE was just defined + above under #ifdef MIPS. But we want the sgi value. */ +# undef FSCALE +# define FSCALE 1000.0 +# endif + +# if defined (ardent) && defined (titan) +# define FSCALE 65536.0 +# endif + +# ifdef tek4300 +# define FSCALE 100.0 +# endif + +# ifdef _AIX +# define FSCALE 65536.0 +# endif + +# endif /* Not FSCALE. */ + +# if !defined (LDAV_CVT) && defined (FSCALE) +# define LDAV_CVT(n) (((double) (n)) / FSCALE) +# endif + + +# if defined(sgi) || (defined(mips) && !defined(BSD)) +# define FIXUP_KERNEL_SYMBOL_ADDR(nl) ((nl)[0].n_value &= ~(1 << 31)) +# endif + + +# if !defined (KERNEL_FILE) && defined (sequent) +# define KERNEL_FILE "/dynix" +# endif + +# if !defined (KERNEL_FILE) && defined (hpux) +# define KERNEL_FILE "/hp-ux" +# endif + +# if !defined(KERNEL_FILE) && (defined(_SEQUENT_) || defined(MIPS) || defined(SVR4) || defined(ISC) || defined (sgi) || (defined (ardent) && defined (titan))) +# define KERNEL_FILE "/unix" +# endif + + +# if !defined (LDAV_SYMBOL) && defined (alliant) +# define LDAV_SYMBOL "_Loadavg" +# endif + +# if !defined(LDAV_SYMBOL) && ((defined(hpux) && !defined(hp9000s300)) || defined(_SEQUENT_) || defined(SVR4) || defined(ISC) || defined(sgi) || (defined (ardent) && defined (titan)) || defined (_AIX)) +# define LDAV_SYMBOL "avenrun" +# endif + +# ifdef HAVE_UNISTD_H +# include +# endif + +# include + +/* LOAD_AVE_TYPE should only get defined if we're going to use the + nlist method. */ +# if !defined(LOAD_AVE_TYPE) && (defined(BSD) || defined(LDAV_CVT) || defined(KERNEL_FILE) || defined(LDAV_SYMBOL)) +# define LOAD_AVE_TYPE double +# endif + +# ifdef LOAD_AVE_TYPE + +# ifndef VMS +# ifndef __linux__ +# ifdef HAVE_NLIST_H +# include +# else +# include +# endif + +# ifdef SUNOS_5 +# include +# include +# include +# endif + +# if defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) +# include +# endif + +# ifndef KERNEL_FILE +# define KERNEL_FILE "/vmunix" +# endif /* KERNEL_FILE */ + +# ifndef LDAV_SYMBOL +# define LDAV_SYMBOL "_avenrun" +# endif /* LDAV_SYMBOL */ +# endif /* __linux__ */ + +# else /* VMS */ + +# ifndef eunice +# include +# include +# else /* eunice */ +# include +# endif /* eunice */ +# endif /* VMS */ + +# ifndef LDAV_CVT +# define LDAV_CVT(n) ((double) (n)) +# endif /* !LDAV_CVT */ + +# endif /* LOAD_AVE_TYPE */ + +# if defined(__GNU__) && !defined (NeXT) +/* Note that NeXT Openstep defines __GNU__ even though it should not. */ +/* GNU system acts much like NeXT, for load average purposes, + but not exactly. */ +# define NeXT +# define host_self mach_host_self +# endif + +# ifdef NeXT +# ifdef HAVE_MACH_MACH_H +# include +# else +# include +# endif +# endif /* NeXT */ + +# ifdef sgi +# include +# endif /* sgi */ + +# ifdef UMAX +# include +# include +# include +# include +# include + +# ifdef UMAX_43 +# include +# include +# include +# include +# include +# else /* Not UMAX_43. */ +# include +# include +# include +# include +# include +# include +# endif /* Not UMAX_43. */ +# endif /* UMAX */ + +# ifdef DGUX +# include +# endif + +# if defined(HAVE_FCNTL_H) || defined(_POSIX_VERSION) +# include +# else +# include +# endif + + +/* Avoid static vars inside a function since in HPUX they dump as pure. */ + +# ifdef NeXT +static processor_set_t default_set; +static int getloadavg_initialized; +# endif /* NeXT */ + +# ifdef UMAX +static unsigned int cpus = 0; +static unsigned int samples; +# endif /* UMAX */ + +# ifdef DGUX +static struct dg_sys_info_load_info load_info; /* what-a-mouthful! */ +# endif /* DGUX */ + +#if !defined(HAVE_LIBKSTAT) && defined(LOAD_AVE_TYPE) +/* File descriptor open to /dev/kmem or VMS load ave driver. */ +static int channel; +/* Nonzero iff channel is valid. */ +static int getloadavg_initialized; +/* Offset in kmem to seek to read load average, or 0 means invalid. */ +static long offset; + +#if !defined(VMS) && !defined(sgi) && !defined(__linux__) +static struct nlist nl[2]; +#endif /* Not VMS or sgi */ + +#ifdef SUNOS_5 +static kvm_t *kd; +#endif /* SUNOS_5 */ + +#endif /* LOAD_AVE_TYPE && !HAVE_LIBKSTAT */ + +/* Put the 1 minute, 5 minute and 15 minute load averages + into the first NELEM elements of LOADAVG. + Return the number written (never more than 3, but may be less than NELEM), + or -1 if an error occurred. */ + +int +getloadavg (loadavg, nelem) + double loadavg[]; + int nelem; +{ + int elem = 0; /* Return value. */ + +# ifdef NO_GET_LOAD_AVG +# define LDAV_DONE + /* Set errno to zero to indicate that there was no particular error; + this function just can't work at all on this system. */ + errno = 0; + elem = -1; +# endif + +# if !defined (LDAV_DONE) && defined (HAVE_LIBKSTAT) +/* Use libkstat because we don't have to be root. */ +# define LDAV_DONE + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *kn; + + kc = kstat_open (); + if (kc == 0) + return -1; + ksp = kstat_lookup (kc, "unix", 0, "system_misc"); + if (ksp == 0 ) + return -1; + if (kstat_read (kc, ksp, 0) == -1) + return -1; + + + kn = kstat_data_lookup (ksp, "avenrun_1min"); + if (kn == 0) + { + /* Return -1 if no load average information is available. */ + nelem = 0; + elem = -1; + } + + if (nelem >= 1) + loadavg[elem++] = (double) kn->value.ul/FSCALE; + + if (nelem >= 2) + { + kn = kstat_data_lookup (ksp, "avenrun_5min"); + if (kn != 0) + { + loadavg[elem++] = (double) kn->value.ul/FSCALE; + + if (nelem >= 3) + { + kn = kstat_data_lookup (ksp, "avenrun_15min"); + if (kn != 0) + loadavg[elem++] = (double) kn->value.ul/FSCALE; + } + } + } + + kstat_close (kc); +# endif /* HAVE_LIBKSTAT */ + +# if !defined (LDAV_DONE) && defined (hpux) && defined (HAVE_PSTAT_GETDYNAMIC) +/* Use pstat_getdynamic() because we don't have to be root. */ +# define LDAV_DONE +# undef LOAD_AVE_TYPE + + struct pst_dynamic dyn_info; + if (pstat_getdynamic (&dyn_info, sizeof (dyn_info), 0, 0) < 0) + return -1; + if (nelem > 0) + loadavg[elem++] = dyn_info.psd_avg_1_min; + if (nelem > 1) + loadavg[elem++] = dyn_info.psd_avg_5_min; + if (nelem > 2) + loadavg[elem++] = dyn_info.psd_avg_15_min; + +# endif /* hpux && HAVE_PSTAT_GETDYNAMIC */ + +# if !defined (LDAV_DONE) && defined (__linux__) +# define LDAV_DONE +# undef LOAD_AVE_TYPE + +# ifndef LINUX_LDAV_FILE +# define LINUX_LDAV_FILE "/proc/loadavg" +# endif + + char ldavgbuf[40]; + double load_ave[3]; + int fd, count; + + fd = open (LINUX_LDAV_FILE, O_RDONLY); + if (fd == -1) + return -1; + count = read (fd, ldavgbuf, 40); + (void) close (fd); + if (count <= 0) + return -1; + + /* The following sscanf must use the C locale. */ + setlocale (LC_NUMERIC, "C"); + count = sscanf (ldavgbuf, "%lf %lf %lf", + &load_ave[0], &load_ave[1], &load_ave[2]); + setlocale (LC_NUMERIC, ""); + if (count < 1) + return -1; + + for (elem = 0; elem < nelem && elem < count; elem++) + loadavg[elem] = load_ave[elem]; + + return elem; + +# endif /* __linux__ */ + +# if !defined (LDAV_DONE) && defined (__NetBSD__) +# define LDAV_DONE +# undef LOAD_AVE_TYPE + +# ifndef NETBSD_LDAV_FILE +# define NETBSD_LDAV_FILE "/kern/loadavg" +# endif + + unsigned long int load_ave[3], scale; + int count; + FILE *fp; + + fp = fopen (NETBSD_LDAV_FILE, "r"); + if (fp == NULL) + return -1; + count = fscanf (fp, "%lu %lu %lu %lu\n", + &load_ave[0], &load_ave[1], &load_ave[2], + &scale); + (void) fclose (fp); + if (count != 4) + return -1; + + for (elem = 0; elem < nelem; elem++) + loadavg[elem] = (double) load_ave[elem] / (double) scale; + + return elem; + +# endif /* __NetBSD__ */ + +# if !defined (LDAV_DONE) && defined (NeXT) +# define LDAV_DONE + /* The NeXT code was adapted from iscreen 3.2. */ + + host_t host; + struct processor_set_basic_info info; + unsigned info_count; + + /* We only know how to get the 1-minute average for this system, + so even if the caller asks for more than 1, we only return 1. */ + + if (!getloadavg_initialized) + { + if (processor_set_default (host_self (), &default_set) == KERN_SUCCESS) + getloadavg_initialized = 1; + } + + if (getloadavg_initialized) + { + info_count = PROCESSOR_SET_BASIC_INFO_COUNT; + if (processor_set_info (default_set, PROCESSOR_SET_BASIC_INFO, &host, + (processor_set_info_t) &info, &info_count) + != KERN_SUCCESS) + getloadavg_initialized = 0; + else + { + if (nelem > 0) + loadavg[elem++] = (double) info.load_average / LOAD_SCALE; + } + } + + if (!getloadavg_initialized) + return -1; +# endif /* NeXT */ + +# if !defined (LDAV_DONE) && defined (UMAX) +# define LDAV_DONE +/* UMAX 4.2, which runs on the Encore Multimax multiprocessor, does not + have a /dev/kmem. Information about the workings of the running kernel + can be gathered with inq_stats system calls. + We only know how to get the 1-minute average for this system. */ + + struct proc_summary proc_sum_data; + struct stat_descr proc_info; + double load; + register unsigned int i, j; + + if (cpus == 0) + { + register unsigned int c, i; + struct cpu_config conf; + struct stat_descr desc; + + desc.sd_next = 0; + desc.sd_subsys = SUBSYS_CPU; + desc.sd_type = CPUTYPE_CONFIG; + desc.sd_addr = (char *) &conf; + desc.sd_size = sizeof conf; + + if (inq_stats (1, &desc)) + return -1; + + c = 0; + for (i = 0; i < conf.config_maxclass; ++i) + { + struct class_stats stats; + bzero ((char *) &stats, sizeof stats); + + desc.sd_type = CPUTYPE_CLASS; + desc.sd_objid = i; + desc.sd_addr = (char *) &stats; + desc.sd_size = sizeof stats; + + if (inq_stats (1, &desc)) + return -1; + + c += stats.class_numcpus; + } + cpus = c; + samples = cpus < 2 ? 3 : (2 * cpus / 3); + } + + proc_info.sd_next = 0; + proc_info.sd_subsys = SUBSYS_PROC; + proc_info.sd_type = PROCTYPE_SUMMARY; + proc_info.sd_addr = (char *) &proc_sum_data; + proc_info.sd_size = sizeof (struct proc_summary); + proc_info.sd_sizeused = 0; + + if (inq_stats (1, &proc_info) != 0) + return -1; + + load = proc_sum_data.ps_nrunnable; + j = 0; + for (i = samples - 1; i > 0; --i) + { + load += proc_sum_data.ps_nrun[j]; + if (j++ == PS_NRUNSIZE) + j = 0; + } + + if (nelem > 0) + loadavg[elem++] = load / samples / cpus; +# endif /* UMAX */ + +# if !defined (LDAV_DONE) && defined (DGUX) +# define LDAV_DONE + /* This call can return -1 for an error, but with good args + it's not supposed to fail. The first argument is for no + apparent reason of type `long int *'. */ + dg_sys_info ((long int *) &load_info, + DG_SYS_INFO_LOAD_INFO_TYPE, + DG_SYS_INFO_LOAD_VERSION_0); + + if (nelem > 0) + loadavg[elem++] = load_info.one_minute; + if (nelem > 1) + loadavg[elem++] = load_info.five_minute; + if (nelem > 2) + loadavg[elem++] = load_info.fifteen_minute; +# endif /* DGUX */ + +# if !defined (LDAV_DONE) && defined (apollo) +# define LDAV_DONE +/* Apollo code from lisch@mentorg.com (Ray Lischner). + + This system call is not documented. The load average is obtained as + three long integers, for the load average over the past minute, + five minutes, and fifteen minutes. Each value is a scaled integer, + with 16 bits of integer part and 16 bits of fraction part. + + I'm not sure which operating system first supported this system call, + but I know that SR10.2 supports it. */ + + extern void proc1_$get_loadav (); + unsigned long load_ave[3]; + + proc1_$get_loadav (load_ave); + + if (nelem > 0) + loadavg[elem++] = load_ave[0] / 65536.0; + if (nelem > 1) + loadavg[elem++] = load_ave[1] / 65536.0; + if (nelem > 2) + loadavg[elem++] = load_ave[2] / 65536.0; +# endif /* apollo */ + +# if !defined (LDAV_DONE) && defined (OSF_MIPS) +# define LDAV_DONE + + struct tbl_loadavg load_ave; + table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); + loadavg[elem++] + = (load_ave.tl_lscale == 0 + ? load_ave.tl_avenrun.d[0] + : (load_ave.tl_avenrun.l[0] / (double) load_ave.tl_lscale)); +# endif /* OSF_MIPS */ + +# if !defined (LDAV_DONE) && (defined (__MSDOS__) || defined (WINDOWS32)) +# define LDAV_DONE + + /* A faithful emulation is going to have to be saved for a rainy day. */ + for ( ; elem < nelem; elem++) + { + loadavg[elem] = 0.0; + } +# endif /* __MSDOS__ || WINDOWS32 */ + +# if !defined (LDAV_DONE) && defined (OSF_ALPHA) +# define LDAV_DONE + + struct tbl_loadavg load_ave; + table (TBL_LOADAVG, 0, &load_ave, 1, sizeof (load_ave)); + for (elem = 0; elem < nelem; elem++) + loadavg[elem] + = (load_ave.tl_lscale == 0 + ? load_ave.tl_avenrun.d[elem] + : (load_ave.tl_avenrun.l[elem] / (double) load_ave.tl_lscale)); +# endif /* OSF_ALPHA */ + +# if !defined (LDAV_DONE) && defined (VMS) + /* VMS specific code -- read from the Load Ave driver. */ + + LOAD_AVE_TYPE load_ave[3]; + static int getloadavg_initialized = 0; +# ifdef eunice + struct + { + int dsc$w_length; + char *dsc$a_pointer; + } descriptor; +# endif + + /* Ensure that there is a channel open to the load ave device. */ + if (!getloadavg_initialized) + { + /* Attempt to open the channel. */ +# ifdef eunice + descriptor.dsc$w_length = 18; + descriptor.dsc$a_pointer = "$$VMS_LOAD_AVERAGE"; +# else + $DESCRIPTOR (descriptor, "LAV0:"); +# endif + if (sys$assign (&descriptor, &channel, 0, 0) & 1) + getloadavg_initialized = 1; + } + + /* Read the load average vector. */ + if (getloadavg_initialized + && !(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0, + load_ave, 12, 0, 0, 0, 0) & 1)) + { + sys$dassgn (channel); + getloadavg_initialized = 0; + } + + if (!getloadavg_initialized) + return -1; +# endif /* VMS */ + +# if !defined (LDAV_DONE) && defined(LOAD_AVE_TYPE) && !defined(VMS) + + /* UNIX-specific code -- read the average from /dev/kmem. */ + +# define LDAV_PRIVILEGED /* This code requires special installation. */ + + LOAD_AVE_TYPE load_ave[3]; + + /* Get the address of LDAV_SYMBOL. */ + if (offset == 0) + { +# ifndef sgi +# ifndef NLIST_STRUCT + strcpy (nl[0].n_name, LDAV_SYMBOL); + strcpy (nl[1].n_name, ""); +# else /* NLIST_STRUCT */ +# ifdef HAVE_STRUCT_NLIST_N_UN_N_NAME + nl[0].n_un.n_name = LDAV_SYMBOL; + nl[1].n_un.n_name = 0; +# else /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ + nl[0].n_name = LDAV_SYMBOL; + nl[1].n_name = 0; +# endif /* not HAVE_STRUCT_NLIST_N_UN_N_NAME */ +# endif /* NLIST_STRUCT */ + +# ifndef SUNOS_5 + if ( +# if !(defined (_AIX) && !defined (ps2)) + nlist (KERNEL_FILE, nl) +# else /* _AIX */ + knlist (nl, 1, sizeof (nl[0])) +# endif + >= 0) + /* Omit "&& nl[0].n_type != 0 " -- it breaks on Sun386i. */ + { +# ifdef FIXUP_KERNEL_SYMBOL_ADDR + FIXUP_KERNEL_SYMBOL_ADDR (nl); +# endif + offset = nl[0].n_value; + } +# endif /* !SUNOS_5 */ +# else /* sgi */ + int ldav_off; + + ldav_off = sysmp (MP_KERNADDR, MPKA_AVENRUN); + if (ldav_off != -1) + offset = (long) ldav_off & 0x7fffffff; +# endif /* sgi */ + } + + /* Make sure we have /dev/kmem open. */ + if (!getloadavg_initialized) + { +# ifndef SUNOS_5 + channel = open ("/dev/kmem", 0); + if (channel >= 0) + { + /* Set the channel to close on exec, so it does not + litter any child's descriptor table. */ +# ifdef F_SETFD +# ifndef FD_CLOEXEC +# define FD_CLOEXEC 1 +# endif + (void) fcntl (channel, F_SETFD, FD_CLOEXEC); +# endif + getloadavg_initialized = 1; + } +# else /* SUNOS_5 */ + /* We pass 0 for the kernel, corefile, and swapfile names + to use the currently running kernel. */ + kd = kvm_open (0, 0, 0, O_RDONLY, 0); + if (kd != 0) + { + /* nlist the currently running kernel. */ + kvm_nlist (kd, nl); + offset = nl[0].n_value; + getloadavg_initialized = 1; + } +# endif /* SUNOS_5 */ + } + + /* If we can, get the load average values. */ + if (offset && getloadavg_initialized) + { + /* Try to read the load. */ +# ifndef SUNOS_5 + if (lseek (channel, offset, 0) == -1L + || read (channel, (char *) load_ave, sizeof (load_ave)) + != sizeof (load_ave)) + { + close (channel); + getloadavg_initialized = 0; + } +# else /* SUNOS_5 */ + if (kvm_read (kd, offset, (char *) load_ave, sizeof (load_ave)) + != sizeof (load_ave)) + { + kvm_close (kd); + getloadavg_initialized = 0; + } +# endif /* SUNOS_5 */ + } + + if (offset == 0 || !getloadavg_initialized) + return -1; +# endif /* LOAD_AVE_TYPE and not VMS */ + +# if !defined (LDAV_DONE) && defined (LOAD_AVE_TYPE) /* Including VMS. */ + if (nelem > 0) + loadavg[elem++] = LDAV_CVT (load_ave[0]); + if (nelem > 1) + loadavg[elem++] = LDAV_CVT (load_ave[1]); + if (nelem > 2) + loadavg[elem++] = LDAV_CVT (load_ave[2]); + +# define LDAV_DONE +# endif /* !LDAV_DONE && LOAD_AVE_TYPE */ + +# ifdef LDAV_DONE + return elem; +# else + /* Set errno to zero to indicate that there was no particular error; + this function just can't work at all on this system. */ + errno = 0; + return -1; +# endif +} + +#endif /* ! HAVE_GETLOADAVG */ + +#ifdef TEST +#include "make.h" + +int +main (argc, argv) + int argc; + char **argv; +{ + int naptime = 0; + + if (argc > 1) + naptime = atoi (argv[1]); + + while (1) + { + double avg[3]; + int loads; + + errno = 0; /* Don't be misled if it doesn't set errno. */ + loads = getloadavg (avg, 3); + if (loads == -1) + { + perror ("Error getting load average"); + exit (1); + } + if (loads > 0) + printf ("1-minute: %f ", avg[0]); + if (loads > 1) + printf ("5-minute: %f ", avg[1]); + if (loads > 2) + printf ("15-minute: %f ", avg[2]); + if (loads > 0) + putchar ('\n'); + + if (naptime == 0) + break; + sleep (naptime); + } + + exit (0); +} +#endif /* TEST */ diff --git a/src/make-3.80/main.c b/src/make-3.80/main.c new file mode 100755 index 00000000..a04671db --- /dev/null +++ b/src/make-3.80/main.c @@ -0,0 +1,2813 @@ +/* Argument parsing and main program of GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1994, 1995, 1996, 1997, 1998, 1999, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#include "make.h" +#include "dep.h" +#include "filedef.h" +#include "variable.h" +#include "job.h" +#include "commands.h" +#include "rule.h" +#include "debug.h" +#include "getopt.h" + +#include +#ifdef _AMIGA +# include +# include +#endif +#ifdef WINDOWS32 +#include +#include "pathstuff.h" +#endif +#if defined(MAKE_JOBSERVER) && defined(HAVE_FCNTL_H) +# include +#endif + +#ifdef _AMIGA +int __stack = 20000; /* Make sure we have 20K of stack space */ +#endif + +extern void init_dir PARAMS ((void)); +extern void remote_setup PARAMS ((void)); +extern void remote_cleanup PARAMS ((void)); +extern RETSIGTYPE fatal_error_signal PARAMS ((int sig)); + +extern void print_variable_data_base PARAMS ((void)); +extern void print_dir_data_base PARAMS ((void)); +extern void print_rule_data_base PARAMS ((void)); +extern void print_file_data_base PARAMS ((void)); +extern void print_vpath_data_base PARAMS ((void)); + +#if defined HAVE_WAITPID || defined HAVE_WAIT3 +# define HAVE_WAIT_NOHANG +#endif + +#ifndef HAVE_UNISTD_H +extern int chdir (); +#endif +#ifndef STDC_HEADERS +# ifndef sun /* Sun has an incorrect decl in a header. */ +extern void exit PARAMS ((int)) __attribute__ ((noreturn)); +# endif +extern double atof (); +#endif + +static void print_data_base PARAMS ((void)); +static void print_version PARAMS ((void)); +static void decode_switches PARAMS ((int argc, char **argv, int env)); +static void decode_env_switches PARAMS ((char *envar, unsigned int len)); +static void define_makeflags PARAMS ((int all, int makefile)); +static char *quote_for_env PARAMS ((char *out, char *in)); +static void initialize_global_hash_tables PARAMS ((void)); + + +/* The structure that describes an accepted command switch. */ + +struct command_switch + { + int c; /* The switch character. */ + + enum /* Type of the value. */ + { + flag, /* Turn int flag on. */ + flag_off, /* Turn int flag off. */ + string, /* One string per switch. */ + positive_int, /* A positive integer. */ + floating, /* A floating-point number (double). */ + ignore /* Ignored. */ + } type; + + char *value_ptr; /* Pointer to the value-holding variable. */ + + unsigned int env:1; /* Can come from MAKEFLAGS. */ + unsigned int toenv:1; /* Should be put in MAKEFLAGS. */ + unsigned int no_makefile:1; /* Don't propagate when remaking makefiles. */ + + char *noarg_value; /* Pointer to value used if no argument is given. */ + char *default_value;/* Pointer to default value. */ + + char *long_name; /* Long option name. */ + }; + +/* True if C is a switch value that corresponds to a short option. */ + +#define short_option(c) ((c) <= CHAR_MAX) + +/* The structure used to hold the list of strings given + in command switches of a type that takes string arguments. */ + +struct stringlist + { + char **list; /* Nil-terminated list of strings. */ + unsigned int idx; /* Index into above. */ + unsigned int max; /* Number of pointers allocated. */ + }; + + +/* The recognized command switches. */ + +/* Nonzero means do not print commands to be executed (-s). */ + +int silent_flag; + +/* Nonzero means just touch the files + that would appear to need remaking (-t) */ + +int touch_flag; + +/* Nonzero means just print what commands would need to be executed, + don't actually execute them (-n). */ + +int just_print_flag; + +/* Print debugging info (--debug). */ + +static struct stringlist *db_flags; +static int debug_flag = 0; + +int db_level = 0; + +#ifdef WINDOWS32 +/* Suspend make in main for a short time to allow debugger to attach */ + +int suspend_flag = 0; +#endif + +/* Environment variables override makefile definitions. */ + +int env_overrides = 0; + +/* Nonzero means ignore status codes returned by commands + executed to remake files. Just treat them all as successful (-i). */ + +int ignore_errors_flag = 0; + +/* Nonzero means don't remake anything, just print the data base + that results from reading the makefile (-p). */ + +int print_data_base_flag = 0; + +/* Nonzero means don't remake anything; just return a nonzero status + if the specified targets are not up to date (-q). */ + +int question_flag = 0; + +/* Nonzero means do not use any of the builtin rules (-r) / variables (-R). */ + +int no_builtin_rules_flag = 0; +int no_builtin_variables_flag = 0; + +/* Nonzero means keep going even if remaking some file fails (-k). */ + +int keep_going_flag; +int default_keep_going_flag = 0; + +/* Nonzero means print directory before starting and when done (-w). */ + +int print_directory_flag = 0; + +/* Nonzero means ignore print_directory_flag and never print the directory. + This is necessary because print_directory_flag is set implicitly. */ + +int inhibit_print_directory_flag = 0; + +/* Nonzero means print version information. */ + +int print_version_flag = 0; + +/* List of makefiles given with -f switches. */ + +static struct stringlist *makefiles = 0; + +/* Number of job slots (commands that can be run at once). */ + +unsigned int job_slots = 1; +unsigned int default_job_slots = 1; + +/* Value of job_slots that means no limit. */ + +static unsigned int inf_jobs = 0; + +/* File descriptors for the jobs pipe. */ + +static struct stringlist *jobserver_fds = 0; + +int job_fds[2] = { -1, -1 }; +int job_rfd = -1; + +/* Maximum load average at which multiple jobs will be run. + Negative values mean unlimited, while zero means limit to + zero load (which could be useful to start infinite jobs remotely + but one at a time locally). */ +#ifndef NO_FLOAT +double max_load_average = -1.0; +double default_load_average = -1.0; +#else +int max_load_average = -1; +int default_load_average = -1; +#endif + +/* List of directories given with -C switches. */ + +static struct stringlist *directories = 0; + +/* List of include directories given with -I switches. */ + +static struct stringlist *include_directories = 0; + +/* List of files given with -o switches. */ + +static struct stringlist *old_files = 0; + +/* List of files given with -W switches. */ + +static struct stringlist *new_files = 0; + +/* If nonzero, we should just print usage and exit. */ + +static int print_usage_flag = 0; + +/* If nonzero, we should print a warning message + for each reference to an undefined variable. */ + +int warn_undefined_variables_flag; + +/* If nonzero, always build all targets, regardless of whether + they appear out of date or not. */ + +int always_make_flag = 0; + +/* The usage output. We write it this way to make life easier for the + translators, especially those trying to translate to right-to-left + languages like Hebrew. */ + +static const char *const usage[] = + { + N_("Options:\n"), + N_("\ + -b, -m Ignored for compatibility.\n"), + N_("\ + -B, --always-make Unconditionally make all targets.\n"), + N_("\ + -C DIRECTORY, --directory=DIRECTORY\n\ + Change to DIRECTORY before doing anything.\n"), + N_("\ + -d Print lots of debugging information.\n"), + N_("\ + --debug[=FLAGS] Print various types of debugging information.\n"), + N_("\ + -e, --environment-overrides\n\ + Environment variables override makefiles.\n"), + N_("\ + -f FILE, --file=FILE, --makefile=FILE\n\ + Read FILE as a makefile.\n"), + N_("\ + -h, --help Print this message and exit.\n"), + N_("\ + -i, --ignore-errors Ignore errors from commands.\n"), + N_("\ + -I DIRECTORY, --include-dir=DIRECTORY\n\ + Search DIRECTORY for included makefiles.\n"), + N_("\ + -j [N], --jobs[=N] Allow N jobs at once; infinite jobs with no arg.\n"), + N_("\ + -k, --keep-going Keep going when some targets can't be made.\n"), + N_("\ + -l [N], --load-average[=N], --max-load[=N]\n\ + Don't start multiple jobs unless load is below N.\n"), + N_("\ + -n, --just-print, --dry-run, --recon\n\ + Don't actually run any commands; just print them.\n"), + N_("\ + -o FILE, --old-file=FILE, --assume-old=FILE\n\ + Consider FILE to be very old and don't remake it.\n"), + N_("\ + -p, --print-data-base Print make's internal database.\n"), + N_("\ + -q, --question Run no commands; exit status says if up to date.\n"), + N_("\ + -r, --no-builtin-rules Disable the built-in implicit rules.\n"), + N_("\ + -R, --no-builtin-variables Disable the built-in variable settings.\n"), + N_("\ + -s, --silent, --quiet Don't echo commands.\n"), + N_("\ + -S, --no-keep-going, --stop\n\ + Turns off -k.\n"), + N_("\ + -t, --touch Touch targets instead of remaking them.\n"), + N_("\ + -v, --version Print the version number of make and exit.\n"), + N_("\ + -w, --print-directory Print the current directory.\n"), + N_("\ + --no-print-directory Turn off -w, even if it was turned on implicitly.\n"), + N_("\ + -W FILE, --what-if=FILE, --new-file=FILE, --assume-new=FILE\n\ + Consider FILE to be infinitely new.\n"), + N_("\ + --warn-undefined-variables Warn when an undefined variable is referenced.\n"), + NULL + }; + +/* The table of command switches. */ + +static const struct command_switch switches[] = + { + { 'b', ignore, 0, 0, 0, 0, 0, 0, 0 }, + { 'B', flag, (char *) &always_make_flag, 1, 1, 0, 0, 0, "always-make" }, + { 'C', string, (char *) &directories, 0, 0, 0, 0, 0, "directory" }, + { 'd', flag, (char *) &debug_flag, 1, 1, 0, 0, 0, 0 }, + { CHAR_MAX+1, string, (char *) &db_flags, 1, 1, 0, "basic", 0, "debug" }, +#ifdef WINDOWS32 + { 'D', flag, (char *) &suspend_flag, 1, 1, 0, 0, 0, "suspend-for-debug" }, +#endif + { 'e', flag, (char *) &env_overrides, 1, 1, 0, 0, 0, + "environment-overrides", }, + { 'f', string, (char *) &makefiles, 0, 0, 0, 0, 0, "file" }, + { 'h', flag, (char *) &print_usage_flag, 0, 0, 0, 0, 0, "help" }, + { 'i', flag, (char *) &ignore_errors_flag, 1, 1, 0, 0, 0, + "ignore-errors" }, + { 'I', string, (char *) &include_directories, 1, 1, 0, 0, 0, + "include-dir" }, + { 'j', positive_int, (char *) &job_slots, 1, 1, 0, (char *) &inf_jobs, + (char *) &default_job_slots, "jobs" }, + { CHAR_MAX+2, string, (char *) &jobserver_fds, 1, 1, 0, 0, 0, + "jobserver-fds" }, + { 'k', flag, (char *) &keep_going_flag, 1, 1, 0, 0, + (char *) &default_keep_going_flag, "keep-going" }, +#ifndef NO_FLOAT + { 'l', floating, (char *) &max_load_average, 1, 1, 0, + (char *) &default_load_average, (char *) &default_load_average, + "load-average" }, +#else + { 'l', positive_int, (char *) &max_load_average, 1, 1, 0, + (char *) &default_load_average, (char *) &default_load_average, + "load-average" }, +#endif + { 'm', ignore, 0, 0, 0, 0, 0, 0, 0 }, + { 'n', flag, (char *) &just_print_flag, 1, 1, 1, 0, 0, "just-print" }, + { 'o', string, (char *) &old_files, 0, 0, 0, 0, 0, "old-file" }, + { 'p', flag, (char *) &print_data_base_flag, 1, 1, 0, 0, 0, + "print-data-base" }, + { 'q', flag, (char *) &question_flag, 1, 1, 1, 0, 0, "question" }, + { 'r', flag, (char *) &no_builtin_rules_flag, 1, 1, 0, 0, 0, + "no-builtin-rules" }, + { 'R', flag, (char *) &no_builtin_variables_flag, 1, 1, 0, 0, 0, + "no-builtin-variables" }, + { 's', flag, (char *) &silent_flag, 1, 1, 0, 0, 0, "silent" }, + { 'S', flag_off, (char *) &keep_going_flag, 1, 1, 0, 0, + (char *) &default_keep_going_flag, "no-keep-going" }, + { 't', flag, (char *) &touch_flag, 1, 1, 1, 0, 0, "touch" }, + { 'v', flag, (char *) &print_version_flag, 1, 1, 0, 0, 0, "version" }, + { 'w', flag, (char *) &print_directory_flag, 1, 1, 0, 0, 0, + "print-directory" }, + { CHAR_MAX+3, flag, (char *) &inhibit_print_directory_flag, 1, 1, 0, 0, 0, + "no-print-directory" }, + { 'W', string, (char *) &new_files, 0, 0, 0, 0, 0, "what-if" }, + { CHAR_MAX+4, flag, (char *) &warn_undefined_variables_flag, 1, 1, 0, 0, 0, + "warn-undefined-variables" }, + { '\0', } + }; + +/* Secondary long names for options. */ + +static struct option long_option_aliases[] = + { + { "quiet", no_argument, 0, 's' }, + { "stop", no_argument, 0, 'S' }, + { "new-file", required_argument, 0, 'W' }, + { "assume-new", required_argument, 0, 'W' }, + { "assume-old", required_argument, 0, 'o' }, + { "max-load", optional_argument, 0, 'l' }, + { "dry-run", no_argument, 0, 'n' }, + { "recon", no_argument, 0, 'n' }, + { "makefile", required_argument, 0, 'f' }, + }; + +/* List of goal targets. */ + +static struct dep *goals, *lastgoal; + +/* List of variables which were defined on the command line + (or, equivalently, in MAKEFLAGS). */ + +struct command_variable + { + struct command_variable *next; + struct variable *variable; + }; +static struct command_variable *command_variables; + +/* The name we were invoked with. */ + +char *program; + +/* Our current directory before processing any -C options. */ + +char *directory_before_chdir; + +/* Our current directory after processing all -C options. */ + +char *starting_directory; + +/* Value of the MAKELEVEL variable at startup (or 0). */ + +unsigned int makelevel; + +/* First file defined in the makefile whose name does not + start with `.'. This is the default to remake if the + command line does not specify. */ + +struct file *default_goal_file; + +/* Pointer to structure for the file .DEFAULT + whose commands are used for any file that has none of its own. + This is zero if the makefiles do not define .DEFAULT. */ + +struct file *default_file; + +/* Nonzero if we have seen the magic `.POSIX' target. + This turns on pedantic compliance with POSIX.2. */ + +int posix_pedantic; + +/* Nonzero if we have seen the `.NOTPARALLEL' target. + This turns off parallel builds for this invocation of make. */ + +int not_parallel; + +/* Nonzero if some rule detected clock skew; we keep track so (a) we only + print one warning about it during the run, and (b) we can print a final + warning at the end of the run. */ + +int clock_skew_detected; + +/* Mask of signals that are being caught with fatal_error_signal. */ + +#ifdef POSIX +sigset_t fatal_signal_set; +#else +# ifdef HAVE_SIGSETMASK +int fatal_signal_mask; +# endif +#endif + +#if !defined HAVE_BSD_SIGNAL && !defined bsd_signal +# if !defined HAVE_SIGACTION +# define bsd_signal signal +# else +typedef RETSIGTYPE (*bsd_signal_ret_t) (); + +static bsd_signal_ret_t +bsd_signal (sig, func) + int sig; + bsd_signal_ret_t func; +{ + struct sigaction act, oact; + act.sa_handler = func; + act.sa_flags = SA_RESTART; + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, sig); + if (sigaction (sig, &act, &oact) != 0) + return SIG_ERR; + return oact.sa_handler; +} +# endif +#endif + +static void +initialize_global_hash_tables () +{ + init_hash_global_variable_set (); + init_hash_files (); + hash_init_directories (); + hash_init_function_table (); +} + +static struct file * +enter_command_line_file (name) + char *name; +{ + if (name[0] == '\0') + fatal (NILF, _("empty string invalid as file name")); + + if (name[0] == '~') + { + char *expanded = tilde_expand (name); + if (expanded != 0) + name = expanded; /* Memory leak; I don't care. */ + } + + /* This is also done in parse_file_seq, so this is redundant + for names read from makefiles. It is here for names passed + on the command line. */ + while (name[0] == '.' && name[1] == '/' && name[2] != '\0') + { + name += 2; + while (*name == '/') + /* Skip following slashes: ".//foo" is "foo", not "/foo". */ + ++name; + } + + if (*name == '\0') + { + /* It was all slashes! Move back to the dot and truncate + it after the first slash, so it becomes just "./". */ + do + --name; + while (name[0] != '.'); + name[2] = '\0'; + } + + return enter_file (xstrdup (name)); +} + +/* Toggle -d on receipt of SIGUSR1. */ + +static RETSIGTYPE +debug_signal_handler (sig) + int sig; +{ + db_level = db_level ? DB_NONE : DB_BASIC; +} + +static void +decode_debug_flags () +{ + char **pp; + + if (debug_flag) + db_level = DB_ALL; + + if (!db_flags) + return; + + for (pp=db_flags->list; *pp; ++pp) + { + const char *p = *pp; + + while (1) + { + switch (tolower (p[0])) + { + case 'a': + db_level |= DB_ALL; + break; + case 'b': + db_level |= DB_BASIC; + break; + case 'i': + db_level |= DB_BASIC | DB_IMPLICIT; + break; + case 'j': + db_level |= DB_JOBS; + break; + case 'm': + db_level |= DB_BASIC | DB_MAKEFILES; + break; + case 'v': + db_level |= DB_BASIC | DB_VERBOSE; + break; + default: + fatal (NILF, _("unknown debug level specification `%s'"), p); + } + + while (*(++p) != '\0') + if (*p == ',' || *p == ' ') + break; + + if (*p == '\0') + break; + + ++p; + } + } +} + +#ifdef WINDOWS32 +/* + * HANDLE runtime exceptions by avoiding a requestor on the GUI. Capture + * exception and print it to stderr instead. + * + * If ! DB_VERBOSE, just print a simple message and exit. + * If DB_VERBOSE, print a more verbose message. + * If compiled for DEBUG, let exception pass through to GUI so that + * debuggers can attach. + */ +LONG WINAPI +handle_runtime_exceptions( struct _EXCEPTION_POINTERS *exinfo ) +{ + PEXCEPTION_RECORD exrec = exinfo->ExceptionRecord; + LPSTR cmdline = GetCommandLine(); + LPSTR prg = strtok(cmdline, " "); + CHAR errmsg[1024]; +#ifdef USE_EVENT_LOG + HANDLE hEventSource; + LPTSTR lpszStrings[1]; +#endif + + if (! ISDB (DB_VERBOSE)) + { + sprintf(errmsg, + _("%s: Interrupt/Exception caught (code = 0x%x, addr = 0x%x)\n"), + prg, exrec->ExceptionCode, exrec->ExceptionAddress); + fprintf(stderr, errmsg); + exit(255); + } + + sprintf(errmsg, + _("\nUnhandled exception filter called from program %s\nExceptionCode = %x\nExceptionFlags = %x\nExceptionAddress = %x\n"), + prg, exrec->ExceptionCode, exrec->ExceptionFlags, + exrec->ExceptionAddress); + + if (exrec->ExceptionCode == EXCEPTION_ACCESS_VIOLATION + && exrec->NumberParameters >= 2) + sprintf(&errmsg[strlen(errmsg)], + (exrec->ExceptionInformation[0] + ? _("Access violation: write operation at address %x\n") + : _("Access violation: read operation at address %x\n")), + exrec->ExceptionInformation[1]); + + /* turn this on if we want to put stuff in the event log too */ +#ifdef USE_EVENT_LOG + hEventSource = RegisterEventSource(NULL, "GNU Make"); + lpszStrings[0] = errmsg; + + if (hEventSource != NULL) + { + ReportEvent(hEventSource, /* handle of event source */ + EVENTLOG_ERROR_TYPE, /* event type */ + 0, /* event category */ + 0, /* event ID */ + NULL, /* current user's SID */ + 1, /* strings in lpszStrings */ + 0, /* no bytes of raw data */ + lpszStrings, /* array of error strings */ + NULL); /* no raw data */ + + (VOID) DeregisterEventSource(hEventSource); + } +#endif + + /* Write the error to stderr too */ + fprintf(stderr, errmsg); + +#ifdef DEBUG + return EXCEPTION_CONTINUE_SEARCH; +#else + exit(255); + return (255); /* not reached */ +#endif +} + +/* + * On WIN32 systems we don't have the luxury of a /bin directory that + * is mapped globally to every drive mounted to the system. Since make could + * be invoked from any drive, and we don't want to propogate /bin/sh + * to every single drive. Allow ourselves a chance to search for + * a value for default shell here (if the default path does not exist). + */ + +int +find_and_set_default_shell(char *token) +{ + int sh_found = 0; + char* search_token; + PATH_VAR(sh_path); + extern char *default_shell; + + if (!token) + search_token = default_shell; + else + search_token = token; + + if (!no_default_sh_exe && + (token == NULL || !strcmp(search_token, default_shell))) { + /* no new information, path already set or known */ + sh_found = 1; + } else if (file_exists_p(search_token)) { + /* search token path was found */ + sprintf(sh_path, "%s", search_token); + default_shell = xstrdup(w32ify(sh_path,0)); + DB (DB_VERBOSE, + (_("find_and_set_shell setting default_shell = %s\n"), default_shell)); + sh_found = 1; + } else { + char *p; + struct variable *v = lookup_variable ("Path", 4); + + /* + * Search Path for shell + */ + if (v && v->value) { + char *ep; + + p = v->value; + ep = strchr(p, PATH_SEPARATOR_CHAR); + + while (ep && *ep) { + *ep = '\0'; + + if (dir_file_exists_p(p, search_token)) { + sprintf(sh_path, "%s/%s", p, search_token); + default_shell = xstrdup(w32ify(sh_path,0)); + sh_found = 1; + *ep = PATH_SEPARATOR_CHAR; + + /* terminate loop */ + p += strlen(p); + } else { + *ep = PATH_SEPARATOR_CHAR; + p = ++ep; + } + + ep = strchr(p, PATH_SEPARATOR_CHAR); + } + + /* be sure to check last element of Path */ + if (p && *p && dir_file_exists_p(p, search_token)) { + sprintf(sh_path, "%s/%s", p, search_token); + default_shell = xstrdup(w32ify(sh_path,0)); + sh_found = 1; + } + + if (sh_found) + DB (DB_VERBOSE, + (_("find_and_set_shell path search set default_shell = %s\n"), + default_shell)); + } + } + + /* naive test */ + if (!unixy_shell && sh_found && + (strstr(default_shell, "sh") || strstr(default_shell, "SH"))) { + unixy_shell = 1; + batch_mode_shell = 0; + } + +#ifdef BATCH_MODE_ONLY_SHELL + batch_mode_shell = 1; +#endif + + return (sh_found); +} +#endif /* WINDOWS32 */ + +#ifdef __MSDOS__ + +static void +msdos_return_to_initial_directory () +{ + if (directory_before_chdir) + chdir (directory_before_chdir); +} +#endif + +extern char *mktemp (); +extern int mkstemp (); + +FILE * +open_tmpfile(name, template) + char **name; + const char *template; +{ + int fd; + +#if defined HAVE_MKSTEMP || defined HAVE_MKTEMP +# define TEMPLATE_LEN strlen (template) +#else +# define TEMPLATE_LEN L_tmpnam +#endif + *name = xmalloc (TEMPLATE_LEN + 1); + strcpy (*name, template); + +#if defined HAVE_MKSTEMP && defined HAVE_FDOPEN + /* It's safest to use mkstemp(), if we can. */ + fd = mkstemp (*name); + if (fd == -1) + return 0; + return fdopen (fd, "w"); +#else +# ifdef HAVE_MKTEMP + (void) mktemp (*name); +# else + (void) tmpnam (*name); +# endif + +# ifdef HAVE_FDOPEN + /* Can't use mkstemp(), but guard against a race condition. */ + fd = open (*name, O_CREAT|O_EXCL|O_WRONLY, 0600); + if (fd == -1) + return 0; + return fdopen (fd, "w"); +# else + /* Not secure, but what can we do? */ + return fopen (*name, "w"); +# endif +#endif +} + + +#ifndef _AMIGA +int +main (argc, argv, envp) + int argc; + char **argv; + char **envp; +#else +int main (int argc, char ** argv) +#endif +{ + static char *stdin_nm = 0; + register struct file *f; + register unsigned int i; + char **p; + struct dep *read_makefiles; + PATH_VAR (current_directory); +#ifdef WINDOWS32 + char *unix_path = NULL; + char *windows32_path = NULL; + + SetUnhandledExceptionFilter(handle_runtime_exceptions); + + /* start off assuming we have no shell */ + unixy_shell = 0; + no_default_sh_exe = 1; +#endif + + default_goal_file = 0; + reading_file = 0; + +#if defined (__MSDOS__) && !defined (_POSIX_SOURCE) + /* Request the most powerful version of `system', to + make up for the dumb default shell. */ + __system_flags = (__system_redirect + | __system_use_shell + | __system_allow_multiple_cmds + | __system_allow_long_cmds + | __system_handle_null_commands + | __system_emulate_chdir); + +#endif + + /* Set up gettext/internationalization support. */ + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + +#ifdef POSIX + sigemptyset (&fatal_signal_set); +#define ADD_SIG(sig) sigaddset (&fatal_signal_set, sig) +#else +#ifdef HAVE_SIGSETMASK + fatal_signal_mask = 0; +#define ADD_SIG(sig) fatal_signal_mask |= sigmask (sig) +#else +#define ADD_SIG(sig) +#endif +#endif + +#define FATAL_SIG(sig) \ + if (bsd_signal (sig, fatal_error_signal) == SIG_IGN) \ + bsd_signal (sig, SIG_IGN); \ + else \ + ADD_SIG (sig); + +#ifdef SIGHUP + FATAL_SIG (SIGHUP); +#endif +#ifdef SIGQUIT + FATAL_SIG (SIGQUIT); +#endif + FATAL_SIG (SIGINT); + FATAL_SIG (SIGTERM); + +#ifdef __MSDOS__ + /* Windows 9X delivers FP exceptions in child programs to their + parent! We don't want Make to die when a child divides by zero, + so we work around that lossage by catching SIGFPE. */ + FATAL_SIG (SIGFPE); +#endif + +#ifdef SIGDANGER + FATAL_SIG (SIGDANGER); +#endif +#ifdef SIGXCPU + FATAL_SIG (SIGXCPU); +#endif +#ifdef SIGXFSZ + FATAL_SIG (SIGXFSZ); +#endif + +#undef FATAL_SIG + + /* Do not ignore the child-death signal. This must be done before + any children could possibly be created; otherwise, the wait + functions won't work on systems with the SVR4 ECHILD brain + damage, if our invoker is ignoring this signal. */ + +#ifdef HAVE_WAIT_NOHANG +# if defined SIGCHLD + (void) bsd_signal (SIGCHLD, SIG_DFL); +# endif +# if defined SIGCLD && SIGCLD != SIGCHLD + (void) bsd_signal (SIGCLD, SIG_DFL); +# endif +#endif + + /* Make sure stdout is line-buffered. */ + +#ifdef HAVE_SETVBUF +# ifdef SETVBUF_REVERSED + setvbuf (stdout, _IOLBF, xmalloc (BUFSIZ), BUFSIZ); +# else /* setvbuf not reversed. */ + /* Some buggy systems lose if we pass 0 instead of allocating ourselves. */ + setvbuf (stdout, (char *) 0, _IOLBF, BUFSIZ); +# endif /* setvbuf reversed. */ +#elif HAVE_SETLINEBUF + setlinebuf (stdout); +#endif /* setlinebuf missing. */ + + /* Figure out where this program lives. */ + + if (argv[0] == 0) + argv[0] = ""; + if (argv[0][0] == '\0') + program = "make"; + else + { +#ifdef VMS + program = strrchr (argv[0], ']'); +#else + program = strrchr (argv[0], '/'); +#endif +#ifdef __MSDOS__ + if (program == 0) + program = strrchr (argv[0], '\\'); + else + { + /* Some weird environments might pass us argv[0] with + both kinds of slashes; we must find the rightmost. */ + char *p = strrchr (argv[0], '\\'); + if (p && p > program) + program = p; + } + if (program == 0 && argv[0][1] == ':') + program = argv[0] + 1; +#endif + if (program == 0) + program = argv[0]; + else + ++program; + } + + /* Set up to access user data (files). */ + user_access (); + + initialize_global_hash_tables (); + + /* Figure out where we are. */ + +#ifdef WINDOWS32 + if (getcwd_fs (current_directory, GET_PATH_MAX) == 0) +#else + if (getcwd (current_directory, GET_PATH_MAX) == 0) +#endif + { +#ifdef HAVE_GETCWD + perror_with_name ("getcwd: ", ""); +#else + error (NILF, "getwd: %s", current_directory); +#endif + current_directory[0] = '\0'; + directory_before_chdir = 0; + } + else + directory_before_chdir = xstrdup (current_directory); +#ifdef __MSDOS__ + /* Make sure we will return to the initial directory, come what may. */ + atexit (msdos_return_to_initial_directory); +#endif + + /* Initialize the special variables. */ + define_variable (".VARIABLES", 10, "", o_default, 0)->special = 1; + /* define_variable (".TARGETS", 8, "", o_default, 0); */ + + /* Read in variables from the environment. It is important that this be + done before $(MAKE) is figured out so its definitions will not be + from the environment. */ + +#ifndef _AMIGA + for (i = 0; envp[i] != 0; ++i) + { + int do_not_define; + register char *ep = envp[i]; + + /* by default, everything gets defined and exported */ + do_not_define = 0; + + while (*ep != '=') + ++ep; +#ifdef WINDOWS32 + if (!unix_path && strneq(envp[i], "PATH=", 5)) + unix_path = ep+1; + else if (!windows32_path && !strnicmp(envp[i], "Path=", 5)) { + do_not_define = 1; /* it gets defined after loop exits */ + windows32_path = ep+1; + } +#endif + /* The result of pointer arithmetic is cast to unsigned int for + machines where ptrdiff_t is a different size that doesn't widen + the same. */ + if (!do_not_define) + define_variable (envp[i], (unsigned int) (ep - envp[i]), + ep + 1, o_env, 1) + /* Force exportation of every variable culled from the environment. + We used to rely on target_environment's v_default code to do this. + But that does not work for the case where an environment variable + is redefined in a makefile with `override'; it should then still + be exported, because it was originally in the environment. */ + ->export = v_export; + } +#ifdef WINDOWS32 + /* + * Make sure that this particular spelling of 'Path' is available + */ + if (windows32_path) + define_variable("Path", 4, windows32_path, o_env, 1)->export = v_export; + else if (unix_path) + define_variable("Path", 4, unix_path, o_env, 1)->export = v_export; + else + define_variable("Path", 4, "", o_env, 1)->export = v_export; + + /* + * PATH defaults to Path iff PATH not found and Path is found. + */ + if (!unix_path && windows32_path) + define_variable("PATH", 4, windows32_path, o_env, 1)->export = v_export; +#endif +#else /* For Amiga, read the ENV: device, ignoring all dirs */ + { + BPTR env, file, old; + char buffer[1024]; + int len; + __aligned struct FileInfoBlock fib; + + env = Lock ("ENV:", ACCESS_READ); + if (env) + { + old = CurrentDir (DupLock(env)); + Examine (env, &fib); + + while (ExNext (env, &fib)) + { + if (fib.fib_DirEntryType < 0) /* File */ + { + /* Define an empty variable. It will be filled in + variable_lookup(). Makes startup quite a bit + faster. */ + define_variable (fib.fib_FileName, + strlen (fib.fib_FileName), + "", o_env, 1)->export = v_export; + } + } + UnLock (env); + UnLock(CurrentDir(old)); + } + } +#endif + + /* Decode the switches. */ + + decode_env_switches ("MAKEFLAGS", 9); +#if 0 + /* People write things like: + MFLAGS="CC=gcc -pipe" "CFLAGS=-g" + and we set the -p, -i and -e switches. Doesn't seem quite right. */ + decode_env_switches ("MFLAGS", 6); +#endif + decode_switches (argc, argv, 0); +#ifdef WINDOWS32 + if (suspend_flag) { + fprintf(stderr, "%s (pid = %d)\n", argv[0], GetCurrentProcessId()); + fprintf(stderr, _("%s is suspending for 30 seconds..."), argv[0]); + Sleep(30 * 1000); + fprintf(stderr, _("done sleep(30). Continuing.\n")); + } +#endif + + decode_debug_flags (); + + /* Print version information. */ + + if (print_version_flag || print_data_base_flag || db_level) + print_version (); + + /* `make --version' is supposed to just print the version and exit. */ + if (print_version_flag) + die (0); + +#ifndef VMS + /* Set the "MAKE_COMMAND" variable to the name we were invoked with. + (If it is a relative pathname with a slash, prepend our directory name + so the result will run the same program regardless of the current dir. + If it is a name with no slash, we can only hope that PATH did not + find it in the current directory.) */ +#ifdef WINDOWS32 + /* + * Convert from backslashes to forward slashes for + * programs like sh which don't like them. Shouldn't + * matter if the path is one way or the other for + * CreateProcess(). + */ + if (strpbrk(argv[0], "/:\\") || + strstr(argv[0], "..") || + strneq(argv[0], "//", 2)) + argv[0] = xstrdup(w32ify(argv[0],1)); +#else /* WINDOWS32 */ +#ifdef __MSDOS__ + if (strchr (argv[0], '\\')) + { + char *p; + + argv[0] = xstrdup (argv[0]); + for (p = argv[0]; *p; p++) + if (*p == '\\') + *p = '/'; + } + /* If argv[0] is not in absolute form, prepend the current + directory. This can happen when Make is invoked by another DJGPP + program that uses a non-absolute name. */ + if (current_directory[0] != '\0' + && argv[0] != 0 + && (argv[0][0] != '/' && (argv[0][0] == '\0' || argv[0][1] != ':'))) + argv[0] = concat (current_directory, "/", argv[0]); +#else /* !__MSDOS__ */ + if (current_directory[0] != '\0' + && argv[0] != 0 && argv[0][0] != '/' && strchr (argv[0], '/') != 0) + argv[0] = concat (current_directory, "/", argv[0]); +#endif /* !__MSDOS__ */ +#endif /* WINDOWS32 */ +#endif + + /* The extra indirection through $(MAKE_COMMAND) is done + for hysterical raisins. */ + (void) define_variable ("MAKE_COMMAND", 12, argv[0], o_default, 0); + (void) define_variable ("MAKE", 4, "$(MAKE_COMMAND)", o_default, 1); + + if (command_variables != 0) + { + struct command_variable *cv; + struct variable *v; + unsigned int len = 0; + char *value, *p; + + /* Figure out how much space will be taken up by the command-line + variable definitions. */ + for (cv = command_variables; cv != 0; cv = cv->next) + { + v = cv->variable; + len += 2 * strlen (v->name); + if (! v->recursive) + ++len; + ++len; + len += 2 * strlen (v->value); + ++len; + } + + /* Now allocate a buffer big enough and fill it. */ + p = value = (char *) alloca (len); + for (cv = command_variables; cv != 0; cv = cv->next) + { + v = cv->variable; + p = quote_for_env (p, v->name); + if (! v->recursive) + *p++ = ':'; + *p++ = '='; + p = quote_for_env (p, v->value); + *p++ = ' '; + } + p[-1] = '\0'; /* Kill the final space and terminate. */ + + /* Define an unchangeable variable with a name that no POSIX.2 + makefile could validly use for its own variable. */ + (void) define_variable ("-*-command-variables-*-", 23, + value, o_automatic, 0); + + /* Define the variable; this will not override any user definition. + Normally a reference to this variable is written into the value of + MAKEFLAGS, allowing the user to override this value to affect the + exported value of MAKEFLAGS. In POSIX-pedantic mode, we cannot + allow the user's setting of MAKEOVERRIDES to affect MAKEFLAGS, so + a reference to this hidden variable is written instead. */ + (void) define_variable ("MAKEOVERRIDES", 13, + "${-*-command-variables-*-}", o_env, 1); + } + + /* If there were -C flags, move ourselves about. */ + if (directories != 0) + for (i = 0; directories->list[i] != 0; ++i) + { + char *dir = directories->list[i]; + if (dir[0] == '~') + { + char *expanded = tilde_expand (dir); + if (expanded != 0) + dir = expanded; + } + if (chdir (dir) < 0) + pfatal_with_name (dir); + if (dir != directories->list[i]) + free (dir); + } + +#ifdef WINDOWS32 + /* + * THIS BLOCK OF CODE MUST COME AFTER chdir() CALL ABOVE IN ORDER + * TO NOT CONFUSE THE DEPENDENCY CHECKING CODE IN implicit.c. + * + * The functions in dir.c can incorrectly cache information for "." + * before we have changed directory and this can cause file + * lookups to fail because the current directory (.) was pointing + * at the wrong place when it was first evaluated. + */ + no_default_sh_exe = !find_and_set_default_shell(NULL); + +#endif /* WINDOWS32 */ + /* Figure out the level of recursion. */ + { + struct variable *v = lookup_variable (MAKELEVEL_NAME, MAKELEVEL_LENGTH); + if (v != 0 && v->value[0] != '\0' && v->value[0] != '-') + makelevel = (unsigned int) atoi (v->value); + else + makelevel = 0; + } + + /* Except under -s, always do -w in sub-makes and under -C. */ + if (!silent_flag && (directories != 0 || makelevel > 0)) + print_directory_flag = 1; + + /* Let the user disable that with --no-print-directory. */ + if (inhibit_print_directory_flag) + print_directory_flag = 0; + + /* If -R was given, set -r too (doesn't make sense otherwise!) */ + if (no_builtin_variables_flag) + no_builtin_rules_flag = 1; + + /* Construct the list of include directories to search. */ + + construct_include_path (include_directories == 0 ? (char **) 0 + : include_directories->list); + + /* Figure out where we are now, after chdir'ing. */ + if (directories == 0) + /* We didn't move, so we're still in the same place. */ + starting_directory = current_directory; + else + { +#ifdef WINDOWS32 + if (getcwd_fs (current_directory, GET_PATH_MAX) == 0) +#else + if (getcwd (current_directory, GET_PATH_MAX) == 0) +#endif + { +#ifdef HAVE_GETCWD + perror_with_name ("getcwd: ", ""); +#else + error (NILF, "getwd: %s", current_directory); +#endif + starting_directory = 0; + } + else + starting_directory = current_directory; + } + + (void) define_variable ("CURDIR", 6, current_directory, o_default, 0); + + /* Read any stdin makefiles into temporary files. */ + + if (makefiles != 0) + { + register unsigned int i; + for (i = 0; i < makefiles->idx; ++i) + if (makefiles->list[i][0] == '-' && makefiles->list[i][1] == '\0') + { + /* This makefile is standard input. Since we may re-exec + and thus re-read the makefiles, we read standard input + into a temporary file and read from that. */ + FILE *outfile; + char *template, *tmpdir; + + if (stdin_nm) + fatal (NILF, _("Makefile from standard input specified twice.")); + +#ifdef VMS +# define DEFAULT_TMPDIR "sys$scratch:" +#else +# ifdef P_tmpdir +# define DEFAULT_TMPDIR P_tmpdir +# else +# define DEFAULT_TMPDIR "/tmp" +# endif +#endif +#define DEFAULT_TMPFILE "GmXXXXXX" + + if (((tmpdir = getenv ("TMPDIR")) == NULL || *tmpdir == '\0') +#if defined __MSDOS__ || defined(WINDOWS32) + /* These are also used commonly on these platforms. */ + && ((tmpdir = getenv ("TEMP")) == NULL || *tmpdir == '\0') + && ((tmpdir = getenv ("TMP")) == NULL || *tmpdir == '\0') +#endif + ) + tmpdir = DEFAULT_TMPDIR; + + template = (char *) alloca (strlen (tmpdir) + + sizeof (DEFAULT_TMPFILE) + 1); + strcpy (template, tmpdir); + +#ifdef HAVE_DOS_PATHS + if (strchr ("/\\", template[strlen (template) - 1]) == NULL) + strcat (template, "/"); +#else +# ifndef VMS + if (template[strlen (template) - 1] != '/') + strcat (template, "/"); +# endif /* !VMS */ +#endif /* !HAVE_DOS_PATHS */ + + strcat (template, DEFAULT_TMPFILE); + outfile = open_tmpfile (&stdin_nm, template); + if (outfile == 0) + pfatal_with_name (_("fopen (temporary file)")); + while (!feof (stdin)) + { + char buf[2048]; + unsigned int n = fread (buf, 1, sizeof (buf), stdin); + if (n > 0 && fwrite (buf, 1, n, outfile) != n) + pfatal_with_name (_("fwrite (temporary file)")); + } + (void) fclose (outfile); + + /* Replace the name that read_all_makefiles will + see with the name of the temporary file. */ + makefiles->list[i] = xstrdup (stdin_nm); + + /* Make sure the temporary file will not be remade. */ + f = enter_file (stdin_nm); + f->updated = 1; + f->update_status = 0; + f->command_state = cs_finished; + /* Can't be intermediate, or it'll be removed too early for + make re-exec. */ + f->intermediate = 0; + f->dontcare = 0; + } + } + +#if defined(MAKE_JOBSERVER) || !defined(HAVE_WAIT_NOHANG) + /* Set up to handle children dying. This must be done before + reading in the makefiles so that `shell' function calls will work. + + If we don't have a hanging wait we have to fall back to old, broken + functionality here and rely on the signal handler and counting + children. + + If we're using the jobs pipe we need a signal handler so that + SIGCHLD is not ignored; we need it to interrupt the read(2) of the + jobserver pipe in job.c if we're waiting for a token. + + If none of these are true, we don't need a signal handler at all. */ + { + extern RETSIGTYPE child_handler PARAMS ((int sig)); +# if defined SIGCHLD + bsd_signal (SIGCHLD, child_handler); +# endif +# if defined SIGCLD && SIGCLD != SIGCHLD + bsd_signal (SIGCLD, child_handler); +# endif + } +#endif + + /* Let the user send us SIGUSR1 to toggle the -d flag during the run. */ +#ifdef SIGUSR1 + bsd_signal (SIGUSR1, debug_signal_handler); +#endif + + /* Define the initial list of suffixes for old-style rules. */ + + set_default_suffixes (); + + /* Define the file rules for the built-in suffix rules. These will later + be converted into pattern rules. We used to do this in + install_default_implicit_rules, but since that happens after reading + makefiles, it results in the built-in pattern rules taking precedence + over makefile-specified suffix rules, which is wrong. */ + + install_default_suffix_rules (); + + /* Define some internal and special variables. */ + + define_automatic_variables (); + + /* Set up the MAKEFLAGS and MFLAGS variables + so makefiles can look at them. */ + + define_makeflags (0, 0); + + /* Define the default variables. */ + define_default_variables (); + + /* Read all the makefiles. */ + + default_file = enter_file (".DEFAULT"); + + read_makefiles + = read_all_makefiles (makefiles == 0 ? (char **) 0 : makefiles->list); + +#ifdef WINDOWS32 + /* look one last time after reading all Makefiles */ + if (no_default_sh_exe) + no_default_sh_exe = !find_and_set_default_shell(NULL); + + if (no_default_sh_exe && job_slots != 1) { + error (NILF, _("Do not specify -j or --jobs if sh.exe is not available.")); + error (NILF, _("Resetting make for single job mode.")); + job_slots = 1; + } +#endif /* WINDOWS32 */ + +#ifdef __MSDOS__ + /* We need to know what kind of shell we will be using. */ + { + extern int _is_unixy_shell (const char *_path); + struct variable *shv = lookup_variable ("SHELL", 5); + extern int unixy_shell; + extern char *default_shell; + + if (shv && *shv->value) + { + char *shell_path = recursively_expand(shv); + + if (shell_path && _is_unixy_shell (shell_path)) + unixy_shell = 1; + else + unixy_shell = 0; + if (shell_path) + default_shell = shell_path; + } + } +#endif /* __MSDOS__ */ + + /* Decode switches again, in case the variables were set by the makefile. */ + decode_env_switches ("MAKEFLAGS", 9); +#if 0 + decode_env_switches ("MFLAGS", 6); +#endif + +#ifdef __MSDOS__ + if (job_slots != 1) + { + error (NILF, + _("Parallel jobs (-j) are not supported on this platform.")); + error (NILF, _("Resetting to single job (-j1) mode.")); + job_slots = 1; + } +#endif + +#ifdef MAKE_JOBSERVER + /* If the jobserver-fds option is seen, make sure that -j is reasonable. */ + + if (jobserver_fds) + { + char *cp; + + for (i=1; i < jobserver_fds->idx; ++i) + if (!streq (jobserver_fds->list[0], jobserver_fds->list[i])) + fatal (NILF, _("internal error: multiple --jobserver-fds options")); + + /* Now parse the fds string and make sure it has the proper format. */ + + cp = jobserver_fds->list[0]; + + if (sscanf (cp, "%d,%d", &job_fds[0], &job_fds[1]) != 2) + fatal (NILF, + _("internal error: invalid --jobserver-fds string `%s'"), cp); + + /* The combination of a pipe + !job_slots means we're using the + jobserver. If !job_slots and we don't have a pipe, we can start + infinite jobs. If we see both a pipe and job_slots >0 that means the + user set -j explicitly. This is broken; in this case obey the user + (ignore the jobserver pipe for this make) but print a message. */ + + if (job_slots > 0) + error (NILF, + _("warning: -jN forced in submake: disabling jobserver mode.")); + + /* Create a duplicate pipe, that will be closed in the SIGCHLD + handler. If this fails with EBADF, the parent has closed the pipe + on us because it didn't think we were a submake. If so, print a + warning then default to -j1. */ + + else if ((job_rfd = dup (job_fds[0])) < 0) + { + if (errno != EBADF) + pfatal_with_name (_("dup jobserver")); + + error (NILF, + _("warning: jobserver unavailable: using -j1. Add `+' to parent make rule.")); + job_slots = 1; + } + + if (job_slots > 0) + { + close (job_fds[0]); + close (job_fds[1]); + job_fds[0] = job_fds[1] = -1; + free (jobserver_fds->list); + free (jobserver_fds); + jobserver_fds = 0; + } + } + + /* If we have >1 slot but no jobserver-fds, then we're a top-level make. + Set up the pipe and install the fds option for our children. */ + + if (job_slots > 1) + { + char c = '+'; + + if (pipe (job_fds) < 0 || (job_rfd = dup (job_fds[0])) < 0) + pfatal_with_name (_("creating jobs pipe")); + + /* Every make assumes that it always has one job it can run. For the + submakes it's the token they were given by their parent. For the + top make, we just subtract one from the number the user wants. We + want job_slots to be 0 to indicate we're using the jobserver. */ + + while (--job_slots) + if (write (job_fds[1], &c, 1) != 1) + pfatal_with_name (_("init jobserver pipe")); + + /* Fill in the jobserver_fds struct for our children. */ + + jobserver_fds = (struct stringlist *) + xmalloc (sizeof (struct stringlist)); + jobserver_fds->list = (char **) xmalloc (sizeof (char *)); + jobserver_fds->list[0] = xmalloc ((sizeof ("1024")*2)+1); + + sprintf (jobserver_fds->list[0], "%d,%d", job_fds[0], job_fds[1]); + jobserver_fds->idx = 1; + jobserver_fds->max = 1; + } +#endif + + /* Set up MAKEFLAGS and MFLAGS again, so they will be right. */ + + define_makeflags (1, 0); + + /* Make each `struct dep' point at the `struct file' for the file + depended on. Also do magic for special targets. */ + + snap_deps (); + + /* Convert old-style suffix rules to pattern rules. It is important to + do this before installing the built-in pattern rules below, so that + makefile-specified suffix rules take precedence over built-in pattern + rules. */ + + convert_to_pattern (); + + /* Install the default implicit pattern rules. + This used to be done before reading the makefiles. + But in that case, built-in pattern rules were in the chain + before user-defined ones, so they matched first. */ + + install_default_implicit_rules (); + + /* Compute implicit rule limits. */ + + count_implicit_rule_limits (); + + /* Construct the listings of directories in VPATH lists. */ + + build_vpath_lists (); + + /* Mark files given with -o flags as very old + and as having been updated already, and files given with -W flags as + brand new (time-stamp as far as possible into the future). */ + + if (old_files != 0) + for (p = old_files->list; *p != 0; ++p) + { + f = enter_command_line_file (*p); + f->last_mtime = f->mtime_before_update = OLD_MTIME; + f->updated = 1; + f->update_status = 0; + f->command_state = cs_finished; + } + + if (new_files != 0) + { + for (p = new_files->list; *p != 0; ++p) + { + f = enter_command_line_file (*p); + f->last_mtime = f->mtime_before_update = NEW_MTIME; + } + } + + /* Initialize the remote job module. */ + remote_setup (); + + if (read_makefiles != 0) + { + /* Update any makefiles if necessary. */ + + FILE_TIMESTAMP *makefile_mtimes = 0; + unsigned int mm_idx = 0; + char **nargv = argv; + int nargc = argc; + int orig_db_level = db_level; + + if (! ISDB (DB_MAKEFILES)) + db_level = DB_NONE; + + DB (DB_BASIC, (_("Updating makefiles....\n"))); + + /* Remove any makefiles we don't want to try to update. + Also record the current modtimes so we can compare them later. */ + { + register struct dep *d, *last; + last = 0; + d = read_makefiles; + while (d != 0) + { + register struct file *f = d->file; + if (f->double_colon) + for (f = f->double_colon; f != NULL; f = f->prev) + { + if (f->deps == 0 && f->cmds != 0) + { + /* This makefile is a :: target with commands, but + no dependencies. So, it will always be remade. + This might well cause an infinite loop, so don't + try to remake it. (This will only happen if + your makefiles are written exceptionally + stupidly; but if you work for Athena, that's how + you write your makefiles.) */ + + DB (DB_VERBOSE, + (_("Makefile `%s' might loop; not remaking it.\n"), + f->name)); + + if (last == 0) + read_makefiles = d->next; + else + last->next = d->next; + + /* Free the storage. */ + free ((char *) d); + + d = last == 0 ? read_makefiles : last->next; + + break; + } + } + if (f == NULL || !f->double_colon) + { + makefile_mtimes = (FILE_TIMESTAMP *) + xrealloc ((char *) makefile_mtimes, + (mm_idx + 1) * sizeof (FILE_TIMESTAMP)); + makefile_mtimes[mm_idx++] = file_mtime_no_search (d->file); + last = d; + d = d->next; + } + } + } + + /* Set up `MAKEFLAGS' specially while remaking makefiles. */ + define_makeflags (1, 1); + + switch (update_goal_chain (read_makefiles, 1)) + { + case 1: + /* The only way this can happen is if the user specified -q and asked + * for one of the makefiles to be remade as a target on the command + * line. Since we're not actually updating anything with -q we can + * treat this as "did nothing". + */ + + case -1: + /* Did nothing. */ + break; + + case 2: + /* Failed to update. Figure out if we care. */ + { + /* Nonzero if any makefile was successfully remade. */ + int any_remade = 0; + /* Nonzero if any makefile we care about failed + in updating or could not be found at all. */ + int any_failed = 0; + register unsigned int i; + struct dep *d; + + for (i = 0, d = read_makefiles; d != 0; ++i, d = d->next) + { + /* Reset the considered flag; we may need to look at the file + again to print an error. */ + d->file->considered = 0; + + if (d->file->updated) + { + /* This makefile was updated. */ + if (d->file->update_status == 0) + { + /* It was successfully updated. */ + any_remade |= (file_mtime_no_search (d->file) + != makefile_mtimes[i]); + } + else if (! (d->changed & RM_DONTCARE)) + { + FILE_TIMESTAMP mtime; + /* The update failed and this makefile was not + from the MAKEFILES variable, so we care. */ + error (NILF, _("Failed to remake makefile `%s'."), + d->file->name); + mtime = file_mtime_no_search (d->file); + any_remade |= (mtime != NONEXISTENT_MTIME + && mtime != makefile_mtimes[i]); + } + } + else + /* This makefile was not found at all. */ + if (! (d->changed & RM_DONTCARE)) + { + /* This is a makefile we care about. See how much. */ + if (d->changed & RM_INCLUDED) + /* An included makefile. We don't need + to die, but we do want to complain. */ + error (NILF, + _("Included makefile `%s' was not found."), + dep_name (d)); + else + { + /* A normal makefile. We must die later. */ + error (NILF, _("Makefile `%s' was not found"), + dep_name (d)); + any_failed = 1; + } + } + } + /* Reset this to empty so we get the right error message below. */ + read_makefiles = 0; + + if (any_remade) + goto re_exec; + if (any_failed) + die (2); + break; + } + + case 0: + re_exec: + /* Updated successfully. Re-exec ourselves. */ + + remove_intermediates (0); + + if (print_data_base_flag) + print_data_base (); + + log_working_directory (0); + + if (makefiles != 0) + { + /* These names might have changed. */ + register unsigned int i, j = 0; + for (i = 1; i < argc; ++i) + if (strneq (argv[i], "-f", 2)) /* XXX */ + { + char *p = &argv[i][2]; + if (*p == '\0') + argv[++i] = makefiles->list[j]; + else + argv[i] = concat ("-f", makefiles->list[j], ""); + ++j; + } + } + + /* Add -o option for the stdin temporary file, if necessary. */ + if (stdin_nm) + { + nargv = (char **) xmalloc ((nargc + 2) * sizeof (char *)); + bcopy ((char *) argv, (char *) nargv, argc * sizeof (char *)); + nargv[nargc++] = concat ("-o", stdin_nm, ""); + nargv[nargc] = 0; + } + + if (directories != 0 && directories->idx > 0) + { + char bad; + if (directory_before_chdir != 0) + { + if (chdir (directory_before_chdir) < 0) + { + perror_with_name ("chdir", ""); + bad = 1; + } + else + bad = 0; + } + else + bad = 1; + if (bad) + fatal (NILF, _("Couldn't change back to original directory.")); + } + +#ifndef _AMIGA + for (p = environ; *p != 0; ++p) + if ((*p)[MAKELEVEL_LENGTH] == '=' + && strneq (*p, MAKELEVEL_NAME, MAKELEVEL_LENGTH)) + { + /* The SGI compiler apparently can't understand + the concept of storing the result of a function + in something other than a local variable. */ + char *sgi_loses; + sgi_loses = (char *) alloca (40); + *p = sgi_loses; + sprintf (*p, "%s=%u", MAKELEVEL_NAME, makelevel); + break; + } +#else /* AMIGA */ + { + char buffer[256]; + int len; + + len = GetVar (MAKELEVEL_NAME, buffer, sizeof (buffer), GVF_GLOBAL_ONLY); + + if (len != -1) + { + sprintf (buffer, "%u", makelevel); + SetVar (MAKELEVEL_NAME, buffer, -1, GVF_GLOBAL_ONLY); + } + } +#endif + + if (ISDB (DB_BASIC)) + { + char **p; + fputs (_("Re-executing:"), stdout); + for (p = nargv; *p != 0; ++p) + printf (" %s", *p); + putchar ('\n'); + } + + fflush (stdout); + fflush (stderr); + + /* Close the dup'd jobserver pipe if we opened one. */ + if (job_rfd >= 0) + close (job_rfd); + +#ifndef _AMIGA + exec_command (nargv, environ); +#else + exec_command (nargv); + exit (0); +#endif + /* NOTREACHED */ + + default: +#define BOGUS_UPDATE_STATUS 0 + assert (BOGUS_UPDATE_STATUS); + break; + } + + db_level = orig_db_level; + } + + /* Set up `MAKEFLAGS' again for the normal targets. */ + define_makeflags (1, 0); + + /* If there is a temp file from reading a makefile from stdin, get rid of + it now. */ + if (stdin_nm && unlink (stdin_nm) < 0 && errno != ENOENT) + perror_with_name (_("unlink (temporary file): "), stdin_nm); + + { + int status; + + /* If there were no command-line goals, use the default. */ + if (goals == 0) + { + if (default_goal_file != 0) + { + goals = (struct dep *) xmalloc (sizeof (struct dep)); + goals->next = 0; + goals->name = 0; + goals->ignore_mtime = 0; + goals->file = default_goal_file; + } + } + else + lastgoal->next = 0; + + if (!goals) + { + if (read_makefiles == 0) + fatal (NILF, _("No targets specified and no makefile found")); + + fatal (NILF, _("No targets")); + } + + /* Update the goals. */ + + DB (DB_BASIC, (_("Updating goal targets....\n"))); + + switch (update_goal_chain (goals, 0)) + { + case -1: + /* Nothing happened. */ + case 0: + /* Updated successfully. */ + status = MAKE_SUCCESS; + break; + case 1: + /* We are under -q and would run some commands. */ + status = MAKE_TROUBLE; + break; + case 2: + /* Updating failed. POSIX.2 specifies exit status >1 for this; + but in VMS, there is only success and failure. */ + status = MAKE_FAILURE; + break; + default: + abort (); + } + + /* If we detected some clock skew, generate one last warning */ + if (clock_skew_detected) + error (NILF, + _("warning: Clock skew detected. Your build may be incomplete.")); + + /* Exit. */ + die (status); + } + + return 0; +} + +/* Parsing of arguments, decoding of switches. */ + +static char options[1 + sizeof (switches) / sizeof (switches[0]) * 3]; +static struct option long_options[(sizeof (switches) / sizeof (switches[0])) + + (sizeof (long_option_aliases) / + sizeof (long_option_aliases[0]))]; + +/* Fill in the string and vector for getopt. */ +static void +init_switches () +{ + register char *p; + register int c; + register unsigned int i; + + if (options[0] != '\0') + /* Already done. */ + return; + + p = options; + + /* Return switch and non-switch args in order, regardless of + POSIXLY_CORRECT. Non-switch args are returned as option 1. */ + *p++ = '-'; + + for (i = 0; switches[i].c != '\0'; ++i) + { + long_options[i].name = (switches[i].long_name == 0 ? "" : + switches[i].long_name); + long_options[i].flag = 0; + long_options[i].val = switches[i].c; + if (short_option (switches[i].c)) + *p++ = switches[i].c; + switch (switches[i].type) + { + case flag: + case flag_off: + case ignore: + long_options[i].has_arg = no_argument; + break; + + case string: + case positive_int: + case floating: + if (short_option (switches[i].c)) + *p++ = ':'; + if (switches[i].noarg_value != 0) + { + if (short_option (switches[i].c)) + *p++ = ':'; + long_options[i].has_arg = optional_argument; + } + else + long_options[i].has_arg = required_argument; + break; + } + } + *p = '\0'; + for (c = 0; c < (sizeof (long_option_aliases) / + sizeof (long_option_aliases[0])); + ++c) + long_options[i++] = long_option_aliases[c]; + long_options[i].name = 0; +} + +static void +handle_non_switch_argument (arg, env) + char *arg; + int env; +{ + /* Non-option argument. It might be a variable definition. */ + struct variable *v; + if (arg[0] == '-' && arg[1] == '\0') + /* Ignore plain `-' for compatibility. */ + return; + v = try_variable_definition (0, arg, o_command, 0); + if (v != 0) + { + /* It is indeed a variable definition. Record a pointer to + the variable for later use in define_makeflags. */ + struct command_variable *cv + = (struct command_variable *) xmalloc (sizeof (*cv)); + cv->variable = v; + cv->next = command_variables; + command_variables = cv; + } + else if (! env) + { + /* Not an option or variable definition; it must be a goal + target! Enter it as a file and add it to the dep chain of + goals. */ + struct file *f = enter_command_line_file (arg); + f->cmd_target = 1; + + if (goals == 0) + { + goals = (struct dep *) xmalloc (sizeof (struct dep)); + lastgoal = goals; + } + else + { + lastgoal->next = (struct dep *) xmalloc (sizeof (struct dep)); + lastgoal = lastgoal->next; + } + lastgoal->name = 0; + lastgoal->file = f; + lastgoal->ignore_mtime = 0; + + { + /* Add this target name to the MAKECMDGOALS variable. */ + struct variable *v; + char *value; + + v = lookup_variable ("MAKECMDGOALS", 12); + if (v == 0) + value = f->name; + else + { + /* Paste the old and new values together */ + unsigned int oldlen, newlen; + + oldlen = strlen (v->value); + newlen = strlen (f->name); + value = (char *) alloca (oldlen + 1 + newlen + 1); + bcopy (v->value, value, oldlen); + value[oldlen] = ' '; + bcopy (f->name, &value[oldlen + 1], newlen + 1); + } + define_variable ("MAKECMDGOALS", 12, value, o_default, 0); + } + } +} + +/* Print a nice usage method. */ + +static void +print_usage (bad) + int bad; +{ + extern char *make_host; + const char *const *cpp; + FILE *usageto; + + if (print_version_flag) + print_version (); + + usageto = bad ? stderr : stdout; + + fprintf (usageto, _("Usage: %s [options] [target] ...\n"), program); + + for (cpp = usage; *cpp; ++cpp) + fputs (_(*cpp), usageto); + + if (!remote_description || *remote_description == '\0') + fprintf (usageto, _("\nThis program built for %s\n"), make_host); + else + fprintf (usageto, _("\nThis program built for %s (%s)\n"), + make_host, remote_description); + + fprintf (usageto, _("Report bugs to \n")); +} + +/* Decode switches from ARGC and ARGV. + They came from the environment if ENV is nonzero. */ + +static void +decode_switches (argc, argv, env) + int argc; + char **argv; + int env; +{ + int bad = 0; + register const struct command_switch *cs; + register struct stringlist *sl; + register int c; + + /* getopt does most of the parsing for us. + First, get its vectors set up. */ + + init_switches (); + + /* Let getopt produce error messages for the command line, + but not for options from the environment. */ + opterr = !env; + /* Reset getopt's state. */ + optind = 0; + + while (optind < argc) + { + /* Parse the next argument. */ + c = getopt_long (argc, argv, options, long_options, (int *) 0); + if (c == EOF) + /* End of arguments, or "--" marker seen. */ + break; + else if (c == 1) + /* An argument not starting with a dash. */ + handle_non_switch_argument (optarg, env); + else if (c == '?') + /* Bad option. We will print a usage message and die later. + But continue to parse the other options so the user can + see all he did wrong. */ + bad = 1; + else + for (cs = switches; cs->c != '\0'; ++cs) + if (cs->c == c) + { + /* Whether or not we will actually do anything with + this switch. We test this individually inside the + switch below rather than just once outside it, so that + options which are to be ignored still consume args. */ + int doit = !env || cs->env; + + switch (cs->type) + { + default: + abort (); + + case ignore: + break; + + case flag: + case flag_off: + if (doit) + *(int *) cs->value_ptr = cs->type == flag; + break; + + case string: + if (!doit) + break; + + if (optarg == 0) + optarg = cs->noarg_value; + + sl = *(struct stringlist **) cs->value_ptr; + if (sl == 0) + { + sl = (struct stringlist *) + xmalloc (sizeof (struct stringlist)); + sl->max = 5; + sl->idx = 0; + sl->list = (char **) xmalloc (5 * sizeof (char *)); + *(struct stringlist **) cs->value_ptr = sl; + } + else if (sl->idx == sl->max - 1) + { + sl->max += 5; + sl->list = (char **) + xrealloc ((char *) sl->list, + sl->max * sizeof (char *)); + } + sl->list[sl->idx++] = optarg; + sl->list[sl->idx] = 0; + break; + + case positive_int: + /* See if we have an option argument; if we do require that + it's all digits, not something like "10foo". */ + if (optarg == 0 && argc > optind) + { + const char *cp; + for (cp=argv[optind]; ISDIGIT (cp[0]); ++cp) + ; + if (cp[0] == '\0') + optarg = argv[optind++]; + } + + if (!doit) + break; + + if (optarg != 0) + { + int i = atoi (optarg); + const char *cp; + + /* Yes, I realize we're repeating this in some cases. */ + for (cp = optarg; ISDIGIT (cp[0]); ++cp) + ; + + if (i < 1 || cp[0] != '\0') + { + error (NILF, _("the `-%c' option requires a positive integral argument"), + cs->c); + bad = 1; + } + else + *(unsigned int *) cs->value_ptr = i; + } + else + *(unsigned int *) cs->value_ptr + = *(unsigned int *) cs->noarg_value; + break; + +#ifndef NO_FLOAT + case floating: + if (optarg == 0 && optind < argc + && (ISDIGIT (argv[optind][0]) || argv[optind][0] == '.')) + optarg = argv[optind++]; + + if (doit) + *(double *) cs->value_ptr + = (optarg != 0 ? atof (optarg) + : *(double *) cs->noarg_value); + + break; +#endif + } + + /* We've found the switch. Stop looking. */ + break; + } + } + + /* There are no more options according to getting getopt, but there may + be some arguments left. Since we have asked for non-option arguments + to be returned in order, this only happens when there is a "--" + argument to prevent later arguments from being options. */ + while (optind < argc) + handle_non_switch_argument (argv[optind++], env); + + + if (!env && (bad || print_usage_flag)) + { + print_usage (bad); + die (bad ? 2 : 0); + } +} + +/* Decode switches from environment variable ENVAR (which is LEN chars long). + We do this by chopping the value into a vector of words, prepending a + dash to the first word if it lacks one, and passing the vector to + decode_switches. */ + +static void +decode_env_switches (envar, len) + char *envar; + unsigned int len; +{ + char *varref = (char *) alloca (2 + len + 2); + char *value, *p; + int argc; + char **argv; + + /* Get the variable's value. */ + varref[0] = '$'; + varref[1] = '('; + bcopy (envar, &varref[2], len); + varref[2 + len] = ')'; + varref[2 + len + 1] = '\0'; + value = variable_expand (varref); + + /* Skip whitespace, and check for an empty value. */ + value = next_token (value); + len = strlen (value); + if (len == 0) + return; + + /* Allocate a vector that is definitely big enough. */ + argv = (char **) alloca ((1 + len + 1) * sizeof (char *)); + + /* Allocate a buffer to copy the value into while we split it into words + and unquote it. We must use permanent storage for this because + decode_switches may store pointers into the passed argument words. */ + p = (char *) xmalloc (2 * len); + + /* getopt will look at the arguments starting at ARGV[1]. + Prepend a spacer word. */ + argv[0] = 0; + argc = 1; + argv[argc] = p; + while (*value != '\0') + { + if (*value == '\\' && value[1] != '\0') + ++value; /* Skip the backslash. */ + else if (isblank ((unsigned char)*value)) + { + /* End of the word. */ + *p++ = '\0'; + argv[++argc] = p; + do + ++value; + while (isblank ((unsigned char)*value)); + continue; + } + *p++ = *value++; + } + *p = '\0'; + argv[++argc] = 0; + + if (argv[1][0] != '-' && strchr (argv[1], '=') == 0) + /* The first word doesn't start with a dash and isn't a variable + definition. Add a dash and pass it along to decode_switches. We + need permanent storage for this in case decode_switches saves + pointers into the value. */ + argv[1] = concat ("-", argv[1], ""); + + /* Parse those words. */ + decode_switches (argc, argv, 1); +} + +/* Quote the string IN so that it will be interpreted as a single word with + no magic by decode_env_switches; also double dollar signs to avoid + variable expansion in make itself. Write the result into OUT, returning + the address of the next character to be written. + Allocating space for OUT twice the length of IN is always sufficient. */ + +static char * +quote_for_env (out, in) + char *out, *in; +{ + while (*in != '\0') + { + if (*in == '$') + *out++ = '$'; + else if (isblank ((unsigned char)*in) || *in == '\\') + *out++ = '\\'; + *out++ = *in++; + } + + return out; +} + +/* Define the MAKEFLAGS and MFLAGS variables to reflect the settings of the + command switches. Include options with args if ALL is nonzero. + Don't include options with the `no_makefile' flag set if MAKEFILE. */ + +static void +define_makeflags (all, makefile) + int all, makefile; +{ + static const char ref[] = "$(MAKEOVERRIDES)"; + static const char posixref[] = "$(-*-command-variables-*-)"; + register const struct command_switch *cs; + char *flagstring; + register char *p; + unsigned int words; + struct variable *v; + + /* We will construct a linked list of `struct flag's describing + all the flags which need to go in MAKEFLAGS. Then, once we + know how many there are and their lengths, we can put them all + together in a string. */ + + struct flag + { + struct flag *next; + const struct command_switch *cs; + char *arg; + }; + struct flag *flags = 0; + unsigned int flagslen = 0; +#define ADD_FLAG(ARG, LEN) \ + do { \ + struct flag *new = (struct flag *) alloca (sizeof (struct flag)); \ + new->cs = cs; \ + new->arg = (ARG); \ + new->next = flags; \ + flags = new; \ + if (new->arg == 0) \ + ++flagslen; /* Just a single flag letter. */ \ + else \ + flagslen += 1 + 1 + 1 + 1 + 3 * (LEN); /* " -x foo" */ \ + if (!short_option (cs->c)) \ + /* This switch has no single-letter version, so we use the long. */ \ + flagslen += 2 + strlen (cs->long_name); \ + } while (0) + + for (cs = switches; cs->c != '\0'; ++cs) + if (cs->toenv && (!makefile || !cs->no_makefile)) + switch (cs->type) + { + default: + abort (); + + case ignore: + break; + + case flag: + case flag_off: + if (!*(int *) cs->value_ptr == (cs->type == flag_off) + && (cs->default_value == 0 + || *(int *) cs->value_ptr != *(int *) cs->default_value)) + ADD_FLAG (0, 0); + break; + + case positive_int: + if (all) + { + if ((cs->default_value != 0 + && (*(unsigned int *) cs->value_ptr + == *(unsigned int *) cs->default_value))) + break; + else if (cs->noarg_value != 0 + && (*(unsigned int *) cs->value_ptr == + *(unsigned int *) cs->noarg_value)) + ADD_FLAG ("", 0); /* Optional value omitted; see below. */ + else if (cs->c == 'j') + /* Special case for `-j'. */ + ADD_FLAG ("1", 1); + else + { + char *buf = (char *) alloca (30); + sprintf (buf, "%u", *(unsigned int *) cs->value_ptr); + ADD_FLAG (buf, strlen (buf)); + } + } + break; + +#ifndef NO_FLOAT + case floating: + if (all) + { + if (cs->default_value != 0 + && (*(double *) cs->value_ptr + == *(double *) cs->default_value)) + break; + else if (cs->noarg_value != 0 + && (*(double *) cs->value_ptr + == *(double *) cs->noarg_value)) + ADD_FLAG ("", 0); /* Optional value omitted; see below. */ + else + { + char *buf = (char *) alloca (100); + sprintf (buf, "%g", *(double *) cs->value_ptr); + ADD_FLAG (buf, strlen (buf)); + } + } + break; +#endif + + case string: + if (all) + { + struct stringlist *sl = *(struct stringlist **) cs->value_ptr; + if (sl != 0) + { + /* Add the elements in reverse order, because + all the flags get reversed below; and the order + matters for some switches (like -I). */ + register unsigned int i = sl->idx; + while (i-- > 0) + ADD_FLAG (sl->list[i], strlen (sl->list[i])); + } + } + break; + } + + flagslen += 4 + sizeof posixref; /* Four more for the possible " -- ". */ + +#undef ADD_FLAG + + /* Construct the value in FLAGSTRING. + We allocate enough space for a preceding dash and trailing null. */ + flagstring = (char *) alloca (1 + flagslen + 1); + bzero (flagstring, 1 + flagslen + 1); + p = flagstring; + words = 1; + *p++ = '-'; + while (flags != 0) + { + /* Add the flag letter or name to the string. */ + if (short_option (flags->cs->c)) + *p++ = flags->cs->c; + else + { + if (*p != '-') + { + *p++ = ' '; + *p++ = '-'; + } + *p++ = '-'; + strcpy (p, flags->cs->long_name); + p += strlen (p); + } + if (flags->arg != 0) + { + /* A flag that takes an optional argument which in this case is + omitted is specified by ARG being "". We must distinguish + because a following flag appended without an intervening " -" + is considered the arg for the first. */ + if (flags->arg[0] != '\0') + { + /* Add its argument too. */ + *p++ = !short_option (flags->cs->c) ? '=' : ' '; + p = quote_for_env (p, flags->arg); + } + ++words; + /* Write a following space and dash, for the next flag. */ + *p++ = ' '; + *p++ = '-'; + } + else if (!short_option (flags->cs->c)) + { + ++words; + /* Long options must each go in their own word, + so we write the following space and dash. */ + *p++ = ' '; + *p++ = '-'; + } + flags = flags->next; + } + + /* Define MFLAGS before appending variable definitions. */ + + if (p == &flagstring[1]) + /* No flags. */ + flagstring[0] = '\0'; + else if (p[-1] == '-') + { + /* Kill the final space and dash. */ + p -= 2; + *p = '\0'; + } + else + /* Terminate the string. */ + *p = '\0'; + + /* Since MFLAGS is not parsed for flags, there is no reason to + override any makefile redefinition. */ + (void) define_variable ("MFLAGS", 6, flagstring, o_env, 1); + + if (all && command_variables != 0) + { + /* Now write a reference to $(MAKEOVERRIDES), which contains all the + command-line variable definitions. */ + + if (p == &flagstring[1]) + /* No flags written, so elide the leading dash already written. */ + p = flagstring; + else + { + /* Separate the variables from the switches with a "--" arg. */ + if (p[-1] != '-') + { + /* We did not already write a trailing " -". */ + *p++ = ' '; + *p++ = '-'; + } + /* There is a trailing " -"; fill it out to " -- ". */ + *p++ = '-'; + *p++ = ' '; + } + + /* Copy in the string. */ + if (posix_pedantic) + { + bcopy (posixref, p, sizeof posixref - 1); + p += sizeof posixref - 1; + } + else + { + bcopy (ref, p, sizeof ref - 1); + p += sizeof ref - 1; + } + } + else if (p == &flagstring[1]) + { + words = 0; + --p; + } + else if (p[-1] == '-') + /* Kill the final space and dash. */ + p -= 2; + /* Terminate the string. */ + *p = '\0'; + + v = define_variable ("MAKEFLAGS", 9, + /* If there are switches, omit the leading dash + unless it is a single long option with two + leading dashes. */ + &flagstring[(flagstring[0] == '-' + && flagstring[1] != '-') + ? 1 : 0], + /* This used to use o_env, but that lost when a + makefile defined MAKEFLAGS. Makefiles set + MAKEFLAGS to add switches, but we still want + to redefine its value with the full set of + switches. Of course, an override or command + definition will still take precedence. */ + o_file, 1); + if (! all) + /* The first time we are called, set MAKEFLAGS to always be exported. + We should not do this again on the second call, because that is + after reading makefiles which might have done `unexport MAKEFLAGS'. */ + v->export = v_export; +} + +/* Print version information. */ + +static void +print_version () +{ + static int printed_version = 0; + + char *precede = print_data_base_flag ? "# " : ""; + + if (printed_version) + /* Do it only once. */ + return; + + /* Print this untranslated. The coding standards recommend translating the + (C) to the copyright symbol, but this string is going to change every + year, and none of the rest of it should be translated (including the + word "Copyright", so it hardly seems worth it. */ + + printf ("%sGNU Make %s\n\ +%sCopyright (C) 2002 Free Software Foundation, Inc.\n", + precede, version_string, precede); + + printf (_("%sThis is free software; see the source for copying conditions.\n\ +%sThere is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\ +%sPARTICULAR PURPOSE.\n"), + precede, precede, precede); + + printed_version = 1; + + /* Flush stdout so the user doesn't have to wait to see the + version information while things are thought about. */ + fflush (stdout); +} + +/* Print a bunch of information about this and that. */ + +static void +print_data_base () +{ + time_t when; + + when = time ((time_t *) 0); + printf (_("\n# Make data base, printed on %s"), ctime (&when)); + + print_variable_data_base (); + print_dir_data_base (); + print_rule_data_base (); + print_file_data_base (); + print_vpath_data_base (); + + when = time ((time_t *) 0); + printf (_("\n# Finished Make data base on %s\n"), ctime (&when)); +} + +/* Exit with STATUS, cleaning up as necessary. */ + +void +die (status) + int status; +{ + static char dying = 0; + + if (!dying) + { + int err; + + dying = 1; + + if (print_version_flag) + print_version (); + + /* Wait for children to die. */ + for (err = (status != 0); job_slots_used > 0; err = 0) + reap_children (1, err); + + /* Let the remote job module clean up its state. */ + remote_cleanup (); + + /* Remove the intermediate files. */ + remove_intermediates (0); + + if (print_data_base_flag) + print_data_base (); + + /* Try to move back to the original directory. This is essential on + MS-DOS (where there is really only one process), and on Unix it + puts core files in the original directory instead of the -C + directory. Must wait until after remove_intermediates(), or unlinks + of relative pathnames fail. */ + if (directory_before_chdir != 0) + chdir (directory_before_chdir); + + log_working_directory (0); + } + + exit (status); +} + +/* Write a message indicating that we've just entered or + left (according to ENTERING) the current directory. */ + +void +log_working_directory (entering) + int entering; +{ + static int entered = 0; + + /* Print nothing without the flag. Don't print the entering message + again if we already have. Don't print the leaving message if we + haven't printed the entering message. */ + if (! print_directory_flag || entering == entered) + return; + + entered = entering; + + if (print_data_base_flag) + fputs ("# ", stdout); + + /* Use entire sentences to give the translators a fighting chance. */ + + if (makelevel == 0) + if (starting_directory == 0) + if (entering) + printf (_("%s: Entering an unknown directory"), program); + else + printf (_("%s: Leaving an unknown directory"), program); + else + if (entering) + printf (_("%s: Entering directory `%s'\n"), + program, starting_directory); + else + printf (_("%s: Leaving directory `%s'\n"), + program, starting_directory); + else + if (starting_directory == 0) + if (entering) + printf (_("%s[%u]: Entering an unknown directory"), + program, makelevel); + else + printf (_("%s[%u]: Leaving an unknown directory"), + program, makelevel); + else + if (entering) + printf (_("%s[%u]: Entering directory `%s'\n"), + program, makelevel, starting_directory); + else + printf (_("%s[%u]: Leaving directory `%s'\n"), + program, makelevel, starting_directory); +} diff --git a/src/make-3.80/make.1 b/src/make-3.80/make.1 new file mode 100755 index 00000000..5b096776 --- /dev/null +++ b/src/make-3.80/make.1 @@ -0,0 +1,291 @@ +.TH MAKE 1L "22 August 1989" "GNU" "LOCAL USER COMMANDS" +.SH NAME +make \- GNU make utility to maintain groups of programs +.SH SYNOPSIS +.B "make " +[ +.B \-f +.I makefile +] [ option ] ... +target ... +.SH WARNING +This man page is an extract of the documentation of +.I GNU make . +It is updated only occasionally, because the GNU project does not use nroff. +For complete, current documentation, refer to the Info file +.B make.info +which is made from the Texinfo source file +.BR make.texinfo . +.SH DESCRIPTION +.LP +The purpose of the +.I make +utility is to determine automatically which +pieces of a large program need to be recompiled, and issue the commands to +recompile them. +The manual describes the GNU implementation of +.IR make , +which was written by Richard Stallman and Roland McGrath. +Our examples show C programs, since they are most common, but you can use +.I make +with any programming language whose compiler can be run with a +shell command. +In fact, +.I make +is not limited to programs. +You can use it to describe any task where some files must be +updated automatically from others whenever the others change. +.LP +To prepare to use +.IR make , +you must write a file called the +.I makefile +that describes the relationships among files in your program, and the +states the commands for updating each file. +In a program, typically the executable file is updated from object +files, which are in turn made by compiling source files. +.LP +Once a suitable makefile exists, each time you change some source files, +this simple shell command: +.sp 1 +.RS +.B make +.RE +.sp 1 +suffices to perform all necessary recompilations. +The +.I make +program uses the makefile data base and the last-modification times +of the files to decide which of the files need to be updated. +For each of those files, it issues the commands recorded in the data base. +.LP +.I make +executes commands in the +.I makefile +to update +one or more target +.IR names , +where +.I name +is typically a program. +If no +.B \-f +option is present, +.I make +will look for the makefiles +.IR GNUmakefile , +.IR makefile , +and +.IR Makefile , +in that order. +.LP +Normally you should call your makefile either +.I makefile +or +.IR Makefile . +(We recommend +.I Makefile +because it appears prominently near the beginning of a directory +listing, right near other important files such as +.IR README .) +The first name checked, +.IR GNUmakefile , +is not recommended for most makefiles. +You should use this name if you have a makefile that is specific to GNU +.IR make , +and will not be understood by other versions of +.IR make . +If +.I makefile +is `\-', the standard input is read. +.LP +.I make +updates a target if it depends on prerequisite files +that have been modified since the target was last modified, +or if the target does not exist. +.SH OPTIONS +.sp 1 +.TP 0.5i +.B \-b +.TP 0.5i +.B \-m +These options are ignored for compatibility with other versions of +.IR make . +.TP 0.5i +.BI "\-C " dir +Change to directory +.I dir +before reading the makefiles or doing anything else. +If multiple +.B \-C +options are specified, each is interpreted relative to the +previous one: +.BR "\-C " / +.BR "\-C " etc +is equivalent to +.BR "\-C " /etc. +This is typically used with recursive invocations of +.IR make . +.TP 0.5i +.B \-d +Print debugging information in addition to normal processing. +The debugging information says which files are being considered for +remaking, which file-times are being compared and with what results, +which files actually need to be remade, which implicit rules are +considered and which are applied---everything interesting about how +.I make +decides what to do. +.TP 0.5i +.B \-e +Give variables taken from the environment precedence +over variables from makefiles. +.TP 0.5i +.BI "\-f " file +Use +.I file +as a makefile. +.TP 0.5i +.B \-i +Ignore all errors in commands executed to remake files. +.TP 0.5i +.BI "\-I " dir +Specifies a directory +.I dir +to search for included makefiles. +If several +.B \-I +options are used to specify several directories, the directories are +searched in the order specified. +Unlike the arguments to other flags of +.IR make , +directories given with +.B \-I +flags may come directly after the flag: +.BI \-I dir +is allowed, as well as +.BI "\-I " dir. +This syntax is allowed for compatibility with the C +preprocessor's +.B \-I +flag. +.TP 0.5i +.BI "\-j " jobs +Specifies the number of jobs (commands) to run simultaneously. +If there is more than one +.B \-j +option, the last one is effective. +If the +.B \-j +option is given without an argument, +.IR make +will not limit the number of jobs that can run simultaneously. +.TP 0.5i +.B \-k +Continue as much as possible after an error. +While the target that failed, and those that depend on it, cannot +be remade, the other dependencies of these targets can be processed +all the same. +.TP 0.5i +.B \-l +.TP 0.5i +.BI "\-l " load +Specifies that no new jobs (commands) should be started if there are +others jobs running and the load average is at least +.I load +(a floating-point number). +With no argument, removes a previous load limit. +.TP 0.5i +.B \-n +Print the commands that would be executed, but do not execute them. +.TP 0.5i +.BI "\-o " file +Do not remake the file +.I file +even if it is older than its dependencies, and do not remake anything +on account of changes in +.IR file . +Essentially the file is treated as very old and its rules are ignored. +.TP 0.5i +.B \-p +Print the data base (rules and variable values) that results from +reading the makefiles; then execute as usual or as otherwise +specified. +This also prints the version information given by the +.B \-v +switch (see below). +To print the data base without trying to remake any files, use +.B make +.B \-p +.BI \-f /dev/null. +.TP 0.5i +.B \-q +``Question mode''. +Do not run any commands, or print anything; just return an exit status +that is zero if the specified targets are already up to date, nonzero +otherwise. +.TP 0.5i +.B \-r +Eliminate use of the built-in implicit rules. +Also clear out the default list of suffixes for suffix rules. +.TP 0.5i +.B \-s +Silent operation; do not print the commands as they are executed. +.TP 0.5i +.B \-S +Cancel the effect of the +.B \-k +option. +This is never necessary except in a recursive +.I make +where +.B \-k +might be inherited from the top-level +.I make +via MAKEFLAGS or if you set +.B \-k +in MAKEFLAGS in your environment. +.TP 0.5i +.B \-t +Touch files (mark them up to date without really changing them) +instead of running their commands. +This is used to pretend that the commands were done, in order to fool +future invocations of +.IR make . +.TP 0.5i +.B \-v +Print the version of the +.I make +program plus a copyright, a list of authors and a notice that there +is no warranty. +.TP 0.5i +.B \-w +Print a message containing the working directory +before and after other processing. +This may be useful for tracking down errors from complicated nests of +recursive +.I make +commands. +.TP 0.5i +.BI "\-W " file +Pretend that the target +.I file +has just been modified. +When used with the +.B \-n +flag, this shows you what would happen if you were to modify that file. +Without +.BR \-n , +it is almost the same as running a +.I touch +command on the given file before running +.IR make , +except that the modification time is changed only in the imagination of +.IR make . +.SH "SEE ALSO" +.I "The GNU Make Manual" +.SH BUGS +See the chapter `Problems and Bugs' in +.I "The GNU Make Manual" . +.SH AUTHOR +This manual page contributed by Dennis Morse of Stanford University. +It has been reworked by Roland McGrath. diff --git a/src/make-3.80/make.h b/src/make-3.80/make.h new file mode 100755 index 00000000..6648ea0d --- /dev/null +++ b/src/make-3.80/make.h @@ -0,0 +1,562 @@ +/* Miscellaneous global declarations and portability cruft for GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* We use instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because make.h was found in $srcdir). */ +#include +#undef HAVE_CONFIG_H +#define HAVE_CONFIG_H 1 + +/* AIX requires this to be the first thing in the file. */ +#ifndef __GNUC__ +# if HAVE_ALLOCA_H +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca /* predefined by HP cc +Olibcalls */ +char *alloca (); +# endif +# endif +# endif +#endif + + +/* Use prototypes if available. */ +#if defined (__cplusplus) || (defined (__STDC__) && __STDC__) +# undef PARAMS +# define PARAMS(protos) protos +#else /* Not C++ or ANSI C. */ +# undef PARAMS +# define PARAMS(protos) () +#endif /* C++ or ANSI C. */ + +/* Specify we want GNU source code. This must be defined before any + system headers are included. */ + +#define _GNU_SOURCE 1 + + +#ifdef CRAY +/* This must happen before #include so + that the declaration therein is changed. */ +# define signal bsdsignal +#endif + +/* If we're compiling for the dmalloc debugger, turn off string inlining. */ +#if defined(HAVE_DMALLOC_H) && defined(__GNUC__) +# define __NO_STRING_INLINES +#endif + +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_TIMEB_H +/* SCO 3.2 "devsys 4.2" has a prototype for `ftime' in that bombs + unless has been included first. Does every system have a + ? If any does not, configure should check for it. */ +# include +#endif + +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include + +#ifndef errno +extern int errno; +#endif + +#ifndef isblank +# define isblank(c) ((c) == ' ' || (c) == '\t') +#endif + +#ifdef HAVE_UNISTD_H +# include +/* Ultrix's unistd.h always defines _POSIX_VERSION, but you only get + POSIX.1 behavior with `cc -YPOSIX', which predefines POSIX itself! */ +# if defined (_POSIX_VERSION) && !defined (ultrix) && !defined (VMS) +# define POSIX 1 +# endif +#endif + +/* Some systems define _POSIX_VERSION but are not really POSIX.1. */ +#if (defined (butterfly) || defined (__arm) || (defined (__mips) && defined (_SYSTYPE_SVR3)) || (defined (sequent) && defined (i386))) +# undef POSIX +#endif + +#if !defined (POSIX) && defined (_AIX) && defined (_POSIX_SOURCE) +# define POSIX 1 +#endif + +#ifndef RETSIGTYPE +# define RETSIGTYPE void +#endif + +#ifndef sigmask +# define sigmask(sig) (1 << ((sig) - 1)) +#endif + +#ifndef HAVE_SA_RESTART +# define SA_RESTART 0 +#endif + +#ifdef HAVE_LIMITS_H +# include +#endif +#ifdef HAVE_SYS_PARAM_H +# include +#endif + +#ifndef PATH_MAX +# ifndef POSIX +# define PATH_MAX MAXPATHLEN +# endif +#endif +#ifndef MAXPATHLEN +# define MAXPATHLEN 1024 +#endif + +#ifdef PATH_MAX +# define GET_PATH_MAX PATH_MAX +# define PATH_VAR(var) char var[PATH_MAX] +#else +# define NEED_GET_PATH_MAX 1 +# define GET_PATH_MAX (get_path_max ()) +# define PATH_VAR(var) char *var = (char *) alloca (GET_PATH_MAX) +extern unsigned int get_path_max PARAMS ((void)); +#endif + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +/* Nonzero if the integer type T is signed. */ +#define INTEGER_TYPE_SIGNED(t) ((t) -1 < 0) + +/* The minimum and maximum values for the integer type T. + Use ~ (t) 0, not -1, for portability to 1's complement hosts. */ +#define INTEGER_TYPE_MINIMUM(t) \ + (! INTEGER_TYPE_SIGNED (t) ? (t) 0 : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)) +#define INTEGER_TYPE_MAXIMUM(t) (~ (t) 0 - INTEGER_TYPE_MINIMUM (t)) + +#ifndef CHAR_MAX +# define CHAR_MAX INTEGER_TYPE_MAXIMUM (char) +#endif + +#ifdef STAT_MACROS_BROKEN +# ifdef S_ISREG +# undef S_ISREG +# endif +# ifdef S_ISDIR +# undef S_ISDIR +# endif +#endif /* STAT_MACROS_BROKEN. */ + +#ifndef S_ISREG +# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif +#ifndef S_ISDIR +# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif + +#ifdef VMS +# include +# include +# include +# include +/* Needed to use alloca on VMS. */ +# include +#endif + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ +# define __attribute__(x) +# endif +/* The __-protected variants of `format' and `printf' attributes + are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) +# define __format__ format +# define __printf__ printf +# endif +#endif + +#if defined (STDC_HEADERS) || defined (__GNU_LIBRARY__) +# include +# include +# define ANSI_STRING 1 +#else /* No standard headers. */ +# ifdef HAVE_STRING_H +# include +# define ANSI_STRING 1 +# else +# include +# endif +# ifdef HAVE_MEMORY_H +# include +# endif +# ifdef HAVE_STDLIB_H +# include +# else +extern char *malloc PARAMS ((int)); +extern char *realloc PARAMS ((char *, int)); +extern void free PARAMS ((char *)); + +extern void abort PARAMS ((void)) __attribute__ ((noreturn)); +extern void exit PARAMS ((int)) __attribute__ ((noreturn)); +# endif /* HAVE_STDLIB_H. */ + +#endif /* Standard headers. */ + +/* These should be in stdlib.h. Make sure we have them. */ +#ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +#endif +#ifndef EXIT_FAILURE +# define EXIT_FAILURE 0 +#endif + +#ifdef ANSI_STRING + +# ifndef bcmp +# define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) +# endif +# ifndef bzero +# define bzero(s, n) memset ((s), 0, (n)) +# endif +# if defined(HAVE_MEMMOVE) && !defined(bcopy) +# define bcopy(s, d, n) memmove ((d), (s), (n)) +# endif + +#else /* Not ANSI_STRING. */ + +# ifndef HAVE_STRCHR +# define strchr(s, c) index((s), (c)) +# define strrchr(s, c) rindex((s), (c)) +# endif + +# ifndef bcmp +extern int bcmp PARAMS ((const char *, const char *, int)); +# endif +# ifndef bzero +extern void bzero PARAMS ((char *, int)); +#endif +# ifndef bcopy +extern void bcopy PARAMS ((const char *b1, char *b2, int)); +# endif + +#endif /* ANSI_STRING. */ +#undef ANSI_STRING + +/* SCO Xenix has a buggy macro definition in . */ +#undef strerror + +#if !defined(ANSI_STRING) && !defined(__DECC) +extern char *strerror PARAMS ((int errnum)); +#endif + +#if HAVE_INTTYPES_H +# include +#endif +#define FILE_TIMESTAMP uintmax_t + +#if !defined(HAVE_STRSIGNAL) +extern char *strsignal PARAMS ((int signum)); +#endif + +/* ISDIGIT offers the following features: + - Its arg may be any int or unsigned int; it need not be an unsigned char. + - It's guaranteed to evaluate its argument exactly once. + NOTE! Make relies on this behavior, don't change it! + - It's typically faster. + POSIX 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that + only '0' through '9' are digits. Prefer ISDIGIT to isdigit() unless + it's important to use the locale's definition of `digit' even when the + host does not conform to POSIX. */ +#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) + +#ifndef iAPX286 +# define streq(a, b) \ + ((a) == (b) || \ + (*(a) == *(b) && (*(a) == '\0' || !strcmp ((a) + 1, (b) + 1)))) +# ifdef HAVE_CASE_INSENSITIVE_FS +/* This is only used on Windows/DOS platforms, so we assume strcmpi(). */ +# define strieq(a, b) \ + ((a) == (b) \ + || (tolower((unsigned char)*(a)) == tolower((unsigned char)*(b)) \ + && (*(a) == '\0' || !strcmpi ((a) + 1, (b) + 1)))) +# else +# define strieq(a, b) streq(a, b) +# endif +#else +/* Buggy compiler can't handle this. */ +# define streq(a, b) (strcmp ((a), (b)) == 0) +# define strieq(a, b) (strcmp ((a), (b)) == 0) +#endif +#define strneq(a, b, l) (strncmp ((a), (b), (l)) == 0) +#ifdef VMS +extern int strcmpi (const char *,const char *); +#endif + +#if defined(__GNUC__) || defined(ENUM_BITFIELDS) +# define ENUM_BITFIELD(bits) :bits +#else +# define ENUM_BITFIELD(bits) +#endif + +/* Handle gettext and locales. */ + +#if HAVE_LOCALE_H +# include +#else +# define setlocale(category, locale) +#endif + +#include + +#define _(msgid) gettext (msgid) +#define N_(msgid) gettext_noop (msgid) +#define S_(msg1,msg2,num) ngettext (msg1,msg2,num) + +/* Handle other OSs. */ + +#if defined(__MSDOS__) || defined(WINDOWS32) +# define PATH_SEPARATOR_CHAR ';' +#else +# if defined(VMS) +# define PATH_SEPARATOR_CHAR ',' +# else +# define PATH_SEPARATOR_CHAR ':' +# endif +#endif + +#ifdef WINDOWS32 +# include +# include +# define pipe(p) _pipe(p, 512, O_BINARY) +# define kill(pid,sig) w32_kill(pid,sig) + +extern void sync_Path_environment(void); +extern int kill(int pid, int sig); +extern int safe_stat(char *file, struct stat *sb); +extern char *end_of_token_w32(char *s, char stopchar); +extern int find_and_set_default_shell(char *token); + +/* indicates whether or not we have Bourne shell */ +extern int no_default_sh_exe; + +/* is default_shell unixy? */ +extern int unixy_shell; +#endif /* WINDOWS32 */ + +struct floc + { + char *filenm; + unsigned long lineno; + }; +#define NILF ((struct floc *)0) + +#define STRING_SIZE_TUPLE(_s) (_s), (sizeof (_s)-1) + + +/* Fancy processing for variadic functions in both ANSI and pre-ANSI + compilers. */ +#if defined __STDC__ && __STDC__ +extern void message (int prefix, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +extern void error (const struct floc *flocp, const char *fmt, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); +extern void fatal (const struct floc *flocp, const char *fmt, ...) + __attribute__ ((noreturn, __format__ (__printf__, 2, 3))); +#else +extern void message (); +extern void error (); +extern void fatal (); +#endif + +extern void die PARAMS ((int)) __attribute__ ((noreturn)); +extern void log_working_directory PARAMS ((int)); +extern void pfatal_with_name PARAMS ((const char *)) __attribute__ ((noreturn)); +extern void perror_with_name PARAMS ((const char *, const char *)); +extern char *savestring PARAMS ((const char *, unsigned int)); +extern char *concat PARAMS ((const char *, const char *, const char *)); +extern char *xmalloc PARAMS ((unsigned int)); +extern char *xrealloc PARAMS ((char *, unsigned int)); +extern char *xstrdup PARAMS ((const char *)); +extern char *find_next_token PARAMS ((char **, unsigned int *)); +extern char *next_token PARAMS ((const char *)); +extern char *end_of_token PARAMS ((char *)); +extern void collapse_continuations PARAMS ((char *)); +extern void remove_comments PARAMS((char *)); +extern char *sindex PARAMS ((const char *, unsigned int, \ + const char *, unsigned int)); +extern char *lindex PARAMS ((const char *, const char *, int)); +extern int alpha_compare PARAMS ((const void *, const void *)); +extern void print_spaces PARAMS ((unsigned int)); +extern char *find_char_unquote PARAMS ((char *, int, int, int)); +extern char *find_percent PARAMS ((char *)); +extern FILE *open_tmpfile PARAMS ((char **, const char *)); + +#ifndef NO_ARCHIVES +extern int ar_name PARAMS ((char *)); +extern void ar_parse_name PARAMS ((char *, char **, char **)); +extern int ar_touch PARAMS ((char *)); +extern time_t ar_member_date PARAMS ((char *)); +#endif + +extern int dir_file_exists_p PARAMS ((char *, char *)); +extern int file_exists_p PARAMS ((char *)); +extern int file_impossible_p PARAMS ((char *)); +extern void file_impossible PARAMS ((char *)); +extern char *dir_name PARAMS ((char *)); +extern void hash_init_directories PARAMS ((void)); + +extern void define_default_variables PARAMS ((void)); +extern void set_default_suffixes PARAMS ((void)); +extern void install_default_suffix_rules PARAMS ((void)); +extern void install_default_implicit_rules PARAMS ((void)); + +extern void build_vpath_lists PARAMS ((void)); +extern void construct_vpath_list PARAMS ((char *pattern, char *dirpath)); +extern int vpath_search PARAMS ((char **file, FILE_TIMESTAMP *mtime_ptr)); +extern int gpath_search PARAMS ((char *file, int len)); + +extern void construct_include_path PARAMS ((char **arg_dirs)); + +extern void user_access PARAMS ((void)); +extern void make_access PARAMS ((void)); +extern void child_access PARAMS ((void)); + +#ifdef HAVE_VFORK_H +# include +#endif + +/* We omit these declarations on non-POSIX systems which define _POSIX_VERSION, + because such systems often declare them in header files anyway. */ + +#if !defined (__GNU_LIBRARY__) && !defined (POSIX) && !defined (_POSIX_VERSION) && !defined(WINDOWS32) + +extern long int atol (); +# ifndef VMS +extern long int lseek (); +# endif + +#endif /* Not GNU C library or POSIX. */ + +#ifdef HAVE_GETCWD +# if !defined(VMS) && !defined(__DECC) +extern char *getcwd (); +#endif +#else +extern char *getwd (); +# define getcwd(buf, len) getwd (buf) +#endif + +extern const struct floc *reading_file; + +extern char **environ; + +extern int just_print_flag, silent_flag, ignore_errors_flag, keep_going_flag; +extern int print_data_base_flag, question_flag, touch_flag, always_make_flag; +extern int env_overrides, no_builtin_rules_flag, no_builtin_variables_flag; +extern int print_version_flag, print_directory_flag; +extern int warn_undefined_variables_flag, posix_pedantic, not_parallel; +extern int clock_skew_detected; + +/* can we run commands via 'sh -c xxx' or must we use batch files? */ +extern int batch_mode_shell; + +extern unsigned int job_slots; +extern int job_fds[2]; +extern int job_rfd; +#ifndef NO_FLOAT +extern double max_load_average; +#else +extern int max_load_average; +#endif + +extern char *program; +extern char *starting_directory; +extern unsigned int makelevel; +extern char *version_string, *remote_description; + +extern unsigned int commands_started; + +extern int handling_fatal_signal; + + +#ifndef MIN +#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b)) +#endif +#ifndef MAX +#define MAX(_a,_b) ((_a)>(_b)?(_a):(_b)) +#endif + +#ifdef VMS +# define MAKE_SUCCESS 1 +# define MAKE_TROUBLE 2 +# define MAKE_FAILURE 3 +#else +# define MAKE_SUCCESS 0 +# define MAKE_TROUBLE 1 +# define MAKE_FAILURE 2 +#endif + +/* Set up heap debugging library dmalloc. */ + +#ifdef HAVE_DMALLOC_H +#include +#endif + + +/* If we have broken SA_RESTART support, then wrap stat() and readdir() with + versions that handle EINTR. Note that there are still plenty of system + calls that can fail with EINTR but this, reportedly, gets the vast + majority of failure cases. If you still experience failures you'll need + to either get a system where SA_RESTART works, or you need to avoid -j. */ + +#ifdef HAVE_BROKEN_RESTART + +/* Here we make an assumption that a system with a broken SA_RESTART has + dirent.h. Right now the only system I know of in this category is PTX, and + it does have dirent.h. +*/ +#include + +#define stat(_f,_b) atomic_stat ((_f), (_b)) +#define readdir(_d) atomic_readdir (_d) + +extern int atomic_stat PARAMS ((const char *file, struct stat *buf)); +extern struct dirent *atomic_readdir PARAMS ((DIR *dir)); + +#endif diff --git a/src/make-3.80/make.lnk b/src/make-3.80/make.lnk new file mode 100755 index 00000000..8fbbeffd --- /dev/null +++ b/src/make-3.80/make.lnk @@ -0,0 +1,5 @@ +FROM LIB:cres.o "commands.o"+"job.o"+"dir.o"+"file.o"+"misc.o"+"main.o"+"read.o"+"remake.o"+"rule.o"+"implicit.o"+"default.o"+"variable.o"+"expand.o"+"function.o"+"vpath.o"+"version.o"+"ar.o"+"arscan.o"+"signame.o"+"remote-stub.o"+"getopt.o"+"getopt1.o"+"alloca.o"+"amiga.o" +TO "make.new" +LIB glob/glob.lib LIB:sc.lib LIB:amiga.lib +QUIET + diff --git a/src/make-3.80/makefile.com b/src/make-3.80/makefile.com new file mode 100755 index 00000000..dd94bc32 --- /dev/null +++ b/src/make-3.80/makefile.com @@ -0,0 +1,138 @@ +$! +$! Makefile.com - builds GNU Make for VMS +$! +$! P1 is non-empty if you want to link with the VAXCRTL library instead +$! of the shareable executable +$! P2 = DEBUG will build an image with debug information +$! P3 = WALL will enable all warning messages (some are suppressed since +$! one macro intentionally causes an error condition) +$! +$! In case of problems with the install you might contact me at +$! zinser@decus.de (preferred) or zinser@sysdev.deutsche-boerse.com +$ +$! hb +$! But don't ask Martin Zinser about the lines, I added/changed. +$! In case of an error do some cleanup +$ on error then $ goto cleanup +$! in case somebody set up her/his own symbol for cc +$ set symbol/scope=(nolocal,noglobal) +$! +$! Just some general constants... +$! +$ true = 1 +$ false = 0 +$ tmpnam = "temp_" + f$getjpi("","pid") +$ tt = tmpnam + ".txt" +$ tc = tmpnam + ".c" +$! +$! Look for the compiler used +$! +$ lval = "" +$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" +$ then +$ if f$trnlnm("SYS").eqs."" then def/nolog sys sys$library: +$ ccopt = "" +$ else +$ ccopt = "/decc/prefix=all" +$ if f$trnlnm("SYS").eqs."" +$ then +$ if f$trnlnm("DECC$LIBRARY_INCLUDE").nes."" +$ then +$ define sys decc$library_include: +$ else +$ if f$search("SYS$COMMON:[DECC$LIB.REFERENCE]DECC$RTLDEF.DIR").nes."" - + then lval = "SYS$COMMON:[DECC$LIB.REFERENCE.DECC$RTLDEF]," +$ if f$search("SYS$COMMON:[DECC$LIB.REFERENCE]SYS$STARLET_C.DIR").nes."" - + then lval = lval+"SYS$COMMON:[DECC$LIB.REFERENCE.SYS$STARLET_C]," +$ lval=lval+"SYS$LIBRARY:" +$ define sys 'lval +$ endif +$ endif +$ endif +$! +$! Should we build a debug image +$! +$ if (p2.eqs."DEBUG") +$ then +$ ccopt = ccopt + "/noopt/debug" +$ lopt = "/debug" +$ else +$ lopt = "" +$ endif +$! +$! Do we want to see all warnings +$! +$ if (p3.nes."WALL") +$ then +$ gosub check_cc_qual +$ endif +$ filelist = "alloca ar arscan commands default dir expand file function " + - + "hash implicit job main misc read remake remote-stub rule " + - + "signame variable version vmsfunctions vmsify vpath " + - + "[.glob]glob [.glob]fnmatch getopt1 getopt" +$ copy config.h-vms config.h +$ n=0 +$ open/write optf make.opt +$ loop: +$ cfile = f$elem(n," ",filelist) +$ if cfile .eqs. " " then goto linkit +$ write sys$output "Compiling ''cfile'..." +$ call compileit 'cfile' 'p1' +$ n = n + 1 +$ goto loop +$ linkit: +$ close optf +$ if p1 .nes. "" then goto link_using_library +$ link/exe=make make.opt/opt'lopt +$ goto cleanup +$ +$ link_using_library: +$ link/exe=make make.opt/opt,sys$library:vaxcrtl/lib'lopt +$ +$ cleanup: +$ if f$trnlnm("SYS").nes."" then $ deassign sys +$ if f$trnlnm("OPTF").nes."" then $ close optf +$ if f$search("make.opt").nes."" then $ del make.opt;* +$ exit +$! +$!------------------------------------------------------------------------------ +$! +$! Check if this is a define relating to the properties of the C/C++ +$! compiler +$! +$CHECK_CC_QUAL: +$ open/write tmpc 'tc +$ ccqual = "/warn=(disable=questcompare)" +$ write tmpc "#include " +$ write tmpc "unsigned int i = 1;" +$ write tmpc "int main(){" +$ write tmpc "if (i < 0){printf(""Mission impossible\n"");}}" +$ close tmpc +$ gosub cc_qual_check +$ return +$! +$!------------------------------------------------------------------------------ +$! +$! Check for properties of C/C++ compiler +$! +$CC_QUAL_CHECK: +$ cc_qual = false +$ set message/nofac/noident/nosever/notext +$ cc 'ccqual' 'tmpnam' +$ if $status then cc_qual = true +$ set message/fac/ident/sever/text +$ delete/nolog 'tmpnam'.*;* +$ if cc_qual then ccopt = ccopt + ccqual +$ return +$!------------------------------------------------------------------------------ +$! +$ compileit : subroutine +$ ploc = f$locate("]",p1) +$ filnam = p1 +$ if ploc .lt. f$length(p1) then filnam=f$extract(ploc+1,100,p1) +$ write optf "''filnam'" +$ cc'ccopt'/include=([],[.glob]) - + /define=("allocated_variable_expand_for_file=alloc_var_expand_for_file","unlink=remove","HAVE_CONFIG_H","VMS") - + 'p1' +$ exit +$ endsubroutine : compileit diff --git a/src/make-3.80/makefile.vms b/src/make-3.80/makefile.vms new file mode 100755 index 00000000..3ada8314 --- /dev/null +++ b/src/make-3.80/makefile.vms @@ -0,0 +1,147 @@ +# Copyright (C) 1988, 1989, 1996, 1997 Free Software Foundation, Inc. +# This file is part of GNU Make. +# +# VMS extensions from GNU Make 3.60 imported by +# Klaus Kämpf (kkaempf@rmi.de) +# Modified for version 3.78.1 by Hartmut.Becker@compaq.com. +# Modified for version 3.80 by zinser@decus.de +# +# GNU Make is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU Make 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Make; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +CC = cc +CP = copy + +%.obj: %.c + $(CC) $(CFLAGS)/obj=$@ $< +# +# Makefile for GNU Make +# + +ifeq ($(CC),cc) +CFLAGS = $(defines) /include=([],[.glob])/prefix=all/standard=relaxed +else +CFLAGS = $(defines) /include=([],[.glob]) +endif +#LDFLAGS = /deb +LDFLAGS = + +ifeq ($(CC),cc) +defines = /define=("unlink=remove","HAVE_CONFIG_H","VMS","allocated_variable_expand_for_file=alloc_var_expand_for_file") +else +ifeq ($(ARCH),VAX) +defines = /define=("HAVE_CONFIG_H","GCC_IS_NATIVE","VAX") +else +defines = /define=("HAVE_CONFIG_H","GCC_IS_NATIVE") +endif +endif + +LOAD_AVG = /define="NO_LDAV" + +# If you don't want archive support, comment these out. +ARCHIVES = ,ar.obj,arscan.obj +ARCHIVES_SRC = ar.c arscan.c + +# If your system needs extra libraries loaded in, define them here. +# System V probably need -lPW for alloca. +# if on vax, uncomment the following line +#LOADLIBES = ,c.opt/opt +ifeq ($(CC),cc) +#LOADLIBES =,sys$$library:vaxcrtl.olb/lib +CRT0 = +else +LOADLIBES =,gnu_cc_library:libgcc.olb/lib +endif + +# If your system doesn't have alloca, or the one provided is bad, +# get it from the Emacs distribution and define these. +#ALLOCA = ,alloca.obj +#ALLOCASRC = alloca.c + +# If there are remote execution facilities defined, +# enable them with switches here (see remote-*.c). +REMOTE = + +# Any extra object files your system needs. +extras = ,signame.obj,remote-stub.obj,vmsfunctions.obj,vmsify.obj +#,directory.obj +# as an alternative: +glob = ,[.glob]glob.obj,[.glob]fnmatch.obj +getopt = ,getopt.obj,getopt1.obj +# Directory to install `make' in. +bindir = [] +# Directory to install the man page in. +mandir = [] +# Number to put on the man page filename. +manext = 1 + +objs = commands.obj,job.obj,dir.obj,file.obj,misc.obj,hash.obj,\ + main.obj,read.obj,remake.obj,rule.obj,implicit.obj,\ + default.obj,variable.obj,expand.obj,function.obj,\ + vpath.obj,version.obj$(ARCHIVES)$(ALLOCA)$(extras)$(getopt)$(glob) +srcs = commands.c job.c dir.c file.c misc.c hash.c\ + main.c read.c remake.c rule.c implicit.c \ + default.c variable.c expand.c function.c \ + vpath.c version.c vmsfunctions.c vmsify.c $(ARCHIVES_SRC) $(ALLOCASRC) \ + commands.h dep.h filedef.h job.h make.h rule.h variable.h + + +.PHONY: all doc +all: config.h make.exe + +doc: make.info make.dvi + + +make.exe: $(objs) + $(LD)$(LDFLAGS)/exe=$@ $^$(LOADLIBES)$(CRT0) + +.PHONY: clean realclean +clean: + $$ purge [...] + -$(RM) make.exe;,*.obj; + -$(RM) *.opt; + -$(RM) [.glob]*.obj; + +# Automatically generated dependencies. +commands.obj: commands.c make.h dep.h commands.h filedef.h variable.h job.h +job.obj: job.c make.h commands.h job.h filedef.h variable.h +dir.obj: dir.c make.h +file.obj: file.c make.h commands.h dep.h filedef.h variable.h +misc.obj: misc.c make.h dep.h +hash.obj: hash.c make.h hash.h +main.obj: main.c make.h commands.h dep.h filedef.h variable.h job.h +read.obj: read.c make.h commands.h dep.h filedef.h variable.h +remake.obj: remake.c make.h commands.h job.h dep.h filedef.h +rule.obj: rule.c make.h commands.h dep.h filedef.h variable.h rule.h +implicit.obj: implicit.c make.h rule.h dep.h filedef.h +default.obj: default.c make.h rule.h dep.h filedef.h commands.h variable.h +variable.obj: variable.c make.h commands.h variable.h dep.h filedef.h +expand.obj: expand.c make.h commands.h filedef.h variable.h +function.obj: function.c make.h variable.h dep.h commands.h job.h +vpath.obj: vpath.c make.h filedef.h variable.h +version.obj: version.c config.h +arscan.obj: arscan.c +ar.obj: ar.c make.h filedef.h +signame.obj: signame.c +remote-stub.obj: remote-stub.c +[.glob]glob.obj: [.glob]glob.c +[.glob]fnmatch.obj: [.glob]fnmatch.c +getopt.obj: getopt.c +getopt1.obj: getopt1.c +vmsfunctions.obj: vmsfunctions.c make.h vmsdir.h +vmsify.obj: vmsify.c make.h + +config.h: config.h-vms + $(CP) $< $@ diff --git a/src/make-3.80/misc.c b/src/make-3.80/misc.c new file mode 100755 index 00000000..7f0b1b30 --- /dev/null +++ b/src/make-3.80/misc.c @@ -0,0 +1,893 @@ +/* Miscellaneous generic support functions for GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1997, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "dep.h" +#include "debug.h" + +/* Variadic functions. We go through contortions to allow proper function + prototypes for both ANSI and pre-ANSI C compilers, and also for those + which support stdarg.h vs. varargs.h, and finally those which have + vfprintf(), etc. and those who have _doprnt... or nothing. + + This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and + VA_END macros used here since we have multiple print functions. */ + +#if HAVE_VPRINTF || HAVE_DOPRNT +# define HAVE_STDVARARGS 1 +# if __STDC__ +# include +# define VA_START(args, lastarg) va_start(args, lastarg) +# else +# include +# define VA_START(args, lastarg) va_start(args) +# endif +# if HAVE_VPRINTF +# define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args)) +# else +# define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp)) +# endif +# define VA_END(args) va_end(args) +#else +/* # undef HAVE_STDVARARGS */ +# define va_alist a1, a2, a3, a4, a5, a6, a7, a8 +# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; +# define VA_START(args, lastarg) +# define VA_PRINTF(fp, lastarg, args) fprintf((fp), (lastarg), va_alist) +# define VA_END(args) +#endif + + +/* Compare strings *S1 and *S2. + Return negative if the first is less, positive if it is greater, + zero if they are equal. */ + +int +alpha_compare (v1, v2) + const void *v1, *v2; +{ + const char *s1 = *((char **)v1); + const char *s2 = *((char **)v2); + + if (*s1 != *s2) + return *s1 - *s2; + return strcmp (s1, s2); +} + +/* Discard each backslash-newline combination from LINE. + Backslash-backslash-newline combinations become backslash-newlines. + This is done by copying the text at LINE into itself. */ + +void +collapse_continuations (line) + char *line; +{ + register char *in, *out, *p; + register int backslash; + register unsigned int bs_write; + + in = strchr (line, '\n'); + if (in == 0) + return; + + out = in; + while (out > line && out[-1] == '\\') + --out; + + while (*in != '\0') + { + /* BS_WRITE gets the number of quoted backslashes at + the end just before IN, and BACKSLASH gets nonzero + if the next character is quoted. */ + backslash = 0; + bs_write = 0; + for (p = in - 1; p >= line && *p == '\\'; --p) + { + if (backslash) + ++bs_write; + backslash = !backslash; + + /* It should be impossible to go back this far without exiting, + but if we do, we can't get the right answer. */ + if (in == out - 1) + abort (); + } + + /* Output the appropriate number of backslashes. */ + while (bs_write-- > 0) + *out++ = '\\'; + + /* Skip the newline. */ + ++in; + + /* If the newline is quoted, discard following whitespace + and any preceding whitespace; leave just one space. */ + if (backslash) + { + in = next_token (in); + while (out > line && isblank ((unsigned char)out[-1])) + --out; + *out++ = ' '; + } + else + /* If the newline isn't quoted, put it in the output. */ + *out++ = '\n'; + + /* Now copy the following line to the output. + Stop when we find backslashes followed by a newline. */ + while (*in != '\0') + if (*in == '\\') + { + p = in + 1; + while (*p == '\\') + ++p; + if (*p == '\n') + { + in = p; + break; + } + while (in < p) + *out++ = *in++; + } + else + *out++ = *in++; + } + + *out = '\0'; +} + + +/* Remove comments from LINE. + This is done by copying the text at LINE onto itself. */ + +void +remove_comments (line) + char *line; +{ + char *comment; + + comment = find_char_unquote (line, '#', 0, 0); + + if (comment != 0) + /* Cut off the line at the #. */ + *comment = '\0'; +} + +/* Print N spaces (used in debug for target-depth). */ + +void +print_spaces (n) + unsigned int n; +{ + while (n-- > 0) + putchar (' '); +} + + +/* Return a newly-allocated string whose contents + concatenate those of s1, s2, s3. */ + +char * +concat (s1, s2, s3) + const char *s1, *s2, *s3; +{ + unsigned int len1, len2, len3; + char *result; + + len1 = *s1 != '\0' ? strlen (s1) : 0; + len2 = *s2 != '\0' ? strlen (s2) : 0; + len3 = *s3 != '\0' ? strlen (s3) : 0; + + result = (char *) xmalloc (len1 + len2 + len3 + 1); + + if (*s1 != '\0') + bcopy (s1, result, len1); + if (*s2 != '\0') + bcopy (s2, result + len1, len2); + if (*s3 != '\0') + bcopy (s3, result + len1 + len2, len3); + *(result + len1 + len2 + len3) = '\0'; + + return result; +} + +/* Print a message on stdout. */ + +void +#if __STDC__ && HAVE_STDVARARGS +message (int prefix, const char *fmt, ...) +#else +message (prefix, fmt, va_alist) + int prefix; + const char *fmt; + va_dcl +#endif +{ +#if HAVE_STDVARARGS + va_list args; +#endif + + log_working_directory (1); + + if (fmt != 0) + { + if (prefix) + { + if (makelevel == 0) + printf ("%s: ", program); + else + printf ("%s[%u]: ", program, makelevel); + } + VA_START (args, fmt); + VA_PRINTF (stdout, fmt, args); + VA_END (args); + putchar ('\n'); + } + + fflush (stdout); +} + +/* Print an error message. */ + +void +#if __STDC__ && HAVE_STDVARARGS +error (const struct floc *flocp, const char *fmt, ...) +#else +error (flocp, fmt, va_alist) + const struct floc *flocp; + const char *fmt; + va_dcl +#endif +{ +#if HAVE_STDVARARGS + va_list args; +#endif + + log_working_directory (1); + + if (flocp && flocp->filenm) + fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno); + else if (makelevel == 0) + fprintf (stderr, "%s: ", program); + else + fprintf (stderr, "%s[%u]: ", program, makelevel); + + VA_START(args, fmt); + VA_PRINTF (stderr, fmt, args); + VA_END (args); + + putc ('\n', stderr); + fflush (stderr); +} + +/* Print an error message and exit. */ + +void +#if __STDC__ && HAVE_STDVARARGS +fatal (const struct floc *flocp, const char *fmt, ...) +#else +fatal (flocp, fmt, va_alist) + const struct floc *flocp; + const char *fmt; + va_dcl +#endif +{ +#if HAVE_STDVARARGS + va_list args; +#endif + + log_working_directory (1); + + if (flocp && flocp->filenm) + fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno); + else if (makelevel == 0) + fprintf (stderr, "%s: *** ", program); + else + fprintf (stderr, "%s[%u]: *** ", program, makelevel); + + VA_START(args, fmt); + VA_PRINTF (stderr, fmt, args); + VA_END (args); + + fputs (_(". Stop.\n"), stderr); + + die (2); +} + +#ifndef HAVE_STRERROR + +#undef strerror + +char * +strerror (errnum) + int errnum; +{ + extern int errno, sys_nerr; +#ifndef __DECC + extern char *sys_errlist[]; +#endif + static char buf[] = "Unknown error 12345678901234567890"; + + if (errno < sys_nerr) + return sys_errlist[errnum]; + + sprintf (buf, _("Unknown error %d"), errnum); + return buf; +} +#endif + +/* Print an error message from errno. */ + +void +perror_with_name (str, name) + const char *str, *name; +{ + error (NILF, _("%s%s: %s"), str, name, strerror (errno)); +} + +/* Print an error message from errno and exit. */ + +void +pfatal_with_name (name) + const char *name; +{ + fatal (NILF, _("%s: %s"), name, strerror (errno)); + + /* NOTREACHED */ +} + +/* Like malloc but get fatal error if memory is exhausted. */ +/* Don't bother if we're using dmalloc; it provides these for us. */ + +#ifndef HAVE_DMALLOC_H + +#undef xmalloc +#undef xrealloc +#undef xstrdup + +char * +xmalloc (size) + unsigned int size; +{ + char *result = (char *) malloc (size); + if (result == 0) + fatal (NILF, _("virtual memory exhausted")); + return result; +} + + +char * +xrealloc (ptr, size) + char *ptr; + unsigned int size; +{ + char *result; + + /* Some older implementations of realloc() don't conform to ANSI. */ + result = ptr ? realloc (ptr, size) : malloc (size); + if (result == 0) + fatal (NILF, _("virtual memory exhausted")); + return result; +} + + +char * +xstrdup (ptr) + const char *ptr; +{ + char *result; + +#ifdef HAVE_STRDUP + result = strdup (ptr); +#else + result = (char *) malloc (strlen (ptr) + 1); +#endif + + if (result == 0) + fatal (NILF, _("virtual memory exhausted")); + +#ifdef HAVE_STRDUP + return result; +#else + return strcpy(result, ptr); +#endif +} + +#endif /* HAVE_DMALLOC_H */ + +char * +savestring (str, length) + const char *str; + unsigned int length; +{ + register char *out = (char *) xmalloc (length + 1); + if (length > 0) + bcopy (str, out, length); + out[length] = '\0'; + return out; +} + +/* Search string BIG (length BLEN) for an occurrence of + string SMALL (length SLEN). Return a pointer to the + beginning of the first occurrence, or return nil if none found. */ + +char * +sindex (big, blen, small, slen) + const char *big; + unsigned int blen; + const char *small; + unsigned int slen; +{ + if (!blen) + blen = strlen (big); + if (!slen) + slen = strlen (small); + + if (slen && blen >= slen) + { + register unsigned int b; + + /* Quit when there's not enough room left for the small string. */ + --slen; + blen -= slen; + + for (b = 0; b < blen; ++b, ++big) + if (*big == *small && strneq (big + 1, small + 1, slen)) + return (char *)big; + } + + return 0; +} + +/* Limited INDEX: + Search through the string STRING, which ends at LIMIT, for the character C. + Returns a pointer to the first occurrence, or nil if none is found. + Like INDEX except that the string searched ends where specified + instead of at the first null. */ + +char * +lindex (s, limit, c) + register const char *s, *limit; + int c; +{ + while (s < limit) + if (*s++ == c) + return (char *)(s - 1); + + return 0; +} + +/* Return the address of the first whitespace or null in the string S. */ + +char * +end_of_token (s) + char *s; +{ + while (*s != '\0' && !isblank ((unsigned char)*s)) + ++s; + return s; +} + +#ifdef WINDOWS32 +/* + * Same as end_of_token, but take into account a stop character + */ +char * +end_of_token_w32 (s, stopchar) + char *s; + char stopchar; +{ + register char *p = s; + register int backslash = 0; + + while (*p != '\0' && *p != stopchar + && (backslash || !isblank ((unsigned char)*p))) + { + if (*p++ == '\\') + { + backslash = !backslash; + while (*p == '\\') + { + backslash = !backslash; + ++p; + } + } + else + backslash = 0; + } + + return p; +} +#endif + +/* Return the address of the first nonwhitespace or null in the string S. */ + +char * +next_token (s) + const char *s; +{ + while (isblank ((unsigned char)*s)) + ++s; + return (char *)s; +} + +/* Find the next token in PTR; return the address of it, and store the + length of the token into *LENGTHPTR if LENGTHPTR is not nil. */ + +char * +find_next_token (ptr, lengthptr) + char **ptr; + unsigned int *lengthptr; +{ + char *p = next_token (*ptr); + char *end; + + if (*p == '\0') + return 0; + + *ptr = end = end_of_token (p); + if (lengthptr != 0) + *lengthptr = end - p; + return p; +} + +/* Copy a chain of `struct dep', making a new chain + with the same contents as the old one. */ + +struct dep * +copy_dep_chain (d) + register struct dep *d; +{ + register struct dep *c; + struct dep *firstnew = 0; + struct dep *lastnew = 0; + + while (d != 0) + { + c = (struct dep *) xmalloc (sizeof (struct dep)); + bcopy ((char *) d, (char *) c, sizeof (struct dep)); + if (c->name != 0) + c->name = xstrdup (c->name); + c->next = 0; + if (firstnew == 0) + firstnew = lastnew = c; + else + lastnew = lastnew->next = c; + + d = d->next; + } + + return firstnew; +} + +#ifdef iAPX286 +/* The losing compiler on this machine can't handle this macro. */ + +char * +dep_name (dep) + struct dep *dep; +{ + return dep->name == 0 ? dep->file->name : dep->name; +} +#endif + +#ifdef GETLOADAVG_PRIVILEGED + +#ifdef POSIX + +/* Hopefully if a system says it's POSIX.1 and has the setuid and setgid + functions, they work as POSIX.1 says. Some systems (Alpha OSF/1 1.2, + for example) which claim to be POSIX.1 also have the BSD setreuid and + setregid functions, but they don't work as in BSD and only the POSIX.1 + way works. */ + +#undef HAVE_SETREUID +#undef HAVE_SETREGID + +#else /* Not POSIX. */ + +/* Some POSIX.1 systems have the seteuid and setegid functions. In a + POSIX-like system, they are the best thing to use. However, some + non-POSIX systems have them too but they do not work in the POSIX style + and we must use setreuid and setregid instead. */ + +#undef HAVE_SETEUID +#undef HAVE_SETEGID + +#endif /* POSIX. */ + +#ifndef HAVE_UNISTD_H +extern int getuid (), getgid (), geteuid (), getegid (); +extern int setuid (), setgid (); +#ifdef HAVE_SETEUID +extern int seteuid (); +#else +#ifdef HAVE_SETREUID +extern int setreuid (); +#endif /* Have setreuid. */ +#endif /* Have seteuid. */ +#ifdef HAVE_SETEGID +extern int setegid (); +#else +#ifdef HAVE_SETREGID +extern int setregid (); +#endif /* Have setregid. */ +#endif /* Have setegid. */ +#endif /* No . */ + +/* Keep track of the user and group IDs for user- and make- access. */ +static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1; +#define access_inited (user_uid != -1) +static enum { make, user } current_access; + + +/* Under -d, write a message describing the current IDs. */ + +static void +log_access (flavor) + char *flavor; +{ + if (! ISDB (DB_JOBS)) + return; + + /* All the other debugging messages go to stdout, + but we write this one to stderr because it might be + run in a child fork whose stdout is piped. */ + + fprintf (stderr, _("%s: user %lu (real %lu), group %lu (real %lu)\n"), + flavor, (unsigned long) geteuid (), (unsigned long) getuid (), + (unsigned long) getegid (), (unsigned long) getgid ()); + fflush (stderr); +} + + +static void +init_access () +{ +#ifndef VMS + user_uid = getuid (); + user_gid = getgid (); + + make_uid = geteuid (); + make_gid = getegid (); + + /* Do these ever fail? */ + if (user_uid == -1 || user_gid == -1 || make_uid == -1 || make_gid == -1) + pfatal_with_name ("get{e}[gu]id"); + + log_access (_("Initialized access")); + + current_access = make; +#endif +} + +#endif /* GETLOADAVG_PRIVILEGED */ + +/* Give the process appropriate permissions for access to + user data (i.e., to stat files, or to spawn a child process). */ +void +user_access () +{ +#ifdef GETLOADAVG_PRIVILEGED + + if (!access_inited) + init_access (); + + if (current_access == user) + return; + + /* We are in "make access" mode. This means that the effective user and + group IDs are those of make (if it was installed setuid or setgid). + We now want to set the effective user and group IDs to the real IDs, + which are the IDs of the process that exec'd make. */ + +#ifdef HAVE_SETEUID + + /* Modern systems have the seteuid/setegid calls which set only the + effective IDs, which is ideal. */ + + if (seteuid (user_uid) < 0) + pfatal_with_name ("user_access: seteuid"); + +#else /* Not HAVE_SETEUID. */ + +#ifndef HAVE_SETREUID + + /* System V has only the setuid/setgid calls to set user/group IDs. + There is an effective ID, which can be set by setuid/setgid. + It can be set (unless you are root) only to either what it already is + (returned by geteuid/getegid, now in make_uid/make_gid), + the real ID (return by getuid/getgid, now in user_uid/user_gid), + or the saved set ID (what the effective ID was before this set-ID + executable (make) was exec'd). */ + + if (setuid (user_uid) < 0) + pfatal_with_name ("user_access: setuid"); + +#else /* HAVE_SETREUID. */ + + /* In 4BSD, the setreuid/setregid calls set both the real and effective IDs. + They may be set to themselves or each other. So you have two alternatives + at any one time. If you use setuid/setgid, the effective will be set to + the real, leaving only one alternative. Using setreuid/setregid, however, + you can toggle between your two alternatives by swapping the values in a + single setreuid or setregid call. */ + + if (setreuid (make_uid, user_uid) < 0) + pfatal_with_name ("user_access: setreuid"); + +#endif /* Not HAVE_SETREUID. */ +#endif /* HAVE_SETEUID. */ + +#ifdef HAVE_SETEGID + if (setegid (user_gid) < 0) + pfatal_with_name ("user_access: setegid"); +#else +#ifndef HAVE_SETREGID + if (setgid (user_gid) < 0) + pfatal_with_name ("user_access: setgid"); +#else + if (setregid (make_gid, user_gid) < 0) + pfatal_with_name ("user_access: setregid"); +#endif +#endif + + current_access = user; + + log_access (_("User access")); + +#endif /* GETLOADAVG_PRIVILEGED */ +} + +/* Give the process appropriate permissions for access to + make data (i.e., the load average). */ +void +make_access () +{ +#ifdef GETLOADAVG_PRIVILEGED + + if (!access_inited) + init_access (); + + if (current_access == make) + return; + + /* See comments in user_access, above. */ + +#ifdef HAVE_SETEUID + if (seteuid (make_uid) < 0) + pfatal_with_name ("make_access: seteuid"); +#else +#ifndef HAVE_SETREUID + if (setuid (make_uid) < 0) + pfatal_with_name ("make_access: setuid"); +#else + if (setreuid (user_uid, make_uid) < 0) + pfatal_with_name ("make_access: setreuid"); +#endif +#endif + +#ifdef HAVE_SETEGID + if (setegid (make_gid) < 0) + pfatal_with_name ("make_access: setegid"); +#else +#ifndef HAVE_SETREGID + if (setgid (make_gid) < 0) + pfatal_with_name ("make_access: setgid"); +#else + if (setregid (user_gid, make_gid) < 0) + pfatal_with_name ("make_access: setregid"); +#endif +#endif + + current_access = make; + + log_access (_("Make access")); + +#endif /* GETLOADAVG_PRIVILEGED */ +} + +/* Give the process appropriate permissions for a child process. + This is like user_access, but you can't get back to make_access. */ +void +child_access () +{ +#ifdef GETLOADAVG_PRIVILEGED + + if (!access_inited) + abort (); + + /* Set both the real and effective UID and GID to the user's. + They cannot be changed back to make's. */ + +#ifndef HAVE_SETREUID + if (setuid (user_uid) < 0) + pfatal_with_name ("child_access: setuid"); +#else + if (setreuid (user_uid, user_uid) < 0) + pfatal_with_name ("child_access: setreuid"); +#endif + +#ifndef HAVE_SETREGID + if (setgid (user_gid) < 0) + pfatal_with_name ("child_access: setgid"); +#else + if (setregid (user_gid, user_gid) < 0) + pfatal_with_name ("child_access: setregid"); +#endif + + log_access (_("Child access")); + +#endif /* GETLOADAVG_PRIVILEGED */ +} + +#ifdef NEED_GET_PATH_MAX +unsigned int +get_path_max () +{ + static unsigned int value; + + if (value == 0) + { + long int x = pathconf ("/", _PC_PATH_MAX); + if (x > 0) + value = x; + else + return MAXPATHLEN; + } + + return value; +} +#endif + + +#ifdef HAVE_BROKEN_RESTART + +#undef stat +#undef readdir + +int +atomic_stat(file, buf) + const char *file; + struct stat *buf; +{ + int r; + + while ((r = stat (file, buf)) < 0) + if (errno != EINTR) + break; + + return r; +} + +struct dirent * +atomic_readdir(dir) + DIR *dir; +{ + struct dirent *r; + + while ((r = readdir (dir)) == NULL) + if (errno != EINTR) + break; + + return r; +} + +#endif /* HAVE_BROKEN_RESTART */ diff --git a/src/make-3.80/n.bat b/src/make-3.80/n.bat new file mode 100755 index 00000000..9beaef49 --- /dev/null +++ b/src/make-3.80/n.bat @@ -0,0 +1,21 @@ +del WinRel /s /q +del WinDebug /s /q +del w32\subproc\WinRel /s /q +del w32\subproc\WinDebug /s /q + +del config.h +nmake /f NMakefile +@if errorlevel 1 goto failure +copy WinRel\make.exe ..\bin + +del WinRel /s /q +del WinDebug /s /q +del w32\subproc\WinRel /s /q +del w32\subproc\WinDebug /s /q + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/make-3.80/read.c b/src/make-3.80/read.c new file mode 100755 index 00000000..9a4c609d --- /dev/null +++ b/src/make-3.80/read.c @@ -0,0 +1,3105 @@ +/* Reading and parsing of makefiles for GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" + +#include + +#include + +#include "dep.h" +#include "filedef.h" +#include "job.h" +#include "commands.h" +#include "variable.h" +#include "rule.h" +#include "debug.h" +#include "hash.h" + + +#ifndef WINDOWS32 +#ifndef _AMIGA +#ifndef VMS +#include +#else +struct passwd *getpwnam PARAMS ((char *name)); +#endif +#endif +#endif /* !WINDOWS32 */ + +/* A 'struct ebuffer' controls the origin of the makefile we are currently + eval'ing. +*/ + +struct ebuffer + { + char *buffer; /* Start of the current line in the buffer. */ + char *bufnext; /* Start of the next line in the buffer. */ + char *bufstart; /* Start of the entire buffer. */ + unsigned int size; /* Malloc'd size of buffer. */ + FILE *fp; /* File, or NULL if this is an internal buffer. */ + struct floc floc; /* Info on the file in fp (if any). */ + }; + +/* Types of "words" that can be read in a makefile. */ +enum make_word_type + { + w_bogus, w_eol, w_static, w_variable, w_colon, w_dcolon, w_semicolon, + w_varassign + }; + + +/* A `struct conditionals' contains the information describing + all the active conditionals in a makefile. + + The global variable `conditionals' contains the conditionals + information for the current makefile. It is initialized from + the static structure `toplevel_conditionals' and is later changed + to new structures for included makefiles. */ + +struct conditionals + { + unsigned int if_cmds; /* Depth of conditional nesting. */ + unsigned int allocated; /* Elts allocated in following arrays. */ + char *ignoring; /* Are we ignoring or interepreting? */ + char *seen_else; /* Have we already seen an `else'? */ + }; + +static struct conditionals toplevel_conditionals; +static struct conditionals *conditionals = &toplevel_conditionals; + + +/* Default directories to search for include files in */ + +static char *default_include_directories[] = + { +#if defined(WINDOWS32) && !defined(INCLUDEDIR) +/* + * This completely up to the user when they install MSVC or other packages. + * This is defined as a placeholder. + */ +#define INCLUDEDIR "." +#endif + INCLUDEDIR, +#ifndef _AMIGA + "/usr/gnu/include", + "/usr/local/include", + "/usr/include", +#endif + 0 + }; + +/* List of directories to search for include files in */ + +static char **include_directories; + +/* Maximum length of an element of the above. */ + +static unsigned int max_incl_len; + +/* The filename and pointer to line number of the + makefile currently being read in. */ + +const struct floc *reading_file = 0; + +/* The chain of makefiles read by read_makefile. */ + +static struct dep *read_makefiles = 0; + +static int eval_makefile PARAMS ((char *filename, int flags)); +static int eval PARAMS ((struct ebuffer *buffer, int flags)); + +static long readline PARAMS ((struct ebuffer *ebuf)); +static void do_define PARAMS ((char *name, unsigned int namelen, + enum variable_origin origin, + struct ebuffer *ebuf)); +static int conditional_line PARAMS ((char *line, const struct floc *flocp)); +static void record_files PARAMS ((struct nameseq *filenames, char *pattern, char *pattern_percent, + struct dep *deps, unsigned int cmds_started, char *commands, + unsigned int commands_idx, int two_colon, + int have_sysv_atvar, + const struct floc *flocp, int set_default)); +static void record_target_var PARAMS ((struct nameseq *filenames, char *defn, + int two_colon, + enum variable_origin origin, + const struct floc *flocp)); +static enum make_word_type get_next_mword PARAMS ((char *buffer, char *delim, + char **startp, unsigned int *length)); + +/* Read in all the makefiles and return the chain of their names. */ + +struct dep * +read_all_makefiles (makefiles) + char **makefiles; +{ + unsigned int num_makefiles = 0; + + /* Create *_LIST variables, to hold the makefiles, targets, and variables + we will be reading. */ + + define_variable ("MAKEFILE_LIST", sizeof ("MAKEFILE_LIST")-1, "", o_file, 0); + + DB (DB_BASIC, (_("Reading makefiles...\n"))); + + /* If there's a non-null variable MAKEFILES, its value is a list of + files to read first thing. But don't let it prevent reading the + default makefiles and don't let the default goal come from there. */ + + { + char *value; + char *name, *p; + unsigned int length; + + { + /* Turn off --warn-undefined-variables while we expand MAKEFILES. */ + int save = warn_undefined_variables_flag; + warn_undefined_variables_flag = 0; + + value = allocated_variable_expand ("$(MAKEFILES)"); + + warn_undefined_variables_flag = save; + } + + /* Set NAME to the start of next token and LENGTH to its length. + MAKEFILES is updated for finding remaining tokens. */ + p = value; + + while ((name = find_next_token (&p, &length)) != 0) + { + if (*p != '\0') + *p++ = '\0'; + name = xstrdup (name); + if (eval_makefile (name, + RM_NO_DEFAULT_GOAL|RM_INCLUDED|RM_DONTCARE) < 2) + free (name); + } + + free (value); + } + + /* Read makefiles specified with -f switches. */ + + if (makefiles != 0) + while (*makefiles != 0) + { + struct dep *tail = read_makefiles; + register struct dep *d; + + if (! eval_makefile (*makefiles, 0)) + perror_with_name ("", *makefiles); + + /* Find the right element of read_makefiles. */ + d = read_makefiles; + while (d->next != tail) + d = d->next; + + /* Use the storage read_makefile allocates. */ + *makefiles = dep_name (d); + ++num_makefiles; + ++makefiles; + } + + /* If there were no -f switches, try the default names. */ + + if (num_makefiles == 0) + { + static char *default_makefiles[] = +#ifdef VMS + /* all lower case since readdir() (the vms version) 'lowercasifies' */ + { "makefile.vms", "gnumakefile.", "makefile.", 0 }; +#else +#ifdef _AMIGA + { "GNUmakefile", "Makefile", "SMakefile", 0 }; +#else /* !Amiga && !VMS */ + { "GNUmakefile", "makefile", "Makefile", 0 }; +#endif /* AMIGA */ +#endif /* VMS */ + register char **p = default_makefiles; + while (*p != 0 && !file_exists_p (*p)) + ++p; + + if (*p != 0) + { + if (! eval_makefile (*p, 0)) + perror_with_name ("", *p); + } + else + { + /* No default makefile was found. Add the default makefiles to the + `read_makefiles' chain so they will be updated if possible. */ + struct dep *tail = read_makefiles; + /* Add them to the tail, after any MAKEFILES variable makefiles. */ + while (tail != 0 && tail->next != 0) + tail = tail->next; + for (p = default_makefiles; *p != 0; ++p) + { + struct dep *d = (struct dep *) xmalloc (sizeof (struct dep)); + d->name = 0; + d->file = enter_file (*p); + d->file->dontcare = 1; + d->ignore_mtime = 0; + /* Tell update_goal_chain to bail out as soon as this file is + made, and main not to die if we can't make this file. */ + d->changed = RM_DONTCARE; + if (tail == 0) + read_makefiles = d; + else + tail->next = d; + tail = d; + } + if (tail != 0) + tail->next = 0; + } + } + + return read_makefiles; +} + +static int +eval_makefile (filename, flags) + char *filename; + int flags; +{ + struct dep *deps; + struct ebuffer ebuf; + const struct floc *curfile; + int makefile_errno; + int r; + + ebuf.floc.filenm = filename; + ebuf.floc.lineno = 1; + + if (ISDB (DB_VERBOSE)) + { + printf (_("Reading makefile `%s'"), filename); + if (flags & RM_NO_DEFAULT_GOAL) + printf (_(" (no default goal)")); + if (flags & RM_INCLUDED) + printf (_(" (search path)")); + if (flags & RM_DONTCARE) + printf (_(" (don't care)")); + if (flags & RM_NO_TILDE) + printf (_(" (no ~ expansion)")); + puts ("..."); + } + + /* First, get a stream to read. */ + + /* Expand ~ in FILENAME unless it came from `include', + in which case it was already done. */ + if (!(flags & RM_NO_TILDE) && filename[0] == '~') + { + char *expanded = tilde_expand (filename); + if (expanded != 0) + filename = expanded; + } + + ebuf.fp = fopen (filename, "r"); + /* Save the error code so we print the right message later. */ + makefile_errno = errno; + + /* If the makefile wasn't found and it's either a makefile from + the `MAKEFILES' variable or an included makefile, + search the included makefile search path for this makefile. */ + if (ebuf.fp == 0 && (flags & RM_INCLUDED) && *filename != '/') + { + register unsigned int i; + for (i = 0; include_directories[i] != 0; ++i) + { + char *name = concat (include_directories[i], "/", filename); + ebuf.fp = fopen (name, "r"); + if (ebuf.fp == 0) + free (name); + else + { + filename = name; + break; + } + } + } + + /* Add FILENAME to the chain of read makefiles. */ + deps = (struct dep *) xmalloc (sizeof (struct dep)); + deps->next = read_makefiles; + read_makefiles = deps; + deps->name = 0; + deps->file = lookup_file (filename); + if (deps->file == 0) + { + deps->file = enter_file (xstrdup (filename)); + if (flags & RM_DONTCARE) + deps->file->dontcare = 1; + } + if (filename != ebuf.floc.filenm) + free (filename); + filename = deps->file->name; + deps->changed = flags; + deps->ignore_mtime = 0; + + /* If the makefile can't be found at all, give up entirely. */ + + if (ebuf.fp == 0) + { + /* If we did some searching, errno has the error from the last + attempt, rather from FILENAME itself. Restore it in case the + caller wants to use it in a message. */ + errno = makefile_errno; + return 0; + } + + /* Add this makefile to the list. */ + do_variable_definition (&ebuf.floc, "MAKEFILE_LIST", filename, o_file, + f_append, 0); + + /* Evaluate the makefile */ + + ebuf.size = 200; + ebuf.buffer = ebuf.bufnext = ebuf.bufstart = xmalloc (ebuf.size); + + curfile = reading_file; + reading_file = &ebuf.floc; + + r = eval (&ebuf, !(flags & RM_NO_DEFAULT_GOAL)); + + reading_file = curfile; + + fclose (ebuf.fp); + + free (ebuf.bufstart); + return r; +} + +int +eval_buffer (buffer) + char *buffer; +{ + struct ebuffer ebuf; + const struct floc *curfile; + int r; + + /* Evaluate the buffer */ + + ebuf.size = strlen (buffer); + ebuf.buffer = ebuf.bufnext = ebuf.bufstart = buffer; + ebuf.fp = NULL; + + ebuf.floc = *reading_file; + + curfile = reading_file; + reading_file = &ebuf.floc; + + r = eval (&ebuf, 1); + + reading_file = curfile; + + return r; +} + + +/* Read file FILENAME as a makefile and add its contents to the data base. + + SET_DEFAULT is true if we are allowed to set the default goal. + + FILENAME is added to the `read_makefiles' chain. + + Returns 0 if a file was not found or not read. + Returns 1 if FILENAME was found and read. + Returns 2 if FILENAME was read, and we kept a reference (don't free it). */ + +static int +eval (ebuf, set_default) + struct ebuffer *ebuf; + int set_default; +{ + static char *collapsed = 0; + static unsigned int collapsed_length = 0; + unsigned int commands_len = 200; + char *commands; + unsigned int commands_idx = 0; + unsigned int cmds_started, tgts_started; + int ignoring = 0, in_ignored_define = 0; + int no_targets = 0; /* Set when reading a rule without targets. */ + int have_sysv_atvar = 0; + struct nameseq *filenames = 0; + struct dep *deps = 0; + long nlines = 0; + int two_colon = 0; + char *pattern = 0, *pattern_percent; + struct floc *fstart; + struct floc fi; + +#define record_waiting_files() \ + do \ + { \ + if (filenames != 0) \ + { \ + fi.lineno = tgts_started; \ + record_files (filenames, pattern, pattern_percent, deps, \ + cmds_started, commands, commands_idx, two_colon, \ + have_sysv_atvar, &fi, set_default); \ + } \ + filenames = 0; \ + commands_idx = 0; \ + no_targets = 0; \ + if (pattern) { free(pattern); pattern = 0; } \ + } while (0) + + pattern_percent = 0; + cmds_started = tgts_started = 1; + + fstart = &ebuf->floc; + fi.filenm = ebuf->floc.filenm; + + /* Loop over lines in the file. + The strategy is to accumulate target names in FILENAMES, dependencies + in DEPS and commands in COMMANDS. These are used to define a rule + when the start of the next rule (or eof) is encountered. + + When you see a "continue" in the loop below, that means we are moving on + to the next line _without_ ending any rule that we happen to be working + with at the moment. If you see a "goto rule_complete", then the + statement we just parsed also finishes the previous rule. */ + + commands = xmalloc (200); + + while (1) + { + int linelen; + char *line; + int len; + char *p; + char *p2; + + /* Grab the next line to be evaluated */ + ebuf->floc.lineno += nlines; + nlines = readline (ebuf); + + /* If there is nothing left to eval, we're done. */ + if (nlines < 0) + break; + + /* If this line is empty, skip it. */ + line = ebuf->buffer; + if (line[0] == '\0') + continue; + + linelen = strlen (line); + + /* Check for a shell command line first. + If it is not one, we can stop treating tab specially. */ + if (line[0] == '\t') + { + if (no_targets) + /* Ignore the commands in a rule with no targets. */ + continue; + + /* If there is no preceding rule line, don't treat this line + as a command, even though it begins with a tab character. + SunOS 4 make appears to behave this way. */ + + if (filenames != 0) + { + if (ignoring) + /* Yep, this is a shell command, and we don't care. */ + continue; + + /* Append this command line to the line being accumulated. */ + if (commands_idx == 0) + cmds_started = ebuf->floc.lineno; + + if (linelen + 1 + commands_idx > commands_len) + { + commands_len = (linelen + 1 + commands_idx) * 2; + commands = xrealloc (commands, commands_len); + } + bcopy (line, &commands[commands_idx], linelen); + commands_idx += linelen; + commands[commands_idx++] = '\n'; + + continue; + } + } + + /* This line is not a shell command line. Don't worry about tabs. */ + + if (collapsed_length < linelen+1) + { + collapsed_length = linelen+1; + if (collapsed != 0) + free (collapsed); + collapsed = (char *) xmalloc (collapsed_length); + } + strcpy (collapsed, line); + /* Collapse continuation lines. */ + collapse_continuations (collapsed); + remove_comments (collapsed); + + /* Compare a word, both length and contents. */ +#define word1eq(s) (len == sizeof(s)-1 && strneq (s, p, sizeof(s)-1)) + p = collapsed; + while (isspace ((unsigned char)*p)) + ++p; + + if (*p == '\0') + /* This line is completely empty--ignore it. */ + continue; + + /* Find the end of the first token. Note we don't need to worry about + * ":" here since we compare tokens by length (so "export" will never + * be equal to "export:"). + */ + for (p2 = p+1; *p2 != '\0' && !isspace ((unsigned char)*p2); ++p2) + ; + len = p2 - p; + + /* Find the start of the second token. If it looks like a target or + variable definition it can't be a preprocessor token so skip + them--this allows variables/targets named `ifdef', `export', etc. */ + while (isspace ((unsigned char)*p2)) + ++p2; + + if ((p2[0] == ':' || p2[0] == '+' || p2[0] == '=') && p2[1] == '\0') + { + /* It can't be a preprocessor token so skip it if we're ignoring */ + if (ignoring) + continue; + + goto skip_conditionals; + } + + /* We must first check for conditional and `define' directives before + ignoring anything, since they control what we will do with + following lines. */ + + if (!in_ignored_define + && (word1eq ("ifdef") || word1eq ("ifndef") + || word1eq ("ifeq") || word1eq ("ifneq") + || word1eq ("else") || word1eq ("endif"))) + { + int i = conditional_line (p, fstart); + if (i < 0) + fatal (fstart, _("invalid syntax in conditional")); + + ignoring = i; + continue; + } + + if (word1eq ("endef")) + { + if (!in_ignored_define) + fatal (fstart, _("extraneous `endef'")); + in_ignored_define = 0; + continue; + } + + if (word1eq ("define")) + { + if (ignoring) + in_ignored_define = 1; + else + { + if (*p2 == '\0') + fatal (fstart, _("empty variable name")); + + /* Let the variable name be the whole rest of the line, + with trailing blanks stripped (comments have already been + removed), so it could be a complex variable/function + reference that might contain blanks. */ + p = strchr (p2, '\0'); + while (isblank ((unsigned char)p[-1])) + --p; + do_define (p2, p - p2, o_file, ebuf); + } + continue; + } + + if (word1eq ("override")) + { + if (*p2 == '\0') + error (fstart, _("empty `override' directive")); + + if (strneq (p2, "define", 6) + && (isblank ((unsigned char)p2[6]) || p2[6] == '\0')) + { + if (ignoring) + in_ignored_define = 1; + else + { + p2 = next_token (p2 + 6); + if (*p2 == '\0') + fatal (fstart, _("empty variable name")); + + /* Let the variable name be the whole rest of the line, + with trailing blanks stripped (comments have already been + removed), so it could be a complex variable/function + reference that might contain blanks. */ + p = strchr (p2, '\0'); + while (isblank ((unsigned char)p[-1])) + --p; + do_define (p2, p - p2, o_override, ebuf); + } + } + else if (!ignoring + && !try_variable_definition (fstart, p2, o_override, 0)) + error (fstart, _("invalid `override' directive")); + + continue; + } + + if (ignoring) + /* Ignore the line. We continue here so conditionals + can appear in the middle of a rule. */ + continue; + + if (word1eq ("export")) + { + /* 'export' by itself causes everything to be exported. */ + if (*p2 == '\0') + export_all_variables = 1; + else + { + struct variable *v; + + v = try_variable_definition (fstart, p2, o_file, 0); + if (v != 0) + v->export = v_export; + else + { + unsigned int len; + char *ap; + + /* Expand the line so we can use indirect and constructed + variable names in an export command. */ + p2 = ap = allocated_variable_expand (p2); + + for (p = find_next_token (&p2, &len); p != 0; + p = find_next_token (&p2, &len)) + { + v = lookup_variable (p, len); + if (v == 0) + v = define_variable_loc (p, len, "", o_file, 0, + fstart); + v->export = v_export; + } + + free (ap); + } + } + goto rule_complete; + } + + if (word1eq ("unexport")) + { + if (*p2 == '\0') + export_all_variables = 0; + else + { + unsigned int len; + struct variable *v; + char *ap; + + /* Expand the line so we can use indirect and constructed + variable names in an unexport command. */ + p2 = ap = allocated_variable_expand (p2); + + for (p = find_next_token (&p2, &len); p != 0; + p = find_next_token (&p2, &len)) + { + v = lookup_variable (p, len); + if (v == 0) + v = define_variable_loc (p, len, "", o_file, 0, fstart); + + v->export = v_noexport; + } + + free (ap); + } + goto rule_complete; + } + + skip_conditionals: + if (word1eq ("vpath")) + { + char *pattern; + unsigned int len; + p2 = variable_expand (p2); + p = find_next_token (&p2, &len); + if (p != 0) + { + pattern = savestring (p, len); + p = find_next_token (&p2, &len); + /* No searchpath means remove all previous + selective VPATH's with the same pattern. */ + } + else + /* No pattern means remove all previous selective VPATH's. */ + pattern = 0; + construct_vpath_list (pattern, p); + if (pattern != 0) + free (pattern); + + goto rule_complete; + } + + if (word1eq ("include") || word1eq ("-include") || word1eq ("sinclude")) + { + /* We have found an `include' line specifying a nested + makefile to be read at this point. */ + struct conditionals *save; + struct conditionals new_conditionals; + struct nameseq *files; + /* "-include" (vs "include") says no error if the file does not + exist. "sinclude" is an alias for this from SGI. */ + int noerror = (p[0] != 'i'); + + p = allocated_variable_expand (p2); + if (*p == '\0') + { + error (fstart, + _("no file name for `%sinclude'"), noerror ? "-" : ""); + continue; + } + + /* Parse the list of file names. */ + p2 = p; + files = multi_glob (parse_file_seq (&p2, '\0', + sizeof (struct nameseq), + 1), + sizeof (struct nameseq)); + free (p); + + /* Save the state of conditionals and start + the included makefile with a clean slate. */ + save = conditionals; + bzero ((char *) &new_conditionals, sizeof new_conditionals); + conditionals = &new_conditionals; + + /* Record the rules that are waiting so they will determine + the default goal before those in the included makefile. */ + record_waiting_files (); + + /* Read each included makefile. */ + while (files != 0) + { + struct nameseq *next = files->next; + char *name = files->name; + int r; + + free ((char *)files); + files = next; + + r = eval_makefile (name, (RM_INCLUDED | RM_NO_TILDE + | (noerror ? RM_DONTCARE : 0))); + if (!r) + { + if (!noerror) + error (fstart, "%s: %s", name, strerror (errno)); + free (name); + } + } + + /* Free any space allocated by conditional_line. */ + if (conditionals->ignoring) + free (conditionals->ignoring); + if (conditionals->seen_else) + free (conditionals->seen_else); + + /* Restore state. */ + conditionals = save; + + goto rule_complete; + } + + if (try_variable_definition (fstart, p, o_file, 0)) + /* This line has been dealt with. */ + goto rule_complete; + + if (line[0] == '\t') + { + p = collapsed; /* Ignore comments, etc. */ + while (isblank ((unsigned char)*p)) + ++p; + if (*p == '\0') + /* The line is completely blank; that is harmless. */ + continue; + + /* This line starts with a tab but was not caught above + because there was no preceding target, and the line + might have been usable as a variable definition. + But now we know it is definitely lossage. */ + fatal(fstart, _("commands commence before first target")); + } + + /* This line describes some target files. This is complicated by + the existence of target-specific variables, because we can't + expand the entire line until we know if we have one or not. So + we expand the line word by word until we find the first `:', + then check to see if it's a target-specific variable. + + In this algorithm, `lb_next' will point to the beginning of the + unexpanded parts of the input buffer, while `p2' points to the + parts of the expanded buffer we haven't searched yet. */ + + { + enum make_word_type wtype; + enum variable_origin v_origin; + char *cmdleft, *semip, *lb_next; + unsigned int len, plen = 0; + char *colonp; + + /* Record the previous rule. */ + + record_waiting_files (); + tgts_started = fstart->lineno; + + /* Search the line for an unquoted ; that is not after an + unquoted #. */ + cmdleft = find_char_unquote (line, ';', '#', 0); + if (cmdleft != 0 && *cmdleft == '#') + { + /* We found a comment before a semicolon. */ + *cmdleft = '\0'; + cmdleft = 0; + } + else if (cmdleft != 0) + /* Found one. Cut the line short there before expanding it. */ + *(cmdleft++) = '\0'; + semip = cmdleft; + + collapse_continuations (line); + + /* We can't expand the entire line, since if it's a per-target + variable we don't want to expand it. So, walk from the + beginning, expanding as we go, and looking for "interesting" + chars. The first word is always expandable. */ + wtype = get_next_mword(line, NULL, &lb_next, &len); + switch (wtype) + { + case w_eol: + if (cmdleft != 0) + fatal(fstart, _("missing rule before commands")); + /* This line contained something but turned out to be nothing + but whitespace (a comment?). */ + continue; + + case w_colon: + case w_dcolon: + /* We accept and ignore rules without targets for + compatibility with SunOS 4 make. */ + no_targets = 1; + continue; + + default: + break; + } + + p2 = variable_expand_string(NULL, lb_next, len); + while (1) + { + lb_next += len; + if (cmdleft == 0) + { + /* Look for a semicolon in the expanded line. */ + cmdleft = find_char_unquote (p2, ';', 0, 0); + + if (cmdleft != 0) + { + unsigned long p2_off = p2 - variable_buffer; + unsigned long cmd_off = cmdleft - variable_buffer; + char *pend = p2 + strlen(p2); + + /* Append any remnants of lb, then cut the line short + at the semicolon. */ + *cmdleft = '\0'; + + /* One school of thought says that you shouldn't expand + here, but merely copy, since now you're beyond a ";" + and into a command script. However, the old parser + expanded the whole line, so we continue that for + backwards-compatiblity. Also, it wouldn't be + entirely consistent, since we do an unconditional + expand below once we know we don't have a + target-specific variable. */ + (void)variable_expand_string(pend, lb_next, (long)-1); + lb_next += strlen(lb_next); + p2 = variable_buffer + p2_off; + cmdleft = variable_buffer + cmd_off + 1; + } + } + + colonp = find_char_unquote(p2, ':', 0, 0); +#ifdef HAVE_DOS_PATHS + /* The drive spec brain-damage strikes again... */ + /* Note that the only separators of targets in this context + are whitespace and a left paren. If others are possible, + they should be added to the string in the call to index. */ + while (colonp && (colonp[1] == '/' || colonp[1] == '\\') && + colonp > p2 && isalpha ((unsigned char)colonp[-1]) && + (colonp == p2 + 1 || strchr (" \t(", colonp[-2]) != 0)) + colonp = find_char_unquote(colonp + 1, ':', 0, 0); +#endif + if (colonp != 0) + break; + + wtype = get_next_mword(lb_next, NULL, &lb_next, &len); + if (wtype == w_eol) + break; + + p2 += strlen(p2); + *(p2++) = ' '; + p2 = variable_expand_string(p2, lb_next, len); + /* We don't need to worry about cmdleft here, because if it was + found in the variable_buffer the entire buffer has already + been expanded... we'll never get here. */ + } + + p2 = next_token (variable_buffer); + + /* If the word we're looking at is EOL, see if there's _anything_ + on the line. If not, a variable expanded to nothing, so ignore + it. If so, we can't parse this line so punt. */ + if (wtype == w_eol) + { + if (*p2 != '\0') + /* There's no need to be ivory-tower about this: check for + one of the most common bugs found in makefiles... */ + fatal (fstart, _("missing separator%s"), + !strneq(line, " ", 8) ? "" + : _(" (did you mean TAB instead of 8 spaces?)")); + continue; + } + + /* Make the colon the end-of-string so we know where to stop + looking for targets. */ + *colonp = '\0'; + filenames = multi_glob (parse_file_seq (&p2, '\0', + sizeof (struct nameseq), + 1), + sizeof (struct nameseq)); + *p2 = ':'; + + if (!filenames) + { + /* We accept and ignore rules without targets for + compatibility with SunOS 4 make. */ + no_targets = 1; + continue; + } + /* This should never be possible; we handled it above. */ + assert (*p2 != '\0'); + ++p2; + + /* Is this a one-colon or two-colon entry? */ + two_colon = *p2 == ':'; + if (two_colon) + p2++; + + /* Test to see if it's a target-specific variable. Copy the rest + of the buffer over, possibly temporarily (we'll expand it later + if it's not a target-specific variable). PLEN saves the length + of the unparsed section of p2, for later. */ + if (*lb_next != '\0') + { + unsigned int l = p2 - variable_buffer; + plen = strlen (p2); + (void) variable_buffer_output (p2+plen, + lb_next, strlen (lb_next)+1); + p2 = variable_buffer + l; + } + + /* See if it's an "override" keyword; if so see if what comes after + it looks like a variable definition. */ + + wtype = get_next_mword (p2, NULL, &p, &len); + + v_origin = o_file; + if (wtype == w_static && word1eq ("override")) + { + v_origin = o_override; + wtype = get_next_mword (p+len, NULL, &p, &len); + } + + if (wtype != w_eol) + wtype = get_next_mword (p+len, NULL, NULL, NULL); + + if (wtype == w_varassign) + { + /* If there was a semicolon found, add it back, plus anything + after it. */ + if (semip) + { + *(--semip) = ';'; + variable_buffer_output (p2 + strlen (p2), + semip, strlen (semip)+1); + } + record_target_var (filenames, p, two_colon, v_origin, fstart); + filenames = 0; + continue; + } + + /* This is a normal target, _not_ a target-specific variable. + Unquote any = in the dependency list. */ + find_char_unquote (lb_next, '=', 0, 0); + + /* We have some targets, so don't ignore the following commands. */ + no_targets = 0; + + /* Expand the dependencies, etc. */ + if (*lb_next != '\0') + { + unsigned int l = p2 - variable_buffer; + (void) variable_expand_string (p2 + plen, lb_next, (long)-1); + p2 = variable_buffer + l; + + /* Look for a semicolon in the expanded line. */ + if (cmdleft == 0) + { + cmdleft = find_char_unquote (p2, ';', 0, 0); + if (cmdleft != 0) + *(cmdleft++) = '\0'; + } + } + + /* Do any of the prerequisites appear to have $@ etc.? */ + have_sysv_atvar = 0; + if (!posix_pedantic) + for (p = strchr (p2, '$'); p != 0; p = strchr (p+1, '$')) + if (p[1] == '@' || (p[1] == '(' && p[2] == '@')) + { + have_sysv_atvar = 1; + break; + } + + /* Is this a static pattern rule: `target: %targ: %dep; ...'? */ + p = strchr (p2, ':'); + while (p != 0 && p[-1] == '\\') + { + register char *q = &p[-1]; + register int backslash = 0; + while (*q-- == '\\') + backslash = !backslash; + if (backslash) + p = strchr (p + 1, ':'); + else + break; + } +#ifdef _AMIGA + /* Here, the situation is quite complicated. Let's have a look + at a couple of targets: + + install: dev:make + + dev:make: make + + dev:make:: xyz + + The rule is that it's only a target, if there are TWO :'s + OR a space around the :. + */ + if (p && !(isspace ((unsigned char)p[1]) || !p[1] + || isspace ((unsigned char)p[-1]))) + p = 0; +#endif +#ifdef HAVE_DOS_PATHS + { + int check_again; + + do { + check_again = 0; + /* For DOS paths, skip a "C:\..." or a "C:/..." */ + if (p != 0 && (p[1] == '\\' || p[1] == '/') && + isalpha ((unsigned char)p[-1]) && + (p == p2 + 1 || strchr (" \t:(", p[-2]) != 0)) { + p = strchr (p + 1, ':'); + check_again = 1; + } + } while (check_again); + } +#endif + if (p != 0) + { + struct nameseq *target; + target = parse_file_seq (&p2, ':', sizeof (struct nameseq), 1); + ++p2; + if (target == 0) + fatal (fstart, _("missing target pattern")); + else if (target->next != 0) + fatal (fstart, _("multiple target patterns")); + pattern = target->name; + pattern_percent = find_percent (pattern); + if (pattern_percent == 0) + fatal (fstart, _("target pattern contains no `%%'")); + free((char *)target); + } + else + pattern = 0; + + /* Parse the dependencies. */ + deps = (struct dep *) + multi_glob (parse_file_seq (&p2, '|', sizeof (struct dep), 1), + sizeof (struct dep)); + if (*p2) + { + /* Files that follow '|' are special prerequisites that + need only exist in order to satisfy the dependency. + Their modification times are irrelevant. */ + struct dep **deps_ptr = &deps; + struct dep *d; + for (deps_ptr = &deps; *deps_ptr; deps_ptr = &(*deps_ptr)->next) + ; + ++p2; + *deps_ptr = (struct dep *) + multi_glob (parse_file_seq (&p2, '\0', sizeof (struct dep), 1), + sizeof (struct dep)); + for (d = *deps_ptr; d != 0; d = d->next) + d->ignore_mtime = 1; + } + + commands_idx = 0; + if (cmdleft != 0) + { + /* Semicolon means rest of line is a command. */ + unsigned int len = strlen (cmdleft); + + cmds_started = fstart->lineno; + + /* Add this command line to the buffer. */ + if (len + 2 > commands_len) + { + commands_len = (len + 2) * 2; + commands = (char *) xrealloc (commands, commands_len); + } + bcopy (cmdleft, commands, len); + commands_idx += len; + commands[commands_idx++] = '\n'; + } + + continue; + } + + /* We get here except in the case that we just read a rule line. + Record now the last rule we read, so following spurious + commands are properly diagnosed. */ + rule_complete: + record_waiting_files (); + } + +#undef word1eq + + if (conditionals->if_cmds) + fatal (fstart, _("missing `endif'")); + + /* At eof, record the last rule. */ + record_waiting_files (); + + free ((char *) commands); + + return 1; +} + + +/* Execute a `define' directive. + The first line has already been read, and NAME is the name of + the variable to be defined. The following lines remain to be read. */ + +static void +do_define (name, namelen, origin, ebuf) + char *name; + unsigned int namelen; + enum variable_origin origin; + struct ebuffer *ebuf; +{ + struct floc defstart; + long nlines = 0; + int nlevels = 1; + unsigned int length = 100; + char *definition = (char *) xmalloc (length); + unsigned int idx = 0; + char *p; + + /* Expand the variable name. */ + char *var = (char *) alloca (namelen + 1); + bcopy (name, var, namelen); + var[namelen] = '\0'; + var = variable_expand (var); + + defstart = ebuf->floc; + + while (1) + { + unsigned int len; + char *line; + + ebuf->floc.lineno += nlines; + nlines = readline (ebuf); + + /* If there is nothing left to eval, we're done. */ + if (nlines < 0) + break; + + line = ebuf->buffer; + + collapse_continuations (line); + + /* If the line doesn't begin with a tab, test to see if it introduces + another define, or ends one. */ + + /* Stop if we find an 'endef' */ + if (line[0] != '\t') + { + p = next_token (line); + len = strlen (p); + + /* If this is another 'define', increment the level count. */ + if ((len == 6 || (len > 6 && isblank ((unsigned char)p[6]))) + && strneq (p, "define", 6)) + ++nlevels; + + /* If this is an 'endef', decrement the count. If it's now 0, + we've found the last one. */ + else if ((len == 5 || (len > 5 && isblank ((unsigned char)p[5]))) + && strneq (p, "endef", 5)) + { + p += 5; + remove_comments (p); + if (*next_token (p) != '\0') + error (&ebuf->floc, + _("Extraneous text after `endef' directive")); + + if (--nlevels == 0) + { + /* Define the variable. */ + if (idx == 0) + definition[0] = '\0'; + else + definition[idx - 1] = '\0'; + + /* Always define these variables in the global set. */ + define_variable_global (var, strlen (var), definition, + origin, 1, &defstart); + free (definition); + return; + } + } + } + + /* Otherwise add this line to the variable definition. */ + len = strlen (line); + if (idx + len + 1 > length) + { + length = (idx + len) * 2; + definition = (char *) xrealloc (definition, length + 1); + } + + bcopy (line, &definition[idx], len); + idx += len; + /* Separate lines with a newline. */ + definition[idx++] = '\n'; + } + + /* No `endef'!! */ + fatal (&defstart, _("missing `endef', unterminated `define'")); + + /* NOTREACHED */ + return; +} + +/* Interpret conditional commands "ifdef", "ifndef", "ifeq", + "ifneq", "else" and "endif". + LINE is the input line, with the command as its first word. + + FILENAME and LINENO are the filename and line number in the + current makefile. They are used for error messages. + + Value is -1 if the line is invalid, + 0 if following text should be interpreted, + 1 if following text should be ignored. */ + +static int +conditional_line (line, flocp) + char *line; + const struct floc *flocp; +{ + int notdef; + char *cmdname; + register unsigned int i; + + if (*line == 'i') + { + /* It's an "if..." command. */ + notdef = line[2] == 'n'; + if (notdef) + { + cmdname = line[3] == 'd' ? "ifndef" : "ifneq"; + line += cmdname[3] == 'd' ? 7 : 6; + } + else + { + cmdname = line[2] == 'd' ? "ifdef" : "ifeq"; + line += cmdname[2] == 'd' ? 6 : 5; + } + } + else + { + /* It's an "else" or "endif" command. */ + notdef = line[1] == 'n'; + cmdname = notdef ? "endif" : "else"; + line += notdef ? 5 : 4; + } + + line = next_token (line); + + if (*cmdname == 'e') + { + if (*line != '\0') + error (flocp, _("Extraneous text after `%s' directive"), cmdname); + /* "Else" or "endif". */ + if (conditionals->if_cmds == 0) + fatal (flocp, _("extraneous `%s'"), cmdname); + /* NOTDEF indicates an `endif' command. */ + if (notdef) + --conditionals->if_cmds; + else if (conditionals->seen_else[conditionals->if_cmds - 1]) + fatal (flocp, _("only one `else' per conditional")); + else + { + /* Toggle the state of ignorance. */ + conditionals->ignoring[conditionals->if_cmds - 1] + = !conditionals->ignoring[conditionals->if_cmds - 1]; + /* Record that we have seen an `else' in this conditional. + A second `else' will be erroneous. */ + conditionals->seen_else[conditionals->if_cmds - 1] = 1; + } + for (i = 0; i < conditionals->if_cmds; ++i) + if (conditionals->ignoring[i]) + return 1; + return 0; + } + + if (conditionals->allocated == 0) + { + conditionals->allocated = 5; + conditionals->ignoring = (char *) xmalloc (conditionals->allocated); + conditionals->seen_else = (char *) xmalloc (conditionals->allocated); + } + + ++conditionals->if_cmds; + if (conditionals->if_cmds > conditionals->allocated) + { + conditionals->allocated += 5; + conditionals->ignoring = (char *) + xrealloc (conditionals->ignoring, conditionals->allocated); + conditionals->seen_else = (char *) + xrealloc (conditionals->seen_else, conditionals->allocated); + } + + /* Record that we have seen an `if...' but no `else' so far. */ + conditionals->seen_else[conditionals->if_cmds - 1] = 0; + + /* Search through the stack to see if we're already ignoring. */ + for (i = 0; i < conditionals->if_cmds - 1; ++i) + if (conditionals->ignoring[i]) + { + /* We are already ignoring, so just push a level + to match the next "else" or "endif", and keep ignoring. + We don't want to expand variables in the condition. */ + conditionals->ignoring[conditionals->if_cmds - 1] = 1; + return 1; + } + + if (cmdname[notdef ? 3 : 2] == 'd') + { + /* "Ifdef" or "ifndef". */ + char *var; + struct variable *v; + register char *p = end_of_token (line); + i = p - line; + p = next_token (p); + if (*p != '\0') + return -1; + + /* Expand the thing we're looking up, so we can use indirect and + constructed variable names. */ + line[i] = '\0'; + var = allocated_variable_expand (line); + + v = lookup_variable (var, strlen (var)); + conditionals->ignoring[conditionals->if_cmds - 1] + = (v != 0 && *v->value != '\0') == notdef; + + free (var); + } + else + { + /* "Ifeq" or "ifneq". */ + char *s1, *s2; + unsigned int len; + char termin = *line == '(' ? ',' : *line; + + if (termin != ',' && termin != '"' && termin != '\'') + return -1; + + s1 = ++line; + /* Find the end of the first string. */ + if (termin == ',') + { + register int count = 0; + for (; *line != '\0'; ++line) + if (*line == '(') + ++count; + else if (*line == ')') + --count; + else if (*line == ',' && count <= 0) + break; + } + else + while (*line != '\0' && *line != termin) + ++line; + + if (*line == '\0') + return -1; + + if (termin == ',') + { + /* Strip blanks after the first string. */ + char *p = line++; + while (isblank ((unsigned char)p[-1])) + --p; + *p = '\0'; + } + else + *line++ = '\0'; + + s2 = variable_expand (s1); + /* We must allocate a new copy of the expanded string because + variable_expand re-uses the same buffer. */ + len = strlen (s2); + s1 = (char *) alloca (len + 1); + bcopy (s2, s1, len + 1); + + if (termin != ',') + /* Find the start of the second string. */ + line = next_token (line); + + termin = termin == ',' ? ')' : *line; + if (termin != ')' && termin != '"' && termin != '\'') + return -1; + + /* Find the end of the second string. */ + if (termin == ')') + { + register int count = 0; + s2 = next_token (line); + for (line = s2; *line != '\0'; ++line) + { + if (*line == '(') + ++count; + else if (*line == ')') + { + if (count <= 0) + break; + else + --count; + } + } + } + else + { + ++line; + s2 = line; + while (*line != '\0' && *line != termin) + ++line; + } + + if (*line == '\0') + return -1; + + *line = '\0'; + line = next_token (++line); + if (*line != '\0') + error (flocp, _("Extraneous text after `%s' directive"), cmdname); + + s2 = variable_expand (s2); + conditionals->ignoring[conditionals->if_cmds - 1] + = streq (s1, s2) == notdef; + } + + /* Search through the stack to see if we're ignoring. */ + for (i = 0; i < conditionals->if_cmds; ++i) + if (conditionals->ignoring[i]) + return 1; + return 0; +} + +/* Remove duplicate dependencies in CHAIN. */ + +static unsigned long +dep_hash_1 (key) + const void *key; +{ + return_STRING_HASH_1 (dep_name ((struct dep const *) key)); +} + +static unsigned long +dep_hash_2 (key) + const void *key; +{ + return_STRING_HASH_2 (dep_name ((struct dep const *) key)); +} + +static int +dep_hash_cmp (x, y) + const void *x; + const void *y; +{ + struct dep *dx = (struct dep *) x; + struct dep *dy = (struct dep *) y; + int cmp = strcmp (dep_name (dx), dep_name (dy)); + + /* If the names are the same but ignore_mtimes are not equal, one of these + is an order-only prerequisite and one isn't. That means that we should + remove the one that isn't and keep the one that is. */ + + if (!cmp && dx->ignore_mtime != dy->ignore_mtime) + dx->ignore_mtime = dy->ignore_mtime = 0; + + return cmp; +} + + +void +uniquize_deps (chain) + struct dep *chain; +{ + struct hash_table deps; + register struct dep **depp; + + hash_init (&deps, 500, dep_hash_1, dep_hash_2, dep_hash_cmp); + + /* Make sure that no dependencies are repeated. This does not + really matter for the purpose of updating targets, but it + might make some names be listed twice for $^ and $?. */ + + depp = &chain; + while (*depp) + { + struct dep *dep = *depp; + struct dep **dep_slot = (struct dep **) hash_find_slot (&deps, dep); + if (HASH_VACANT (*dep_slot)) + { + hash_insert_at (&deps, dep, dep_slot); + depp = &dep->next; + } + else + { + /* Don't bother freeing duplicates. + It's dangerous and little benefit accrues. */ + *depp = dep->next; + } + } + + hash_free (&deps, 0); +} + +/* Record target-specific variable values for files FILENAMES. + TWO_COLON is nonzero if a double colon was used. + + The links of FILENAMES are freed, and so are any names in it + that are not incorporated into other data structures. + + If the target is a pattern, add the variable to the pattern-specific + variable value list. */ + +static void +record_target_var (filenames, defn, two_colon, origin, flocp) + struct nameseq *filenames; + char *defn; + int two_colon; + enum variable_origin origin; + const struct floc *flocp; +{ + struct nameseq *nextf; + struct variable_set_list *global; + + global = current_variable_set_list; + + /* If the variable is an append version, store that but treat it as a + normal recursive variable. */ + + for (; filenames != 0; filenames = nextf) + { + struct variable *v; + register char *name = filenames->name; + struct variable_set_list *vlist; + char *fname; + char *percent; + + nextf = filenames->next; + free ((char *) filenames); + + /* If it's a pattern target, then add it to the pattern-specific + variable list. */ + percent = find_percent (name); + if (percent) + { + struct pattern_var *p; + + /* Get a reference for this pattern-specific variable struct. */ + p = create_pattern_var(name, percent); + vlist = p->vars; + fname = p->target; + } + else + { + struct file *f; + + /* Get a file reference for this file, and initialize it. + We don't want to just call enter_file() because that allocates a + new entry if the file is a double-colon, which we don't want in + this situation. */ + f = lookup_file (name); + if (!f) + f = enter_file (name); + else if (f->double_colon) + f = f->double_colon; + + initialize_file_variables (f, 1); + vlist = f->variables; + fname = f->name; + } + + /* Make the new variable context current and define the variable. */ + current_variable_set_list = vlist; + v = try_variable_definition (flocp, defn, origin, 1); + if (!v) + error (flocp, _("Malformed per-target variable definition")); + v->per_target = 1; + + /* If it's not an override, check to see if there was a command-line + setting. If so, reset the value. */ + if (origin != o_override) + { + struct variable *gv; + int len = strlen(v->name); + + current_variable_set_list = global; + gv = lookup_variable (v->name, len); + if (gv && (gv->origin == o_env_override || gv->origin == o_command)) + { + v = define_variable_in_set (v->name, len, gv->value, gv->origin, + gv->recursive, vlist->set, flocp); + v->append = 0; + } + } + + /* Free name if not needed further. */ + if (name != fname && (name < fname || name > fname + strlen (fname))) + free (name); + } + + current_variable_set_list = global; +} + +/* Record a description line for files FILENAMES, + with dependencies DEPS, commands to execute described + by COMMANDS and COMMANDS_IDX, coming from FILENAME:COMMANDS_STARTED. + TWO_COLON is nonzero if a double colon was used. + If not nil, PATTERN is the `%' pattern to make this + a static pattern rule, and PATTERN_PERCENT is a pointer + to the `%' within it. + + The links of FILENAMES are freed, and so are any names in it + that are not incorporated into other data structures. */ + +static void +record_files (filenames, pattern, pattern_percent, deps, cmds_started, + commands, commands_idx, two_colon, have_sysv_atvar, + flocp, set_default) + struct nameseq *filenames; + char *pattern, *pattern_percent; + struct dep *deps; + unsigned int cmds_started; + char *commands; + unsigned int commands_idx; + int two_colon; + int have_sysv_atvar; + const struct floc *flocp; + int set_default; +{ + struct nameseq *nextf; + int implicit = 0; + unsigned int max_targets = 0, target_idx = 0; + char **targets = 0, **target_percents = 0; + struct commands *cmds; + + if (commands_idx > 0) + { + cmds = (struct commands *) xmalloc (sizeof (struct commands)); + cmds->fileinfo.filenm = flocp->filenm; + cmds->fileinfo.lineno = cmds_started; + cmds->commands = savestring (commands, commands_idx); + cmds->command_lines = 0; + } + else + cmds = 0; + + for (; filenames != 0; filenames = nextf) + { + char *name = filenames->name; + struct file *f; + struct dep *d; + struct dep *this; + char *implicit_percent; + + nextf = filenames->next; + free (filenames); + + /* Check for .POSIX. We used to do this in snap_deps() but that's not + good enough: it doesn't happen until after the makefile is read, + which means we cannot use its value during parsing. */ + + if (streq (name, ".POSIX")) + posix_pedantic = 1; + + implicit_percent = find_percent (name); + implicit |= implicit_percent != 0; + + if (implicit && pattern != 0) + fatal (flocp, _("mixed implicit and static pattern rules")); + + if (implicit && implicit_percent == 0) + fatal (flocp, _("mixed implicit and normal rules")); + + if (implicit) + { + if (targets == 0) + { + max_targets = 5; + targets = (char **) xmalloc (5 * sizeof (char *)); + target_percents = (char **) xmalloc (5 * sizeof (char *)); + target_idx = 0; + } + else if (target_idx == max_targets - 1) + { + max_targets += 5; + targets = (char **) xrealloc ((char *) targets, + max_targets * sizeof (char *)); + target_percents + = (char **) xrealloc ((char *) target_percents, + max_targets * sizeof (char *)); + } + targets[target_idx] = name; + target_percents[target_idx] = implicit_percent; + ++target_idx; + continue; + } + + /* If there are multiple filenames, copy the chain DEPS + for all but the last one. It is not safe for the same deps + to go in more than one place in the data base. */ + this = nextf != 0 ? copy_dep_chain (deps) : deps; + + if (pattern != 0) + { + /* If this is an extended static rule: + `targets: target%pattern: dep%pattern; cmds', + translate each dependency pattern into a plain filename + using the target pattern and this target's name. */ + if (!pattern_matches (pattern, pattern_percent, name)) + { + /* Give a warning if the rule is meaningless. */ + error (flocp, + _("target `%s' doesn't match the target pattern"), name); + this = 0; + } + else + { + /* We use patsubst_expand to do the work of translating + the target pattern, the target's name and the dependencies' + patterns into plain dependency names. */ + char *buffer = variable_expand (""); + + for (d = this; d != 0; d = d->next) + { + char *o; + char *percent = find_percent (d->name); + if (percent == 0) + continue; + o = patsubst_expand (buffer, name, pattern, d->name, + pattern_percent, percent); + /* If the name expanded to the empty string, that's + illegal. */ + if (o == buffer) + fatal (flocp, + _("target `%s' leaves prerequisite pattern empty"), + name); + free (d->name); + d->name = savestring (buffer, o - buffer); + } + } + } + + /* If at least one of the dependencies uses $$@ etc. deal with that. + It would be very nice and very simple to just expand everything, but + it would break a lot of backward compatibility. Maybe that's OK + since we're just emulating a SysV function, and if we do that then + why not emulate it completely (that's what SysV make does: it + re-expands the entire prerequisite list, all the time, with $@ + etc. in scope. But, it would be a pain indeed to document this + ("iff you use $$@, your prerequisite lists is expanded twice...") + Ouch. Maybe better to make the code more complex. */ + + if (have_sysv_atvar) + { + char *p; + int tlen = strlen (name); + char *fnp = strrchr (name, '/'); + int dlen; + int flen; + + if (fnp) + { + dlen = fnp - name; + ++fnp; + flen = strlen (fnp); + } + else + { + dlen = 0; + fnp = name; + flen = tlen; + } + + + for (d = this; d != 0; d = d->next) + for (p = strchr (d->name, '$'); p != 0; p = strchr (p+1, '$')) + { + char *s = p; + char *at; + int atlen; + + /* If it's a '$@' or '$(@', it's escaped */ + if ((++p)[0] == '$' + && (p[1] == '@' || (p[1] == '(' && p[2] == '@'))) + { + bcopy (p, s, strlen (p)+1); + continue; + } + + /* Maybe found one. Check. p will point to '@' [for $@] or + ')' [for $(@)] or 'D' [for $(@D)] or 'F' [for $(@F)]. */ + if (p[0] != '@' + && (p[0] != '(' || (++p)[0] != '@' + || ((++p)[0] != ')' + && (p[1] != ')' || (p[0] != 'D' && p[0] != 'F'))))) + continue; + + /* Found one. Compute the length and string ptr. Move p + past the variable reference. */ + switch (p[0]) + { + case 'D': + atlen = dlen; + at = name; + p += 2; + break; + + case 'F': + atlen = flen; + at = fnp; + p += 2; + break; + + default: + atlen = tlen; + at = name; + ++p; + break; + } + + /* Get more space. */ + { + int soff = s - d->name; + int poff = p - d->name; + d->name = (char *) xrealloc (d->name, + strlen (d->name) + atlen + 1); + s = d->name + soff; + p = d->name + poff; + } + + /* Copy the string over. */ + bcopy(p, s+atlen, strlen (p)+1); + bcopy(at, s, atlen); + p = s + atlen - 1; + } + } + + if (!two_colon) + { + /* Single-colon. Combine these dependencies + with others in file's existing record, if any. */ + f = enter_file (name); + + if (f->double_colon) + fatal (flocp, + _("target file `%s' has both : and :: entries"), f->name); + + /* If CMDS == F->CMDS, this target was listed in this rule + more than once. Just give a warning since this is harmless. */ + if (cmds != 0 && cmds == f->cmds) + error (flocp, + _("target `%s' given more than once in the same rule."), + f->name); + + /* Check for two single-colon entries both with commands. + Check is_target so that we don't lose on files such as .c.o + whose commands were preinitialized. */ + else if (cmds != 0 && f->cmds != 0 && f->is_target) + { + error (&cmds->fileinfo, + _("warning: overriding commands for target `%s'"), + f->name); + error (&f->cmds->fileinfo, + _("warning: ignoring old commands for target `%s'"), + f->name); + } + + f->is_target = 1; + + /* Defining .DEFAULT with no deps or cmds clears it. */ + if (f == default_file && this == 0 && cmds == 0) + f->cmds = 0; + if (cmds != 0) + f->cmds = cmds; + /* Defining .SUFFIXES with no dependencies + clears out the list of suffixes. */ + if (f == suffix_file && this == 0) + { + d = f->deps; + while (d != 0) + { + struct dep *nextd = d->next; + free (d->name); + free ((char *)d); + d = nextd; + } + f->deps = 0; + } + else if (f->deps != 0) + { + /* Add the file's old deps and the new ones in THIS together. */ + + struct dep *firstdeps, *moredeps; + if (cmds != 0) + { + /* This is the rule with commands, so put its deps first. + The rationale behind this is that $< expands to the + first dep in the chain, and commands use $< expecting + to get the dep that rule specifies. */ + firstdeps = this; + moredeps = f->deps; + } + else + { + /* Append the new deps to the old ones. */ + firstdeps = f->deps; + moredeps = this; + } + + if (firstdeps == 0) + firstdeps = moredeps; + else + { + d = firstdeps; + while (d->next != 0) + d = d->next; + d->next = moredeps; + } + + f->deps = firstdeps; + } + else + f->deps = this; + + /* If this is a static pattern rule, set the file's stem to + the part of its name that matched the `%' in the pattern, + so you can use $* in the commands. */ + if (pattern != 0) + { + static char *percent = "%"; + char *buffer = variable_expand (""); + char *o = patsubst_expand (buffer, name, pattern, percent, + pattern_percent, percent); + f->stem = savestring (buffer, o - buffer); + } + } + else + { + /* Double-colon. Make a new record + even if the file already has one. */ + f = lookup_file (name); + /* Check for both : and :: rules. Check is_target so + we don't lose on default suffix rules or makefiles. */ + if (f != 0 && f->is_target && !f->double_colon) + fatal (flocp, + _("target file `%s' has both : and :: entries"), f->name); + f = enter_file (name); + /* If there was an existing entry and it was a double-colon + entry, enter_file will have returned a new one, making it the + prev pointer of the old one, and setting its double_colon + pointer to the first one. */ + if (f->double_colon == 0) + /* This is the first entry for this name, so we must + set its double_colon pointer to itself. */ + f->double_colon = f; + f->is_target = 1; + f->deps = this; + f->cmds = cmds; + } + + /* Free name if not needed further. */ + if (f != 0 && name != f->name + && (name < f->name || name > f->name + strlen (f->name))) + { + free (name); + name = f->name; + } + + /* See if this is first target seen whose name does + not start with a `.', unless it contains a slash. */ + if (default_goal_file == 0 && set_default + && (*name != '.' || strchr (name, '/') != 0 +#ifdef HAVE_DOS_PATHS + || strchr (name, '\\') != 0 +#endif + )) + { + int reject = 0; + + /* If this file is a suffix, don't + let it be the default goal file. */ + + for (d = suffix_file->deps; d != 0; d = d->next) + { + register struct dep *d2; + if (*dep_name (d) != '.' && streq (name, dep_name (d))) + { + reject = 1; + break; + } + for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next) + { + register unsigned int len = strlen (dep_name (d2)); + if (!strneq (name, dep_name (d2), len)) + continue; + if (streq (name + len, dep_name (d))) + { + reject = 1; + break; + } + } + if (reject) + break; + } + + if (!reject) + default_goal_file = f; + } + } + + if (implicit) + { + targets[target_idx] = 0; + target_percents[target_idx] = 0; + create_pattern_rule (targets, target_percents, two_colon, deps, cmds, 1); + free ((char *) target_percents); + } +} + +/* Search STRING for an unquoted STOPCHAR or blank (if BLANK is nonzero). + Backslashes quote STOPCHAR, blanks if BLANK is nonzero, and backslash. + Quoting backslashes are removed from STRING by compacting it into + itself. Returns a pointer to the first unquoted STOPCHAR if there is + one, or nil if there are none. */ + +char * +find_char_unquote (string, stop1, stop2, blank) + char *string; + int stop1; + int stop2; + int blank; +{ + unsigned int string_len = 0; + register char *p = string; + + while (1) + { + if (stop2 && blank) + while (*p != '\0' && *p != stop1 && *p != stop2 + && ! isblank ((unsigned char) *p)) + ++p; + else if (stop2) + while (*p != '\0' && *p != stop1 && *p != stop2) + ++p; + else if (blank) + while (*p != '\0' && *p != stop1 + && ! isblank ((unsigned char) *p)) + ++p; + else + while (*p != '\0' && *p != stop1) + ++p; + + if (*p == '\0') + break; + + if (p > string && p[-1] == '\\') + { + /* Search for more backslashes. */ + register int i = -2; + while (&p[i] >= string && p[i] == '\\') + --i; + ++i; + /* Only compute the length if really needed. */ + if (string_len == 0) + string_len = strlen (string); + /* The number of backslashes is now -I. + Copy P over itself to swallow half of them. */ + bcopy (&p[i / 2], &p[i], (string_len - (p - string)) - (i / 2) + 1); + p += i / 2; + if (i % 2 == 0) + /* All the backslashes quoted each other; the STOPCHAR was + unquoted. */ + return p; + + /* The STOPCHAR was quoted by a backslash. Look for another. */ + } + else + /* No backslash in sight. */ + return p; + } + + /* Never hit a STOPCHAR or blank (with BLANK nonzero). */ + return 0; +} + +/* Search PATTERN for an unquoted %. */ + +char * +find_percent (pattern) + char *pattern; +{ + return find_char_unquote (pattern, '%', 0, 0); +} + +/* Parse a string into a sequence of filenames represented as a + chain of struct nameseq's in reverse order and return that chain. + + The string is passed as STRINGP, the address of a string pointer. + The string pointer is updated to point at the first character + not parsed, which either is a null char or equals STOPCHAR. + + SIZE is how big to construct chain elements. + This is useful if we want them actually to be other structures + that have room for additional info. + + If STRIP is nonzero, strip `./'s off the beginning. */ + +struct nameseq * +parse_file_seq (stringp, stopchar, size, strip) + char **stringp; + int stopchar; + unsigned int size; + int strip; +{ + register struct nameseq *new = 0; + register struct nameseq *new1, *lastnew1; + register char *p = *stringp; + char *q; + char *name; + +#ifdef VMS +# define VMS_COMMA ',' +#else +# define VMS_COMMA 0 +#endif + + while (1) + { + /* Skip whitespace; see if any more names are left. */ + p = next_token (p); + if (*p == '\0') + break; + if (*p == stopchar) + break; + + /* Yes, find end of next name. */ + q = p; + p = find_char_unquote (q, stopchar, VMS_COMMA, 1); +#ifdef VMS + /* convert comma separated list to space separated */ + if (p && *p == ',') + *p =' '; +#endif +#ifdef _AMIGA + if (stopchar == ':' && p && *p == ':' + && !(isspace ((unsigned char)p[1]) || !p[1] + || isspace ((unsigned char)p[-1]))) + { + p = find_char_unquote (p+1, stopchar, VMS_COMMA, 1); + } +#endif +#ifdef HAVE_DOS_PATHS + /* For DOS paths, skip a "C:\..." or a "C:/..." until we find the + first colon which isn't followed by a slash or a backslash. + Note that tokens separated by spaces should be treated as separate + tokens since make doesn't allow path names with spaces */ + if (stopchar == ':') + while (p != 0 && !isspace ((unsigned char)*p) && + (p[1] == '\\' || p[1] == '/') && isalpha ((unsigned char)p[-1])) + p = find_char_unquote (p + 1, stopchar, VMS_COMMA, 1); +#endif + if (p == 0) + p = q + strlen (q); + + if (strip) +#ifdef VMS + /* Skip leading `[]'s. */ + while (p - q > 2 && q[0] == '[' && q[1] == ']') +#else + /* Skip leading `./'s. */ + while (p - q > 2 && q[0] == '.' && q[1] == '/') +#endif + { + q += 2; /* Skip "./". */ + while (q < p && *q == '/') + /* Skip following slashes: ".//foo" is "foo", not "/foo". */ + ++q; + } + + /* Extract the filename just found, and skip it. */ + + if (q == p) + /* ".///" was stripped to "". */ +#ifdef VMS + continue; +#else +#ifdef _AMIGA + name = savestring ("", 0); +#else + name = savestring ("./", 2); +#endif +#endif + else +#ifdef VMS +/* VMS filenames can have a ':' in them but they have to be '\'ed but we need + * to remove this '\' before we can use the filename. + * Savestring called because q may be read-only string constant. + */ + { + char *qbase = xstrdup (q); + char *pbase = qbase + (p-q); + char *q1 = qbase; + char *q2 = q1; + char *p1 = pbase; + + while (q1 != pbase) + { + if (*q1 == '\\' && *(q1+1) == ':') + { + q1++; + p1--; + } + *q2++ = *q1++; + } + name = savestring (qbase, p1 - qbase); + free (qbase); + } +#else + name = savestring (q, p - q); +#endif + + /* Add it to the front of the chain. */ + new1 = (struct nameseq *) xmalloc (size); + new1->name = name; + new1->next = new; + new = new1; + } + +#ifndef NO_ARCHIVES + + /* Look for multi-word archive references. + They are indicated by a elt ending with an unmatched `)' and + an elt further down the chain (i.e., previous in the file list) + with an unmatched `(' (e.g., "lib(mem"). */ + + new1 = new; + lastnew1 = 0; + while (new1 != 0) + if (new1->name[0] != '(' /* Don't catch "(%)" and suchlike. */ + && new1->name[strlen (new1->name) - 1] == ')' + && strchr (new1->name, '(') == 0) + { + /* NEW1 ends with a `)' but does not contain a `('. + Look back for an elt with an opening `(' but no closing `)'. */ + + struct nameseq *n = new1->next, *lastn = new1; + char *paren = 0; + while (n != 0 && (paren = strchr (n->name, '(')) == 0) + { + lastn = n; + n = n->next; + } + if (n != 0 + /* Ignore something starting with `(', as that cannot actually + be an archive-member reference (and treating it as such + results in an empty file name, which causes much lossage). */ + && n->name[0] != '(') + { + /* N is the first element in the archive group. + Its name looks like "lib(mem" (with no closing `)'). */ + + char *libname; + + /* Copy "lib(" into LIBNAME. */ + ++paren; + libname = (char *) alloca (paren - n->name + 1); + bcopy (n->name, libname, paren - n->name); + libname[paren - n->name] = '\0'; + + if (*paren == '\0') + { + /* N was just "lib(", part of something like "lib( a b)". + Edit it out of the chain and free its storage. */ + lastn->next = n->next; + free (n->name); + free ((char *) n); + /* LASTN->next is the new stopping elt for the loop below. */ + n = lastn->next; + } + else + { + /* Replace N's name with the full archive reference. */ + name = concat (libname, paren, ")"); + free (n->name); + n->name = name; + } + + if (new1->name[1] == '\0') + { + /* NEW1 is just ")", part of something like "lib(a b )". + Omit it from the chain and free its storage. */ + if (lastnew1 == 0) + new = new1->next; + else + lastnew1->next = new1->next; + lastn = new1; + new1 = new1->next; + free (lastn->name); + free ((char *) lastn); + } + else + { + /* Replace also NEW1->name, which already has closing `)'. */ + name = concat (libname, new1->name, ""); + free (new1->name); + new1->name = name; + new1 = new1->next; + } + + /* Trace back from NEW1 (the end of the list) until N + (the beginning of the list), rewriting each name + with the full archive reference. */ + + while (new1 != n) + { + name = concat (libname, new1->name, ")"); + free (new1->name); + new1->name = name; + lastnew1 = new1; + new1 = new1->next; + } + } + else + { + /* No frobnication happening. Just step down the list. */ + lastnew1 = new1; + new1 = new1->next; + } + } + else + { + lastnew1 = new1; + new1 = new1->next; + } + +#endif + + *stringp = p; + return new; +} + +/* Find the next line of text in an eval buffer, combining continuation lines + into one line. + Return the number of actual lines read (> 1 if continuation lines). + Returns -1 if there's nothing left in the buffer. + + After this function, ebuf->buffer points to the first character of the + line we just found. + */ + +/* Read a line of text from a STRING. + Since we aren't really reading from a file, don't bother with linenumbers. + */ + +static unsigned long +readstring (ebuf) + struct ebuffer *ebuf; +{ + char *p; + + /* If there is nothing left in this buffer, return 0. */ + if (ebuf->bufnext > ebuf->bufstart + ebuf->size) + return -1; + + /* Set up a new starting point for the buffer, and find the end of the + next logical line (taking into account backslash/newline pairs). */ + + p = ebuf->buffer = ebuf->bufnext; + + while (1) + { + int backslash = 0; + + /* Find the next newline. Keep track of backslashes as we look. */ + for (; *p != '\n' && *p != '\0'; ++p) + if (*p == '\\') + backslash = !backslash; + + /* If we got to the end of the string or a newline with no backslash, + we're done. */ + if (*p == '\0' || !backslash) + break; + } + + /* Overwrite the newline char. */ + *p = '\0'; + ebuf->bufnext = p+1; + + return 0; +} + +static long +readline (ebuf) + struct ebuffer *ebuf; +{ + char *p; + char *end; + char *start; + long nlines = 0; + + /* The behaviors between string and stream buffers are different enough to + warrant different functions. Do the Right Thing. */ + + if (!ebuf->fp) + return readstring (ebuf); + + /* When reading from a file, we always start over at the beginning of the + buffer for each new line. */ + + p = start = ebuf->bufstart; + end = p + ebuf->size; + *p = '\0'; + + while (fgets (p, end - p, ebuf->fp) != 0) + { + char *p2; + unsigned long len; + int backslash; + + len = strlen (p); + if (len == 0) + { + /* This only happens when the first thing on the line is a '\0'. + It is a pretty hopeless case, but (wonder of wonders) Athena + lossage strikes again! (xmkmf puts NULs in its makefiles.) + There is nothing really to be done; we synthesize a newline so + the following line doesn't appear to be part of this line. */ + error (&ebuf->floc, + _("warning: NUL character seen; rest of line ignored")); + p[0] = '\n'; + len = 1; + } + + /* Jump past the text we just read. */ + p += len; + + /* If the last char isn't a newline, the whole line didn't fit into the + buffer. Get some more buffer and try again. */ + if (p[-1] != '\n') + goto more_buffer; + + /* We got a newline, so add one to the count of lines. */ + ++nlines; + +#if !defined(WINDOWS32) && !defined(__MSDOS__) + /* Check to see if the line was really ended with CRLF; if so ignore + the CR. */ + if ((p - start) > 1 && p[-2] == '\r') + { + --p; + p[-1] = '\n'; + } +#endif + + backslash = 0; + for (p2 = p - 2; p2 >= start; --p2) + { + if (*p2 != '\\') + break; + backslash = !backslash; + } + + if (!backslash) + { + p[-1] = '\0'; + break; + } + + /* It was a backslash/newline combo. If we have more space, read + another line. */ + if (end - p >= 80) + continue; + + /* We need more space at the end of our buffer, so realloc it. + Make sure to preserve the current offset of p. */ + more_buffer: + { + unsigned long off = p - start; + ebuf->size *= 2; + start = ebuf->buffer = ebuf->bufstart = (char *) xrealloc (start, + ebuf->size); + p = start + off; + end = start + ebuf->size; + *p = '\0'; + } + } + + if (ferror (ebuf->fp)) + pfatal_with_name (ebuf->floc.filenm); + + /* If we found some lines, return how many. + If we didn't, but we did find _something_, that indicates we read the last + line of a file with no final newline; return 1. + If we read nothing, we're at EOF; return -1. */ + + return nlines ? nlines : p == ebuf->bufstart ? -1 : 1; +} + +/* Parse the next "makefile word" from the input buffer, and return info + about it. + + A "makefile word" is one of: + + w_bogus Should never happen + w_eol End of input + w_static A static word; cannot be expanded + w_variable A word containing one or more variables/functions + w_colon A colon + w_dcolon A double-colon + w_semicolon A semicolon + w_varassign A variable assignment operator (=, :=, +=, or ?=) + + Note that this function is only used when reading certain parts of the + makefile. Don't use it where special rules hold sway (RHS of a variable, + in a command list, etc.) */ + +static enum make_word_type +get_next_mword (buffer, delim, startp, length) + char *buffer; + char *delim; + char **startp; + unsigned int *length; +{ + enum make_word_type wtype = w_bogus; + char *p = buffer, *beg; + char c; + + /* Skip any leading whitespace. */ + while (isblank ((unsigned char)*p)) + ++p; + + beg = p; + c = *(p++); + switch (c) + { + case '\0': + wtype = w_eol; + break; + + case ';': + wtype = w_semicolon; + break; + + case '=': + wtype = w_varassign; + break; + + case ':': + wtype = w_colon; + switch (*p) + { + case ':': + ++p; + wtype = w_dcolon; + break; + + case '=': + ++p; + wtype = w_varassign; + break; + } + break; + + case '+': + case '?': + if (*p == '=') + { + ++p; + wtype = w_varassign; + break; + } + + default: + if (delim && strchr (delim, c)) + wtype = w_static; + break; + } + + /* Did we find something? If so, return now. */ + if (wtype != w_bogus) + goto done; + + /* This is some non-operator word. A word consists of the longest + string of characters that doesn't contain whitespace, one of [:=#], + or [?+]=, or one of the chars in the DELIM string. */ + + /* We start out assuming a static word; if we see a variable we'll + adjust our assumptions then. */ + wtype = w_static; + + /* We already found the first value of "c", above. */ + while (1) + { + char closeparen; + int count; + + switch (c) + { + case '\0': + case ' ': + case '\t': + case '=': + goto done_word; + + case ':': +#ifdef HAVE_DOS_PATHS + /* A word CAN include a colon in its drive spec. The drive + spec is allowed either at the beginning of a word, or as part + of the archive member name, like in "libfoo.a(d:/foo/bar.o)". */ + if (!(p - beg >= 2 + && (*p == '/' || *p == '\\') && isalpha ((unsigned char)p[-2]) + && (p - beg == 2 || p[-3] == '('))) +#endif + goto done_word; + + case '$': + c = *(p++); + if (c == '$') + break; + + /* This is a variable reference, so note that it's expandable. + Then read it to the matching close paren. */ + wtype = w_variable; + + if (c == '(') + closeparen = ')'; + else if (c == '{') + closeparen = '}'; + else + /* This is a single-letter variable reference. */ + break; + + for (count=0; *p != '\0'; ++p) + { + if (*p == c) + ++count; + else if (*p == closeparen && --count < 0) + { + ++p; + break; + } + } + break; + + case '?': + case '+': + if (*p == '=') + goto done_word; + break; + + case '\\': + switch (*p) + { + case ':': + case ';': + case '=': + case '\\': + ++p; + break; + } + break; + + default: + if (delim && strchr (delim, c)) + goto done_word; + break; + } + + c = *(p++); + } + done_word: + --p; + + done: + if (startp) + *startp = beg; + if (length) + *length = p - beg; + return wtype; +} + +/* Construct the list of include directories + from the arguments and the default list. */ + +void +construct_include_path (arg_dirs) + char **arg_dirs; +{ + register unsigned int i; +#ifdef VAXC /* just don't ask ... */ + stat_t stbuf; +#else + struct stat stbuf; +#endif + /* Table to hold the dirs. */ + + register unsigned int defsize = (sizeof (default_include_directories) + / sizeof (default_include_directories[0])); + register unsigned int max = 5; + register char **dirs = (char **) xmalloc ((5 + defsize) * sizeof (char *)); + register unsigned int idx = 0; + +#ifdef __MSDOS__ + defsize++; +#endif + + /* First consider any dirs specified with -I switches. + Ignore dirs that don't exist. */ + + if (arg_dirs != 0) + while (*arg_dirs != 0) + { + char *dir = *arg_dirs++; + + if (dir[0] == '~') + { + char *expanded = tilde_expand (dir); + if (expanded != 0) + dir = expanded; + } + + if (stat (dir, &stbuf) == 0 && S_ISDIR (stbuf.st_mode)) + { + if (idx == max - 1) + { + max += 5; + dirs = (char **) + xrealloc ((char *) dirs, (max + defsize) * sizeof (char *)); + } + dirs[idx++] = dir; + } + else if (dir != arg_dirs[-1]) + free (dir); + } + + /* Now add at the end the standard default dirs. */ + +#ifdef __MSDOS__ + { + /* The environment variable $DJDIR holds the root of the + DJGPP directory tree; add ${DJDIR}/include. */ + struct variable *djdir = lookup_variable ("DJDIR", 5); + + if (djdir) + { + char *defdir = (char *) xmalloc (strlen (djdir->value) + 8 + 1); + + strcat (strcpy (defdir, djdir->value), "/include"); + dirs[idx++] = defdir; + } + } +#endif + + for (i = 0; default_include_directories[i] != 0; ++i) + if (stat (default_include_directories[i], &stbuf) == 0 + && S_ISDIR (stbuf.st_mode)) + dirs[idx++] = default_include_directories[i]; + + dirs[idx] = 0; + + /* Now compute the maximum length of any name in it. */ + + max_incl_len = 0; + for (i = 0; i < idx; ++i) + { + unsigned int len = strlen (dirs[i]); + /* If dir name is written with a trailing slash, discard it. */ + if (dirs[i][len - 1] == '/') + /* We can't just clobber a null in because it may have come from + a literal string and literal strings may not be writable. */ + dirs[i] = savestring (dirs[i], len - 1); + if (len > max_incl_len) + max_incl_len = len; + } + + include_directories = dirs; +} + +/* Expand ~ or ~USER at the beginning of NAME. + Return a newly malloc'd string or 0. */ + +char * +tilde_expand (name) + char *name; +{ +#ifndef VMS + if (name[1] == '/' || name[1] == '\0') + { + extern char *getenv (); + char *home_dir; + int is_variable; + + { + /* Turn off --warn-undefined-variables while we expand HOME. */ + int save = warn_undefined_variables_flag; + warn_undefined_variables_flag = 0; + + home_dir = allocated_variable_expand ("$(HOME)"); + + warn_undefined_variables_flag = save; + } + + is_variable = home_dir[0] != '\0'; + if (!is_variable) + { + free (home_dir); + home_dir = getenv ("HOME"); + } +#if !defined(_AMIGA) && !defined(WINDOWS32) + if (home_dir == 0 || home_dir[0] == '\0') + { + extern char *getlogin (); + char *logname = getlogin (); + home_dir = 0; + if (logname != 0) + { + struct passwd *p = getpwnam (logname); + if (p != 0) + home_dir = p->pw_dir; + } + } +#endif /* !AMIGA && !WINDOWS32 */ + if (home_dir != 0) + { + char *new = concat (home_dir, "", name + 1); + if (is_variable) + free (home_dir); + return new; + } + } +#if !defined(_AMIGA) && !defined(WINDOWS32) + else + { + struct passwd *pwent; + char *userend = strchr (name + 1, '/'); + if (userend != 0) + *userend = '\0'; + pwent = getpwnam (name + 1); + if (pwent != 0) + { + if (userend == 0) + return xstrdup (pwent->pw_dir); + else + return concat (pwent->pw_dir, "/", userend + 1); + } + else if (userend != 0) + *userend = '/'; + } +#endif /* !AMIGA && !WINDOWS32 */ +#endif /* !VMS */ + return 0; +} + +/* Given a chain of struct nameseq's describing a sequence of filenames, + in reverse of the intended order, return a new chain describing the + result of globbing the filenames. The new chain is in forward order. + The links of the old chain are freed or used in the new chain. + Likewise for the names in the old chain. + + SIZE is how big to construct chain elements. + This is useful if we want them actually to be other structures + that have room for additional info. */ + +struct nameseq * +multi_glob (chain, size) + struct nameseq *chain; + unsigned int size; +{ + extern void dir_setup_glob (); + register struct nameseq *new = 0; + register struct nameseq *old; + struct nameseq *nexto; + glob_t gl; + + dir_setup_glob (&gl); + + for (old = chain; old != 0; old = nexto) + { +#ifndef NO_ARCHIVES + char *memname; +#endif + + nexto = old->next; + + if (old->name[0] == '~') + { + char *newname = tilde_expand (old->name); + if (newname != 0) + { + free (old->name); + old->name = newname; + } + } + +#ifndef NO_ARCHIVES + if (ar_name (old->name)) + { + /* OLD->name is an archive member reference. + Replace it with the archive file name, + and save the member name in MEMNAME. + We will glob on the archive name and then + reattach MEMNAME later. */ + char *arname; + ar_parse_name (old->name, &arname, &memname); + free (old->name); + old->name = arname; + } + else + memname = 0; +#endif /* !NO_ARCHIVES */ + + switch (glob (old->name, GLOB_NOCHECK|GLOB_ALTDIRFUNC, NULL, &gl)) + { + case 0: /* Success. */ + { + register int i = gl.gl_pathc; + while (i-- > 0) + { +#ifndef NO_ARCHIVES + if (memname != 0) + { + /* Try to glob on MEMNAME within the archive. */ + struct nameseq *found + = ar_glob (gl.gl_pathv[i], memname, size); + if (found == 0) + { + /* No matches. Use MEMNAME as-is. */ + unsigned int alen = strlen (gl.gl_pathv[i]); + unsigned int mlen = strlen (memname); + struct nameseq *elt + = (struct nameseq *) xmalloc (size); + if (size > sizeof (struct nameseq)) + bzero (((char *) elt) + sizeof (struct nameseq), + size - sizeof (struct nameseq)); + elt->name = (char *) xmalloc (alen + 1 + mlen + 2); + bcopy (gl.gl_pathv[i], elt->name, alen); + elt->name[alen] = '('; + bcopy (memname, &elt->name[alen + 1], mlen); + elt->name[alen + 1 + mlen] = ')'; + elt->name[alen + 1 + mlen + 1] = '\0'; + elt->next = new; + new = elt; + } + else + { + /* Find the end of the FOUND chain. */ + struct nameseq *f = found; + while (f->next != 0) + f = f->next; + + /* Attach the chain being built to the end of the FOUND + chain, and make FOUND the new NEW chain. */ + f->next = new; + new = found; + } + + free (memname); + } + else +#endif /* !NO_ARCHIVES */ + { + struct nameseq *elt = (struct nameseq *) xmalloc (size); + if (size > sizeof (struct nameseq)) + bzero (((char *) elt) + sizeof (struct nameseq), + size - sizeof (struct nameseq)); + elt->name = xstrdup (gl.gl_pathv[i]); + elt->next = new; + new = elt; + } + } + globfree (&gl); + free (old->name); + free ((char *)old); + break; + } + + case GLOB_NOSPACE: + fatal (NILF, _("virtual memory exhausted")); + break; + + default: + old->next = new; + new = old; + break; + } + } + + return new; +} diff --git a/src/make-3.80/readme.vms b/src/make-3.80/readme.vms new file mode 100755 index 00000000..d4a9667c --- /dev/null +++ b/src/make-3.80/readme.vms @@ -0,0 +1,183 @@ +This is the VMS port of GNU Make done by Hartmut.Becker@compaq.com. + +It is based on the specific version 3.77k and on 3.78.1. 3.77k was done +by Klaus Kämpf , the code was based on the VMS port of +GNU Make 3.60 by Mike Moretti. + +It was ported on OpenVMS/Alpha V7.1, DECC V5.7-006. It was re-build and +tested on OpenVMS/Alpha V7.2, OpenVMS/VAX 7.1 and 5.5-2. Different +versions of DECC were used. VAXC was tried: it fails; but it doesn't +seem worth to get it working. There are still some PTRMISMATCH warnings +during the compile. Although perl is working on VMS the test scripts +don't work. The function $shell is still missing. + +There is a known bug in some of the VMS CRTLs. It is in the shipped +versions of VMS V7.2 and V7.2-1 and in the currently (October 1999) +available ECOs for VMS V7.1 and newer versions. It is fixed in versions +shipped with newer VMS versions and all ECO kits after October 1999. It +only shows up during the daylight saving time period (DST): stat() +returns a modification time 1 hour ahead. This results in GNU make +warning messages. For a just created source you will see: + + $ gmake x.exe + gmake.exe;1: *** Warning: File `x.c' has modification time in the future (940582863 > 940579269) + cc /obj=x.obj x.c + link x.obj /exe=x.exe + gmake.exe;1: *** Warning: Clock skew detected. Your build may be incomplete. + + +New in 3.78.1: + +Fix a problem with automatically remaking makefiles. GNU make uses an +execve to restart itself after a successful remake of the makefile. On +UNIX systems execve replaces the running program with a new one and +resets all signal handling to the default. On VMS execve creates a child +process, signal and exit handlers of the parent are still active, and, +unfortunately, corrupt the exit code from the child. Fix in job.c: +ignore SIGCHLD. + +Added some switches to reflect latest features of DECC. Modifications in +makefile.vms. + +Set some definitions to reflect latest features of DECC. Modifications in +config.h-vms (which is copied to config.h). + +Added extern strcmpi declaration to avoid 'implicitly declared' messages. +Modification in make.h. + +Default rule for C++, conditionals for gcc (GCC_IS_NATIVE) or DEC/Digital/ +Compaq c/c++ compilers. Modifications in default.c. + +Usage of opendir() and friends, suppress file version. Modifications in dir.c. + +Added VMS specific code to handle ctrl+c and ctrl+y to abort make. +Modifications in job.c. + +Added support to have case sensitive targets and dependencies but to +still use case blind file names. This is especially useful for Java +makefiles on VMS: + + .SUFFIXES : + .SUFFIXES : .class .java + .java.class : + javac "$< + HelloWorld.class : HelloWorld.java + +A new macro WANT_CASE_SENSITIVE_TARGETS in config.h-vms was introduced. +It needs to be enabled to get this feature; default is disabled. The +macro HAVE_CASE_INSENSITIVE_FS must not be touched: it is still enabled. +Modifications in file.c and config.h-vms. + +Bootstrap make to start building make is still makefile.com, but make +needs to be re-made with a make to make a correct version: ignore all +possible warnings, delete all objects, rename make.exe to a different +name and run it. + +Made some minor modifications to the bootstrap build makefile.com. + +This is the VMS port of GNU Make. + +It is based on the VMS port of GNU Make 3.60 by Mike Moretti. + +This port was done by Klaus Kämpf + +There is first-level support available from proGIS Software, Germany. +Visit their web-site at http://www.progis.de to get information +about other vms software and forthcoming updates to gnu make. + +New for 3.77: + +/bin/sh style I/O redirection is supported. You can now write lines like + mcr sys$disk:[]program.exe < input.txt > output.txt &> error.txt + +Makefile variables are looked up in the current environment. You can set +symbols or logicals in DCL and evaluate them in the Makefile via +$(). Variables defined in the Makefile +override VMS symbols/logicals ! + +Functions for file names are working now. See the GNU Make manual for +$(dir ...) and $(wildcard ...). Unix-style and VMS-style names are +supported as arguments. + +The default rules are set up for GNU C. Building an executable from a +single source file is as easy as 'make file.exe'. + +The variable $(ARCH) is predefined as ALPHA or VAX resp. Makefiles for +different VMS systems can now be written by checking $(ARCH) as in + ifeq ($(ARCH),ALPHA) + $(ECHO) "On the Alpha" + else + $(ECHO) "On the VAX" + endif + +Command lines of excessive length are correctly broken and written to a +batch file in sys$scratch for later execution. There's no limit to the +lengths of commands (and no need for .opt files :-) any more. + +Empty commands are handled correctly and don't end in a new DCL process. + + +New for 3.76: + +John W. Eaton has updated the VMS port to support libraries and VPATH. + + +To build Make, simply type @makefile. This should compile all the +necessary files and link Make. There is also a file called +makefile.vms. If you already have GNU Make built you can just use +Make with this makefile to rebuild. + +Here are some notes about GNU Make for VMS: + +The cd command is supported if it's called as $(CD). This invokes +the 'builtin_cd' command which changes the directory. +Calling 'set def' doesn't do the trick, since a sub-shell is +spawned for this command, the directory is changed *in this sub-shell* +and the sub-shell ends. + +Libraries are not supported. They were in GNU Make 3.60 but somehow I +didn't care porting the code. If there is enough interest, I'll do it at +some later time. + +The variable $^ separates files with commas instead of spaces (It's the +natural thing to do for VMS). + +See defaults.c for VMS default suffixes and my definitions for default +rules and variables. + +The shell function is not implemented yet. + +Load average routines haven't been implemented for VMS yet. + +The default include directory for including other makefiles is +SYS$SYSROOT:[SYSLIB] (I don't remember why I didn't just use +SYS$LIBRARY: instead; maybe it wouldn't work that way). + +The default makefiles make looks for are: makefile.vms, gnumakefile, +makefile., and gnumakefile. . + +The stat() function and handling of time stamps in VMS is broken, so I +replaced it with a hack in vmsfunctions.c. I will provide a full rewrite +somewhere in the future. Be warned, the time resolution inside make is +less than what vms provides. This might be a problem on the faster Alphas. + +You can use a : in a filename only if you preceed it with a backslash ('\'). +E.g.- hobbes\:[bogas.files] + +Make ignores success, informational, or warning errors (-S-, -I-, or +-W-). But it will stop on -E- and -F- errors. (unless you do something +to override this in your makefile, or whatever). + +Remote stuff isn't implemented yet. + +Multiple line DCL commands, such as "if" statements, must be put inside +command files. You can run a command file by using \@. + + +VMS changes made for 3.74.3 + +Lots of default settings are adapted for VMS. See default.c. + +Long command lines are now converted to command files. + +Comma (',') as a separator is now allowed. See makefile.vms for an example. diff --git a/src/make-3.80/remake.c b/src/make-3.80/remake.c new file mode 100755 index 00000000..72c4d78a --- /dev/null +++ b/src/make-3.80/remake.c @@ -0,0 +1,1420 @@ +/* Basic dependency engine for GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "filedef.h" +#include "job.h" +#include "commands.h" +#include "dep.h" +#include "variable.h" +#include "debug.h" + +#include + +#ifdef HAVE_FCNTL_H +#include +#else +#include +#endif + +#ifdef VMS +#include +#endif +#ifdef WINDOWS32 +#include +#endif + +extern int try_implicit_rule PARAMS ((struct file *file, unsigned int depth)); + + +/* The test for circular dependencies is based on the 'updating' bit in + `struct file'. However, double colon targets have seperate `struct + file's; make sure we always use the base of the double colon chain. */ + +#define start_updating(_f) (((_f)->double_colon ? (_f)->double_colon : (_f))\ + ->updating = 1) +#define finish_updating(_f) (((_f)->double_colon ? (_f)->double_colon : (_f))\ + ->updating = 0) +#define is_updating(_f) (((_f)->double_colon ? (_f)->double_colon : (_f))\ + ->updating) + + +/* Incremented when a command is started (under -n, when one would be). */ +unsigned int commands_started = 0; + +/* Current value for pruning the scan of the goal chain (toggle 0/1). */ +static unsigned int considered; + +static int update_file PARAMS ((struct file *file, unsigned int depth)); +static int update_file_1 PARAMS ((struct file *file, unsigned int depth)); +static int check_dep PARAMS ((struct file *file, unsigned int depth, FILE_TIMESTAMP this_mtime, int *must_make_ptr)); +static int touch_file PARAMS ((struct file *file)); +static void remake_file PARAMS ((struct file *file)); +static FILE_TIMESTAMP name_mtime PARAMS ((char *name)); +static int library_search PARAMS ((char **lib, FILE_TIMESTAMP *mtime_ptr)); + + +/* Remake all the goals in the `struct dep' chain GOALS. Return -1 if nothing + was done, 0 if all goals were updated successfully, or 1 if a goal failed. + If MAKEFILES is nonzero, these goals are makefiles, so -t, -q, and -n should + be disabled for them unless they were also command-line targets, and we + should only make one goal at a time and return as soon as one goal whose + `changed' member is nonzero is successfully made. */ + +int +update_goal_chain (goals, makefiles) + register struct dep *goals; + int makefiles; +{ + int t = touch_flag, q = question_flag, n = just_print_flag; + unsigned int j = job_slots; + int status = -1; + +#define MTIME(file) (makefiles ? file_mtime_no_search (file) \ + : file_mtime (file)) + + /* Duplicate the chain so we can remove things from it. */ + + goals = copy_dep_chain (goals); + + { + /* Clear the `changed' flag of each goal in the chain. + We will use the flag below to notice when any commands + have actually been run for a target. When no commands + have been run, we give an "up to date" diagnostic. */ + + struct dep *g; + for (g = goals; g != 0; g = g->next) + g->changed = 0; + } + + /* All files start with the considered bit 0, so the global value is 1. */ + considered = 1; + + /* Update all the goals until they are all finished. */ + + while (goals != 0) + { + register struct dep *g, *lastgoal; + + /* Start jobs that are waiting for the load to go down. */ + + start_waiting_jobs (); + + /* Wait for a child to die. */ + + reap_children (1, 0); + + lastgoal = 0; + g = goals; + while (g != 0) + { + /* Iterate over all double-colon entries for this file. */ + struct file *file; + int stop = 0, any_not_updated = 0; + + for (file = g->file->double_colon ? g->file->double_colon : g->file; + file != NULL; + file = file->prev) + { + unsigned int ocommands_started; + int x; + check_renamed (file); + if (makefiles) + { + if (file->cmd_target) + { + touch_flag = t; + question_flag = q; + just_print_flag = n; + } + else + touch_flag = question_flag = just_print_flag = 0; + } + + /* Save the old value of `commands_started' so we can compare + later. It will be incremented when any commands are + actually run. */ + ocommands_started = commands_started; + + x = update_file (file, makefiles ? 1 : 0); + check_renamed (file); + + /* Set the goal's `changed' flag if any commands were started + by calling update_file above. We check this flag below to + decide when to give an "up to date" diagnostic. */ + g->changed += commands_started - ocommands_started; + + /* If we updated a file and STATUS was not already 1, set it to + 1 if updating failed, or to 0 if updating succeeded. Leave + STATUS as it is if no updating was done. */ + + stop = 0; + if ((x != 0 || file->updated) && status < 1) + { + if (file->update_status != 0) + { + /* Updating failed, or -q triggered. The STATUS value + tells our caller which. */ + status = file->update_status; + /* If -q just triggered, stop immediately. It doesn't + matter how much more we run, since we already know + the answer to return. */ + stop = (!keep_going_flag && !question_flag + && !makefiles); + } + else + { + FILE_TIMESTAMP mtime = MTIME (file); + check_renamed (file); + + if (file->updated && g->changed && + mtime != file->mtime_before_update) + { + /* Updating was done. If this is a makefile and + just_print_flag or question_flag is set (meaning + -n or -q was given and this file was specified + as a command-line target), don't change STATUS. + If STATUS is changed, we will get re-exec'd, and + enter an infinite loop. */ + if (!makefiles + || (!just_print_flag && !question_flag)) + status = 0; + if (makefiles && file->dontcare) + /* This is a default makefile; stop remaking. */ + stop = 1; + } + } + } + + /* Keep track if any double-colon entry is not finished. + When they are all finished, the goal is finished. */ + any_not_updated |= !file->updated; + + if (stop) + break; + } + + /* Reset FILE since it is null at the end of the loop. */ + file = g->file; + + if (stop || !any_not_updated) + { + /* If we have found nothing whatever to do for the goal, + print a message saying nothing needs doing. */ + + if (!makefiles + /* If the update_status is zero, we updated successfully + or not at all. G->changed will have been set above if + any commands were actually started for this goal. */ + && file->update_status == 0 && !g->changed + /* Never give a message under -s or -q. */ + && !silent_flag && !question_flag) + message (1, ((file->phony || file->cmds == 0) + ? _("Nothing to be done for `%s'.") + : _("`%s' is up to date.")), + file->name); + + /* This goal is finished. Remove it from the chain. */ + if (lastgoal == 0) + goals = g->next; + else + lastgoal->next = g->next; + + /* Free the storage. */ + free ((char *) g); + + g = lastgoal == 0 ? goals : lastgoal->next; + + if (stop) + break; + } + else + { + lastgoal = g; + g = g->next; + } + } + + /* If we reached the end of the dependency graph toggle the considered + flag for the next pass. */ + if (g == 0) + considered = !considered; + } + + if (makefiles) + { + touch_flag = t; + question_flag = q; + just_print_flag = n; + job_slots = j; + } + return status; +} + +/* If FILE is not up to date, execute the commands for it. + Return 0 if successful, 1 if unsuccessful; + but with some flag settings, just call `exit' if unsuccessful. + + DEPTH is the depth in recursions of this function. + We increment it during the consideration of our dependencies, + then decrement it again after finding out whether this file + is out of date. + + If there are multiple double-colon entries for FILE, + each is considered in turn. */ + +static int +update_file (file, depth) + struct file *file; + unsigned int depth; +{ + register int status = 0; + register struct file *f; + + f = file->double_colon ? file->double_colon : file; + + /* Prune the dependency graph: if we've already been here on _this_ + pass through the dependency graph, we don't have to go any further. + We won't reap_children until we start the next pass, so no state + change is possible below here until then. */ + if (f->considered == considered) + { + DBF (DB_VERBOSE, _("Pruning file `%s'.\n")); + return f->command_state == cs_finished ? f->update_status : 0; + } + + /* This loop runs until we start commands for a double colon rule, or until + the chain is exhausted. */ + for (; f != 0; f = f->prev) + { + f->considered = considered; + + status |= update_file_1 (f, depth); + check_renamed (f); + + if (status != 0 && !keep_going_flag) + break; + + if (f->command_state == cs_running + || f->command_state == cs_deps_running) + { + /* Don't run the other :: rules for this + file until this rule is finished. */ + status = 0; + break; + } + } + + /* Process the remaining rules in the double colon chain so they're marked + considered. Start their prerequisites, too. */ + for (; f != 0 ; f = f->prev) + { + struct dep *d; + + f->considered = considered; + + for (d = f->deps; d != 0; d = d->next) + status |= update_file (d->file, depth + 1); + } + + return status; +} + +/* Consider a single `struct file' and update it as appropriate. */ + +static int +update_file_1 (file, depth) + struct file *file; + unsigned int depth; +{ + register FILE_TIMESTAMP this_mtime; + int noexist, must_make, deps_changed; + int dep_status = 0; + register struct dep *d, *lastd; + int running = 0; + + DBF (DB_VERBOSE, _("Considering target file `%s'.\n")); + + if (file->updated) + { + if (file->update_status > 0) + { + DBF (DB_VERBOSE, + _("Recently tried and failed to update file `%s'.\n")); + return file->update_status; + } + + DBF (DB_VERBOSE, _("File `%s' was considered already.\n")); + return 0; + } + + switch (file->command_state) + { + case cs_not_started: + case cs_deps_running: + break; + case cs_running: + DBF (DB_VERBOSE, _("Still updating file `%s'.\n")); + return 0; + case cs_finished: + DBF (DB_VERBOSE, _("Finished updating file `%s'.\n")); + return file->update_status; + default: + abort (); + } + + ++depth; + + /* Notice recursive update of the same file. */ + start_updating (file); + + /* Looking at the file's modtime beforehand allows the possibility + that its name may be changed by a VPATH search, and thus it may + not need an implicit rule. If this were not done, the file + might get implicit commands that apply to its initial name, only + to have that name replaced with another found by VPATH search. */ + + this_mtime = file_mtime (file); + check_renamed (file); + noexist = this_mtime == NONEXISTENT_MTIME; + if (noexist) + DBF (DB_BASIC, _("File `%s' does not exist.\n")); + else if (ORDINARY_MTIME_MIN <= this_mtime && this_mtime <= ORDINARY_MTIME_MAX + && file->low_resolution_time) + { + /* Avoid spurious rebuilds due to low resolution time stamps. */ + int ns = FILE_TIMESTAMP_NS (this_mtime); + if (ns != 0) + error (NILF, _("*** Warning: .LOW_RESOLUTION_TIME file `%s' has a high resolution time stamp"), + file->name); + this_mtime += FILE_TIMESTAMPS_PER_S - 1 - ns; + } + + must_make = noexist; + + /* If file was specified as a target with no commands, + come up with some default commands. */ + + if (!file->phony && file->cmds == 0 && !file->tried_implicit) + { + if (try_implicit_rule (file, depth)) + DBF (DB_IMPLICIT, _("Found an implicit rule for `%s'.\n")); + else + DBF (DB_IMPLICIT, _("No implicit rule found for `%s'.\n")); + file->tried_implicit = 1; + } + if (file->cmds == 0 && !file->is_target + && default_file != 0 && default_file->cmds != 0) + { + DBF (DB_IMPLICIT, _("Using default commands for `%s'.\n")); + file->cmds = default_file->cmds; + } + + /* Update all non-intermediate files we depend on, if necessary, + and see whether any of them is more recent than this file. */ + + lastd = 0; + d = file->deps; + while (d != 0) + { + FILE_TIMESTAMP mtime; + int maybe_make; + + check_renamed (d->file); + + mtime = file_mtime (d->file); + check_renamed (d->file); + + if (is_updating (d->file)) + { + error (NILF, _("Circular %s <- %s dependency dropped."), + file->name, d->file->name); + /* We cannot free D here because our the caller will still have + a reference to it when we were called recursively via + check_dep below. */ + if (lastd == 0) + file->deps = d->next; + else + lastd->next = d->next; + d = d->next; + continue; + } + + d->file->parent = file; + maybe_make = must_make; + dep_status |= check_dep (d->file, depth, this_mtime, &maybe_make); + if (! d->ignore_mtime) + must_make = maybe_make; + + check_renamed (d->file); + + { + register struct file *f = d->file; + if (f->double_colon) + f = f->double_colon; + do + { + running |= (f->command_state == cs_running + || f->command_state == cs_deps_running); + f = f->prev; + } + while (f != 0); + } + + if (dep_status != 0 && !keep_going_flag) + break; + + if (!running) + d->changed = file_mtime (d->file) != mtime; + + lastd = d; + d = d->next; + } + + /* Now we know whether this target needs updating. + If it does, update all the intermediate files we depend on. */ + + if (must_make || always_make_flag) + { + for (d = file->deps; d != 0; d = d->next) + if (d->file->intermediate) + { + FILE_TIMESTAMP mtime = file_mtime (d->file); + check_renamed (d->file); + d->file->parent = file; + dep_status |= update_file (d->file, depth); + check_renamed (d->file); + + { + register struct file *f = d->file; + if (f->double_colon) + f = f->double_colon; + do + { + running |= (f->command_state == cs_running + || f->command_state == cs_deps_running); + f = f->prev; + } + while (f != 0); + } + + if (dep_status != 0 && !keep_going_flag) + break; + + if (!running) + d->changed = ((file->phony && file->cmds != 0) + || file_mtime (d->file) != mtime); + } + } + + finish_updating (file); + + DBF (DB_VERBOSE, _("Finished prerequisites of target file `%s'.\n")); + + if (running) + { + set_command_state (file, cs_deps_running); + --depth; + DBF (DB_VERBOSE, _("The prerequisites of `%s' are being made.\n")); + return 0; + } + + /* If any dependency failed, give up now. */ + + if (dep_status != 0) + { + file->update_status = dep_status; + notice_finished_file (file); + + --depth; + + DBF (DB_VERBOSE, _("Giving up on target file `%s'.\n")); + + if (depth == 0 && keep_going_flag + && !just_print_flag && !question_flag) + error (NILF, + _("Target `%s' not remade because of errors."), file->name); + + return dep_status; + } + + if (file->command_state == cs_deps_running) + /* The commands for some deps were running on the last iteration, but + they have finished now. Reset the command_state to not_started to + simplify later bookkeeping. It is important that we do this only + when the prior state was cs_deps_running, because that prior state + was definitely propagated to FILE's also_make's by set_command_state + (called above), but in another state an also_make may have + independently changed to finished state, and we would confuse that + file's bookkeeping (updated, but not_started is bogus state). */ + set_command_state (file, cs_not_started); + + /* Now record which prerequisites are more + recent than this file, so we can define $?. */ + + deps_changed = 0; + for (d = file->deps; d != 0; d = d->next) + { + FILE_TIMESTAMP d_mtime = file_mtime (d->file); + check_renamed (d->file); + + if (! d->ignore_mtime) + { +#if 1 + /* %%% In version 4, remove this code completely to + implement not remaking deps if their deps are newer + than their parents. */ + if (d_mtime == NONEXISTENT_MTIME && !d->file->intermediate) + /* We must remake if this dep does not + exist and is not intermediate. */ + must_make = 1; +#endif + + /* Set DEPS_CHANGED if this dep actually changed. */ + deps_changed |= d->changed; + } + + /* Set D->changed if either this dep actually changed, + or its dependent, FILE, is older or does not exist. */ + d->changed |= noexist || d_mtime > this_mtime; + + if (!noexist && ISDB (DB_BASIC|DB_VERBOSE)) + { + const char *fmt = 0; + + if (d->ignore_mtime) + { + if (ISDB (DB_VERBOSE)) + fmt = _("Prerequisite `%s' is order-only for target `%s'.\n"); + } + else if (d_mtime == NONEXISTENT_MTIME) + { + if (ISDB (DB_BASIC)) + fmt = _("Prerequisite `%s' of target `%s' does not exist.\n"); + } + else if (d->changed) + { + if (ISDB (DB_BASIC)) + fmt = _("Prerequisite `%s' is newer than target `%s'.\n"); + } + else if (ISDB (DB_VERBOSE)) + fmt = _("Prerequisite `%s' is older than target `%s'.\n"); + + if (fmt) + { + print_spaces (depth); + printf (fmt, dep_name (d), file->name); + fflush (stdout); + } + } + } + + /* Here depth returns to the value it had when we were called. */ + depth--; + + if (file->double_colon && file->deps == 0) + { + must_make = 1; + DBF (DB_BASIC, + _("Target `%s' is double-colon and has no prerequisites.\n")); + } + else if (!noexist && file->is_target && !deps_changed && file->cmds == 0 + && !always_make_flag) + { + must_make = 0; + DBF (DB_VERBOSE, + _("No commands for `%s' and no prerequisites actually changed.\n")); + } + else if (!must_make && file->cmds != 0 && always_make_flag) + { + must_make = 1; + DBF (DB_VERBOSE, _("Making `%s' due to always-make flag.\n")); + } + + if (!must_make) + { + if (ISDB (DB_VERBOSE)) + { + print_spaces (depth); + printf (_("No need to remake target `%s'"), file->name); + if (!streq (file->name, file->hname)) + printf (_("; using VPATH name `%s'"), file->hname); + puts ("."); + fflush (stdout); + } + + notice_finished_file (file); + + /* Since we don't need to remake the file, convert it to use the + VPATH filename if we found one. hfile will be either the + local name if no VPATH or the VPATH name if one was found. */ + + while (file) + { + file->name = file->hname; + file = file->prev; + } + + return 0; + } + + DBF (DB_BASIC, _("Must remake target `%s'.\n")); + + /* It needs to be remade. If it's VPATH and not reset via GPATH, toss the + VPATH. */ + if (!streq(file->name, file->hname)) + { + DB (DB_BASIC, (_(" Ignoring VPATH name `%s'.\n"), file->hname)); + file->ignore_vpath = 1; + } + + /* Now, take appropriate actions to remake the file. */ + remake_file (file); + + if (file->command_state != cs_finished) + { + DBF (DB_VERBOSE, _("Commands of `%s' are being run.\n")); + return 0; + } + + switch (file->update_status) + { + case 2: + DBF (DB_BASIC, _("Failed to remake target file `%s'.\n")); + break; + case 0: + DBF (DB_BASIC, _("Successfully remade target file `%s'.\n")); + break; + case 1: + DBF (DB_BASIC, _("Target file `%s' needs remade under -q.\n")); + break; + default: + assert (file->update_status >= 0 && file->update_status <= 2); + break; + } + + file->updated = 1; + return file->update_status; +} + +/* Set FILE's `updated' flag and re-check its mtime and the mtime's of all + files listed in its `also_make' member. Under -t, this function also + touches FILE. + + On return, FILE->update_status will no longer be -1 if it was. */ + +void +notice_finished_file (file) + register struct file *file; +{ + struct dep *d; + int ran = file->command_state == cs_running; + int touched = 0; + + file->command_state = cs_finished; + file->updated = 1; + + if (touch_flag + /* The update status will be: + -1 if this target was not remade; + 0 if 0 or more commands (+ or ${MAKE}) were run and won; + 1 if some commands were run and lost. + We touch the target if it has commands which either were not run + or won when they ran (i.e. status is 0). */ + && file->update_status == 0) + { + if (file->cmds != 0 && file->cmds->any_recurse) + { + /* If all the command lines were recursive, + we don't want to do the touching. */ + unsigned int i; + for (i = 0; i < file->cmds->ncommand_lines; ++i) + if (!(file->cmds->lines_flags[i] & COMMANDS_RECURSE)) + goto have_nonrecursing; + } + else + { + have_nonrecursing: + if (file->phony) + file->update_status = 0; + else + { + /* Should set file's modification date and do nothing else. */ + file->update_status = touch_file (file); + + /* Pretend we ran a real touch command, to suppress the + "`foo' is up to date" message. */ + commands_started++; + + /* Request for the timestamp to be updated (and distributed + to the double-colon entries). Simply setting ran=1 would + almost have done the trick, but messes up with the also_make + updating logic below. */ + touched = 1; + } + } + } + + if (file->mtime_before_update == UNKNOWN_MTIME) + file->mtime_before_update = file->last_mtime; + + if ((ran && !file->phony) || touched) + { + struct file *f; + int i = 0; + + /* If -n, -t, or -q and all the commands are recursive, we ran them so + really check the target's mtime again. Otherwise, assume the target + would have been updated. */ + + if (question_flag || just_print_flag || touch_flag) + { + for (i = file->cmds->ncommand_lines; i > 0; --i) + if (! (file->cmds->lines_flags[i-1] & COMMANDS_RECURSE)) + break; + } + + /* If there were no commands at all, it's always new. */ + + else if (file->is_target && file->cmds == 0) + i = 1; + + file->last_mtime = i == 0 ? UNKNOWN_MTIME : NEW_MTIME; + + /* Propagate the change of modification time to all the double-colon + entries for this file. */ + for (f = file->double_colon; f != 0; f = f->prev) + f->last_mtime = file->last_mtime; + } + + if (ran && file->update_status != -1) + /* We actually tried to update FILE, which has + updated its also_make's as well (if it worked). + If it didn't work, it wouldn't work again for them. + So mark them as updated with the same status. */ + for (d = file->also_make; d != 0; d = d->next) + { + d->file->command_state = cs_finished; + d->file->updated = 1; + d->file->update_status = file->update_status; + + if (ran && !d->file->phony) + /* Fetch the new modification time. + We do this instead of just invalidating the cached time + so that a vpath_search can happen. Otherwise, it would + never be done because the target is already updated. */ + (void) f_mtime (d->file, 0); + } + else if (file->update_status == -1) + /* Nothing was done for FILE, but it needed nothing done. + So mark it now as "succeeded". */ + file->update_status = 0; +} + +/* Check whether another file (whose mtime is THIS_MTIME) + needs updating on account of a dependency which is file FILE. + If it does, store 1 in *MUST_MAKE_PTR. + In the process, update any non-intermediate files + that FILE depends on (including FILE itself). + Return nonzero if any updating failed. */ + +static int +check_dep (file, depth, this_mtime, must_make_ptr) + struct file *file; + unsigned int depth; + FILE_TIMESTAMP this_mtime; + int *must_make_ptr; +{ + struct dep *d; + int dep_status = 0; + + ++depth; + start_updating (file); + + if (!file->intermediate) + /* If this is a non-intermediate file, update it and record + whether it is newer than THIS_MTIME. */ + { + FILE_TIMESTAMP mtime; + dep_status = update_file (file, depth); + check_renamed (file); + mtime = file_mtime (file); + check_renamed (file); + if (mtime == NONEXISTENT_MTIME || mtime > this_mtime) + *must_make_ptr = 1; + } + else + { + /* FILE is an intermediate file. */ + FILE_TIMESTAMP mtime; + + if (!file->phony && file->cmds == 0 && !file->tried_implicit) + { + if (try_implicit_rule (file, depth)) + DBF (DB_IMPLICIT, _("Found an implicit rule for `%s'.\n")); + else + DBF (DB_IMPLICIT, _("No implicit rule found for `%s'.\n")); + file->tried_implicit = 1; + } + if (file->cmds == 0 && !file->is_target + && default_file != 0 && default_file->cmds != 0) + { + DBF (DB_IMPLICIT, _("Using default commands for `%s'.\n")); + file->cmds = default_file->cmds; + } + + /* If the intermediate file actually exists + and is newer, then we should remake from it. */ + check_renamed (file); + mtime = file_mtime (file); + check_renamed (file); + if (mtime != NONEXISTENT_MTIME && mtime > this_mtime) + *must_make_ptr = 1; + /* Otherwise, update all non-intermediate files we depend on, + if necessary, and see whether any of them is more + recent than the file on whose behalf we are checking. */ + else + { + struct dep *lastd; + + lastd = 0; + d = file->deps; + while (d != 0) + { + int maybe_make; + + if (is_updating (d->file)) + { + error (NILF, _("Circular %s <- %s dependency dropped."), + file->name, d->file->name); + if (lastd == 0) + { + file->deps = d->next; + free ((char *) d); + d = file->deps; + } + else + { + lastd->next = d->next; + free ((char *) d); + d = lastd->next; + } + continue; + } + + d->file->parent = file; + maybe_make = *must_make_ptr; + dep_status |= check_dep (d->file, depth, this_mtime, + &maybe_make); + if (! d->ignore_mtime) + *must_make_ptr = maybe_make; + check_renamed (d->file); + if (dep_status != 0 && !keep_going_flag) + break; + + if (d->file->command_state == cs_running + || d->file->command_state == cs_deps_running) + /* Record that some of FILE's deps are still being made. + This tells the upper levels to wait on processing it until + the commands are finished. */ + set_command_state (file, cs_deps_running); + + lastd = d; + d = d->next; + } + } + } + + finish_updating (file); + return dep_status; +} + +/* Touch FILE. Return zero if successful, one if not. */ + +#define TOUCH_ERROR(call) return (perror_with_name (call, file->name), 1) + +static int +touch_file (file) + register struct file *file; +{ + if (!silent_flag) + message (0, "touch %s", file->name); + +#ifndef NO_ARCHIVES + if (ar_name (file->name)) + return ar_touch (file->name); + else +#endif + { + int fd = open (file->name, O_RDWR | O_CREAT, 0666); + + if (fd < 0) + TOUCH_ERROR ("touch: open: "); + else + { + struct stat statbuf; + char buf; + + if (fstat (fd, &statbuf) < 0) + TOUCH_ERROR ("touch: fstat: "); + /* Rewrite character 0 same as it already is. */ + if (read (fd, &buf, 1) < 0) + TOUCH_ERROR ("touch: read: "); + if (lseek (fd, 0L, 0) < 0L) + TOUCH_ERROR ("touch: lseek: "); + if (write (fd, &buf, 1) < 0) + TOUCH_ERROR ("touch: write: "); + /* If file length was 0, we just + changed it, so change it back. */ + if (statbuf.st_size == 0) + { + (void) close (fd); + fd = open (file->name, O_RDWR | O_TRUNC, 0666); + if (fd < 0) + TOUCH_ERROR ("touch: open: "); + } + (void) close (fd); + } + } + + return 0; +} + +/* Having checked and updated the dependencies of FILE, + do whatever is appropriate to remake FILE itself. + Return the status from executing FILE's commands. */ + +static void +remake_file (file) + struct file *file; +{ + if (file->cmds == 0) + { + if (file->phony) + /* Phony target. Pretend it succeeded. */ + file->update_status = 0; + else if (file->is_target) + /* This is a nonexistent target file we cannot make. + Pretend it was successfully remade. */ + file->update_status = 0; + else + { + const char *msg_noparent + = _("%sNo rule to make target `%s'%s"); + const char *msg_parent + = _("%sNo rule to make target `%s', needed by `%s'%s"); + + /* This is a dependency file we cannot remake. Fail. */ + if (!keep_going_flag && !file->dontcare) + { + if (file->parent == 0) + fatal (NILF, msg_noparent, "", file->name, ""); + + fatal (NILF, msg_parent, "", file->name, file->parent->name, ""); + } + + if (!file->dontcare) + { + if (file->parent == 0) + error (NILF, msg_noparent, "*** ", file->name, "."); + else + error (NILF, msg_parent, "*** ", + file->name, file->parent->name, "."); + } + file->update_status = 2; + } + } + else + { + chop_commands (file->cmds); + + /* The normal case: start some commands. */ + if (!touch_flag || file->cmds->any_recurse) + { + execute_file_commands (file); + return; + } + + /* This tells notice_finished_file it is ok to touch the file. */ + file->update_status = 0; + } + + /* This does the touching under -t. */ + notice_finished_file (file); +} + +/* Return the mtime of a file, given a `struct file'. + Caches the time in the struct file to avoid excess stat calls. + + If the file is not found, and SEARCH is nonzero, VPATH searching and + replacement is done. If that fails, a library (-lLIBNAME) is tried and + the library's actual name (/lib/libLIBNAME.a, etc.) is substituted into + FILE. */ + +FILE_TIMESTAMP +f_mtime (file, search) + register struct file *file; + int search; +{ + FILE_TIMESTAMP mtime; + + /* File's mtime is not known; must get it from the system. */ + +#ifndef NO_ARCHIVES + if (ar_name (file->name)) + { + /* This file is an archive-member reference. */ + + char *arname, *memname; + struct file *arfile; + int arname_used = 0; + time_t member_date; + + /* Find the archive's name. */ + ar_parse_name (file->name, &arname, &memname); + + /* Find the modification time of the archive itself. + Also allow for its name to be changed via VPATH search. */ + arfile = lookup_file (arname); + if (arfile == 0) + { + arfile = enter_file (arname); + arname_used = 1; + } + mtime = f_mtime (arfile, search); + check_renamed (arfile); + if (search && strcmp (arfile->hname, arname)) + { + /* The archive's name has changed. + Change the archive-member reference accordingly. */ + + char *name; + unsigned int arlen, memlen; + + if (!arname_used) + { + free (arname); + arname_used = 1; + } + + arname = arfile->hname; + arlen = strlen (arname); + memlen = strlen (memname); + + /* free (file->name); */ + + name = (char *) xmalloc (arlen + 1 + memlen + 2); + bcopy (arname, name, arlen); + name[arlen] = '('; + bcopy (memname, name + arlen + 1, memlen); + name[arlen + 1 + memlen] = ')'; + name[arlen + 1 + memlen + 1] = '\0'; + + /* If the archive was found with GPATH, make the change permanent; + otherwise defer it until later. */ + if (arfile->name == arfile->hname) + rename_file (file, name); + else + rehash_file (file, name); + check_renamed (file); + } + + if (!arname_used) + free (arname); + free (memname); + + file->low_resolution_time = 1; + + if (mtime == NONEXISTENT_MTIME) + /* The archive doesn't exist, so its members don't exist either. */ + return NONEXISTENT_MTIME; + + member_date = ar_member_date (file->hname); + mtime = (member_date == (time_t) -1 + ? NONEXISTENT_MTIME + : file_timestamp_cons (file->hname, member_date, 0)); + } + else +#endif + { + mtime = name_mtime (file->name); + + if (mtime == NONEXISTENT_MTIME && search && !file->ignore_vpath) + { + /* If name_mtime failed, search VPATH. */ + char *name = file->name; + if (vpath_search (&name, &mtime) + /* Last resort, is it a library (-lxxx)? */ + || (name[0] == '-' && name[1] == 'l' + && library_search (&name, &mtime))) + { + if (mtime != UNKNOWN_MTIME) + /* vpath_search and library_search store UNKNOWN_MTIME + if they didn't need to do a stat call for their work. */ + file->last_mtime = mtime; + + /* If we found it in VPATH, see if it's in GPATH too; if so, + change the name right now; if not, defer until after the + dependencies are updated. */ + if (gpath_search (name, strlen(name) - strlen(file->name) - 1)) + { + rename_file (file, name); + check_renamed (file); + return file_mtime (file); + } + + rehash_file (file, name); + check_renamed (file); + mtime = name_mtime (name); + } + } + } + + { + /* Files can have bogus timestamps that nothing newly made will be + "newer" than. Updating their dependents could just result in loops. + So notify the user of the anomaly with a warning. + + We only need to do this once, for now. */ + + if (!clock_skew_detected + && mtime != NONEXISTENT_MTIME + && !file->updated) + { + static FILE_TIMESTAMP adjusted_now; + + FILE_TIMESTAMP adjusted_mtime = mtime; + +#if defined(WINDOWS32) || defined(__MSDOS__) + /* Experimentation has shown that FAT filesystems can set file times + up to 3 seconds into the future! Play it safe. */ + +#define FAT_ADJ_OFFSET (FILE_TIMESTAMP) 3 + + FILE_TIMESTAMP adjustment = FAT_ADJ_OFFSET << FILE_TIMESTAMP_LO_BITS; + if (ORDINARY_MTIME_MIN + adjustment <= adjusted_mtime) + adjusted_mtime -= adjustment; +#endif + + /* If the file's time appears to be in the future, update our + concept of the present and try once more. */ + if (adjusted_now < adjusted_mtime) + { + int resolution; + FILE_TIMESTAMP now = file_timestamp_now (&resolution); + adjusted_now = now + (resolution - 1); + if (adjusted_now < adjusted_mtime) + { +#ifdef NO_FLOAT + error (NILF, _("Warning: File `%s' has modification time in the future"), + file->name); +#else + double from_now = + (FILE_TIMESTAMP_S (mtime) - FILE_TIMESTAMP_S (now) + + ((FILE_TIMESTAMP_NS (mtime) - FILE_TIMESTAMP_NS (now)) + / 1e9)); + error (NILF, _("Warning: File `%s' has modification time %.2g s in the future"), + file->name, from_now); +#endif + clock_skew_detected = 1; + } + } + } + } + + /* Store the mtime into all the entries for this file. */ + if (file->double_colon) + file = file->double_colon; + + do + { + /* If this file is not implicit but it is intermediate then it was + made so by the .INTERMEDIATE target. If this file has never + been built by us but was found now, it existed before make + started. So, turn off the intermediate bit so make doesn't + delete it, since it didn't create it. */ + if (mtime != NONEXISTENT_MTIME && file->command_state == cs_not_started + && file->command_state == cs_not_started + && !file->tried_implicit && file->intermediate) + file->intermediate = 0; + + file->last_mtime = mtime; + file = file->prev; + } + while (file != 0); + + return mtime; +} + + +/* Return the mtime of the file or archive-member reference NAME. */ + +static FILE_TIMESTAMP +name_mtime (name) + register char *name; +{ + struct stat st; + + if (stat (name, &st) != 0) + { + if (errno != ENOENT && errno != ENOTDIR) + perror_with_name ("stat:", name); + return NONEXISTENT_MTIME; + } + + return FILE_TIMESTAMP_STAT_MODTIME (name, st); +} + + +/* Search for a library file specified as -lLIBNAME, searching for a + suitable library file in the system library directories and the VPATH + directories. */ + +static int +library_search (lib, mtime_ptr) + char **lib; + FILE_TIMESTAMP *mtime_ptr; +{ + static char *dirs[] = + { +#ifndef _AMIGA + "/lib", + "/usr/lib", +#endif +#if defined(WINDOWS32) && !defined(LIBDIR) +/* + * This is completely up to the user at product install time. Just define + * a placeholder. + */ +#define LIBDIR "." +#endif + LIBDIR, /* Defined by configuration. */ + 0 + }; + + static char *libpatterns = NULL; + + char *libname = &(*lib)[2]; /* Name without the `-l'. */ + FILE_TIMESTAMP mtime; + + /* Loop variables for the libpatterns value. */ + char *p, *p2; + unsigned int len; + + char *file, **dp; + + /* If we don't have libpatterns, get it. */ + if (!libpatterns) + { + int save = warn_undefined_variables_flag; + warn_undefined_variables_flag = 0; + + libpatterns = xstrdup (variable_expand ("$(strip $(.LIBPATTERNS))")); + + warn_undefined_variables_flag = save; + } + + /* Loop through all the patterns in .LIBPATTERNS, and search on each one. */ + p2 = libpatterns; + while ((p = find_next_token (&p2, &len)) != 0) + { + static char *buf = NULL; + static int buflen = 0; + static int libdir_maxlen = -1; + char *libbuf = variable_expand (""); + + /* Expand the pattern using LIBNAME as a replacement. */ + { + char c = p[len]; + char *p3, *p4; + + p[len] = '\0'; + p3 = find_percent (p); + if (!p3) + { + /* Give a warning if there is no pattern, then remove the + pattern so it's ignored next time. */ + error (NILF, _(".LIBPATTERNS element `%s' is not a pattern"), p); + for (; len; --len, ++p) + *p = ' '; + *p = c; + continue; + } + p4 = variable_buffer_output (libbuf, p, p3-p); + p4 = variable_buffer_output (p4, libname, strlen (libname)); + p4 = variable_buffer_output (p4, p3+1, len - (p3-p)); + p[len] = c; + } + + /* Look first for `libNAME.a' in the current directory. */ + mtime = name_mtime (libbuf); + if (mtime != NONEXISTENT_MTIME) + { + *lib = xstrdup (libbuf); + if (mtime_ptr != 0) + *mtime_ptr = mtime; + return 1; + } + + /* Now try VPATH search on that. */ + + file = libbuf; + if (vpath_search (&file, mtime_ptr)) + { + *lib = file; + return 1; + } + + /* Now try the standard set of directories. */ + + if (!buflen) + { + for (dp = dirs; *dp != 0; ++dp) + { + int l = strlen (*dp); + if (l > libdir_maxlen) + libdir_maxlen = l; + } + buflen = strlen (libbuf); + buf = xmalloc(libdir_maxlen + buflen + 2); + } + else if (buflen < strlen (libbuf)) + { + buflen = strlen (libbuf); + buf = xrealloc (buf, libdir_maxlen + buflen + 2); + } + + for (dp = dirs; *dp != 0; ++dp) + { + sprintf (buf, "%s/%s", *dp, libbuf); + mtime = name_mtime (buf); + if (mtime != NONEXISTENT_MTIME) + { + *lib = xstrdup (buf); + if (mtime_ptr != 0) + *mtime_ptr = mtime; + return 1; + } + } + } + + return 0; +} diff --git a/src/make-3.80/remote-cstms.c b/src/make-3.80/remote-cstms.c new file mode 100755 index 00000000..b0587396 --- /dev/null +++ b/src/make-3.80/remote-cstms.c @@ -0,0 +1,310 @@ +/* GNU Make remote job exportation interface to the Customs daemon. + THIS CODE IS NOT SUPPORTED BY THE GNU PROJECT. + Please do not send bug reports or questions about it to + the Make maintainers. + +Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "job.h" +#include "filedef.h" +#include "commands.h" +#include "job.h" +#include "debug.h" + +#include +#include + +#include "customs.h" + +char *remote_description = "Customs"; + +/* File name of the Customs `export' client command. + A full path name can be used to avoid some path-searching overhead. */ +#define EXPORT_COMMAND "/usr/local/bin/export" + +/* ExportPermit gotten by start_remote_job_p, and used by start_remote_job. */ +static ExportPermit permit; + +/* Normalized path name of the current directory. */ +static char *normalized_cwd; + +/* Call once at startup even if no commands are run. */ + +void +remote_setup () +{ +} + +/* Called before exit. */ + +void +remote_cleanup () +{ +} + +/* Return nonzero if the next job should be done remotely. */ + +int +start_remote_job_p (first_p) + int first_p; +{ + static int inited = 0; + int status; + int njobs; + + if (!inited) + { + /* Allow the user to turn off job exportation (useful while he is + debugging Customs, for example). */ + if (getenv ("GNU_MAKE_NO_CUSTOMS") != 0) + { + inited = -1; + return 0; + } + + /* For secure Customs, make is installed setuid root and + Customs requires a privileged source port be used. */ + make_access (); + + if (ISDB (DB_JOBS)) + Rpc_Debug(1); + + /* Ping the daemon once to see if it is there. */ + inited = Customs_Ping () == RPC_SUCCESS ? 1 : -1; + + /* Return to normal user access. */ + user_access (); + + if (starting_directory == 0) + /* main couldn't figure it out. */ + inited = -1; + else + { + /* Normalize the current directory path name to something + that should work on all machines exported to. */ + + normalized_cwd = (char *) xmalloc (GET_PATH_MAX); + strcpy (normalized_cwd, starting_directory); + if (Customs_NormPath (normalized_cwd, GET_PATH_MAX) < 0) + /* Path normalization failure means using Customs + won't work, but it's not really an error. */ + inited = -1; + } + } + + if (inited < 0) + return 0; + + njobs = job_slots_used; + if (!first_p) + njobs -= 1; /* correction for being called from reap_children() */ + + /* the first job should run locally, or, if the -l flag is given, we use + that as clue as to how many local jobs should be scheduled locally */ + if (max_load_average < 0 && njobs == 0 || njobs < max_load_average) + return 0; + + status = Customs_Host (EXPORT_SAME, &permit); + if (status != RPC_SUCCESS) + { + DB (DB_JOBS, (_("Customs won't export: %s\n"), + Rpc_ErrorMessage (status))); + return 0; + } + + return !CUSTOMS_FAIL (&permit.addr); +} + +/* Start a remote job running the command in ARGV, with environment from + ENVP. It gets standard input from STDIN_FD. On failure, return + nonzero. On success, return zero, and set *USED_STDIN to nonzero if it + will actually use STDIN_FD, zero if not, set *ID_PTR to a unique + identification, and set *IS_REMOTE to nonzero if the job is remote, zero + if it is local (meaning *ID_PTR is a process ID). */ + +int +start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin) + char **argv, **envp; + int stdin_fd; + int *is_remote; + int *id_ptr; + int *used_stdin; +{ + char waybill[MAX_DATA_SIZE], msg[128]; + struct hostent *host; + struct timeval timeout; + struct sockaddr_in sin; + int len; + int retsock, retport, sock; + Rpc_Stat status; + int pid; + + /* Create the return socket. */ + retsock = Rpc_UdpCreate (True, 0); + if (retsock < 0) + { + error (NILF, "exporting: Couldn't create return socket."); + return 1; + } + + /* Get the return socket's port number. */ + len = sizeof (sin); + if (getsockname (retsock, (struct sockaddr *) &sin, &len) < 0) + { + (void) close (retsock); + perror_with_name ("exporting: ", "getsockname"); + return 1; + } + retport = sin.sin_port; + + /* Create the TCP socket for talking to the remote child. */ + sock = Rpc_TcpCreate (False, 0); + + /* Create a WayBill to give to the server. */ + len = Customs_MakeWayBill (&permit, normalized_cwd, argv[0], argv, + envp, retport, waybill); + + /* Modify the waybill as if the remote child had done `child_access ()'. */ + { + WayBill *wb = (WayBill *) waybill; + wb->ruid = wb->euid; + wb->rgid = wb->egid; + } + + /* Send the request to the server, timing out in 20 seconds. */ + timeout.tv_usec = 0; + timeout.tv_sec = 20; + sin.sin_family = AF_INET; + sin.sin_port = htons (Customs_Port ()); + sin.sin_addr = permit.addr; + status = Rpc_Call (sock, &sin, (Rpc_Proc) CUSTOMS_IMPORT, + len, (Rpc_Opaque) waybill, + sizeof(msg), (Rpc_Opaque) msg, + 1, &timeout); + + host = gethostbyaddr((char *)&permit.addr, sizeof(permit.addr), AF_INET); + + if (status != RPC_SUCCESS) + { + (void) close (retsock); + (void) close (sock); + error (NILF, "exporting to %s: %s", + host ? host->h_name : inet_ntoa (permit.addr), + Rpc_ErrorMessage (status)); + return 1; + } + else if (msg[0] != 'O' || msg[1] != 'k' || msg[2] != '\0') + { + (void) close (retsock); + (void) close (sock); + error (NILF, "exporting to %s: %s", + host ? host->h_name : inet_ntoa (permit.addr), + msg); + return 1; + } + else + { + error (NILF, "*** exported to %s (id %u)", + host ? host->h_name : inet_ntoa (permit.addr), + permit.id); + } + + fflush (stdout); + fflush (stderr); + + pid = vfork (); + if (pid < 0) + { + /* The fork failed! */ + perror_with_name ("vfork", ""); + return 1; + } + else if (pid == 0) + { + /* Child side. Run `export' to handle the connection. */ + static char sock_buf[20], retsock_buf[20], id_buf[20]; + static char *new_argv[6] = + { EXPORT_COMMAND, "-id", sock_buf, retsock_buf, id_buf, 0 }; + + /* Set up the arguments. */ + (void) sprintf (sock_buf, "%d", sock); + (void) sprintf (retsock_buf, "%d", retsock); + (void) sprintf (id_buf, "%x", permit.id); + + /* Get the right stdin. */ + if (stdin_fd != 0) + (void) dup2 (stdin_fd, 0); + + /* Unblock signals in the child. */ + unblock_sigs (); + + /* Run the command. */ + exec_command (new_argv, envp); + } + + /* Parent side. Return the `export' process's ID. */ + (void) close (retsock); + (void) close (sock); + *is_remote = 0; + *id_ptr = pid; + *used_stdin = 1; + return 0; +} + +/* Get the status of a dead remote child. Block waiting for one to die + if BLOCK is nonzero. Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR + to the termination signal or zero if it exited normally, and *COREDUMP_PTR + nonzero if it dumped core. Return the ID of the child that died, + 0 if we would have to block and !BLOCK, or < 0 if there were none. */ + +int +remote_status (exit_code_ptr, signal_ptr, coredump_ptr, block) + int *exit_code_ptr, *signal_ptr, *coredump_ptr; + int block; +{ + return -1; +} + +/* Block asynchronous notification of remote child death. + If this notification is done by raising the child termination + signal, do not block that signal. */ +void +block_remote_children () +{ + return; +} + +/* Restore asynchronous notification of remote child death. + If this is done by raising the child termination signal, + do not unblock that signal. */ +void +unblock_remote_children () +{ + return; +} + +/* Send signal SIG to child ID. Return 0 if successful, -1 if not. */ +int +remote_kill (id, sig) + int id; + int sig; +{ + return -1; +} diff --git a/src/make-3.80/remote-stub.c b/src/make-3.80/remote-stub.c new file mode 100755 index 00000000..69af3975 --- /dev/null +++ b/src/make-3.80/remote-stub.c @@ -0,0 +1,109 @@ +/* Template for the remote job exportation interface to GNU Make. +Copyright (C) 1988, 1989, 1992, 1993, 1996 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "filedef.h" +#include "job.h" +#include "commands.h" + + +char *remote_description = 0; + +/* Call once at startup even if no commands are run. */ + +void +remote_setup () +{ +} + +/* Called before exit. */ + +void +remote_cleanup () +{ +} + +/* Return nonzero if the next job should be done remotely. */ + +int +start_remote_job_p (first_p) + int first_p; +{ + return 0; +} + +/* Start a remote job running the command in ARGV, + with environment from ENVP. It gets standard input from STDIN_FD. On + failure, return nonzero. On success, return zero, and set *USED_STDIN + to nonzero if it will actually use STDIN_FD, zero if not, set *ID_PTR to + a unique identification, and set *IS_REMOTE to zero if the job is local, + nonzero if it is remote (meaning *ID_PTR is a process ID). */ + +int +start_remote_job (argv, envp, stdin_fd, is_remote, id_ptr, used_stdin) + char **argv, **envp; + int stdin_fd; + int *is_remote; + int *id_ptr; + int *used_stdin; +{ + return -1; +} + +/* Get the status of a dead remote child. Block waiting for one to die + if BLOCK is nonzero. Set *EXIT_CODE_PTR to the exit status, *SIGNAL_PTR + to the termination signal or zero if it exited normally, and *COREDUMP_PTR + nonzero if it dumped core. Return the ID of the child that died, + 0 if we would have to block and !BLOCK, or < 0 if there were none. */ + +int +remote_status (exit_code_ptr, signal_ptr, coredump_ptr, block) + int *exit_code_ptr, *signal_ptr, *coredump_ptr; + int block; +{ + errno = ECHILD; + return -1; +} + +/* Block asynchronous notification of remote child death. + If this notification is done by raising the child termination + signal, do not block that signal. */ +void +block_remote_children () +{ + return; +} + +/* Restore asynchronous notification of remote child death. + If this is done by raising the child termination signal, + do not unblock that signal. */ +void +unblock_remote_children () +{ + return; +} + +/* Send signal SIG to child ID. Return 0 if successful, -1 if not. */ +int +remote_kill (id, sig) + int id; + int sig; +{ + return -1; +} diff --git a/src/make-3.80/respf.$$$ b/src/make-3.80/respf.$$$ new file mode 100755 index 00000000..29791e7b --- /dev/null +++ b/src/make-3.80/respf.$$$ @@ -0,0 +1,23 @@ +commands.o +job.o +dir.o +file.o +misc.o +main.o +read.o +remake.o +rule.o +implicit.o +default.o +variable.o +expand.o +function.o +vpath.o +version.o +ar.o +arscan.o +signame.o +remote-stub.o +getopt.o +getopt1.o +glob/libglob.a diff --git a/src/make-3.80/rule.c b/src/make-3.80/rule.c new file mode 100755 index 00000000..e693c022 --- /dev/null +++ b/src/make-3.80/rule.c @@ -0,0 +1,717 @@ +/* Pattern and suffix rule internals for GNU Make. +Copyright (C) 1988,89,90,91,92,93, 1998 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "dep.h" +#include "filedef.h" +#include "job.h" +#include "commands.h" +#include "variable.h" +#include "rule.h" + +static void freerule PARAMS ((struct rule *rule, struct rule *lastrule)); + +/* Chain of all pattern rules. */ + +struct rule *pattern_rules; + +/* Pointer to last rule in the chain, so we can add onto the end. */ + +struct rule *last_pattern_rule; + +/* Number of rules in the chain. */ + +unsigned int num_pattern_rules; + +/* Maximum number of target patterns of any pattern rule. */ + +unsigned int max_pattern_targets; + +/* Maximum number of dependencies of any pattern rule. */ + +unsigned int max_pattern_deps; + +/* Maximum length of the name of a dependencies of any pattern rule. */ + +unsigned int max_pattern_dep_length; + +/* Chain of all pattern-specific variables. */ + +static struct pattern_var *pattern_vars; + +/* Pointer to last struct in the chain, so we can add onto the end. */ + +static struct pattern_var *last_pattern_var; + +/* Pointer to structure for the file .SUFFIXES + whose dependencies are the suffixes to be searched. */ + +struct file *suffix_file; + +/* Maximum length of a suffix. */ + +unsigned int maxsuffix; + +/* Compute the maximum dependency length and maximum number of + dependencies of all implicit rules. Also sets the subdir + flag for a rule when appropriate, possibly removing the rule + completely when appropriate. */ + +void +count_implicit_rule_limits () +{ + char *name; + unsigned int namelen; + register struct rule *rule, *lastrule; + + num_pattern_rules = max_pattern_targets = max_pattern_deps = 0; + max_pattern_dep_length = 0; + + name = 0; + namelen = 0; + rule = pattern_rules; + lastrule = 0; + while (rule != 0) + { + unsigned int ndeps = 0; + register struct dep *dep; + struct rule *next = rule->next; + unsigned int ntargets; + + ++num_pattern_rules; + + ntargets = 0; + while (rule->targets[ntargets] != 0) + ++ntargets; + + if (ntargets > max_pattern_targets) + max_pattern_targets = ntargets; + + for (dep = rule->deps; dep != 0; dep = dep->next) + { + unsigned int len = strlen (dep->name); + +#ifdef VMS + char *p = strrchr (dep->name, ']'); + char *p2; + if (p == 0) + p = strrchr (dep->name, ':'); + p2 = p != 0 ? strchr (dep->name, '%') : 0; +#else + char *p = strrchr (dep->name, '/'); + char *p2 = p != 0 ? strchr (dep->name, '%') : 0; +#endif + ndeps++; + + if (len > max_pattern_dep_length) + max_pattern_dep_length = len; + + if (p != 0 && p2 > p) + { + /* There is a slash before the % in the dep name. + Extract the directory name. */ + if (p == dep->name) + ++p; + if (p - dep->name > namelen) + { + if (name != 0) + free (name); + namelen = p - dep->name; + name = (char *) xmalloc (namelen + 1); + } + bcopy (dep->name, name, p - dep->name); + name[p - dep->name] = '\0'; + + /* In the deps of an implicit rule the `changed' flag + actually indicates that the dependency is in a + nonexistent subdirectory. */ + + dep->changed = !dir_file_exists_p (name, ""); +#ifdef VMS + if (dep->changed && strchr (name, ':') != 0) +#else + if (dep->changed && *name == '/') +#endif + { + /* The name is absolute and the directory does not exist. + This rule can never possibly match, since this dependency + can never possibly exist. So just remove the rule from + the list. */ + freerule (rule, lastrule); + --num_pattern_rules; + goto end_main_loop; + } + } + else + /* This dependency does not reside in a subdirectory. */ + dep->changed = 0; + } + + if (ndeps > max_pattern_deps) + max_pattern_deps = ndeps; + + lastrule = rule; + end_main_loop: + rule = next; + } + + if (name != 0) + free (name); +} + +/* Create a pattern rule from a suffix rule. + TARGET is the target suffix; SOURCE is the source suffix. + CMDS are the commands. + If TARGET is nil, it means the target pattern should be `(%.o)'. + If SOURCE is nil, it means there should be no deps. */ + +static void +convert_suffix_rule (target, source, cmds) + char *target, *source; + struct commands *cmds; +{ + char *targname, *targpercent, *depname; + char **names, **percents; + struct dep *deps; + unsigned int len; + + if (target == 0) + /* Special case: TARGET being nil means we are defining a + `.X.a' suffix rule; the target pattern is always `(%.o)'. */ + { +#ifdef VMS + targname = savestring ("(%.obj)", 7); +#else + targname = savestring ("(%.o)", 5); +#endif + targpercent = targname + 1; + } + else + { + /* Construct the target name. */ + len = strlen (target); + targname = xmalloc (1 + len + 1); + targname[0] = '%'; + bcopy (target, targname + 1, len + 1); + targpercent = targname; + } + + names = (char **) xmalloc (2 * sizeof (char *)); + percents = (char **) alloca (2 * sizeof (char *)); + names[0] = targname; + percents[0] = targpercent; + names[1] = percents[1] = 0; + + if (source == 0) + deps = 0; + else + { + /* Construct the dependency name. */ + len = strlen (source); + depname = xmalloc (1 + len + 1); + depname[0] = '%'; + bcopy (source, depname + 1, len + 1); + deps = (struct dep *) xmalloc (sizeof (struct dep)); + deps->next = 0; + deps->name = depname; + deps->ignore_mtime = 0; + } + + create_pattern_rule (names, percents, 0, deps, cmds, 0); +} + +/* Convert old-style suffix rules to pattern rules. + All rules for the suffixes on the .SUFFIXES list + are converted and added to the chain of pattern rules. */ + +void +convert_to_pattern () +{ + register struct dep *d, *d2; + register struct file *f; + register char *rulename; + register unsigned int slen, s2len; + + /* Compute maximum length of all the suffixes. */ + + maxsuffix = 0; + for (d = suffix_file->deps; d != 0; d = d->next) + { + register unsigned int namelen = strlen (dep_name (d)); + if (namelen > maxsuffix) + maxsuffix = namelen; + } + + rulename = (char *) alloca ((maxsuffix * 2) + 1); + + for (d = suffix_file->deps; d != 0; d = d->next) + { + /* Make a rule that is just the suffix, with no deps or commands. + This rule exists solely to disqualify match-anything rules. */ + convert_suffix_rule (dep_name (d), (char *) 0, (struct commands *) 0); + + f = d->file; + if (f->cmds != 0) + /* Record a pattern for this suffix's null-suffix rule. */ + convert_suffix_rule ("", dep_name (d), f->cmds); + + /* Record a pattern for each of this suffix's two-suffix rules. */ + slen = strlen (dep_name (d)); + bcopy (dep_name (d), rulename, slen); + for (d2 = suffix_file->deps; d2 != 0; d2 = d2->next) + { + s2len = strlen (dep_name (d2)); + + if (slen == s2len && streq (dep_name (d), dep_name (d2))) + continue; + + bcopy (dep_name (d2), rulename + slen, s2len + 1); + f = lookup_file (rulename); + if (f == 0 || f->cmds == 0) + continue; + + if (s2len == 2 && rulename[slen] == '.' && rulename[slen + 1] == 'a') + /* A suffix rule `.X.a:' generates the pattern rule `(%.o): %.X'. + It also generates a normal `%.a: %.X' rule below. */ + convert_suffix_rule ((char *) 0, /* Indicates `(%.o)'. */ + dep_name (d), + f->cmds); + + /* The suffix rule `.X.Y:' is converted + to the pattern rule `%.Y: %.X'. */ + convert_suffix_rule (dep_name (d2), dep_name (d), f->cmds); + } + } +} + + +/* Install the pattern rule RULE (whose fields have been filled in) + at the end of the list (so that any rules previously defined + will take precedence). If this rule duplicates a previous one + (identical target and dependencies), the old one is replaced + if OVERRIDE is nonzero, otherwise this new one is thrown out. + When an old rule is replaced, the new one is put at the end of the + list. Return nonzero if RULE is used; zero if not. */ + +int +new_pattern_rule (rule, override) + register struct rule *rule; + int override; +{ + register struct rule *r, *lastrule; + register unsigned int i, j; + + rule->in_use = 0; + rule->terminal = 0; + + rule->next = 0; + + /* Search for an identical rule. */ + lastrule = 0; + for (r = pattern_rules; r != 0; lastrule = r, r = r->next) + for (i = 0; rule->targets[i] != 0; ++i) + { + for (j = 0; r->targets[j] != 0; ++j) + if (!streq (rule->targets[i], r->targets[j])) + break; + if (r->targets[j] == 0) + /* All the targets matched. */ + { + register struct dep *d, *d2; + for (d = rule->deps, d2 = r->deps; + d != 0 && d2 != 0; d = d->next, d2 = d2->next) + if (!streq (dep_name (d), dep_name (d2))) + break; + if (d == 0 && d2 == 0) + { + /* All the dependencies matched. */ + if (override) + { + /* Remove the old rule. */ + freerule (r, lastrule); + /* Install the new one. */ + if (pattern_rules == 0) + pattern_rules = rule; + else + last_pattern_rule->next = rule; + last_pattern_rule = rule; + + /* We got one. Stop looking. */ + goto matched; + } + else + { + /* The old rule stays intact. Destroy the new one. */ + freerule (rule, (struct rule *) 0); + return 0; + } + } + } + } + + matched:; + + if (r == 0) + { + /* There was no rule to replace. */ + if (pattern_rules == 0) + pattern_rules = rule; + else + last_pattern_rule->next = rule; + last_pattern_rule = rule; + } + + return 1; +} + + +/* Install an implicit pattern rule based on the three text strings + in the structure P points to. These strings come from one of + the arrays of default implicit pattern rules. + TERMINAL specifies what the `terminal' field of the rule should be. */ + +void +install_pattern_rule (p, terminal) + struct pspec *p; + int terminal; +{ + register struct rule *r; + char *ptr; + + r = (struct rule *) xmalloc (sizeof (struct rule)); + + r->targets = (char **) xmalloc (2 * sizeof (char *)); + r->suffixes = (char **) xmalloc (2 * sizeof (char *)); + r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int)); + + r->targets[1] = 0; + r->suffixes[1] = 0; + r->lens[1] = 0; + + r->lens[0] = strlen (p->target); + /* These will all be string literals, but we malloc space for + them anyway because somebody might want to free them later on. */ + r->targets[0] = savestring (p->target, r->lens[0]); + r->suffixes[0] = find_percent (r->targets[0]); + if (r->suffixes[0] == 0) + /* Programmer-out-to-lunch error. */ + abort (); + else + ++r->suffixes[0]; + + ptr = p->dep; + r->deps = (struct dep *) multi_glob (parse_file_seq (&ptr, '\0', + sizeof (struct dep), 1), + sizeof (struct dep)); + + if (new_pattern_rule (r, 0)) + { + r->terminal = terminal; + r->cmds = (struct commands *) xmalloc (sizeof (struct commands)); + r->cmds->fileinfo.filenm = 0; + r->cmds->fileinfo.lineno = 0; + /* These will all be string literals, but we malloc space for them + anyway because somebody might want to free them later. */ + r->cmds->commands = xstrdup (p->commands); + r->cmds->command_lines = 0; + } +} + + +/* Free all the storage used in RULE and take it out of the + pattern_rules chain. LASTRULE is the rule whose next pointer + points to RULE. */ + +static void +freerule (rule, lastrule) + register struct rule *rule, *lastrule; +{ + struct rule *next = rule->next; + register unsigned int i; + register struct dep *dep; + + for (i = 0; rule->targets[i] != 0; ++i) + free (rule->targets[i]); + + dep = rule->deps; + while (dep) + { + struct dep *t; + + t = dep->next; + /* We might leak dep->name here, but I'm not sure how to fix this: I + think that pointer might be shared (e.g., in the file hash?) */ + free ((char *) dep); + dep = t; + } + + free ((char *) rule->targets); + free ((char *) rule->suffixes); + free ((char *) rule->lens); + + /* We can't free the storage for the commands because there + are ways that they could be in more than one place: + * If the commands came from a suffix rule, they could also be in + the `struct file's for other suffix rules or plain targets given + on the same makefile line. + * If two suffixes that together make a two-suffix rule were each + given twice in the .SUFFIXES list, and in the proper order, two + identical pattern rules would be created and the second one would + be discarded here, but both would contain the same `struct commands' + pointer from the `struct file' for the suffix rule. */ + + free ((char *) rule); + + if (pattern_rules == rule) + if (lastrule != 0) + abort (); + else + pattern_rules = next; + else if (lastrule != 0) + lastrule->next = next; + if (last_pattern_rule == rule) + last_pattern_rule = lastrule; +} + +/* Create a new pattern rule with the targets in the nil-terminated + array TARGETS. If TARGET_PERCENTS is not nil, it is an array of + pointers into the elements of TARGETS, where the `%'s are. + The new rule has dependencies DEPS and commands from COMMANDS. + It is a terminal rule if TERMINAL is nonzero. This rule overrides + identical rules with different commands if OVERRIDE is nonzero. + + The storage for TARGETS and its elements is used and must not be freed + until the rule is destroyed. The storage for TARGET_PERCENTS is not used; + it may be freed. */ + +void +create_pattern_rule (targets, target_percents, + terminal, deps, commands, override) + char **targets, **target_percents; + int terminal; + struct dep *deps; + struct commands *commands; + int override; +{ + register struct rule *r = (struct rule *) xmalloc (sizeof (struct rule)); + register unsigned int max_targets, i; + + r->cmds = commands; + r->deps = deps; + r->targets = targets; + + max_targets = 2; + r->lens = (unsigned int *) xmalloc (2 * sizeof (unsigned int)); + r->suffixes = (char **) xmalloc (2 * sizeof (char *)); + for (i = 0; targets[i] != 0; ++i) + { + if (i == max_targets - 1) + { + max_targets += 5; + r->lens = (unsigned int *) + xrealloc ((char *) r->lens, max_targets * sizeof (unsigned int)); + r->suffixes = (char **) + xrealloc ((char *) r->suffixes, max_targets * sizeof (char *)); + } + r->lens[i] = strlen (targets[i]); + r->suffixes[i] = (target_percents == 0 ? find_percent (targets[i]) + : target_percents[i]) + 1; + if (r->suffixes[i] == 0) + abort (); + } + + if (i < max_targets - 1) + { + r->lens = (unsigned int *) xrealloc ((char *) r->lens, + (i + 1) * sizeof (unsigned int)); + r->suffixes = (char **) xrealloc ((char *) r->suffixes, + (i + 1) * sizeof (char *)); + } + + if (new_pattern_rule (r, override)) + r->terminal = terminal; +} + +/* Create a new pattern-specific variable struct. */ + +struct pattern_var * +create_pattern_var (target, suffix) + char *target, *suffix; +{ + register struct pattern_var *p = 0; + unsigned int len = strlen(target); + + /* Look to see if this pattern already exists in the list. */ + for (p = pattern_vars; p != NULL; p = p->next) + if (p->len == len && !strcmp(p->target, target)) + break; + + if (p == 0) + { + p = (struct pattern_var *) xmalloc (sizeof (struct pattern_var)); + if (last_pattern_var != 0) + last_pattern_var->next = p; + else + pattern_vars = p; + last_pattern_var = p; + p->next = 0; + p->target = target; + p->len = len; + p->suffix = suffix + 1; + p->vars = create_new_variable_set(); + } + + return p; +} + +/* Look up a target in the pattern-specific variable list. */ + +struct pattern_var * +lookup_pattern_var (target) + char *target; +{ + struct pattern_var *p; + unsigned int targlen = strlen(target); + + for (p = pattern_vars; p != 0; p = p->next) + { + char *stem; + unsigned int stemlen; + + if (p->len > targlen) + /* It can't possibly match. */ + continue; + + /* From the lengths of the filename and the pattern parts, + find the stem: the part of the filename that matches the %. */ + stem = target + (p->suffix - p->target - 1); + stemlen = targlen - p->len + 1; + + /* Compare the text in the pattern before the stem, if any. */ + if (stem > target && !strneq (p->target, target, stem - target)) + continue; + + /* Compare the text in the pattern after the stem, if any. + We could test simply using streq, but this way we compare the + first two characters immediately. This saves time in the very + common case where the first character matches because it is a + period. */ + if (*p->suffix == stem[stemlen] + && (*p->suffix == '\0' || streq (&p->suffix[1], &stem[stemlen+1]))) + break; + } + + return p; +} + +/* Print the data base of rules. */ + +static void /* Useful to call from gdb. */ +print_rule (r) + struct rule *r; +{ + register unsigned int i; + register struct dep *d; + + for (i = 0; r->targets[i] != 0; ++i) + { + fputs (r->targets[i], stdout); + if (r->targets[i + 1] != 0) + putchar (' '); + else + putchar (':'); + } + if (r->terminal) + putchar (':'); + + for (d = r->deps; d != 0; d = d->next) + printf (" %s", dep_name (d)); + putchar ('\n'); + + if (r->cmds != 0) + print_commands (r->cmds); +} + +void +print_rule_data_base () +{ + register unsigned int rules, terminal; + register struct rule *r; + + puts (_("\n# Implicit Rules")); + + rules = terminal = 0; + for (r = pattern_rules; r != 0; r = r->next) + { + ++rules; + + putchar ('\n'); + print_rule (r); + + if (r->terminal) + ++terminal; + } + + if (rules == 0) + puts (_("\n# No implicit rules.")); + else + { + printf (_("\n# %u implicit rules, %u"), rules, terminal); +#ifndef NO_FLOAT + printf (" (%.1f%%)", (double) terminal / (double) rules * 100.0); +#else + { + int f = (terminal * 1000 + 5) / rules; + printf (" (%d.%d%%)", f/10, f%10); + } +#endif + puts (_(" terminal.")); + } + + if (num_pattern_rules != rules) + { + /* This can happen if a fatal error was detected while reading the + makefiles and thus count_implicit_rule_limits wasn't called yet. */ + if (num_pattern_rules != 0) + fatal (NILF, _("BUG: num_pattern_rules wrong! %u != %u"), + num_pattern_rules, rules); + } + + puts (_("\n# Pattern-specific variable values")); + + { + struct pattern_var *p; + + rules = 0; + for (p = pattern_vars; p != 0; p = p->next) + { + ++rules; + + printf ("\n%s :\n", p->target); + print_variable_set (p->vars->set, "# "); + } + + if (rules == 0) + puts (_("\n# No pattern-specific variable values.")); + else + { + printf (_("\n# %u pattern-specific variable values"), rules); + } + } +} diff --git a/src/make-3.80/rule.h b/src/make-3.80/rule.h new file mode 100755 index 00000000..30cc5449 --- /dev/null +++ b/src/make-3.80/rule.h @@ -0,0 +1,72 @@ +/* Definitions for using pattern rules in GNU Make. +Copyright (C) 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Structure used for pattern rules. */ + +struct rule + { + struct rule *next; + char **targets; /* Targets of the rule. */ + unsigned int *lens; /* Lengths of each target. */ + char **suffixes; /* Suffixes (after `%') of each target. */ + struct dep *deps; /* Dependencies of the rule. */ + struct commands *cmds; /* Commands to execute. */ + char terminal; /* If terminal (double-colon). */ + char in_use; /* If in use by a parent pattern_search. */ + }; + +struct pattern_var + { + struct pattern_var *next; + char *target; + unsigned int len; + char *suffix; + struct variable_set_list *vars; + }; + +/* For calling install_pattern_rule. */ +struct pspec + { + char *target, *dep, *commands; + }; + + +extern struct rule *pattern_rules; +extern struct rule *last_pattern_rule; +extern unsigned int num_pattern_rules; + +extern unsigned int max_pattern_deps; +extern unsigned int max_pattern_targets; +extern unsigned int max_pattern_dep_length; + +extern struct file *suffix_file; +extern unsigned int maxsuffix; + + +extern void install_pattern_rule PARAMS ((struct pspec *p, int terminal)); +extern int new_pattern_rule PARAMS ((struct rule *rule, int override)); +extern struct pattern_var *create_pattern_var PARAMS ((char *target, char *suffix)); +extern struct pattern_var *lookup_pattern_var PARAMS ((char *target)); +extern void count_implicit_rule_limits PARAMS ((void)); +extern void convert_to_pattern PARAMS ((void)); +extern void create_pattern_rule PARAMS ((char **targets, + char **target_percents, int terminal, + struct dep *deps, + struct commands *commands, + int override)); diff --git a/src/make-3.80/signame.c b/src/make-3.80/signame.c new file mode 100755 index 00000000..051d5449 --- /dev/null +++ b/src/make-3.80/signame.c @@ -0,0 +1,255 @@ +/* Convert between signal names and numbers. +Copyright (C) 1990,92,93,95,96,99, 2002 Free Software Foundation, Inc. +This file was part of the GNU C Library, but is now part of GNU make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" + +/* If the system provides strsignal, we don't need it. */ + +#if !defined(HAVE_STRSIGNAL) + +/* If the system provides sys_siglist, we'll use that. + Otherwise create our own. + */ + +#if !defined(SYS_SIGLIST_DECLARED) + +/* Some systems do not define NSIG in . */ +#ifndef NSIG +#ifdef _NSIG +#define NSIG _NSIG +#else +#define NSIG 32 +#endif +#endif + +/* There is too much variation in Sys V signal numbers and names, so + we must initialize them at runtime. */ + +static const char *undoc; + +static const char *sys_siglist[NSIG]; + +/* Table of abbreviations for signals. Note: A given number can + appear more than once with different abbreviations. */ +#define SIG_TABLE_SIZE (NSIG*2) + +typedef struct + { + int number; + const char *abbrev; + } num_abbrev; + +static num_abbrev sig_table[SIG_TABLE_SIZE]; + +/* Number of elements of sig_table used. */ +static int sig_table_nelts = 0; + +/* Enter signal number NUMBER into the tables with ABBREV and NAME. */ + +static void +init_sig (number, abbrev, name) + int number; + const char *abbrev; + const char *name; +{ + /* If this value is ever greater than NSIG it seems like it'd be a bug in + the system headers, but... better safe than sorry. We know, for + example, that this isn't always true on VMS. */ + + if (number >= 0 && number < NSIG) + sys_siglist[number] = name; + + if (sig_table_nelts < SIG_TABLE_SIZE) + { + sig_table[sig_table_nelts].number = number; + sig_table[sig_table_nelts++].abbrev = abbrev; + } +} + +static int +signame_init () +{ + int i; + + undoc = xstrdup (_("unknown signal")); + + /* Initialize signal names. */ + for (i = 0; i < NSIG; i++) + sys_siglist[i] = undoc; + + /* Initialize signal names. */ +#if defined (SIGHUP) + init_sig (SIGHUP, "HUP", _("Hangup")); +#endif +#if defined (SIGINT) + init_sig (SIGINT, "INT", _("Interrupt")); +#endif +#if defined (SIGQUIT) + init_sig (SIGQUIT, "QUIT", _("Quit")); +#endif +#if defined (SIGILL) + init_sig (SIGILL, "ILL", _("Illegal Instruction")); +#endif +#if defined (SIGTRAP) + init_sig (SIGTRAP, "TRAP", _("Trace/breakpoint trap")); +#endif + /* If SIGIOT == SIGABRT, we want to print it as SIGABRT because + SIGABRT is in ANSI and POSIX.1 and SIGIOT isn't. */ +#if defined (SIGABRT) + init_sig (SIGABRT, "ABRT", _("Aborted")); +#endif +#if defined (SIGIOT) + init_sig (SIGIOT, "IOT", _("IOT trap")); +#endif +#if defined (SIGEMT) + init_sig (SIGEMT, "EMT", _("EMT trap")); +#endif +#if defined (SIGFPE) + init_sig (SIGFPE, "FPE", _("Floating point exception")); +#endif +#if defined (SIGKILL) + init_sig (SIGKILL, "KILL", _("Killed")); +#endif +#if defined (SIGBUS) + init_sig (SIGBUS, "BUS", _("Bus error")); +#endif +#if defined (SIGSEGV) + init_sig (SIGSEGV, "SEGV", _("Segmentation fault")); +#endif +#if defined (SIGSYS) + init_sig (SIGSYS, "SYS", _("Bad system call")); +#endif +#if defined (SIGPIPE) + init_sig (SIGPIPE, "PIPE", _("Broken pipe")); +#endif +#if defined (SIGALRM) + init_sig (SIGALRM, "ALRM", _("Alarm clock")); +#endif +#if defined (SIGTERM) + init_sig (SIGTERM, "TERM", _("Terminated")); +#endif +#if defined (SIGUSR1) + init_sig (SIGUSR1, "USR1", _("User defined signal 1")); +#endif +#if defined (SIGUSR2) + init_sig (SIGUSR2, "USR2", _("User defined signal 2")); +#endif + /* If SIGCLD == SIGCHLD, we want to print it as SIGCHLD because that + is what is in POSIX.1. */ +#if defined (SIGCHLD) + init_sig (SIGCHLD, "CHLD", _("Child exited")); +#endif +#if defined (SIGCLD) + init_sig (SIGCLD, "CLD", _("Child exited")); +#endif +#if defined (SIGPWR) + init_sig (SIGPWR, "PWR", _("Power failure")); +#endif +#if defined (SIGTSTP) + init_sig (SIGTSTP, "TSTP", _("Stopped")); +#endif +#if defined (SIGTTIN) + init_sig (SIGTTIN, "TTIN", _("Stopped (tty input)")); +#endif +#if defined (SIGTTOU) + init_sig (SIGTTOU, "TTOU", _("Stopped (tty output)")); +#endif +#if defined (SIGSTOP) + init_sig (SIGSTOP, "STOP", _("Stopped (signal)")); +#endif +#if defined (SIGXCPU) + init_sig (SIGXCPU, "XCPU", _("CPU time limit exceeded")); +#endif +#if defined (SIGXFSZ) + init_sig (SIGXFSZ, "XFSZ", _("File size limit exceeded")); +#endif +#if defined (SIGVTALRM) + init_sig (SIGVTALRM, "VTALRM", _("Virtual timer expired")); +#endif +#if defined (SIGPROF) + init_sig (SIGPROF, "PROF", _("Profiling timer expired")); +#endif +#if defined (SIGWINCH) + /* "Window size changed" might be more accurate, but even if that + is all that it means now, perhaps in the future it will be + extended to cover other kinds of window changes. */ + init_sig (SIGWINCH, "WINCH", _("Window changed")); +#endif +#if defined (SIGCONT) + init_sig (SIGCONT, "CONT", _("Continued")); +#endif +#if defined (SIGURG) + init_sig (SIGURG, "URG", _("Urgent I/O condition")); +#endif +#if defined (SIGIO) + /* "I/O pending" has also been suggested. A disadvantage is + that signal only happens when the process has + asked for it, not everytime I/O is pending. Another disadvantage + is the confusion from giving it a different name than under Unix. */ + init_sig (SIGIO, "IO", _("I/O possible")); +#endif +#if defined (SIGWIND) + init_sig (SIGWIND, "WIND", _("SIGWIND")); +#endif +#if defined (SIGPHONE) + init_sig (SIGPHONE, "PHONE", _("SIGPHONE")); +#endif +#if defined (SIGPOLL) + init_sig (SIGPOLL, "POLL", _("I/O possible")); +#endif +#if defined (SIGLOST) + init_sig (SIGLOST, "LOST", _("Resource lost")); +#endif +#if defined (SIGDANGER) + init_sig (SIGDANGER, "DANGER", _("Danger signal")); +#endif +#if defined (SIGINFO) + init_sig (SIGINFO, "INFO", _("Information request")); +#endif +#if defined (SIGNOFP) + init_sig (SIGNOFP, "NOFP", _("Floating point co-processor not available")); +#endif + + return 1; +} + +#endif /* SYS_SIGLIST_DECLARED */ + + +char * +strsignal (signal) + int signal; +{ + static char buf[] = "Signal 12345678901234567890"; + +#if !defined(SYS_SIGLIST_DECLARED) + static char sig_initted = 0; + + if (!sig_initted) + sig_initted = signame_init (); +#endif + + if (signal > 0 || signal < NSIG) + return (char *) sys_siglist[signal]; + + sprintf (buf, "Signal %d", signal); + return buf; +} + +#endif /* HAVE_STRSIGNAL */ diff --git a/src/make-3.80/subproc.bat b/src/make-3.80/subproc.bat new file mode 100755 index 00000000..d64eeec9 --- /dev/null +++ b/src/make-3.80/subproc.bat @@ -0,0 +1,6 @@ +cd w32\subproc +set MAKE=%2 +set MAKEFILE=%1 +if x%2 == x set MAKE=nmake +%MAKE% /f %MAKEFILE% +cd ..\.. diff --git a/src/make-3.80/variable.c b/src/make-3.80/variable.c new file mode 100755 index 00000000..bb8d8108 --- /dev/null +++ b/src/make-3.80/variable.c @@ -0,0 +1,1263 @@ +/* Internals of variables for GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, +2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "dep.h" +#include "filedef.h" +#include "job.h" +#include "commands.h" +#include "variable.h" +#include "rule.h" +#ifdef WINDOWS32 +#include "pathstuff.h" +#endif +#include "hash.h" + +/* Hash table of all global variable definitions. */ + +static unsigned long +variable_hash_1 (keyv) + const void *keyv; +{ + struct variable const *key = (struct variable const *) keyv; + return_STRING_N_HASH_1 (key->name, key->length); +} + +static unsigned long +variable_hash_2 (keyv) + const void *keyv; +{ + struct variable const *key = (struct variable const *) keyv; + return_STRING_N_HASH_2 (key->name, key->length); +} + +static int +variable_hash_cmp (xv, yv) + const void *xv; + const void *yv; +{ + struct variable const *x = (struct variable const *) xv; + struct variable const *y = (struct variable const *) yv; + int result = x->length - y->length; + if (result) + return result; + return_STRING_N_COMPARE (x->name, y->name, x->length); +} + +#ifndef VARIABLE_BUCKETS +#define VARIABLE_BUCKETS 523 +#endif +#ifndef PERFILE_VARIABLE_BUCKETS +#define PERFILE_VARIABLE_BUCKETS 23 +#endif +#ifndef SMALL_SCOPE_VARIABLE_BUCKETS +#define SMALL_SCOPE_VARIABLE_BUCKETS 13 +#endif + +static struct variable_set global_variable_set; +static struct variable_set_list global_setlist + = { 0, &global_variable_set }; +struct variable_set_list *current_variable_set_list = &global_setlist; + +/* Implement variables. */ + +void +init_hash_global_variable_set () +{ + hash_init (&global_variable_set.table, VARIABLE_BUCKETS, + variable_hash_1, variable_hash_2, variable_hash_cmp); +} + +/* Define variable named NAME with value VALUE in SET. VALUE is copied. + LENGTH is the length of NAME, which does not need to be null-terminated. + ORIGIN specifies the origin of the variable (makefile, command line + or environment). + If RECURSIVE is nonzero a flag is set in the variable saying + that it should be recursively re-expanded. */ + +struct variable * +define_variable_in_set (name, length, value, origin, recursive, set, flocp) + const char *name; + unsigned int length; + char *value; + enum variable_origin origin; + int recursive; + struct variable_set *set; + const struct floc *flocp; +{ + struct variable *v; + struct variable **var_slot; + struct variable var_key; + + if (set == NULL) + set = &global_variable_set; + + var_key.name = (char *) name; + var_key.length = length; + var_slot = (struct variable **) hash_find_slot (&set->table, &var_key); + + if (env_overrides && origin == o_env) + origin = o_env_override; + + v = *var_slot; + if (! HASH_VACANT (v)) + { + if (env_overrides && v->origin == o_env) + /* V came from in the environment. Since it was defined + before the switches were parsed, it wasn't affected by -e. */ + v->origin = o_env_override; + + /* A variable of this name is already defined. + If the old definition is from a stronger source + than this one, don't redefine it. */ + if ((int) origin >= (int) v->origin) + { + if (v->value != 0) + free (v->value); + v->value = xstrdup (value); + if (flocp != 0) + v->fileinfo = *flocp; + else + v->fileinfo.filenm = 0; + v->origin = origin; + v->recursive = recursive; + } + return v; + } + + /* Create a new variable definition and add it to the hash table. */ + + v = (struct variable *) xmalloc (sizeof (struct variable)); + v->name = savestring (name, length); + v->length = length; + hash_insert_at (&set->table, v, var_slot); + v->value = xstrdup (value); + if (flocp != 0) + v->fileinfo = *flocp; + else + v->fileinfo.filenm = 0; + v->origin = origin; + v->recursive = recursive; + v->expanding = 0; + v->exp_count = 0; + v->per_target = 0; + v->append = 0; + v->export = v_default; + + v->exportable = 1; + if (*name != '_' && (*name < 'A' || *name > 'Z') + && (*name < 'a' || *name > 'z')) + v->exportable = 0; + else + { + for (++name; *name != '\0'; ++name) + if (*name != '_' && (*name < 'a' || *name > 'z') + && (*name < 'A' || *name > 'Z') && !ISDIGIT(*name)) + break; + + if (*name != '\0') + v->exportable = 0; + } + + return v; +} + +/* If the variable passed in is "special", handle its special nature. + Currently there are two such variables, both used for introspection: + .VARIABLES expands to a list of all the variables defined in this instance + of make. + .TARGETS expands to a list of all the targets defined in this + instance of make. + Returns the variable reference passed in. */ + +#define EXPANSION_INCREMENT(_l) ((((_l) / 500) + 1) * 500) + +static struct variable * +handle_special_var (var) + struct variable *var; +{ + static unsigned long last_var_count = 0; + + + /* This one actually turns out to be very hard, due to the way the parser + records targets. The way it works is that target information is collected + internally until make knows the target is completely specified. It unitl + it sees that some new construct (a new target or variable) is defined that + it knows the previous one is done. In short, this means that if you do + this: + + all: + + TARGS := $(.TARGETS) + + then $(TARGS) won't contain "all", because it's not until after the + variable is created that the previous target is completed. + + Changing this would be a major pain. I think a less complex way to do it + would be to pre-define the target files as soon as the first line is + parsed, then come back and do the rest of the definition as now. That + would allow $(.TARGETS) to be correct without a major change to the way + the parser works. + + if (streq (var->name, ".TARGETS")) + var->value = build_target_list (var->value); + else + */ + + if (streq (var->name, ".VARIABLES") + && global_variable_set.table.ht_fill != last_var_count) + { + unsigned long max = EXPANSION_INCREMENT (strlen (var->value)); + unsigned long len; + char *p; + struct variable **vp = (struct variable **) global_variable_set.table.ht_vec; + struct variable **end = &vp[global_variable_set.table.ht_size]; + + /* Make sure we have at least MAX bytes in the allocated buffer. */ + var->value = xrealloc (var->value, max); + + /* Walk through the hash of variables, constructing a list of names. */ + p = var->value; + len = 0; + for (; vp < end; ++vp) + if (!HASH_VACANT (*vp)) + { + struct variable *v = *vp; + int l = v->length; + + len += l + 1; + if (len > max) + { + unsigned long off = p - var->value; + + max += EXPANSION_INCREMENT (l + 1); + var->value = xrealloc (var->value, max); + p = &var->value[off]; + } + + bcopy (v->name, p, l); + p += l; + *(p++) = ' '; + } + *(p-1) = '\0'; + + /* Remember how many variables are in our current count. Since we never + remove variables from the list, this is a reliable way to know whether + the list is up to date or needs to be recomputed. */ + + last_var_count = global_variable_set.table.ht_fill; + } + + return var; +} + + +/* Lookup a variable whose name is a string starting at NAME + and with LENGTH chars. NAME need not be null-terminated. + Returns address of the `struct variable' containing all info + on the variable, or nil if no such variable is defined. */ + +struct variable * +lookup_variable (name, length) + const char *name; + unsigned int length; +{ + const struct variable_set_list *setlist; + struct variable var_key; + + var_key.name = (char *) name; + var_key.length = length; + + for (setlist = current_variable_set_list; + setlist != 0; setlist = setlist->next) + { + const struct variable_set *set = setlist->set; + struct variable *v; + + v = (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key); + if (v) + return v->special ? handle_special_var (v) : v; + } + +#ifdef VMS + /* since we don't read envp[] on startup, try to get the + variable via getenv() here. */ + { + char *vname = alloca (length + 1); + char *value; + strncpy (vname, name, length); + vname[length] = 0; + value = getenv (vname); + if (value != 0) + { + char *sptr; + int scnt; + + sptr = value; + scnt = 0; + + while ((sptr = strchr (sptr, '$'))) + { + scnt++; + sptr++; + } + + if (scnt > 0) + { + char *nvalue; + char *nptr; + + nvalue = alloca (strlen (value) + scnt + 1); + sptr = value; + nptr = nvalue; + + while (*sptr) + { + if (*sptr == '$') + { + *nptr++ = '$'; + *nptr++ = '$'; + } + else + { + *nptr++ = *sptr; + } + sptr++; + } + + *nptr = '\0'; + return define_variable (vname, length, nvalue, o_env, 1); + + } + + return define_variable (vname, length, value, o_env, 1); + } + } +#endif /* VMS */ + + return 0; +} + +/* Lookup a variable whose name is a string starting at NAME + and with LENGTH chars in set SET. NAME need not be null-terminated. + Returns address of the `struct variable' containing all info + on the variable, or nil if no such variable is defined. */ + +struct variable * +lookup_variable_in_set (name, length, set) + const char *name; + unsigned int length; + const struct variable_set *set; +{ + struct variable var_key; + + var_key.name = (char *) name; + var_key.length = length; + + return (struct variable *) hash_find_item ((struct hash_table *) &set->table, &var_key); +} + +/* Initialize FILE's variable set list. If FILE already has a variable set + list, the topmost variable set is left intact, but the the rest of the + chain is replaced with FILE->parent's setlist. If FILE is a double-colon + rule, then we will use the "root" double-colon target's variable set as the + parent of FILE's variable set. + + If we're READing a makefile, don't do the pattern variable search now, + since the pattern variable might not have been defined yet. */ + +void +initialize_file_variables (file, reading) + struct file *file; + int reading; +{ + register struct variable_set_list *l = file->variables; + + if (l == 0) + { + l = (struct variable_set_list *) + xmalloc (sizeof (struct variable_set_list)); + l->set = (struct variable_set *) xmalloc (sizeof (struct variable_set)); + hash_init (&l->set->table, PERFILE_VARIABLE_BUCKETS, + variable_hash_1, variable_hash_2, variable_hash_cmp); + file->variables = l; + } + + /* If this is a double-colon, then our "parent" is the "root" target for + this double-colon rule. Since that rule has the same name, parent, + etc. we can just use its variables as the "next" for ours. */ + + if (file->double_colon && file->double_colon != file) + { + initialize_file_variables (file->double_colon, reading); + l->next = file->double_colon->variables; + return; + } + + if (file->parent == 0) + l->next = &global_setlist; + else + { + initialize_file_variables (file->parent, reading); + l->next = file->parent->variables; + } + + /* If we're not reading makefiles and we haven't looked yet, see if + we can find a pattern variable. */ + + if (!reading && !file->pat_searched) + { + struct pattern_var *p = lookup_pattern_var (file->name); + + file->pat_searched = 1; + if (p != 0) + { + /* If we found one, insert it between the current target's + variables and the next set, whatever it is. */ + file->pat_variables = (struct variable_set_list *) + xmalloc (sizeof (struct variable_set_list)); + file->pat_variables->set = p->vars->set; + } + } + + /* If we have a pattern variable match, set it up. */ + + if (file->pat_variables != 0) + { + file->pat_variables->next = l->next; + l->next = file->pat_variables; + } +} + +/* Pop the top set off the current variable set list, + and free all its storage. */ + +static void +free_variable_name_and_value (item) + void *item; +{ + struct variable *v = (struct variable *) item; + free (v->name); + free (v->value); +} + +void +pop_variable_scope () +{ + struct variable_set_list *setlist = current_variable_set_list; + struct variable_set *set = setlist->set; + + current_variable_set_list = setlist->next; + free ((char *) setlist); + + hash_map (&set->table, free_variable_name_and_value); + hash_free (&set->table, 1); + + free ((char *) set); +} + +struct variable_set_list * +create_new_variable_set () +{ + register struct variable_set_list *setlist; + register struct variable_set *set; + + set = (struct variable_set *) xmalloc (sizeof (struct variable_set)); + hash_init (&set->table, SMALL_SCOPE_VARIABLE_BUCKETS, + variable_hash_1, variable_hash_2, variable_hash_cmp); + + setlist = (struct variable_set_list *) + xmalloc (sizeof (struct variable_set_list)); + setlist->set = set; + setlist->next = current_variable_set_list; + + return setlist; +} + +/* Create a new variable set and push it on the current setlist. */ + +struct variable_set_list * +push_new_variable_scope () +{ + return (current_variable_set_list = create_new_variable_set()); +} + +/* Merge SET1 into SET0, freeing unused storage in SET1. */ + +static void +merge_variable_sets (to_set, from_set) + struct variable_set *to_set, *from_set; +{ + struct variable **from_var_slot = (struct variable **) from_set->table.ht_vec; + struct variable **from_var_end = from_var_slot + from_set->table.ht_size; + + for ( ; from_var_slot < from_var_end; from_var_slot++) + if (! HASH_VACANT (*from_var_slot)) + { + struct variable *from_var = *from_var_slot; + struct variable **to_var_slot + = (struct variable **) hash_find_slot (&to_set->table, *from_var_slot); + if (HASH_VACANT (*to_var_slot)) + hash_insert_at (&to_set->table, from_var, to_var_slot); + else + { + /* GKM FIXME: delete in from_set->table */ + free (from_var->value); + free (from_var); + } + } +} + +/* Merge SETLIST1 into SETLIST0, freeing unused storage in SETLIST1. */ + +void +merge_variable_set_lists (setlist0, setlist1) + struct variable_set_list **setlist0, *setlist1; +{ + register struct variable_set_list *list0 = *setlist0; + struct variable_set_list *last0 = 0; + + while (setlist1 != 0 && list0 != 0) + { + struct variable_set_list *next = setlist1; + setlist1 = setlist1->next; + + merge_variable_sets (list0->set, next->set); + + last0 = list0; + list0 = list0->next; + } + + if (setlist1 != 0) + { + if (last0 == 0) + *setlist0 = setlist1; + else + last0->next = setlist1; + } +} + +/* Define the automatic variables, and record the addresses + of their structures so we can change their values quickly. */ + +void +define_automatic_variables () +{ +#ifdef WINDOWS32 + extern char* default_shell; +#else + extern char default_shell[]; +#endif + register struct variable *v; + char buf[200]; + + sprintf (buf, "%u", makelevel); + (void) define_variable (MAKELEVEL_NAME, MAKELEVEL_LENGTH, buf, o_env, 0); + + sprintf (buf, "%s%s%s", + version_string, + (remote_description == 0 || remote_description[0] == '\0') + ? "" : "-", + (remote_description == 0 || remote_description[0] == '\0') + ? "" : remote_description); + (void) define_variable ("MAKE_VERSION", 12, buf, o_default, 0); + +#ifdef __MSDOS__ + /* Allow to specify a special shell just for Make, + and use $COMSPEC as the default $SHELL when appropriate. */ + { + static char shell_str[] = "SHELL"; + const int shlen = sizeof (shell_str) - 1; + struct variable *mshp = lookup_variable ("MAKESHELL", 9); + struct variable *comp = lookup_variable ("COMSPEC", 7); + + /* Make $MAKESHELL override $SHELL even if -e is in effect. */ + if (mshp) + (void) define_variable (shell_str, shlen, + mshp->value, o_env_override, 0); + else if (comp) + { + /* $COMSPEC shouldn't override $SHELL. */ + struct variable *shp = lookup_variable (shell_str, shlen); + + if (!shp) + (void) define_variable (shell_str, shlen, comp->value, o_env, 0); + } + } +#endif + + /* This won't override any definition, but it + will provide one if there isn't one there. */ + v = define_variable ("SHELL", 5, default_shell, o_default, 0); + v->export = v_export; /* Always export SHELL. */ + + /* On MSDOS we do use SHELL from environment, since + it isn't a standard environment variable on MSDOS, + so whoever sets it, does that on purpose. */ +#ifndef __MSDOS__ + /* Don't let SHELL come from the environment. */ + if (*v->value == '\0' || v->origin == o_env || v->origin == o_env_override) + { + free (v->value); + v->origin = o_file; + v->value = xstrdup (default_shell); + } +#endif + + /* Make sure MAKEFILES gets exported if it is set. */ + v = define_variable ("MAKEFILES", 9, "", o_default, 0); + v->export = v_ifset; + + /* Define the magic D and F variables in terms of + the automatic variables they are variations of. */ + +#ifdef VMS + define_variable ("@D", 2, "$(dir $@)", o_automatic, 1); + define_variable ("%D", 2, "$(dir $%)", o_automatic, 1); + define_variable ("*D", 2, "$(dir $*)", o_automatic, 1); + define_variable ("variables; + + hash_init (&table, VARIABLE_BUCKETS, + variable_hash_1, variable_hash_2, variable_hash_cmp); + + /* Run through all the variable sets in the list, + accumulating variables in TABLE. */ + for (s = set_list; s != 0; s = s->next) + { + struct variable_set *set = s->set; + v_slot = (struct variable **) set->table.ht_vec; + v_end = v_slot + set->table.ht_size; + for ( ; v_slot < v_end; v_slot++) + if (! HASH_VACANT (*v_slot)) + { + struct variable **new_slot; + struct variable *v = *v_slot; + + /* If this is a per-target variable and it hasn't been touched + already then look up the global version and take its export + value. */ + if (v->per_target && v->export == v_default) + { + struct variable *gv; + + gv = lookup_variable_in_set (v->name, strlen(v->name), + &global_variable_set); + if (gv) + v->export = gv->export; + } + + switch (v->export) + { + case v_default: + if (v->origin == o_default || v->origin == o_automatic) + /* Only export default variables by explicit request. */ + continue; + + /* The variable doesn't have a name that can be exported. */ + if (! v->exportable) + continue; + + if (! export_all_variables + && v->origin != o_command + && v->origin != o_env && v->origin != o_env_override) + continue; + break; + + case v_export: + break; + + case v_noexport: + continue; + + case v_ifset: + if (v->origin == o_default) + continue; + break; + } + + new_slot = (struct variable **) hash_find_slot (&table, v); + if (HASH_VACANT (*new_slot)) + hash_insert_at (&table, v, new_slot); + } + } + + makelevel_key.name = MAKELEVEL_NAME; + makelevel_key.length = MAKELEVEL_LENGTH; + hash_delete (&table, &makelevel_key); + + result = result_0 = (char **) xmalloc ((table.ht_fill + 2) * sizeof (char *)); + + v_slot = (struct variable **) table.ht_vec; + v_end = v_slot + table.ht_size; + for ( ; v_slot < v_end; v_slot++) + if (! HASH_VACANT (*v_slot)) + { + struct variable *v = *v_slot; + + /* If V is recursively expanded and didn't come from the environment, + expand its value. If it came from the environment, it should + go back into the environment unchanged. */ + if (v->recursive + && v->origin != o_env && v->origin != o_env_override) + { + char *value = recursively_expand_for_file (v, file); +#ifdef WINDOWS32 + if (strcmp(v->name, "Path") == 0 || + strcmp(v->name, "PATH") == 0) + convert_Path_to_windows32(value, ';'); +#endif + *result++ = concat (v->name, "=", value); + free (value); + } + else + { +#ifdef WINDOWS32 + if (strcmp(v->name, "Path") == 0 || + strcmp(v->name, "PATH") == 0) + convert_Path_to_windows32(v->value, ';'); +#endif + *result++ = concat (v->name, "=", v->value); + } + } + + *result = (char *) xmalloc (100); + (void) sprintf (*result, "%s=%u", MAKELEVEL_NAME, makelevel + 1); + *++result = 0; + + hash_free (&table, 0); + + return result_0; +} + +/* Given a variable, a value, and a flavor, define the variable. + See the try_variable_definition() function for details on the parameters. */ + +struct variable * +do_variable_definition (flocp, varname, value, origin, flavor, target_var) + const struct floc *flocp; + const char *varname; + char *value; + enum variable_origin origin; + enum variable_flavor flavor; + int target_var; +{ + char *p, *alloc_value = NULL; + struct variable *v; + int append = 0; + + /* Calculate the variable's new value in VALUE. */ + + switch (flavor) + { + default: + case f_bogus: + /* Should not be possible. */ + abort (); + case f_simple: + /* A simple variable definition "var := value". Expand the value. + We have to allocate memory since otherwise it'll clobber the + variable buffer, and we may still need that if we're looking at a + target-specific variable. */ + p = alloc_value = allocated_variable_expand (value); + break; + case f_conditional: + /* A conditional variable definition "var ?= value". + The value is set IFF the variable is not defined yet. */ + v = lookup_variable (varname, strlen (varname)); + if (v) + return v; + + flavor = f_recursive; + /* FALLTHROUGH */ + case f_recursive: + /* A recursive variable definition "var = value". + The value is used verbatim. */ + p = value; + break; + case f_append: + { + /* If we have += but we're in a target variable context, we want to + append only with other variables in the context of this target. */ + if (target_var) + { + append = 1; + v = lookup_variable_in_set (varname, strlen (varname), + current_variable_set_list->set); + } + else + v = lookup_variable (varname, strlen (varname)); + + if (v == 0) + { + /* There was no old value. + This becomes a normal recursive definition. */ + p = value; + flavor = f_recursive; + } + else + { + /* Paste the old and new values together in VALUE. */ + + unsigned int oldlen, vallen; + char *val; + + val = value; + if (v->recursive) + /* The previous definition of the variable was recursive. + The new value is the unexpanded old and new values. */ + flavor = f_recursive; + else + /* The previous definition of the variable was simple. + The new value comes from the old value, which was expanded + when it was set; and from the expanded new value. Allocate + memory for the expansion as we may still need the rest of the + buffer if we're looking at a target-specific variable. */ + val = alloc_value = allocated_variable_expand (val); + + oldlen = strlen (v->value); + vallen = strlen (val); + p = (char *) alloca (oldlen + 1 + vallen + 1); + bcopy (v->value, p, oldlen); + p[oldlen] = ' '; + bcopy (val, &p[oldlen + 1], vallen + 1); + } + } + } + +#ifdef __MSDOS__ + /* Many Unix Makefiles include a line saying "SHELL=/bin/sh", but + non-Unix systems don't conform to this default configuration (in + fact, most of them don't even have `/bin'). On the other hand, + $SHELL in the environment, if set, points to the real pathname of + the shell. + Therefore, we generally won't let lines like "SHELL=/bin/sh" from + the Makefile override $SHELL from the environment. But first, we + look for the basename of the shell in the directory where SHELL= + points, and along the $PATH; if it is found in any of these places, + we define $SHELL to be the actual pathname of the shell. Thus, if + you have bash.exe installed as d:/unix/bash.exe, and d:/unix is on + your $PATH, then SHELL=/usr/local/bin/bash will have the effect of + defining SHELL to be "d:/unix/bash.exe". */ + if ((origin == o_file || origin == o_override) + && strcmp (varname, "SHELL") == 0) + { + char shellpath[PATH_MAX]; + extern char * __dosexec_find_on_path (const char *, char *[], char *); + + /* See if we can find "/bin/sh.exe", "/bin/sh.com", etc. */ + if (__dosexec_find_on_path (p, (char **)0, shellpath)) + { + char *p; + + for (p = shellpath; *p; p++) + { + if (*p == '\\') + *p = '/'; + } + v = define_variable_loc (varname, strlen (varname), + shellpath, origin, flavor == f_recursive, + flocp); + } + else + { + char *shellbase, *bslash; + struct variable *pathv = lookup_variable ("PATH", 4); + char *path_string; + char *fake_env[2]; + size_t pathlen = 0; + + shellbase = strrchr (p, '/'); + bslash = strrchr (p, '\\'); + if (!shellbase || bslash > shellbase) + shellbase = bslash; + if (!shellbase && p[1] == ':') + shellbase = p + 1; + if (shellbase) + shellbase++; + else + shellbase = p; + + /* Search for the basename of the shell (with standard + executable extensions) along the $PATH. */ + if (pathv) + pathlen = strlen (pathv->value); + path_string = (char *)xmalloc (5 + pathlen + 2 + 1); + /* On MSDOS, current directory is considered as part of $PATH. */ + sprintf (path_string, "PATH=.;%s", pathv ? pathv->value : ""); + fake_env[0] = path_string; + fake_env[1] = (char *)0; + if (__dosexec_find_on_path (shellbase, fake_env, shellpath)) + { + char *p; + + for (p = shellpath; *p; p++) + { + if (*p == '\\') + *p = '/'; + } + v = define_variable_loc (varname, strlen (varname), + shellpath, origin, + flavor == f_recursive, flocp); + } + else + v = lookup_variable (varname, strlen (varname)); + + free (path_string); + } + } + else +#endif /* __MSDOS__ */ +#ifdef WINDOWS32 + if ((origin == o_file || origin == o_override) && streq (varname, "SHELL")) + { + extern char *default_shell; + + /* Call shell locator function. If it returns TRUE, then + set no_default_sh_exe to indicate sh was found and + set new value for SHELL variable. */ + + if (find_and_set_default_shell (p)) + { + v = define_variable_in_set (varname, strlen (varname), default_shell, + origin, flavor == f_recursive, + (target_var + ? current_variable_set_list->set + : NULL), + flocp); + no_default_sh_exe = 0; + } + else + v = lookup_variable (varname, strlen (varname)); + } + else +#endif + + /* If we are defining variables inside an $(eval ...), we might have a + different variable context pushed, not the global context (maybe we're + inside a $(call ...) or something. Since this function is only ever + invoked in places where we want to define globally visible variables, + make sure we define this variable in the global set. */ + + v = define_variable_in_set (varname, strlen (varname), p, + origin, flavor == f_recursive, + (target_var + ? current_variable_set_list->set : NULL), + flocp); + v->append = append; + + if (alloc_value) + free (alloc_value); + + return v; +} + +/* Try to interpret LINE (a null-terminated string) as a variable definition. + + ORIGIN may be o_file, o_override, o_env, o_env_override, + or o_command specifying that the variable definition comes + from a makefile, an override directive, the environment with + or without the -e switch, or the command line. + + See the comments for parse_variable_definition(). + + If LINE was recognized as a variable definition, a pointer to its `struct + variable' is returned. If LINE is not a variable definition, NULL is + returned. */ + +struct variable * +try_variable_definition (flocp, line, origin, target_var) + const struct floc *flocp; + char *line; + enum variable_origin origin; + int target_var; +{ + register int c; + register char *p = line; + register char *beg; + register char *end; + enum variable_flavor flavor = f_bogus; + char *name, *expanded_name; + struct variable *v; + + while (1) + { + c = *p++; + if (c == '\0' || c == '#') + return 0; + if (c == '=') + { + end = p - 1; + flavor = f_recursive; + break; + } + else if (c == ':') + if (*p == '=') + { + end = p++ - 1; + flavor = f_simple; + break; + } + else + /* A colon other than := is a rule line, not a variable defn. */ + return 0; + else if (c == '+' && *p == '=') + { + end = p++ - 1; + flavor = f_append; + break; + } + else if (c == '?' && *p == '=') + { + end = p++ - 1; + flavor = f_conditional; + break; + } + else if (c == '$') + { + /* This might begin a variable expansion reference. Make sure we + don't misrecognize chars inside the reference as =, := or +=. */ + char closeparen; + int count; + c = *p++; + if (c == '(') + closeparen = ')'; + else if (c == '{') + closeparen = '}'; + else + continue; /* Nope. */ + + /* P now points past the opening paren or brace. + Count parens or braces until it is matched. */ + count = 0; + for (; *p != '\0'; ++p) + { + if (*p == c) + ++count; + else if (*p == closeparen && --count < 0) + { + ++p; + break; + } + } + } + } + + beg = next_token (line); + while (end > beg && isblank ((unsigned char)end[-1])) + --end; + p = next_token (p); + + /* Expand the name, so "$(foo)bar = baz" works. */ + name = (char *) alloca (end - beg + 1); + bcopy (beg, name, end - beg); + name[end - beg] = '\0'; + expanded_name = allocated_variable_expand (name); + + if (expanded_name[0] == '\0') + fatal (flocp, _("empty variable name")); + + v = do_variable_definition (flocp, expanded_name, p, + origin, flavor, target_var); + + free (expanded_name); + + return v; +} + +/* Print information for variable V, prefixing it with PREFIX. */ + +static void +print_variable (v, prefix) + register struct variable *v; + char *prefix; +{ + const char *origin; + + switch (v->origin) + { + case o_default: + origin = _("default"); + break; + case o_env: + origin = _("environment"); + break; + case o_file: + origin = _("makefile"); + break; + case o_env_override: + origin = _("environment under -e"); + break; + case o_command: + origin = _("command line"); + break; + case o_override: + origin = _("`override' directive"); + break; + case o_automatic: + origin = _("automatic"); + break; + case o_invalid: + default: + abort (); + } + fputs ("# ", stdout); + fputs (origin, stdout); + if (v->fileinfo.filenm) + printf (_(" (from `%s', line %lu)"), + v->fileinfo.filenm, v->fileinfo.lineno); + putchar ('\n'); + fputs (prefix, stdout); + + /* Is this a `define'? */ + if (v->recursive && strchr (v->value, '\n') != 0) + printf ("define %s\n%s\nendef\n", v->name, v->value); + else + { + register char *p; + + printf ("%s %s= ", v->name, v->recursive ? v->append ? "+" : "" : ":"); + + /* Check if the value is just whitespace. */ + p = next_token (v->value); + if (p != v->value && *p == '\0') + /* All whitespace. */ + printf ("$(subst ,,%s)", v->value); + else if (v->recursive) + fputs (v->value, stdout); + else + /* Double up dollar signs. */ + for (p = v->value; *p != '\0'; ++p) + { + if (*p == '$') + putchar ('$'); + putchar (*p); + } + putchar ('\n'); + } +} + + +/* Print all the variables in SET. PREFIX is printed before + the actual variable definitions (everything else is comments). */ + +void +print_variable_set (set, prefix) + register struct variable_set *set; + char *prefix; +{ + hash_map_arg (&set->table, print_variable, prefix); + + fputs (_("# variable set hash-table stats:\n"), stdout); + fputs ("# ", stdout); + hash_print_stats (&set->table, stdout); + putc ('\n', stdout); +} + +/* Print the data base of variables. */ + +void +print_variable_data_base () +{ + puts (_("\n# Variables\n")); + + print_variable_set (&global_variable_set, ""); +} + + +/* Print all the local variables of FILE. */ + +void +print_file_variables (file) + struct file *file; +{ + if (file->variables != 0) + print_variable_set (file->variables->set, "# "); +} + +#ifdef WINDOWS32 +void +sync_Path_environment(void) +{ + char* path = allocated_variable_expand("$(Path)"); + static char* environ_path = NULL; + + if (!path) + return; + + /* + * If done this before, don't leak memory unnecessarily. + * Free the previous entry before allocating new one. + */ + if (environ_path) + free(environ_path); + + /* + * Create something WINDOWS32 world can grok + */ + convert_Path_to_windows32(path, ';'); + environ_path = concat("Path", "=", path); + putenv(environ_path); + free(path); +} +#endif diff --git a/src/make-3.80/variable.h b/src/make-3.80/variable.h new file mode 100755 index 00000000..d9cd7f7c --- /dev/null +++ b/src/make-3.80/variable.h @@ -0,0 +1,183 @@ +/* Definitions for using variables in GNU Make. +Copyright (C) 1988, 1989, 1990, 1991, 1992, 2002 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "hash.h" + +/* Codes in a variable definition saying where the definition came from. + Increasing numeric values signify less-overridable definitions. */ +enum variable_origin + { + o_default, /* Variable from the default set. */ + o_env, /* Variable from environment. */ + o_file, /* Variable given in a makefile. */ + o_env_override, /* Variable from environment, if -e. */ + o_command, /* Variable given by user. */ + o_override, /* Variable from an `override' directive. */ + o_automatic, /* Automatic variable -- cannot be set. */ + o_invalid /* Core dump time. */ + }; + +enum variable_flavor + { + f_bogus, /* Bogus (error) */ + f_simple, /* Simple definition (:=) */ + f_recursive, /* Recursive definition (=) */ + f_append, /* Appending definition (+=) */ + f_conditional /* Conditional definition (?=) */ + }; + +/* Structure that represents one variable definition. + Each bucket of the hash table is a chain of these, + chained through `next'. */ + +#define EXP_COUNT_BITS 15 /* This gets all the bitfields into 32 bits */ + +#define EXP_COUNT_MAX ((1<1, allow this many self-referential + expansions. */ + + enum variable_origin + origin ENUM_BITFIELD (3); /* Variable origin. */ + + unsigned int exportable:1; /* Nonzero if the variable _could_ be + exported. */ + enum variable_export + { + v_export, /* Export this variable. */ + v_noexport, /* Don't export this variable. */ + v_ifset, /* Export it if it has a non-default value. */ + v_default /* Decide in target_environment. */ + } export ENUM_BITFIELD (2); + }; + +/* Structure that represents a variable set. */ + +struct variable_set + { + struct hash_table table; /* Hash table of variables. */ + }; + +/* Structure that represents a list of variable sets. */ + +struct variable_set_list + { + struct variable_set_list *next; /* Link in the chain. */ + struct variable_set *set; /* Variable set. */ + }; + +extern char *variable_buffer; +extern struct variable_set_list *current_variable_set_list; + +/* expand.c */ +extern char *variable_buffer_output PARAMS ((char *ptr, char *string, unsigned int length)); +extern char *variable_expand PARAMS ((char *line)); +extern char *allocated_variable_expand_for_file PARAMS ((char *line, struct file *file)); +#define allocated_variable_expand(line) \ + allocated_variable_expand_for_file (line, (struct file *) 0) +extern char *expand_argument PARAMS ((char *str, char *end)); +extern char *variable_expand_string PARAMS ((char *line, char *string, + long length)); + +/* function.c */ +extern int handle_function PARAMS ((char **op, char **stringp)); +extern int pattern_matches PARAMS ((char *pattern, char *percent, char *str)); +extern char *subst_expand PARAMS ((char *o, char *text, char *subst, char *replace, + unsigned int slen, unsigned int rlen, int by_word, int suffix_only)); +extern char *patsubst_expand PARAMS ((char *o, char *text, char *pattern, char *replace, + char *pattern_percent, char *replace_percent)); + +/* expand.c */ +extern char *recursively_expand_for_file PARAMS ((struct variable *v, + struct file *file)); +#define recursively_expand(v) recursively_expand_for_file (v, NULL) + +/* variable.c */ +extern struct variable_set_list *create_new_variable_set PARAMS ((void)); +extern struct variable_set_list *push_new_variable_scope PARAMS ((void)); +extern void pop_variable_scope PARAMS ((void)); +extern void define_automatic_variables PARAMS ((void)); +extern void initialize_file_variables PARAMS ((struct file *file, int read)); +extern void print_file_variables PARAMS ((struct file *file)); +extern void print_variable_set PARAMS ((struct variable_set *set, char *prefix)); +extern void merge_variable_set_lists PARAMS ((struct variable_set_list **setlist0, struct variable_set_list *setlist1)); +extern struct variable *do_variable_definition PARAMS ((const struct floc *flocp, const char *name, char *value, enum variable_origin origin, enum variable_flavor flavor, int target_var)); +extern struct variable *try_variable_definition PARAMS ((const struct floc *flocp, char *line, enum variable_origin origin, int target_var)); +extern void init_hash_global_variable_set PARAMS ((void)); +extern void hash_init_function_table PARAMS ((void)); +extern struct variable *lookup_variable PARAMS ((const char *name, unsigned int length)); +extern struct variable *lookup_variable_in_set PARAMS ((const char *name, + unsigned int length, + const struct variable_set *set)); + +extern struct variable *define_variable_in_set + PARAMS ((const char *name, unsigned int length, char *value, + enum variable_origin origin, int recursive, + struct variable_set *set, const struct floc *flocp)); + +/* Define a variable in the current variable set. */ + +#define define_variable(n,l,v,o,r) \ + define_variable_in_set((n),(l),(v),(o),(r),\ + current_variable_set_list->set,NILF) + +/* Define a variable with a location in the current variable set. */ + +#define define_variable_loc(n,l,v,o,r,f) \ + define_variable_in_set((n),(l),(v),(o),(r),\ + current_variable_set_list->set,(f)) + +/* Define a variable with a location in the global variable set. */ + +#define define_variable_global(n,l,v,o,r,f) \ + define_variable_in_set((n),(l),(v),(o),(r),NULL,(f)) + +/* Define a variable in FILE's variable set. */ + +#define define_variable_for_file(n,l,v,o,r,f) \ + define_variable_in_set((n),(l),(v),(o),(r),(f)->variables->set,NILF) + +/* Warn that NAME is an undefined variable. */ + +#define warn_undefined(n,l) do{\ + if (warn_undefined_variables_flag) \ + error (reading_file, \ + _("warning: undefined variable `%.*s'"), \ + (int)(l), (n)); \ + }while(0) + +extern char **target_environment PARAMS ((struct file *file)); + +extern int export_all_variables; + +#define MAKELEVEL_NAME "MAKELEVEL" +#define MAKELEVEL_LENGTH (sizeof (MAKELEVEL_NAME) - 1) diff --git a/src/make-3.80/version.c b/src/make-3.80/version.c new file mode 100755 index 00000000..1918b6f7 --- /dev/null +++ b/src/make-3.80/version.c @@ -0,0 +1,17 @@ +/* We use instead of "config.h" so that a compilation + using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h + (which it would do because make.h was found in $srcdir). */ +#include + +#ifndef MAKE_HOST +# define MAKE_HOST "unknown" +#endif + +char *version_string = VERSION; +char *make_host = MAKE_HOST; + +/* + Local variables: + version-control: never + End: + */ diff --git a/src/make-3.80/vmsdir.h b/src/make-3.80/vmsdir.h new file mode 100755 index 00000000..59034759 --- /dev/null +++ b/src/make-3.80/vmsdir.h @@ -0,0 +1,61 @@ +/* dirent.h for vms */ + +#ifndef VMSDIR_H +#define VMSDIR_H + +#include + +#define MAXNAMLEN 255 + +#ifndef __DECC +#if !defined (__GNUC__) && !defined (__ALPHA) +typedef unsigned long u_long; +typedef unsigned short u_short; +#endif +#endif + +struct direct +{ + off_t d_off; + u_long d_fileno; + u_short d_reclen; + u_short d_namlen; + char d_name[MAXNAMLEN + 1]; +}; + +#undef DIRSIZ +#define DIRSIZ(dp) \ + (((sizeof (struct direct) \ + - (MAXNAMLEN+1) \ + + ((dp)->d_namlen+1)) \ + + 3) & ~3) + +#define d_ino d_fileno /* compatability */ + + +/* + * Definitions for library routines operating on directories. + */ + +typedef struct DIR +{ + struct direct dir; + char d_result[MAXNAMLEN + 1]; +#if defined (__ALPHA) || defined (__DECC) + struct FAB fab; +#else + struct fabdef fab; +#endif +} DIR; + +#ifndef NULL +#define NULL 0 +#endif + +extern DIR *opendir PARAMS (()); +extern struct direct *readdir PARAMS ((DIR *dfd)); +#define rewinddir(dirp) seekdir((dirp), (long)0) +extern int closedir PARAMS ((DIR *dfd)); +extern char *vmsify PARAMS ((char *name, int type)); + +#endif /* VMSDIR_H */ diff --git a/src/make-3.80/vmsfunctions.c b/src/make-3.80/vmsfunctions.c new file mode 100755 index 00000000..f6708cc1 --- /dev/null +++ b/src/make-3.80/vmsfunctions.c @@ -0,0 +1,261 @@ +/* vmsfunctions.c */ + +#include "make.h" +#include "debug.h" + +#ifdef __DECC +#include +#endif +#include +#include +#include +#include +#include +#include "vmsdir.h" + +#ifdef HAVE_VMSDIR_H + +DIR * +opendir (dspec) + char *dspec; +{ + struct DIR *dir = (struct DIR *)xmalloc (sizeof (struct DIR)); + struct NAM *dnam = (struct NAM *)xmalloc (sizeof (struct NAM)); + struct FAB *dfab = &dir->fab; + char *searchspec = (char *)xmalloc (MAXNAMLEN + 1); + + memset (dir, 0, sizeof *dir); + + *dfab = cc$rms_fab; + *dnam = cc$rms_nam; + sprintf (searchspec, "%s*.*;", dspec); + + dfab->fab$l_fna = searchspec; + dfab->fab$b_fns = strlen (searchspec); + dfab->fab$l_nam = dnam; + + *dnam = cc$rms_nam; + dnam->nam$l_esa = searchspec; + dnam->nam$b_ess = MAXNAMLEN; + + if (! (sys$parse (dfab) & 1)) + { + free (dir); + free (dnam); + free (searchspec); + return (NULL); + } + + return dir; +} + +#define uppercasify(str) \ + do \ + { \ + char *tmp; \ + for (tmp = (str); *tmp != '\0'; tmp++) \ + if (islower ((unsigned char)*tmp)) \ + *tmp = toupper ((unsigned char)*tmp); \ + } \ + while (0) + +struct direct * +readdir (dir) + DIR * dir; +{ + struct FAB *dfab = &dir->fab; + struct NAM *dnam = (struct NAM *)(dfab->fab$l_nam); + struct direct *dentry = &dir->dir; + int i; + + memset (dentry, 0, sizeof *dentry); + + dnam->nam$l_rsa = dir->d_result; + dnam->nam$b_rss = MAXNAMLEN; + + DB (DB_VERBOSE, (".")); + + if (!((i = sys$search (dfab)) & 1)) + { + DB (DB_VERBOSE, (_("sys$search failed with %d\n"), i)); + return (NULL); + } + + dentry->d_off = 0; + if (dnam->nam$w_fid == 0) + dentry->d_fileno = 1; + else + dentry->d_fileno = dnam->nam$w_fid[0] + (dnam->nam$w_fid[1] << 16); + + dentry->d_reclen = sizeof (struct direct); + dentry->d_namlen = dnam->nam$b_name + dnam->nam$b_type; + strncpy (dentry->d_name, dnam->nam$l_name, dentry->d_namlen); + dentry->d_name[dentry->d_namlen] = '\0'; + uppercasify (dentry->d_name); + + return (dentry); +} + +int +closedir (dir) + DIR *dir; +{ + if (dir != NULL) + { + struct FAB *dfab = &dir->fab; + struct NAM *dnam = (struct NAM *)(dfab->fab$l_nam); + if (dnam != NULL) + free (dnam->nam$l_esa); + free (dnam); + free (dir); + } + + return 0; +} +#endif /* compiled for OpenVMS prior to V7.x */ + +char * +getwd (cwd) + char *cwd; +{ + static char buf[512]; + + if (cwd) + return (getcwd (cwd, 512)); + else + return (getcwd (buf, 512)); +} + +int +vms_stat (name, buf) + char *name; + struct stat *buf; +{ + int status; + int i; + + static struct FAB Fab; + static struct NAM Nam; + static struct fibdef Fib; /* short fib */ + static struct dsc$descriptor FibDesc = + { sizeof (Fib), DSC$K_DTYPE_Z, DSC$K_CLASS_S, (char *) &Fib }; + static struct dsc$descriptor_s DevDesc = + { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, &Nam.nam$t_dvi[1] }; + static char EName[NAM$C_MAXRSS]; + static char RName[NAM$C_MAXRSS]; + static struct dsc$descriptor_s FileName = + { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 }; + static struct dsc$descriptor_s string = + { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 }; + static unsigned long Rdate[2]; + static unsigned long Cdate[2]; + static struct atrdef Atr[] = + { +#if defined(VAX) + /* Revision date */ + { sizeof (Rdate), ATR$C_REVDATE, (unsigned int) &Rdate[0] }, + /* Creation date */ + { sizeof (Cdate), ATR$C_CREDATE, (unsigned int) &Cdate[0] }, +#else + /* Revision date */ + { sizeof (Rdate), ATR$C_REVDATE, &Rdate[0] }, + /* Creation date */ + { sizeof (Cdate), ATR$C_CREDATE, &Cdate[0]}, +#endif + { 0, 0, 0 } + }; + static short int DevChan; + static short int iosb[4]; + + name = vmsify (name, 0); + + /* initialize RMS structures, we need a NAM to retrieve the FID */ + Fab = cc$rms_fab; + Fab.fab$l_fna = name; /* name of file */ + Fab.fab$b_fns = strlen (name); + Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */ + + Nam = cc$rms_nam; + Nam.nam$l_esa = EName; /* expanded filename */ + Nam.nam$b_ess = sizeof (EName); + Nam.nam$l_rsa = RName; /* resultant filename */ + Nam.nam$b_rss = sizeof (RName); + + /* do $PARSE and $SEARCH here */ + status = sys$parse (&Fab); + if (!(status & 1)) + return -1; + + DevDesc.dsc$w_length = Nam.nam$t_dvi[0]; + status = sys$assign (&DevDesc, &DevChan, 0, 0); + if (!(status & 1)) + return -1; + + FileName.dsc$a_pointer = Nam.nam$l_name; + FileName.dsc$w_length = Nam.nam$b_name + Nam.nam$b_type + Nam.nam$b_ver; + + /* Initialize the FIB */ + for (i = 0; i < 3; i++) + { +#ifndef __VAXC + Fib.fib$w_fid[i] = Nam.nam$w_fid[i]; + Fib.fib$w_did[i] = Nam.nam$w_did[i]; +#else + Fib.fib$r_fid_overlay.fib$w_fid[i] = Nam.nam$w_fid[i]; + Fib.fib$r_did_overlay.fib$w_did[i] = Nam.nam$w_did[i]; +#endif + } + + status = sys$qiow (0, DevChan, IO$_ACCESS, &iosb, 0, 0, + &FibDesc, &FileName, 0, 0, &Atr, 0); + sys$dassgn (DevChan); + if (!(status & 1)) + return -1; + status = iosb[0]; + if (!(status & 1)) + return -1; + + status = stat (name, buf); + if (status) + return -1; + + buf->st_mtime = ((Rdate[0] >> 24) & 0xff) + ((Rdate[1] << 8) & 0xffffff00); + buf->st_ctime = ((Cdate[0] >> 24) & 0xff) + ((Cdate[1] << 8) & 0xffffff00); + + return 0; +} + +char * +cvt_time (tval) + unsigned long tval; +{ + static long int date[2]; + static char str[27]; + static struct dsc$descriptor date_str = + { 26, DSC$K_DTYPE_T, DSC$K_CLASS_S, str }; + + date[0] = (tval & 0xff) << 24; + date[1] = ((tval >> 8) & 0xffffff); + + if ((date[0] == 0) && (date[1] == 0)) + return ("never"); + + sys$asctim (0, &date_str, date, 0); + str[26] = '\0'; + + return (str); +} + +int +strcmpi (s1, s2) + const char *s1; + const char *s2; +{ + while (*s1 != '\0' && toupper(*s1) == toupper(*s2)) + { + s1++; + s2++; + } + + return toupper(*(unsigned char *) s1) - toupper(*(unsigned char *) s2); +} diff --git a/src/make-3.80/vmsify.c b/src/make-3.80/vmsify.c new file mode 100755 index 00000000..f7871bb2 --- /dev/null +++ b/src/make-3.80/vmsify.c @@ -0,0 +1,981 @@ +/* + vmsify.c + + Module for vms <-> unix file name conversion + + Written by Klaus Kämpf (kkaempf@progis.de) + of proGIS Software, Aachen, Germany + +*/ + +#include +#include +#include + +#if VMS +#include +#include +#include +#include +#include +#include +#include +#include +/* Initialize a string descriptor (struct dsc$descriptor_s) for an + arbitrary string. ADDR is a pointer to the first character + of the string, and LEN is the length of the string. */ + +#define INIT_DSC_S(dsc, addr, len) do { \ + (dsc).dsc$b_dtype = DSC$K_DTYPE_T; \ + (dsc).dsc$b_class = DSC$K_CLASS_S; \ + (dsc).dsc$w_length = (len); \ + (dsc).dsc$a_pointer = (addr); \ +} while (0) + +/* Initialize a string descriptor (struct dsc$descriptor_s) for a + NUL-terminated string. S is a pointer to the string; the length + is determined by calling strlen(). */ + +#define INIT_DSC_CSTRING(dsc, s) INIT_DSC_S(dsc, s, strlen(s)) +#endif + +/* + copy 'from' to 'to' up to but not including 'upto' + return 0 if eos on from + return 1 if upto found + + return 'to' at last char + 1 + return 'from' at match + 1 or eos if no match + + if as_dir == 1, change all '.' to '_' + else change all '.' but the last to '_' +*/ + +static int +copyto (char **to, char **from, char upto, int as_dir) +{ + char *s; + + s = strrchr (*from, '.'); + + while (**from) + { + if (**from == upto) + { + do + { + (*from)++; + } + while (**from == upto); + return 1; + } + if (**from == '.') + { + if ((as_dir == 1) + || (*from != s)) + **to = '_'; + else + **to = '.'; + } + else + { + if (isupper ((unsigned char)**from)) + **to = tolower ((unsigned char)**from); + else + **to = **from; + } + (*to)++; + (*from)++; + } + + return 0; +} + + +/* + get translation of logical name + +*/ + +static char * +trnlog (char *name) +{ + int stat; + static char reslt[1024]; + $DESCRIPTOR (reslt_dsc, reslt); + short resltlen; + struct dsc$descriptor_s name_dsc; + char *s; + + INIT_DSC_CSTRING (name_dsc, name); + + stat = lib$sys_trnlog (&name_dsc, &resltlen, &reslt_dsc); + + if ((stat&1) == 0) + { + return ""; + } + if (stat == SS$_NOTRAN) + { + return ""; + } + reslt[resltlen] = '\0'; + + s = (char *)malloc (resltlen+1); + if (s == 0) + return ""; + strcpy (s, reslt); + return s; +} + +static char * +showall (char *s) +{ + static char t[512]; + char *pt; + + pt = t; + if (strchr (s, '\\') == 0) + return s; + while (*s) + { + if (*s == '\\') + { + *pt++ = *s; + } + *pt++ = *s++; + } + return pt; +} + + +enum namestate { N_START, N_DEVICE, N_OPEN, N_DOT, N_CLOSED, N_DONE }; + +/* + convert unix style name to vms style + type = 0 -> name is a full name (directory and filename part) + type = 1 -> name is a directory + type = 2 -> name is a filename without directory + + The following conversions are applied + (0) (1) (2) + input full name dir name file name + +1 ./ [] .dir +2 ../ .dir + +3 // : :[000000] :000000.dir +4 //a a: a: a: +5 //a/ a: a: a:000000.dir + +9 / [000000] [000000] 000000.dir +10 /a [000000]a [a] [000000]a +11 /a/ [a] [a] [000000]a.dir +12 /a/b [a]b [a.b] [a]b +13 /a/b/ [a.b] [a.b] [a]b.dir +14 /a/b/c [a.b]c [a.b.c] [a.b]c +15 /a/b/c/ [a.b.c] [a.b.c] [a.b]c.dir + +16 a a [.a] a +17 a/ [.a] [.a] a.dir +18 a/b [.a]b [.a.b] [.a]b +19 a/b/ [.a.b] [.a.b] [.a]b.dir +20 a/b/c [.a.b]c [.a.b.c] [.a.b]c +21 a/b/c/ [.a.b.c] [.a.b.c] [.a.b]c.dir + +22 a.b.c a_b.c [.a_b_c] a_b_c.dir + +23 [x][y]z [x.y]z [x.y]z [x.y]z +24 [x][.y]z [x.y]z [x.y]z [x.y]z + +25 filenames with '$' are left unchanged if they contain no '/' +25 filenames with ':' are left unchanged +26 filenames with a single pair of '[' ']' are left unchanged + + the input string is not written to +*/ + +char * +vmsify (name, type) + char *name; + int type; +{ +/* max 255 device + max 39 directory + max 39 filename + max 39 filetype + max 5 version +*/ +#define MAXPATHLEN 512 + + enum namestate nstate; + static char vmsname[MAXPATHLEN+1]; + char *fptr; + char *vptr; + char *s,*s1; + int as_dir; + int count; + + if (name == 0) + return 0; + fptr = name; + vptr = vmsname; + nstate = N_START; + + /* case 25a */ + + s = strpbrk (name, "$:"); + if (s != 0) + { + char *s1; + char *s2; + + if (type == 1) + { + s1 = strchr (s+1, '['); + s2 = strchr (s+1, ']'); + } + + if (*s == '$') + { + if (strchr (name, '/') == 0) + { + if ((type == 1) && (s1 != 0) && (s2 == 0)) + { + strcpy (vmsname, name); + strcat (vmsname, "]"); + return vmsname; + } + else + return name; + } + } + else + { + if ((type == 1) && (s1 != 0) && (s2 == 0)) + { + strcpy (vmsname, name); + strcat (vmsname, "]"); + return vmsname; + } + else + return name; + } + } + + /* case 26 */ + + s = strchr (name, '['); + + if (s != 0) + { + s1 = strchr (s+1, '['); + if (s1 == 0) + { + if ((type == 1) + && (strchr (s+1, ']') == 0)) + { + strcpy (vmsname, name); + strcat (vmsname, "]"); + return vmsname; + } + else + return name; /* single [, keep unchanged */ + } + s1--; + if (*s1 != ']') + { + return name; /* not ][, keep unchanged */ + } + + /* we have ][ */ + + s = name; + + /* s -> starting char + s1 -> ending ']' */ + + do + { + strncpy (vptr, s, s1-s); /* copy up to but not including ']' */ + vptr += s1-s; + if (*s1 == 0) + break; + s = s1 + 1; /* s -> char behind ']' */ + if (*s != '[') /* was '][' ? */ + break; /* no, last ] found, exit */ + s++; + if (*s != '.') + *vptr++ = '.'; + s1 = strchr (s, ']'); + if (s1 == 0) /* no closing ] */ + s1 = s + strlen (s); + } + while (1); + + *vptr++ = ']'; + + fptr = s; + + } + + else /* no [ in name */ + + { + + int state; + int rooted = 1; /* flag if logical is rooted, else insert [000000] */ + + state = 0; + + do + { + + switch (state) + { + case 0: /* start of loop */ + if (*fptr == '/') + { + fptr++; + state = 1; + } + else if (*fptr == '.') + { + fptr++; + state = 10; + } + else + state = 2; + break; + + case 1: /* '/' at start */ + if (*fptr == '/') + { + fptr++; + state = 3; + } + else + state = 4; + break; + + case 2: /* no '/' at start */ + s = strchr (fptr, '/'); + if (s == 0) /* no '/' (16) */ + { + if (type == 1) + { + strcpy (vptr, "[."); + vptr += 2; + } + copyto (&vptr, &fptr, 0, (type==1)); + if (type == 1) + *vptr++ = ']'; + state = -1; + } + else /* found '/' (17..21) */ + { + if ((type == 2) + && (*(s+1) == 0)) /* 17(2) */ + { + copyto (&vptr, &fptr, '/', 1); + state = 7; + } + else + { + strcpy (vptr, "[."); + vptr += 2; + copyto (&vptr, &fptr, '/', 1); + nstate = N_OPEN; + state = 9; + } + } + break; + + case 3: /* '//' at start */ + while (*fptr == '/') /* collapse all '/' */ + fptr++; + if (*fptr == 0) /* just // */ + { + char cwdbuf[MAXPATHLEN+1]; + + s1 = getcwd(cwdbuf, MAXPATHLEN); + if (s1 == 0) + { + return ""; /* FIXME, err getcwd */ + } + s = strchr (s1, ':'); + if (s == 0) + { + return ""; /* FIXME, err no device */ + } + strncpy (vptr, s1, s-s1+1); + vptr += s-s1+1; + state = -1; + break; + } + + s = vptr; + + if (copyto (&vptr, &fptr, '/', 1) == 0) /* copy device part */ + { + *vptr++ = ':'; + state = -1; + break; + } + *vptr = ':'; + nstate = N_DEVICE; + if (*fptr == 0) /* just '//a/' */ + { + strcpy (vptr+1, "[000000]"); + vptr += 9; + state = -1; + break; + } + *vptr = 0; + /* check logical for [000000] insertion */ + s1 = trnlog (s); + if (*s1 != 0) + { /* found translation */ + char *s2; + for (;;) /* loop over all nested logicals */ + { + s2 = s1 + strlen (s1) - 1; + if (*s2 == ':') /* translation ends in ':' */ + { + s2 = trnlog (s1); + free (s1); + if (*s2 == 0) + { + rooted = 0; + break; + } + s1 = s2; + continue; /* next iteration */ + } + if (*s2 == ']') /* translation ends in ']' */ + { + if (*(s2-1) == '.') /* ends in '.]' */ + { + if (strncmp (fptr, "000000", 6) != 0) + rooted = 0; + } + else + { + strcpy (vmsname, s1); + s = strchr (vmsname, ']'); + *s = '.'; + nstate = N_DOT; + vptr = s; + } + } + break; + } + free (s1); + } + else + rooted = 0; + + if (*vptr == 0) + { + nstate = N_DEVICE; + *vptr++ = ':'; + } + else + vptr++; + + if (rooted == 0) + { + strcpy (vptr, "[000000."); + vptr += 8; + s1 = vptr-1; + nstate = N_DOT; + } + else + s1 = 0; + + /* s1-> '.' after 000000 or NULL */ + + s = strchr (fptr, '/'); + if (s == 0) + { /* no next '/' */ + if (*(vptr-1) == '.') + *(vptr-1) = ']'; + else if (rooted == 0) + *vptr++ = ']'; + copyto (&vptr, &fptr, 0, (type == 1)); + state = -1; + break; + } + else + { + while (*(s+1) == '/') /* skip multiple '/' */ + s++; + } + + if ((rooted != 0) + && (*(vptr-1) != '.')) + { + *vptr++ = '['; + nstate = N_DOT; + } + else + if ((nstate == N_DOT) + && (s1 != 0) + && (*(s+1) == 0)) + { + if (type == 2) + { + *s1 = ']'; + nstate = N_CLOSED; + } + } + state = 9; + break; + + case 4: /* single '/' at start (9..15) */ + if (*fptr == 0) + state = 5; + else + state = 6; + break; + + case 5: /* just '/' at start (9) */ + if (type != 2) + { + *vptr++ = '['; + nstate = N_OPEN; + } + strcpy (vptr, "000000"); + vptr += 6; + if (type == 2) + state = 7; + else + state = 8; + break; + + case 6: /* chars following '/' at start 10..15 */ + *vptr++ = '['; + nstate = N_OPEN; + s = strchr (fptr, '/'); + if (s == 0) /* 10 */ + { + if (type != 1) + { + strcpy (vptr, "000000]"); + vptr += 7; + } + copyto (&vptr, &fptr, 0, (type == 1)); + if (type == 1) + { + *vptr++ = ']'; + } + state = -1; + } + else /* 11..15 */ + { + if ( (type == 2) + && (*(s+1) == 0)) /* 11(2) */ + { + strcpy (vptr, "000000]"); + nstate = N_CLOSED; + vptr += 7; + } + copyto (&vptr, &fptr, '/', (*(vptr-1) != ']')); + state = 9; + } + break; + + case 7: /* add '.dir' and exit */ + if ((nstate == N_OPEN) + || (nstate == N_DOT)) + { + s = vptr-1; + while (s > vmsname) + { + if (*s == ']') + { + break; + } + if (*s == '.') + { + *s = ']'; + break; + } + s--; + } + } + strcpy (vptr, ".dir"); + vptr += 4; + state = -1; + break; + + case 8: /* add ']' and exit */ + *vptr++ = ']'; + state = -1; + break; + + case 9: /* 17..21, fptr -> 1st '/' + 1 */ + if (*fptr == 0) + { + if (type == 2) + { + state = 7; + } + else + state = 8; + break; + } + s = strchr (fptr, '/'); + if (s == 0) + { + if (type != 1) + { + if (nstate == N_OPEN) + { + *vptr++ = ']'; + nstate = N_CLOSED; + } + as_dir = 0; + } + else + { + if (nstate == N_OPEN) + { + *vptr++ = '.'; + nstate = N_DOT; + } + as_dir = 1; + } + } + else + { + while (*(s+1) == '/') + s++; + if ( (type == 2) + && (*(s+1) == 0)) /* 19(2), 21(2)*/ + { + if (nstate != N_CLOSED) + { + *vptr++ = ']'; + nstate = N_CLOSED; + } + as_dir = 1; + } + else + { + if (nstate == N_OPEN) + { + *vptr++ = '.'; + nstate = N_DOT; + } + as_dir = 1; + } + } + if ( (*fptr == '.') /* check for '..' or '../' */ + && (*(fptr+1) == '.') + && ((*(fptr+2) == '/') + || (*(fptr+2) == 0)) ) + { + fptr += 2; + if (*fptr == '/') + { + do + { + fptr++; + } + while (*fptr == '/'); + } + else if (*fptr == 0) + type = 1; + vptr--; /* vptr -> '.' or ']' */ + s1 = vptr; + for (;;) + { + s1--; + if (*s1 == '.') /* one back */ + { + vptr = s1; + nstate = N_OPEN; + break; + } + if (*s1 == '[') /* top level reached */ + { + if (*fptr == 0) + { + strcpy (s1, "[000000]"); + vptr = s1 + 8; + nstate = N_CLOSED; + s = 0; + break; + } + else + { + vptr = s1+1; + nstate = N_OPEN; + break; + } + } + } + } + else + { + copyto (&vptr, &fptr, '/', as_dir); + if (nstate == N_DOT) + nstate = N_OPEN; + } + if (s == 0) + { /* 18,20 */ + if (type == 1) + *vptr++ = ']'; + state = -1; + } + else + { + if (*(s+1) == 0) + { + if (type == 2) /* 19,21 */ + { + state = 7; + } + else + { + *vptr++ = ']'; + state = -1; + } + } + } + break; + + case 10: /* 1,2 first is '.' */ + if (*fptr == '.') + { + fptr++; + state = 11; + } + else + state = 12; + break; + + case 11: /* 2, '..' at start */ + count = 1; + if (*fptr != 0) + { + if (*fptr != '/') /* got ..xxx */ + { + return name; + } + do /* got ../ */ + { + fptr++; + while (*fptr == '/') fptr++; + if (*fptr != '.') + break; + if (*(fptr+1) != '.') + break; + fptr += 2; + if ((*fptr == 0) + || (*fptr == '/')) + count++; + } + while (*fptr == '/'); + } + { /* got '..' or '../' */ + char cwdbuf[MAXPATHLEN+1]; + + s1 = getcwd(cwdbuf, MAXPATHLEN); + if (s1 == 0) + { + return ""; /* FIXME, err getcwd */ + } + strcpy (vptr, s1); + s = strchr (vptr, ']'); + if (s != 0) + { + nstate = N_OPEN; + while (s > vptr) + { + s--; + if (*s == '[') + { + s++; + strcpy (s, "000000]"); + state = -1; + break; + } + else if (*s == '.') + { + if (--count == 0) + { + if (*fptr == 0) /* had '..' or '../' */ + { + *s++ = ']'; + state = -1; + } + else /* had '../xxx' */ + { + state = 9; + } + *s = 0; + break; + } + } + } + } + vptr += strlen (vptr); + } + break; + + case 12: /* 1, '.' at start */ + if (*fptr != 0) + { + if (*fptr != '/') + { + return name; + } + while (*fptr == '/') + fptr++; + } + + { + char cwdbuf[MAXPATHLEN+1]; + + s1 = getcwd(cwdbuf, MAXPATHLEN); + if (s1 == 0) + { + return ""; /*FIXME, err getcwd */ + } + strcpy (vptr, s1); + if (*fptr == 0) + { + state = -1; + break; + } + else + { + s = strchr (vptr, ']'); + if (s == 0) + { + state = -1; + break; + } + *s = 0; + nstate = N_OPEN; + vptr += strlen (vptr); + state = 9; + } + } + break; + } + + } + while (state > 0); + + + } + + + /* directory conversion done + fptr -> filename part of input string + vptr -> free space in vmsname + */ + + *vptr++ = 0; + + return vmsname; +} + + + +/* + convert from vms-style to unix-style + + dev:[dir1.dir2] //dev/dir1/dir2/ +*/ + +char * +unixify (char *name) +{ + static char piece[512]; + char *s, *p; + + if (strchr (name, '/') != 0) /* already in unix style */ + return name; + + p = piece; + *p = 0; + + /* device part */ + + s = strchr (name, ':'); + + if (s != 0) + { + *s = 0; + *p++ = '/'; + *p++ = '/'; + strcpy (p, name); + p += strlen (p); + *s = ':'; + } + + /* directory part */ + + *p++ = '/'; + s = strchr (name, '['); + + if (s != 0) + { + s++; + switch (*s) + { + case ']': /* [] */ + strcat (p, "./"); + break; + case '-': /* [- */ + strcat (p, "../"); + break; + case '.': + strcat (p, "./"); /* [. */ + break; + default: + s--; + break; + } + s++; + while (*s) + { + if (*s == '.') + *p++ = '/'; + else + *p++ = *s; + s++; + if (*s == ']') + { + s++; + break; + } + } + if (*s != 0) /* more after ']' ?? */ + { + if (*(p-1) != '/') + *p++ = '/'; + strcpy (p, s); /* copy it anyway */ + } + } + + else /* no '[' anywhere */ + + { + *p++ = 0; + } + + /* force end with '/' */ + + if (*(p-1) != '/') + *p++ = '/'; + *p = 0; + + return piece; +} + +/* EOF */ diff --git a/src/make-3.80/vpath.c b/src/make-3.80/vpath.c new file mode 100755 index 00000000..065779be --- /dev/null +++ b/src/make-3.80/vpath.c @@ -0,0 +1,587 @@ +/* Implementation of pattern-matching file search paths for GNU Make. +Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc. +This file is part of GNU Make. + +GNU Make is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Make 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 General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Make; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "make.h" +#include "filedef.h" +#include "variable.h" +#ifdef WINDOWS32 +#include "pathstuff.h" +#endif + + +/* Structure used to represent a selective VPATH searchpath. */ + +struct vpath + { + struct vpath *next; /* Pointer to next struct in the linked list. */ + char *pattern; /* The pattern to match. */ + char *percent; /* Pointer into `pattern' where the `%' is. */ + unsigned int patlen;/* Length of the pattern. */ + char **searchpath; /* Null-terminated list of directories. */ + unsigned int maxlen;/* Maximum length of any entry in the list. */ + }; + +/* Linked-list of all selective VPATHs. */ + +static struct vpath *vpaths; + +/* Structure for the general VPATH given in the variable. */ + +static struct vpath *general_vpath; + +/* Structure for GPATH given in the variable. */ + +static struct vpath *gpaths; + +static int selective_vpath_search PARAMS ((struct vpath *path, char **file, FILE_TIMESTAMP *mtime_ptr)); + +/* Reverse the chain of selective VPATH lists so they + will be searched in the order given in the makefiles + and construct the list from the VPATH variable. */ + +void +build_vpath_lists () +{ + register struct vpath *new = 0; + register struct vpath *old, *nexto; + register char *p; + + /* Reverse the chain. */ + for (old = vpaths; old != 0; old = nexto) + { + nexto = old->next; + old->next = new; + new = old; + } + + vpaths = new; + + /* If there is a VPATH variable with a nonnull value, construct the + general VPATH list from it. We use variable_expand rather than just + calling lookup_variable so that it will be recursively expanded. */ + + { + /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */ + int save = warn_undefined_variables_flag; + warn_undefined_variables_flag = 0; + + p = variable_expand ("$(strip $(VPATH))"); + + warn_undefined_variables_flag = save; + } + + if (*p != '\0') + { + /* Save the list of vpaths. */ + struct vpath *save_vpaths = vpaths; + + /* Empty `vpaths' so the new one will have no next, and `vpaths' + will still be nil if P contains no existing directories. */ + vpaths = 0; + + /* Parse P. */ + construct_vpath_list ("%", p); + + /* Store the created path as the general path, + and restore the old list of vpaths. */ + general_vpath = vpaths; + vpaths = save_vpaths; + } + + /* If there is a GPATH variable with a nonnull value, construct the + GPATH list from it. We use variable_expand rather than just + calling lookup_variable so that it will be recursively expanded. */ + + { + /* Turn off --warn-undefined-variables while we expand SHELL and IFS. */ + int save = warn_undefined_variables_flag; + warn_undefined_variables_flag = 0; + + p = variable_expand ("$(strip $(GPATH))"); + + warn_undefined_variables_flag = save; + } + + if (*p != '\0') + { + /* Save the list of vpaths. */ + struct vpath *save_vpaths = vpaths; + + /* Empty `vpaths' so the new one will have no next, and `vpaths' + will still be nil if P contains no existing directories. */ + vpaths = 0; + + /* Parse P. */ + construct_vpath_list ("%", p); + + /* Store the created path as the GPATH, + and restore the old list of vpaths. */ + gpaths = vpaths; + vpaths = save_vpaths; + } +} + +/* Construct the VPATH listing for the pattern and searchpath given. + + This function is called to generate selective VPATH lists and also for + the general VPATH list (which is in fact just a selective VPATH that + is applied to everything). The returned pointer is either put in the + linked list of all selective VPATH lists or in the GENERAL_VPATH + variable. + + If SEARCHPATH is nil, remove all previous listings with the same + pattern. If PATTERN is nil, remove all VPATH listings. Existing + and readable directories that are not "." given in the searchpath + separated by the path element separator (defined in make.h) are + loaded into the directory hash table if they are not there already + and put in the VPATH searchpath for the given pattern with trailing + slashes stripped off if present (and if the directory is not the + root, "/"). The length of the longest entry in the list is put in + the structure as well. The new entry will be at the head of the + VPATHS chain. */ + +void +construct_vpath_list (pattern, dirpath) + char *pattern, *dirpath; +{ + register unsigned int elem; + register char *p; + register char **vpath; + register unsigned int maxvpath; + unsigned int maxelem; + char *percent = NULL; + + if (pattern != 0) + { + pattern = xstrdup (pattern); + percent = find_percent (pattern); + } + + if (dirpath == 0) + { + /* Remove matching listings. */ + register struct vpath *path, *lastpath; + + lastpath = 0; + path = vpaths; + while (path != 0) + { + struct vpath *next = path->next; + + if (pattern == 0 + || (((percent == 0 && path->percent == 0) + || (percent - pattern == path->percent - path->pattern)) + && streq (pattern, path->pattern))) + { + /* Remove it from the linked list. */ + if (lastpath == 0) + vpaths = path->next; + else + lastpath->next = next; + + /* Free its unused storage. */ + free (path->pattern); + free ((char *) path->searchpath); + free ((char *) path); + } + else + lastpath = path; + + path = next; + } + + if (pattern != 0) + free (pattern); + return; + } + +#ifdef WINDOWS32 + convert_vpath_to_windows32(dirpath, ';'); +#endif + + /* Figure out the maximum number of VPATH entries and put it in + MAXELEM. We start with 2, one before the first separator and one + nil (the list terminator) and increment our estimated number for + each separator or blank we find. */ + maxelem = 2; + p = dirpath; + while (*p != '\0') + if (*p++ == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p)) + ++maxelem; + + vpath = (char **) xmalloc (maxelem * sizeof (char *)); + maxvpath = 0; + + /* Skip over any initial separators and blanks. */ + p = dirpath; + while (*p == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p)) + ++p; + + elem = 0; + while (*p != '\0') + { + char *v; + unsigned int len; + + /* Find the end of this entry. */ + v = p; + while (*p != '\0' && *p != PATH_SEPARATOR_CHAR + && !isblank ((unsigned char)*p)) + ++p; + + len = p - v; + /* Make sure there's no trailing slash, + but still allow "/" as a directory. */ +#ifdef __MSDOS__ + /* We need also to leave alone a trailing slash in "d:/". */ + if (len > 3 || (len > 1 && v[1] != ':')) +#endif + if (len > 1 && p[-1] == '/') + --len; + + if (len > 1 || *v != '.') + { + v = savestring (v, len); + + /* Verify that the directory actually exists. */ + + if (dir_file_exists_p (v, "")) + { + /* It does. Put it in the list. */ + vpath[elem++] = dir_name (v); + free (v); + if (len > maxvpath) + maxvpath = len; + } + else + /* The directory does not exist. Omit from the list. */ + free (v); + } + + /* Skip over separators and blanks between entries. */ + while (*p == PATH_SEPARATOR_CHAR || isblank ((unsigned char)*p)) + ++p; + } + + if (elem > 0) + { + struct vpath *path; + /* ELEM is now incremented one element past the last + entry, to where the nil-pointer terminator goes. + Usually this is maxelem - 1. If not, shrink down. */ + if (elem < (maxelem - 1)) + vpath = (char **) xrealloc ((char *) vpath, + (elem + 1) * sizeof (char *)); + + /* Put the nil-pointer terminator on the end of the VPATH list. */ + vpath[elem] = 0; + + /* Construct the vpath structure and put it into the linked list. */ + path = (struct vpath *) xmalloc (sizeof (struct vpath)); + path->searchpath = vpath; + path->maxlen = maxvpath; + path->next = vpaths; + vpaths = path; + + /* Set up the members. */ + path->pattern = pattern; + path->percent = percent; + path->patlen = strlen (pattern); + } + else + { + /* There were no entries, so free whatever space we allocated. */ + free ((char *) vpath); + if (pattern != 0) + free (pattern); + } +} + +/* Search the GPATH list for a pathname string that matches the one passed + in. If it is found, return 1. Otherwise we return 0. */ + +int +gpath_search (file, len) + char *file; + int len; +{ + register char **gp; + + if (gpaths && (len <= gpaths->maxlen)) + for (gp = gpaths->searchpath; *gp != NULL; ++gp) + if (strneq (*gp, file, len) && (*gp)[len] == '\0') + return 1; + + return 0; +} + +/* Search the VPATH list whose pattern matches *FILE for a directory + where the name pointed to by FILE exists. If it is found, we set *FILE to + the newly malloc'd name of the existing file, *MTIME_PTR (if MTIME_PTR is + not NULL) to its modtime (or zero if no stat call was done), and return 1. + Otherwise we return 0. */ + +int +vpath_search (file, mtime_ptr) + char **file; + FILE_TIMESTAMP *mtime_ptr; +{ + register struct vpath *v; + + /* If there are no VPATH entries or FILENAME starts at the root, + there is nothing we can do. */ + + if (**file == '/' +#ifdef HAVE_DOS_PATHS + || **file == '\\' + || (*file)[1] == ':' +#endif + || (vpaths == 0 && general_vpath == 0)) + return 0; + + for (v = vpaths; v != 0; v = v->next) + if (pattern_matches (v->pattern, v->percent, *file)) + if (selective_vpath_search (v, file, mtime_ptr)) + return 1; + + if (general_vpath != 0 + && selective_vpath_search (general_vpath, file, mtime_ptr)) + return 1; + + return 0; +} + + +/* Search the given VPATH list for a directory where the name pointed + to by FILE exists. If it is found, we set *FILE to the newly malloc'd + name of the existing file, *MTIME_PTR (if MTIME_PTR is not NULL) to + its modtime (or zero if no stat call was done), and we return 1. + Otherwise we return 0. */ + +static int +selective_vpath_search (path, file, mtime_ptr) + struct vpath *path; + char **file; + FILE_TIMESTAMP *mtime_ptr; +{ + int not_target; + char *name, *n; + char *filename; + register char **vpath = path->searchpath; + unsigned int maxvpath = path->maxlen; + register unsigned int i; + unsigned int flen, vlen, name_dplen; + int exists = 0; + + /* Find out if *FILE is a target. + If and only if it is NOT a target, we will accept prospective + files that don't exist but are mentioned in a makefile. */ + { + struct file *f = lookup_file (*file); + not_target = f == 0 || !f->is_target; + } + + flen = strlen (*file); + + /* Split *FILE into a directory prefix and a name-within-directory. + NAME_DPLEN gets the length of the prefix; FILENAME gets the + pointer to the name-within-directory and FLEN is its length. */ + + n = strrchr (*file, '/'); +#ifdef HAVE_DOS_PATHS + /* We need the rightmost slash or backslash. */ + { + char *bslash = strrchr(*file, '\\'); + if (!n || bslash > n) + n = bslash; + } +#endif + name_dplen = n != 0 ? n - *file : 0; + filename = name_dplen > 0 ? n + 1 : *file; + if (name_dplen > 0) + flen -= name_dplen + 1; + + /* Allocate enough space for the biggest VPATH entry, + a slash, the directory prefix that came with *FILE, + another slash (although this one may not always be + necessary), the filename, and a null terminator. */ + name = (char *) xmalloc (maxvpath + 1 + name_dplen + 1 + flen + 1); + + /* Try each VPATH entry. */ + for (i = 0; vpath[i] != 0; ++i) + { + int exists_in_cache = 0; + + n = name; + + /* Put the next VPATH entry into NAME at N and increment N past it. */ + vlen = strlen (vpath[i]); + bcopy (vpath[i], n, vlen); + n += vlen; + + /* Add the directory prefix already in *FILE. */ + if (name_dplen > 0) + { +#ifndef VMS + *n++ = '/'; +#endif + bcopy (*file, n, name_dplen); + n += name_dplen; + } + +#ifdef HAVE_DOS_PATHS + /* Cause the next if to treat backslash and slash alike. */ + if (n != name && n[-1] == '\\' ) + n[-1] = '/'; +#endif + /* Now add the name-within-directory at the end of NAME. */ +#ifndef VMS + if (n != name && n[-1] != '/') + { + *n = '/'; + bcopy (filename, n + 1, flen + 1); + } + else +#endif + bcopy (filename, n, flen + 1); + + /* Check if the file is mentioned in a makefile. If *FILE is not + a target, that is enough for us to decide this file exists. + If *FILE is a target, then the file must be mentioned in the + makefile also as a target to be chosen. + + The restriction that *FILE must not be a target for a + makefile-mentioned file to be chosen was added by an + inadequately commented change in July 1990; I am not sure off + hand what problem it fixes. + + In December 1993 I loosened this restriction to allow a file + to be chosen if it is mentioned as a target in a makefile. This + seem logical. */ + { + struct file *f = lookup_file (name); + if (f != 0) + exists = not_target || f->is_target; + } + + if (!exists) + { + /* That file wasn't mentioned in the makefile. + See if it actually exists. */ + +#ifdef VMS + exists_in_cache = exists = dir_file_exists_p (vpath[i], filename); +#else + /* Clobber a null into the name at the last slash. + Now NAME is the name of the directory to look in. */ + *n = '\0'; + + /* We know the directory is in the hash table now because either + construct_vpath_list or the code just above put it there. + Does the file we seek exist in it? */ + exists_in_cache = exists = dir_file_exists_p (name, filename); +#endif + } + + if (exists) + { + /* The file is in the directory cache. + Now check that it actually exists in the filesystem. + The cache may be out of date. When vpath thinks a file + exists, but stat fails for it, confusion results in the + higher levels. */ + + struct stat st; + +#ifndef VMS + /* Put the slash back in NAME. */ + *n = '/'; +#endif + + if (!exists_in_cache /* Makefile-mentioned file need not exist. */ + || stat (name, &st) == 0) /* Does it really exist? */ + { + /* We have found a file. + Store the name we found into *FILE for the caller. */ + + *file = savestring (name, (n + 1 - name) + flen); + + if (mtime_ptr != 0) + /* Store the modtime into *MTIME_PTR for the caller. + If we have had no need to stat the file here, + we record UNKNOWN_MTIME to indicate this. */ + *mtime_ptr = (exists_in_cache + ? FILE_TIMESTAMP_STAT_MODTIME (name, st) + : UNKNOWN_MTIME); + + free (name); + return 1; + } + else + exists = 0; + } + } + + free (name); + return 0; +} + +/* Print the data base of VPATH search paths. */ + +void +print_vpath_data_base () +{ + register unsigned int nvpaths; + register struct vpath *v; + + puts (_("\n# VPATH Search Paths\n")); + + nvpaths = 0; + for (v = vpaths; v != 0; v = v->next) + { + register unsigned int i; + + ++nvpaths; + + printf ("vpath %s ", v->pattern); + + for (i = 0; v->searchpath[i] != 0; ++i) + printf ("%s%c", v->searchpath[i], + v->searchpath[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR); + } + + if (vpaths == 0) + puts (_("# No `vpath' search paths.")); + else + printf (_("\n# %u `vpath' search paths.\n"), nvpaths); + + if (general_vpath == 0) + puts (_("\n# No general (`VPATH' variable) search path.")); + else + { + register char **path = general_vpath->searchpath; + register unsigned int i; + + fputs (_("\n# General (`VPATH' variable) search path:\n# "), stdout); + + for (i = 0; path[i] != 0; ++i) + printf ("%s%c", path[i], + path[i + 1] == 0 ? '\n' : PATH_SEPARATOR_CHAR); + } +} diff --git a/src/make-3.80/w32/compat/dirent.c b/src/make-3.80/w32/compat/dirent.c new file mode 100755 index 00000000..db871a90 --- /dev/null +++ b/src/make-3.80/w32/compat/dirent.c @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include +#include "dirent.h" + + +DIR* +opendir(const char* pDirName) +{ + struct stat sb; + DIR* pDir; + char* pEndDirName; + int nBufferLen; + + /* sanity checks */ + if (!pDirName) { + errno = EINVAL; + return NULL; + } + if (stat(pDirName, &sb) != 0) { + errno = ENOENT; + return NULL; + } + if ((sb.st_mode & S_IFMT) != S_IFDIR) { + errno = ENOTDIR; + return NULL; + } + + /* allocate a DIR structure to return */ + pDir = (DIR *) malloc(sizeof (DIR)); + + if (!pDir) + return NULL; + + /* input directory name length */ + nBufferLen = strlen(pDirName); + + /* copy input directory name to DIR buffer */ + strcpy(pDir->dir_pDirectoryName, pDirName); + + /* point to end of the copied directory name */ + pEndDirName = &pDir->dir_pDirectoryName[nBufferLen - 1]; + + /* if directory name did not end in '/' or '\', add '/' */ + if ((*pEndDirName != '/') && (*pEndDirName != '\\')) { + pEndDirName++; + *pEndDirName = '/'; + } + + /* now append the wildcard character to the buffer */ + pEndDirName++; + *pEndDirName = '*'; + pEndDirName++; + *pEndDirName = '\0'; + + /* other values defaulted */ + pDir->dir_nNumFiles = 0; + pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; + pDir->dir_ulCookie = __DIRENT_COOKIE; + + return pDir; +} + +void +closedir(DIR *pDir) +{ + /* got a valid pointer? */ + if (!pDir) { + errno = EINVAL; + return; + } + + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) { + errno = EINVAL; + return; + } + + /* close the WINDOWS32 directory handle */ + if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) + FindClose(pDir->dir_hDirHandle); + + free(pDir); + + return; +} + +struct dirent * +readdir(DIR* pDir) +{ + WIN32_FIND_DATA wfdFindData; + + if (!pDir) { + errno = EINVAL; + return NULL; + } + + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) { + errno = EINVAL; + return NULL; + } + + if (pDir->dir_nNumFiles == 0) { + pDir->dir_hDirHandle = FindFirstFile(pDir->dir_pDirectoryName, &wfdFindData); + if (pDir->dir_hDirHandle == INVALID_HANDLE_VALUE) + return NULL; + } else if (!FindNextFile(pDir->dir_hDirHandle, &wfdFindData)) + return NULL; + + /* bump count for next call to readdir() or telldir() */ + pDir->dir_nNumFiles++; + + /* fill in struct dirent values */ + pDir->dir_sdReturn.d_ino = -1; + strcpy(pDir->dir_sdReturn.d_name, wfdFindData.cFileName); + + return &pDir->dir_sdReturn; +} + +void +rewinddir(DIR* pDir) +{ + if (!pDir) { + errno = EINVAL; + return; + } + + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) { + errno = EINVAL; + return; + } + + /* close the WINDOWS32 directory handle */ + if (pDir->dir_hDirHandle != INVALID_HANDLE_VALUE) + if (!FindClose(pDir->dir_hDirHandle)) + errno = EBADF; + + /* reset members which control readdir() */ + pDir->dir_hDirHandle = INVALID_HANDLE_VALUE; + pDir->dir_nNumFiles = 0; + + return; +} + +int +telldir(DIR* pDir) +{ + if (!pDir) { + errno = EINVAL; + return -1; + } + + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) { + errno = EINVAL; + return -1; + } + + /* return number of times readdir() called */ + return pDir->dir_nNumFiles; +} + +void +seekdir(DIR* pDir, long nPosition) +{ + if (!pDir) + return; + + /* sanity check that this is a DIR pointer */ + if (pDir->dir_ulCookie != __DIRENT_COOKIE) + return; + + /* go back to beginning of directory */ + rewinddir(pDir); + + /* loop until we have found position we care about */ + for (--nPosition; nPosition && readdir(pDir); nPosition--); + + /* flag invalid nPosition value */ + if (nPosition) + errno = EINVAL; + + return; +} diff --git a/src/make-3.80/w32/include/dirent.h b/src/make-3.80/w32/include/dirent.h new file mode 100755 index 00000000..3437bd06 --- /dev/null +++ b/src/make-3.80/w32/include/dirent.h @@ -0,0 +1,37 @@ +#ifndef _DIRENT_H +#define _DIRENT_H + +#include +#include +#include +#include + +#ifndef NAME_MAX +#define NAME_MAX 255 +#endif + +#define __DIRENT_COOKIE 0xfefeabab + + +struct dirent +{ + ino_t d_ino; /* unused - no equivalent on WINDOWS32 */ + char d_name[NAME_MAX+1]; +}; + +typedef struct dir_struct { + ULONG dir_ulCookie; + HANDLE dir_hDirHandle; + DWORD dir_nNumFiles; + char dir_pDirectoryName[NAME_MAX+1]; + struct dirent dir_sdReturn; +} DIR; + +DIR *opendir(const char *); +struct dirent *readdir(DIR *); +void rewinddir(DIR *); +void closedir(DIR *); +int telldir(DIR *); +void seekdir(DIR *, long); + +#endif diff --git a/src/make-3.80/w32/include/pathstuff.h b/src/make-3.80/w32/include/pathstuff.h new file mode 100755 index 00000000..a036f7b2 --- /dev/null +++ b/src/make-3.80/w32/include/pathstuff.h @@ -0,0 +1,9 @@ +#ifndef _PATHSTUFF_H +#define _PATHSTUFF_H + +extern char * convert_Path_to_windows32(char *Path, char to_delim); +extern char * convert_vpath_to_windows32(char *Path, char to_delim); +extern char * w32ify(char *file, int resolve); +extern char * getcwd_fs(char *buf, int len); + +#endif diff --git a/src/make-3.80/w32/include/sub_proc.h b/src/make-3.80/w32/include/sub_proc.h new file mode 100755 index 00000000..9cc54a57 --- /dev/null +++ b/src/make-3.80/w32/include/sub_proc.h @@ -0,0 +1,47 @@ +#ifndef SUB_PROC_H +#define SUB_PROC_H + +/* + * Component Name: + * + * $Date: 1997/08/27 20:34:23 $ + * + * $Source: /cvsroot/make/make/w32/include/sub_proc.h,v $ + * + * $Revision: 1.4 $ + */ + +/* $Id: sub_proc.h,v 1.4 1997/08/27 20:34:23 psmith Exp $ */ + +#ifdef WINDOWS32 + +#define EXTERN_DECL(entry, args) extern entry args +#define VOID_DECL void + +EXTERN_DECL(HANDLE process_init, (VOID_DECL)); +EXTERN_DECL(HANDLE process_init_fd, (HANDLE stdinh, HANDLE stdouth, + HANDLE stderrh)); +EXTERN_DECL(long process_begin, (HANDLE proc, char **argv, char **envp, + char *exec_path, char *as_user)); +EXTERN_DECL(long process_pipe_io, (HANDLE proc, char *stdin_data, + int stdin_data_len)); +EXTERN_DECL(long process_file_io, (HANDLE proc)); +EXTERN_DECL(void process_cleanup, (HANDLE proc)); +EXTERN_DECL(HANDLE process_wait_for_any, (VOID_DECL)); +EXTERN_DECL(void process_register, (HANDLE proc)); +EXTERN_DECL(HANDLE process_easy, (char** argv, char** env)); +EXTERN_DECL(BOOL process_kill, (HANDLE proc, int signal)); + +/* support routines */ +EXTERN_DECL(long process_errno, (HANDLE proc)); +EXTERN_DECL(long process_last_err, (HANDLE proc)); +EXTERN_DECL(long process_exit_code, (HANDLE proc)); +EXTERN_DECL(long process_signal, (HANDLE proc)); +EXTERN_DECL(char * process_outbuf, (HANDLE proc)); +EXTERN_DECL(char * process_errbuf, (HANDLE proc)); +EXTERN_DECL(int process_outcnt, (HANDLE proc)); +EXTERN_DECL(int process_errcnt, (HANDLE proc)); +EXTERN_DECL(void process_pipes, (HANDLE proc, int pipes[3])); + +#endif +#endif diff --git a/src/make-3.80/w32/include/w32err.h b/src/make-3.80/w32/include/w32err.h new file mode 100755 index 00000000..68a65906 --- /dev/null +++ b/src/make-3.80/w32/include/w32err.h @@ -0,0 +1,10 @@ +#ifndef _W32ERR_H_ +#define _W32ERR_H_ + +#ifndef EXTERN_DECL +#define EXTERN_DECL(entry, args) entry args +#endif + +EXTERN_DECL(char * map_windows32_error_to_string, (DWORD error)); + +#endif /* !_W32ERR_H */ diff --git a/src/make-3.80/w32/pathstuff.c b/src/make-3.80/w32/pathstuff.c new file mode 100755 index 00000000..d8f38453 --- /dev/null +++ b/src/make-3.80/w32/pathstuff.c @@ -0,0 +1,238 @@ +#include +#include +#include "make.h" +#include "pathstuff.h" + +/* + * Convert delimiter separated vpath to Canonical format. + */ +char * +convert_vpath_to_windows32(char *Path, char to_delim) +{ + char *etok; /* token separator for old Path */ + + /* + * Convert all spaces to delimiters. Note that pathnames which + * contain blanks get trounced here. Use 8.3 format as a workaround. + */ + for (etok = Path; etok && *etok; etok++) + if (isblank ((unsigned char) *etok)) + *etok = to_delim; + + return (convert_Path_to_windows32(Path, to_delim)); +} + +/* + * Convert delimiter separated path to Canonical format. + */ +char * +convert_Path_to_windows32(char *Path, char to_delim) +{ + char *etok; /* token separator for old Path */ + char *p; /* points to element of old Path */ + + /* is this a multi-element Path ? */ + for (p = Path, etok = strpbrk(p, ":;"); + etok; + etok = strpbrk(p, ":;")) + if ((etok - p) == 1) { + if (*(etok - 1) == ';' || + *(etok - 1) == ':') { + etok[-1] = to_delim; + etok[0] = to_delim; + p = ++etok; + continue; /* ignore empty bucket */ + } else if (!isalpha ((unsigned char) *p)) { + /* found one to count, handle things like '.' */ + *etok = to_delim; + p = ++etok; + } else if ((*etok == ':') && (etok = strpbrk(etok+1, ":;"))) { + /* found one to count, handle drive letter */ + *etok = to_delim; + p = ++etok; + } else + /* all finished, force abort */ + p += strlen(p); + } else { + /* found another one, no drive letter */ + *etok = to_delim; + p = ++etok; + } + + return Path; +} + +/* + * Convert to forward slashes. Resolve to full pathname optionally + */ +char * +w32ify(char *filename, int resolve) +{ + static char w32_path[FILENAME_MAX]; + char *p; + + if (resolve) + _fullpath(w32_path, filename, sizeof (w32_path)); + else + strncpy(w32_path, filename, sizeof (w32_path)); + + for (p = w32_path; p && *p; p++) + if (*p == '\\') + *p = '/'; + + return w32_path; +} + +char * +getcwd_fs(char* buf, int len) +{ + char *p; + + if (p = getcwd(buf, len)) { + char *q = w32ify(buf, 0); + strncpy(buf, q, len); + } + + return p; +} + +#ifdef unused +/* + * Convert delimiter separated pathnames (e.g. PATH) or single file pathname + * (e.g. c:/foo, c:\bar) to NutC format. If we are handed a string that + * _NutPathToNutc() fails to convert, just return the path we were handed + * and assume the caller will know what to do with it (It was probably + * a mistake to try and convert it anyway due to some of the bizarre things + * that might look like pathnames in makefiles). + */ +char * +convert_path_to_nutc(char *path) +{ + int count; /* count of path elements */ + char *nutc_path; /* new NutC path */ + int nutc_path_len; /* length of buffer to allocate for new path */ + char *pathp; /* pointer to nutc_path used to build it */ + char *etok; /* token separator for old path */ + char *p; /* points to element of old path */ + char sep; /* what flavor of separator used in old path */ + char *rval; + + /* is this a multi-element path ? */ + for (p = path, etok = strpbrk(p, ":;"), count = 0; + etok; + etok = strpbrk(p, ":;")) + if ((etok - p) == 1) { + if (*(etok - 1) == ';' || + *(etok - 1) == ':') { + p = ++etok; + continue; /* ignore empty bucket */ + } else if (etok = strpbrk(etok+1, ":;")) + /* found one to count, handle drive letter */ + p = ++etok, count++; + else + /* all finished, force abort */ + p += strlen(p); + } else + /* found another one, no drive letter */ + p = ++etok, count++; + + if (count) { + count++; /* x1;x2;x3 <- need to count x3 */ + + /* + * Hazard a guess on how big the buffer needs to be. + * We have to convert things like c:/foo to /c=/foo. + */ + nutc_path_len = strlen(path) + (count*2) + 1; + nutc_path = xmalloc(nutc_path_len); + pathp = nutc_path; + *pathp = '\0'; + + /* + * Loop through PATH and convert one elemnt of the path at at + * a time. Single file pathnames will fail this and fall + * to the logic below loop. + */ + for (p = path, etok = strpbrk(p, ":;"); + etok; + etok = strpbrk(p, ":;")) { + + /* don't trip up on device specifiers or empty path slots */ + if ((etok - p) == 1) + if (*(etok - 1) == ';' || + *(etok - 1) == ':') { + p = ++etok; + continue; + } else if ((etok = strpbrk(etok+1, ":;")) == NULL) + break; /* thing found was a WINDOWS32 pathname */ + + /* save separator */ + sep = *etok; + + /* terminate the current path element -- temporarily */ + *etok = '\0'; + +#ifdef __NUTC__ + /* convert to NutC format */ + if (_NutPathToNutc(p, pathp, 0) == FALSE) { + free(nutc_path); + rval = savestring(path, strlen(path)); + return rval; + } +#else + *pathp++ = '/'; + *pathp++ = p[0]; + *pathp++ = '='; + *pathp++ = '/'; + strcpy(pathp, &p[2]); +#endif + + pathp += strlen(pathp); + *pathp++ = ':'; /* use Unix style path separtor for new path */ + *pathp = '\0'; /* make sure we are null terminaed */ + + /* restore path separator */ + *etok = sep; + + /* point p to first char of next path element */ + p = ++etok; + + } + } else { + nutc_path_len = strlen(path) + 3; + nutc_path = xmalloc(nutc_path_len); + pathp = nutc_path; + *pathp = '\0'; + p = path; + } + + /* + * OK, here we handle the last element in PATH (e.g. c of a;b;c) + * or the path was a single filename and will be converted + * here. Note, testing p here assures that we don't trip up + * on paths like a;b; which have trailing delimiter followed by + * nothing. + */ + if (*p != '\0') { +#ifdef __NUTC__ + if (_NutPathToNutc(p, pathp, 0) == FALSE) { + free(nutc_path); + rval = savestring(path, strlen(path)); + return rval; + } +#else + *pathp++ = '/'; + *pathp++ = p[0]; + *pathp++ = '='; + *pathp++ = '/'; + strcpy(pathp, &p[2]); +#endif + } else + *(pathp-1) = '\0'; /* we're already done, don't leave trailing : */ + + rval = savestring(nutc_path, strlen(nutc_path)); + free(nutc_path); + return rval; +} + +#endif diff --git a/src/make-3.80/w32/subproc/NMakefile b/src/make-3.80/w32/subproc/NMakefile new file mode 100755 index 00000000..66afe650 --- /dev/null +++ b/src/make-3.80/w32/subproc/NMakefile @@ -0,0 +1,60 @@ +# NOTE: If you have no `make' program at all to process this makefile, run +# `build.bat' instead. +# +# Copyright (C) 1988,89,91,92,93,94,95,96,97 Free Software Foundation, Inc +# This file is part of GNU Make. +# +# GNU Make is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# GNU Make 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Make; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +# +# NMakefile for GNU Make (subproc library) +# +LIB = lib +CC = cl + +OUTDIR=. +MAKEFILE=NMakefile + +CFLAGS_any = /nologo /MT /W3 /GX /Z7 /YX /D WIN32 /D WINDOWS32 /D _WINDOWS -I. -I../include -I../../ +CFLAGS_debug = $(CFLAGS_any) /Od /D _DEBUG /FR.\WinDebug\ /Fp.\WinDebug\subproc.pch /Fo.\WinDebug/ +CFLAGS_release = $(CFLAGS_any) /O2 /FR.\WinRel\ /Fp.\WinRel\subproc.pch /Fo.\WinRel/ + +all: Release Debug + +Release: + $(MAKE) /f $(MAKEFILE) OUTDIR=WinRel CFLAGS="$(CFLAGS_release)" WinRel/subproc.lib +Debug: + $(MAKE) /f $(MAKEFILE) OUTDIR=WinDebug CFLAGS="$(CFLAGS_debug)" WinDebug/subproc.lib + +clean: + rmdir /s /q WinRel WinDebug + erase *.pdb + +$(OUTDIR): + if not exist .\$@\nul mkdir .\$@ + +OBJS = $(OUTDIR)/misc.obj $(OUTDIR)/w32err.obj $(OUTDIR)/sub_proc.obj + +$(OUTDIR)/subproc.lib: $(OUTDIR) $(OBJS) + $(LIB) -out:$@ @<< + $(OBJS) +<< + +.c{$(OUTDIR)}.obj: + $(CC) $(CFLAGS) /c $< + +$(OUTDIR)/misc.obj: misc.c proc.h +$(OUTDIR)/sub_proc.obj: sub_proc.c ../include/sub_proc.h ../include/w32err.h proc.h +$(OUTDIR)/w32err.obj: w32err.c ../include/w32err.h diff --git a/src/make-3.80/w32/subproc/build.bat b/src/make-3.80/w32/subproc/build.bat new file mode 100755 index 00000000..26ab1cbe --- /dev/null +++ b/src/make-3.80/w32/subproc/build.bat @@ -0,0 +1,10 @@ +if not exist .\WinDebug\nul mkdir .\WinDebug +cl.exe /nologo /MT /W3 /GX /Z7 /YX /Od /I .. /I . /I ../include /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c misc.c +cl.exe /nologo /MT /W3 /GX /Z7 /YX /Od /I .. /I . /I ../include /I ../.. /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c sub_proc.c +cl.exe /nologo /MT /W3 /GX /Z7 /YX /Od /I .. /I . /I ../include /D WIN32 /D WINDOWS32 /D _DEBUG /D _WINDOWS /FR.\WinDebug/ /Fp.\WinDebug/subproc.pch /Fo.\WinDebug/ /c w32err.c +lib.exe /NOLOGO /OUT:.\WinDebug\subproc.lib .\WinDebug/misc.obj .\WinDebug/sub_proc.obj .\WinDebug/w32err.obj +if not exist .\WinRel\nul mkdir .\WinRel +cl.exe /nologo /MT /W3 /GX /YX /O2 /I ../include /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c misc.c +cl.exe /nologo /MT /W3 /GX /YX /O2 /I ../include /I ../.. /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c sub_proc.c +cl.exe /nologo /MT /W3 /GX /YX /O2 /I ../include /D WIN32 /D WINDOWS32 /D NDEBUG /D _WINDOWS /FR.\WinRel/ /Fp.\WinRel/subproc.pch /Fo.\WinRel/ /c w32err.c +lib.exe /NOLOGO /OUT:.\WinRel\subproc.lib .\WinRel/misc.obj .\WinRel/sub_proc.obj .\WinRel/w32err.obj diff --git a/src/make-3.80/w32/subproc/misc.c b/src/make-3.80/w32/subproc/misc.c new file mode 100755 index 00000000..d0e9ad9b --- /dev/null +++ b/src/make-3.80/w32/subproc/misc.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include "proc.h" + + +/* + * Description: Convert a NULL string terminated UNIX environment block to + * an environment block suitable for a windows32 system call + * + * Returns: TRUE= success, FALSE=fail + * + * Notes/Dependencies: the environment block is sorted in case-insensitive + * order, is double-null terminated, and is a char *, not a char ** + */ +int _cdecl compare(const void *a1, const void *a2) +{ + return _stricoll(*((char**)a1),*((char**)a2)); +} +bool_t +arr2envblk(char **arr, char **envblk_out) +{ + char **tmp; + int size_needed; + int arrcnt; + char *ptr; + + arrcnt = 0; + while (arr[arrcnt]) { + arrcnt++; + } + + tmp = (char**) calloc(arrcnt + 1, sizeof(char *)); + if (!tmp) { + return FALSE; + } + + arrcnt = 0; + size_needed = 0; + while (arr[arrcnt]) { + tmp[arrcnt] = arr[arrcnt]; + size_needed += strlen(arr[arrcnt]) + 1; + arrcnt++; + } + size_needed++; + + qsort((void *) tmp, (size_t) arrcnt, sizeof (char*), compare); + + ptr = *envblk_out = calloc(size_needed, 1); + if (!ptr) { + free(tmp); + return FALSE; + } + + arrcnt = 0; + while (tmp[arrcnt]) { + strcpy(ptr, tmp[arrcnt]); + ptr += strlen(tmp[arrcnt]) + 1; + arrcnt++; + } + + free(tmp); + return TRUE; +} diff --git a/src/make-3.80/w32/subproc/proc.h b/src/make-3.80/w32/subproc/proc.h new file mode 100755 index 00000000..249ffd81 --- /dev/null +++ b/src/make-3.80/w32/subproc/proc.h @@ -0,0 +1,13 @@ +#ifndef _PROC_H +#define _PROC_H + +typedef int bool_t; + +#define E_SCALL 101 +#define E_IO 102 +#define E_NO_MEM 103 +#define E_FORK 104 + +extern bool_t arr2envblk(char **arr, char **envblk_out); + +#endif diff --git a/src/make-3.80/w32/subproc/sub_proc.c b/src/make-3.80/w32/subproc/sub_proc.c new file mode 100755 index 00000000..52f2fa2c --- /dev/null +++ b/src/make-3.80/w32/subproc/sub_proc.c @@ -0,0 +1,1207 @@ +#include +#include +#include /* for msvc _beginthreadex, _endthreadex */ +#include + +#include "sub_proc.h" +#include "proc.h" +#include "w32err.h" +#include "config.h" +#include "debug.h" + +static char *make_command_line(char *shell_name, char *exec_path, char **argv); + +typedef struct sub_process_t { + int sv_stdin[2]; + int sv_stdout[2]; + int sv_stderr[2]; + int using_pipes; + char *inp; + DWORD incnt; + char * volatile outp; + volatile DWORD outcnt; + char * volatile errp; + volatile DWORD errcnt; + int pid; + int exit_code; + int signal; + long last_err; + long lerrno; +} sub_process; + +/* keep track of children so we can implement a waitpid-like routine */ +static sub_process *proc_array[256]; +static int proc_index = 0; +static int fake_exits_pending = 0; + +/* + * When a process has been waited for, adjust the wait state + * array so that we don't wait for it again + */ +static void +process_adjust_wait_state(sub_process* pproc) +{ + int i; + + if (!proc_index) + return; + + for (i = 0; i < proc_index; i++) + if (proc_array[i]->pid == pproc->pid) + break; + + if (i < proc_index) { + proc_index--; + if (i != proc_index) + memmove(&proc_array[i], &proc_array[i+1], + (proc_index-i) * sizeof(sub_process*)); + proc_array[proc_index] = NULL; + } +} + +/* + * Waits for any of the registered child processes to finish. + */ +static sub_process * +process_wait_for_any_private(void) +{ + HANDLE handles[256]; + DWORD retval, which; + int i; + + if (!proc_index) + return NULL; + + /* build array of handles to wait for */ + for (i = 0; i < proc_index; i++) { + handles[i] = (HANDLE) proc_array[i]->pid; + + if (fake_exits_pending && proc_array[i]->exit_code) + break; + } + + /* wait for someone to exit */ + if (!fake_exits_pending) { + retval = WaitForMultipleObjects(proc_index, handles, FALSE, INFINITE); + which = retval - WAIT_OBJECT_0; + } else { + fake_exits_pending--; + retval = !WAIT_FAILED; + which = i; + } + + /* return pointer to process */ + if (retval != WAIT_FAILED) { + sub_process* pproc = proc_array[which]; + process_adjust_wait_state(pproc); + return pproc; + } else + return NULL; +} + +/* + * Terminate a process. + */ +BOOL +process_kill(HANDLE proc, int signal) +{ + sub_process* pproc = (sub_process*) proc; + pproc->signal = signal; + return (TerminateProcess((HANDLE) pproc->pid, signal)); +} + +/* + * Use this function to register processes you wish to wait for by + * calling process_file_io(NULL) or process_wait_any(). This must be done + * because it is possible for callers of this library to reuse the same + * handle for multiple processes launches :-( + */ +void +process_register(HANDLE proc) +{ + proc_array[proc_index++] = (sub_process *) proc; +} + +/* + * Public function which works kind of like waitpid(). Wait for any + * of the children to die and return results. To call this function, + * you must do 1 of things: + * + * x = process_easy(...); + * + * or + * + * x = process_init_fd(); + * process_register(x); + * + * or + * + * x = process_init(); + * process_register(x); + * + * You must NOT then call process_pipe_io() because this function is + * not capable of handling automatic notification of any child + * death. + */ + +HANDLE +process_wait_for_any(void) +{ + sub_process* pproc = process_wait_for_any_private(); + + if (!pproc) + return NULL; + else { + /* + * Ouch! can't tell caller if this fails directly. Caller + * will have to use process_last_err() + */ + (void) process_file_io(pproc); + return ((HANDLE) pproc); + } +} + +long +process_errno(HANDLE proc) +{ + return (((sub_process *)proc)->lerrno); +} + +long +process_signal(HANDLE proc) +{ + return (((sub_process *)proc)->signal); +} + + long +process_last_err(HANDLE proc) +{ + return (((sub_process *)proc)->last_err); +} + + long +process_exit_code(HANDLE proc) +{ + return (((sub_process *)proc)->exit_code); +} + + char * +process_outbuf(HANDLE proc) +{ + return (((sub_process *)proc)->outp); +} + + char * +process_errbuf(HANDLE proc) +{ + return (((sub_process *)proc)->errp); +} + + int +process_outcnt(HANDLE proc) +{ + return (((sub_process *)proc)->outcnt); +} + + int +process_errcnt(HANDLE proc) +{ + return (((sub_process *)proc)->errcnt); +} + + void +process_pipes(HANDLE proc, int pipes[3]) +{ + pipes[0] = ((sub_process *)proc)->sv_stdin[0]; + pipes[1] = ((sub_process *)proc)->sv_stdout[0]; + pipes[2] = ((sub_process *)proc)->sv_stderr[0]; + return; +} + + + HANDLE +process_init() +{ + sub_process *pproc; + /* + * open file descriptors for attaching stdin/stdout/sterr + */ + HANDLE stdin_pipes[2]; + HANDLE stdout_pipes[2]; + HANDLE stderr_pipes[2]; + SECURITY_ATTRIBUTES inherit; + BYTE sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; + + pproc = malloc(sizeof(*pproc)); + memset(pproc, 0, sizeof(*pproc)); + + /* We can't use NULL for lpSecurityDescriptor because that + uses the default security descriptor of the calling process. + Instead we use a security descriptor with no DACL. This + allows nonrestricted access to the associated objects. */ + + if (!InitializeSecurityDescriptor((PSECURITY_DESCRIPTOR)(&sd), + SECURITY_DESCRIPTOR_REVISION)) { + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + return((HANDLE)pproc); + } + + inherit.nLength = sizeof(inherit); + inherit.lpSecurityDescriptor = (PSECURITY_DESCRIPTOR)(&sd); + inherit.bInheritHandle = TRUE; + + // By convention, parent gets pipe[0], and child gets pipe[1] + // This means the READ side of stdin pipe goes into pipe[1] + // and the WRITE side of the stdout and stderr pipes go into pipe[1] + if (CreatePipe( &stdin_pipes[1], &stdin_pipes[0], &inherit, 0) == FALSE || + CreatePipe( &stdout_pipes[0], &stdout_pipes[1], &inherit, 0) == FALSE || + CreatePipe( &stderr_pipes[0], &stderr_pipes[1], &inherit, 0) == FALSE) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + return((HANDLE)pproc); + } + + // + // Mark the parent sides of the pipes as non-inheritable + // + if (SetHandleInformation(stdin_pipes[0], + HANDLE_FLAG_INHERIT, 0) == FALSE || + SetHandleInformation(stdout_pipes[0], + HANDLE_FLAG_INHERIT, 0) == FALSE || + SetHandleInformation(stderr_pipes[0], + HANDLE_FLAG_INHERIT, 0) == FALSE) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + return((HANDLE)pproc); + } + pproc->sv_stdin[0] = (int) stdin_pipes[0]; + pproc->sv_stdin[1] = (int) stdin_pipes[1]; + pproc->sv_stdout[0] = (int) stdout_pipes[0]; + pproc->sv_stdout[1] = (int) stdout_pipes[1]; + pproc->sv_stderr[0] = (int) stderr_pipes[0]; + pproc->sv_stderr[1] = (int) stderr_pipes[1]; + + pproc->using_pipes = 1; + + pproc->lerrno = 0; + + return((HANDLE)pproc); +} + + + HANDLE +process_init_fd(HANDLE stdinh, HANDLE stdouth, HANDLE stderrh) +{ + sub_process *pproc; + + pproc = malloc(sizeof(*pproc)); + memset(pproc, 0, sizeof(*pproc)); + + /* + * Just pass the provided file handles to the 'child side' of the + * pipe, bypassing pipes altogether. + */ + pproc->sv_stdin[1] = (int) stdinh; + pproc->sv_stdout[1] = (int) stdouth; + pproc->sv_stderr[1] = (int) stderrh; + + pproc->last_err = pproc->lerrno = 0; + + return((HANDLE)pproc); +} + + +static HANDLE +find_file(char *exec_path, LPOFSTRUCT file_info) +{ + HANDLE exec_handle; + char *fname; + char *ext; + + fname = malloc(strlen(exec_path) + 5); + strcpy(fname, exec_path); + ext = fname + strlen(fname); + + strcpy(ext, ".exe"); + if ((exec_handle = (HANDLE)OpenFile(fname, file_info, + OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { + free(fname); + return(exec_handle); + } + + strcpy(ext, ".cmd"); + if ((exec_handle = (HANDLE)OpenFile(fname, file_info, + OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { + free(fname); + return(exec_handle); + } + + strcpy(ext, ".bat"); + if ((exec_handle = (HANDLE)OpenFile(fname, file_info, + OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { + free(fname); + return(exec_handle); + } + + /* should .com come before this case? */ + if ((exec_handle = (HANDLE)OpenFile(exec_path, file_info, + OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { + free(fname); + return(exec_handle); + } + + strcpy(ext, ".com"); + if ((exec_handle = (HANDLE)OpenFile(fname, file_info, + OF_READ | OF_SHARE_COMPAT)) != (HANDLE)HFILE_ERROR) { + free(fname); + return(exec_handle); + } + + free(fname); + return(exec_handle); +} + + +/* + * Description: Create the child process to be helped + * + * Returns: + * + * Notes/Dependencies: + */ +long +process_begin( + HANDLE proc, + char **argv, + char **envp, + char *exec_path, + char *as_user) +{ + sub_process *pproc = (sub_process *)proc; + char *shell_name = 0; + int file_not_found=0; + HANDLE exec_handle; + char buf[256]; + DWORD bytes_returned; + DWORD flags; + char *command_line; + STARTUPINFO startInfo; + PROCESS_INFORMATION procInfo; + char *envblk=NULL; + OFSTRUCT file_info; + + + /* + * Shell script detection... if the exec_path starts with #! then + * we want to exec shell-script-name exec-path, not just exec-path + * NT doesn't recognize #!/bin/sh or #!/etc/Tivoli/bin/perl. We do not + * hard-code the path to the shell or perl or whatever: Instead, we + * assume it's in the path somewhere (generally, the NT tools + * bin directory) + * We use OpenFile here because it is capable of searching the Path. + */ + + exec_handle = find_file(exec_path, &file_info); + + /* + * If we couldn't open the file, just assume that Windows32 will be able + * to find and execute it. + */ + if (exec_handle == (HANDLE)HFILE_ERROR) { + file_not_found++; + } + else { + /* Attempt to read the first line of the file */ + if (ReadFile( exec_handle, + buf, sizeof(buf) - 1, /* leave room for trailing NULL */ + &bytes_returned, 0) == FALSE || bytes_returned < 2) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_IO; + CloseHandle(exec_handle); + return(-1); + } + if (buf[0] == '#' && buf[1] == '!') { + /* + * This is a shell script... Change the command line from + * exec_path args to shell_name exec_path args + */ + char *p; + + /* Make sure buf is NULL terminated */ + buf[bytes_returned] = 0; + /* + * Depending on the file system type, etc. the first line + * of the shell script may end with newline or newline-carriage-return + * Whatever it ends with, cut it off. + */ + p= strchr(buf, '\n'); + if (p) + *p = 0; + p = strchr(buf, '\r'); + if (p) + *p = 0; + + /* + * Find base name of shell + */ + shell_name = strrchr( buf, '/'); + if (shell_name) { + shell_name++; + } else { + shell_name = &buf[2];/* skipping "#!" */ + } + + } + CloseHandle(exec_handle); + } + + flags = 0; + + if (file_not_found) + command_line = make_command_line( shell_name, exec_path, argv); + else + command_line = make_command_line( shell_name, file_info.szPathName, + argv); + + if ( command_line == NULL ) { + pproc->last_err = 0; + pproc->lerrno = E_NO_MEM; + return(-1); + } + + if (envp) { + if (arr2envblk(envp, &envblk) ==FALSE) { + pproc->last_err = 0; + pproc->lerrno = E_NO_MEM; + free( command_line ); + return(-1); + } + } + + if ((shell_name) || (file_not_found)) { + exec_path = 0; /* Search for the program in %Path% */ + } else { + exec_path = file_info.szPathName; + } + + /* + * Set up inherited stdin, stdout, stderr for child + */ + GetStartupInfo(&startInfo); + startInfo.dwFlags = STARTF_USESTDHANDLES; + startInfo.lpReserved = 0; + startInfo.cbReserved2 = 0; + startInfo.lpReserved2 = 0; + startInfo.lpTitle = shell_name ? shell_name : exec_path; + startInfo.hStdInput = (HANDLE)pproc->sv_stdin[1]; + startInfo.hStdOutput = (HANDLE)pproc->sv_stdout[1]; + startInfo.hStdError = (HANDLE)pproc->sv_stderr[1]; + + if (as_user) { + if (envblk) free(envblk); + return -1; + } else { + DB (DB_JOBS, ("CreateProcess(%s,%s,...)\n", + exec_path ? exec_path : "NULL", + command_line ? command_line : "NULL")); + if (CreateProcess( + exec_path, + command_line, + NULL, + 0, /* default security attributes for thread */ + TRUE, /* inherit handles (e.g. helper pipes, oserv socket) */ + flags, + envblk, + 0, /* default starting directory */ + &startInfo, + &procInfo) == FALSE) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_FORK; + fprintf(stderr, "process_begin: CreateProcess(%s, %s, ...) failed.\n", exec_path, command_line); + if (envblk) free(envblk); + free( command_line ); + return(-1); + } + } + + pproc->pid = (int)procInfo.hProcess; + /* Close the thread handle -- we'll just watch the process */ + CloseHandle(procInfo.hThread); + + /* Close the halves of the pipes we don't need */ + if (pproc->sv_stdin) { + CloseHandle((HANDLE)pproc->sv_stdin[1]); + (HANDLE)pproc->sv_stdin[1] = 0; + } + if (pproc->sv_stdout) { + CloseHandle((HANDLE)pproc->sv_stdout[1]); + (HANDLE)pproc->sv_stdout[1] = 0; + } + if (pproc->sv_stderr) { + CloseHandle((HANDLE)pproc->sv_stderr[1]); + (HANDLE)pproc->sv_stderr[1] = 0; + } + + free( command_line ); + if (envblk) free(envblk); + pproc->lerrno=0; + return 0; +} + + + +static DWORD +proc_stdin_thread(sub_process *pproc) +{ + DWORD in_done; + for (;;) { + if (WriteFile( (HANDLE) pproc->sv_stdin[0], pproc->inp, pproc->incnt, + &in_done, NULL) == FALSE) + _endthreadex(0); + // This if should never be true for anonymous pipes, but gives + // us a chance to change I/O mechanisms later + if (in_done < pproc->incnt) { + pproc->incnt -= in_done; + pproc->inp += in_done; + } else { + _endthreadex(0); + } + } + return 0; // for compiler warnings only.. not reached +} + +static DWORD +proc_stdout_thread(sub_process *pproc) +{ + DWORD bufsize = 1024; + char c; + DWORD nread; + pproc->outp = malloc(bufsize); + if (pproc->outp == NULL) + _endthreadex(0); + pproc->outcnt = 0; + + for (;;) { + if (ReadFile( (HANDLE)pproc->sv_stdout[0], &c, 1, &nread, NULL) + == FALSE) { +/* map_windows32_error_to_string(GetLastError());*/ + _endthreadex(0); + } + if (nread == 0) + _endthreadex(0); + if (pproc->outcnt + nread > bufsize) { + bufsize += nread + 512; + pproc->outp = realloc(pproc->outp, bufsize); + if (pproc->outp == NULL) { + pproc->outcnt = 0; + _endthreadex(0); + } + } + pproc->outp[pproc->outcnt++] = c; + } + return 0; +} + +static DWORD +proc_stderr_thread(sub_process *pproc) +{ + DWORD bufsize = 1024; + char c; + DWORD nread; + pproc->errp = malloc(bufsize); + if (pproc->errp == NULL) + _endthreadex(0); + pproc->errcnt = 0; + + for (;;) { + if (ReadFile( (HANDLE)pproc->sv_stderr[0], &c, 1, &nread, NULL) == FALSE) { + map_windows32_error_to_string(GetLastError()); + _endthreadex(0); + } + if (nread == 0) + _endthreadex(0); + if (pproc->errcnt + nread > bufsize) { + bufsize += nread + 512; + pproc->errp = realloc(pproc->errp, bufsize); + if (pproc->errp == NULL) { + pproc->errcnt = 0; + _endthreadex(0); + } + } + pproc->errp[pproc->errcnt++] = c; + } + return 0; +} + + +/* + * Purpose: collects output from child process and returns results + * + * Description: + * + * Returns: + * + * Notes/Dependencies: + */ + long +process_pipe_io( + HANDLE proc, + char *stdin_data, + int stdin_data_len) +{ + sub_process *pproc = (sub_process *)proc; + bool_t stdin_eof = FALSE, stdout_eof = FALSE, stderr_eof = FALSE; + HANDLE childhand = (HANDLE) pproc->pid; + HANDLE tStdin, tStdout, tStderr; + DWORD dwStdin, dwStdout, dwStderr; + HANDLE wait_list[4]; + DWORD wait_count; + DWORD wait_return; + HANDLE ready_hand; + bool_t child_dead = FALSE; + + + /* + * Create stdin thread, if needed + */ + pproc->inp = stdin_data; + pproc->incnt = stdin_data_len; + if (!pproc->inp) { + stdin_eof = TRUE; + CloseHandle((HANDLE)pproc->sv_stdin[0]); + (HANDLE)pproc->sv_stdin[0] = 0; + } else { + tStdin = (HANDLE) _beginthreadex( 0, 1024, + (unsigned (__stdcall *) (void *))proc_stdin_thread, pproc, 0, + (unsigned int *) &dwStdin); + if (tStdin == 0) { + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done; + } + } + + /* + * Assume child will produce stdout and stderr + */ + tStdout = (HANDLE) _beginthreadex( 0, 1024, + (unsigned (__stdcall *) (void *))proc_stdout_thread, pproc, 0, + (unsigned int *) &dwStdout); + tStderr = (HANDLE) _beginthreadex( 0, 1024, + (unsigned (__stdcall *) (void *))proc_stderr_thread, pproc, 0, + (unsigned int *) &dwStderr); + + if (tStdout == 0 || tStderr == 0) { + + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done; + } + + + /* + * Wait for all I/O to finish and for the child process to exit + */ + + while (!stdin_eof || !stdout_eof || !stderr_eof || !child_dead) { + wait_count = 0; + if (!stdin_eof) { + wait_list[wait_count++] = tStdin; + } + if (!stdout_eof) { + wait_list[wait_count++] = tStdout; + } + if (!stderr_eof) { + wait_list[wait_count++] = tStderr; + } + if (!child_dead) { + wait_list[wait_count++] = childhand; + } + + wait_return = WaitForMultipleObjects(wait_count, wait_list, + FALSE, /* don't wait for all: one ready will do */ + child_dead? 1000 :INFINITE); /* after the child dies, subthreads have + one second to collect all remaining output */ + + if (wait_return == WAIT_FAILED) { +/* map_windows32_error_to_string(GetLastError());*/ + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done; + } + + ready_hand = wait_list[wait_return - WAIT_OBJECT_0]; + + if (ready_hand == tStdin) { + CloseHandle((HANDLE)pproc->sv_stdin[0]); + (HANDLE)pproc->sv_stdin[0] = 0; + CloseHandle(tStdin); + tStdin = 0; + stdin_eof = TRUE; + + } else if (ready_hand == tStdout) { + + CloseHandle((HANDLE)pproc->sv_stdout[0]); + (HANDLE)pproc->sv_stdout[0] = 0; + CloseHandle(tStdout); + tStdout = 0; + stdout_eof = TRUE; + + } else if (ready_hand == tStderr) { + + CloseHandle((HANDLE)pproc->sv_stderr[0]); + (HANDLE)pproc->sv_stderr[0] = 0; + CloseHandle(tStderr); + tStderr = 0; + stderr_eof = TRUE; + + } else if (ready_hand == childhand) { + + if (GetExitCodeProcess(childhand, &pproc->exit_code) == FALSE) { + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done; + } + child_dead = TRUE; + + } else { + + /* ?? Got back a handle we didn't query ?? */ + pproc->last_err = 0; + pproc->lerrno = E_FAIL; + goto done; + } + } + + done: + if (tStdin != 0) + CloseHandle(tStdin); + if (tStdout != 0) + CloseHandle(tStdout); + if (tStderr != 0) + CloseHandle(tStderr); + + if (pproc->lerrno) + return(-1); + else + return(0); + +} + +/* + * Purpose: collects output from child process and returns results + * + * Description: + * + * Returns: + * + * Notes/Dependencies: + */ + long +process_file_io( + HANDLE proc) +{ + sub_process *pproc; + HANDLE childhand; + DWORD wait_return; + + if (proc == NULL) + pproc = process_wait_for_any_private(); + else + pproc = (sub_process *)proc; + + /* some sort of internal error */ + if (!pproc) + return -1; + + childhand = (HANDLE) pproc->pid; + + /* + * This function is poorly named, and could also be used just to wait + * for child death if you're doing your own pipe I/O. If that is + * the case, close the pipe handles here. + */ + if (pproc->sv_stdin[0]) { + CloseHandle((HANDLE)pproc->sv_stdin[0]); + pproc->sv_stdin[0] = 0; + } + if (pproc->sv_stdout[0]) { + CloseHandle((HANDLE)pproc->sv_stdout[0]); + pproc->sv_stdout[0] = 0; + } + if (pproc->sv_stderr[0]) { + CloseHandle((HANDLE)pproc->sv_stderr[0]); + pproc->sv_stderr[0] = 0; + } + + /* + * Wait for the child process to exit + */ + + wait_return = WaitForSingleObject(childhand, INFINITE); + + if (wait_return != WAIT_OBJECT_0) { +/* map_windows32_error_to_string(GetLastError());*/ + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + goto done2; + } + + if (GetExitCodeProcess(childhand, &pproc->exit_code) == FALSE) { + pproc->last_err = GetLastError(); + pproc->lerrno = E_SCALL; + } + +done2: + if (pproc->lerrno) + return(-1); + else + return(0); + +} + +/* + * Description: Clean up any leftover handles, etc. It is up to the + * caller to manage and free the input, ouput, and stderr buffers. + */ + void +process_cleanup( + HANDLE proc) +{ + sub_process *pproc = (sub_process *)proc; + int i; + + if (pproc->using_pipes) { + for (i= 0; i <= 1; i++) { + if ((HANDLE)pproc->sv_stdin[i]) + CloseHandle((HANDLE)pproc->sv_stdin[i]); + if ((HANDLE)pproc->sv_stdout[i]) + CloseHandle((HANDLE)pproc->sv_stdout[i]); + if ((HANDLE)pproc->sv_stderr[i]) + CloseHandle((HANDLE)pproc->sv_stderr[i]); + } + } + if ((HANDLE)pproc->pid) + CloseHandle((HANDLE)pproc->pid); + + free(pproc); +} + + +/* + * Description: + * Create a command line buffer to pass to CreateProcess + * + * Returns: the buffer or NULL for failure + * Shell case: sh_name a:/full/path/to/script argv[1] argv[2] ... + * Otherwise: argv[0] argv[1] argv[2] ... + * + * Notes/Dependencies: + * CreateProcess does not take an argv, so this command creates a + * command line for the executable. + */ + +static char * +make_command_line( char *shell_name, char *full_exec_path, char **argv) +{ + int argc = 0; + char** argvi; + int* enclose_in_quotes = NULL; + int* enclose_in_quotes_i; + unsigned int bytes_required = 0; + char* command_line; + char* command_line_i; + int cygwin_mode = 0; /* HAVE_CYGWIN_SHELL */ + int have_sh = 0; /* HAVE_CYGWIN_SHELL */ + +#ifdef HAVE_CYGWIN_SHELL + have_sh = (shell_name != NULL || strstr(full_exec_path, "sh.exe")); + cygwin_mode = 1; +#endif + + if (shell_name && full_exec_path) { + bytes_required + = strlen(shell_name) + 1 + strlen(full_exec_path); + /* + * Skip argv[0] if any, when shell_name is given. + */ + if (*argv) argv++; + /* + * Add one for the intervening space. + */ + if (*argv) bytes_required++; + } + + argvi = argv; + while (*(argvi++)) argc++; + + if (argc) { + enclose_in_quotes = (int*) calloc(1, argc * sizeof(int)); + + if (!enclose_in_quotes) { + return NULL; + } + } + + /* We have to make one pass through each argv[i] to see if we need + * to enclose it in ", so we might as well figure out how much + * memory we'll need on the same pass. + */ + + argvi = argv; + enclose_in_quotes_i = enclose_in_quotes; + while(*argvi) { + char* p = *argvi; + unsigned int backslash_count = 0; + + /* + * We have to enclose empty arguments in ". + */ + if (!(*p)) *enclose_in_quotes_i = 1; + + while(*p) { + switch (*p) { + case '\"': + /* + * We have to insert a backslash for each " + * and each \ that precedes the ". + */ + bytes_required += (backslash_count + 1); + backslash_count = 0; + break; + +#if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL) + case '\\': + backslash_count++; + break; +#endif + /* + * At one time we set *enclose_in_quotes_i for '*' or '?' to suppress + * wildcard expansion in programs linked with MSVC's SETARGV.OBJ so + * that argv in always equals argv out. This was removed. Say you have + * such a program named glob.exe. You enter + * glob '*' + * at the sh command prompt. Obviously the intent is to make glob do the + * wildcarding instead of sh. If we set *enclose_in_quotes_i for '*' or '?', + * then the command line that glob would see would be + * glob "*" + * and the _setargv in SETARGV.OBJ would _not_ expand the *. + */ + case ' ': + case '\t': + *enclose_in_quotes_i = 1; + /* fall through */ + + default: + backslash_count = 0; + break; + } + + /* + * Add one for each character in argv[i]. + */ + bytes_required++; + + p++; + } + + if (*enclose_in_quotes_i) { + /* + * Add one for each enclosing ", + * and one for each \ that precedes the + * closing ". + */ + bytes_required += (backslash_count + 2); + } + + /* + * Add one for the intervening space. + */ + if (*(++argvi)) bytes_required++; + enclose_in_quotes_i++; + } + + /* + * Add one for the terminating NULL. + */ + bytes_required++; + + command_line = (char*) malloc(bytes_required); + + if (!command_line) { + if (enclose_in_quotes) free(enclose_in_quotes); + return NULL; + } + + command_line_i = command_line; + + if (shell_name && full_exec_path) { + while(*shell_name) { + *(command_line_i++) = *(shell_name++); + } + + *(command_line_i++) = ' '; + + while(*full_exec_path) { + *(command_line_i++) = *(full_exec_path++); + } + + if (*argv) { + *(command_line_i++) = ' '; + } + } + + argvi = argv; + enclose_in_quotes_i = enclose_in_quotes; + + while(*argvi) { + char* p = *argvi; + unsigned int backslash_count = 0; + + if (*enclose_in_quotes_i) { + *(command_line_i++) = '\"'; + } + + while(*p) { + if (*p == '\"') { + if (cygwin_mode && have_sh) { /* HAVE_CYGWIN_SHELL */ + /* instead of a \", cygwin likes "" */ + *(command_line_i++) = '\"'; + } else { + + /* + * We have to insert a backslash for the " + * and each \ that precedes the ". + */ + backslash_count++; + + while(backslash_count) { + *(command_line_i++) = '\\'; + backslash_count--; + }; + } +#if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL) + } else if (*p == '\\') { + backslash_count++; + } else { + backslash_count = 0; +#endif + } + + /* + * Copy the character. + */ + *(command_line_i++) = *(p++); + } + + if (*enclose_in_quotes_i) { +#if !defined(HAVE_MKS_SHELL) && !defined(HAVE_CYGWIN_SHELL) + /* + * Add one \ for each \ that precedes the + * closing ". + */ + while(backslash_count--) { + *(command_line_i++) = '\\'; + }; +#endif + *(command_line_i++) = '\"'; + } + + /* + * Append an intervening space. + */ + if (*(++argvi)) { + *(command_line_i++) = ' '; + } + + enclose_in_quotes_i++; + } + + /* + * Append the terminating NULL. + */ + *command_line_i = '\0'; + + if (enclose_in_quotes) free(enclose_in_quotes); + return command_line; +} + +/* + * Description: Given an argv and optional envp, launch the process + * using the default stdin, stdout, and stderr handles. + * Also, register process so that process_wait_for_any_private() + * can be used via process_file_io(NULL) or + * process_wait_for_any(). + * + * Returns: + * + * Notes/Dependencies: + */ +HANDLE +process_easy( + char **argv, + char **envp) +{ + HANDLE hIn; + HANDLE hOut; + HANDLE hErr; + HANDLE hProcess; + + if (DuplicateHandle(GetCurrentProcess(), + GetStdHandle(STD_INPUT_HANDLE), + GetCurrentProcess(), + &hIn, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) { + fprintf(stderr, + "process_easy: DuplicateHandle(In) failed (e=%d)\n", + GetLastError()); + return INVALID_HANDLE_VALUE; + } + if (DuplicateHandle(GetCurrentProcess(), + GetStdHandle(STD_OUTPUT_HANDLE), + GetCurrentProcess(), + &hOut, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) { + fprintf(stderr, + "process_easy: DuplicateHandle(Out) failed (e=%d)\n", + GetLastError()); + return INVALID_HANDLE_VALUE; + } + if (DuplicateHandle(GetCurrentProcess(), + GetStdHandle(STD_ERROR_HANDLE), + GetCurrentProcess(), + &hErr, + 0, + TRUE, + DUPLICATE_SAME_ACCESS) == FALSE) { + fprintf(stderr, + "process_easy: DuplicateHandle(Err) failed (e=%d)\n", + GetLastError()); + return INVALID_HANDLE_VALUE; + } + + hProcess = process_init_fd(hIn, hOut, hErr); + + if (process_begin(hProcess, argv, envp, argv[0], NULL)) { + fake_exits_pending++; + ((sub_process*) hProcess)->exit_code = process_last_err(hProcess); + + /* close up unused handles */ + CloseHandle(hIn); + CloseHandle(hOut); + CloseHandle(hErr); + } + + process_register(hProcess); + + return hProcess; +} diff --git a/src/make-3.80/w32/subproc/w32err.c b/src/make-3.80/w32/subproc/w32err.c new file mode 100755 index 00000000..afe7668f --- /dev/null +++ b/src/make-3.80/w32/subproc/w32err.c @@ -0,0 +1,51 @@ +#include +#include "w32err.h" + +/* + * Description: the windows32 version of perror() + * + * Returns: a pointer to a static error + * + * Notes/Dependencies: I got this from + * comp.os.ms-windows.programmer.win32 + */ +char * +map_windows32_error_to_string (DWORD ercode) { +/* __declspec (thread) necessary if you will use multiple threads */ +__declspec (thread) static char szMessageBuffer[128]; + + /* Fill message buffer with a default message in + * case FormatMessage fails + */ + wsprintf (szMessageBuffer, "Error %ld", ercode); + + /* + * Special code for winsock error handling. + */ + if (ercode > WSABASEERR) { + HMODULE hModule = GetModuleHandle("wsock32"); + if (hModule != NULL) { + FormatMessage(FORMAT_MESSAGE_FROM_HMODULE, + hModule, + ercode, + LANG_NEUTRAL, + szMessageBuffer, + sizeof(szMessageBuffer), + NULL); + FreeLibrary(hModule); + } + } else { + /* + * Default system message handling + */ + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + ercode, + LANG_NEUTRAL, + szMessageBuffer, + sizeof(szMessageBuffer), + NULL); + } + return szMessageBuffer; +} + diff --git a/src/make-3.80/x.bat b/src/make-3.80/x.bat new file mode 100755 index 00000000..eec2b9b5 --- /dev/null +++ b/src/make-3.80/x.bat @@ -0,0 +1,15 @@ +nmake /f NMakefile +@if errorlevel 1 goto failure +copy WinRel\make.exe ..\bin + +del WinRel /s /q +del WinDebug /s /q +del w32\subproc\WinRel /s /q +del w32\subproc\WinDebug /s /q + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/man/apropo-b.lnk b/src/man/apropo-b.lnk new file mode 100755 index 00000000..1dab9ddf --- /dev/null +++ b/src/man/apropo-b.lnk @@ -0,0 +1,14 @@ +-k ..\..\..\lib +-l libcb.lib +-l libsysb.lib +-l libiar.lib +-m +-u +-i +-o apropos +-bl RCODE=0x8100 +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\..\lib\c0b.rel +apropos +utils diff --git a/src/man/apropo-l.lnk b/src/man/apropo-l.lnk new file mode 100755 index 00000000..b5a02e7f --- /dev/null +++ b/src/man/apropo-l.lnk @@ -0,0 +1,12 @@ +-k ..\..\..\lib +-l libcl.lib +-l libsysl.lib +-l libiar.lib +-m +-u +-i +-o apropos +-bl RCODE=0x8100 +..\..\..\lib\c0l.rel +apropos +utils diff --git a/src/man/apropos.c b/src/man/apropos.c new file mode 100755 index 00000000..04ab93a6 --- /dev/null +++ b/src/man/apropos.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1987 Regents of the University of California.\n\ + All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)apropos.c 5.6 (Berkeley) 6/29/88"; +#endif /* not lint */ + +#if 1 /* Nick */ +#include +#include "utils.h" +#define MAXPATHLEN PATHLEN +typedef unsigned int u_int; +#else +#include +#endif +#include +#include +#include + +#define DEF_PATH "/usr/man:/usr/new/man:/usr/local/man" +#define MAXLINELEN 1000 /* max line handled */ +#define WHATIS "whatis" /* database name */ + +#define NO 0 /* no/false */ +#define YES 1 /* yes/true */ + +static char *myname; + +main(argc, argv) + int argc; + char **argv; +{ + extern char *optarg; + extern int optind; + register char *beg, *end, **C; + int ch, foundman = NO, *found, isapropos; + int a_match(), w_match(), (*match)(); + char *manpath = NULL, buf[MAXLINELEN + 1], fname[MAXPATHLEN + 1]; + char wbuf[MAXLINELEN + 1], *getenv(), *malloc(); + + myname = (beg = rindex(*argv, '/')) ? beg + 1 : *argv; + if (!strcmp(myname, "apropos")) { + isapropos = YES; + match = a_match; + } + else { + isapropos = NO; + match = w_match; + } + while ((ch = getopt(argc, argv, "M:P:")) != EOF) + switch((char)ch) { + case 'M': + case 'P': /* backward contemptible */ + manpath = optarg; + break; + case '?': + default: + usage(); + } + argv += optind; + argc -= optind; + if (argc < 1) + usage(); + + if (!(manpath = getenv("MANPATH"))) + manpath = DEF_PATH; + + /*NOSTRICT*/ + if (!(found = (int *)malloc((u_int)argc))) { + fprintf(stderr, "%s: out of space.\n", myname); + exit(1); + } + bzero((char *)found, argc * sizeof(int)); + + if (isapropos) + for (C = argv; *C; ++C) /* convert to lower-case */ + lowstr(*C, *C); + else for (C = argv; *C; ++C) /* trim full paths */ + if (beg = rindex(*C, '/')) + *C = beg + 1; + + for (beg = manpath; beg; beg = end) { /* through path list */ + end = index(beg, ':'); + if (!end) + (void)sprintf(fname, "%s/%s", beg, WHATIS); + else { + (void)sprintf(fname, "%.*s/%s", end - beg, beg, WHATIS); + ++end; + } + if (!freopen(fname, "r", stdin)) + continue; + + /* for each file found */ + for (foundman = YES; gets(buf);) { + if (isapropos) + lowstr(buf, wbuf); + else + dashtrunc(buf, wbuf); + for (C = argv; *C; ++C) + if ((*match)(wbuf, *C)) { + puts(buf); + found[C - argv] = YES; + + /* only print line once */ + while (*++C) + if ((*match)(wbuf, *C)) + found[C - argv] = YES; + break; + } + } + } + if (!foundman) { + fprintf(stderr, "%s: no %s file found in %s.\n", myname, WHATIS, manpath); + exit(1); + } + for (C = argv; *C; ++C) + if (!found[C - argv]) + printf("%s: %s\n", *C, isapropos ? "nothing appropriate" : "not found"); +} + +/* + * a_match -- + * match for apropos; anywhere the string appears + */ +static +a_match(bp, str) + register char *bp, *str; +{ + register int len; + register char test; + + if (!*bp) + return(NO); + /* backward compatible: everything matches empty string */ + if (!*str) + return(YES); + for (test = *str++, len = strlen(str); *bp;) + if (test == *bp++ && !strncmp(bp, str, len)) + return(YES); + return(NO); +} + +/* + * w_match -- + * match for whatis; looks for full word match + */ +static +w_match(bp, str) + register char *bp, *str; +{ + register int len; + register char *start; + + if (!*str || !*bp) + return(NO); + for (len = strlen(str);;) { + for (; *bp && !isdigit(*bp) && !isalpha(*bp); ++bp); + if (!*bp) + break; + for (start = bp++; *bp && (isdigit(*bp) || isalpha(*bp)); ++bp); + if (bp - start == len && !strncasecmp(start, str, len)) + return(YES); + } + return(NO); +} + +/* + * dashtrunc -- + * truncate a string at " - " + */ +static +dashtrunc(from, to) + register char *from, *to; +{ + do { + if (from[0] == ' ' && from[1] == '-' && from[2] == ' ') + break; + } while (*to++ = *from++); + *to = '\0'; +} + +/* + * lowstr -- + * convert a string to lower case + */ +static +lowstr(from, to) + register char *from, *to; +{ + do { + *to++ = isupper(*from) ? tolower(*from) : *from; + } while (*from++); +} + +/* + * usage -- + * print usage message and die + */ +static +usage() +{ + fprintf(stderr, "usage: %s [-M path] string ...\n", myname); + exit(1); +} diff --git a/src/man/build-b.ban b/src/man/build-b.ban new file mode 100755 index 00000000..431dbe8e --- /dev/null +++ b/src/man/build-b.ban @@ -0,0 +1,45 @@ +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ ..\utils +@if errorlevel 1 goto failure +del utils.r01 +as-z80 -l -o utils.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ ..\apropos +@if errorlevel 1 goto failure +del apropos.r01 +as-z80 -l -o apropos.s01 +@if errorlevel 1 goto failure + +link-z80 -f apropos +@if errorlevel 1 goto failure +ihex2bin -l apropos.i86 ..\..\..\bin\banked\apropos +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ ..\catman +@if errorlevel 1 goto failure +del catman.r01 +as-z80 -l -o catman.s01 +@if errorlevel 1 goto failure + +link-z80 -f catman +@if errorlevel 1 goto failure +ihex2bin -l catman.i86 ..\..\..\bin\banked\catman +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ ..\man +@if errorlevel 1 goto failure +del man.r01 +as-z80 -l -o man.s01 +@if errorlevel 1 goto failure + +link-z80 -f man +@if errorlevel 1 goto failure +ihex2bin -l man.i86 ..\..\..\bin\banked\man +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/man/build-l.ban b/src/man/build-l.ban new file mode 100755 index 00000000..9c2a8a1f --- /dev/null +++ b/src/man/build-l.ban @@ -0,0 +1,45 @@ +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ ..\utils +@if errorlevel 1 goto failure +del utils.r01 +as-z80 -l -o utils.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ ..\apropos +@if errorlevel 1 goto failure +del apropos.r01 +as-z80 -l -o apropos.s01 +@if errorlevel 1 goto failure + +link-z80 -f apropos +@if errorlevel 1 goto failure +ihex2bin -l apropos.i86 ..\..\..\bin\large\apropos +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ ..\catman +@if errorlevel 1 goto failure +del catman.r01 +as-z80 -l -o catman.s01 +@if errorlevel 1 goto failure + +link-z80 -f catman +@if errorlevel 1 goto failure +ihex2bin -l catman.i86 ..\..\..\bin\large\catman +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ ..\man +@if errorlevel 1 goto failure +del man.r01 +as-z80 -l -o man.s01 +@if errorlevel 1 goto failure + +link-z80 -f man +@if errorlevel 1 goto failure +ihex2bin -l man.i86 ..\..\..\bin\large\man +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/man/catman-b.lnk b/src/man/catman-b.lnk new file mode 100755 index 00000000..2b3631b9 --- /dev/null +++ b/src/man/catman-b.lnk @@ -0,0 +1,14 @@ +-k ..\..\..\lib +-l libcb.lib +-l libsysb.lib +-l libiar.lib +-m +-u +-i +-o catman +-bl RCODE=0x8100 +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\..\lib\c0b.rel +catman +utils diff --git a/src/man/catman-l.lnk b/src/man/catman-l.lnk new file mode 100755 index 00000000..c8e5a317 --- /dev/null +++ b/src/man/catman-l.lnk @@ -0,0 +1,12 @@ +-k ..\..\..\lib +-l libcl.lib +-l libsysl.lib +-l libiar.lib +-m +-u +-i +-o catman +-bl RCODE=0x8100 +..\..\..\lib\c0l.rel +catman +utils diff --git a/src/man/catman.8 b/src/man/catman.8 new file mode 100755 index 00000000..cccade5e --- /dev/null +++ b/src/man/catman.8 @@ -0,0 +1,119 @@ +.\" Copyright (c) 1980 Regents of the University of California. +.\" All rights reserved. The Berkeley software License Agreement +.\" specifies the terms and conditions for redistribution. +.\" +.\" @(#)catman.8 6.5.2 (2.11BSD) 1996/11/16 +.\" +.TH CATMAN 8 "October 23, 1996" +.UC 4 +.SH NAME +catman \- create the cat files for the manual +.SH SYNOPSIS +.B /usr/sbin/catman +[ +.B \-p +] [ +.B \-n +] [ +.B \-w +] [ +.B \-M +.I path +] +[ sections ] +.SH DESCRIPTION +.I Catman +creates the preformatted versions of the on-line manual from the nroff +input files. +Each manual page is examined and those whose preformatted versions are +missing or out of date are recreated. +If any changes are made, +.I catman +will recreate the +.B whatis +database. +.PP +If there is one parameter not starting with a `\-', +it is taken to be a list of manual sections to look in. +For example +.IP +.B catman 123 +.LP +will cause the updating to only happen to manual sections +1, 2, and 3. +.PP +Options: +.TP +.B \-n +prevents creations of the +.B whatis +database. +.TP +.B \-p +prints what would be done instead of doing it. +.TP +.B \-w +causes only the +.B whatis +database to be created. +No manual reformatting is done. +.TP +.B \-M +updates manual pages located in the set of directories specified by +.I path +(/usr/man by default). +.I Path +has the form of a colon (`:') separated list of directory names, +for example `/usr/local/man:/usr/man'. +If the environment variable `MANPATH' is set, +its value is used for the default path. +.PP +If the nroff source file contains only a line of the form `.so manx/yyy.x', +a symbolic link is made in the catx directory to the appropriate +preformatted manual page. +This feature allows easy distribution of the preformatted manual pages +among a group of associated machines with +.I rdist(1). +The nroff sources need not be distributed to all machines, +thus saving the associated disk space. +As an example, consider a local network with 5 machines, +called mach1 through mach5. +Suppose mach3 has the manual page nroff sources. +Every night, mach3 runs +.I catman +via +.I cron(8) +and later runs +.I rdist +with a distfile that looks like: +.IP +.nf +.ta \w'${MANUAL'u + +MANSLAVES = ( mach1 mach2 mach4 mach5 ) + +MANUALS = (/usr/man/cat[1-8no] /usr/man/whatis) + +${MANUALS} -> ${MANSLAVES} + install -R; + notify root; + +.fi +.SH FILES +.nf +.ta \w'/usr/sbin/makewhatis 'u +/usr/man default manual directory location +/usr/man/man?/*.* raw (nroff input) manual sections +/usr/man/cat?/*.* preformatted manual pages +/usr/man/whatis whatis database +/usr/sbin/makewhatis command script to make whatis database +.fi +.DT +.SH "SEE ALSO" +man(1), cron(8), rdist(1) +.SH BUGS +Acts oddly on nights with full moons. +.PP +The need for catman(8) is almost but not quite gone. Most of the manpages +have been moved out of /usr/src/man into the sourcecode hierarchy. +The recreation of the whatis database is the main use of catman now. diff --git a/src/man/catman.bat b/src/man/catman.bat new file mode 100755 index 00000000..9dc3f772 --- /dev/null +++ b/src/man/catman.bat @@ -0,0 +1,47 @@ +nroff -man man/man1/basename.1 >man/cat1/basename.0 +nroff -man man/man1/cal.1 >man/cat1/cal.0 +nroff -man man/man1/cat.1 >man/cat1/cat.0 +nroff -man man/man1/chmod.1 >man/cat1/chmod.0 +nroff -man man/man1/chown.1 >man/cat1/chown.0 +nroff -man man/man1/cmp.1 >man/cat1/cmp.0 +nroff -man man/man1/cp.1 >man/cat1/cp.0 +nroff -man man/man1/date.1 >man/cat1/date.0 +nroff -man man/man1/dd.1 >man/cat1/dd.0 +nroff -man man/man1/diff.1 >man/cat1/diff.0 +nroff -man man/man1/du.1 >man/cat1/du.0 +nroff -man man/man1/echo.1 >man/cat1/echo.0 +nroff -man man/man1/ed.1 >man/cat1/ed.0 +nroff -man man/man1/expr.1 >man/cat1/expr.0 +nroff -man man/man1/file.1 >man/cat1/file.0 +nroff -man man/man1/find.1 >man/cat1/find.0 +nroff -man man/man1/grep.1 >man/cat1/grep.0 +nroff -man man/man1/kill.1 >man/cat1/kill.0 +nroff -man man/man1/ln.1 >man/cat1/ln.0 +nroff -man man/man1/login.1 >man/cat1/login.0 +nroff -man man/man1/ls.1 >man/cat1/ls.0 +nroff -man man/man1/man.1 >man/cat1/man.0 +nroff -man man/man1/mkdir.1 >man/cat1/mkdir.0 +nroff -man man/man1/mv.1 >man/cat1/mv.0 +nroff -man man/man1/od.1 >man/cat1/od.0 +nroff -man man/man1/passwd.1 >man/cat1/passwd.0 +nroff -man man/man1/pr.1 >man/cat1/pr.0 +nroff -man man/man1/ps.1 >man/cat1/ps.0 +nroff -man man/man1/pwd.1 >man/cat1/pwd.0 +nroff -man man/man1/rm.1 >man/cat1/rm.0 +nroff -man man/man1/roff.1 >man/cat1/roff.0 +nroff -man man/man1/sh.1 >man/cat1/sh.0 +nroff -man man/man1/sort.1 >man/cat1/sort.0 +nroff -man man/man1/split.1 >man/cat1/split.0 +nroff -man man/man1/su.1 >man/cat1/su.0 +nroff -man man/man1/sum.1 >man/cat1/sum.0 +nroff -man man/man1/tail.1 >man/cat1/tail.0 +nroff -man man/man1/tar.1 >man/cat1/tar.0 +nroff -man man/man1/tee.1 >man/cat1/tee.0 +nroff -man man/man1/test.1 >man/cat1/test.0 +nroff -man man/man1/time.1 >man/cat1/time.0 +nroff -man man/man1/touch.1 >man/cat1/touch.0 +nroff -man man/man1/tr.1 >man/cat1/tr.0 +nroff -man man/man1/troff.1 >man/cat1/troff.0 +nroff -man man/man1/true.1 >man/cat1/true.0 +nroff -man man/man1/uniq.1 >man/cat1/uniq.0 +nroff -man man/man1/wc.1 >man/cat1/wc.0 diff --git a/src/man/catman.c b/src/man/catman.c new file mode 100755 index 00000000..11d14000 --- /dev/null +++ b/src/man/catman.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 1980 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +#if !defined(lint) && defined(DOSCCS) +char copyright[] = +"@(#) Copyright (c) 1980 Regents of the University of California.\n\ + All rights reserved.\n"; + +static char sccsid[] = "@(#)catman.c 5.7.1 (2.11BSD) 1996/10/21"; +#endif + +/* + * catman: update cat'able versions of manual pages + * (whatis database also) + */ +#include +#if 1 /* Nick */ +#include +#else +#include +#endif +#include +#if 1 /* Nick */ +#include +#include +#else +#include +#include +#include +#endif +#include +#include +#include + +char buf[BUFSIZ]; +char pflag; +char nflag; +char wflag; +char man[MAXNAMLEN+6] = "manx/"; +int exstat = 0; +char cat[MAXNAMLEN+6] = "catx/"; +char lncat[MAXNAMLEN+9] = "../catx/"; +char *manpath = "/usr/man"; +char *sections = "12345678ln"; +#if 1 /* Nick */ +char *makewhatis = "/usr/bin/makewhatis"; +#else +char *makewhatis = "/usr/sbin/makewhatis"; +#endif + +main(ac, av) + int ac; + char *av[]; +{ + char *mp, *nextp; + + if ((mp = getenv("MANPATH")) != NULL) + manpath = mp; + + ac--, av++; + while (ac > 0 && av[0][0] == '-') { + switch (av[0][1]) { + + case 'p': + pflag++; + break; + + case 'n': + nflag++; + break; + + case 'w': + wflag++; + break; + + case 'M': + case 'P': + if (ac < 1) { + fprintf(stderr, "%s: missing path\n", + av[0]); + exit(1); + } + ac--, av++; + manpath = *av; + break; + + default: + goto usage; + } + ac--, av++; + } + if (ac > 1) { +usage: + printf("usage: catman [ -p ] [ -n ] [ -w ] [ -M path ] [ sections ]\n"); + exit(-1); + } + if (ac == 1) + sections = *av; + for (mp = manpath; mp && ((nextp = index(mp, ':')), 1); mp = nextp) { + if (nextp) + *nextp++ = '\0'; + doit(mp); + } + exit(exstat); +} + +doit(mandir) + char *mandir; +{ + register char *msp, *csp, *sp; + int changed = 1; + int status; + + if (wflag) + goto whatis; + if (chdir(mandir) < 0) { + sprintf(buf, "catman: %s", mandir); + perror(buf); + /* exstat = 1; */ + return; + } + if (pflag) + printf("cd %s\n", mandir); + msp = &man[5]; + csp = &cat[5]; + (void) umask(0); + for (sp = sections; *sp; sp++) { + register DIR *mdir; +#if 1 /* Nick */ + register struct dirent *dir; +#else + register struct direct *dir; +#endif + struct stat sbuf; + + man[3] = cat[3] = *sp; + *msp = *csp = '\0'; + if ((mdir = opendir(man)) == NULL) { + /* sprintf(buf, "catman: opendir: %s", man); */ + /* perror(buf); */ + /* exstat = 1; */ + continue; + } + if (stat(cat, &sbuf) < 0) { + register char *cp; + + (void) strcpy(buf, cat); + cp = rindex(buf, '/'); + if (cp && cp[1] == '\0') + *cp = '\0'; + if (pflag) + printf("mkdir %s\n", buf); + else if (mkdir(buf, 0777) < 0) { + sprintf(buf, "catman: mkdir: %s", cat); + perror(buf); + exstat = 1; + continue; + } + (void) stat(cat, &sbuf); + } + if (access(cat, 7 /*R_OK|W_OK|X_OK*/) == -1) { + sprintf(buf, "catman: %s", cat); + perror(buf); + exstat = 1; + continue; + } + if ((sbuf.st_mode & S_IFMT) != S_IFDIR) { + fprintf(stderr, "catman: %s: Not a directory\n", cat); + exstat = 1; + continue; + } + while ((dir = readdir(mdir)) != NULL) { + time_t time; + register char *tsp; + FILE *inf; + int makelink; + + if (dir->d_ino == 0 || dir->d_name[0] == '.') + continue; + /* + * Make sure this is a man file, i.e., that it + * ends in .[0-9] or .[0-9][a-z] + */ + tsp = rindex(dir->d_name, '.'); + if (tsp == NULL) + continue; + if (!isdigit(*++tsp) && *tsp != *sp) + continue; + if (*++tsp && !isalpha(*tsp)) + continue; + if (*tsp && *++tsp) + continue; + (void) strcpy(msp, dir->d_name); + if ((inf = fopen(man, "r")) == NULL) { + sprintf(buf, "catman: %s"); + perror(buf); + exstat = 1; + continue; + } + makelink = 0; + if (getc(inf) == '.' && getc(inf) == 's' + && getc(inf) == 'o') { + if (getc(inf) != ' ' || + fgets(lncat+3, sizeof(lncat)-3, inf)==NULL) { + fclose(inf); + continue; + } + if (lncat[strlen(lncat)-1] == '\n') + lncat[strlen(lncat)-1] = '\0'; + if (strncmp(lncat+3, "man", 3) != 0) { + fclose(inf); + continue; + } + bcopy("../cat", lncat, sizeof("../cat")-1); + makelink = 1; + } + fclose(inf); + (void) strcpy(csp, dir->d_name); + if (stat(cat, &sbuf) >= 0) { + time = sbuf.st_mtime; + (void) stat(man, &sbuf); +#if 1 /* Nick please look into this! */ + if (*((long *)&time) >= *((long *)&sbuf.st_mtime)) +#else + if (time >= sbuf.st_mtime) +#endif + continue; + (void) unlink(cat); + } + if (makelink) { + /* + * Don't unlink a directory by accident. + */ + if (stat(lncat+3, &sbuf) >= 0 && + (((sbuf.st_mode&S_IFMT)==S_IFREG) || + ((sbuf.st_mode&S_IFMT)==S_IFLNK))) + (void) unlink(cat); + if (pflag) + printf("ln -s %s %s\n", lncat, cat); + else + if (symlink(lncat, cat) == -1) { + sprintf(buf, "catman: symlink: %s", cat); + perror(buf); + exstat = 1; + continue; + } + } + else { + sprintf(buf, "nroff -man %s > %s", man, cat); + if (pflag) + printf("%s\n", buf); + else if ((status = system(buf)) != 0) { + fprintf(stderr, "catman: nroff: %s: exit status %d: Owooooo!\n", cat, status); + exstat = 1; + continue; + } + } + changed = 1; + } + closedir(mdir); + } + if (changed && !nflag) { +whatis: + sprintf(buf, "%s %s", makewhatis, mandir); + if (pflag) + printf("%s\n", buf); + else if ((status = system(buf)) != 0) { + fprintf(stderr, "catman: %s: exit status %d\n", + buf, status); + exstat = 1; + } + } + return; +} diff --git a/src/man/man-b.lnk b/src/man/man-b.lnk new file mode 100755 index 00000000..c412ee9a --- /dev/null +++ b/src/man/man-b.lnk @@ -0,0 +1,13 @@ +-k ..\..\..\lib +-l libcb.lib +-l libsysb.lib +-l libiar.lib +-m +-u +-i +-o man +-bl RCODE=0x8100 +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\..\lib\c0b.rel +man diff --git a/src/man/man-l.lnk b/src/man/man-l.lnk new file mode 100755 index 00000000..d9204221 --- /dev/null +++ b/src/man/man-l.lnk @@ -0,0 +1,11 @@ +-k ..\..\..\lib +-l libcl.lib +-l libsysl.lib +-l libiar.lib +-m +-u +-i +-o man +-bl RCODE=0x8100 +..\..\..\lib\c0l.rel +man diff --git a/src/man/man.c b/src/man/man.c new file mode 100755 index 00000000..e08aec55 --- /dev/null +++ b/src/man/man.c @@ -0,0 +1,484 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if !defined(lint) && defined(DOSCCS) +char copyright[] = +"@(#) Copyright (c) 1987 Regents of the University of California.\n\ + All rights reserved.\n"; +#endif + +#ifndef lint +static char sccsid[] = "@(#)man.c 5.17.1 (2.11BSD) 1999/11/26"; +#endif /* not lint */ + +#if 1 /* Nick */ +#include +#include +#include +/* #include "utils.h" */ +#define MAXPATHLEN PATHLEN +typedef unsigned int u_int; +#define read _read /* Nick, very temporary */ +#define write _write /* Nick, very temporary */ +int ioctl(int fd, int request, ...); /* IAR don't use regparams! */ +int open(char *name, unsigned int flag, ...); /* IAR don't use regparams! */ +#else +#include +#include +#include +#endif +#include +#include +#include +#include + +#if 1 /* Nick */ +#define DEF_PAGER "/bin/more -s" +#define DEF_PATH "/usr/man" +#else +#define DEF_PAGER "/usr/ucb/more -s" +#define DEF_PATH "/usr/man:/usr/new/man:/usr/local/man" +#define LOCAL_PATH "/usr/local/man" +#define NEW_PATH "/usr/new/man" +#endif + +#define NO 0 +#define YES 1 + +static char *command, /* command buffer */ + *defpath, /* default search path */ +#if 0 /* Nick */ + *locpath, /* local search path */ +#endif + *machine, /* machine type */ + *manpath, /* current search path */ +#if 0 /* Nick */ + *newpath, /* new search path */ +#endif + *pager, /* requested pager */ + how; /* how to display */ + +#define ALL 0x1 /* show all man pages */ +#define CAT 0x2 /* copy file to stdout */ +#define WHERE 0x4 /* just tell me where */ + +main(argc, argv) + int argc; + register char **argv; +{ + extern char *optarg; + extern int optind; + int ch; + char *getenv(), *malloc(); + + while ((ch = getopt(argc, argv, "-M:P:afkw")) != EOF) + switch((char)ch) { + case '-': + how |= CAT; + break; + case 'M': + case 'P': /* backward compatibility */ + defpath = optarg; + break; + case 'a': + how |= ALL; + break; + /* + * "man -f" and "man -k" are backward contemptible, + * undocumented ways of calling whatis(1) and apropos(1). + */ + case 'f': + jump(argv, "-f", "whatis"); + /*NOTREACHED*/ + case 'k': + jump(argv, "-k", "apropos"); + /*NOTREACHED*/ + /* + * Deliberately undocumented; really only useful when + * you're moving man pages around. Not worth adding. + */ + case 'w': + how |= WHERE | ALL; + break; + case '?': + default: + usage(); + } + argv += optind; + + if (!*argv) + usage(); + + if (!(how & CAT)) + if (!isatty(1)) + how |= CAT; + else if (pager = getenv("PAGER")) { + register char *p; + + /* + * if the user uses "more", we make it "more -s" + * watch out for PAGER = "mypager /usr/ucb/more" + */ + for (p = pager; *p && !isspace(*p); ++p); + for (; p > pager && *p != '/'; --p); + if (p != pager) + ++p; + /* make sure it's "more", not "morex" */ + if (!strncmp(p, "more", 4) && (!p[4] || isspace(p[4]))){ + char *opager = pager; + /* + * allocate space to add the "-s" + */ + if (!(pager = malloc((u_int)(strlen(opager) + + sizeof("-s") + 1)))) { + fputs("man: out of space.\n", stderr); + exit(1); + } + (void)sprintf(pager, "%s %s", opager, "-s"); + } + } + else + pager = DEF_PAGER; + if (!(machine = getenv("MACHINE"))) + setmachine(); + if (!defpath && !(defpath = getenv("MANPATH"))) + defpath = DEF_PATH; +#if 0 /* Nick */ + locpath = LOCAL_PATH; + newpath = NEW_PATH; +#endif + man(argv); + /* use system(3) in case someone's pager is "pager arg1 arg2" */ + if (command) + (void)system(command); + exit(0); +} + +typedef struct { + char *name, *msg; +} MANDIR; +static MANDIR list1[] = { /* section one list */ + "cat1", "1st", "cat8", "8th", "cat6", "6th", + "cat.old", "old", NULL, NULL, +}, list2[] = { /* rest of the list */ + "cat2", "2nd", "cat3", "3rd", "cat4", "4th", + "cat5", "5th", "cat7", "7th", "cat3f", "3rd (F)", + NULL, NULL, +}, list3[2]; /* single section */ + +static +man(argv) + char **argv; +{ + register char *p; + MANDIR *section, *getsect(); + int res; + + for (; *argv; ++argv) { + manpath = defpath; + section = NULL; + switch(**argv) { +#if 0 /* Nick */ + case 'l': /* local */ + /* support the "{l,local,n,new}###" syntax */ + for (p = *argv; isalpha(*p); ++p); + if (!strncmp(*argv, "l", p - *argv) || + !strncmp(*argv, "local", p - *argv)) { + ++argv; + manpath = locpath; + section = getsect(p); + } + break; + case 'n': /* new */ + for (p = *argv; isalpha(*p); ++p); + if (!strncmp(*argv, "n", p - *argv) || + !strncmp(*argv, "new", p - *argv)) { + ++argv; + manpath = newpath; + section = getsect(p); + } + break; + /* + * old isn't really a separate section of the manual, + * and its entries are all in a single directory. + */ + case 'o': /* old */ + for (p = *argv; isalpha(*p); ++p); + if (!strncmp(*argv, "o", p - *argv) || + !strncmp(*argv, "old", p - *argv)) { + ++argv; + list3[0] = list1[3]; + section = list3; + } + break; +#endif + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': + if (section = getsect(*argv)) + ++argv; + } + + if (*argv) { + if (section) + res = manual(section, *argv); + else { + res = manual(list1, *argv); + if (!res || (how & ALL)) + res += manual(list2, *argv); + } + if (res || how&WHERE) + continue; + } + + fputs("man: ", stderr); + if (*argv) + fprintf(stderr, "no entry for %s in the ", *argv); + else + fputs("what do you want from the ", stderr); + if (section) + fprintf(stderr, "%s section of the ", section->msg); +#if 0 /* Nick */ + if (manpath == locpath) + fputs("local ", stderr); + else if (manpath == newpath) + fputs("new ", stderr); +#endif + if (*argv) + fputs("manual.\n", stderr); + else + fputs("manual?\n", stderr); + exit(1); + } +} + +/* + * manual -- + * given a directory list and a file name find a file that + * matches; check ${directory}/${dir}/{file name} and + * ${directory}/${dir}/${machine}/${file name}. + */ +static +manual(section, name) + MANDIR *section; + char *name; +{ + register char *beg, *end; + register MANDIR *dp; + register int res; + char fname[MAXPATHLEN + 1], *index(); + + if (strlen(name) > MAXNAMLEN-2) /* leave room for the ".0" */ + name[MAXNAMLEN-2] = '\0'; + for (beg = manpath, res = 0;; beg = end + 1) { + if (end = index(beg, ':')) + *end = '\0'; + for (dp = section; dp->name; ++dp) { + (void)sprintf(fname, "%s/%s/%s.0", beg, dp->name, name); + if (access(fname, 4 /*R_OK*/)) { + (void)sprintf(fname, "%s/%s/%s/%s.0", beg, + dp->name, machine, name); + if (access(fname, 4 /*R_OK*/)) + continue; + } + if (how & WHERE) + printf("man: found in %s.\n", fname); + else if (how & CAT) + cat(fname); + else + add(fname); + if (!(how & ALL)) + return(1); + res = 1; + } + if (!end) + return(res); + *end = ':'; + } + /*NOTREACHED*/ +} + +/* + * cat -- + * cat out the file + */ +static +cat(fname) + char *fname; +{ + register int fd, n; + char buf[BUFSIZ]; + + if (!(fd = open(fname, O_RDONLY, 0))) { + perror("man: open"); + exit(1); + } + while ((n = read(fd, buf, sizeof(buf))) > 0) + if (write(1, buf, n) != n) { + perror("man: write"); + exit(1); + } + if (n == -1) { + perror("man: read"); + exit(1); + } + (void)close(fd); +} + +/* + * add -- + * add a file name to the list for future paging + */ +static +add(fname) + char *fname; +{ + static u_int buflen; + static int len; + static char *cp; + int flen; + char *malloc(), *realloc(), *strcpy(); + + if (!command) { + if (!(command = malloc(buflen = 1024))) { + fputs("man: out of space.\n", stderr); + exit(1); + } + len = strlen(strcpy(command, pager)); + cp = command + len; + } + flen = strlen(fname); + if (len + flen + 2 > buflen) { /* +2 == space, EOS */ + if (!(command = realloc(command, buflen += 1024))) { + fputs("man: out of space.\n", stderr); + exit(1); + } + cp = command + len; + } + *cp++ = ' '; + len += flen + 1; /* +1 = space */ + (void)strcpy(cp, fname); + cp += flen; +} + +/* + * getsect -- + * return a point to the section structure for a particular suffix + */ +static MANDIR * +getsect(s) + char *s; +{ + switch(*s++) { + case '1': + if (!*s) + return(list1); + break; + case '2': + if (!*s) { + list3[0] = list2[0]; + return(list3); + } + break; + /* sect. 3 requests are for either section 3, or section 3[fF]. */ + case '3': + if (!*s) { + list3[0] = list2[1]; + return(list3); + } + else if ((*s == 'f' || *s == 'F') && !*++s) { + list3[0] = list2[5]; + return(list3); + } + break; + case '4': + if (!*s) { + list3[0] = list2[2]; + return(list3); + } + break; + case '5': + if (!*s) { + list3[0] = list2[3]; + return(list3); + } + break; + case '6': + if (!*s) { + list3[0] = list1[2]; + return(list3); + } + break; + case '7': + if (!*s) { + list3[0] = list2[4]; + return(list3); + } + break; + case '8': + if (!*s) { + list3[0] = list1[1]; + return(list3); + } + } + return((MANDIR *)NULL); +} + +/* + * jump -- + * strip out flag argument and jump + */ +static +jump(argv, flag, name) + char **argv, *name; + register char *flag; +{ + register char **arg; + + argv[0] = name; + for (arg = argv + 1; *arg; ++arg) + if (!strcmp(*arg, flag)) + break; + for (; *arg; ++arg) + arg[0] = arg[1]; + execvp(name, argv); + fprintf(stderr, "%s: Command not found.\n", name); + exit(1); +} + +/* + * This is done in a function by itself because 'uname()' uses a 640 + * structure which we do not want permanently allocated on main()'s stack. +*/ +setmachine() + { + struct utsname foo; + + if (uname(&foo) < 0) + strcpy(foo.machine, "?"); + machine = strdup(foo.machine); + } + +/* + * usage -- + * print usage and die + */ +static +usage() +{ + fputs("usage: man [-] [-a] [-M path] [section] title ...\n", stderr); + exit(1); +} diff --git a/src/man/mkwhatis.bat b/src/man/mkwhatis.bat new file mode 100755 index 00000000..5f4c41d2 --- /dev/null +++ b/src/man/mkwhatis.bat @@ -0,0 +1,32 @@ +#!/bin/sh - +# +# Copyright (c) 1980 Regents of the University of California. +# All rights reserved. The Berkeley software License Agreement +# specifies the terms and conditions for redistribution. +# +# @(#)makewhatis.sh 5.3 (Berkeley) 3/29/86 +# +trap "rm -f /tmp/whatis$$; exit 1" 1 2 13 15 +MANDIR=${1-/usr/man} +TMPFILE=/tmp/whatis$$ +rm -f $TMPFILE +cp /dev/null $TMPFILE +if test ! -d $MANDIR ; then exit 0 ; fi +cd $MANDIR +top=`pwd` +for i in cat* +do + if [ -d $i ] ; then + cd $i + for file in `find . -type f -name '*.0' -print` + do + sed -n -f /usr/man/makewhatis.sed $file + done >> $TMPFILE + cd $top + fi +done +rm -f $top/whatis +sort -u $TMPFILE > $top/whatis +chmod 664 whatis >/dev/null 2>&1 +rm -f $TMPFILE +exit 0 diff --git a/src/man/mkwhatis.sed b/src/man/mkwhatis.sed new file mode 100755 index 00000000..13df2f49 --- /dev/null +++ b/src/man/mkwhatis.sed @@ -0,0 +1,45 @@ +#!/bin/sh - +# +# Copyright (c) 1988 Regents of the University of California. +# All rights reserved. +# +# Redistribution and use in source and binary forms are permitted +# provided that the above copyright notice and this paragraph are +# duplicated in all such forms and that any documentation, +# advertising materials, and other materials related to such +# distribution and use acknowledge that the software was developed +# by the University of California, Berkeley. The name of the +# University may not be used to endorse or promote products derived +# from this software without specific prior written permission. +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +# +# @(#)makewhatis.sed 5.3 (Berkeley) 7/9/88 +# +/(\([a-zA-Z0-9]*\).*UNIX Programmer's Manual/ { + s;.*(\([a-zA-Z0-9]*\).*UNIX.*;\1; + h + d +} +/^NAME/!d + +:name + s;.*;; + N + s;\n;; + # some twits underline the command name + s;_;;g + /^[^ ]/b print + H + b name + +:print + x + s;\n;;g + /-/!d + s;\([a-z][A-z]\)-[ ][ ]*;\1; + s;\([a-zA-Z0-9,]\)[ ][ ]*;\1 ;g + s;[^a-zA-Z0-9]*\([a-zA-Z0-9]*\)[^a-zA-Z0-9]*\(.*\) - \(.*\);\2 (\1) - \3; + p + d diff --git a/src/man/mkwhatis.sh b/src/man/mkwhatis.sh new file mode 100755 index 00000000..5f4c41d2 --- /dev/null +++ b/src/man/mkwhatis.sh @@ -0,0 +1,32 @@ +#!/bin/sh - +# +# Copyright (c) 1980 Regents of the University of California. +# All rights reserved. The Berkeley software License Agreement +# specifies the terms and conditions for redistribution. +# +# @(#)makewhatis.sh 5.3 (Berkeley) 3/29/86 +# +trap "rm -f /tmp/whatis$$; exit 1" 1 2 13 15 +MANDIR=${1-/usr/man} +TMPFILE=/tmp/whatis$$ +rm -f $TMPFILE +cp /dev/null $TMPFILE +if test ! -d $MANDIR ; then exit 0 ; fi +cd $MANDIR +top=`pwd` +for i in cat* +do + if [ -d $i ] ; then + cd $i + for file in `find . -type f -name '*.0' -print` + do + sed -n -f /usr/man/makewhatis.sed $file + done >> $TMPFILE + cd $top + fi +done +rm -f $top/whatis +sort -u $TMPFILE > $top/whatis +chmod 664 whatis >/dev/null 2>&1 +rm -f $TMPFILE +exit 0 diff --git a/src/man/n.bat b/src/man/n.bat new file mode 100755 index 00000000..84519b79 --- /dev/null +++ b/src/man/n.bat @@ -0,0 +1,23 @@ +copy catman.bat ..\..\bin +copy mkwhatis.bat ..\..\bin\man +copy mkwhatis.sed ..\..\bin\man +copy mkwhatis.sh ..\..\bin\man + +md build-l +cd build-l +copy ..\apropo-l.lnk apropos.lnk +copy ..\catman-l.lnk catman.lnk +copy ..\man-l.lnk man.lnk +copy ..\build-l.ban n.bat +call n +cd.. + +md build-b +cd build-b +copy ..\apropo-b.lnk apropos.lnk +copy ..\catman-b.lnk catman.lnk +copy ..\man-b.lnk man.lnk +copy ..\build-b.ban n.bat +call n +cd .. + diff --git a/src/man/utils.c b/src/man/utils.c new file mode 100755 index 00000000..018e4030 --- /dev/null +++ b/src/man/utils.c @@ -0,0 +1,75 @@ +/* utils.c for uzi180 utils by Nick - subroutines based on utils.asz source */ + +#include "utils.h" + +#define TRUE 1 +#define FALSE 0 + +#if 0 +/* convert an integer to a string in any base (2-36) */ +char *itob (int n, char *s, int base) + { + register unsigned int u; + register char *p, *q; + register negative, c; + if ((n < 0) && (base == -10)) { + negative = TRUE; + u = -n; + } + else { + negative = FALSE; + u = n; + } + if (base == -10) /* Signals signed conversion */ + base = 10; + p = q = s; + do { /* Generate digits in reverse order */ + if ((*p = u % base + '0') > '9') + *p += ('A' - ('9' + 1)); + ++p; + u = u / base; + } while (u > 0); + if (negative) + *p++ = '-'; + *p = '\0'; /* Terminate the string */ + while (q < --p) { /* Reverse the digits */ + c = *q; + *q++ = *p; + *p = c; + } + return s; + } +#endif + +void bzero(char *ptr, int count) + { + while (count--) + { + *ptr++ = 0; + } + } + +void bfill(char *ptr, char val, int count) + { + while (count--) + *ptr++ = val; + } + +void bcopy(char *src, char *dest, int count) + { + while (count--) + { + *dest++ = *src++; + } + } + +int int_min(int a, int b) + { + return (b < a ? b : a); + } + +int int_max(int a, int b) + { + return (b > a ? b : a); + } + diff --git a/src/man/utils.h b/src/man/utils.h new file mode 100755 index 00000000..094a5abe --- /dev/null +++ b/src/man/utils.h @@ -0,0 +1,14 @@ +/* utils.h for uzi180 utils by Nick - subroutines based on utils.asz source */ + +#ifndef __UTILS_H +#define __UTILS_H + +/* char *itob(int n, char *s, int base); */ +void bzero(char *ptr, int count); +void bfill(char *ptr, char val, int count); +void bcopy(char *src, char *dest, int count); +int int_min(int a, int b); +int int_max(int a, int b); + +#endif /* __UTILS_H */ + diff --git a/src/mkutil/4dos.com b/src/mkutil/4dos.com new file mode 100755 index 0000000000000000000000000000000000000000..ef6c91e9efeebc3f5b47e8c7ce73a9a79fc15550 GIT binary patch literal 153314 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 +#include +#include + +#define PATHLEN 512 + +void main(int argc, char **argv) + { + int i, count, fdin; + FILE *fileout; + char *infile = NULL; + char *outfile = NULL; + char line[PATHLEN]; + char name[PATHLEN]; + char buffer[8]; + + if (argc > 1) + { + infile = argv[1]; + } + + if (argc > 2) + { + outfile = argv[2]; + } + + if (infile == NULL) + { + printf("usage: bin2c infile.bin [outfile.c]\n"); + + fflush(stdout); + exit(1); + } + + if (outfile == NULL) + { + outfile = name; + strcpy(outfile, infile); + + i = strlen(outfile); + while (i--) + { + if (outfile[i] == '\\') + { + break; /* no extension, so don't strip it */ + } + if (outfile[i] == '.') + { + outfile[i] = 0; /* strip dot and extension */ + break; /* ready to concatenate our extension */ + } + } + + strcat(outfile, ".c"); + } + + if (!strcmp(infile, outfile)) + { + fprintf(stderr, "input and output filenames identical\n"); + + fflush(stderr); + exit(1); + } + + fdin = open(infile, O_RDONLY | O_BINARY); + if (fdin < 0) + { + fprintf(stderr, "can't open: "); + perror(infile); + + fflush(stderr); + exit(1); + } + + fileout = fopen(outfile, "w"); + if (fileout == NULL) + { + fprintf(stderr, "can't create: "); + perror(outfile); + + fflush(stderr); + exit(1); + } + + strcpy(line, "/* "); + strcat(line, outfile); + strcat(line, " generated from "); + strcat(line, infile); + strcat(line, ", do not edit! */\n"); + fputs(line, fileout); + + *line = 0; /* causes a blank line to be written after title */ + + count = read(fdin, buffer, 8); + while (count > 0) + { + strcat(line, "\n"); + fputs(line, fileout); + + *line = 0; + for (i = 0; i < count; i++) + { + sprintf(&line[i*5], "0x%02x,", buffer[i] & 0xff); + } + + count = read(fdin, buffer, 8); + } + + if (*line) + { + line[strlen(line)-1] = 0; /* kill trailing comma */ + strcat(line, "\n"); + fputs(line, fileout); + + *line = 0; /* causes a blank line to be written at end */ + } + + strcat(line, "\n"); + fputs(line, fileout); + + fclose(fileout); + close(fdin); + + printf("converted %s to %s\n", infile, outfile); + + fflush(stdout); + exit(0); + } + diff --git a/src/mkutil/bin2c.exe b/src/mkutil/bin2c.exe new file mode 100755 index 0000000000000000000000000000000000000000..8ed8ca852b139432fd9c575ff33e31d23c48d933 GIT binary patch literal 57388 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 literal 0 HcmV?d00001 diff --git a/src/mkutil/crcd.com b/src/mkutil/crcd.com new file mode 100755 index 0000000000000000000000000000000000000000..ee5da3b7050dc8249ccea5bd9c0d706a3088f838 GIT binary patch literal 1045 zcmcgq|7#m%7=P|^mox|G#wLRX9Pde?tlest%7pf;i|wkYOS7rl>bgNRXB%h}x!hTt zh?((+_U@Pc;%{1&L50v_3W23@Byl&|^@p2RL8w1%c2l2`;kRwfEv4ss9oqlE_ks6) zp67i&pNHp5W4)4v*#VhVpTP-M3!hz&gv#%8>fVbGz!|puD_0EJQto!dT*p1^)PVyG zHbVsfUt;y!C3wY_$_-yJXiFuA>gL_tB5VFuo#F5vgFiDlMD?DGNY)edehU;1`F@3g#KBzm^qJIbPF8Swtu3KWCrN6e6X~vHj zQRs`OQfZB(-%(QJ?c|sOw?yXrPTt(TlP|$>TbkMxVW%E@lf^v@HlXLqr&VaycE#GS zv_Cjr2<3kI@W`F~&>J^=_%#gO2%h~Ng64NP$$X}*;C;Ylh*cr@<(v=y1|)ztVWL$*+xS37xtga))R%NHfq_rka-|?>VDy-&K5}Cu(btos7gGs1-ZJ( z+_l{GeF>hYMa7KE$iRu1gO9{BTDEcLS|2~ynzv5R3N@|CaEh!g)$h2!3>v&VtZ{O; ze(wcqHZRolhxCz&)+7h1Th#v=T;w5|{lM+kn~qh!;P6NHv^6WoRlj^@f^E4*b)q$B z@cpPPS``Rpdw1}lZTD6Ha*JH<7Iy?c*%&Ih?l%w!a|6bzaXB0?z5-_L&+~IWi+T;q zaM;@C;Y)@Su1%j|3%(5dG;93ftgftWiEwE$FnIx(4NJdj(M>wq*Wb}Mc$j$Sn4*&X z9i5$`APTQ%;v)(n`v~zu$jMmbwHHrCBZm)>lUw>J(&33HM8?L*cwBpH^xuwV$Y}gs z#l!9;iMXbacq&1((b8UVv> L9c?fS|L^$+UZ{5- literal 0 HcmV?d00001 diff --git a/src/mkutil/ihex2bin.c b/src/mkutil/ihex2bin.c new file mode 100755 index 00000000..d70908f7 --- /dev/null +++ b/src/mkutil/ihex2bin.c @@ -0,0 +1,272 @@ +/*************************************************************************** +* ihex2bin +* By Jason Nunn , Oct 2000 +***************************************************************************/ +#include +// really for Turbo C: #ifdef _MSC_VER +// really for Turbo C: #include +// really for Turbo C: #else +#include +// really for Turbo C: #endif +#include +#if 1 /* Nick */ +#include +#endif + +#define STR_LEN 255 + +unsigned char *text; +unsigned int text_base = -1; /* Nick */ +unsigned int text_top = 0; /* Nick unsigned */ +unsigned int text_size = 0; /* Nick */ +unsigned int mem_offset = 0; /* Nick */ +int embed_length = 0; /* Nick */ +int iar_mapping = 0; /* Nick */ +char strln[STR_LEN + 1]; + +int readtoken(int sl,int el) +{ + int x,v = 0,ord; + + ord = (el - sl) * 4; + for(x = sl;x <= el;x++) + { + char c; + + c = tolower(strln[x]); + + if(isdigit(c)) + v |= (c - '0') << ord; + else + if(isxdigit(c)) + v |= ((c - 'a') + 10) << ord; + else + { + printf("garbage found in input file. Aborting.\n"); + exit(-1); + } + + ord -= 4; + } + + return v; +} + +int main(int argc,char *argv[]) +{ + FILE *fp; +#if 1 /* Nick */ + int j, ac, ap; +#endif + char nstr[STR_LEN]; + + printf("ihex2bin, by Jason Nunn , Oct 2000\n"); + +#if 1 /* Nick */ + ac = argc; + for (ap = 1; ap < ac; ap++) + { + if (strcmp(argv[ap], "-l") == 0 || strcmp(argv[ap], "-L") == 0) + { + embed_length = 1; + } + else if (strcmp(argv[ap], "-i") == 0 || strcmp(argv[ap], "-I") == 0) + { + iar_mapping = 1; + } + else + { + break; + } + } + + if (ap >= ac || argv[ap][0] == '-') + { + printf("usage: ihex2bin [-l] [-i] infile [outfile]\n"); + printf(" -l embed length at location 4 in output\n"); + printf(" -i logical/physical mapping for IAR compiler\n"); + printf("outfile name is constructed from infile if not specified,\n"); + printf("and in this case the filename extension is changed to .bin\n"); + exit(1); + } +#else + if(argc < 2) + { + printf("No filename specified, Aborting.\n"); + exit(-1); + } +#endif + +#if 1 + fp = fopen(argv[ap++],"r"); +#else + fp = fopen(argv[1],"r"); +#endif + if(fp == NULL) +#if 1 + { + printf("Error: can't open input file '%s'\n", argv[1]); + exit(1); + } +#else + perror("main()::fopen()"); +#endif + + text = malloc(0x100000); // malloc(0xffff); + if(text == NULL) + { +#if 1 + printf("Error: can't allocate 0x100000 bytes\n"); + exit(1); +#else + perror("main()::malloc()"); + exit(-1); +#endif + } + + memset(text, 0xff, 0x100000); // memset(text,0xff,0xffff); + + for(;;) + { + unsigned int data_no,mem_start,i,pos; /* Nick unsigned */ + + if(feof(fp)) + break; + + if(fgets(strln,STR_LEN,fp) == NULL) + break; + + if(strln[0] != ':') + continue; + +#if 1 /* Nick */ + if(readtoken(7,8) == 0x04) + { + mem_offset = readtoken(9,12); + if (iar_mapping) + { + mem_offset = (mem_offset & 0xf) << 14; + } + else + { + mem_offset <<= 16; + } + continue; + } + + if(readtoken(7,8) == 0x05) + { + /* not sure what this means, some kind of configuration area? */ + continue; + } +#endif + + if(readtoken(7,8)) /* Nick == 0x01) */ + break; + + data_no = readtoken(1,2); + mem_start = readtoken(3,6) + mem_offset; /* Nick mem_offset */ + +#if 1 /* Nick */ + if (mem_start < text_base) + text_base = mem_start; +#endif + + i = (mem_start + data_no); + if(i > text_top) + text_top = i; + + for(i = 0,pos = 9;i < data_no;i++) + { + text[mem_start + i] = readtoken(pos,pos + 1); + pos += 2; + } + } + fclose(fp); + +#if 1 /* Nick */ + if (text_top < text_base) + text_base = text_top; +#endif + +#if 1 /* Nick */ + if (ap >= ac) + { + strcpy(nstr, argv[ap - 1]); + j = strlen(nstr); + while (j--) + { + if (nstr[j] == '\\') + { + break; /* the filename has no extension, so don't strip it */ + } + if (nstr[j] == '.') + { + nstr[j] = 0; /* strip the period and the extension */ + break; /* now ready to concatenate our extension */ + } + } + strcat(nstr, ".bin"); + } + else + { + strcpy(nstr, argv[ap]); +#if 0 + j = strlen(nstr); + while (j--) + { + if (nstr[j] == '\\') + { + strcat(nstr, ".bin"); + break; /* the filename has no extension, so don't strip it */ + } + if (nstr[j] == '.') + { + break; /* an extension was provided, so use it */ + } + } +#endif + } + if (!strcmp(nstr, argv[ap - 1])) + { + printf("Error: input and output filenames identical\n"); + exit(1); + } + j = open(nstr, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); + if (j < 0) + { + printf("Error: could not create file '%s'\n", nstr); + exit(1); + } + text_size = text_top - text_base; + if (embed_length) + { + if (text_size < 8 || + text[text_base + 4] != 0x78 || + text[text_base + 5] != 0x56 || + text[text_base + 6] != 0x34 || + text[text_base + 7] != 0x12) + { + printf("Error: length placeholder value of 0x12345678 not found\n"); + exit(1); + } + text[text_base + 4] = text_size & 0xff; + text[text_base + 5] = (text_size >> 8) & 0xff; + text[text_base + 6] = (text_size >> 16) & 0xff; + text[text_base + 7] = (text_size >> 24) & 0xff; + } + write(j, text + text_base, text_size); + close(j); + + printf("Created '%s' origin 0x%x size 0x%x\n", nstr, text_base, text_size); +#else + sprintf(nstr,"%s.bin",argv[1]); + fp = fopen(nstr,"w"); + fwrite(text,text_top,1,fp); + fclose(fp); + + printf("Wrote %u bytes.\n",text_top); +#endif + + return 0; +} diff --git a/src/mkutil/ihex2bin.exe b/src/mkutil/ihex2bin.exe new file mode 100755 index 0000000000000000000000000000000000000000..bcfb99dfcad7c0d3a09181019de53fad7267801e GIT binary patch literal 57391 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 literal 0 HcmV?d00001 diff --git a/src/mkutil/mklink-b.bat b/src/mkutil/mklink-b.bat new file mode 100755 index 00000000..2a70fc8f --- /dev/null +++ b/src/mkutil/mklink-b.bat @@ -0,0 +1,30 @@ +@if .%1==. goto failure + +@echo -k %2..\..\lib>%1.lnk +@echo -l libcb.lib>>%1.lnk +@echo -l libsysb.lib>>%1.lnk +@echo -l libiar.lib>>%1.lnk +@echo -m>>%1.lnk +@echo -u>>%1.lnk +@echo -i>>%1.lnk +@echo -o %1>>%1.lnk +@echo -bl RCODE=0x8100>>%1.lnk +@echo -bl CODE=0x4000,0x10000>>%1.lnk +@echo -bc CODE=0x4000>>%1.lnk +@echo %2..\..\lib\c0b.rel>>%1.lnk +@echo %1>>%1.lnk + +@echo SUCCESS +@goto done + +:failure +@echo usage: %0 filename +@echo. +@echo Writes link-z80 definition file "filename.lnk" for banked memory model, +@echo containing the needed commands to link "filename.rel" to "filename.i86". +@echo The generated file can then be manually edited to link further modules. +@echo Please note, any previously existing "filename.lnk" will be overwritten! +@echo. + +:done + diff --git a/src/mkutil/mklink-l.bat b/src/mkutil/mklink-l.bat new file mode 100755 index 00000000..5ed40087 --- /dev/null +++ b/src/mkutil/mklink-l.bat @@ -0,0 +1,28 @@ +@if .%1==. goto failure + +@echo -k %2..\..\lib>%1.lnk +@echo -l libcl.lib>>%1.lnk +@echo -l libsysl.lib>>%1.lnk +@echo -l libiar.lib>>%1.lnk +@echo -m>>%1.lnk +@echo -u>>%1.lnk +@echo -i>>%1.lnk +@echo -o %1>>%1.lnk +@echo -bl RCODE=0x8100>>%1.lnk +@echo %2..\..\lib\c0l.rel>>%1.lnk +@echo %1>>%1.lnk + +@echo SUCCESS +@goto done + +:failure +@echo usage: %0 filename +@echo. +@echo Writes link-z80 definition file "filename.lnk" for large memory model, +@echo containing the needed commands to link "filename.rel" to "filename.i86". +@echo The generated file can then be manually edited to link further modules. +@echo Please note, any previously existing "filename.lnk" will be overwritten! +@echo. + +:done + diff --git a/src/mkutil/mknbat-b.bat b/src/mkutil/mknbat-b.bat new file mode 100755 index 00000000..d0c375be --- /dev/null +++ b/src/mkutil/mknbat-b.bat @@ -0,0 +1,34 @@ +@if .%1==. goto failure + +@echo iccz80 -S -w -mb -v1 -z -A -I..\..\include\ %1>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo del %1.r01>>n.bat +@echo as-z80 -l -o %1.s01>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo.>>n.bat +@echo link-z80 -f %1>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo ihex2bin -l %1.i86 %1>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo.>>n.bat +@echo @echo SUCCESS>>n.bat +@echo @goto done>>n.bat +@echo :failure>>n.bat +@echo @echo FAILURE>>n.bat +@echo :done>>n.bat +@echo.>>n.bat + +@echo SUCCESS +@goto done + +:failure +@echo usage: %0 filename +@echo. +@echo Writes Windows NT/2000/XP batch file "n.bat" for banked memory model, +@echo containing the needed commands to compile "filename.c" to "filename". +@echo The generated file can then be manually edited to add further commands. +@echo Please note, any previously existing "n.bat" will be overwritten! +@echo. + +:done + diff --git a/src/mkutil/mknbat-l.bat b/src/mkutil/mknbat-l.bat new file mode 100755 index 00000000..921a0bd6 --- /dev/null +++ b/src/mkutil/mknbat-l.bat @@ -0,0 +1,34 @@ +@if .%1==. goto failure + +@echo iccz80 -S -w -ml -v1 -z -A -I..\..\include\ %1>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo del %1.r01>>n.bat +@echo as-z80 -l -o %1.s01>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo.>>n.bat +@echo link-z80 -f %1>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo ihex2bin -l %1.i86 %1>>n.bat +@echo @if errorlevel 1 goto failure>>n.bat +@echo.>>n.bat +@echo @echo SUCCESS>>n.bat +@echo @goto done>>n.bat +@echo :failure>>n.bat +@echo @echo FAILURE>>n.bat +@echo :done>>n.bat +@echo.>>n.bat + +@echo SUCCESS +@goto done + +:failure +@echo usage: %0 filename +@echo. +@echo Writes Windows NT/2000/XP batch file "n.bat" for large memory model, +@echo containing the needed commands to compile "filename.c" to "filename". +@echo The generated file can then be manually edited to add further commands. +@echo Please note, any previously existing "n.bat" will be overwritten! +@echo. + +:done + diff --git a/src/mkutil/n.bat b/src/mkutil/n.bat new file mode 100755 index 00000000..1079950a --- /dev/null +++ b/src/mkutil/n.bat @@ -0,0 +1,30 @@ +copy 4dos.com ..\bin +copy crc.com ..\bin +copy crcd.com ..\bin +copy mklink-l.bat ..\bin +copy mklink-b.bat ..\bin +copy mknbat-l.bat ..\bin +copy mknbat-b.bat ..\bin + +cl -Zi -I. ihex2bin.c +@if errorlevel 1 goto failure +copy ihex2bin.exe ..\bin + +cl -Zi -I. bin2c.c +@if errorlevel 1 goto failure +copy bin2c.exe ..\bin + +cl -Zi -I. -DVAX touch.c +@if errorlevel 1 goto failure +copy touch.exe ..\bin + +rem cl -Zi -I. -DVAX setfsize.c +rem @if errorlevel 1 goto failure +rem copy setfsize.exe ..\bin + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/mkutil/setfsize.c b/src/mkutil/setfsize.c new file mode 100755 index 00000000..1e5a053f --- /dev/null +++ b/src/mkutil/setfsize.c @@ -0,0 +1,93 @@ +/* setfsize.c by Nick for UZI180 utils */ + +#include +#include +#include +#include +#include + +#define BUFFER 0x200 + +void main(int argc, char **argv) + { + int fd, count; + off_t wanted, current, remain; + char *buf; + + if (argc < 3 || !isdigit(argv[2][0])) + { + printf("usage: %s filename size\n", argv[0]); + exit(1); + } + + fd = open(argv[1], O_RDWR); + if (fd < 0) + { + fd = creat(argv[1], 0666); + if (fd < 0) + { + fprintf(stderr, "%s: can't create: ", argv[0]); + fflush(stderr); + perror(argv[1]); + exit(1); + } + } + + current = lseek(fd, 0, SEEK_END); + if (current < 0) + { + fprintf(stderr, "%s: can't seek: ", argv[0]); + fflush(stderr); + perror(argv[1]); + exit(1); + } + + printf("Existing size was %ld\n", current); + + wanted = atol(argv[2]); + if (wanted < current) + { + if (lseek(fd, wanted, SEEK_SET) != wanted) + { + fprintf(stderr, "%s: can't seek: ", argv[0]); + fflush(stderr); + perror(argv[1]); + exit(1); + } + + write(fd, NULL, 0); + printf("Truncated to new size of %ld\n", wanted); + } + else + { + buf = calloc(BUFFER, 1); + if (buf == NULL) + { + fprintf(stderr, "%s: can't allocate %d bytes\n", + argv[0], BUFFER); + fflush(stderr); + exit(1); + } + + remain = wanted - current; + while (remain) + { + count = min(remain, BUFFER); + if (write(fd, buf, count) != count) + { + fprintf(stderr, "%s: can't write: ", argv[0]); + fflush(stderr); + perror(argv[1]); + exit(1); + } + + remain -= count; + } + + printf("Extended to new size of %ld\n", wanted); + } + + close(fd); + exit(0); + } + diff --git a/src/mkutil/setfsize.exe b/src/mkutil/setfsize.exe new file mode 100755 index 0000000000000000000000000000000000000000..19ee48516b08527a1012a5141785f165e86fde30 GIT binary patch literal 57390 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 + * license: GNU Public License version 2 + */ + +#ifdef VAX /* Nick */ +#include +#include +#include +#include +#define STDERR_FILENO 2 +#else +#include +#include +#include +#endif +#include +#include +#include + +void wr(char *s) { + write(STDERR_FILENO, s, strlen(s)); +} + +int getint(p, p1) + char *p; + char **p1; +{ + int v = 0; + for (v = 0; *p >= '0' && *p <= '9'; ++p) { + v *= 10; + v += *p - '0'; + } + *p1=p; + return v; +} + +#ifndef VAX /* Nick */ +int xconvtime(t1, t2, timet) + char *t1; + char *t2; + time_t *timet; +{ + int h,m,s,d,mm,y; + char *t, *dd, *e; + struct tm tt; + + t=t1; + dd=t2; + h=getint(t, &e); + if ((h<0) || (h>23) || (*e!=':')) return 0; + m=getint(t=++e, &e); + if ((m<0) || (m>59) || (*e!=':')) return 0; + s=getint(t=++e, &e); + if ((s<0) || (s>59) || (*e!=0)) return 0; + d=getint(dd, &e); + if ((d<1) || (d>31) || (*e!='/')) return 0; + mm=getint(dd=++e, &e); + if ((mm<1) || (mm>12) || (*e!='/')) return 0; + dd++; + y=getint(dd=++e, &e); + if (y<100) {if (y<80) y+=100;} else y-=1900; + if ((y<0) || (*e!=0)) return 0; + tt.tm_hour=h; + tt.tm_min=m; + tt.tm_sec=s; + tt.tm_year=y; + tt.tm_mon=mm-1; + tt.tm_mday=d; + *timet=mktime(&tt); + return 1; +} +#endif + +int main(argc, argv) + int argc; + char **argv; +{ + int i, fd, er = 0, ncreate = 0, modif = 0, mytime = 0, tmptim; + struct utimbuf utim; + struct stat statbuf; + char *p; + time_t now, mytimet; + + if (argc < 2) { +#ifdef VAX /* Nick */ + wr("usage: touch [-c] [-m] filename ...\n"); +#else + wr("usage: touch [-c] [-m] [-d time] filename ...\n"); +#endif + return 0; + } + argc--; + argv++; + while ((argc > 0) && (**argv == '-')) { + argc--; + p = *argv++ ; + while (*++p) switch (*p) { +#ifndef VAX /* Nick */ + case 'd': + if (!xconvtime(*argv, *(argv+1), &mytimet)) { + wr("Bad date/time format\n"); + return 0; + } + argc -= 2; + argv += 2; + mytime = 1; + break; +#endif + case 'c': + ncreate = 1; + break; + case 'm': + modif = 1; + break; + default: + wr("Unknown option(s) "); + wr(p); + wr(".\n"); + return 0; + } + } + for (i = 0; i < argc; i++) { + p = argv[i]; +#ifdef VAX /* Nick */ + if ((fd = open(p, O_RDWR)) < 0) { +#else + if ((fd = open(p, 2)) < 0) { +#endif + if (errno == ENOENT) { + if (!ncreate) { + er = creat(p, 0666); + if (er != -1) er = close(er); + } + } + } else { + close(fd); + time(&now); + stat(p, &statbuf); + utim.actime = now; + utim.modtime = now; +#ifndef VAX /* Nick */ + if (mytime) { + utim.actime = mytimet; + utim.modtime = mytimet; + } +#endif + if (modif) utim.actime = statbuf.st_atime; + er = utime(p, &utim); + } + if (er != 0) { + wr("Can't touch file "); + wr(p); + wr(".\n"); + } + } + return er; +} + diff --git a/src/mkutil/touch.exe b/src/mkutil/touch.exe new file mode 100755 index 0000000000000000000000000000000000000000..7fd6378ca129ec9e725042ccf385b2af1c2b95cb GIT binary patch literal 61484 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 literal 0 HcmV?d00001 diff --git a/src/sh/bsh/args.c b/src/sh/bsh/args.c new file mode 100755 index 00000000..fde27611 --- /dev/null +++ b/src/sh/bsh/args.c @@ -0,0 +1,135 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + +extern char * *copyargs(); +static struct dolnod *dolh; + +char flagadr[10]; + +char flagchar[] = { + 'x', 'n', 'v', 't', 's', 'i', 'e', 'r', 'k', 'u', 0 +}; +int flagval[] = { + execpr, noexec, readpr, oneflg, stdflg, intflg, errflg, rshflg, keyflg, setflg, 0 +}; + +/* ======== option handling ======== */ + + +int options(argc,argv) + char * *argv; + int argc; +{ + register char * cp; + register char * *argp=argv; + register char * flagc; + char * flagp; + + if ( argc>1 && *argp[1]=='-' + ) { cp=argp[1]; + flags &= ~(execpr|readpr); + while ( *++cp + ) { flagc=flagchar; + + while ( *flagc && *flagc != *cp ) { flagc++ ; } + if ( *cp == *flagc + ) { flags |= flagval[flagc-flagchar]; + } else if ( *cp=='c' && argc>2 && comdiv==0 + ) { comdiv=argp[2]; + argp[1]=argp[0]; argp++; argc--; + } else { failed(argv[1],badopt); + ; } + ; } + argp[1]=argp[0]; argc--; + ; } + + /* set up $- */ + flagc=flagchar; + flagp=flagadr; + while ( *flagc + ) { if ( flags&flagval[flagc-flagchar] + ) { *flagp++ = *flagc; + ; } + flagc++; + ; } + *flagp++=0; + + return(argc); +} + +int setargs(argi) + char * argi[]; +{ + /* count args */ + register char * *argp=argi; + register int argn=0; + + while ( Rcheat(*argp++)!=ENDARGS ) { argn++ ; } + + /* free old ones unless on for loop chain */ + freeargs(dolh); + dolh=(struct dolnod *)copyargs(argi,argn); /* sets dolv */ + assnum(&dolladr,dolc=argn-1); +} + +int freeargs(blk) + struct dolnod * blk; +{ + register char * *argp; + register struct dolnod * argr=0; + register struct dolnod * argblk; + + if ( argblk=blk + ) { argr = argblk->dolnxt; + if ( (--argblk->doluse)==0 + ) { for ( argp=(char **)argblk->dolarg; Rcheat(*argp)!=ENDARGS; argp++ + ) { free(*argp) ; } + free(argblk); + ; } + ; } + return (int)argr; +} + +static char * * copyargs(from, n) + char * from[]; +{ + register char * * np=(char **)alloc(sizeof(char **)*n+3*BYTESPERWORD); + register char * * fp=from; + register char * * pp=np; + + ((struct dolnod *)np)->doluse=1; /* use count */ + np=(char **)((struct dolnod *)np)->dolarg; + dolv=np; + + while ( n-- + ) { *np++ = make(*fp++) ; } + *np++ = ENDARGS; + return(pp); +} + +clearup() +{ + /* force `for' $* lists to go away */ + while ( argfor=(struct dolnod *)freeargs(argfor) ); + + /* clean up io files */ + while ( pop() ); +} + +struct dolnod * useargs() +{ + if ( dolh + ) { dolh->doluse++; + dolh->dolnxt=argfor; + return(argfor=dolh); + } else { return(0); + ; } +} diff --git a/src/sh/bsh/blok.c b/src/sh/bsh/blok.c new file mode 100755 index 00000000..12d61b66 --- /dev/null +++ b/src/sh/bsh/blok.c @@ -0,0 +1,116 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + + +/* + * storage allocator + * (circular first fit strategy) + */ + +#define BUSY 01 +#define busy(x) (Rcheat((x)->word)&BUSY) + +unsigned brkincr=BRKINCR; +struct blk * blokp; /*current search pointer*/ +#if 0 /* Nick */ +struct blk * bloktop; /*=BLK(end);*/ /*top of arena (last blok)*/ +#else +struct blk * bloktop=BLK(end); /*top of arena (last blok)*/ +#endif + + + +char * alloc(nbytes) + unsigned nbytes; +{ + register unsigned rbytes = round(nbytes+BYTESPERWORD,BYTESPERWORD); + + for (;;) { int c=0; + register struct blk * p = blokp; + register struct blk * q; + do { if ( !busy(p) + ) { while ( !busy(q = p->word) ) { p->word = q->word ; } + if ( ADR(q)-ADR(p) >= rbytes + ) { blokp = BLK(ADR(p)+rbytes); + if ( q > blokp + ) { blokp->word = p->word; + ; } + p->word=BLK(Rcheat(blokp)|BUSY); + return(ADR(p+1)); + ; } + ; } + q = p; p = BLK(Rcheat(p->word)&~BUSY); + } while ( p>q || (c++)==0 ); + addblok(rbytes); + } +} + +int addblok(reqd) + unsigned reqd; +{ + if ( stakbas!=staktop + ) { register char * rndstak; + register struct blk * blokstak; + + pushstak(0); + rndstak=(char *)round(staktop,BYTESPERWORD); + blokstak=BLK(stakbas)-1; + blokstak->word=stakbsy; stakbsy=blokstak; + bloktop->word=BLK(Rcheat(rndstak)|BUSY); + bloktop=BLK(rndstak); + ; } + reqd += brkincr; reqd &= ~(brkincr-1); + blokp=bloktop; + bloktop=bloktop->word=BLK(Rcheat(bloktop)+reqd); + bloktop->word=BLK(ADR(end)+1); + { + register char * stakadr=STK(bloktop+2); + staktop=movstr(stakbot,stakadr); + stakbas=stakbot=stakadr; + } +} + +int free(ap) + struct blk * ap; +{ + register struct blk * p; + + if ( (p=ap) && pword) &= ~BUSY; + ; } +} + +#ifdef DEBUG +chkbptr(ptr) + struct blk * ptr; +{ + int exf=0; + register struct blk * p = end; + register struct blk * q; + int us=0, un=0; + + for (;;) { + q = Rcheat(p->word)&~BUSY; + if ( p==ptr ) { exf++ ; } + if ( qbloktop ) { abort(3) ; } + if ( p==bloktop ) { break ; } + if ( busy(p) + ) { us += q-p; + } else { un += q-p; + ; } + if ( p>=q ) { abort(4) ; } + p=q; + } + if ( exf==0 ) { abort(1) ; } + prn(un); prc(' '); prn(us); prc('\n'); +} +#endif + diff --git a/src/sh/bsh/brkincr.h b/src/sh/bsh/brkincr.h new file mode 100755 index 00000000..6b43e257 --- /dev/null +++ b/src/sh/bsh/brkincr.h @@ -0,0 +1,3 @@ + +#define BRKINCR 01000 +#define BRKMAX 04000 diff --git a/src/sh/bsh/bsh.lnk b/src/sh/bsh/bsh.lnk new file mode 100755 index 00000000..ea1850a8 --- /dev/null +++ b/src/sh/bsh/bsh.lnk @@ -0,0 +1,33 @@ +-k ..\..\..\lib +-l libcb.lib +-l libsysb.lib +-l libiar.lib +-m +-u +-i +-o bsh +-bl RCODE=0x8100 +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\..\lib\c0b.rel +args +blok +builtin +cmd +ctype +error +expand +fault +io +macro +main +msg +name +print +service +setbrk +stak +string +word +xec +data diff --git a/src/sh/bsh/builtin.c b/src/sh/bsh/builtin.c new file mode 100755 index 00000000..739a6d38 --- /dev/null +++ b/src/sh/bsh/builtin.c @@ -0,0 +1,3 @@ + +builtin() +{return(0);} diff --git a/src/sh/bsh/cmd.c b/src/sh/bsh/cmd.c new file mode 100755 index 00000000..0f38b543 --- /dev/null +++ b/src/sh/bsh/cmd.c @@ -0,0 +1,425 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" +#include "sym.h" + +extern struct ionod * inout(); +extern int chkword(); +extern int chksym(); +extern struct trenod * term(); +extern struct trenod * makelist(); +extern struct trenod * list(); +extern struct regnod * syncase(); +extern struct trenod * item(); +extern int skipnl(); +extern int prsym(); +extern int synbad(); + + +/* ======== command line decoding ========*/ + + + + +struct trenod * makefork(flgs, i) + int flgs; + struct trenod * i; +{ + register struct trenod * t; + + t=(struct trenod *)getstak(FORKTYPE); + ((struct forknod *)t)->forktyp=flgs|TFORK; + ((struct forknod *)t)->forktre=i; + ((struct forknod *)t)->forkio=0; + return(t); +} + +static struct trenod * makelist(type,i,r) + int type; + struct trenod * i, * r; +{ + register struct trenod * t; + + if ( i==0 || r==0 + ) { synbad(); + } else { + t = (struct trenod *)getstak(LSTTYPE); + ((struct lstnod *)t)->lsttyp = type; + ((struct lstnod *)t)->lstlef = i; + ((struct lstnod *)t)->lstrit = r; + ; } + return(t); +} + +/* + * cmd + * empty + * list + * list & [ cmd ] + * list [ ; cmd ] + */ + +struct trenod * cmd(sym,flg) + register int sym; + int flg; +{ + register struct trenod * i, * e; + + i = list(flg); + + if ( wdval=='\n' + ) { if ( flg&NLFLG + ) { wdval=';'; chkpr('\n'); + ; } + } else if ( i==0 && (flg&MTFLG)==0 + ) { synbad(); + ; } + + switch ( wdval ) { + + case '&': + if ( i + ) { i = makefork(FINT|FPRS|FAMP, i); + } else { synbad(); + ; } + + case ';': + if ( e=cmd(sym,flg|MTFLG) + ) { i=makelist(TLST, i, e); + ; } + break; + + case EOFSYM: + if ( sym=='\n' + ) { break; + ; } + + default: + if ( sym + ) { chksym(sym); + ; } + + } + return(i); +} + +/* + * list + * term + * list && term + * list || term + */ + +static struct trenod * list(flg) +{ + register struct trenod * r; + register int b; + + r = term(flg); + while ( r && ((b=(wdval==ANDFSYM)) || wdval==ORFSYM) + ) { r = makelist((b ? TAND : TORF), r, term(NLFLG)); + ; } + return(r); +} + +/* + * term + * item + * item |^ term + */ + +static struct trenod * term(flg) +{ + register struct trenod * t; + + reserv++; + if ( flg&NLFLG + ) { skipnl(); + } else { word(); + ; } + + if ( (t=item((-1))) && (wdval=='^' || wdval=='|') + ) { return(makelist(TFIL, makefork(FPOU,t), makefork(FPIN|FPCL,term(NLFLG)))); + } else { return(t); + ; } +} + +static struct regnod * syncase(esym) + register int esym; +{ + skipnl(); + if ( wdval==esym + ) { return(0); + } else { + register struct regnod *r = (struct regnod *)getstak(REGTYPE); + r->regptr=0; + for (;;) { wdarg->argnxt=r->regptr; + r->regptr=wdarg; + if ( wdval || ( word()!=')' && wdval!='|' ) + ) { synbad(); + ; } + if ( wdval=='|' + ) { word(); + } else { break; + ; } + } + r->regcom=cmd(0,NLFLG|MTFLG); + if ( wdval==ECSYM + ) { r->regnxt=syncase(esym); + } else { chksym(esym); + r->regnxt=0; + ; } + return(r); + ; } +} + +/* + * item + * + * ( cmd ) [ < in ] [ > out ] + * word word* [ < in ] [ > out ] + * if ... then ... else ... fi + * for ... while ... do ... done + * case ... in ... esac + * begin ... end + */ + +static struct trenod * item(flag) + char flag; +{ + register struct trenod * t; + register struct ionod * io; + + if ( flag + ) { io=inout((struct ionod *)0); + } else { io=0; + ; } + + switch ( wdval ) { + + case CASYM: + { + t=(struct trenod *)getstak(SWTYPE); + chkword(); + ((struct swnod *)t)->swarg=wdarg->argval; + skipnl(); chksym(INSYM|BRSYM); + ((struct swnod *)t)->swlst=syncase(wdval==INSYM ? + ESSYM : KTSYM); + ((struct swnod *)t)->swtyp=TSW; + break; + } + + case IFSYM: + { + register int w; + t=(struct trenod *)getstak(IFTYPE); + ((struct ifnod *)t)->iftyp=TIF; + ((struct ifnod *)t)->iftre=cmd(THSYM,NLFLG); + ((struct ifnod *)t)->thtre=cmd(ELSYM|FISYM|EFSYM,NLFLG); + ((struct ifnod *)t)->eltre=((w=wdval)==ELSYM ? + cmd(FISYM,NLFLG) : + (w==EFSYM ? (wdval=IFSYM, item(0)) : 0)); + if ( w==EFSYM ) { return(t) ; } + break; + } + + case FORSYM: + { + t=(struct trenod *)getstak(FORTYPE); + ((struct fornod *)t)->fortyp=TFOR; + ((struct fornod *)t)->forlst=0; + chkword(); + ((struct fornod *)t)->fornam=wdarg->argval; + if ( skipnl()==INSYM + ) { chkword(); + ((struct fornod *)t)->forlst=(struct comnod *)item(0); + if ( wdval!='\n' && wdval!=';' + ) { synbad(); + ; } + chkpr(wdval); skipnl(); + ; } + chksym(DOSYM|BRSYM); + ((struct fornod *)t)->fortre=cmd(wdval==DOSYM ? + ODSYM : KTSYM, NLFLG); + break; + } + + case WHSYM: + case UNSYM: + { + t=(struct trenod *)getstak(WHTYPE); + ((struct whnod *)t)->whtyp=(wdval==WHSYM ? TWH : TUN); + ((struct whnod *)t)->whtre = cmd(DOSYM,NLFLG); + ((struct whnod *)t)->dotre = cmd(ODSYM,NLFLG); + break; + } + + case BRSYM: + t=cmd(KTSYM,NLFLG); + break; + + case '(': + { + register struct parnod * p; + p=(struct parnod *)getstak(PARTYPE); + p->partre=cmd(')',NLFLG); + p->partyp=TPAR; + t=makefork(0,p); + break; + } + + default: + if ( io==0 + ) { return(0); + ; } + + case 0: + { + register struct argnod * argp; + register struct argnod * *argtail; + register struct argnod * *argset=0; + int keywd=1; + t=(struct trenod *)getstak(COMTYPE); + ((struct comnod *)t)->comio=io; /*initial io chain*/ + argtail = &(((struct comnod *)t)->comarg); + while ( wdval==0 + ) { argp = wdarg; + if ( wdset && keywd + ) { + argp->argnxt=(struct argnod *)argset; + argset=(struct argnod **)argp; + } else { + *argtail=argp; + argtail = &(argp->argnxt); + keywd=flags&keyflg; + ; } + word(); + if ( flag + ) { ((struct comnod *)t)->comio= + inout(((struct comnod *)t)->comio); + ; } + ; } + + ((struct comnod *)t)->comtyp=TCOM; + ((struct comnod *)t)->comset=(struct argnod *)argset; + *argtail=0; + return(t); + } + + } + reserv++; word(); + if ( io=inout(io) + ) { t=makefork(0,t); t->treio=io; + ; } + return(t); +} + + +static int skipnl() +{ + while ( (reserv++, word()=='\n') ) { chkpr('\n') ; } + return(wdval); +} + +static struct ionod * inout(lastio) + struct ionod * lastio; +{ + register int iof; + register struct ionod * iop; + register char c; + + iof=wdnum; + + switch ( wdval ) { + + case DOCSYM: + iof |= IODOC; break; + + case APPSYM: + case '>': + if ( wdnum==0 ) { iof |= 1 ; } + iof |= IOPUT; + if ( wdval==APPSYM + ) { iof |= IOAPP; break; + ; } + + case '<': + if ( (c=nextc(0))=='&' + ) { iof |= IOMOV; + } else if ( c=='>' + ) { iof |= IORDW; + } else { peekc=c|MARK; + ; } + break; + + default: + return(lastio); + } + + chkword(); + iop=(struct ionod *)getstak(IOTYPE); + iop->ioname=wdarg->argval; + iop->iofile=iof; + if ( iof&IODOC + ) { iop->iolst=iopend; iopend=iop; + ; } + word(); iop->ionxt=inout(lastio); + return(iop); +} + +static int chkword() +{ + if ( word() + ) { synbad(); + ; } +} + +static int chksym(sym) +{ + register int x = sym&wdval; + if ( ((x&SYMFLG) ? x : sym) != wdval + ) { synbad(); + ; } +} + +static int prsym(sym) +{ + if ( sym&SYMFLG + ) { register struct sysnod * sp=reserved; + while ( sp->sysval + && sp->sysval!=sym + ) { sp++ ; } + prs(sp->sysnam); + } else if ( sym==EOFSYM + ) { prs(endoffile); + } else { if ( sym&SYMREP ) { prc(sym) ; } + if ( sym=='\n' + ) { prs("newline"); + } else { prc(sym); + ; } + ; } +} + +static int synbad() +{ + prp(); prs(synmsg); + if ( (flags&ttyflg)==0 + ) { prs(atline); prn(standin->flin); + ; } + prs(colon); + prc('`'); + if ( wdval + ) { prsym(wdval); + } else { prs(wdarg->argval); + ; } + prc('\''); prs(unexpected); + newline(); + exitsh(SYNBAD); +} diff --git a/src/sh/bsh/ctype.c b/src/sh/bsh/ctype.c new file mode 100755 index 00000000..0b05cded --- /dev/null +++ b/src/sh/bsh/ctype.c @@ -0,0 +1,110 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + +char _ctype1[] = +{ +/* 000 001 002 003 004 005 006 007 */ + _EOF, 0, 0, 0, 0, 0, 0, 0, + +/* bs ht nl vt np cr so si */ + 0, _TAB, _EOR, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + +/* sp ! " # $ % & ' */ + _SPC, 0, _DQU, 0, _DOL1, 0, _AMP, 0, + +/* ( ) * + , - . / */ + _BRA, _KET, 0, 0, 0, 0, 0, 0, + +/* 0 1 2 3 4 5 6 7 */ + 0, 0, 0, 0, 0, 0, 0, 0, + +/* 8 9 : ; < = > ? */ + 0, 0, 0, _SEM, _LT, 0, _GT, 0, + +/* @ A B C D E F G */ + 0, 0, 0, 0, 0, 0, 0, 0, + +/* H I J K L M N O */ + 0, 0, 0, 0, 0, 0, 0, 0, + +/* P Q R S T U V W */ + 0, 0, 0, 0, 0, 0, 0, 0, + +/* X Y Z [ \ ] ^ _ */ + 0, 0, 0, 0, _BSL, 0, _HAT, 0, + +/* ` a b c d e f g */ + _LQU, 0, 0, 0, 0, 0, 0, 0, + +/* h i j k l m n o */ + 0, 0, 0, 0, 0, 0, 0, 0, + +/* p q r s t u v w */ + 0, 0, 0, 0, 0, 0, 0, 0, + +/* x y z { | } ~ del */ + 0, 0, 0, 0, _BAR, 0, 0, 0 +}; + + +char _ctype2[] = +{ +/* 000 001 002 003 004 005 006 007 */ + 0, 0, 0, 0, 0, 0, 0, 0, + +/* bs ht nl vt np cr so si */ + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, + +/* sp ! " # $ % & ' */ + 0, _PCS, 0, _NUM, _DOL2, 0, 0, 0, + +/* ( ) * + , - . / */ + 0, 0, _AST, _PLS, 0, _MIN, 0, 0, + +/* 0 1 2 3 4 5 6 7 */ + _DIG, _DIG, _DIG, _DIG, _DIG, _DIG, _DIG, _DIG, + +/* 8 9 : ; < = > ? */ + _DIG, _DIG, 0, 0, 0, _EQ, 0, _QU, + +/* @ A B C D E F G */ + _AT, _UPC, _UPC, _UPC, _UPC, _UPC, _UPC, _UPC, + +/* H I J K L M N O */ + _UPC, _UPC, _UPC, _UPC, _UPC, _UPC, _UPC, _UPC, + +/* P Q R S T U V W */ + _UPC, _UPC, _UPC, _UPC, _UPC, _UPC, _UPC, _UPC, + +/* X Y Z [ \ ] ^ _ */ + _UPC, _UPC, _UPC, _SQB, 0, 0, 0, _UPC, + +/* ` a b c d e f g */ + 0, _LPC, _LPC, _LPC, _LPC, _LPC, _LPC, _LPC, + +/* h i j k l m n o */ + _LPC, _LPC, _LPC, _LPC, _LPC, _LPC, _LPC, _LPC, + +/* p q r s t u v w */ + _LPC, _LPC, _LPC, _LPC, _LPC, _LPC, _LPC, _LPC, + +/* x y z { | } ~ del */ + _LPC, _LPC, _LPC, _CBR, 0, _CKT, 0, 0 +}; + diff --git a/src/sh/bsh/ctype.h b/src/sh/bsh/ctype.h new file mode 100755 index 00000000..ac3a9480 --- /dev/null +++ b/src/sh/bsh/ctype.h @@ -0,0 +1,90 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + + +/* table 1 */ +#define T_SUB 01 +#define T_MET 02 +#define T_SPC 04 +#define T_DIP 010 +#define T_EOF 020 +#define T_EOR 040 +#define T_QOT 0100 +#define T_ESC 0200 + +/* table 2 */ +#define T_BRC 01 +#define T_DEF 02 +#define T_AST 04 +#define T_DIG 010 +#define T_FNG 020 +#define T_SHN 040 +#define T_IDC 0100 +#define T_SET 0200 + +/* for single chars */ +#define _TAB (T_SPC) +#define _SPC (T_SPC) +#define _UPC (T_IDC) +#define _LPC (T_IDC) +#define _DIG (T_DIG) +#define _EOF (T_EOF) +#define _EOR (T_EOR) +#define _BAR (T_DIP) +#define _HAT (T_MET) +#define _BRA (T_MET) +#define _KET (T_MET) +#define _SQB (T_FNG) +#define _AMP (T_DIP) +#define _SEM (T_DIP) +#define _LT (T_DIP) +#define _GT (T_DIP) +#define _LQU (T_QOT|T_ESC) +#define _BSL (T_ESC) +#define _DQU (T_QOT) +#define _DOL1 (T_SUB|T_ESC) + +#define _CBR T_BRC +#define _CKT T_DEF +#define _AST (T_AST|T_FNG) +#define _EQ (T_DEF) +#define _MIN (T_DEF|T_SHN) +#define _PCS (T_SHN) +#define _NUM (T_SHN) +#define _DOL2 (T_SHN) +#define _PLS (T_DEF|T_SET) +#define _AT (T_AST) +#define _QU (T_DEF|T_FNG|T_SHN) + +/* abbreviations for tests */ +#define _IDCH (T_IDC|T_DIG) +#define _META (T_SPC|T_DIP|T_MET|T_EOR) + +extern char _ctype1[]; + +/* nb these args are not call by value !!!! */ +#define space(c) (((c)&0200)==0 && _ctype1[c]&(T_SPC)) +#define eofmeta(c) (((c)&0200)==0 && _ctype1[c]&(_META|T_EOF)) +#define qotchar(c) (((c)&0200)==0 && _ctype1[c]&(T_QOT)) +#define eolchar(c) (((c)&0200)==0 && _ctype1[c]&(T_EOR|T_EOF)) +#define dipchar(c) (((c)&0200)==0 && _ctype1[c]&(T_DIP)) +#define subchar(c) (((c)&0200)==0 && _ctype1[c]&(T_SUB|T_QOT)) +#define escchar(c) (((c)&0200)==0 && _ctype1[c]&(T_ESC)) + +extern char _ctype2[]; + +#define digit(c) (((c)&0200)==0 && _ctype2[c]&(T_DIG)) +#define fngchar(c) (((c)&0200)==0 && _ctype2[c]&(T_FNG)) +#define dolchar(c) (((c)&0200)==0 && _ctype2[c]&(T_AST|T_BRC|T_DIG|T_IDC|T_SHN)) +#define defchar(c) (((c)&0200)==0 && _ctype2[c]&(T_DEF)) +#define setchar(c) (((c)&0200)==0 && _ctype2[c]&(T_SET)) +#define digchar(c) (((c)&0200)==0 && _ctype2[c]&(T_AST|T_DIG)) +#define letter(c) (((c)&0200)==0 && _ctype2[c]&(T_IDC)) +#define alphanum(c) (((c)&0200)==0 && _ctype2[c]&(_IDCH)) +#define astchar(c) (((c)&0200)==0 && _ctype2[c]&(T_AST)) diff --git a/src/sh/bsh/data.c b/src/sh/bsh/data.c new file mode 100755 index 00000000..c806e041 --- /dev/null +++ b/src/sh/bsh/data.c @@ -0,0 +1,89 @@ +/* data.c by Nick for UNIX V7 Bourne shell */ + +#include "defs.h" + +/* temp files and io */ +/* int output; */ /* done in main.c and given value = 2 */ +int ioset; +struct ionod * iotemp; /* files to be deleted sometime */ +struct ionod * iopend; /* documents waiting to be read at NL */ + +/* substitution */ +int dolc; +char * *dolv; +struct dolnod * argfor; +struct argnod * gchain; + +/* stak stuff */ + +/* A chain of ptrs of stack blocks that + * have become covered by heap allocation. + * `tdystak' will return them to the heap. + */ +struct blk * stakbsy; + +/* Base of the entire stack */ +char * stakbas; + +/* Top of entire stack */ +char * brkend; + +/* Base of current item */ +/* char * stakbot; */ + +/* Top of current item */ +char * staktop; + +/* name tree and words */ +/* struct sysnod reserved[]; */ +int wdval; +int wdnum; +struct argnod * wdarg; +int wdset; /* Nick */ +int dset; +char reserv; + +/* special names */ +/* char flagadr[]; */ +char * cmdadr; +char * exitadr; +char * dolladr; +char * pcsadr; +char * pidadr; + +/* char defpath[]; */ + +/* transput */ +/* char tmpout[]; */ +char * tmpnam; +int serial; +/* struct fileblk * standin; */ +int peekc; +char * comdiv; +/* char devnull[]; */ + +/* flags */ +int flags; + +/* error exits from various parts of shell */ +jmp_buf subshell; +jmp_buf errshell; + +char trapnote; +/* char * trapcom[]; */ +/* char trapflg[]; */ + +/* execflgs */ +int exitval; +char execbrk; +int loopcnt; +int breakcnt; + +char nosubst; /* Nick, set by trim() */ + +#if 0 /* Nick */ +int end; +#else +address end[1]; +#endif + diff --git a/src/sh/bsh/defs.h b/src/sh/bsh/defs.h new file mode 100755 index 00000000..6ca03ccc --- /dev/null +++ b/src/sh/bsh/defs.h @@ -0,0 +1,302 @@ + +/* + * UNIX shell + */ + +#define NULL 0 /* Nick */ +#define read _read /* Nick, very temporary */ +#define write _write /* Nick, very temporary */ +int ioctl(int fd, int request, ...); /* IAR don't use regparams! */ +int open(char *name, unsigned int flag, ...); /* IAR don't use regparams! */ + +/* error exits from various parts of shell */ +#define ERROR 1 +#define SYNBAD 2 +#define SIGFAIL 3 +#define SIGFLG 0200 + +/* command tree */ +#define FPRS 020 +#define FINT 040 +#define FAMP 0100 +#define FPIN 0400 +#define FPOU 01000 +#define FPCL 02000 +#define FCMD 04000 +#define COMMSK 017 + +#define TCOM 0 +#define TPAR 1 +#define TFIL 2 +#define TLST 3 +#define TIF 4 +#define TWH 5 +#define TUN 6 +#define TSW 7 +#define TAND 8 +#define TORF 9 +#define TFORK 10 +#define TFOR 11 + +/* execute table */ +#define SYSSET 1 +#define SYSCD 2 +#define SYSEXEC 3 +#define SYSLOGIN 4 +#define SYSTRAP 5 +#define SYSEXIT 6 +#define SYSSHFT 7 +#define SYSWAIT 8 +#define SYSCONT 9 +#define SYSBREAK 10 +#define SYSEVAL 11 +#define SYSDOT 12 +#define SYSRDONLY 13 +#define SYSTIMES 14 +#define SYSXPORT 15 +#define SYSNULL 16 +#define SYSREAD 17 +#define SYSTST 18 +#define SYSUMASK 19 + +/* used for input and output of shell */ +#define INIO 10 +#define OTIO 11 + +/*io nodes*/ +#define USERIO 10 +#define IOUFD 15 +#define IODOC 16 +#define IOPUT 32 +#define IOAPP 64 +#define IOMOV 128 +#define IORDW 256 +#define INPIPE 0 +#define OTPIPE 1 + +/* arg list terminator */ +#define ENDARGS 0 + +#include "mode.h" +#include "name.h" + + +/* result type declarations */ +#define alloc malloc +char * alloc(); +int addblok(); +char * make(); +char * movstr(); +struct trenod * cmd(); +struct trenod * makefork(); +struct namnod * lookup(); +int setname(); +int setargs(); +struct dolnod * useargs(); +float expr(); +char * catpath(); +char * getpath(); +char * *scan(); +char * mactrim(); +char * macro(); +char * execs(); +int await(); +int post(); +char * copyto(); +int exname(); +char * staknam(); +int printnam(); +int printflg(); +int prs(); +int prc(); +int getenv(); +char * *setenv(); + +#define attrib(n,f) (n->namflg |= f) +#define round(a,b) (((int)((ADR(a)+b)-1))&~((b)-1)) +#define closepipe(x) (close(x[INPIPE]), close(x[OTPIPE])) +#define eq(a,b) (cf(a,b)==0) +#define max(a,b) ((a)>(b)?(a):(b)) +#define assert(x) ; + +/* temp files and io */ +extern int output; +extern int ioset; +extern struct ionod * iotemp; /* files to be deleted sometime */ +extern struct ionod * iopend; /* documents waiting to be read at NL */ + +/* substitution */ +extern int dolc; +extern char * *dolv; +extern struct dolnod * argfor; +extern struct argnod * gchain; + +/* stack */ +#define BLK(x) ((struct blk *)(x)) +#define BYT(x) ((char *)(x)) +#define STK(x) ((char *)(x)) +#define ADR(x) ((char*)(x)) + +/* stak stuff */ +#include "stak.h" + +/* string constants */ +extern char atline[]; +extern char readmsg[]; +extern char colon[]; +extern char minus[]; +extern char nullstr[]; +extern char sptbnl[]; +extern char unexpected[]; +extern char endoffile[]; +extern char synmsg[]; + +/* name tree and words */ +extern struct sysnod reserved[]; +extern int wdval; +extern int wdnum; +extern struct argnod * wdarg; +extern int wdset; /* Nick */ +extern int dset; +extern char reserv; + +/* prompting */ +extern char stdprompt[]; +extern char supprompt[]; +extern char profile[]; + +/* built in names */ +extern struct namnod fngnod; +extern struct namnod ifsnod; +extern struct namnod homenod; +extern struct namnod mailnod; +extern struct namnod pathnod; +extern struct namnod ps1nod; +extern struct namnod ps2nod; + +/* special names */ +extern char flagadr[]; +extern char * cmdadr; +extern char * exitadr; +extern char * dolladr; +extern char * pcsadr; +extern char * pidadr; + +extern char defpath[]; + +/* names always present */ +extern char mailname[]; +extern char homename[]; +extern char pathname[]; +extern char fngname[]; +extern char ifsname[]; +extern char ps1name[]; +extern char ps2name[]; + +/* transput */ +extern char tmpout[]; +extern char * tmpnam; +extern int serial; +#define TMPNAM 7 +extern struct fileblk * standin; +#define input (standin->fdes) +#define eof (standin->feof) +extern int peekc; +extern char * comdiv; +extern char devnull[]; + +/* flags */ +#define noexec 01 +#define intflg 02 +#define prompt 04 +#define setflg 010 +#define errflg 020 +#define ttyflg 040 +#define forked 0100 +#define oneflg 0200 +#define rshflg 0400 +#define waiting 01000 +#define stdflg 02000 +#define execpr 04000 +#define readpr 010000 +#define keyflg 020000 +extern int flags; + +/* error exits from various parts of shell */ +#include +extern jmp_buf subshell; +extern jmp_buf errshell; + +/* fault handling */ +#include "brkincr.h" +extern unsigned brkincr; + +#define MINTRAP 0 +#define MAXTRAP 17 + +#define INTR 2 +#define QUIT 3 +#define MEMF 11 +#define ALARM 14 +#define KILL 15 +#define TRAPSET 2 +#define SIGSET 4 +#define SIGMOD 8 + +int fault(); +extern char trapnote; +extern char * trapcom[]; +extern char trapflg[]; + +/* name tree and words */ +extern char * *environ; +extern char numbuf[]; +extern char export[]; +extern char readonly[]; + +/* execflgs */ +extern int exitval; +extern char execbrk; +extern int loopcnt; +extern int breakcnt; + +/* messages */ +extern char mailmsg[]; +extern char coredump[]; +extern char badopt[]; +extern char badparam[]; +extern char badsub[]; +extern char nospace[]; +extern char notfound[]; +extern char badtrap[]; +extern char baddir[]; +extern char badshift[]; +extern char illegal[]; +extern char restricted[]; +extern char execpmsg[]; +extern char notid[]; +extern char wtfailed[]; +extern char badcreate[]; +extern char piperr[]; +extern char badopen[]; +extern char badnum[]; +extern char arglist[]; +#if 1 /* Nick */ +extern char execformat[]; +extern char tooshort[]; +extern char noalign[]; +#endif +extern char txtbsy[]; +extern char toobig[]; +extern char badexec[]; +extern char notfound[]; +extern char badfile[]; + +#if 0 /* Nick */ +extern int end; +#else +extern address end[]; +#endif + +#include "ctype.h" + diff --git a/src/sh/bsh/dup.h b/src/sh/bsh/dup.h new file mode 100755 index 00000000..f3d12daa --- /dev/null +++ b/src/sh/bsh/dup.h @@ -0,0 +1,13 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#if 0 /* Nick... in V7 unix this differentiates dup2() from dup() */ +#define DUPFLG 0100 +#endif + diff --git a/src/sh/bsh/error.c b/src/sh/bsh/error.c new file mode 100755 index 00000000..1580d1b3 --- /dev/null +++ b/src/sh/bsh/error.c @@ -0,0 +1,83 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + + +/* ======== error handling ======== */ + +exitset() +{ + assnum(&exitadr,exitval); +} + +sigchk() +{ + /* Find out if it is time to go away. + * `trapnote' is set to SIGSET when fault is seen and + * no trap has been set. + */ + if ( trapnote&SIGSET + ) { exitsh(SIGFAIL); + ; } +} + +failed(s1,s2) + char * s1, * s2; +{ + prp(); prs(s1); + if ( s2 + ) { prs(colon); prs(s2); + ; } + newline(); exitsh(ERROR); +} + +error(s) + char * s; +{ + failed(s,NULL); +} + +exitsh(xno) + int xno; +{ + /* Arrive here from `FATAL' errors + * a) exit command, + * b) default trap, + * c) fault with no trap set. + * + * Action is to return to command level or exit. + */ + exitval=xno; + if ( (flags & (forked|errflg|ttyflg)) != ttyflg + ) { done(); + } else { clearup(); + longjmp(errshell,1); + ; } +} + +done() +{ + register char * t; + if ( t=trapcom[0] + ) { trapcom[0]=0; /*should free but not long */ + execexp(t,0); + ; } + rmtemp(0); + exit(exitval); +} + +rmtemp(base) + struct ionod * base; +{ + while ( iotemp>base + ) { unlink(iotemp->ioname); + iotemp=iotemp->iolst; + ; } +} diff --git a/src/sh/bsh/expand.c b/src/sh/bsh/expand.c new file mode 100755 index 00000000..b0ec4b58 --- /dev/null +++ b/src/sh/bsh/expand.c @@ -0,0 +1,198 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" +#if 1 /* Nick */ +#include +#else +#include +#endif +#define DIRSIZ 15 +#include +#if 1 /* Nick */ +#include +#else +#include +#endif + + + +/* globals (file name generation) + * + * "*" in params matches r.e ".*" + * "?" in params matches r.e. "." + * "[...]" in params matches character class + * "[...a-z...]" in params matches a through z. + * + */ + +extern int addg(); + + +int expand(as,rflg) + char * as; +{ + int count, dirf; + char dir=0; + char * rescan = 0; + register char * s, * cs; + struct argnod * schain = gchain; + struct direct entry; + struct stat statb; + + if ( trapnote&SIGSET ) { return(0); ; } + + s=cs=as; entry.d_name[DIRSIZ-1]=0; /* to end the string */ + + /* check for meta chars */ + { + register char slash; slash=0; + while ( !fngchar(*cs) + ) { if ( *cs++==0 + ) { if ( rflg && slash ) { break; } else { return(0) ; } + } else if ( *cs=='/' + ) { slash++; + ; } + ; } + } + + for (;;) { if ( cs==s + ) { s=nullstr; + break; + } else if ( *--cs == '/' + ) { *cs=0; + if ( s==cs ) { s="/" ; } + break; + ; } + } + if ( stat(s,&statb)>=0 + && (statb.st_mode&S_IFMT)==S_IFDIR + && (dirf=open(s,0))>0 + ) { dir++; + ; } + count=0; + if ( *cs==0 ) { *cs++=0200 ; } + if ( dir + ) { /* check for rescan */ + register char * rs; rs=cs; + + do { if ( *rs=='/' ) { rescan=rs; *rs=0; gchain=0 ; } + } while ( *rs++ ); + + while ( read(dirf, &entry, 16) == 16 && (trapnote&SIGSET) == 0 + ) { if ( entry.d_ino==0 || + (*entry.d_name=='.' && *cs!='.') + ) { continue; + ; } + if ( gmatch(entry.d_name, cs) + ) { addg(s,entry.d_name,rescan); count++; + ; } + ; } + close(dirf); + + if ( rescan + ) { register struct argnod * rchain; + rchain=gchain; gchain=schain; + if ( count + ) { count=0; + while ( rchain + ) { count += expand(rchain->argval,1); + rchain=rchain->argnxt; + ; } + ; } + *rescan='/'; + ; } + ; } + + { + register char c; + s=as; + while ( c = *s + ) { *s++=(c&0177?c:'/') ; } + } + return(count); +} + +gmatch(s, p) + register char * s, * p; +{ + register int scc; + char c; + + if ( scc = *s++ + ) { if ( (scc &= 0177)==0 + ) { scc=0200; + ; } + ; } + switch ( c = *p++ ) { + + case '[': + {char ok; int lc; + ok=0; lc=077777; + while ( c = *p++ + ) { if ( c==']' + ) { return(ok?gmatch(s,p):0); + } else if ( c=='-' + ) { if ( lc<=scc && scc<=(*p++) ) { ok++ ; } + } else { if ( scc==(lc=(c&0177)) ) { ok++ ; } + ; } + ; } + return(0); + } + + default: + if ( (c&0177)!=scc ) { return(0) ; } + + case '?': + return(scc?gmatch(s,p):0); + + case '*': + if ( *p==0 ) { return(1) ; } + --s; + while ( *s + ) { if ( gmatch(s++,p) ) { return(1) ; } ; } + return(0); + + case 0: + return(scc==0); + } +} + +static int addg(as1,as2,as3) + char * as1, * as2, * as3; +{ + register char * s1, * s2; + register int c; + + s2 = locstak()+BYTESPERWORD; + + s1=as1; + while ( c = *s1++ + ) { if ( (c &= 0177)==0 + ) { *s2++='/'; + break; + ; } + *s2++=c; + ; } + s1=as2; + while ( *s2 = *s1++ ) { s2++ ; } + if ( s1=as3 + ) { *s2++='/'; + while ( *s2++ = *++s1 ); + ; } + makearg(endstak(s2)); +} + +makearg(args) + register char * args; +{ + ((struct argnod *)args)->argnxt=gchain; + gchain=(struct argnod *)args; +} + diff --git a/src/sh/bsh/fault.c b/src/sh/bsh/fault.c new file mode 100755 index 00000000..632bb74a --- /dev/null +++ b/src/sh/bsh/fault.c @@ -0,0 +1,109 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + + +char * trapcom[MAXTRAP]; +char trapflg[MAXTRAP]; + +/* ======== fault handling routines ======== */ + + +int fault(sig) + register int sig; +{ + register int flag; + + signal(sig,fault); + if ( sig==MEMF + ) { if ( setbrk(brkincr) == -1 + ) { error(nospace); + ; } + } else if ( sig==ALARM + ) { if ( flags&waiting + ) { done(); + ; } + } else { flag = (trapcom[sig] ? TRAPSET : SIGSET); + trapnote |= flag; + trapflg[sig] |= flag; + ; } +} + +stdsigs() +{ + ignsig(QUIT); + getsig(INTR); + getsig(MEMF); + getsig(ALARM); +} + +ignsig(n) +{ + register int s, i; + + if ( (s=signal(i=n,1)&01)==0 + ) { trapflg[i] |= SIGMOD; + ; } + return(s); +} + +getsig(n) +{ + register int i; + + if ( trapflg[i=n]&SIGMOD || ignsig(i)==0 + ) { signal(i,fault); + ; } +} + +oldsigs() +{ + register int i; + register char * t; + + i=MAXTRAP; + while ( i-- + ) { t=trapcom[i]; + if ( t==0 || *t + ) { clrsig(i); + ; } + trapflg[i]=0; + ; } + trapnote=0; +} + +clrsig(i) + int i; +{ + free(trapcom[i]); trapcom[i]=0; + if ( trapflg[i]&SIGMOD + ) { signal(i,fault); + trapflg[i] &= ~SIGMOD; + ; } +} + +chktrap() +{ + /* check for traps */ + register int i=MAXTRAP; + register char * t; + + trapnote &= ~TRAPSET; + while ( --i + ) { if ( trapflg[i]&TRAPSET + ) { trapflg[i] &= ~TRAPSET; + if ( t=trapcom[i] + ) { int savxit=exitval; + execexp(t,0); + exitval=savxit; exitset(); + ; } + ; } + ; } +} diff --git a/src/sh/bsh/io.c b/src/sh/bsh/io.c new file mode 100755 index 00000000..d037496c --- /dev/null +++ b/src/sh/bsh/io.c @@ -0,0 +1,138 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" +#include "dup.h" + + +/* ======== input output and file copying ======== */ + +initf(fd) + int fd; +{ + register struct fileblk * f=standin; + + f->fdes=fd; f->fsiz=((flags&(oneflg|ttyflg))==0 ? BUFSIZ : 1); + f->fnxt=f->fend=f->fbuf; f->feval=0; f->flin=1; + f->feof=0; +} + +estabf(s) + register char * s; +{ + register struct fileblk * f; + + (f=standin)->fdes = -1; + f->fend=length(s)+(f->fnxt=s); + f->flin=1; + return(f->feof=(s==0)); +} + +push(af) + struct fileblk * af; +{ + register struct fileblk * f; + + (f=af)->fstak=standin; + f->feof=0; f->feval=0; + standin=f; +} + +pop() +{ + register struct fileblk * f; + + if ( (f=standin)->fstak + ) { if ( f->fdes>=0 ) { close(f->fdes) ; } + standin=f->fstak; + return((-1)); + } else { return(0); + ; } +} + +chkpipe(pv) + int *pv; +{ + if ( pipe(pv)<0 || pv[INPIPE]<0 || pv[OTPIPE]<0 + ) { error(piperr); + ; } +} + +chkopen(idf) + char * idf; +{ + register int rc; + + if ( (rc=open(idf,0))<0 + ) { failed(idf,badopen); + } else { return(rc); + ; } +} + +rename(f1,f2) + register int f1, f2; +{ + if ( f1!=f2 + ) { +#if 1 /* Nick */ + dup2(f1, f2); +#else + dup(f1|DUPFLG, f2); +#endif + close(f1); + if ( f2==0 ) { ioset|=1 ; } + ; } +} + +create(s) + char * s; +{ + register int rc; + + if ( (rc=creat(s,0666))<0 + ) { failed(s,badcreate); + } else { return(rc); + ; } +} + +tmpfil() +{ + itos(serial++); movstr(numbuf,tmpnam); + return(create(tmpout)); +} + +/* set by trim */ +extern char nosubst; + +copy(ioparg) + struct ionod * ioparg; +{ + char c, *ends; + register char *cline, *clinep; + int fd; + register struct ionod * iop; + + if ( iop=ioparg + ) { copy(iop->iolst); + ends=mactrim(iop->ioname); if ( nosubst ) { iop->iofile &= ~IODOC ; } + fd=tmpfil(); + iop->ioname=cpystak(tmpout); + iop->iolst=iotemp; iotemp=iop; + cline=locstak(); + + for (;;) { clinep=cline; chkpr('\n'); + while ( (c = (nosubst ? readc() : nextc(*ends)), !eolchar(c)) ) { *clinep++ = c ; } + *clinep=0; + if ( eof || eq(cline,ends) ) { break ; } + *clinep++='\n'; + write(fd,cline,clinep-cline); + } + close(fd); + ; } +} diff --git a/src/sh/bsh/junk/REPL8.PMM b/src/sh/bsh/junk/REPL8.PMM new file mode 100755 index 00000000..9618caf7 --- /dev/null +++ b/src/sh/bsh/junk/REPL8.PMM @@ -0,0 +1,33 @@ +; repl8.pmm + +xfargs.c .9 xe +xfblok.c .9 xe +xfbrkincr.h .9 xe +xfbuiltin.c .9 xe +xfcmd.c .9 xe +xfctype.c .9 xe +xfctype.h .9 xe +xfdefs.h .9 xe +xfdup.h .9 xe +xferror.c .9 xe +xfexpand.c .9 xe +xffault.c .9 xe +xfio.c .9 xe +xfmac.h .9 xe +xfmacro.c .9 xe +xfmain.c .9 xe +xfmode.h .9 xe +xfmsg.c .9 xe +xfname.c .9 xe +xfname.h .9 xe +xfprint.c .9 xe +xfservice.c .9 xe +xfsetbrk.c .9 xe +xfstak.c .9 xe +xfstak.h .9 xe +xfstring.c .9 xe +xfsym.h .9 xe +xftimeout.h .9 xe +xfword.c .9 xe +xfxec.c .9 xe + diff --git a/src/sh/bsh/junk/REPL9X.PMM b/src/sh/bsh/junk/REPL9X.PMM new file mode 100755 index 00000000..d0fcb3d4 --- /dev/null +++ b/src/sh/bsh/junk/REPL9X.PMM @@ -0,0 +1,11 @@ +; repl9.pmm + +ua [qr e uc + + @e] +ua [qr e uc# +] +ua [qr e uc#%%%% @e] +ua i#include "nick.h" + + diff --git a/src/sh/bsh/junk/REPL9Y.PMM b/src/sh/bsh/junk/REPL9Y.PMM new file mode 100755 index 00000000..eb7f9375 --- /dev/null +++ b/src/sh/bsh/junk/REPL9Y.PMM @@ -0,0 +1,105 @@ +; repl9.pmm + +ua [qr e uc + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +] +ua [qr e uc%%%%#] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] +ua [qr e uc FIXME  ] + diff --git a/src/sh/bsh/junk/X.bat b/src/sh/bsh/junk/X.bat new file mode 100755 index 00000000..5c94724d --- /dev/null +++ b/src/sh/bsh/junk/X.bat @@ -0,0 +1 @@ +iccz80 -S -w -mb -v1 -z -A -I..\..\..\..\include\ a diff --git a/src/sh/bsh/junk/makefile b/src/sh/bsh/junk/makefile new file mode 100755 index 00000000..bf520ab0 --- /dev/null +++ b/src/sh/bsh/junk/makefile @@ -0,0 +1,34 @@ +CFLAGS = -n -s -O + +all: sh + +cp: sh + cp sh /bin/sh + rm sh *.o + +cmp: sh + cmp sh /bin/sh + rm sh *.o + +sh: setbrk.o +sh: builtin.o blok.o stak.o +sh: cmd.o fault.o main.o +sh: word.o string.o name.o args.o +sh: xec.o service.o error.o io.o +sh: print.o macro.o expand.o +sh: ctype.o msg.o +blok.o: brkincr.h +fault.o: brkincr.h +main.o: brkincr.h +stak.o: brkincr.h + +sh:; cc -o sh -n -s *.o + +newsys:; :newsys file=msg; make sh +install:; :install +diff:; :diff +list:; list Makefile *.h *.s *.c + +.c.o:; cc -O -c $< +.c.s:; cc -O -S -o $*.s $< +.s.o:; as - -o $*.o /usr/include/sys.s $< diff --git a/src/sh/bsh/junk/nick.h b/src/sh/bsh/junk/nick.h new file mode 100755 index 00000000..f2682550 --- /dev/null +++ b/src/sh/bsh/junk/nick.h @@ -0,0 +1,82 @@ +#define LOCAL static +#define PROC extern +#define TYPE typedef +#define STRUCT TYPE struct +#define UNION TYPE union +#define REG register +#define IF if ( +#define THEN ) { +#define ELSE } else { +#define ELIF } else if ( +#define FI ; } +#define BEGIN { +#define END } +#define SWITCH switch ( +#define IN ) { +#define ENDSW } +#define FOR for ( +#define WHILE while ( +#define DO ) { +#define OD ; } +#define REP do { +#define PER } while ( +#define DONE ); +#define LOOP for (;;) { +#define POOL } +#define SKIP ; +#define DIV / +#define REM % +#define NEQ ^ +#define ANDF && +#define ORF || +#define TRUE (-1) +#define FALSE 0 +#define LOBYTE 0377 +#define STRIP 0177 +#define QUOTE 0200 +#define EOF 0 +#define NL '\n' +#define SP ' ' +#define LQ '`' +#define RQ '\'' +#define MINUS '-' +#define COLON ':' +#define MAX(a,b) max(a,b) +#define CHAR char +#define BOOL char +#define UFD int +#define INT int +#define REAL float +#define ADDRESS char * FIXME +#define L_INT long int +#define VOID int +#define POS unsigned +#define STRING char * FIXME +#define MSG char [] FIXME +#define PIPE int [] FIXME +#define STKPTR char * FIXME +#define BYTPTR char * FIXME +#define STATBUF struct stat +#define BLKPTR struct blk * FIXME +#define FILEBLK struct fileblk +#define FILEHDR struct filehdr +#define FILE struct fileblk * FIXME +#define TREPTR struct trenod * FIXME +#define FORKPTR struct forknod * FIXME +#define COMPTR struct comnod * FIXME +#define SWPTR struct swnod * FIXME +#define REGPTR struct regnod * FIXME +#define PARPTR struct parnod * FIXME +#define IFPTR struct ifnod * FIXME +#define WHPTR struct whnod * FIXME +#define FORPTR struct fornod * FIXME +#define LSTPTR struct lstnod * FIXME +#define ARGPTR struct argnod * FIXME +#define DOLPTR struct dolnod * FIXME +#define IOPTR struct ionod * FIXME +#define NAMNOD struct namnod +#define NAMPTR struct namnod * FIXME +#define SYSNOD struct sysnod +#define SYSPTR struct sysnod * FIXME +#define SYSTAB struct sysnod [] FIXME +#define NIL NULL diff --git a/src/sh/bsh/junk/pre.bat b/src/sh/bsh/junk/pre.bat new file mode 100755 index 00000000..6278cacb --- /dev/null +++ b/src/sh/bsh/junk/pre.bat @@ -0,0 +1,3 @@ +cl /EP /C %1 > a +mv %1 old_%1 +mv a %1 diff --git a/src/sh/bsh/junk/preall.bat b/src/sh/bsh/junk/preall.bat new file mode 100755 index 00000000..43294d97 --- /dev/null +++ b/src/sh/bsh/junk/preall.bat @@ -0,0 +1,32 @@ +call pre args.c +call pre blok.c +call pre brkincr.h +call pre builtin.c +call pre cmd.c +call pre ctype.c +call pre ctype.h +call pre defs.h +call pre dup.h +call pre error.c +call pre expand.c +call pre fault.c +call pre io.c +call pre mac.h +call pre macro.c +call pre main.c +call pre mode.h +call pre msg.c +call pre name.c +call pre name.h +call pre nick.h +call pre print.c +call pre service.c +call pre setbrk.c +call pre silly.c +call pre stak.c +call pre stak.h +call pre string.c +call pre sym.h +call pre timeout.h +call pre word.c +call pre xec.c diff --git a/src/sh/bsh/junk/silly.c b/src/sh/bsh/junk/silly.c new file mode 100755 index 00000000..783126a1 --- /dev/null +++ b/src/sh/bsh/junk/silly.c @@ -0,0 +1,484 @@ + + +/*** +*stdio.h - definitions/declarations for standard I/O routines +* +* Copyright (c) 1985-1997, Microsoft Corporation. All rights reserved. +* +*Purpose: +* This file defines the structures, values, macros, and functions +* used by the level 2 I/O ("standard I/O") routines. +* [ANSI/System V] +* +* [Public] +* +****/ + + +#pragma once + + + + + + + + + + + +/* + * Currently, all MS C compilers for Win32 platforms default to 8 byte + * alignment. + */ +#pragma pack(push,8) + + + + + + + + +/* Define _CRTIMP */ + + + + + + + + + + +/* Define __cdecl for non-Microsoft compilers */ + + + + + +/* Define _CRTAPI1 (for compatibility with the NT SDK) */ + + + + + + + + + + + +typedef unsigned int size_t; + + + + + + +typedef unsigned short wchar_t; + + + + + +typedef wchar_t wint_t; +typedef wchar_t wctype_t; + + + + + + + + + + + + +typedef char * va_list; + + + + + +/* Buffered I/O macros */ + + + + + + + + +/* + * Default number of supported streams. _NFILE is confusing and obsolete, but + * supported anyway for backwards compatibility. + */ + + + + + + +/* + * Number of entries in _iob[] (declared below). Note that _NSTREAM_ must be + * greater than or equal to _IOB_ENTRIES. + */ + + + + + + + + + + + + + + + + + + + + +struct _iobuf { + char *_ptr; + int _cnt; + char *_base; + int _flag; + int _file; + int _charbuf; + int _bufsiz; + char *_tmpfname; + }; +typedef struct _iobuf FILE; + + + + + + +/* Directory where temporary files may be created. */ + + + + + + + + + +/* L_tmpnam = size of P_tmpdir + * + 1 (in case P_tmpdir does not end in "/") + * + 12 (for the filename string) + * + 1 (for the null terminator) + */ + + + + + + + + + + + + + + + +/* Seek method constants */ + + + + + + + + + + + + +/* Define NULL pointer value */ + + + + + + + + + + +/* Declare _iob[] array */ + + + extern FILE _iob[]; + + + +/* Define file position type */ + + + + + + + + + +typedef __int64 fpos_t; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/* Function prototypes */ + + + + int __cdecl _filbuf(FILE *); + int __cdecl _flsbuf(int, FILE *); + + + + + FILE * __cdecl _fsopen(const char *, const char *, int); + + + void __cdecl clearerr(FILE *); + int __cdecl fclose(FILE *); + int __cdecl _fcloseall(void); + + + + + FILE * __cdecl _fdopen(int, const char *); + + + int __cdecl feof(FILE *); + int __cdecl ferror(FILE *); + int __cdecl fflush(FILE *); + int __cdecl fgetc(FILE *); + int __cdecl _fgetchar(void); + int __cdecl fgetpos(FILE *, fpos_t *); + char * __cdecl fgets(char *, int, FILE *); + + + + + int __cdecl _fileno(FILE *); + + + int __cdecl _flushall(void); + FILE * __cdecl fopen(const char *, const char *); + int __cdecl fprintf(FILE *, const char *, ...); + int __cdecl fputc(int, FILE *); + int __cdecl _fputchar(int); + int __cdecl fputs(const char *, FILE *); + size_t __cdecl fread(void *, size_t, size_t, FILE *); + FILE * __cdecl freopen(const char *, const char *, FILE *); + int __cdecl fscanf(FILE *, const char *, ...); + int __cdecl fsetpos(FILE *, const fpos_t *); + int __cdecl fseek(FILE *, long, int); + long __cdecl ftell(FILE *); + size_t __cdecl fwrite(const void *, size_t, size_t, FILE *); + int __cdecl getc(FILE *); + int __cdecl getchar(void); + int __cdecl _getmaxstdio(void); + char * __cdecl gets(char *); + int __cdecl _getw(FILE *); + void __cdecl perror(const char *); + int __cdecl _pclose(FILE *); + FILE * __cdecl _popen(const char *, const char *); + int __cdecl printf(const char *, ...); + int __cdecl putc(int, FILE *); + int __cdecl putchar(int); + int __cdecl puts(const char *); + int __cdecl _putw(int, FILE *); + int __cdecl remove(const char *); + int __cdecl rename(const char *, const char *); + void __cdecl rewind(FILE *); + int __cdecl _rmtmp(void); + int __cdecl scanf(const char *, ...); + void __cdecl setbuf(FILE *, char *); + int __cdecl _setmaxstdio(int); + int __cdecl setvbuf(FILE *, char *, int, size_t); + int __cdecl _snprintf(char *, size_t, const char *, ...); + int __cdecl sprintf(char *, const char *, ...); + int __cdecl sscanf(const char *, const char *, ...); + char * __cdecl _tempnam(const char *, const char *); + FILE * __cdecl tmpfile(void); + char * __cdecl tmpnam(char *); + int __cdecl ungetc(int, FILE *); + int __cdecl _unlink(const char *); + int __cdecl vfprintf(FILE *, const char *, va_list); + int __cdecl vprintf(const char *, va_list); + int __cdecl _vsnprintf(char *, size_t, const char *, va_list); + int __cdecl vsprintf(char *, const char *, va_list); + + + + +/* wide function prototypes, also declared in wchar.h */ + + + + + + + + + FILE * __cdecl _wfsopen(const wchar_t *, const wchar_t *, int); + + + wint_t __cdecl fgetwc(FILE *); + wint_t __cdecl _fgetwchar(void); + wint_t __cdecl fputwc(wint_t, FILE *); + wint_t __cdecl _fputwchar(wint_t); + wint_t __cdecl getwc(FILE *); + wint_t __cdecl getwchar(void); + wint_t __cdecl putwc(wint_t, FILE *); + wint_t __cdecl putwchar(wint_t); + wint_t __cdecl ungetwc(wint_t, FILE *); + + wchar_t * __cdecl fgetws(wchar_t *, int, FILE *); + int __cdecl fputws(const wchar_t *, FILE *); + wchar_t * __cdecl _getws(wchar_t *); + int __cdecl _putws(const wchar_t *); + + int __cdecl fwprintf(FILE *, const wchar_t *, ...); + int __cdecl wprintf(const wchar_t *, ...); + int __cdecl _snwprintf(wchar_t *, size_t, const wchar_t *, ...); + int __cdecl swprintf(wchar_t *, const wchar_t *, ...); + int __cdecl vfwprintf(FILE *, const wchar_t *, va_list); + int __cdecl vwprintf(const wchar_t *, va_list); + int __cdecl _vsnwprintf(wchar_t *, size_t, const wchar_t *, va_list); + int __cdecl vswprintf(wchar_t *, const wchar_t *, va_list); + int __cdecl fwscanf(FILE *, const wchar_t *, ...); + int __cdecl swscanf(const wchar_t *, const wchar_t *, ...); + int __cdecl wscanf(const wchar_t *, ...); + + + + + + + FILE * __cdecl _wfdopen(int, const wchar_t *); + FILE * __cdecl _wfopen(const wchar_t *, const wchar_t *); + FILE * __cdecl _wfreopen(const wchar_t *, const wchar_t *, FILE *); + void __cdecl _wperror(const wchar_t *); + FILE * __cdecl _wpopen(const wchar_t *, const wchar_t *); + int __cdecl _wremove(const wchar_t *); + wchar_t * __cdecl _wtempnam(const wchar_t *, const wchar_t *); + wchar_t * __cdecl _wtmpnam(wchar_t *); + + + + + + + + + + +/* Macro definitions */ + + + + + + + + + + + + + + + + + + + + + + + + +/* Non-ANSI names for compatibility */ + + + + + int __cdecl fcloseall(void); + FILE * __cdecl fdopen(int, const char *); + int __cdecl fgetchar(void); + int __cdecl fileno(FILE *); + int __cdecl flushall(void); + int __cdecl fputchar(int); + int __cdecl getw(FILE *); + int __cdecl putw(int, FILE *); + int __cdecl rmtmp(void); + char * __cdecl tempnam(const char *, const char *); + int __cdecl unlink(const char *); + + + + + + + + +#pragma pack(pop) + + + + + +(char *) p, q; + +int main(int argc, char **argv) + { + printf("hello, world\n"); + return 0; + } + diff --git a/src/sh/bsh/junk/silly.exe b/src/sh/bsh/junk/silly.exe new file mode 100755 index 0000000000000000000000000000000000000000..a0aedf3ace24c788ad13c207b1038c983108dd94 GIT binary patch literal 28672 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 RNMJ?+GZL7Qz+W$c{|TOa{FVR! literal 0 HcmV?d00001 diff --git a/src/sh/bsh/junk/silly.zip b/src/sh/bsh/junk/silly.zip new file mode 100755 index 0000000000000000000000000000000000000000..f1269c4ce96d7565af63dac85451700468895a0b GIT binary patch literal 33072 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

rVsQU zvU|H}qJ?2JhN;d15egg+>GU<#9vwMN2k3>8_k2`vgu}-6NltS05T6#9sVwgxnr54) zUI*OLnWaGahzc%U00`WE--m0iAL%<3$P*XjVl#6)Q#W>^d=u^E#8@)?EXwvc2)Pl^ zXv>z>pj26WHA6$*%3JL#@S6+36(2)+mV?pKXNC;%w}E~s^VotMM|_IW+gvBhI7PKH z$pSU;(^+iqNfTl85Gm<$6lx}_8*w||=W;d3IyoVYq+ZE3`wd}Vbo2cCfb#}ADckAG z;ew&-F(30sqCEQ4FAM00wGOup2HkNvCeE>btobyH7ss%5>F)+VAh_IovL8+;iz)1$ zr-_|hCGpV%9zxu~)p{zAL@T;ZiIP{65qBU&wWu30{K`A@87ucQKL?&dsmwVQ(%lvx<@eOb>mkKX!tj@H$ z*%BbGzDf}5=EOp+VY!@hK;MKig1pzm4#%+e;~bt8ZyoWf-O9cK$`YjcNZ~?oaMZ6j zKViuAu8zq**zR_s!w{<-<$FXPt=LLT65M%}UZ4fi3WO2`EHaJr$q;Aft|y~tMZ*H1 zNSvJZjv2+tm#}q{vodHZ)njB_A;PafQT}McS-orS@!4wJ>umsJFY7%YJ0Pz*_MftU zOC1Y93skU@mem3~l2U_{8!K?JK9 zv#PlJ#eBa~J`9z?+iMOqF*As z;u1oY!@xk*8M|7nw>bH6EwrJ07dC?%zpNp|u4f>B!(KP{0v@dvu29gvXTz2svXM<> zwZG4&z*4t=5s$-K;aq`)JeFgsh;l35a9EFUIWsR7z*i2R2bJ^ zu$@uiXnHy(d5(^?wRb z3!EE$Z@BW#yr)7j`lAfsP`?wse-Yu^rb*>;w2i}pUL>B+suC(|oK-a=iH5U4n;08r z*yr*`pno9J$t(CdV1W*|N9++VLy=q{2kq?S-_e0?9`xIT2L~CUqc=8S6U7c+LwUYp z=uj6O2ko#ns1qOSQ?#*KTKlXG<`B@RTY)L7`ms}v1!uB+4K6HsCs@?2MfY-fjlVA? zS2&|9%r$Z!zRe9>{8!pN=O9{p(7a zod%xM{=y_Vly?xw#SV2bsbdRY-Bu0OBcLHq;h*2pQH85n4b;=vC0L0uqmBsmBD)3* zFJfP;Q4m7F3Z(f$>fyqf49Olt$?(o9vP>TDyWz_j&(U-RE2hidfcID*~cf*4i*He%K;lfQ1?R&^%VaZ z?hT2Xy|>Bp7#*g&CHI~@)4O;!yj0rY_+6x`0ql5A#UNSu6c@UXpeynOHZ83R??iR> zZ<*LpA+xR-A52oX;0eBaR2FhshKmxl<}Rv0X169Nn2ek#12x||Sx>C5E;6{P0T#{) zi`jh|owHX-PIFfe0FLWTMxaOm6@lz2v3O*mcXZX46 ze#R%PVSrWKPJKRgp^-Z;=o^13yG<3WulKbL5-#8EDob~SOQBCZ)WMHn&Y}b<8;!5< zw-{72w@n&$E$qk;p%#1Sh0A_JVJEIzK4)DCE~E zGn^Rks1hGi2Dt(cooIFjrS({Y88f8dgIb7Kfrk53HB{UP|Fiu3ic%!oCCeZr2_A&% zJp~=7hr0fQZkQeZKBt}FK15FR<}i2A7*o}L8?P-s(Nk@g-6_#yI8g`vv z)@cw|h@KM9_HE_u<@08^SQ02Yq80mz3gu=4k&~aY1E1}&y;BS6{Q66ZjbY10stw`GbY1HQ9S^;Xw1JZ_D;tQzLwiTZ4+)YJOd*Ul+<1$Q z)xb-?9Y0C?rmI%W&75uOTykh!v-xsq+i*U24vQh|7$Ig}AY@eXdN1JLfgSeX&Qk_| zo~F;7@4YYJHFGy!QbEYLG#SrI3O3_H*O%l=E#|*w#z?KibJ8?E?SKujDz%0k=-TLZ8q*Syvg$-Q9B->=J6EF?RhyiSZ`;wjJ>68tZPz^oJ8<%*)zs7 z$Bw4pPBR&2gubx~OS<1KmXSoUEwqH47%C;6+!N_yn&H~Kr=ov42wCA)ZtciA^esl( z>W`;jyU9uI8K}cWh!;KsQGOnHv0?@BJKC`gKK@A-+0EYZTlPgG$qL z!8jk!?RZ14)=xaBYKuAg!>erv)Wp3o~?8xw#g6n~9P!&A?+bV)?Lt*oc{U zV*mW03l3zHu@FMZ`=fHR>-}7!ABNwdOtb)@-ayM&uk)#p_I0n^{&{f(XKNKa=nJ=3a2cS-p3xwPwq=a@#}m&Al9ef2t!rO=^7= z`gth~2-=wCHwHw~m;rmFm)b#VTN6t_?VyF+e`^Od3O+!TBQgJo9gLg@ra|(7p8d`& z8EFGs_93y?ar(Q(v&YQm)Ff71Z?}+1t-`%@i`XINS#;jaontZb#tUmMD+ zMf~pJDQ5Ep6kJSDs5^@*+hY}}W+?rmG);*DIpsGA<=vbjwPfy})*K}R@RFf+k&qqk{P!TG}X%+r+xvt6e;|KH~bC z8KMc==HDqJRY6+4R0naQTk8w%btIiB@_vjp4A@ma+9)u_UC^zaBQsZZdUX<0VHg*+ zf}h)E#&snF7HxU4$#xbPsjaNU$~Bh{BAD6tr8>(9Kmy>TQV)_?^?$VuO6pD!PdD2S z+QS&9h`Lo1Ny!5mg?C{xy82K3y94eE-L5(MeJu0_!_)|<16nAiv^PrptZU6xY$T9t>E`t?m%q2o}?vL=!^q} z?(@ANXS}*|@^1nq+p{AnhN?;-#S?JZylV$TPz5^ z=VZW~%;3P%lndKlTy0<8OSAv}K8>;US(A4QocTx}z)=HK<=FNH&=-_VkPFTgCQq38&T1LCMwcRn{Uxl#if435wvi z&DH@YpSh8HH+L@krExN7fF63ADO)l61GX>0*-c|1V#L8W`ssbf@5N=EswT7b)aU1A zE}{`@wc$>2zsGtf_@20xx3*M8$b)Mq`rN@`T_Hr0QH^)4Mj#a7bbsD|Cb1o7DVJTVGz6U898OHmp0mM@xOP??JAwCCzOYD<}t0TS}(S=DqKj^Ej&soa_AnbQXdZV zd-lJK7gyMcTdz=}<*2K-9gAn^;pF7AtM-BEyUP#>NaYP#9c5q;(PxoHT`|=^F`~?S#ePj7(DlL>(kEWzgwcQ{)DDOtDhN+l7YWB|DjTL{W$> zF9!4R)IkAe zhkR_V5ecm`iO?bK5ech5g&zm&k+Y{hVX<)`n{?B;)y`p1R3qv$SjXAl-L*i z?NoVjo$zkl$3A+ROriR* zWvrGWHW<1P#guk>i<%W<+qB&5zNq@c5%jGc6KYU|gl(1=2ndD|A~$q6X=Ie0UqNs2 z&!ABYi^Ewf;|a=nhPru{V;Te@nJM>V-i)s8ygZc6>msl3NG9D1g%t1m+2ZKRNw#o* zc&&fkp5{ji2+DG{e>AYSyT&l~^BxnL`1%x^RXztEGAd!ue2^i^SQft}eUD*FP*>jS zlXF!+-mcvO!=m+r3|_g~dqPM+b=Vkz+&6bsM3letL`x+rU~{UH+PoGnGAK)}7NmyI?0c z0mX_@D{QHzR zR?O*8S=kMGJ6}s8IxGIokB{P(cv9faS3LCU3KmI$a$8&RMCDczAmDA=x3@K=Oj1(M zjTqfAQVGSOtVvI8B`wv}wjfM=5w zFK33H%r7`Sg(!qcB-qGL=_*iQvvnutXE!TNP5Q4ke;Vj%Wu*^gHfE@%G_Ib{?eOdn z0FTSPGjGbr&bm`Omkf_xgeBUblT*h}SG>uX%k*&s@-*s0;jnJ1pcLD9O0!oyv0hP5s+;WL z19PBe(6y4@5PWmR2$?*cS&MtmI)lNGT$TKku_4+;1ZLkd?f_@+F{S^Bv5E-C_j*;0 z*_+`OOXR_E9u2ym?OJj}9WbEX4s1ic>;Ozve z_l$m&nwG{CQX!%^_9DX3-KUDto8buY``#!+t7xN-%5loEhGkjJ`n!x+%|TglN8(YVDkro0l8fqS z5*Ru-@5u_eRZ#1oCA3UtA|KU-66dE-)FQ{ON!eIR91YWp{Yw^`rknSTOJMEYKI`S3 z1V?U~x*5@T%`a*>-49HUdb^e{E(EUPcy{!ryVI(rpruX#+c(wN)eOaF4cddDqzP3K zWw0Dp7@{|H={%_H_?a!vW=i88VNeXsuXDjY*}zT5Oyt?h)mn2rbY4V#%3~=UB#oV((E`suznWd!Bgy zOUF{VV%BmfV7HM2c)jHC?F{SzvYE7c|3CVvndmrjm`S4LDM(m~l<5S21QxJY5$BPs zfs)H+_9+Z?VQlUfucBZeAtH6g8LPp@mT#|vmCIkqnIl*6gYbFEnnI0Q1`DOC)1dt& zm6X>@XCw{SDwP4YN-z6CJ9{0#l0Ckh0J^MR+OSb`t_6{ILruo7{j%jSMn#TNq0Nt) zrwAZ~;20{BV$A2Cn=3YCvK<0ZkXG)vTb!KM!crXA?NaKh*oyRPz zf(i(%_v~>V@NLrdBQGKGqxdDlL=Hq$aflwd#28b{nFH)UoLq0V^QjY`)1Y z+u4j!_Z89|w*GSe_LqQs9^)x~`}2GqLEfb!FkOkS%hMe2AjhKwso0pT|k z3Q=0EURBi&qL`4|-eZE$Gf25Bp*Cc?t;Uqa&JAfOql$yIUt)s+owRG% z#y2|y5I^geED{eJpHIgual00mmScD~5!6(Nxl=HVbfWt zCC1faz&dMUbx~aK`QgX^F0?sb^x4v($ERUwcL__<{3BYG*drL?dI_*|L6#QTnRi^F zV|mS5Gl=#=GL2t!p(#C*Ty(7X%I@TojQN56idIjJU@bPWq>4R`=BytHwuE*Xq7xJn z2$1JgNOG|>t!8FFIS0lec!dK-Q5UQ6ZHSW*Bo3#%*|!5YgG8K!xDt1SjrU*=g2DkX zyb4QfIR~AhG$-WC2M6vKs;So{X%rzPCJVP!?$aXg7B-gHko=|Qtlowo)>@k=+W;=d z0r0o~x}34cmp01VqE290j z=4i80<%2yvH=jPwDBaX3SvTB2U0q0@qE54%Z1xO*C$p7i4XZ>w#t4>nU@rWmZjbEm z%i|kP#bZ1!`33C=mLz)0zehxl0Gtr>wfH*|Ko>e%L}orbmfF~b#f8Qh9EbhOOr`?8 zzD_ViX+D4Mj}VOnC`|+FRv-&&8BSB}lhSRu9xSMB3}b_~aSpNBnxqn1{v`g~Q6Iq( zFe7Bj*^3zxP5n}(x==UvU&yZh`Iuj1t$#wu`v_B)21u2_PzQHSQBG+Y6;u^|op&nV zMk$Aia-J!H>Kbb>(ny2;ZRRiTO3QBOmS}6#IyR@ubk53ua*XT3EBGiNno;}y@|Gu1 z@BX;Vn-9&c-v?@zFW3O6e4GlthA)d*)UiWohRptvdD46iZmEuK2|fSlW2m5!9d+N3 z5tD?0R{YEWxg)A8n5c%fTuirfi5QrJO!qwyYCh{QRxo!E8F=83oH%8lswb27t@|zV zRw-CmCTB8oxdXzoaL`7jR-L({~Mls9KI%%}2>f1$koB=N*$*!s-%% zaJWKFbKk}BA;gW&^8Oz z_LaG$Nz+5v{Q^~G>rYt~#g}>H7QX31lNt6hK2M@$2WoClZ#1n?lRGSoQ1Av>*SS$= zndDXg=SmcI3@{AvW)3iJe=CkEix>sp$>~gV2~AeW#V@CH5a^Ya|CYMv3lG!#;GAt3 z8v4o4gZw_t%P7tO6LrA^A0wu)ZR*-Y2DPN-1VU1cq^BTArn0TJOqdCaf&cFNrE`Dq z0~xE6Xk}M~n$s|YC%d|p3k9|F^LMyO9tk=@cf82QcXCPH+0XC(*U4W(P-ttoQhNqifXv0y z&2hENLbm#B(vnNElVbofR$sOrHurl#N$ce>3cQ|JcV(efaD-vYq-a#XnC5`$=lLIn zmO^T5Xnk5Z$enA#TT?}0^yHgAdbWUMHz;;_*u_b(WXG-mS-+T03p-gONIzx{eW-i8jdsjcCt)&#+%AJa8b63<`;SJSlSBW9O%T)JuNKsp1Yb+KfwX zXpGojjESMA8~xGcvCH!lLv4W_QKDPWBmLN-FP9U}4b$+o^xaErQ$AIj@H4>X4*;9L zlttLNSkM|PM65`Cqetm3S);%-Dm*rXWpzqp$didGl+j0Ind{ot_F5+eZ)7-LvoM*6 zS-!eSvb#^3U@8?A#DXm%{ISf}P!b~Qh&9LBk^0E(G1>FM`~cj&B;oqBYGXdNu=;xm zG?@JvuG(;C93_efNL`2kdsOdKz$a$FI1Vt(gWMj8m=*=&WEkeDtqY^Cq{x28_~Epn zXh?hK;g?%`=LFHxuJsv8Dk~Q#l$lCS*N*opdk!!DG-`4N3bWW!4Wb@ zzT9X1h$hoB!-l%?*Od^0FvibqZh{?Of?8SN7?C1!h8=1^4-6qZO-tt!#f&{Y1)P5+ zTPI#LENt07$SI^?F%gK&E!uX&^J;w2h|#XlVzaQy(S(lIgVE$W`jj3mLfmiTAMh>~ z5wi%%hY?0oU}M1}s(f+_3DeBa-Tx`|@l{mo#nu_f*5V2P8*2exFS_3LCKd)(4)*^a z)nhQ$_YU^)Fw_689V4qS*oqB!UV#T3_~i!TWMvCb>9A0=uuEV^e1dHeFflTvms)q{ zP9J1vFyRulz;n!*soR4fgi2r#L9t$3+X48YK}tci?%5 zWLA?!*$4BPdiR;Ow}@*p%lo28F1(6ds46-O-{zkDpfcKl7W2qvuO9Cr0u_Qb5kXyl zsOwr#dYtQoe>LCTH$JqZ+9au5aZ*1arm=Sbu1{a`*W$@k9QjvcY%@5F#f-wbordRH zDI^b4CxpmO9isM*WtU&m2|qtXuvpYz{9e6&;8dl_*jxZ~4mQlWAF-RrTFASi))(7t zZs|z(5OAD}RPOWlHFFQH2RH}CtSb#PmhlowMl-H4tdLD~amnc%_r-`Ol1)+>v8LdMTP_;T9kp8tE~{%P2rpVR4D z_czqSalUF6X&{AaQv$(HrLhA4xXSuYU>w9;Nl-GnD153-Ps8A085!K`FmOp0tBvF# z={W(ka8Q^S`D|nr?-EpWk-C+R{;DFMyAP34-&O|5IV?VfdMqGAe54Z#N%{^70#58_ ztR|ar_*=w-H>*o)1J5%QC|E2`N#GFOfKH3F@1*;&^JpJJp<21IXD=ausQp568H7&{ zL}CTDmvAgo3&EQ_^YaKJEUpATFJ2Ht7=oK4hrU{yqce`_Sit>fYY_OM)A6Z6Glr}i z4;*p1N#rL#Hx+~VTxI+@yg>E{+!X(@ebs_eqz!bORxLz`BmX+Ck=>2soT-$ zpK%86cIjUonjrHsS7Q?1cBJUM{|vh}i@PruyZZgOrMQ6qiK|yJx3pFVo6GOSft|pEViw2p$a-&|z^Tc>&I%$YDXTU{mwc|@Cr*$v#`#KWRg=mWPf@c&M%q}pH zFZL=T`644ZONJM#5RApF%~NK)!^zi;FZ7!XQv$dnw4!GsF5_ARSai?lFXa9Kv**W)7a;+JKA zPWJ@XzJ`|6O1m&0kcVy=nL>%5@ZCP3&N3GIfI-H%5dFm$fb?bt=OdM?bK0wp(XQXuWo4mrRxdrYyM z`f3s7lLb0`mv4!_I8j$$zTbH*C?1(-M}qW&(na15u*m2sU%gZ2&eYE5(cAIUs778t zVy8d}TtZTr;k?w}$+TnZz2U7|GfN z#uhyt!0n7+sP2e?)yb9|~mxyz|6!DW!i_B50jE_hZN%3r=qP{~_nB(9PODBuZg6zPep^%ZNP*Jn*rvxmBZ0YSAt0LxW*rj^K zuro2(=St4+t{}J6_q^4=R49uI3_Iv!i1^QYvq(gmM$dnZwflOtC{h>%oqY3jWIYLy z%;xRzAU}(DQ$Gc>crMrE6f+Pj~``utBHumSSG9rtaLB zDwHvE+-JVtY>_q;d^zYS=^MlY=j731&ppP&IgiH;^ z!3Eui33)tIHy(Ndp*nzT=fwULc%-DL{Dc+3H?A6%wMl$KrT#$FrBu))h(@AbifZVv zsj{-cEd5F747k*XyWdhRi@ORZBr)%>Tay&W{dKUS`HSDpIERv=b(9$t+p*kJ z3E6a??2ecBMPzAH0lR=)BYj;g=pGm>&TH0l+e)U-O9^yHETnAc08ipBU`LIp_%u$4 zwV&G|VrK`EcgDFe%By*6&S|x8yh$(LIL&-Z4jo61mer%%1?GGCmuDQ3O12- zkno(6yHc(jn#3^u>qXOOPM~@qvVCR=zKhkx^c!B_xPJBvVin)m$E2CeV=1^w;bhXu zdEfj~eYOMLk9;8Q7`1-XMB#QJpNR9|OJw?}LIlrA0-p^mxm!;Ld|Y}W#d&^_TxziZ z#hgs$0U21<&tYU?Ihn}%+i{tz4dFA!BgyUzUPoBAry5`gmPrJqNRuuJ_&JNAh}sf{ zZ?*}?DpzM0-kynuA#!Iq~*u)lQJwuhp3jOgshAJ&4R$;1C(sQe4A6GhiZi{VUUg* zcDPi$p;5d`Y_qgb-oi}Pa*V3SlhK*SEw1+OM;&;nK};d1q9l(e!1s{LRvkAs0iF*w z&tCz(e-#y>Py7!~)@z}AiWKUahplLO)8qXS-TDcioT#j4=DT7@BC@J71Trprn&uw- z8+18;pSwb}4sI)Ym{$;|QGN2Gg%CdYNIrgg+@_jI;gq>6?tV3`rmNa%BW-4&3jM8b zQk};>e&!KNtrNuphHF<-^O2=CUj3o!pmL9JuCYMAs_$x6ici+x1J93ulNG9ljbB&| zJlyvb?zl1yj6{t;@W9$7k1Z(w=7yv4+azyYw&MpH_RkqC{kj_Oz*niTVo*z&nrp(qcoz9g zYCLTF^P*P%*69}R+XAg`adG0Th>ClREs8-B=}0GTU!m3)7Z+mtaHS6G$L~q0c01Y` zwqD_=-+xgqa)6m_+^?c9klH&g(=5CnAYR%$27?IB@co$QBUU%Y$(}P@!=+%ZSF0f9 z;BYx|u!cQ6#tQ*$uMFo+p>P=x38zCLu7v1C@j0qFE-(ct)-%NT*oO!imd5>+>UmoJUG@q2$hu@e;D&4_l%Crr$}j)j1TvYG7aS`KAwjGu#ohGm#p+lW zY>!<<&!9yqX0>9Vu}4mVg1BpnWn?Gav{HC4W9MFk4JLouG1%Nd_CNrt68Gk14x(#b zuqqs+hq)gdLmv50mV{)V=7*_|Zqk*c8j^<+igiAUM_P*_OL7vN&HGXgtknZrmUiyz zHRVNvHI8ueq7Y5k4Cg3l0$WV@4%DNT6D$Tzouvq$!#GhZ9CYYsrB!mBtWXHgQgC>F z5aKo^XccR474-malyOb_+-HA^{haco^z^OIek5<>nB?+2O~I-}fiynwAg$fzmsskulN|(MY1j+%q(Y<@>YF_rjF8|=O5m6+U zSk25|VbV2y0dC&y7-vkKGO<2xK3grGCDEj3e&kx8JH5uuLtBOe%7#`eJoh2w%zKgq$e~BdPFa})VVz@Ys~yknPDiWstlI7tsPMi1YVG2mhLc6 zS-DNi5LG;W|KZtuIK87SnQ7^?OmcW#w=DF?rfyk$&eiRUjB)w*bLS7gnpW(TwrnCY z5G_7s)`YK9^1N@Rl%N!Z6Z0)>kc}ZY!G+^^gzZf%wl!ISfGv(MRq(iy`~oJNU{FQC zsH(S&lqTnEq%4b_Lcx;Sr#GLbTtJq3cY()u`RIQ$n^%}AIMR}9$+h&cSluTGm0yXB z_>uaXDqfFcG=523ZkVG6v>jW(KCTlQ`-8bq*09C>B5g_>cb)s_$cST)4P^~iS8*OH zbMrieoiXbV#X`mXWUDsAnQzISMGqiBqK_A2AFu4vNY9IuH@-Oob44GwH!I7Nn7!9q zgCN&z{7E51#dW>sO2R{>S)B&|)5aW?)*O0h{4Ce6JELuPy=0*7zOqXpc~AGjYy;5q z4h%vL^ncB2B?fHkfq;O408i+D{QP%vEA)T<1PlZi3ASd|;IP^b4AlG0>3pRf7~h5U zkN2<9e;=Cq8a)nxzo7pZq51}$|5eZNHJbPH*~_6`qhGcXZ-=D5MsouKQGbq1eZ$>> z55|4P1%gfsdU^j>?%U~!uet7k$kv~;6#tF8nw0gA+_!VxUUNAC!Ib|_dHXkXDm&O8 zAK}j>|6h~dUZcOgp#Nv?+rOb(8S?*e)o;hZy+*eI(0>et`!_6~MCm_b-_BZjjjcfX z@8p$#1LLn&{v-J9435{}OMt`wInu@W-@x93kgsg~=a=Lq>h^XZ!fS9VV8Gs=;}PC) zQTRgMxZ8i+@3p(VaNp`czvdF){YMr0->|E$$bVbz%eUjL$n$G#0s#9T$>%rVzkWUJ z>;BQeZ||44o-JNcU2NcLY5%6|iE6L$V1_^n{zYp@#SpYnnK zM&+yS{Tub=#J!a=drd{7ed!_x2%EjZ{>2|!;nDx`#JyG4dW~J7`vd!;v-Jl2mlKCC z251ZYhwIu~ZIjpFYStIFW=!`uG(*W7%r7w(_k^l!+2F$Iu6)89<- zLVnvu{+j&A4Iux~RQ_+=)O75>asLQHz3Jh6&7Bnha9=t)-(de@;8mOHzZv2M`?h!L zHMU0dKh@s<%GC~9{2TWVGrXxAf6Yaf{+}xHH|zb2dA(T){?QC?OSNBfZvou@6mGu( z|HTk|_-lV#@QWedmfgMv`^ml3X8flJ_utU1oIC%Bep~4A8f~fmzhxi)Mot|*_($^F zYK+%pB8~s4&G1kWbK1Y5 zUmWgjR_Zl+27vxENA-sLS4aMN_cu%YaiMq8OP?h$?@Mcz^%^Ab<9XBJ$Ggbn-GXHuC~VK?E?MbKOii zebMCl+p=;&7%aqqWc-n>wO17qI`=2!B)1rt3BBpUOKv`^Xp>f~wiwes*7V-S_YP_U zTwtT7$m;XxFpTHss`4=)Y9yZ1b;hJD5&$P-4Tw#~K^=DW%jgmq$LUpx)pC2iQ9Drw zRliHRCdBKCR6ipqB%=hTQv-6(ludp!*1!MOzD%}OoPl1_ej~u75=XF#e~qZxX$bfm z(&Ggz|9?HQ{_)7MxCu?-#}n(H@qawx_{XD0RSHSkvHB(IvFYREgJUWgAM_CKWiaPr} zkG&7vs0Jnw0090UV_-iv4IIs!=!{%cZ0v~G5WcKQz6P~DVK0Fo+kJ(3DIrM&1Q8H7 ztWZV%n65%sT3;r2&lPoF*wva@|2lHif$W|7%gtouOJ%HS%LFLaAf7ABDt5JEv1Ka& z(>qhz8?+wQFhm`HEvxSVgl<_`OfV2~JRq4=ut7nopTbR*y(Eb~08+f@TDkqc?z@A? zH6d&}rqJoqsjWS*ZOM_XCzMt3hh^SsF_nk1MzHY*@`Mn2bpPqPI^8`Rhm+nXc# zTu2ydPUJCJsEq9nyuTPaQ^s^AaGLgtJvHf_+)Z}bN%fK)|N6=kiS&D1%K(sYBNU#P zS@FrUsWeF7)`iW$LotbH5bCB%@S9;=S%oWUZ5f3vbv>5GQ;Nd0brB<~%s{Ju6wqbf zOI}Bz9iNH>hse725OnPWvf}W&e_Rp}pyYbVS`%RokArO3#!U~qND)aO2VN(jxvW)F z(amUNH|}-QkaJ`_f3%-&*kJPT^Q*tLeVR>0OM@6`g!H3O^p{{^C_{XI_oPp{t?o{xcyUOwL_ z@_~TRzbqs&=3ZmYV3-r_YPY@y$_ml!XED56;>S}nI9DRvz=MECR>H>Qpv!e>QxKq# zjV~P@OQ8N@1-Iv0^cl25dZp9f3OlZBEy+L3H`x8!=0Ewe9Oy-`iio#*+5-1jvlh3^ zuz@dHPGJ3NP_|e_@qnej^J>J>-kD9)OOtYF{@87)>(KN!Mps4qeN|Nz zkkeN*+d!^ov7Ct{f_1FDWrJm-ruCfkxs?oh8O`6+lreA-jCgJ#S8jh4pp=uh09J@C4p1fYz zKJm7~N{>I>C|>?J7gUF=xFKx!GuO(L(9nxeS}#eQ`{Yon4{dG@so26*SVv#~?e@J9 z`?wW2pi=2vz!QeYS1nNZ5E1a^JcjhBD@(+YR?Ia7?hK-&{;1BYx&?VUUiUf1@xhDh zd$jn({9UNF)uV$KqZ7l#X64X>^nwf5+<(JKG8hXUD&XMTZnp1xGNA&y}et^BBD54UuxN82Uz} z-^Gug!35*GR)a|Ej{3fmpw06duha(YX@O3L5gA<&ueF*2ho!`c%~Ct>FdB{4PN~0e zYkFqr!JDO4J#Re&Jz~?|CRCOGH})zie184=i1@|2K(BYG_%F%X16(my|cdDg!Nkg zQF3Iwb>ZFvrYjB?>JY4ruq0L48kifGsq?f6Q_dF7C1t zbnNO|(IDVrJ;GU^9;k|5hJjL(GFD2O` zAw#XzdU1JUq}aILm_Z__c-N*dTVW#nO2&3nt%}R31Q%L{e9COkJp9jX-J@CFE>mwy zBO13pIPi9idZu=TtX5F!!)`yF3fFDW`Jz#8>Se4}G~j;gAgG%S*J78Vp4;@0CsUnr zN{_%*Qv<6DWoWCs*-BigULr|H<+q0bM>s}R3KAv2FqnJWX~0#1sCw6^)72*}SyrfM z;ukRWsab1fRF3Ysb#z3mPROM2aJNdi)So58ymYxbb#RO^t2(bCVKg0}UTp|-4Q*2h zm3T(VP@OA8E2~5fmy;NQ%pr~1OQ86K_~Ss&%i?l^5x=!3uWz7#Cw9EbO%%%yP7wWX zd}8QmWnpXNNN27zGbJ@cDI=jGKQSpivoa}vaI6R#n6%V1)ujwtN?<3)cS-;XECdV; z?2M^53IPg?TnF;Mu?W=9od5v-!6I5Ld}K5~zyBHkU>`#l3u|W!TRJ1+9~0It#wG+r zwiZTKbml~`Q2%|7f)WHXm2^5p&_N;@HR{EV+idyynSjbyrZ{4!(9 z#7;yq-hNbdJdli8&y14P_caUEAQ_c`ws>y(ZT)S%cRiNgScm4kLRg5!vVD`_?!%fB z+S3?C8l8z+wy|}>Ra@YL2ji*Q{Ig>^;+P@XVs2>I8UTt)69<`XpIYXifm5>#*(~UW zpT^AsCFL=Uqvq_SFZ`ZmX7R{B4V`6_{gBQF&I97s%SnR!&PZh46uCqyVTh7c3d>}Y z-KYMDQI7nZr9i`ExUySPcLFUu`+>=dSwkJIiwQVouhH=NUhjG4K=E7vylTQLUqvIN z_L)BIQ=MA|d@o%^$A#aad6H+YS+B1`iljYHw`%8L$|^`&pt6;ynOgpqPyQObyT&ic zqa?BAKs7%LRB(D7jgt4#jhUqWv{`~4J0XzAf9q4LK6YG!%!Fx(~H(n9;iosaK0Qsq+K|Z^rQKVtk(4vB%lI(fxr&{{!J9Np(Du7|CD4ka=}&`|x9kR?s8D@PyeE%ekz|Ce<%A{8Yv}ok7$HCOVw& zu~!HxZmd1SHnF|ccN*I3;GxO@2&_li&usx8iGB{_S6bIYzpOvXUnV~sTF;j)P&Bv& zh`#{`MAM=V*y;ew6YyaI`CelMJMg8AZ@z1|a)762NVbg@G8u~%I>i~DqNXof7B<5$~c;fDsO4aVK9e(WnlbOgEpZ* zpT%c+JPjpqT19)AK}Dt5HvOVn!67d*n&pl2-=i9llup>UbgoLhaPfP2U< z_>ESLH}+L4H=tJUz2pR?xo~h(tEZzYVY+NTbg?rlP!31g9xXjl!_Cc#))*Ra7^WSb z#QbfUfoXZ28M8zSwET(_^O2%}wYZnB!of0O-heObOkIjKM+5FH=tJ@#DUNSlDb(05nSF!6Q@X#{nByo+?dbhIL)j|h09Zyc0=^Ps zRZSzHcGD&6HpGPN>$ZJyUDcxj7Y&i@qdu$O5-1Sk2*MOcE$1;S zjV`wi#Z;8GN{A!~o+z@Ztsh$unYL1V5|$*8!d<|zoKV3dG=00mG6bSsh{Jn%crCQ^0Rk;`M%PWil9s|pAxtSqYt#z(ii_U@0)PK}taQhXS*VU~E!a$QuU6iI=^|eY;UR z*W_c#CDyBGcvJ3S9m73fG)z;`^l!k)`{B|N+YrRXMmFP{;iON#@h@%)C^jWug@+m9IM!+ncmx_I4`49 z)K~MH2`^Pj*qe&!Lp}*}|1ra>1a0(~m7Cpa63puazpDd04OcXGe2b8n%bj&{RTJGH z9t;PAGdHYSm)>=_69V8+A*T|zQf3~?^xa9un*jruFcilvqMbN23@ez>mAx5i!tG@+ z6P#mh={n~XWAJ4;g{~flSdwp#2Ky`Ib~P%y=;E@XZsX%}KDKXaChIX>Nj++aFkm^W*37ZV(LuYz zw==KABTF3p%olurAo)rkS?&uy+qnMT-Pwe!zYN(%ZacFWuPa@h#V~DGiUHd31tZpS zI;8x@_N2!iD^|&pm-7bz?6ur8g=~^y#erzZDv?Su_TvFWiQ;d|zwB1ig$)_8AvWUR zxA`ndJ4AL>?8@mW;w1c4YXpbzCClB`WUK#Pi~wyhwV@Tl>M-`zNV0VY8X$ay{dD7`avU(_f+2_gDr% zdNYs`mhFH`RM+Y*lkOa#ZoxUdTEF%QJ=WEgHSPX=A`+qy@yX>N1;$yY$Qhb#2R#PR zny_5Jhf0qzms`st9@vyVL8pUK&v>=@jYCnzJ|>MVxerTKANyFbvueN@vs5h`mAJx2 zu!lm5Q5I}hoN0-r z>r$nU(UBuhFji}t=-qj?9KQOIYl(_ln4;LYU&39E|0a_|U39%vuw$=7?cT=hxVoFW z+T6jHXH6F;OF1H!7Ot?u_e>NX4_>zFgs}4FYQ~^H>l9uD76qp6lNS{PYmxyWE0;{ zouW-?o6f$S5bb7%L@gGj*1kM{(=S%NP{MI*A7y-zc<_f=N2p~{!ED!Jt(DComJ2{t z)iBDAjuWb-QI!x6-lG{6&AjKI?lj44x>^ejb0d$WCt>2ZoU|uVHmblk6$R~zxvl> zB1VQ$2(|omxU41(1Tn7wZ31ze3THX zJ9?3V;|8Kf;_z&C@XnO`2l2$-^4wQH{nEyfNVxSA8T09z0ak5v%0WVu$Bf`fh+AZk zf@BS(p9Ic0W}w7cICLNS#=BvF9SGh_hww3)jkz=uz1P*z6IsNB$mj?ydAJ}jwA;YS z@CCP{TVXAf6Hwlz!R*C$Q3t}y zhV&_AMLK`Ot0m7jS*L5x_*rAVFY?Vh>3~=Yt}5&da}R`e|A&$)BaCdf8F0sya!(C_ z3m;&_4B(e5ktG;F?y7K9H84Bs9ss{e7F9B=zuEAif4NuOK8536=@;bSc0>vdErl9` z&D(yB?F8Up;;35gP;~Wdz|{!#Fx7yjwop?sFby3ygmqLpMq#ZkW6SQGGI+QP*nTb^ z5;Uyl9@Oz=Ws-~dZbXMOyPT8FGC$=rW?#z*R6K6qy$na+pNvVwP5auIKQL+*k3sIs zeG$WdI>u1wpa$s4Zyfj!X=sB>DJacXr7uFBwYBn+t~$%TByFeyHjCGK8`dB1!ZK01 zMIR4^O?&lxmrhFwOT-iraE?L)eGsxtQN#oi_HKcD!N=40eq90v$~!<2F@|5y84vK< zwSJ8(-sI$zsMn)OZQ&qyZ>@;hO_HvEMbG7->m{kGs@j^pWh&?@%b|J)X6j`P0)9-`BxpvMi__MmiCa;gJSl3!dZ6PQzUL-ANEuKQSmfe)id(*J z-R0GHk1XC+dI`B$dL>1xw5{^%HsHsl?y~Fa7tL<4c>BurgXG2c3kDR5%+6xKX6?1ZSjKnG)cHyr>8eb%3VhbXh(xz_=s` z`tHzo!h^56HNQ0-ntO1;#)feQZxM->@BO>wxAoZC+1WiSd;C|ueD@)f@^Spx*+;0M zEGD?S0C7O*8LHP{c7tetmIEk5kicp@PR>xYXY*`H9T#_ky86zfzW7-Le>=~zf#*<5bN;< zm}dO_5Fe}8YLL|THa5BETiq11 zrOZmV=Y3>`L~TUF7a(}Urt1xUg5M!z4KicU&rZ^0OR_XPidD|{tv3HR0KWqf5;@u> zTmYkpW^`cP4gVK0pR>{g{EZs)UfZA0$XhV>nD_l>UO+w__Po~ZKs`EKdt_g*hsYN= zEZQFb$Xwj={*_(2Y%Ex0;OFp|SGW{maSDc72$6(41#%cPU1#hdja`5aFc@7G3Z~Ch zFpZc|3K5k^S5FQ!newKdC5#hxYDBRFdMfSXG8zpq>IWy^6I!%+#uz~QM`KSH-)D|T z^oW^)j<_8z8Bx z*l2;u{E@&h)7H+;{<`TJ>S@J1a$Z~Eu z@<$m4P~`XLLd7bSe!p+1$nxPa4WS1}&qS)8ap85QZ0Rl$W`RY%(#6(?^GCVwbm@&> zR(h(80al8K;{sRAOGmd_S~9yOcKWeR#gEhL(cjAz%3RP7PZzaJnT3L(J5>>3nJG|*+&~YZZVR-4FB`;!&2L)cC^osW0sSwYvN`g?-{mt)BGNc< z;3Y=y;=FT-WjQhb9R9`OG=K?h2z-eYXOvTO>q@h%@igVWqgi&Naif_@O7F*bFlE4dDp$sh*i;Ti{*p!9!$sTT;g0+J zLRYr7`J}2sh7q@r(0Hdnj4N{k3}yMvz_Ybc6MN9Zd?q4*r~~#NAM9K-x)!n4RRuvZp@*)F%iezjP=NX=9owJj*!O4r!}uDz z*#CdY>4nuFf_m-%=IJ3yo?=FPdK}Q9U$Ea3O289J_N`dNqg)@5Jg-Vn+)~z3K-5>a zB2dmy(O1Dx!dJo6l0iC=_ZRxFR4Rm`q7oCJ<+fn3wzoEF3=AxcTSvhEzzM|>%q5{e zh`91cW&Z~en>ae!Ino*FDB0L;(EpdjUcI;h!eIUuQ6{WnPE45QZ;@Cc!7?7=&hBc= zRlL0M&D%>-H!Xhju{G)BCU+knp0tWN5Tbu>Ag}GrHK^MP%=6kI-4jF?=j8S@X9{ou zxHYZ``Pi5JG=RpT8iE1=-H{l9RgUq8)ne_+nJf3wB5X|Lcl)#OHQQx>5eG~nH=Y~U4V`wQk0#EBxfGKb5wHff zJ_r5Z+WtDEe(^P_Jh6AqItSMh@tM(SK<#1`;>myD*eoQCJyayP((gbT)_e|%lR<(`8rlN{5%F8PJ z5UGaWl~qJq!+vI;nSRUg;|4w#>%h!NX(iZ94viaxzS`f`Z!=>@o-l(sbjH(6W2i)z zmcW8o_Du$YTtp?WiXtU`KE9O77IUts2(7_q-*%PZYYNf2XUnNq83=ARLtoEnG^Tw; z(48)A!`Es6&3n=~1$(dFlSO%?o_KZSeTj{!R(uzKb{@U}|D8OTLF)~{KUw1g^G}D( zPprDz8`%CRCN8Qrc32z;Uq6Zoypk;XbI7XlYNB8^1tf_^cmu@Q@pVOoV-#@MG@a(J z(h`;LztN+*>Io@feV#cUex_4)mC9tB?SYyd2^T93uHH*t_+s5{zYho}MdFXCi=~R6@8<93Z(bc^)NN|;SU4(jdRAvU zbhzzMB4(-~9H^N$V#yZI^v=HSkU@3A3`6Dx5 zp$2tK%JoE{oAbabQCNx4<*;&u2~#D7b`<5UKv|&MUqOpPFu>oIESq`1VaQTnX`qvX zq=Q$yn#_IwCdc?2rkiaJBlR@HO>pK6t=_8PJf)}2qUY>3u8S68D(SHiWqS#--H#dv zyw#suBSqU{B4Zis-u3mRO|@9e`@d274H>zjjtY(3hP!#9W@}qeD(>-@Cic^^huiuy zKd&7hxpHUHmoW4v3(%cKBAyfNP7JikH|SH*-kVwdb##5Y15<%g;Fdq5=?EY~&t#@v z8fWgvhBKw_#Ev3R8)lX3j@b>$42#Qb9OO>qIXPDfVKn=tyl$fdkYn_MS1MDlZv;^Wr^jvSmZ(*hA?v4Bn?Ea9J zVeIrPZlg8O*IKdvl>VqI$ZV>}U`Cp4&vB`@zQo!Sz8&cT59aq`Kd;I}QhooN=0Vp^ z%?(YwBSr>0#{Qhe*63`1nH(hCp}X}5rbxHi;W?{>b9^FEqwkAuhD>>YQ<*1Y4HsGr zLep;qD9s1W&Xd3@^@1P=9C#Zp87H1?_I$Fxr^+x<%PD<@iz#$H+$K&gjGsu`-f3@H znZG{G9RXNij@Lzt&8rXpo{k`Zh5>0o+)I160H(TJthw8;ah7Jsz+w%TX=-v11Q&9} z=MT7!xxnvcVc3Z%9}=`~Q?^?swfAEQl%9$PaP?Yqr_m<`6Fwf!_xaykionga0?{PA5XTT#N3DlTKUaXU3N_6LL&woy1^b~MWrr%TD-he6cHOlc0RAezu zL92AGwBFT;o&N|_O;BSoM&lPrM2ok@A+Q$tz>{~vvC38=SH%j01v&e;=Z zX1-fX1AM{?Wnw(=Wx(Ab`v=VWLyg+!&=$f;vNbpb1tvtqp?yDvHHn^Pl!8$xx|BR? zD*E%!yAa^?uEDdlC;oKJjkRhfJ%|zn+q|!?(9@#w)o5ThS-Q74- zj5pW!I+l|?EgSYWYJ?MfAvB8)0If^h-K!@EW6XhSkD7x5}KQMNj3uT3E#}yYIs* z^kOx2CsyqcZ(nA4n^SP&&tKsGuGAz-q7g|ysABr3TK|J8ObuMDo#~8xlys~%=}~-I z`oH%V>h(j5Wc1XA#3dH665O4(s_EbNI3y%{m|{JOtO4Xvc;nrUc< zwf<9$&mY0RLB5t0s@Y$2bdhmK8+MY1QOXE#=BSCL@JcI1-a?RKohfV(Cuc{XgC>w? z1N*t@X7k6dA}K&HnI>UC-TpOz_z^Svt1)%6qVU@g4-4sVYs z&$iM6Fjqf$=L}x!w?vl$$`^t;IZuTRRX4!1y9i~G=0#c*awY1fqs@rkjbda+G1Qf_ z#!*i+(pyV9A}&}X=>9nN=P^LqGGDd;jYKD?=<6Qic{Clepr|Z`SQh4n=Zpxe!w|5* zvcRpnE3OvS4JY2Fi+eENBMpx68;oYn)XkN4rO9cUz}zlVi;58Psh>zHkcY!$7iXW8Dce{H+0jT|WiHJtgGGo%$qcUR z^9$%V-P7w^qt0hv98!F^^yClc7}nVeb7tScO<+bO_rHJW=o%7_AE1?j|ExM`WIp=$ z%tiEY4_nepW{n1iPxk;dk*a)EyJ?BI=oQ}nhx8DV{ClP8r!(x}Cu)BXF@S{~ol%Ig z&QH53iVrK&_r7gKjkO@sm=Ioyr&=Z~i8wLXUA}7dJN?vJ|HNMU24087;@9)L5sdJ< z<$nL6m(MKE>FXgl;X?x@MwUc8pN{QpM|R~um{@(bq}P9^p}|=RUsHGB0LiveRN@4< zl@*#=wZT(M0!*T%T-lV0G%ZF%ZCkeWq42XgdQPLi?KxUkEOP^V`?~_X>64J~VuXJg zgUz@BfKC$3Lxm6e&0T%v8Bq}<#zUY3w<%|fa41rt^`SMJcI1UVoy=&coE1%UES{SG z}0mcKP*V0Y>^3dccx>3#*KSVL`D@g0bxZ^vuw?83fGr)aizO8Y? z?P1A2VDwdE0^EQbB?;~bl&S;gTNceI>uoIY08J(AXhxHEYUQxAYwRQTdjKo%7=ZwQ zd>ea#79MG0tf>{?tV2;5d@#H=3R83fyW+rxB?(DF1$Or^rdyV`Q_|h{snIIOxAe2~ z!L7jMUNRx;d`P%UUD9czy##;kV3_E4-d03C>jhQ;qqih6n1t9k>i z8*$;!%3;sTX-x7-2blNII|cAPj+4z&%_W#suhVho7Qr&L8!b7S__PlTfb#*_mtGmO zhjZ_bzYK9T8~jJJNfjur$&%gYs>{-bKM8Ig3(~NdsB=rA?8_{9%&htZ9*l#1C!JJv zdncpX#$rcO`N0A_Y}{g$2LJaXBa5{Oac@;@-}^P@{$j1%+*0eou{B37!K-zyu)tMo zp!-f`mDx7Ej`Be;)Sxj2jUojTtwv<2wzqI+Reu|QYir9}sMqxm@U`1hrp~koW^6Hi z@<;|{eDdk3F-WInZS+9Hx((J&tCdL$F?nkRsU5P4QB3Qf3UF0w>zsay`iEbuHW_3P z7I{bwAr<25Fz}P-;;x8*b{%}j2i4q+{L_`Qd0#PGw+OeB0`t> zLi^d_&F|n=*6pxv3k~82hs6|UNc0-7d3{JYjd|jqerq&Xkn!m>U4Ml=@;_)v+1alQ&g_4B<4aAn6pEbWj^VF z+`>_FNC7cEKj>vf{GIari9hA?)K!nt`oICkdopmm5+TolyNp!Q?U+KG1o!Bo$#QeG zf^inOVmH7BwNBx=D%<>k*YMddW58i#ZLB*>S1_IX3L8n3zsrLS($GKUG49cQA&5>a zGP1Vn4jxgy|6@7|hOOrB2Lu4%{z>V7R^2uRMs(&j33_&!^eDr*zZ83dmdimaSR`6Q zC8L`t0TB~f=r zLL1{*+Ho|FkQit1#J%E7*6qNPq9nMc#-{jR2g5O$f?`v$6tiN?L zqN?IuYI?J`D!-y`PY9cIcFKVu6==BQcDdG-!%AZjL#{^~m%K&1c-YpR8yIN8UU7d`Vmu-g8m{iV3DE73a3<)loZf@QCP~=sr2c) zGE&i<;U4Oz+2hN$ZNo}+lQ#XTpoUvZ`pk^^J3c}WAq?}kqhF0p3Qf_SqfF7TAHAgX zHuTIq0`bz)o2q~z>+52avW@AGHq1PXITN#)h)@vYB-qS;mZ%Sp_b&)C@iNp5;=VI% zE@HY9pMNCumL5*uMWq5mG!xX!a&x2@$IbWGlDX+!n&s=)$%uCe=i}o>--YyJ>8?zv zs0bC%V0x%Np9-sMbRQW;h*e#$K8n?&u~Ca5w^U!xz!Gx)p8oEJXvXqK|M;%0j(yhF z=brU;tY`OfC0B#*e=H95G-zTcr`J#>b zq<{y>8qM$ZYUSbMX}8YJ;m7Wg7X1#krY?ZcgSEJWJGt2tJ+YvH*%z%HP!uLwpHS~h zt2LfTmKKUfl};@sFD36ii&Z(w0yoUY6oIvTZekl+OuT!1_JnDDS#>(qqDwyGO0^kd zLgXj$!4r`aJ!7D9#})Mh(WN;p92Xl+9ZyWC2?O@K$j)JZ*cVGMqWD}){9X$8#Rp~A zyAeAiY~$U8IJTp0bQ_rh)|LZv+p}8Jhmy##VH$R;`Ci00>37ak`$8#aHkN~S7RAz~ z|8*0Jj9@{fwMB2kX|LllCDO+5GZjX>t+f9waH)3^}NTDVe%_FW|;A zhh=xesLLKrPi%72>(+po;fsrR7KFz4n^6a@7Aoj$`C?Eqa^uOWPXL+y)oRa~yC+A_ zfWL|(YI~~IE;P&@CrXB}=xK|wei1(^_7H|VXjtu2|KRVpNK=l;v~}Qv=NGV%4VCh{ zbMd(VB1`5l6D=mj4>!7D_Te|FMOrs=6cLAK%Blk9m4m(2j7HrV+U~Q~$J%x-> zhBb1qs)dHMmMF&^MMH5uzX!iINfMHI9U(@LLb0f*%JKy~Dt>GNZR|t$h)|(Pm#<96 zc;y$f)@VP1u;TUo&~fDyO&*opgQ=j(4VpIq*xj%l!!Ex2QYbye?qHuF5}|7k*tW8^d-UsV+hP-!g9NV z_eQq(Eo|nc)F$7>y>Ly`F5;%R4v=~gVVq7LrtL7 z5lz%hmn_~XWYvi*$}B_)s*DP2Jsid$~Hd<)biODD>Lo|X0DhCzo#3YM-Pa;?G z&l%|Pd$+Ham`yyr&n>C$fx~i7n`g`BGQQZEs>XUmOSoK}jJ1R==KL*p_V}HwoTbKH zS&|zfIS4W{8!!q8g0$mbPp{k#MM?&?L67!9z*tQ`Nes#eMv5F~HHPxy2BtVAbwV-y zx~~N{1()_z51{5B&t&}O?#`FSHM5bEquzGC`8076G`FB;)r1r8K~@nxc-xp0Ey>>* zw@vB^7C%;m!wMnnl^H3hs>tvgegoEvJr!1n7@Y;ATp&|QW~A8{_1fh%Xo_l3Hc>J8 zjBzfbX%qw7Q<_ld+ioNmXH@Sgc9fhe)O+Agq*6v13P#cgrAAcwGFWp)b0@u;*O7-E zs|gqjmHEl^74cMM3o4^AHobvarFb8YO(B=%W0+JjO;0XuL;+eF>{rOIQz2(@3%zG= z@)gGIcDKg!)S6!St^G&ayV29@)8p;e!`X3lzf{kuxfC4pN1_E2>?PJI{%>&i*oc8_ z0!gx`Uuy4C{77Vhw{xOp(!wx|F*$pGRr!VmL5L^-QXlv1+{RAGLIr&=LM^Lz@kJBY z%~`!^&JIFvok+EpLvr3~)jz~dDGm%es?;gSsN5M9ikc2UM2E+o@8ims7CKv0t;T7c zHrdqzN0P(+PV*aV__bAMG!!13)%p`#eH;ud>=-VXZlYvHjxV>)*M@zsmKd@PP*8cE zwYOA&>*0(5TO0Y%3jH|z{JyE_$PlR1OC5i>$SAfXD=%B7R9n{P0TUw!Zw6YaJ2*PJD4sry z$1rhl>0nlak-ah9Qg&mRBdRS242u_vRZ79#MR~|iO%&nPlH&qhg5&Z~()6OHYK<9f z(lO)AVsy??K?WxlXrZhkP$_75lekIrvn@J~y6vZ|KdCM$|>O29|xB8*hg zlEfDGib@1Yvr=IMD*KFl9t5jqf%Qy+cwEw^^}6q0ckzja&7P^>26tPv_)pN4Kl(l; z&I*lIZZ#ad=P5Zj4|~Aq`4LkYDy6&T{ixc6(D?lw@2(8cfSTa> zH%A6{#;QRlCvLUMMWI1_xrBL_drF9;8E92SxdEnfCspjX!kA`sv`khQ}#ijZ`O?6uz}O513D z#+aEyk&YIypr_=0mL-^!=>>Vrsm2lkNu;x3rd=)3L)<7@R2Mw*%D;{{yK;Oor0q;o zgzvo-?p-i;O5x`THZoWXA>w-z8m}yba1i94*0UHh*NwqC3_86eeMUNwzF91X`zm?PP(S`rNJ70MuluE z@n6>i=|Waex`usd$x=ouy(_!eyT*u(*qOEAr+aH0y2i65H%Q7aY!KXMFkm>xs(bMVzV-D78bhYe_u6ZEFtCg%^P-VSM@9xeS z68gL^hk~onqGLeksp-sdS7bD(Y!vUw3eFZ-7cpNVO+%@$-YwW8_IIx~Kx$^s7Nd2! zUu_+WG@BEH0?BlpVOZhRs8rK}Ek>YDO1Cm5-IE(-&?6R%6@p_d4ISPYvU=(jq7p(C z_8g&KLXmd{0d@piG&h5F46IKB3G7d{`Z}bm@)OZKFU?^X%(G_sf;qvA`asW_?pYc# z@s7G&+aBTXaU8D&(NsA&&ot;^Z|j02$8W-5^XQ%o5L9m zT}enePTlN0btT$%?BS3hq(7-yZ}Mu9K%zP)yQjJaH$HRXQC$;}$l&f=q{!*)Jf3fw zDXHoxqEj+IcX;hv8{N=t%PHK_Oviz)QGFO9VG<1=xZr{YFTK_#>%on2J)_b2=^l%= zgYPWMsH;*mb0>&2EfeO*41Ya#34G8&w&lFq~ZJ;j5ZxDI^&Qt<^PD4)FrIq0nx9wSJhs z&`bS{zO4q|+BHGWZObcbTiA2cSs$fvb;ICzy~unQmr=bU_&aG5A~&3QUpzMd+YTa17e_A9RX}^2 z&h_GCb+E&x*8ViyqGsS47XSfG{9Ls^3=`O4m`!pLK~FBD!0%``_SEfVv9h!DI*`AJ zMjSsvq$%<#=IFtZ@fSYc&FFYFYI7}}Yaz5De3V%SOr!|@Na7WHYz(YSOf9TUT;h0a2kBu#%q~!H7*XT8xu)e&%u~@Y9f34b zjPlRJyGHW*yig3isF8cH4+0k+yV6uTYCh9wsfR&l~^E z#3JA!BvQ;|JG5*LCjH)$p+;7mR<_Xw2#s4^!zlt*6A5+rdEl+}nk43k&Z54{oU{R! zy`f>9{?4Zu{ldRo$}Mi)Yll@WAo`W`K7VW#*uDpAvAGIIb}K`7c0Z5QXG@D~^@lu&hW+nZ*3Q_3&U{$4-}aCdfrp9zD`2gF zp9aMNn#OZ{Tw^m_zS>0GanZS+9wR&=c&tcD(V;8y^Cdw@6AkrgizIaFaOyB~-+V0B zGKI}X;0|2%^w;Wg=wzgYy+;6WlSYW2fyR6Z!^z|Qz{gjWAC%@w)WPPcb$ku_xKP&A zd~#KlSU|k17JHIa)54YAVsz@lZE=zMWd@Q{vL5n-#CL zg?}+MOWWo%MdRv`Z^4$!NRvE6IBmLqW$F=B0@y-I!%Umgq9}c=ARE2t0-Eet)h02}}-OX?D9mVB~v{Cv#gc_ldVf1tXvO zwIgu67Wpr&EN~T7gwzi6hkT>i6nmob_r9i~z_*2!0QAGv0eMEE>LEwGvZ5+8*UI&+G+2TN z0Uw;BG}nNDVOHGa1Lsq7sDi;dK_-?60D?zi%upl`XZsFdXZ(PW64%+wView4Y{o>S zu4EtFfhOGs9G-&ZO$VE$WSAq5A8U5baHA2Q5k{1L^gXE(mj|oAcgR4|3?bL8yb8(Im~+kwjlDXJ#laAUC&IWLiKA@k-RDFC|G_kfx=NF$zyXPP+$nZ3<3d{56H<0#caJUEU+E zKF1iCaL$zftluorT?EXtSOExS8Qos?5&>E3WRvx6 z+ir!QzBBF4rtKo-MA*-qXF63cYc@&;w=Nz9Wgz)i+)^^Jw|V$cmO6h)?C;cI2|)EPi}9Bqxrw2h(~B6^*R5 zB|i^dIYz?(_G<6SRO#ONCb^3!%Us;1wBcvaCCr9FkYiz;?@5#v2hx9aSmM z3P20tR@@RF;f^unO-PIi4%S6^HEfN+GeG_oJjBPpQ`aPsO)%$krnm>~*ndM^-G&V_ z2{O?vUqsNiJxtI2bHe5evGaU_lDKeBAC4#6?T(CI9>ud0MxrxY#nvnD)0e6xtoc*T zrZ^>A51T&_B-`1R(-2vq+bv6=(|Zn!s2Fa$?{>WB5Yg;*O97(Z)}Sz13!(D5rxpH| z4Q-fD%~ySLgo9*9_|2M$+PuJ(qdU&}0+x5Xi{%`Ko z(Uiu}I_2sYUm*7JQu2L+3T*gMPwbOmt}_qf^vNWRgy}L&oI$Ri08wXK5g?GqDOnJn z{_x_o)+7iAMvq#*_}PK$w!yZ0k|Tq~PgM65Jk;=#X^Uw`{*meVVl zKpGbTF7r)thWgE;d9-j8P!`DX^Cj)Ttz&xld6mgKCcqWHa`+iL5!srGimL1OjtYX7 z4Hu^%Ht(n41UbI!ug}_qR4s#mxD+<@k7RV_991jyIi#UOUh~2Z4ts5m6c0?>%xO=c zx#`cv0C0UoYdO$MWpvru_R?O(`NKmE_*--rz?mxMyn;AplLi2j*g!A|gwtVBhjf^p zQE~cpUF^T&I6me)MSgY>yFSmlju7f<>m(f#DYweM#l)0MNoKfAwzle)>kIti*a4P#`Nmm{QeYd`c^J{A zL%~Nu1*6=w=Bj;NHaKKmP-nrdtrehCDc8%| zKGd&Tbnkn4d-J0u@Pg;)D?ij!0IOj-@;LQ(b+(Rj;crW;-nL`CIgG@iaRf(hv4T!5 zgg!_ulo3Y?k*^NUJdi}_FzHfE`8tNbRZw!FfntV$PtJz2yQ0qG%RuAZcJ2pIxx=d1OoKCn7pBb;G)nhK zkDg8HL%p_*ur4(3tmJx>^e3ry6p?`6-;2ST2N#!k%yHb!BZFu`_}l#ZY7t+qiSC!? zQIP`<(T*lm0S~vdO{oM+2`D_c=P;;hV7DQ7bPf&9A;GoLtrG6NFb;Zzsq1sT1Zl1& z&g|A>5l1;GOQW{M$d9p9!F-2%lAJev%&anagr3{-;H#BMR3-Ci%*?D+T>$POt&rcC z`EkvB8}}$_O|tD|;dUlN&yFKs!82a5@Pr#V%8fBUiIe#{$)=?49Qegv4Jl22bB8`x zJ+$2)_rV!cx@D}*c^J0Xmyl+KYOb#lN!<)*Nr{hd5 zagQ2ABSY7yCX2T0F!h;xUYbxeJyW4_sCT4M_2I10*RqXViaZL%U|y5}gZ-=$z8#Q!z#v(dNyO+<@UwRYTKLHL%MdF9RPDHl|5vf5F_W+W7KC?Kcw zFe*0ZF~&nkVk_W7$ulDE{(c#x(GeSysLi1Vrg1@?=`nb#O)y=eF+Ge(T|2&dKfm8+ z>FUD6e`Cu0mO0E&M(!dwd!tV8C5C;Hu?q>9Z^?rK&pD$D6cHwU00Ve(g+V1kWl{C7B+elK$S`_n!{DlCe5V~X>s z@=_V|ASv#w@JJO<0ls_A>QihL_YaO8;#2D@TRMFIdiJi5>_m=AobJDSHfG3fUbH?D z4i#8JSI{cod{;Hi)^NJPycGiO~Dd`6fFtH3)#F!yj#5R<#Qe9v7V zemc<%;=r1uvIEG?GW;tf3}2?NWU1lIzPyA)(4r({UN=jZX}LiknWo4p!W4_V4)7LR5+x2-~j z6iOJ0YHkli?VI!=K?H?c`Pl}8b{K%#4F*?pay7-ds5d5pkKNT5eC%g|X4Zc4zlJ_y zf%xF&UB#HkH`xtcd7Tx?vvSFnj3&63h+R;> zAFg2anT0a`70YJ?&YD7-Aqk-vHn2-tkDGr5^3xHu;*agM96mvsTME25gHv~)I1PsxB&?<& zH|WX*>nT@#8%wet`#ff3YkdSODBm|we`=leLe8p@QH-sQ^hRDMobrSnWO|+qX1WGb z^^U$QQ=XHGFObqkvU4`2U%RKBfzb3HOT4l2MuzqDY+LMr0EnN&1}!PKlnl%Os=Dl? zmtm`r5oZE8k;m6q$*bjWw5zJ>zpv`p|BBsJWx0AdDe}(9ajFf;(Y7AZ<;iSkiw=4*-H@Ek0$Wm77v98(x?L)tbAdmY)ZejH{W) zTrm+cPX1yEx@9wNSvIvg6&bx@&of@a;pB(K#zdJe9HtddJ{BTYc?$|>>@0Qw#%t2gYJ!^zxHaw<VhW@U7J5CRqPixjX#de*D|(rEF}ANB>*?R>tDS%hxTV8c-R@T4bb-` zx(3U=(%C8KXb9+0Km4c=H7Ry-LE_iT8yTU?k%pJTv~;?wiP*O zhozn9SgLM(AmH3}`zFjIeONqvDRt_xi-r#2SG5{p?-o}{tqWdJ=9itG@BUugNNn_& z3DUv$0RG6`3sGwjRE%Un>xjkBl=0={4QO9JSc;-=tn?87SV^WeDi3CFw`&e87_0HYQOE!g-?uC?y$jW1#9uH{yNwZ4 z<3t zBK!7oVe`|*Zq&4vsqdu77*Ng|ZN0|{0kp0u1`jv4^;-Amnk`TvB8k^MZ{3)8$pd^g zi%YEiv3fz&g4fCSzZ4CK0R}W9(Ha~#zQBhk9JYn4ZQVyC2mBmCqzOPR-R_96z>cO7v3}tPaQs;}{EQp@w6nBk0 zDsd3Gk%uOW7&GN_!Hhm~4hJzdr(NAjxDv1~fh^^Ea@KCnwWwQir@iKCPb0qexpD5x zO8TWQe5J~!92z^gt=u3_izrTSe0*|=O-39A5xr)yMzo0>y22pSX)^IYjev*%@lzft zcrtkl*1#k}b=UMjVT;}*&4{CI;v0~RVPetBb+|9kDr?gH`)jDB@Gd?_GGQw}|QA~F?k6^~Z`v8<0 zE$zPZG+3Up1B2j?@&Qkv#J&6ff}U`eY;G)^K6rzEi^yj3!f`thOQFKQXL(+5vKG(2 z;7wV6Dw`|D4H?H72?sH)JP^rSBm(F5m9`QFxO{ZOj750akZgfJn^%@j zXewf|C%5kdStX>Ckfw{3EOwdJu#L>%LSx&yKu+XI3mrW=GS~S)gRyC2qj39Y#eUo` zGzuH{>%Y`h&cEMj6;WRz;qT8${#*Vd_O){`rZLcWlAM;Gb%mCjbybmLR;p7JJ3Jbv z2BLp(RM=OB?(Y%;h6DPqR3y{idg$$+^z(o3r~m!t|6{xLTaUh#)qkq`zx-0YO+7$m zceCk4ro{ZfXV0%HGhuRF-gdkM5M8*)MJKzg~#B&9C~|T2cEqrwYj%=2u5rqZsMm^jCVH_@T&!4-=dp_);*VWQ;9D z4N}I4^J1{&r^k{s-^l_;;F|p<=VMH>+)bw#kS6Jn*R~L!g3(Pi3is~TH>$u?Rf5Pd=5`6(z5K~t9#dOxQWgBNMGh8PLgMtj$y!onxo-Kj}4UlTLi#>5M*J($C;W7#UHt(gd05KvK||@%c*ActR%55$Me%l zgr#q+5+le~0&Mx1p~W=O3NnP3Or0al+D>HLN0^|{-iLNCN0&g=Mqa?Ii%KYcjfz8fk;Ej{#GXHPkL66UVaz!$ zg}HBmz|gc5q+)U_$$KdAOs zET2D*@YN^%><;M}f|PKIh_NneelVV5zxgge`oYio*#ht#R(2(TbznkwJ^P-YKEPBg zqo~M-Db@v78Pg*dm2t1tDk=(fU##lWfi+eoC<}CRE_wf-%pN$AspiSAlie5U|1z|5 zG?+4at=(h+()s3^^-|>o z*rlu8A6EzLM8<1lcA9_R0x?SF1=XDS7$WFTxZm-ab0*CB9 z2&c!~Qrm;-^)*F!ed+AMn(>hi@?rpmk3D4y+DhqiIj6Tzl`FO17T@gr)vb#3ibP;P zy0Qt5ugvJrnvTj!9AJjAwzCX_4^9s5Pq8XDVEu!4)|JE+5-1=S$1V(5x-A;#r5fdL zFPsEimwi;)Cm1N@S;y&FiGa{9f%Xo}Z5G(rH-ex$ASbsIG>@-VZfoziPzz@DqCOv2 z&zHxnY~Pv85sz{O9+Pc;6>64&MS3bqx3+gguNslA)AUB}B#ha}{3=O%7pm3z4&I#R z&6An+r@SC^=vo1cER;rrVQHQaWK&Cqg{h%ZN32gRI(=()R2p;MpdC`L#aiR>w`tPS%k9!OYb^oezYmS z0{=bgL9#UIbe&`oH@FZLp~~S00dPlz5fSU-J7|siWssH>caqd6&N(QN=6{ukE7f8^ z$h-l{Br6mG{wja4r%L+rJP(aH@>7OWBYReY(F#)}P|?q@a_VSV1IOsh?|PS#Mi8lmyNw4m6~4 zJ5L_p*F|l|xn54erYyi_lHnu+;rVTm`t7GiFa{~(E#~AV)&e`EU0;;|9YN8rJeLzz zcdTs`Te#QC_SbOJnrLcI1X9a&{z4S0p*}x+iWaSwcu@F)+`#Mz3+*Es?08Gxl!HBI zi;AcU)Ka4VbI!?B^yKTXr^G>9t^`*$B372iN zY14uq_%)H_s#MPyFuU?*9{xY(YKBv#ophXbYUR?!lsfpuY$? zD9fEmZKThO4hz+w=n;}M^@rQ^%R$fU65|}l1rPPCQ0~;nYAX1zc9Ps=-|0Z=B6wyO zlC1HW7LL3?@e&q*dw=!w@^x))Xd!?T6^FV(?oQoc;AdsMC?4;p*>)V0c zm|IlgsPS(j0fv1~(HTbLX1Q<$@LNG;f_pa@U%|TRT4pBS`p+=9R!BD=x@PblzRB2m zvE5s_z=@z7ti)%11vD|q@xIX;{v0Yt=9jXRm zj(+8lx7qk;94jQJVvxeE4!U~MQ5ARcvW-1f0{#3Xhg!O%(V~ zL&lUQwrePIiOG|RHV#?B40cLbqgs*>5r$JP zT=|adPb9XT3c1)(5=(3snS`5~q^d2`sB!x;OXXIW5TBXihV+y{wIs&Wvp@ERFd+N| zx(dgIX48|IS}NYJq}QS*iwxPynD$bqf}?{6}|WT%eg6#GliM|=cxm7<0ntH0o}nDUbHRvger}3p#4lKGjurg`UAG?_5K!+Oh#(( zJXdXiUFLifuFE(yivqzf^9J-ily~)tLF0N1_F>$ff4$gfJ&z@q@+I$ziiDJ;Wvr;7 zEDzE>>`US11`u?{8FsM^GV_nPo+#m#1xp5vy}(l`_ReA9%BHlXpPg-W+JbiWtl zrfy={talf};%2Zy1TgZ^vBWE=lB3%8sia)s(?C)ncQv2j?p5n{VC!CNWfw1P!9Wje zO)uel4oZlTJcUtK8Yo*}*)P{M6r^aVEN<`e$R07=R@Vz#FsXTRLm3)w+Si&C0O}|i zbm$~ASAP%=lgt#^AcIW!?WH-G|Z@^Y?tl+3sxOM`qZ|75$Y&+TYxnZX3jNSrOAF*(YyOyGT%zdAv z207HU_r7c1@F#8PgAWNK7AWVd1}R}II6p%dYRktWNYmQZ(r3R_P~|H z9DBu^Fj)Ph^4Jb}YNFAq{38Nnc(9>!(yXaf*XvdN2AxY%1Nx9Dh2RF1^6saN% z1_CL{IiZ?b)7xa#*kn2ZqOjc1DBajHAZYV6@WEZ!^kuYjSrWY$|2PD`&rMyFQV|VZ z3SmCY3dpOI#wmZ;@j|YO|SeRuFl(M|zx5Wf@o_szrq8 zrYB0z9ShCk+`)Nf$fUZ0iy40w$khaSZCDGd5;-oJST`E`QT``yZaS{W^{=k zav8)jMWfmN9%vmR0E#?mkjLAXC;e>VTAzzIg1|#KYP6&38t;9&6->$<%b&8PN}#nAZoMv-qg3a?%%L28UY*Oo zYLleqb8VO2C)c{Ep z^M^+j$4C264$i7}5m4Y@;QLZd)FF}@K*fGpi(N!K z+$S;li`bzQrzD{qk)!#oHscZg7mKs?8;|*Y(n~P)Zy30#~hZ#75=vQUQYruCVf>{!-z=i}OQ z$9u={;cCsZw)=VA@<;tYXC4io7l7&U-%R$}3oO?(#;nYb*e(0lbVwhD#1H;)S`?g? zq%VWLl93XaljrA_j}1#)JDW;tYiq>pmnF`PVii-x%Enik+z0=bj(1~obH)Z~j2zo5 zT|IQK#>)y^8qEm1joA-la4^x3ZJGl(9JOyfREP}>@Sj00cWx|IlX?eT zx2or7@l`t0)*_9BD3PO#CyraeZOfKrsRxtvu{g*KH#?Q*3%Z3EN;^>3rC=8OO@-?p zzXyj+MPGc+bhTbdp;Om%sCM2Vw5-H~78=XiN@PoVn}9W!Q6pR}XR>o0lRW!@=+`xi zed{kUot@@5bJnYpt)@(u1)Fv0&j0h`M_IerqlVtKGIJpzK2CT4;k|;8=Ld2F0OGZo zlNzgZWMFtLT}OLz`q9!0FeVMaSW-QT+BKvZ_1YFNw~CW2iZXJEx4KpVPe{LtiZFq-RI>+HOol-aAf#co7UvYzU-26b63NCW5tVwOzdb+X!PoYBvGR`3n(F{PEM|+AN-@fRoe~Z)V$LWqy3gF(=uRwOpn z3hYHnFqFxr$>VJb?j}a4bbMmVSp|~IRr}QqBw>&elEZ6aYn_#G)TyJv@U`%JqRSZY z6aTJ;q};jK8s`0oqBaLsKa!f*F74f#c}dZ?F3?*-O*4x}L*uaa%H99;-agRbLZPDK z#Kw>%7ZUnPFh%VAi{NEd_gci^N&ZLwEvmy$G)bw1FdWC~kcO;5N&~55gOuGrLA`&u zdzAfrU5nWD38a5`qrTQ=cqmV}k9Ag3#mPfi42s)O6=zbT4cUeF?p*|oE^%bfY;B&6 z8PE89LSQ%?oRY^zd&z#XL=1p^w1fkwasw#Vr;(JNF~^78WrV4oVCH0g>GSbT71e-M z`RhR-Fo3mTwSy}>gtIPeSN#v?9V6lN>gtxd!KBeOwoh)E?mGMg0znp9u2|k(AQeH^ zZ2qc8_N@0jjt6u(h&wWc z4={Zz=ldxC4E+F@NY*K$>#J!f@2v9*rG)Avjt}xJ{|woCE+%`w_C&NiZ9RTRlNQ}R zw5y_gt&1RsW%qvj?AA)N*DRyZVIk|p`qsXKx+MHh^&-yvA58dJK5HU?Dc=Z&4CC4LL&Y0ekb3K$*J2;Xb5<^J0B zekAh)TnMGwe3lKNWr@brb2uIeB!S#W1$Q}H#O5| zyzrQB{mFB*%pyBjF7jYC`$CnR?>aI+|9n)el=KWgFs@V$bKKy(Z}LQxUp#a$Z@aQ5 zRG~bk3trlAWSKN94CK(~f=P&kR2%Hu`^P0XD~FOmnm@Gy34{>gDFWEf2_q5H%G%}K zKq}7y^UMr|e}b|q% zx5dZdZBKdLW;bPeI%^G=U*o(I6h%jO@^VyYh25Q%x`m!3RNi8-pw(3)*x%)GHg?-M z;yB3gT~HLSMAJwsOqFPHudY4G!X1QC&)aWdF}neJ_sc+7Z~2=lu>vJo*wM zsoE{W8eMhs*wwLdBin{EM?k0z5JL8s&ED09!j6R$M+m?TC<ctzUg#YbaE*>*X4e-a+oml^I2H$ve0OCOLe~l7;B`0=h=Cz}ez2+DU4|Z4qwt;Qd zu8s+IJ%g@j26Kw>h-_MdDUnpVQpcg;RrPOxs)0r?Uh40hZ8?~OO01*No-Iy$MkGWH z9FA0M{|r#Cm@v8YT7Bp^(OPsaLzoTIiTU)1$^5vsVr2#61-*N^#oX%!^Y!k?e57gK zEU7(kol-J=@(9ZLyJg@Dqw$BnL^ynjf*r&GhFl)y@jPr=S+s7&#RN0!TD>emKtu!G ztK(T)usGg!W!Na>cDC2HJp6Uhv(eh(P{#KUv5mkURg%N1t{6m8o>Gcx;-rDAT>Zan zvS&|))4GEPhS5r_6eLD`K0%78a^$Mf;Zm-oyW4@_8tl(VY7xp8c zp50e(o0^BKu0-B#iFDD$mk-16dre5C9?v%5KR!rb#Pfff$H_Z3Z?qa;3~=c1(37h}k82%%B{L(8tL4i#5jK>uo(HY^UoJK9w+TjLhj3Q3ALADK_P)C#dFOv$(Aj zljaOf_Ucm=Tq!1GR8GW2HFQr%Q1J&xm$(9x@Y%3}>{9M`2SlVo+T0wBG` zl`!%L#nUV*h}9a{LT)^NV+{#q^qWK%>2ga{-R6u1qle*BL-tj>*2y?XwQ7PLUgvHQ zKMJ2b1*qj|o~>kMT)L0E?|Yea4Fr)Kf8o8Qd$$j1RtHcSm5T*f=tI)UyFazmuLImk zliv;ER3Fe7^)eUGBZ#jNqDLqX9i%K3$!SEaF)z15L9MBRghFnC@{c_C0KP?`mr`uW zX#%t+p~rL1c~}Q|rs_f$-^@(j+8M7@FF`Ykb#dFKsUx)0?HkP5jQ&PPMjf@3oGP!s z5Lp+z?)KT|8%DG@pTuI!B>zoyQKD4NcIIPy7@McFznS{Q3W6g2fIj^g!qUL!jM=n% za{v-vtV;VdCFNNb(3|)i#k8Q$B49zCg@2kZ`mB%431;;;Vpk!bmQp!5*mn3M4sdCcMs z*t|0i7KFyFw;fw}t%u)Z*b46Kaf3q9LK4NLQETxr9QIY+eM2&{;_uM+c`sna2*Z&F z#ZW^Zx79&L);bo*rE^r{%FxW1HXtbt(0&)Wv=qbp=qct$5=;|dh2|z< zX8o{~OPUROx}>;v)3|Top4g~~Af~49aR1Vj&9rLywnt>DiQ@KIS3TDja{T?HZh2wN z1Hn)#UD|V_(u^7e74vb26>PWkIoIOc>+V zb;zgGSpj@kE@K{wQQ&5H+RVxGTbEC+Ecvufes7IMO<7x)!iRDJKEv=DjD7u#s(4A9 zmEKvcVQqSNkf5f(e)(o(H~Mz1DO-5A*dpmDLJ`A?u?7PPJBn(pMjlKA<7Op8@x&uz z3gf9tvqUxX9FnOT&`3dfvfQjrb7MF0ALMKa*jadYN$DqUBO5l=%gRSkjB?Q?u0paV z*Zen->QC*ksD=cV;r=0gu+qe7l32JB%cg^OJ)oH}#wY)TA#_l1Q5-k~a@u##Rd=k_ zI+em2kV`d7x{L4Vq7t^ww$2%xclu$+!RSwY89ar(D&uVMbF*)WibBhSNK^jF-IF-? zb9G|OC(5xs92IY0Q4>4L3e-mc*L|p^7@)~*AC))tNsB;*6WKy>ipV4V?Mrg`>ZV%X zmewrHi`KA-k#}HnWUZR}hU^CsXF2a=B!5;?WPdteC28fqyDv%imfQ|OuF_85L^n-y zt4o3&Zo_d(+uj~|K|7ShEV0%x({hBx2ZF4RW8S_Xd&pLKM%t(+AT>&cngdkItqXo6 zz^u2|W!f?7_*j^3_~QqxYDBs%F5ijMXe*2k<`=_aW3=v+}>P6-&+Bj^H{7l@LjJ@ z*yj#vp?tUVZP#a1SNsGla?@HZnd`jPTS>)Ej^Zy~%zKT&0fsZEE$)2yD~I2U?mvXYfXV)K&U({? zra^#HP{G+L+<48@_N@G*EIlEQH@KPtI5#k)QM0iO&rd>J<*%6M(a2Xn&w5U}*wdyN zVYZ@H&}_8J>&1Ydu<)lYt+pmf$oe;}E{RMMtuA&SdVWeVBzVw}OE|3OUt<)Z>vUK88 zWxn(2yG79vO|o4>=qA5}AE@GET)dgFFrujtD0&OP-+<$V;h&m-C-XkFoKIs;K+;gw zN5tN44^y{oR7+JBUx~krfB~V*wCwYNykmMiPrm-x+MHJEb(z*TGS)|KVbQcW1nB%+ zF2nUUmv}O%NW#w1vQoBc4G8m4!qJ)arI&9GHg`X#{!N_MZ{^1fQutgq98#Aas-u*xnRn)l*<5rEDhYByo60c&}35I)^i-^U6JP-amgpLmM4U}Gl^tJ z$4_0&l@%P;18wI%0zE4$xt}rEu2GP*HvDQxi=1{+BkEMu6bYS7(;=RwjnI*mlgVIQ z&c&O4v~ZlHBFAS|**6&C=$(P6fH#W>Y^uY`JYV%#ksTy1dC`Cn^e)&ClenoL7Hj?# z%1v7}V%^n6Y%3I(Obx$C>?D$c1AQ(~A z09Pw~cnXa?MGo(yD9A$X0^&RnsGAYAN2X9dG4emyhsf_|Wgz z!m`B;Gy9aoyI72ohHzt5IU!9XnI)}^U*=3HG{3s1r5jCVv#01;JbjlS8|A($@!+Oh z&?r&VjY6Xgr`VCW`t>g-y~F-vc&jW_aSxR?8ZWG)g0>3@T}0!;=uSh9S?(F&woE?v z8t^7|3bZ@vl7EJ03|kxJ6MTg_HsQaDz~7D#tm;iiB^zjI4eUMtJf@)IarE|p?xG>T zCcR8@75~uh1(U_Nln@DSePqXP_yRhH!Zb6BV$E!PnJvd>6^A2s+HKwXhD7mU0p*S( zBUqO6GJk<-2s7vs+?eE;{FYp>rqzD!W*q^e$GY(k1vP_>vQU4Qy!ey(mc3ba+_X_| z3yxz?M2*T{NxmvZVFE1+d6NoEh85?FaS)$a!rdox(&MyaJxwOro~p=|a`>kcTovYm z@K9F6a&*TB8TxAW{PYKNSK~T|yiHA-N3gj^6UdYzY9WUibW=Y8$nA2(5_TxrmvZ+$$4YQ@{^W|bJUYQ2P z6l`PyTIvKyv-X1_cOPn|4K>O6Lf&U)Lv^1aqx3P%>jHyszD8!*TKeHmw+J_1k4fvq zVW!$=YzjdIYjsN5BG+kSw)Y6rXzeHjWryd+%_1dU*&$L?7W$1^ei5_Whe*aQjj(;S zqner&W2-o(PSqXt;uDm?!Figu!i79d17 zOxdQNNSy9%O#maITJ_r36WWS(5RCZ`-F2c5zsz^-%IZgFqyO6F^hKpdJuE0=yJRC- z)b5*UPvN95c(=9hp>~JpnFnY`pR714nQyDB3YaU+PxfNq350Xjxt8dq?k9u(Q{6%~ z=lisB!bvW8?P{6Q=*P}}FQShFBO62q+tbNDbvH7~ffDq>G4aaov{N&~_6IR5To91Z z$Q8!s-O0d!9uH}E$pI5C{9z5-&Ni$+n$%~F`{u)c3egcQ?@ zryar{s-JuaRdFIFv&Jej#6kW#*>PBb;lm`<-s0F7=dd-vHpYEzM!aH{-%D5`XUnB@ zxkJJYBax2A)Y47K5k)Xq$My~pSUFQZ?*2Ze@?5i*HGq{OroN*_8BY`V7QmKR>wP6N z+m2_e;QAHM2lJV7B~rl`X7i8Td|r=12s8ZLj-4Ruw2vO!xThsahz<^zHR+Ty8@ZVP zj!l)mC!bk`dnf1?d-|kV@0s86K@T%!yrCBM-<+1qk2Q0Gb(yy9rReXg?UHDL$wSfd z%rpgMMLUpF`T#a7Xw#rUg6-dwYd(c>&s*vwGM|NP(O4UN=sI9-_mVHiPr<*c=s*t3 zOE4F3!&B_;SW*RIZqRo=ybNX+B7P?{b(wL%tJ7Z4UYYc)&N?{kTLY);HA;u7I`15; zPEXT!qUyqaA5&S_!Y00$rIwj^L)hyqcJXU7yCHP!93l_}TE5yO$bUp2M|p2RS15}r z!O+`HnR9=DS5;JFI)MOIv`DLfYQnJtC{29bQ0YcM*8~z{WKw)>gT*gKS&J230QPHzRR>px!w+y^z*G;Zo$;pwgh@wO)rwJrX?nVo@FKYG~s3N)I@L);cmRoD|u<7h1{OVI2o~5aOxc|!b@xt`N z^8DQaryXd8`x%bSQI2@Y6)wYHgv$|hgV`e+kPkwI)8RuC{5?d$GIi6uedsNsrJsXj zpm|_?L41<%aPmziCgOpHwiesw91sCtM#t3v0@`f+zw~mtfmbQ`2T@oz~A`$qV%*5b-W7AXk386^+f*TVGX9b zGd|YEE_6jWbXC8($qaDUgTRTaiCN-QdDAvn`M%wP%eFLs0JFM1yH&qkyKU{O_0#PP zh?YcoXNS}$8ITG(1IxGOIp+gozLm!mAoGfa00R!<68K)Xr++u4^ugS7?Z45aH`bD< z+VvP`t9xuVq(gR@YGdv&hwMBi0=^hi#dk~~CZJ{SLpdUjRh+eAZ;GXE#sB2!+dBTo zKMuAL0NOh~fTNZ#rhV+#)zY1MI+*fo)K1G?q5oyvN$Wx$Mrs9XkuT`YdjiSwblv7f zgmdaUTJx>oO}G8X&>hgBcoq@*q8`zouHenzkBN#2!;G@2EeZRidzg8n)+$Wi+OD&u zPi$zthPAECA{r-QuN6nj!P#(XK<;+FWtSd|>+7w5(m0Grt^i}9orXJ=@)0^^rI(2| z!~222$0tEhw8cdRVR3?`qc4vm->-qK=mM!H(!E*x;5zn>%~>_&YUOXN?Str*Js61) z_s^fdm}{C%iNf&WdL%O3VIxKe*xF}U16!3g@DH-9_IiAtjzc$v4~}ZL1@KKp+Q64A znx`$}whYatQ}Ty;lqaKS!bc(`Zg0p3L{2=?qH|ZncG$x?2fsRPSu%b51r}*BA9qVA z(){bV=wM4^Vj2=?2H@vY7a+ui`-%tu`m$!qFc7ud)sfS4NMY89~kn^U4{<lnV>QHTf;tbSfs0Ips-Adb(FQ*6l3+5r zn3!x53i_OasGTePyU_NyEL~U^Wa|R8+~(62%a=3Ad@EN#NHY__=&Y z*jAU-a(jfGxks?-hc-qhqW^JiDSQuQyqt@gF}1dIVSxk&xMI@bGn_FwWw?3?EP4S$ zF-9&f@?P-zARoyZSvF-aJ4Ab*l4hv*0<+?GvClbnJ6Fj;y4s?@Ip7k7?PZck?Fd(W zpi&~o;d{0MwbP{H&7tzj{{8BH_@ZjD5_`gRMGRr#S1efZ);VSkzQ9Bq2sOOfT&tF# z0&*OO$(S$Yt_&2Np2&~Tkxd3w>c~CXH)mgNc{M@clH7~AQN$U~6|_fw{`Q$1l|{Uu zPO;>eyEmcBpX9fw34+k`INCjG4J|3v7wkNJMNU{GSq6tp3%?dr+L|cp6q?!0VLNmC z^IGMz047y$Dxvp$(io{M%*F8GxANLZLb>QA)q5vH`*ba}aoRHDybnq8sj8B-aETVD z-pzEk{i)_Tdt|Uon)~x8tSa6c{j0OwUDkhyu9yD1D{UiJ_#Ms6!9^&5^U1&SsJfl% z{ZU!+r4y8$4aKTH*;QgGXRY%b%`}X!Nu_qZwmomFkeFNzHrs(11BHrkFVa}@0J6WY z{5sbW_DvN0I=D!6cx!^OjO;ymET@Yk!bu#mR+rx%m2zbfE^sQDqG0}oI> zV|Zp;%8}cL7#>w@__LF=eo`kYks0^(pO*wj0-U@z37fI>OeHHc&`lwK>a! zw$xevK(zD%FVeCt3gF*3x#Au#(AmH)i9KLTdouyuz=S%iAw3Qux8}9Eqh+iVdeX2y zeEBwMx^Apmix5&fkkCF#pdxS!ln&kQIBwW)IhvoG-)e+vVJsZwIJQm94|3c84ZMCO z1N=V#qd;80bYV{%cU4L$KN!>iAYdYq4VR9(UfD57*S&Yy5@WRaTebjADHOu%ZAz)2 z6!LQ2lf|6!{F5}sy(LAxM<@D2eOP*WHWW$LlwCYqX4RjcdK=r1S77gyUp8*rOW8((?!n}GDjoGiEVGyS1ZM?+*G-gtGsEn4|Umx<);87elk?Zv1 zw0ej$4|)wiqK_cv;~eI38D45Eoy@*6)t+e!U{XHl_o=^uaU^|wz{-}BY=@K#-A-zY zF6>Pz=}BI@PF#Z1+09126lLcysY3pDtC(gWAotU_yCoapJvCb*h9)b{rlR%`J#sL0 z+joqjEy%c2x^z#CVR&G6jdkMp4AVx^q-o~bX5PbXifZjG&gGxRg-L*p&bU%{;Q6D{ zHOjUGf<5gNZOsXR3T?B+u%TJ41F!}L?V*15;=o2lAVgh){gFSii4p5djz+7H2imjne)oti}W>m=P|lbVGz8ZxX{eb)<^}s zs#RZ+Yg}re(M5RrX7R*agPp06pB#_P<#Dw4=HVq7VD@emEaZ0y;+E#b&G{ZdD!bY} zthYvjG^nf>6^{@d43}RB;7OW;p1oYH1f(yZMcB5Z|8f=i39?!31gWZMfodH?$GJsZ z-Qk_Z_4d#&aELeR%A)yEK$S(W%khjx)8!?UxOSkJxHczf!Q(hTv&rByW`jS_(Si9e zO7j6DwK_aGQueXp&tOvcz1oii!!k*4ekMsq?;P7hy-+t@(Z(wl|g`5*4(9$LKX#cQa z?We$j;1!%!A=P5i`DaiRhupR6fx{%5I?ph?2INo?N?*k z>u5M#3S|jwBI6BoBJiWL)sie4a<6vB+qkT0$bxD#C^y(RV=KXjA6qwl!iOJO#)lse zn}SZ-KT865C3lanaWe`qa|_Iz8T*VWB`EU=C%PyQ@HKAQ7IW+mKU?h*J`nX-@Gt z0|5hF^<=Y$0K0%JI`fPsJ8LM4ho-|%` z=XYhY^u*cIbpEpj&$pO7pHZrZ z8PBt?@SJy=v5eY(C;kAhx1_TlsYiSQ`~(6L9|%N~3}*a3<7SImmCg7kz4Hrni#{;Y zLcu27g%{I|_J`N&c#wn_-B{k^GMW4i8(Yw)g$I~+Vx4(Dbtuv2ZIdY&XCKE4!7_#bdPMI{B#^B;35m!Xq2CH~@H4H^Y=YKEJ=zM%7 zb0*;PYxX#MeH%@k90R<1qA|dGr8+CQ^uqUk~HyQFQqYg++4T9^~XLm>Q~p3 z|6P0I(zPFNZ*-S1`_`(phQ0B5BoBD;(+U6elE2d4NW}kRdm~|eyuHyZzW{*^o`;X4 z?hEke;LpOJDf!Q`H?p44sljgeGWe})|8LkE`%16a8@HE!qP_9xS~ebpd|(Li7`(Ie zFW4LVO8;7WBcu7hWN$QSiwHX5L-70HABTSe{weq$mHubh8;$-sj^8184L)A_pJZ>O z4cKoehk=gDDSF}RD|%rv)AB6hZ7>hu>mc(T&w{+ZoTH*+ohYo6=6IVgLS}nS24VTGlO4KJ*0XIw*HD*^Qm5 zX^Dtbx&Ez6%nE21p(v6{|Ae8^&oJ~eRl`d6r+`+AT-91dx*6B~Co!c`OQN#Tj8E>= z>U#|Bhcq8qod2{S&eL}Y+85r$#nIjd+xTVNV=77X>0}9CbB!_vS5d$Yq=^f&UWx zx8RS!55d0=Zv)OE_|L&_f^UG|0Uv_@3j9;>{|es+e+=G>GG`Hv!pGs00vtCRei3{w z{2KU;@b|&*fbW5S68^u#zW{$6{`c_j2d?soMP5&w<>uzWCxIlL9vz%DiAzdw@E(sR zk=)8$m&wIPf@~w25)T*2b-HXzcb~Z~`#6WKIwe2>7EUx0Gw; zB(4R2H?w+|wn{B6h_*|uV$%cl&ieNDwst4SrOiNJl-=d?84yZxzI7YcPDygbca;~e z+i(@K@w2(hSEbFk)hV^s-q%v^6x*CltxaN6ZA;UG_0Gon+U-U;!n=*|=$}ulZ*7zA zZ*+ESuiaMfY(U*DZ9AK$6s#4S+FGxc`|Kx{>k#YyLb;VxZoAZ8@7&SUE=sj6&IYM< z8{s&&)wZ-SM8aF~iS)O$wbt)y5T>$UxroBxUQ>RZu+ZLJT~w~9a~+*O~5TibrWM2H=e{hPa- za2s0MP+jZ&&h2eYts*N5NL_uMQGa>Uw)VD;wg%DZZ|b0-D$2=mZZs!oS<`*(we7nJ zZwAdd6YQbxSU6*b*J#w|Fon5g%a(DgCtKNC3oNPi^Q~<=TW{yMwe@0IZHHKhDX^p7 z+qPZW&R|A5(9~Mjwv#Kb@93z#zkW^Iu0l@gsBh0(zO1gLg}cU)+-@ksx3BONPbh}` z78~(LJUFMoe|OWA0-Hbj?@|80v{t=By;Ripzyr0db!APh^@SYXN7jq}`t}aYACBwd zJdh5I!Zvgs_hiB*b8^*Bg1B);L27TuyqE<3w}i^pMo?_2uk-BMR==I*Vo6gAW+umF z6aDhGI;o`|p!y9MN8BU*D_7E9U+=j(7ky$oW>iNZ_x(@E32-M90!?-GMUA!Xo7&1r zp4RLZ>$xPN|50>K_;@(_;eiBSy;#cFEo#I3Lk|+JPpmV59G5|9;&#*S?e(13$gRb? zvwdA_Lt7#D&z4fid~tn;*xt6A`zMwvf|!CG?!^SZu|iQZxUaE17Ue#juu*KOY~6|3 z$^9-N(B34n9^w9h;S{!DUEp41z3ZiFxF53_U4+^88RFnBPdUYZI!WIsze`7WR29&fQdjBD4)@OF9|q} z;#td;9^ce9ISky3ma?Mq+U-Wyf_C53G* z$vZt8H+afEPI9N+w3~L*ZrV+|Y4`twE4<##ZNl5}N%z+E?vLO!)~O={mukl6BhH)g zuS|*4KM^CC@kgh`_fLr*m=b?%O8iSx;$NN;r;E8{I&;JCGta%0aFA>yet91EAxHCi zpU=2m+3GWHD^?(+@(!Qzbp7l`H-`^hxE~;#O*|pQ2ZUT5Li)(=7KB8YM|eHLW01ca z5I$aEJhEv)xC`OE2+1H&hVVgzs}aUYb`jEJt)(Qlru%2N`(yp`I>XcdBJttBrC0tw zn)lJaQnc+a{e?c}?^=w#Q~oS}<=@ou4^R0^_$&V=%R0GfH`Q4ZcqRh$J=@lYcR#$) zgn#RIMtJa>M!5HD!!+eM_nsgNp9X&ap*IdWKb|bNcfttWX86Ou62H(4p9B7@-#Gh? z>$yLCL;J=(pG<$xK^CjP!cp-?%^OZ`%NxyaEdMC}siEHvUxcM#&tyr%#jMxj(SEj! zySlGYc-@q}%xZ?T7G)ai6}yLpO`EL&w1(KoR&9nUW;nylOP!K;omrMbyGhq!!f4%? zZF+()G~p}FbfK9pGSgnO%tjOLGsA#Mzsjt;#e_cq?}XnDPisxP$!n5{A2fO1YlaV- z`LdZGGU;G#WtR3Q&GbQ&pQp_F{>6m<$mH*rX8!ADerB@K7t?OqO}l9~?WWzd`|I8R z1W-!@1QY-O00;oxfMPD%#l@cy0RRBR0RR9A0001UX>4qHE^lILU69X812GWBXS+po zmExgC!5pL@Xe`u|2hpmCu>OJKQEJ>|Z6NI~Yg+Z}Q7^tqpP-=l4*CQ=c=6`RI=dSs z-M}x*e0&+cjPJM*KeO#I04zX$C{IM72g0;aL!O{;yhWf|+-XayB17cO^d*GA*(K#n zGs{;&J__S@pgvmXB4mA~mAu;WkD7bL7Eb;BlilNk7CC?X?4&Q!#PIN1Zj3Ho%2>`L zGcbquY?h@Xl#15KZImeP0S%@4`_Rt>;M%#7O5M}I&JaZ1m`Xlg_F#e@cWM(3;ySfL zZkXCaDf3iKwe-IFo$Ku`lf8crLE3R5dpa~)s@Pj{vpE&h#lwxSyjp1;Ha6>)2hyMa z0#Hi>1QY-O00;n%ePS*oS?Fhdb^rh{fdBvr0001UX>4qHE_!KjT)ShGY{9lP+O}=m zwr%aUZQHhO+wSh&wr$(C_4ax9d*gfO)~GRRW&X%jSt}}L%$PG3q=7+D0000W03N*! z>8OP@h^qdLc!2-_ApdLg>O7o~liXooCiZ5CEV=otqD@+{*DlDVu~cHGG6>U!_;GzNTz^mqaP-yKEz7}CLYHDHPS z8)*Ri-yL!OXGcw{6jHQf4NKHx)5pgL$5gV);dC@g5-Jq3Cy6J=iK_MzF`|ensj8qr z!S1Dwrn-)D7E+agO1h?wt-7H|^b*AM=m7usR`-;KblvlGz1ScC0HqKB0AT-S4IIs! z=!{%cZ0t7K5PoESA}^s0rCX89J}K%2G`V8{2cdB6wh=(mi4qecZ$+ zT$^V6C3o(1^E!)m#+wv`AbROcdxe|kO(IYjZRHF+pz^L-*)q@M-9f2!E-Z~=LOmSq zE{j`S3b4x@$c{S)ijUbA4{S;wPn;iBCoWCCFl|*Q*AJkBD{69+Jhz{MBxVk0(VfzV z9xs=bj9a%vlze+S)FZoORwPw-bK`DfHO|Q@>~016ca@%UJ%#6)o3G3*EG*0^&F7n! zntA3LhfQeoh&Z*X*Ourg=M$Mr@|-o7g$-zOLJLJ|yGY|;p6HrLV zB?uBRo*h4igQym$J_5)>q&#Yf`HV1dVUS}g&EJv6ZbqH{s>{#?JloCQCSSyODpl8( zLO&Jopu^Ui0+U1ioO3_*aL)mCe0j2F$rIwhEI?IAUVT;81|Hed56Rpv=j>8IEJBen zGVo#u@DPGVC%l1R=^?}sJ2iN#%`Kz(n;s25Hn!z{w>d*P}nU2a`GU8R0 zJILv0&n5y6eS6p$E~6X-czbSsgu5*xnu}60Q=ZP9jK4#kQKLB`rafbS9PMj5ts#g> zIU{8547~}p6IU+(6I4i@_s|sh#8|8(W7wCBnVs}2CSbYk~lJyNvV^S)@0k>m)~k{fZcxe zV}#QsgKjZKZo~Ji5}`|Rarnsa{W#P!%vk5LzN%{l%Q_=~wIiU0(q(ZE(@{&0#ZA@n|Xeml}`SjX64apch|r0pR$(C=Mgm!?FTa@h?9X?tNPf zoc3qafk{_zEm#f&UJ*V6Kf#VH5Gw~Po$0yg*B#U7`T=A9Na1gRmnC@oCy6sYbVC?# z-Sr{Dlp;Oi=<5O?n=&JYv&KgAE{dN;*6X$?MzHCf^xJvd^3#cD#}^hox!{u&a~%q% z&vY%7$y*AG3U~_F>A~SRJ0t3D{1zVNO;*mT^S7lKG2Z0dUr8?+JZJu?3OCHs*xi7R zu(C=V4vUH;PpxNQeu4IyKd^oWD?zV>$)byFbDHW}5u)dpm>Z@AUsoAJ1bY5ShRL0L|e4Lm!6Lc2@tP4@IX<6;WA zY#Tc&A9Q)gi>ld&@tF?32_&7*14$H8muZ`GJA479)hL);W7G5ar9CBPHbZh;itsn8iNzP7Xi*Ft$ay&>#0jEQkL}(QwJa}*r2`MjcZ^eu zWIS>@4SU3q5ss7Dn$9Fd`6aaOxg}-Z4(wJ2618-A?Zl|dIFEk@z2VQQM838lq0|Sn zrIni$kt0drC&ja+p9ud%7^Ln%vE5YYnsH#QGJg~l%@90nxP)c;T6E3Hl^fKR+>8lZ zTd$mz=b>2t-*>+(MtgJGO}R8Scl%TBmg9Oor+tJE7F-p*z)5`aR+Vff)(S#Nv%O=% zJ!r;I3XKu-$;iM!uhY$%MB{!vj$hggakHlCC||5IYf}Thpwj8wR*grwxq=#$Hk16H z8un7Z4w|u-(kc?RT{vWJ#dNL?p0D}sxg#i>=xHa28-kg6 zdHUmBUIz=94kmBqZq(-`*h)wcpshpLehNC!ue)qZXL0pK^ZoE_ndINB5azdl^S*T> z|6;@fcD!_m#W#bVBN%`gSqAi3C|ZRp%%D7o7zQ={d-3NQiPg38$#WRVFVi z^?9j;kzjMIEP>Aw>&geiTq9q4=U`XJitxg}j!-os+jW4JD5!GLVRPKjDjiQ93-E&H zTUvEffUGf#H0Zu#dT*e*Z}o@2|10>9QEjRb{TosLADv<7Xk}q*J^^3gADl|19)(qx%f~-!=OGw~&j4wX=mS zozeffprC~Eax`&vakQmipyc*}`tPr?Ke!w-`%ix$V*mhv{+l(jF{U$$QP;9N7(?=9 z>n$`>1>zP)dU5HR4!6(9XG{le%r;$MuldeF*OV1lA*xMr*Q8Ba3$Lm(Bz?$rP_f zKzfZCp;ts2v9mJu(QcA;X!|r*h&;rDh*{sdO={rRnyI0X+?CpN0KJCyk`vITD8!y^(0w~ z9hdgcWygAD51!zsmU;ao&`9Et!q8}9&=DVBQJRcr`!Rd#m3&n5Lbi)yi^vXT&84G- z*4+*zZLc1)`C6=Z$KgWXDpy&crH*29ZxR3b+I;X}JL*wCwn1k}9gPl5T|`3DDIDW0 zO7M+R+Sn)Jq~3iPqHBNi!-k!`eeH?@aq_9gZE-p#?8?GxmGoU6zYiBlb`9spPsrxC zPZ-@_lE`I!LKChcNiH|<8dd@Yo*xn&kGXfTP+Bl--Dg3B_M0YF==Z4?JA4cWIT-xT z{8hKkOA&YXuV13KNWAS6_*qK69a>KI(qWKmh&t@)j%bU8Kx^ukv{mVN6cMo*AV5ca zMM#2NVB!pW-W8NNUrLJDC+XS9_9VWgjzhHwEIV%fE8e+E(^iH@22Os^82D#{yb5%VE~ zhBIxE%tH%9XpU2V68~(^iP;^MghlpQTF&pALjC%uWhTBU@Yv7qd)e37CgCu^u1Y9oYm8r(DTXT3K7^doUR)b^7K!clo8RnwZd2dQ>2)@0 zC+q9f(@*AF_OZ4$ogcjiU8QNj%X(G`(xB|jTI~Vj4UwfiU>i=_1Uv07fOpc^M8LL) zb?Ep=t-qznlS;@7q-ZPlM3j0UgmZdps)~uvDYQ{u zmdN1tUA%8S;NY6}4uvU|S`qDZDPfrPQhQ>QsE4^RJaQrWoX%gpN#(mq)87VfDRl%u zl@VqQ3;y5%mXRplZQBP3M_QVIdD!t$o|A|gm-oq9T)a~SdYMoMg+LL(NR7UjbbT#$ zlTLu??Ws{IBo=3IWx&k!_h(ED%jj@79{Gm}m=x^DHgi+%%EZS9#yWhC+lJH_M8|S9 z@VpQ%ETO+)MOIxjV7i-p3NY&hC?;d*eN8cmN}=9l*-?d9Jv4uU=UW`e*Konpxnh;z zwUi+DVppgCyoTYE+8oXLfr0mUr!|vM_#z7#v${p2=VqLUcL10##bI7!C;d z>O{apiI413 zpZxeaf`K>a2n!-|8UL0|7BN8?;(MU zqodgu`9Zf=hq4CpmD4h?YJU#?hgI57d5~Qa<=Q02K0AZ~kERMX`jvafb3S zhth+=*+2NF8|&I1{7m@03Wmu2<7X)4cEJut*sB`Kc%}+T;=@RM=5U#SjDb{pUv8|Z zJ5&w=EjB$nLP+=XCly)j+7T2CN|8qk(^h)$4)-)ZK+oq2>Cj8$rQdRa?KbrwpJHB7 zuz9F6R~I2ivBTkVQJQS`Gp@TG^&ri&qae)Xq1DZguNda5=ZZ`_Fq=YcT#~N+il}@2 zs@kQs{mbke(i!O3Z4%}Qc$v6%hW^*d|(Ors1M5R|amhLWO$Yms1s*Z@s=I!+GBS=|2{ZWoL7+9Eh zJ`ncrK>FWV<<_B)aAnGp{+|Pn0Q?3_RIlWkf@Z@_v~`;{4m9(b#`+r7Vt8fkdKhoH zuP4Y?`n6_KX{4*+SO1Q7L^sX_7KTRS9NYZVkIn)|N51Tcn#5zm5rWovMjl{>{KrvaJ!=!AW>F`4Y4e*A6Kn=BQgxAvA-V|y4e@as zx50=;j4{+whe(jS(a-HJ;Bsf&*N#KVQ|QjnFDVoAS--T}9?~mbBZKjkdYV7}3i`K- z8dq1tk52{c0#85i|E+l7Wb0RO{@GPd|I(&^ZvZ1_4|@|jqnu<5wM7MlP=5Y*R7C9t zSEE0OtQOG93#=7|;j480%0^mAfkX#(uc1pyB#a?WT#H#JIc_&wN9To!8cIu~n#&Kl z7u>Cv6IFZQ%r$I_m3%x8V6OHxlUkJ~oiAgUaMsJ_ZlStfJWn63_^QSzCJp>&9pb!M zA-O(hWjUat=Ug`M^SF7@S6e>;o>ZF&)21dz#z!VJlj;c#R7SERTnkW&l{O_~V&2Jp zg@=dHn1695c?vK0;qO0BOO!}yWaUBermL0{N+I2h#r=k8(bSLF-2P5>+ozd!+tVQp zi&-_6W47Cus9Y>weDdf=gcZAsWXh;lv$Ile(rP&HHXV&MO+i&vH~hGDtnu=lK+3Q0 zVP^514x4l{NTX)N)Mu@=mYUGd&rvEA520;F*tk+WM(V&&DOZqQT(X!O8qOcE+95rA zbsgh=cAfgehf{kNWQqMB;Wt@Kk%^Ohx)})C$WW0|?GI#rxS$mfccDV`To$a)i+$;_q6`?&VHXwWs1jG(V6;3+H~W1=DOX`(ewcOC zKrO5A8~%R-h+#~|pzI%j9w7ez05VTeQM4-*K=9S|8`jNa*$7je?$-GL2wy=#Sto5j zT3~_JNeK=Fw@M=WdfU{=hg&%61Bcz6VSk*yVs~fu{ENNMjbgph>)>!CNtA~oaMR!y zH+_{|rp=r60P!dHZjn)%(^WnFSjO06Dk}1x0c%`ay`Ev;y)@Tu=Z!D5;VA`#EOQ26 zZv#d46xQE3*sS1O9-%?qE0GB_yjw>~4*Q-IlBknbrCJrC0mTMtX?pWQX4kSxYfU;| z4hXD309WZkRqY}*YdMAMp*i4!#Hzc#b{Ua3TyvXm(gCpyoRX2NvCE%Hufm|P0dMID zsItMOFCWN+6@Y6upfaZ62F%}b#)$U@?My8nUSRQ#x&yqAJcw$pg);gnhVISU4_VT+ zWBM3Oib=apD}2os-Ps&n%O{AlQy`#|mbOJSU-jTjRcr5n8ZS`GtaKDVT{d;Hz~n>1 z3tC_n#lkIMCLE32Z{o7_Iw#d;(8_)_3yY?uzc0ZIv8Dvn7N`wcYW~({;NNcd6fSMJX~NnLev{acFvuq z*Uqg!bt7qXl#-1tiqsZLgud-LREOlj`gaEOa(MYVd6`d#>1#UJvdGNEgj<~#v#+Ji zx9mg98!KMWW+p@{dk}ETlC|~;eIDUkL>5o?LtD?&Da!7i5bbxI_4mRU)cI;r7#@AY%zeYYlNe9|rWkup7)J#|-H9#*ZU-B~E1Q@N*wEE1_U#14DF z2XqID+4%X`!lM^`qpyvCBV)1EGf-Ca58(gB^20wYZv}kP@%{tx7UKVSNX90nPXC~+ zW)-*j7xi1_7s?PA#WnM4qp2yY*j9lt*BGS6BB! z&~g#&3|;H=j_>_%nm6O;`7undh+Duf>Lj?P3f4EvB2B4~eZYCUG7@^=>RUp1VjB{> zh4o`URn1v!!WSb(2m^tgg8{gZR&0GlSSC-Z6?tUKm)D0LdeX8^!>!FLRdTdJm z6046-xM6%_Fg}U7$2r2zkAG@a$so=bfQU9(7c&!`OAGT2?uBJ9qi1Rd)a&P)YE@50 zjCP@kVzq>(Y$;n$+@TGVM(dkpqvh-U%jL@iq#kqU-3a_$i8N_~ zoBacWrSHKJP%fVi`CH7S_kHu!X2c_d#2t6qJBCfS))fg@E58?aSEfieqzhKk-y&Iz ztDAdEB+rA}Hbz}p!(UH`B9J<=d2l!GYXhX7Sfe1dq_-q>Zrnrh%=S&Mds@wI=EWVU z%)>xv?Z#3Sj2AXLRPUcMbkj{6)*dT451vdUM0{u_=3d_^o5GO9tV5 z<uVxEaB0zt??5XB*f$hI(ZR2KpwTX*0HJ#B-rCB>A5 zmx82m&)t@!GZ5KiDgG2z`-wx|ASvJ%Gt4FgTDU&3$Xw8s6uO5CL$J3UY> zGd;G$88GH~Wtq#N`N^QysYMOr|FGt{=@rSTI!I%>!EapZJ^kiA^`a6gDHZhHZd`ebUV@>Uh?Z24k%rO2 zkK(z6nD7RzgiGNfc!!yqrQj^BKv)3h)E;nz6#Y>Yb)xZ*Rnf>AVW?zDKF*PvX=*K% zk%ZYSG#=H}QAji@w6Djmg>95Ap;Cbko5u)JchohR8L)UWXXiy64UBr8in4{_GlefU z)~QuWxH`hI2d-r9L^VIpi|E918WUl;i}lZYTB=A#~JLNhXpsPD#fNofDLehES@*86o*Bl1pl8S^%B;% zdC1;m<=4hK?SE`v9#&{-D{Q{=SjUgTnIboR6vAD)U--DF;5o5Hr+j*R=$Sqs&cUSv zR zSlPQe9S4tZ`f+P#q1BflAG5ciwBanDVM1gd;YC1G_pxAbX+)P?H zI|^$D=LNg%r3ZW1vnVj;G5z&CB6(8y#n$uLA5xr{PRV|^28}O!A;%#1@%$o|7De0!Jp;cxB zIH8lo!LChF2JWEBTQ@3R@IpK)2Ww@EC5R3lU3RdP_YnC=W;6&&yj&^=7Fd!gB^fI> z9?W&j#x3~RYU`PPK`=4+22_o=}3GP;&1jq8=3lJ;(}Dge0uwEd<2;^eX-2 zjFi0;4J5r3%qwGIme`}Ju( zjHboM+I`&abi2*`EulM>(%}QY#1FocMV1bp z)l7ckrE)~78Z3A1naB4F9H34}T|jAJFAC*F28~!x=RBc^?#`Xsa5M|&uQ8kN)sz11 zcxHMUH70B20I^MrbNK{Z5WXUS65&|`^7}j{=!I@CNz%3cz6@@P@8IJsWbKH-td_c) zl+rs3uy4)|?Mi(T(x_!yL8t&3HyeO(g@?N;3uJLbzLfdrQQJ?Z+Z9&__<4&>t9oYs z?8WcH3$v>Sz^U3&dk+K4LiAKxH)VPKM+xC}?jBWbO_u)mrQ*IjQjPxpBW; ziLPztAm6ks`u9`>{16{suQ65Vy@}H;_vFM*SOId-GPl;S8#Aq{j}SVK=|?aR+Fhf`6A#^(vgSS z7Ll|^l13rUPwT9zv~02l*k2p7lJhD5{hYqq7%8Sjif}v0dTle(<>uW5%=1YX@e9(e zBI!qlJkd#a+2`6kttfnCt<*0-YSA*Q2yAela#S>a7qhUMcgkMPQYQN>F{~-^T-bKG zB=9Kfz0kdPDO2#??-Kh4>y9p5=lMVf^Xme*5JCZSBhj&SL^>!t9i$q^6D{ob*&u;Z zy06wRQ3~O-X0E=3*>t#k%sD8BW)f{ZI-EKXn=?UmPFdrInY%_C!{WN)iXDyK4|oj&_pWV5p|mI1r|Ak( zD&QuVNA1kqmPKbCVNq=++?wFY7ejy7MLW_N53Fb&>&5C-i@JnwGgk;dKwLDLr$uRB zE72&BJDK0+(e69o%ND4O^vUh;v4dzsJYY%7H2Tojc1g>#u*au`l>^UXusVBJFfP{< zYEbouv|dQDKo*YCrfv@@qX{!pfnWxdm2$=15k(FI1Xvcg0my;q#@p~K#Vz;#8#hAO z677xh2htq|Xyy~nD492+{L!8jb6bM#o`*+S0+b0Ywg!J@ zv)lD}G#w1Ev=1Wq{vcs+U>qU}YxF)DC?TR2*1ba>sX9j{9afE-pEm`IBTNhcYK>hT zB%c^0U4+%{S(B|H2%Ssr(A~OJ4B6S`bVz2QGk=4TSF6D)SVza(cP911_=mH@r}vJd zEKHHbiYUUDXR`vu=b85wXghsK!SD39tHj3Zw|bYoq7ZFb3S69--b3cm zb`HalcZi;x3OnSyEN>H2nTJGLPD1G^jC8micD!^yx_}5mA4Ois(I_L4x`AcbWp7BK z6*#C3&&BVqmF64tHYO3nm{R55JIPepj;FIkL*Y=n*8`kk)ppbKsl->5JTATzl1VyB zwnNQyz%}#C(|{P&IPbPgd89?sfw|_OC9VMgjfTpKwrUDpsJTA;lr{Y(K!r{m1c-- z`67MDaz^BY?>i~*Mz^aA_>>UW4mSI%8Z+5-C4*OG0}F}$ol6U?cVRWPe0boZv`4IO z_lIheBV{@k!#sZMA2?|@{nPHPe(t7eNmI6t)Z_rk5XXj9<&8VRy``#g(tSww*iv01 zn}V&aQn3Q-9|T(48ymz? z;iYQCmSUsZ`TGzA9l5?#J zu{Ze^wtnAEnEl&}ZM96eiPh2b3O?ubwGlDKzWv5a0)bintbxf3EQilgN<;HXzU=4| z_@OBWZzopUuP+48Im8c`Ub|RdM;I;v!>`BE6RTl^rSm3(puy0#4;T)TjHQsZ4qf~2 zS)y$D!F6FCY|Ll>BDH4AojO3oiHGrT)=nQEG>~OpKHsVot^?ZVK@g5A;5RaSWFRp{ zgr(*f36U}O8G4|lQV6j_f;r&NNCv>XVbuul<4R|X$R)Gf?wb^#-jBDQq@kxcyh@+p zOMLC)i)ISvC;tB?V-udbW6ysAK^F9X1cIr7i?#DVF8-rqx50qo)9N>@LR|nND6JP( z9RX!d47e`Tp_1t?5d>J35oEonveB{IV>L=>TOtaz@0;s1+d_Ztk|%_Zr#eo223$wg zTy5k7x{kWFLQdM=V#f%=S@(9YAPpCFP@x)9k+RoO@wfCzX{?dUhO>R`A*Y8+TS02o zBenVlg0Ye#^?4S5a@;6aw#RzpiA@$g#!u}Un4byg1iz75E+s&iuq`FtOW}DOVw@F_ z!B|mJ#pN1-n&pzZnJ<%A>oVhid_B8qE zwJF8P;juWE*xNw}m6!#_j>6(VyFyd6ab>jds1-beJb4PurfS?Uk+xG8P3P4Y6$pI2 zjkmSsNKv6Pmov4Gz%pb|7yAuHwfLDPOuk<3<}Qx9k+YEv=ZC?(^fK7RB?terSFv&$ z?VBsIhQW}2KD>vIq;@kG+ls7;2U><&LcgP6ZbY|7d*oJR1sFlqIGbZ(N}4tuXKSc? zUUq72OnTt~C6*MfMWzf^zVI(6CFVKUD6wCkh2V@$`qon>UA(E&-Ia*{TH<-@PPmd< z00p5x^OqnSnmmJ_Hsi}TpT?8`OjxqaAArG)kO){YK>SI#dEA^H3-45j!-Eh@lIVymo6`@fYn#X0Id(k8%!pE_e4BT!Su9E|w}Ebrk!io-jY5RShU`vup*5 zmmToO0co@KRVhJpFREZfV1Yg;kKXRI;ru&hI$^^5&OWnSW}GeAiTLHNI$LA?QX9}_ z8s`VcDi|a8rzPdqO#5|RM|GoPFk%gEe+jG{NA+!{W!==iHx?*;ivD+l#GpY^&41dP z#Q$OQpM(Xlu%k2bQP%m_8;Rmm>N{)$jZ%C~;)?g65J#E0AqN7Hx({!?Ru8U0WJAPM zk&v8bz3%%dA=Q}VTCQil6X!I`N%BnCaUnVvG|lq^I+dGJviaV3fs~qNUuH?0vAf%j zQmrvw*_{ZJXkF!Onu0dPf~%(ZBskVp4IR3J9-TG${kfXZ@enXJ4ZQIaAFpB~xV%E2 zLE|5lC|Fx*M(9@7=ucZ*kMkHPV$PgJFcjtR`8 z5!v_4en20|NZ*w69**myd!t+J;|fif47bm`Wn)_PruGIx%w+p-WuJUD~m@K=5y#l6b<#l7``#QIIl zD|iEHA`7u{;K*yv9n5an;|`(*ztkzuO8z_*u0M=`KE>c~3{n_!!DDvoX3R}1v8q20YVB7JFZ9`Jbw zY;$qOij>iA`EwR!r6E$(K-N|+i(_ZftU>b(x4g4lXJ~(XJTlL$$ao~ej%f(}yK3Id ztPyL{dVm2R)}7UZWh^v6?~U@qJoiN1CZMQJ`$yWiDWmj_Pl~v3&F%h4SgO?qZiGGN zr;zwQgJw&nNoq*cwj?V*0@g$WCXAh}ZBLqI*BscrxYBjOL7{bRdi{j{VDs37Z(j6% ze(Z=P&E;V039uSv6EJ6Qcxr7_)kZ7*K_$2xnsr{krNdobS|^JvLgK`dmJzPkFXVub zO2*E6RubKcba1B6+{g2N6!a1B8KVZryP!A3%Y%}{36eq0$aVK)Ue!o}|8c%%+!p@^ zK--LS5xs2)RSay{LD-yds#k~341Q12ErI67c0`EvTfA@aon5xvLfy310qAw~Q+}Pj zxi0VL>hk&%)ini&Zz^sjBMUX`(RYgjkVVDAoMabXa`Abgq%sSQ(Vd;bp$C${{4Bf! z6KFOt=+^xYOs0uwETlJ3{MGmg$C}g_z#i@&lb%_Y8OQ+1jrWaP?qHmS2yh#t{XrC4 zhCe(!1~1^YvBZ6>U^d(Jqaz5;Kt+!vPd^nQCh6!wr8Saz!K8P3#TJgfjKk-lKj8nJ z^_IC((v<)L09XV6Pu6Q=U_@tbqNHQB`7f~a{GbLlZqQjJIm3s5u_0;Mir|hXT$h9} zofJ!y?l@+RmacnF?67gQ+6 zor)1*k{j0%w{w#xtI?D!$GfY{e#7RJwydRyfBBBIyng`(CJt7{#Lj>VCA}2z0#L1(P{U z9!Mx}R2edjxu&mj1Gz>FI!7EleF}A`_vQ&E#xtC5)Cat7x@q;A(*H%*vmUbBAyGF&R-EeD^U8r&m*Z zp=b0NL5|WqF5GqD#53YRO+Xzovd5=F7e=y&9B>D{kq=(z14qA4yypRZ#mNvD3JmhP zKIl8XnxW>i^SwtGfLH`)>{wMN->r{8tw^g#RCj@b5V~{-fa(wcof6 zE~H=1cWTqkvP6K*68R22wo|ohx;atV0C44Qw<_N8AuuAL>@<#Muhs9}StD*jjh7r} z2t=NrDfb>vGP~`nT447^_hZwwiPXx!#zwOwR z{)hSWRFFBRa2-0^pO0$ap#in*iZ7h*MJC-$tZ8qxxO-Xy%XvZ z4XM&3h0W-xSRvbSfjT?0ra6Zd&Sh#8yQcJ$&1!gYS++ieEA~N-8B1F+;K>?d& zj6xPB-`5yuD^Ni%Yy-%&#G+hVR7@V3{Y0*~<{JHFzFgapIT=GC^pqv0wyoj(F+_yW# zLf|5rFsr-5USt>^q~*sq1YV+Lk+oNODXN(n`W(%E;&DTic`)r}07VBd_f3#;;Y8-4 zQL@0_@MFw_#)vf%=S`t%rw^&?_3z`cbtp=KwB%Auc>{I1;Sye-{5#wl(yAG)zu@!AQs&38&qvJs>Xw+?|o-j%)uGkGAigP!5S1> z(+E@Fge?DGaM;0Q&C#^hC#=@srga>dVM43dwabhqK>oVt+^P4&mv z)$QI{E!K5SOYv+havYC_E4M^X#6Q|~l#}Li@Gr?+9+E+d2@7J{7K%fgOVXb)2pMPD zWm>pfp}Fc%!<~VXvW+gYDOOg-ZyUq*6Cj3n=9LoO2ZDc(mSawzSRVrtu|HhcG)`fSFAC zK)!%AYBbWAQA;lQ(1c~;y5&xhObG-^@kGE40YVGraS+^1XSQl{hk2w3-1DrNthNA* zVCFW1^WXOS9N63Y48+}TSuOYgYL2VeOKSZSfvfEPrli1^Af5XvolqSz=){~BZXqlHF>O?5d%7d=%F;m-b@^Jxj2 z+uOWrIuyCg=N(+@-(!YDzG#*?5yjZo{07QnGdd_8`IJD|6uY)lsw>NPZlaCPq_#aMl;hM zEQpdwxJMDmX9A(gLBEyx&dI-6F7Ivl1erR z8;9zsc--U*-nX*W-PK&|hOyu7Cs=C0TJz%RO3%>(A>+X_pgPlZ*<<33T!wRV;zvXN z>-_VwueQosfm`NN^4H2#y9I!7R<}(~vZo?ZdyrVMG!Y|%zH&R5KyJRPs@4ae(JnxV z;*Tg;L$E9zTnE9Sb5)T=C*}QARiKYugK4jOUR9$tOj?>IG64u!rfG*j;Dx?&eoeWN z7k zEOGB)Qe!A%MWxVi;)XFT(yC8utQ==z#=^F4dolq($|F zL0N`wkF7P`Z5)4wAuXmsXVnv*|9&FG8^K#X6O_iP%unnJkW-Z0j0w?Fvf(SzZ94IW zMNK29SV%<8Of7eH#W6ObpbNF_4=|ZkmUleGtehqMir*GG}3iapPjF@PdwpvOrv(*Z1$@oveUSt7Vg&=|? zR%M0rIbun)rn5QDYH>0!48R|n%mti3Ft?+37G>0dDQoGxM#REe>i^k{ds|cvfGqa@ zfGh1Yp%t=YoyJ0>a|@X2d*!B)v-u1yJ$QbwZZjQYwRNu`KHrdqrQ6u*ihvIwVf%Ba zK)LT#l4P7*Y&6JJ9&TiKOW|S#f#)!&O;Kx=Rf#Mf9ziU9y#?HQT?}p($2~8<%>J$~ zHqfU0)2SFWZcheWg{m)CbS5N=J7TLksGU^nI#>aVhH?UOCPlUj z6gmFGVmq}NC0pXumy8H#VD`G8l(h+c6J|sFc*-K z&0tf+TjSmV7^xj?-50WF>*l|JV}Yaj1AXTuP4j*$K?`fZ`cNlnntsIqXUj*Oz}b8S z1v}P0=H>aX&ubt1;?iHx#K`UMSsN`q_dXWy7}@&L$(3dB=up`_u*b*>4oU?@cqU5o zsEeD0XHQi0@62Jp^G!iFQm&VEnovh^$KdgroOizz6u+8sT{(-O6_sScy6NR?+uYU~ znw*)~kx5rc?w>7^!zN_T)gWQ59Co)_fI2mYSyA8F;1Bax8pnQL#SWB2b|F8d9D6-m zZC%)znt!pPq8}jX%p{OQle_E~K)cH1=S;bknHPzLbff+6jV!cjlnB1-MU&{@4!VVc2sE`~nXvI0hUd=c zIGtl1!Q1>jS>X+&Ja~hK$MYw?x#Ok<<7+lxa#x+|l>|rx@fe;g|B2fCd^E@F)SMr~ zjU&sv@tl{>gU;&jAU{V%!oAkvTMD#6l|l6bx|S{;8_6a@)|1K!Ge;B>xHtt9lKbQanJv7KS-&kLg~yqO!a8OS3Q;x=Zcweb80g85j9W!-xbCla zO2u>LiSRckhhJ=Xf61^FU`+kQr-#3tGl?nDs#@X^kD1u=L^27AP5OUVt&LJjlX$#o zt2c*jGOo_B-M*2d=+aN9JbiKj+p?Ej$6{g|WUzY_HO1bt3aY@ue%j8yZhRd*UXLVk z$7_jz%hB%PM7blThbX(Ycy{6*wW`ASNw0iWL3%OiopDv70Hd4EUHCru{0l&T;r}}& z9kzprqWzbW@&Nr$>B+{x%EZ*d+QcQE*LIKrCdBL#1&0YWzMFem0mVEG4bu@wBh{$j zgHfbi(pFE&anAHi5;|$b3)V99hkkJD# zZ$l!um-t5y%uGlIZvkDF2d2tpJ(O)=k0`=lW7};bjzq@NC8JU;I%Sx&v>|^yl$lk~ zLs+zg*>-5z98Bh;HB*hOB)xp&FCa8-O)ZxwSZx&4;rD^J)?2c;BRZ@4E=%$TSk8uq zb;bw3Qp~Hsav6_=b*~*(jiA_1^2hwKRbcxbti|Rk9NFbm0MQlYQ5vDcytcR{a0czmZ5yW<6 zMbYbD7ZzO5nxp^qlOpMGFtq)%=7RpeFluM~uMe_YRo3p14VmvxZ(yIUVS##^z`d@c z0nWs8yC9q|-VD!UKVb#@JWH&(OzY(l zeI@pe3z}>Z#fQRu2Ws{XFKU!`(-_{OwVbW?8V4^&H(-m8v zn?=XNU(`_Rv_}Ba%YmYfq^WpoMy-&UduzT~G>@Bhxk&WWwvBEtpdV&guyx(D7ty;& z>jiI;6m*To9{7sc_wTg2fC;j7nwg=!r_oZ3W#nC6)Y!=Cy_Y|NEe#Q;!_|K`>FmZ? zO4k}Dq!ujdmX-6KP@?(R=9F%qw|ttEsFh!}w_S1GOd2)UN)UIIC+^`N{WeGI?M-72 zgj7lB8iyscEA3+SO4lhYDPLoMlYQYVe4MR+FcKqsIoPze!kz*s#qCTrB-&bxl1wD< zu*LcKv`N^H&=zvoVs(#2C744rrWzH|Qm$}#<<*L4NK6w#i}h>Ip06Ica`YM-O2lh8 zEb<@AcvxPntN0wN&R(4z-)*{iVis!a|7FGWY z|L(R$sv*XlGt+C>ohMopRh*~f%gimitvutbXc>?&WEhpFF5!^UV$Vc}x|DLDb{%Ol zyL^O50SclXS6iD?hV0j!6mj2lo0sI<5lFbr{Jxxe0aA}{)kn|<$?_HUA9ZDePO9n~ z`n^+Ws8C{O<9Qb77~2#Z(q}Vid5pt=w9L0%lISe9g}*_Pa;L8cDYhZ@?~`;Y-6ZrW z5_bask@!nV+}SF2b`o_J3oC>}Qx*;qi?Z&rK@eb;aFxrAj}+#A1@cIEzo!+I7#zsL3d`J_s4O9j>ehMk^3NXJDDPo;>a?c*NUetc*!~q9%uyd)-`^^C zgU`Zi9y9YwuIz~E8@>f<-=upyvU}*=1qb(&^j~!4BzGBRZKj`=+-?DykXl5oXs<4q zhHr{q>i9PBJM@vXytf1z5`B(6$lOfK?;f`__=fp({fD_r`t&KaDSPwyY4Og|r%bh{ zwagKRB{J2@7kz3t?xWkDU#{<*$zS%oj#8(y{l=voJUr9(&44|rcaO? z|0aLBLE5|HTJ0_J8|%-P6ZN6f_Obie*P9>dJB(f;s$LJ9PS`V(Y9rjTZi=>^o+>sV zh_4nofrnlq9q`MK)|p!T?RM|0uQR_YO@Z-z+orp+C_^r`TeirLy1laNY_7V zvxoXW2Bwo4osmh(_J0zDzP#h!K>OEv6ANuK;m*=E08T|L!k;mk5`6Vn0cr9q3Q;JM zlnscF-Z=4u#QL7??;H0nZoF~yr1kaSY|*&OC**nXy)8?KM(DeLHsJD3Q zCg&!ykK)tb?g-lh9>T{qyB`9pcM;vB_gl3zyE;1h-thCz2-!4$C8Y$c=2EY@zsw_B z^Ga-Fk=7E_NYtCKzAL?JqUN=fhb=qYpOURd0(t%f&Ia?s65De?*Y z1*3G}Q=@jY|B8Ma6Wj{E6`-&x&0z}*mo?R}%(Q3>?kG^@fKQa= zeb2aeaM4a{e{KxjGZ@Zepqdq{859aV=DOMqVra>+LTb;|2*SgzO@Ixr0z2B!lmypT zU^U031E~bNcl|4Q%{sWTsgae#6B6wyUv@@urseXoqXLQuJ5}=nB`0t%JL00Md5S^B zDMl;`c3yNEiW6%nI*D0_CNNdJ6$QVSatbHSPxnJ;cC z-j~{y7P_*hp)HC4&Q$G{5n8E=?SywK393U5{FBH>cSu*7Bd`X65Ss95`2{Eb0OTYq@vI=;Z5pIS+=zEna%p&KhPM<4o6Z^42VYzwhAB5T=Qe0$60=?(@zY+OoP}w8 z4mf-b=GD-g`A?2jX>Sc#&O}NNvO{&x=9|1>=*eldX zQYMAVaNSQJB9zqZfM}W_V-wT<>}^1?uzR$Gw!eb#!ZsYpIu5~Dfl%kj-UF7|Hl`_< zmIj-|D6o8FD=*aN^c1v%z>jMF8_6+=E{7+#Wx1`>0(u~piu_aPy8XUJgRtB8wnB}w z8hG^KK(H6%XfHewg{PFri;omitLvxBuTJ6uivx`$*b0KI>dv_E<%v+}JGQOB)FlFK z)6@Ry#{;`?N1K36+;Mz6G3bS>)20L`0O{&{jzBkw5~)T<2joR}s7@9oz!o6}TLYs7 zVoW|_b;GVAJ;d#^UJn;Mo+c%?w`55)yQNlN;LbI#zh9SJuTVLqZpv4irk*zfEZoEu z4Ef5N7*~H?-a1W2GRiF6(?ZxPX}2D4VA=~or_kU%UL~AovKmsWM>c5Fmi9;kjR2<+ zPVw}98k5j#Uh&bVzw)5k~#wdgJzR5ilU4-K5aUc8?%C)xIauf-zu%ec{3~D61Q>?i9 z9Ks`~shiHTMIg@1;QWqqpJ>wqu2mj|r{+RxE3>9O-`km;W1QX= z2TidDP{I-`=%jX2b6_7@jG}CicEQysVUTIvZ>PD2&U~4~n>siDHHlNuy|bXW1rzlh zaWzLT=ljeqs3e9|ss6cMbk`nU|NgaG@cVCiJ1;>L;P_|g&;Osce_I2ae@CEV)b#8& zIgtEH`9SNSixaC^#=Ae%`zmr))N61#Zf;&G@<}JqX#Q|1xo*9DY{xN^n5>V}u?f&v zaxi~Q>&5y)+8+3iJUv=}kS}8^s+_<=$lsnF;C9!&NxH}NsgKL7jySuvw z3&EY>?(XjH?(XjHk9l+N4BW}fr+4_&XR&^#S9R^)-6j889@!!5V_Kkt&Cr4at{AhZ zxckL$zfwL7p25{?8c*E$1Qd7DIYNl*tJ=~HsM|AkYOkZX3rWQ7z^<33F#)7oBCz5V zLXksDOVJs-TCB4;`DHD%p?nuAg9Ep$A;hLr@f>R=oLOJssqF9Sz)lLh-&c1}BOBRpJ3DuEao>?R9wA zPMVU3lXA#0cv(Wnsu1_5$k5A?j0Ws~VkdOW%`TA3jiJrd*aIMqCb6MNQp*~zBp3f@dE2^DUH6sXxGeQ^{>Sx&I z@&KH#-9KoM!iBnv1cZBj z#LnK^zxooWP`_QsSDZ&VH1P z9pyLan(;y>h7O+KzDH&xm7={UQEBd?2xM?+0*B1ViPBT?sgrWY`0gZ$t?X~+n6Q}L zr`9=pmEw3m5 zpr(gW+)jBub)l9!&*u|=Dz!}!tgG|A?IU!)%T<>42)kULNT{7J-kezpLN*F_;iE8k zGlx|gW-Zjn5WWUW=!MgMLt!VjOFmm&3Heff?m_hM=UGUNz+AIH(8Lp;?;r}b4Fs=o zoQ)2?j{KMdQlHXZ9T#W`ybIDa2TMa4=3OBNkKDnSbij{8Mc)kPB<8wrCJ-*FO--<3 zK%+{$h-sw@+_a)uXcg9D^=3>Ef)8rJVtE_xQ&o_$BmBblmIOq<32 zn%4fMmiYabI5X{*lXx4f>~vl0CoMOfjI@E1FbgZN!$Vtp`%ejC6Z9c;H5@pL_SJw( zkM>_BeA1OG=4Q?|wJurJu9EGoYnb;y9=qo_0WmSd>~q4Rq~%TY*5e zF|DE01+Frd*EBLz|KP<32d-0N5X37e-^yVSGtxM}J~g4b&wg|dI2Ow@p%xfi@!aVg zqk~0mloJlg6l+|Kd)6x$jj&xMnY_}=MMZMrxoe$dW*W-;mEj*BU#WI2rrkRF-18t?~vuh%COfz(w=Tvln9lr&3<<^drUEgA)weENd zri--ro}Mangh=5F041;pW`c6nSSiM{8PDUACa5-z(p35V^^I2=*QtlPz@;(7SZtqH zb&-Gx6ih~7qCW`zru5YLesOPRWAWUXPdo-|Vf1 zdP8ji?KE(nYc@M%pw1VmQa&7)nU%t6*+jvC$%ON=khI~I&Pvxy4(;mu$BWH(eT05< zz?KL{PVTMG*}-_e0vrOgT~#j51>Q4JlExW0%m$2~_75A;6Hjbk9<)ILtTGlt$hm%2 zZg#=XCHkWI9!f^@;_D2weD^q?3Ta>W$nB2@dPqg{h|o`%YEIPwcv?+~1uUvpnOQ~Q zw=IakPxm$Yp=;^^U7Xc>$5d;wd@H>@G~e9I`ub0G#HUHE|7fBP+L+}re2t_r{MB4w zX>DZwT03Ya{h!)FwSrGz

NvV+SMW0Y4*nLCpSO5R0^eD*Ke!Yd`(N?8R;7TWS&$ zwx>(TNZro;eFV${(*3Cx>kAZ>g1~n<04CD7fow9H_%bdIks6Zs&ujK#{&}Gd&M$h8j9Ew+yn0n<^O)Sfplrd*8MvbC z>KTGVr6hcr0t7Be@(Oha1fs@QqK+Z7np4JxbOPn8AyA1f&`RC#V2cNwTv*M`>Xp zT&})+5W&E*FWy;(2jmYeo_dhPr2DIFP)vJ*aJt!c&=%4#MaZR^KwRdvQFs?JQ|9B< zhVch{&?G-6DNH^;w+|yKv8%lXHGxA6AZ=n_8=8V{lL#?^y#l^_+H`I8&j076n zFUKOMs(6kp5PV7_bhFA=TF?1$rwt*B|C1b35vS4sA+p+{;i>GzksclxaRG;jhI^mU z#}T)n4S?4abEa8Lvr15{i}m_sx)G&bQmGg7gkOJOM{&otEDoW-)eO2~MB?-x&d6qu z<=hSq0ATp(-wH@Jde-(vI*8waP zliM03e$%#OFE-%KHFxoN7;>TCVDYS${`s`+<`L>~cGJLVyJk;!4`JOG$lHRqdQTwA z)t;v~L)3F4;|9#!xH=^rh1tE=lq*BDpD4mtcJk1&sV84(u;{|IVRL77w|w(dU}O#I zL74HqCM;c^2i1h#EzyLSWFm0D!};mM3XYgLd+3ZEnfA-QK3lx1WAY=Og7w*vIO3s$ zR&p^U$UtQxvQr(mRmgy4genYmlXnM`?ya38Xp0%%kDLt1lNl_i&*cKv7gyVt_Yy3R zKc>;PzNvFfPBA9T2~+Eob3Md>E(Xe z))8>g(M01ItD);k!yS7fZsK0ea+!NCWbwDKh@x@PsXOvgA-(!_ zykw*KVt3!jzEw;wr*JCW9Hd;`UPTQ8IGG5Vlb{G5>ufDh(wQ4+khyay*~ZDB0UC&H z`fT~=PnbS;noxSu%`x3-i8 zNrP)A`dmSwoWTT>kqvh(M!@8uwFB;bXI65(V}u7(NEj}Fiw7M zqU(Oq4;Gk~E}W;0te?(o9R=9RC>gN{OcinzI>>-+5RXmOA|bRUVLK$;BB6AraO0rd za`sdw%r;Kr4^-eS;f-wUa`70FM6{usKIBO?esp9cY?Fx-38?4aMd(7S4ioJ*`vQQv z6|U1m`K8@j70!DRQ}M1Pfq=!!9W}u~f3U_Gw8ReFfy3-#Gv_2UvLdqVqKke+-WvV{ zr~$oyAZPa4-L%puEMML(69Q~H0c70EHhP*wuKKBEtd=Y`7@`o#m}+{9k_m0wxZLEv zsQS|p#H|fIa!`b*b(RMZ5SjrT2Shk=WR#6>L2q$D(5RW&;jD$>1o=E|-8|#*XIOs8 zDc5AKjIQmxJfzL*B99*kM%{9SWbpmWan$8RTi8E6*1vC0^C0*KWjWeD>Dk&`qZ#^o zj`2@?e~!&6p92jU6}4qJ$Pl6{i{FyCN3+JOD{uA6xvC#;*KC1g)c8pPqgd@Z!OyEa zYzRy0le?;=77vjQs3LEo7cnJH1MCx3W}p4DD&NpB9?bsh1lFsI$%J=d7vVrmBS*P@ zFlq`D3;|si(ZtvAw>~S)2TI(mtrY;{U#fnvc66!?Hb*AIJHF_GWKa#ZFRcv1kKG4} zR|>PA<0x>s%VCk5*h#6%r^~1hk*^Gx`o0y3M zCm4`}dzmisg{(`R1VNyE9_nyBD1ut5s6xQ#xE9-noLBm}(Gts=b-#D2%`nyiunJez zKj`EKLoQfv&y)tzh@7~{4;BgrzKS|#s;Gy1pAyG}J{>A0wLxR!V@^PA!L#}0NyHpS z9JKk0lSWm}EGbZWYb&0h+(Hxxv~BzLwx*O`T>PaGtvg0Mp*WN&>A9_>rMlW0h@P8t z+BIvRVdJC~$&btlV^taSWatdOu?DhGPdM51iOIb_YPjrxZFF_rhLq-JC$>>@YqEtf(>dh z6@wxb;ovyrRH>E>o#%RNwZu^BRews;YHo`QC=a88D;GK%-weD;Khz3GwTbL+>~}WB zn{>JKUq(KjMtv$A)=uRUXC6;!_J}9cDauK8kve=}2viTcR?r!OX|5O{k)bweaqU^B z)frqK6=zTVS`dCWcNQ=IbkMS zbjHVId}zOFf(1TX#3V&Jm#Lpg1B%lro<_{%wV$xvMuR^!r*=_)tr)!-ju5%;jncP> zHu$0#rx>eWmes7gONY@MlofX*5;dxHGOH`LsEQ(rriBGhQpll%Tn8blVKfu@q{^Q- zKZT?cId)CV%vfTtpI+=&ve-1;yl+?nW$W@yC+{RUa?{wwfTnAHQN!VWV0zTkxqNXU za23nFqc`1^N+ks)bpp_~sm7*eC_Zb@78ogwzltD(@vuT4wV_MvL21X=WN|iA0{aM! zY-oO+O{)9WCOW3VQ@hQPm4H5v+J}lkit7@ijVVZ};`6ZsUNoIX6pw*ARpro_cnXx+ z#+m#cK@JlC^6W3hoauPhWi)V>9#w^U;fS)AiI;zLES1Y=Er-4y<^11o{`H_|t8HyU zrSt!zpPHVUHHU#HT84~>u}G1c?`L2EOBG=rsmcdZsmwmPp)Rz|{o++5Gz2(=&NxFA zsMzxDb>MQD3u#ltDjpzicPV4=QS)H_RMpS_RQb;9r8baweN`$0{`dQ!jjh(}DZ9y@ zyuK;@s|_1D=b8_3H`HkS+BaJoZB+0m6~gqWc?u7VADXrzDaLgErMY55GTSZ?31Q`q zqs75tEiA>3#ddXo#T}rjJv}uVT2um$)wj7&_NV<)4$@$0>yU8F#~S=-Vbnb9N$B;U zi;l)b6gj^`+zww(H7rZcq@~3ngzidsi97}=CFIw@de0u)0rw_#KjIPs50Y;pWaL0Z z6|2yZQ;Z>{46g0-2fpF;vmn}<-LsUSj~v)MYc~*8ZBQR+Jjw|v(bT__L4|kAULkbu``Nkm_tktNZ@Z6{`Mn|MnNJOdj1SZu`r8 z9bVqB*sS4aE6<#m)^0aD$42wO?a+QLwwi19j#0?449=n1(ky17HF5OJ<3OjW4HT=Ga|}OUp4_ zo3JX%>^0Rah{_ps-%BKsnt+~#*2F+~KQn7B)DmKA&|;i5F*(UEc>VO{0SRr67kV+b z>+xz>+FimBGyQ^6CHw>ow_XD1SdgVba^@LVXkT8l)(oV%ko?&{tc15G7hOZWrP)x}dOMTXt2vbxu4bA}^0SLf-DkQmBf=WHJpOh8t5VXP$t*DF1 z@HWK3;3F2BjEVOFv|b`sLR^U}>;^pW1D}9DB$wP0bIw7h(B~7<<%0v)3+2@7k~FfA z5~GFND%WX2kcEvUW&}U+Ig9rph_%)x^0rr(V+DQVa)xfQZRQI!P#ifLJgGmrKgS%a zUzS3l(iEclF?HAnQBIV>sW1?-<}n|x2=!Z=qRfhy5BBujeEl|~a8sjT*>L}Sbs=$z zJk5Br*)sr|%v_o^tQ7SW!&lmYz7Rm!9@*cQ$32{iLw8*A3&I{aN$8YkkAM^wFd^o9 z@elgC42x(%$@%bDN<$|`r_YX{SS+$LnQ}C`TESqY`8>HlL(~$$)%7e}0n98V*^D($ zO1GtZFu=Fb4E5T^S%qh7l1iv}l6Z1Qz4%6e4G_s^FJ_3;bxRfMLS0yXAv*izqsvNJ z27t+U2~d{$iT(T1`z#Qk$p1#`A^ z!Yop`=$-QA9U>%>NIulAW(v|$Z)z9HW}(WyBD(}}dI*bept4l`DU-a&GN<%{w>AWc zelOk2BuaLm`u6lj(+VZ2-NFbNSCD0$3uTs3ZUtbjXko_y?EqKi0Nu8Caa38vDCka3 zXQESRvRp21Ik_Eguat~;>Yfh_WbcDxwti^nS6?^M`!o-OI6ZXa1tVOvn8LQHYa>bI zlA04RF%_bof*{Gtw%RfQdJI~gyC0X1{lO0;Ob$YoT@fk{!?f-!suoUUl#VYypeH#+ zsrg)SBA-B{le)8CK;GY1@7UX@#9w1$5q6ApUo+o>$4j7swS3-ay1DU18z~2OvLL!)F&w)(5ZD?gjSt8J=z)OT_3+GB zt6~GU@EWct@1qwc;J6v;O*#Xs-#l<>2;6nS3BWp&Jw)>q9X)q|xR{ zMiolx!ZFTuZEJe06N5I=9ROU;eOk3KpITV`qXYuj_6%EPxHFC%Nf4+mgqJ0%cgp`OgFLA)F#17m zk7!JboMAE~!_?M=!FOUrUqjq*s!$Y!z4P$Pt-W)+XbI=~3X1iJC#%5`k_bK=XZ>(S(=)^R+VR(wV0@5ul z5jn$lH6IT2!Q72Y=M#ku-Q9T|e&ig#Opw+b02+8j}|2CxAOA`iG@QiLhz!4ROj7TaEmIR+(JM%@pbikPJQ}EbzKIc zrHI_?k;Y%T-nK?&dKPxJ{~y(3(AM`3_HoeD|5rOkN^YZ5wO5aG5rGUwl?bbJuN@QEik|E)*mrxrnb$FkF}>4bn!5sYT_7musg4{XYxGd34q zI|m!)T#s0cq|9WTk?V_XHn+4Sdhl4!1uOS?`kFZg*Zm!XV%8M~8q2uw#iHrfXje!k zy4a<)j{D-m=F}_mBI<|l@!|{6V^TGvx-0CWM73wEDnSDwfcC{+ZtE3=+&{+8uvdL$ zy^uZabIpGoxqlwEs{f1jK^N75hL!9feD= z>8>9+VyexcABcDXZDn zP`3p{urJiYAxS?z0D%(v8mdTT96k!VabQQSD_nmYE*XA{|b6c3}S@mQdN=KTJMrHC}NX&5td*I^K@-R{;9w zV~KSyZr>_w&7=Y0C{>%!x@T;GyIs0hhen884AtoPw;d^3@ZX@;X0i9BV^@D1w-guf zJhS)8=a$xLVY2(4nBj>9H4Q_w?VFbeITw~CTVp%et*?&g$Yo~98BAWbad_)E=sD-m zkCig#u87mn4V019Vu+s+Xco7btP!FTY4Ae4I*_a`eQ$`YC+{6U+nmE3Znq(nC1VJSco`D2sqicF5J_pS@e!lMmN%PAg>RYjO6;>EYW3a|XDVO&WxsutB0eCN9$9&9IklC7_F;K~oBU3puVti-}n2yhr##~zgG!%%mn6=+A;yr89TvI6|kfC~Jx?5@X zFk`9?Hd{u`Hr@)gdjb1L`CKGEwIw6~KpO79_X$Tm9V(qBG!q+i*7J)~ipmDL>h4ua z#}e}bI&6(K02pK_&emAdI@KEOQO|WPeQ^YF)w#zTnFCtbQY;b$yJBGe0*!t1D&-;# z^cHN!QTTdnST5YM>~HDrfST73Vj5`|rUNn%EhAG%@e@AV2b5Wc{GZTB=r)2N_|8l+ z&LBlHbQ?04M?}yA6%JA;;Lb_`xpf$vCa}`h9FMnrCS*Z_yAMO>8eNW^q^jq_Y{`&v z({-< z$lRIQ`8Ikxej3%tfo9 z2WgFy|I!NfV2qZmSzu_^(*f8{2aN1GiFE_2JOR=I*-<@yYUWW`XS_t1BU{8nIxRRy zsWd(!S|rZ7iInQemLTzC1M-BlpQ*Jal@~9f$6!B}7lr|Z`*5=@p>J#J5bLy5l<&5d z^%U5j8bL&d0xussGI=C z)`kg4olHY9MfBp!*tB1};4!{}7BNPpZ2)HM9g?4Q1hUYz_DoWhok;N`ybfeO;3rA) zSg_RqmS46*j7NZe{F23ch8scI(BZk#Y*u%A;l>aL16Mj(d=_K_91V_$K!J>$eLux( zMqo{2+gKGbU&A8aD~y?m#xhrOes}e8OLfmvRklJ=hD5Wzd4+WW!>j_8URS!!BXszvUS7N`43jV5bK7mjB4aShI8unDQBi zS05_qblzOpBi7iJ16_$cW{%^`$CEkIii|r46)Am#aNwLYTKJ{Ma5(4bxM4hac8gd< zk6wPN!7nr(GU>QYq>%GSodf>!PGnziAcC-?19+dv$tu5ML~xHQhh=RN-cYDM z5OgUNH1VMjsg@$^+ifbXY%oZCuJ1kd_op#z=S}l{S|3D?0 z?t`pTv%x499#&q&KNi!G7sQRYh7d8dSGd^a-G@|Giscy`)HPW;SNO}>v%l+b7H@~l z(2!m_BFkPCfxSEfd+KFQ^1x%ar7SJGmMI|yUL;NzO+OByosK6}duOF`9B z#}%J#luq1gz7}jEY9Zh_BzL7;H#7;O`_&7jeLey20n7H9#rq*#7t^nQf#v+oH;74O zV;}wVWFBL|RSFxuRt|h~fa+`qsxRq4+A(tdsFB?5LOuc8fox>@s9Xf+NdmVO6sb#3 z225OfBH4L?Y zLZnfbD9oJMP(*DBt+#c;vC`Gqh3D74IUqjx+Myx%QEStI@~>bfW<^%z^J*qpw(i6P zPX%9`+mDKa@RDLenj;rT3g@_2Zf)9&sT(RBN?Lv%KPy6^bqHywi%LoIeqP``d;pj7 zpKo)BbW^VI!4J|>!3-C#*vqJZ!>WcIYio0$rzrFjM-E+qeZtuWC}@L9N={#Kos@+N z<;gkGShnZuOyX?Q5I#d5;~&Mj#573@gD@u?_Whl=rhlQgXLQ2o;;bV`e7@I&h&VHM7M6jR|g8qnfb05 zqKK@j4Bm{(o~F46zXol#$8%@!*1>IgH`5BjG>WgjRA2%JUr5JKkK2?p$s96wMO?3@ zRkW2mtt3qJlp(zPCRI6Y<7b{QR63E&AlY}-)t?w^<5eH34l4KX=Nb!Ss`{>G#kr;Y z+;DvH*qFd;n0W+LK*N1bp^q!mfQeLi0uL;m@|c72Z*EvCy(hWqvh6>8X8D%E*srYy z0=i1!B2Ml~Jm$xq8gx*?5cv@T39G9WU%5i}F5mir`V&WO{BRJSs2u5*cL7A8@H}a$ z2CYiU)Lau9+Kb>fV#8tUfQwq0TZda{?*%HK;^M?vK_%B1Yb3oS;*n15zCsOICnrMN zaD@)bryohFHanUb)*j)=KYo!fvI3iI+^?c85Zl@>e_nteAY9r!1_lex@cEMGC0sYg z#*#B!!!Bp4Q!6KKXLmVru!cE2#svmps|f8$CU@x{39UsYq5$VX_ARP8E-(cl);+}V z*oy!W=_!s>4#o~6BC-*x@Z7KL#4wB7$dv%vJGm$XM{y5z(#+022s)N0My6Bxqe3k_ zCwffwnZYc@Q=cH%_>iS5W8?lx^*j~NF3W^WWL@%W;D%%-l!n79$~PZm0+GbR1Dc5u zA1~IJ>~4DYVs)$ws>i0HXV9z^y;?rd&@CrHPQ*FIJhGE|S|Plbu5&NK3Y{nI7YuCqz?ruaHBnRo1MjE9==@=S@?(SCU7HI_OMp~r18v#kBL^{61ec$_C@w$8$ z>w!6Et@+L7zvDUVeOO0wYde{(G8wW=^XOC5z!wmIG3Cw{8EPO&D$acvqm7x=j;qD;r?z%kptxDlePgyq& z*W=yF`#p1f^bJDFv6T$3X`-=&WGrh1&WsuLpEVStS)uv*IABcgp6D<;aV#NlO1{1~ ziJ2dj-f^H>lf~E_*KTq3Q7tNUsW_z6bjfoK2_y~|naQM3OO%SIX%`cJFT#zf)r{e~ z*}}&j_$RHIAW?G=k;SWxl644H|Dm$(JshdgunBY_0%@HwqRhO7W4quuM!cQXyvhmc z=UIvZd5;Hw)Q?$`rKv$QDUzOAAgn(MN^^_GgD>Y$8POk$afnlAt*t9Wh(8K65sTcE zOcbaIfkY)QGLB+?QHvL2ud41ifN9&u8Bn1>WMZl@-=vB7xF_-<2{YfNif)W8Js}LE z)G{%M{P_fHL_dFHw;XB04WG;9QIUD4v_T&eHQeA=OB2OY0saS`ob?R+6jf!)1_5g5 zizqx?J9uhP!}978RAMzd&%(61_#~DxQGZgFGMa3kL{x$&|> z!cRa_y)HJWypVbq#}_RyHS!wgf}Ht~^tfb2$T)c2?cqI%yf=qIhZjAB*5{myJ-bp^ zqGIC8L`HfgR->Uq5%|0x?!(Mvznn`YfP^Y6J59FAOx%O(K4qLPJxL4WV;nCU(}yiq zcwMMK75r()-m8&w)_F=EaeJ4!aV_Sgib8=$*JBaJPX^{%ukr;7%=Hf#_*R6|lMRtr zEvoBtRBR9dNPi%w&8GT3cIMRFXV2XG*i&I!H{>l+H+#e5wVMaEG-^w4zqjm6w@5j7 z30^!n_X){qmT~}H3v>Lq?}9{6e1Sm(qGmx{fcHd{@rc@RR9a&t4t~XzyEXbwa%vE}eAnvj@U|g2Iwe@MYk4U&C zyzrjv)v`ip_n|MnM2T#CaR%JYO+p53OO&}u?ml=>wz1r`?BjpqLfNim%iO!PinD0< zx=v!Teon9DyYjBb{moi!p|lpYw>N=0PSTeYUvI*NS~}^MFCQPCz3l6#*{wzNE*-xh zREWCKTUZnUW0$Qj#VqwHHPi9NTs{swRMuC#99;5WLPKmuD0+3H^=SVkSbO0@Wc((c z!$V%`?YaE)S7o9S0>mG+M7vEDlUiRbfL-opAZ_z(w`!OY0fC#% z7LBnM?){6!!rE!lw=IH&*PG2^5w~X=4r;X}!&-{EZ;TO@=|3!`eD*3l*4lml(Fe8m zrjEmQ%G)yZ1X2raYaWG$+uqdOFaLH)c-1_-$~vq4qXk0YGcOT>rTrGvIbTvQ)z6C>>5Ye3Zo0lgON5@3X5Ya5^K4(Jk0BTho1qE<3jz@!fIx`A z^JN_z4J^S%L27e0W1`qzi!x^+PjTL*ANjvp&UMNS&Kb9mW#Sz^)X<|3Bj~#4JY@~L zvXrdzQqdPSy5ex~OMhB2&|~haD&Pog;!sX}9MNR6Q8)EX6zfrRhsQ7)3#x}x-W*M6 zv_2)XdKM>oH<~JoZPP2dcBeEMf_sJbs# zflw_jf({>~$25+}nHlG} z>n${vPek8;(pWD_TLNSi_^4?zN&Ic0+Lm2P&}nl=WQudYXWrWp(dzX{Qx!jmx@hj} zOy5hi=L96QGD?P*l3cN@Li$_7Cpxd_$aF=s5{w_MB`6_{sPlOfy@tB;lcF(6!jOA? z=TMI(c`zfG2HWYw*HUXjw8R%Wv%?G3IhB&h7fhl_JWtP#rqGJUC$o&|brq_jobEZt z!md0r`A(;eXO|BYu@a+%_4e`iQI;dk@Nfq-_U*gFZ*&xp$1a|m z9>0#-m>Lpk zn<#K{jglW?c74&7B4GItTR{44Z4D#IjNbo5X5FVuw{N zfwY^|f^bf!Yk?Y$5uI2-lE`hY-hDQnY z-Ow-Zu<(2k$vePw*-+fe<72-i({4R8b1p$xibYfNz@_^M%Uek=h@X((8`gBA#B=YS zV|_x9N~jxR$97_NVZJiMtP_)-?qseuAQ&RCidNj6feB4|p<9?}u9ixA-#>TILFc#| z{s9wwIYBQU7I(NaA8tXvvyg^ni7tD5+{`#s8sp{34V~Us1lVU?cv8|Q%WiPlwKI*1S%&Ab7MGtf>SR%vb{(H9+SFf z$plkD*bA?;^FFl>A#stPhsLw&S%k2-UkoX{tVflm_(+$Li+zYx->ZuXidi>g8YR3n zZH$~vKb}uoBAAOS3(MytGcN*HpGonNmVTWs8xwj>GkYETLVm{G|Kh$UWw(~BPq1w_`;Vs$Vjkn3b?4_uLodD15e0n(4s^?XK1DnsLldKAt$DqJ7@ciz`eGJxjt;)odP`k9@! z(5ef}(_;7{oxi^K&R2O7*pbl+olVEW@g&!(dvi?kx!Ow<0#^3M?;F;THu8ywhh&%)g_M=nlz-ItVpL&HFObbNIDHo$`1oz@NM3hAyl z`qccs835i$h690seG%l~W(_uj#KMiV3}oT8`3@hT`Ficke0<9pZ*k9>`8Te@&e_q?=Dl5`)uPGG!P5`dWv3 z51TX0$yd0gQ=qsREB6a`YivO$jTwn>jVm8~(j2aYyeU0<)sgWMeU)RqRcGLsh`jO` zyeoKv{S!z_Et;Ru@`i?s&k>fL@#&;l7#`7k?^fPZ-0tyOohP;>`1{z~NI(23LFegN zb7VZWMVpw=6G%Z6?>GdjE6n(##ss2QoEga;Ua?7^X%_Kyra5gAl`=&@a$cjRut4r- zNg4sFwW&e{Tzu#=^((e^We0M8(p`h;qL1>S$wd5A5K>+JVwNCwQj1f3=CBI0VeLvy zeY(zZi+vXfAJAPN^cKwyTLId80t*FLj^@@7sFNeuOm(ndevna7R{cqDpTgi|-;V<1H}tQ}T(u&=F5PO;XWV`f62C5ON7So_s?A;?_cfLpD@#GbRv8_#6L8`=qJV-m8bRUc?a z=;~uHIDni}eNlm%%)rAzL>ox~A(^UBkbXJo~{OmgWGCLB&g#DcZP?`g!l2 za={s&6<#8Hk(4Zt-C!k`UaVw7V9$b5dKhkKZ~3HvR;|M;Iv3#T?2S!Vn7{JcY6qYF z^efvI*3GUj4VlTt>i3~KP}>u00u~~%BPVjjR$Borex)>m)Fj;t>`DH8&z5YOH)O7K z7C(GPOR>ftQi8MVPoHzTtYOHie^jXJ|K4r<2#s=5m>-X0CQLxXkWNz=o>RRSmMe19 zwgENEt^hw;!@w>8#_55NXL2d*&|~%3B7An!61j&NifVzCvB-nQO3^UW5n-a!CR%Y! z!pX{2GZ(V{wj^9kCaOE)9#xMsMHOM(-olempNwTskjNcgVXC}+Pj5HQb53Px_MX1O ze?2bQn9xi$*dWn^wSS(Nxei*EtbJ~ZBbkq3!M!?7gR~*GMz#TiNh%=PE2$HK8$?vQ zeZe?*P3m>>LXFsU`3Z74B(BMm{Bg@1@`H@2r9zI!_~86fe@qnRDRT^&D3oFEIhyY> zF3Wi#X;en;qXv`)9A{F{@s7ypj-p3%$Tgj4s^M~R%Kmu!1yu;GCPkRRHbdJkw!4V5D1lG zFktJ0zRA`f5tRs!54Mcy85ylbsa`k=4JqtyyS(P&kx|?HghHnBJT%R6H>m%GQFych z;ZRAG@eb9lyo}h1r%7rpj$FelO?Km-6m-7~o2!-kGHFdn8UVw|j6q`PSii4Kh#x*x zkpS;^2EXXNHZA=osc}}Dj%<`RVrl~EA(Pw!J>1g?ma3lgF-aPz%zmyZF1u-Juq{%}w;z7x10+EIc7m0fz3L5R)c0xZ1ch6PDSWCQ?pkvP#=)J2HX13X|z0zL`Q-)6FOTY#R-c5!#b0 z9rowuB*k0~^?a>9q#0YHEL~048=09|J-0QQyyM^mQ$@xlnK~6&80f#6eh9B9h zzTzyiDK4A+oUPqTMU$+VtG$iGYzk5Onfa|GolWr6+!y=$w3ag3$SH?#Zv{=)8&3b3D`CgLl8`H985VQ0jv_?G#ms|yju|Cx;@r#HQCW;p<~0g<;fTfw_SC9_1-6pV zlau3<>vxYdUY)F_NsFVs6YX4;gF87v%s%-BvyGLnE6t~9jOH7wM?ZF4zY(-$Ar(_U zEP8r!jEr!+iimS1*HLY3zEV$>{pmV`!tdH?wFUV=ZYmhBormij)}o1(}BxF(!P*VNS%pR&7<|63)?G5 zak5e#MK!h@FNQ>LE-n`BbSiG;2f`p?^`UsknLeq zU-yLyWjm7&Z9U6liGN8lp)Z=D&~^1W$OS)-nT9rB5+Q@k|G%lLbkTO*;_DgD|F%NY7sKy2~m8Hkoc33daIQ24;*~K9J zfgj~mgWfG}7Z`LNpCkCZFV1iz>olgqjKMcqD&2SY2;?Zi7XzO@&oQE1r9VVxmVhoJ z7KBxsL?tBJ`TbayV=1Q2aQXgLWD|ByOSJKVY78_D4SaLJS@BGI92OPZ!xlSec0O1E1LgYWz`aSMZ}s>nM^a3Bjbp&f zpGd8plU}iYfu)Y>6}7Rmx{+VJ7L;(Cv;$ zReL?N6_%u9wnjYD4&DpFQv&?NTAxNssvZrsHM>nWl0?nLj5zHXal~W1R-UG z{`0dAj@2nWS@--5h=yL1JC_a0gs}9D;D`%E5vx*CTwFi5ow{pb#6}S2&ivY} zp2yZN?-7kdkL-HlnKM#&<)n8kM`XP|T0hV51D%&+Ec8^JNUa!?+>J$vmqo(%ag754 z`eI)Y1)FSzYGinTkc|7dLN`Q^0v~%7+j-OD0YN?++muo~WKQp-Far&~UiaY^RlHmyds# zfXY-Ymir~Yg9n+kKodpU@11YkW|oK}uH*LO79<9_GvRbW4RawPD=Nyi)^{|ox+lI1 zIU(8cl@QHmj0T*Tv zlx)qZJxCIQ;5|D{705-kOYkXT>Sj%%^uwF}F+QR9YoK1Y-trZu1eO@O+y^?!1|s7Y ztcp&aALwF`Ul%_+6~*W>9^4@v@}aj}tcv)m(2PxgVE3Ir#jbXN(bTb^9)JDP&(>2P zHG!2dFQ+u8y~i;&EJr-Js2(K%12NCNWqnA7^rWoyQzWI!p#P7_F#@q^>JRfHIr#_{sF!z+#5cANTx8WlfW)(+i&JT$`7< zyV=P^31)v@PE>q`>BGIRL2x!UVWxeYBH_|kPq}9?uHj}5Z9EIRA1u=|gD%0}Fxa1= z;!-T{l#IC@zVP(JbWNl7qz`ZIRgthO2c|Y7Rzf6JytMp6E{Dcp%WBVxR7Q!C(Il=`jp{80_RAnNpnsJU!TPnokl5$tOc= zSHSUI(xvBSO9ldQAc=sml*m~@9v^vtMroOC6ZOhs91BGX#v&EzP-s?Z zv{yV@ar5NgmTpKM3oSNEexopd=22r(ZY=9$$u6^CU~0cwQ|iqo0!>hA11VZ#PSSxQ zj2e6$lk@X!-LP^g7Z)=kXxERa7CZ~mM&!FOU8c)PQ}Se>Ts25kP3)UBaqnLp9;5A6 zvz2=9=|q)WS)jF6^=L;=CNEfFPDhJ=3Gt#pfDx!kuIChY%SL&fv`=8eletM}DHZ|e zS%2RkNnHR-)y%Q*W-VscfNPZ&C6OV@v1!I%*74qZYJJ@I-86Fb*Rm>MnY$zGm_qGz z5gX9nsEGOV#R*qKA;Wjdj1=FuIoUo(VG7DQ@xE4%-a|5(?BFBdG9u}GKF(s&bdz>s zjVG08qf`~uAQnVy##>OKW`(EN;6|4mBu*5g9+%}+LGrp2@r7jD9L-pG6{j&K$R@bV zxdw|9(wJ4h#QPFGG&iQC;sYvZp(AOd0wLZ$zCIy0d21`>LAVS27TvEE^Or>BvLGXn!(xIyGhj;N;DEA;u->+3h!z+-aTxFfJQP_5KX!}x=J-9 zUqYnPxn6Al^iY3S)_zxDDDKcy))rF4{D8r9ur*!0_J^gFV9&OS(&Su?VL$76nBGqcRbdbrV%mKe_DdGySuV2+Jk$Cbvkl}x=mI`b=*S9 znfr6=taY4y9Kwql@X_FwPW>ZFakQt&mNAmBDNu0VY_19A55&9v@kGrsPBA zz6@?8|C<(%@6G5QgRxiX{C-mPGlHuA+BO^BP5yFxT#KLFI4l)xocj&778A2U?_~;} zrLM3xV>dH+vcO?P1kESCc>aQDmpoyt)OT=;I(B#Eqka*N%P_+dU|fz@l_m}en7uSY zw6H_9*erS|j$^oxgH^vc9)Gy)oR{+a`dV7AM?l6L#7iZ`|7B~@?JUkD4V6@ozvtP^ z?50HhHSwAR9@{8s!K+$0D^9}0)x0K~?9m)4t^08$$HM$RMcyw9-;w0{yGz`PaN?tGdinF_iP!J;+QMRwe zkkS;!@Uf;@Y9d#~QR5N<6K8-EZI5UFQX<=xuORz#CU4#8mHoSBouI_rb;``D8=!v; z1Iqxy2O0s$pohRHg<0Y`brEnR4D|3&K(xRs5C{h3``1qpNJZ+20w4H^q9Q7Y@~=}c zAYu?mI#$qixg7@79pG}f)DA=G#?$Bo9RG~A0?_ukRfMv@yKWmI|DbO?R4D3xEz(#jWcCGdOnF~UF8%h3) z$+uj4bKxfvCyeb089Z`cNZK(@HhC68vFJm|D^GMlH^w7uRi@>9RO>2fm3(G!V^db zV~B~vpM3|~!2B&2RNk*+1NhAwSa$`+qXf84wtvPhyW{;9n;XuR7Xs)|1Z2ov9dZCH z#NHli|7U?gj`hD4m?U7PA`nOfFZA2;@pC{tp#i|Iwgxu;BPN!Sntw~CRh16E9U}|? z^t&dXGk`!Q22NIve>Pd4`r~iGLGi(pRX|3s0PcgoV{#=k2xJcZGgY*v`?u6UjQ65# zK&24^6u#@YFg6g#+Q8_~j%&pv{;lKmUa(w`0!`XY>|a%|X8#Lo|3B=dlpFZ1y^7bQ z=zD;)3xMP92Cy;TE%<*`2+-olzqq%%M<*0Hg7sDhz;*uwgf9@zE{|@xmJkzjE6AN9 z@yq4`3g-Nm6t^ROuX!!ODL~yQj9)G86#>XlW5_QO=WhD_T;Vgb$bQT9<6T>u1-Ljs z-|DXCIwb+F12De2W9~25WxL6L32|%g%d+E0Z6L&GfeLn4;C5gOv@x*$wWR&R)sLM2 zEjL8&<>m|^ClnC*E?4~Nf4O%n+AmyR9;$!Ifah-r{uK2>AP{icB4G1fu80c2H8-;S zMc$j7b@!k5e176g=U+BZCxBZ_+Zqd$0uUpx?&k4^8VF=-4*?q*INlMM`Kg-6PvFc> zOBlCbz@`A0-R_6MTL8)q7>#--kJ;4!0vlLa{fk|lDe*HKgwzbaJ^uMZ<<@!F4mV8x z0Ji{$i@Qdj{>3)8`L+1`qOvIE=ihn{h1OJS1K5SHh<@Fh-)I5@I*7fqxzYa!j8=h- z-=f#o*MZw8L7+Zh{gZi=z|nidTeKr^QSs+c&K%tN7x~cF5Uk*R%4G>~Jb-mq4JRXj zY;I-c_6t}$A^X;4e_sz~7P49Y>cRy8Y>g9D_p0;hO|hSc_TtW z8W;ox00002fWhw<9ks9~QRUAUFAx9#Kkwft^x^mg=qRcJ}q zghXAD+Giw%RJ7o9YC!I(ib*I_{adKcWwN!>4D^!DD*+~z1cFukOJvn{L%@4Tj~B4Q z|MSTD$0Nt$CN#+(Ppp3)sQ=>;r^Y{*8r3MIXvgZ8sK=&{j`okJWL3iHXp|&WDP)fm zj*k-5>?LAE5mmvUqzWM=D}exoEJ_?r^&I6aq$&cH^h_OF^g@y7$7uBE0RFRJVBjyh zBv3#|S`Yw$-JjLKeik%zG;^XeT2{5O+h9ZZngV!*Unz(pU6abXF6;+_&VU8&u$ADd z5=JnH6j>8OQ6eB+(aijO+QO9_7R$2LPeoVi;O6V{x)u!s|4!XWyu1Zqdbt|xl;2gW zusKT>O&zs&fH5 z*+QEvXizVGxX>l!)zJ+KrVj)E)sQ|lB(m60Qd~Mbzc5!|Uf;C2z_iQ6&*Lu8C-xlO zLZ<}+ZEjgOF*6g)_Ll`&4HdN;yZYRf6S=0=eRQyk+RCHVcKE%z-7p zCEDycL`5Q^T`#P1ulqh|1ov-67FH4g-!9IOLSlot%0(+m@>h^$N^e1O<2WQFd{=vt zy_+HB?`7tkhNp)L3sfP~MT@m~e}q+7%!@w#E|UqUo-O|FxVU88T}gv}XDDd*UFJ(V z$_P)j1`fUb-O6AM!m62r>TQoZfC?8VBDfJvxl_xMT~^-Y;~L99N;Bez1cpd@;5dj8 z`#!$i1i`jkN8M8o*&B21Kt|PNOn=n2;|t4jkSxIIHzSwMDGZUv(eh#sJ8AAApl$Cgja!^safOE)Wg>oPWi zg#5yNg8Fak`ini*nMk@j;A{f(Q%&c1>-W7czZY<)<=lo^7UxSPCPmwoM01V#qRyZ_ zzV@!*(fM^9Pn`+S^4$trqyj9c8MHVtoGY^i&B|gz{-piRvT&AwTX*zkq2@gKOE8Kl zEw|7%cScn7XFf^yeKEwzvrYQ9!U9@y_MV=S4i`VJB#vF1goneAH~|y#rkUJoG`^i3x4kFNbO`}R#wej9?M@Tcplds@kb4+A-EkR zxF-TO*5$kMn`F0CL1@5^bJ!YK6nyB<+mol@Z{eYi)+paOLLK3_vgqa+loMY9>;<`{y&po{)p=v71T{cZME( z??_M)b!NF{= zx>9m!ASletRu-Ui7mEEl+5kVjww=>?uf$+uTfO^qY&US>D8WY^fSI+Gzd{(YGx^2g zGL%mQ4rv7L$iq6d8PQb_fA#QQNmr4I=pJ^}o-2rr$+z)(0n}u!MVlRJj^+CFyY#&o zH9SA@60$QRy2pl-eb)-TOcQo?wr_y~iZj>$fm~CJYjw9R?U%4@so1lvqFJYt7#hDx z3tNfgpUI)FJ?D896(TD6ou}-(WhUa)${@jZ-nhI9R_YEDWb*Ard-e&wJGTSuzbq|p zdgdHC*Dv0FRVzHhyYw#tLf?nJJJPkrtJ8bR+wJ3fo)Skv;X(SWj2eUCgY3t$2jw9f zlzTZ<%m_D8T3y7^){9_-z!b0;)j4CN`E)>i{ibVDBcsw>CSUOKDex>W289!=6kFo>tcLs}D?vXGoNB)(lvH9%rbZjXW;& zfe-4>^*~x)mU?<5Gry{n&4|J#D_;lgn!;A3L&S%_(Sr+0y_n3^Bk9{WQfg_X2^&`o zT$Q!{{J9;+Y+6vdu{KwC)ItP*4z!D)joZf=UdN53Djd6+p3&_UmTY1#b+lF}m6gA!_1U>EOaRuBpd3@i-HoQXFsF$#=KAJYHF zJnE@j+VOvk4E|qZE*93#7PfRo|BNw|voM#EFv|-krdD=PG#52d$PWrEcBG_2|2Hd( zKU*sNJk@yw0{S`#BBA=+zD zbyHtiMgFz7`p110f%Wr-`($d+Xte3?0c_x^*-X~6Rp?6Xm%gtYoPIA+*x|9|2Y9&} z%j7Pq;DeE)j|?ALEKMoI3x(QvplOp1Dko{`yly{{UR{!!=OSd>N9;?HM;0&Hl1Jj4 ziA$H~VxZavE0BI~fqYg&mP!`yNLG=k9!cP``N!ztfaJq|yqB**-9i@k-MOK1T@f%% z__~5<0<+~JiZp$nmN-0%H1(I$lvy1{cWZrx4W2maCue)oqKkI(IU(&s6)df$w7$sJ zv0Hpoj58hN@@PcVBi96SLNO;PWK0yv^bKw|4KKN04*Ph60sJ;oXYCuwqkgZWe=+b) zVD4h~wB+zQd;Qd@j~1k0?gMn>difAqPPx zuHn9RpZERrQ_e&7TvY+kn50CLEZqsT5mKF`nge0Bz#J2mfmkXKg)EVtCX|SP7&*aC zr%YjmK$qO^M*c;D-5sRNFFc7@Z%~|jb=WtlKrH8b?-vN1+Vz_E$;<6l*bp)_=m1nX zdS)`L9I7a&&p9uFZKiv&SMrI0xld-d4`4`K2 z?CF}5&iONAu(Pm%bc*^ltRB{&zFz{uljz)(y?dA$JQ_MP=z;RN3L9`UxP|k=b0mI@ zxYNBdmT-YB^_&UInHdG7&X~NWUG?%e3P(C0Y^n_f>^9=H5vpZ(YI9E#$aNc-edF>M zfe{tx!z9p8zux7rq6AZfZWIyEt<@~VLKa|z$2*~UQL9STPYmRCzy(pQJ!1$^jbuc@ zCXTn_;f)E|;-8HPZ$J19ea4}LH=m#HbDC+*E`hH`dE&NqdJQNFH)~ad#Hc5}Jl@&n zAg#>EN|d+W&kfi=cY;B$AKk;R7P&o7-uW_APri3*Ok~_nu%xAemIV2+^q;D$GG*=F zHthsP)H~-dFB|N%SM4UuQq?JciGO>T3gsc(Ul9~E2n6cd1g(<(o;a*e!fFb!mop~1~~}d!iOEs{fGzyL!2k*mh47Xya>^e5G1r3pxJL6{G5v^IFLe%#6= z4WC7C^K4eyq3x?2pf2D2u)*~Vu)}pJF;!^T9I@)7VV1j_uP*CAK-Dp#9=Lpcz{(N} z7Ex6Zq#VMq@7tCZWS@)f#clAUH)Y3KC71Q5iV?55*(#|)wyyNSeQ8e9UOIKmhR1Rs z4M!I(7X&>0_Y+yq0t9+$-lI8;AH7)i7z?oR>_%`|H-2bagttG;y?y1n$To5SDiLmd zRaJ=A6XSbV0K5e7&RlAU;7!1r5m%sUeNOZ44;py;hYzxwO1zH>*wo>@Dc_K{5w}s>C8q^b3R=5*LXNg& zSEp4GlMJ5^zrPN%S6ZSdo049BF&~I3)O@m@V?F51*~nh15K2L8q^729#wcbSyKKVj zIGR_uT$pk2X)X5G3Y$aIzUVLvtrzV5$Zzoik8X+sZ~kPo_?}{U$?srz)Hsh+FT9mk zfFI_LUARP_qqaO^#G}GHbxjPud9pfNb6)t}(WW8HPYvYgn08DlUl?5k8lkS3Aq+3Z zLy7_^Ih*JOGNdqXhKkw_TnXoY{7ap8?<@;lNVui2h-@BkBRX2C(Vqe~2KHj6!iIDO zOK3gmL!bdNKSZ7Pj)oqwO6%7ORp&;bMoMzs#l?y#?*eP7p=R_<;~9y|)(99xdu&^cWVCVM%bXjaW}mC+!mtV=s0^ zgVtaFPHkGDNH;)_yHgneo>9e>HfnZqw+UaYgT4+-BWftedzE&k5%PCxf?PF*6j|4p zvs3_p7rmQ`I(|>@Uk@9~<+{TRN?~;Hy2Wl9zv;jG2X_7n;Mx@L=Igb|F_DtO-)GpC zm8<3d-fbAG8Kv@6VF6)6w4Z1_j%+IH9CfFH#zyQbG}Jnr&uAe-?{1P|#;Pz-v}n4_ zzc7Zg;K5OkOgM(LMcv7d#G~v*8nXA^HzW?N);0}Tm%|P*2`V=>^p*zSEn^LfRsTLsGhN(tK%>IA$QM~!PG2H zR%Lk}!`4cKl&zsEInp5Bz}1S}KI_mkyYvK}{Dz$XO^Ui_#(2sq>=_o?;riS7B*d`O z$caNgHlpq0+gYKBuL~G$(p{3?+^qUn9x2>)Y^t?vu2(|mS3=GEgq!XjqrO( zi+IE#tdqte7Up?8A?j93Iys&j_2K-`0}4gcG(`1}27j&VgfISWoVfLE8adC=nm&S| zisizEp1H$sMU7etTvo` zSQ`vtMt)e34XfU~7nk$d{OEohyyDK|=}iY!_OySj_rM;r@Foj4&K)RxE~7Zk11szy zHo5mn5`NZQV$Tsta`6}E^n;Tbc7C1_74=uGhkCWdKnTbKlU;zyC6_mQOI)u#Z?-* zU5NhwjHphu)A9PBhzk8t4*wHT=F6(Gc7+TGyq!wlLCi3Eycfy(7b{Ju88ikO?QE2Kz@$FI{}uZ}gfU#YX7SC6PYq8rQi=ydQjvPbeJ zL~a~ygKEB1OeHWW0uEzJt~`gBgLE_W-omFBCjaamiYo8Lv-spB}XX zwpRF^js z@ZKJJ_Y+{NCcHvTu=48TXL01<*$a33+=XmyS(Dajh9zT(ra?QXYI^ovP6hR?XP2?r zRyU4bLvBFDVVN2DLd9d5D*zQFMb%2F6Pgv?I~wqJA5{QSvCaZK*%XL8`7i%j1SYC2 z$Gg+Lr&OtJH?729y#V?{6ThNavQC603hE_KA%9<`!ab}x{yy21wH7-KrPAT?oHb{i zBDLpRd|Ycu{`n?FN9h^yIvOwQ%l~b?Z-#gbuEr!2SyeBN$4!P3%Fx$-@(UXCAzParaQRc3-2GaZ>ETUy zSbzou9RWW)fdQE(ELH+RPfCLzpD;%?cNP9C@4J|T7-n$I6xp_~Ey$*~ichX&w*eZg z^+B@EpZ{rYm=;6#w^%bSQW?m|wZX%qsg-f3L0x3u=>#D8Br8UYI9vyun%I)) zpcnPU06Vl*8t@KHshT)?4`k}(Rkqs0$jdwt(X@Y!byH3oVbpQ|0Hj9Ks#qR&HAPxb zCEfiQ`mHj0yM91!=hzdn`=TgWC8hgD$iOsCmy5a!LwIM8peZCT+f$JyR#79HB2K8M+13XPc-`^|^D2d+(# zpSPn+?_A;2<`SFSUfYRT)AES(2MAWTzFdo&!ADKbkkUSisgA%vq>^Cci+lOhtWy-9 z253HZJOh(PHb$`Uh%!y~&2?*|EJ6n*YVh*|rM(X9fQ36Sj(Cv04}JhXJ+6I&UQli= zjy>iV)JUowt~2u|2%Vo}Q_Y`#&*Q3jh6aPgQ;ACgQYFCDCzM}bd)(kA6t#1n5CJBVj{vivp_FnIND_!MMci-&N#qQzvFPaIzzZpT z9=9Hxzqhuf_{B&mbF)l}B{0l6IV1@@pSAJQf=7!%%7Mzk;Ts1}(o&fO zr?8tvAQRp(`+3_a;~H2A<-^Mst@?}a)2E`$hUI^~*hkB&D^NA9s7U9}#quT0>te@W zrK)vY)(u?FW5*&dPKy?UM1WtavVj0Uy#?WE#e#mn;+YQq&f6uG20vA;IsyacUAJdQ zlVJyD`B3KZ=EZ~ieyQ!xds}{`%h%ZtL~*yD(_e4x-?M7|)eEcN4_2OX!G2=(5o;;& zX=3Wv?Zs#84_(w#JD(N!2 z0IY9xI6He^u$s8!U94XLSy=o{T1B$;>hG9MVduBROwqpLwF&KkqV)^-YV*DI#~Ha%3dAu5NSRXlIiD- zyN-=JfbkTD-`1ccS@#R@Y<=n&V!qzMrM|Dw@7di{RJ~&B0OUaPN#N0==mK0RQNOSW zWqfP7SU#Skq_MkH?FI1E(PqS(VI40hx@E&O1PWWb`f-{ocpGBFN9PaucK>x&l|#sFaIkV+%Qc z7qqm$HmGVF0(DC%$A3)CVgU^loND=vDN|;8CK}ml^}}TO1MYfy{YZG^$BlMAQTQ_w zmfP$arfu8+4K`U64Op%RRJDP{Qgz$3x(u9`Lr80iI>q4u>JXCAz}3&!_SNBRJ+-r* zY|#LAVOD;mg|RTLMBycF=kMeGKc!;nRyTm;A*Vb1D%#@=vihp#m?aC)5Y1Z2*0T7tJt&F_x3AR7rjUJU}y1EIoDZ_@{0iNF2Oz@j24CQA*;TOLTf>sQcM!|1)qWOQNAftQmUUF!@MaB-4kmlaC2#m4vJz37>>P;aF znzGO|{0MZRQZ=->u@n~I_y0-K)7RY-xJ07Y2NSq_T%>QN5G7a{p78bSIhnqEH4Ap1r@ ztQtT-%1Vn|HbTnMH$AG`-#6Fi|3CESjUWA4_Lm4<_zw&A`VpW1v0xKNM?1%#dzG?{ z)dmB?SCzomV0GOeI?aV+D+$67Q;-JO1vDrlg<-x8Et7Ex$Hj%G-W%g_$(7GQN`%~8 zFOQtg#IT_6BX&+)xLp+6-rDOvHHu=ttGo+F>k<2M?ZP@>x^ZZBiu&>woMD- zxhF|v{d;EIe5SSIvEPm~mu+0<;|6%}!bVL2k(D}7sttItthbUJQFM}FL8*KG4pyq# zoY?Rq}lJsknMAy81;Qs~})#Vmz$7Iv8>dqb+96)Y(v?=j=a=G6J%jv(ar zLR?~0Aq^*oEw8W*nBAjnP;?}wkiGaCl+QyftvCm6I3y z6e#?T=iHz-F^qN>DVrle5nHkE)!C%^Lq1o(#-O=tK@Q2JyP|Vc2w|r@#%Mh#-xAiy zQe#f8)2u(~i%n=5&zZ042F-%uT&=hr2}5v)NNT=#hu4BZzsB=KLV%MyvL z^V4-l+B%^HOkA$?{T*~PqPFe)%{JGfDO|7`*Up9UHg@e`4HA-M{T$!TfLEY_znWw| zUc&CHqadq$3@-B=u+vlHPg^R5wfAus^;*eRG7Jp)jO!Oi8|>Mp*w1&I0> z^j4l{1dLTEX#&e-v$*w~RxE?xHx$!(8iEip`<)fGhqtD$57W!EBDVliY+kA%7D<9& zI}nxWb1=$a_gvHbX<+VV+Ez?{u@(a~p(SEIKfC|MqN-x0egfd~i+C7KtvS$Z&3-~H zk&8hT#NU_DdHj*A5nfv)*n2Z=8+z}of=RQI0gbDH>d*#RNHKvSrGUdcXUon?^5>HynoORLdRKcz#_ z7+-@-oRAzjKY;Nxn3YAzN(93>5+gCjG-$1l`NrLvlQSrkJs%Ig9J0WP3WmGkF4$Khd;Uu23_|>Umy3m41wHNvG14Y$l;_i_;JFVOX!_5rZLSB5t zjOMTM10Les3!=+1%Cg?N+-;cL_Da+JKusazDrS94)A8Rn@H&?WraWRNo2$=`FbXSL zN*8@(Zgt~xWNZ18zY|JV1yGyZPMwqZ!Pf+rn;2r*LmMejTwy|DYJUm{40qYumgQ&S zr}?{ZW{J&iIGz74myS^SsD3iLPBUl3a0MN;9+bnPL9{lR+dVy}0)W-?(bTL?2~&ig zeGErIJA?`r401tkS{8J{ctoDbX~i0%e?HSTI6bRC=R-?FJG7OFoCpbk)=ML?$B@9r zxR3QQM00JR4zrBKMj@TXg5E#0Ur#ag1B)_t)3v2Ac(QXbo5ByZZ<~fHFxg`KOXn3tih^@F$kY7G3jh11L zXcO-l)&A0QyCSa5H6nC)`J0K$a2~&MP*(b)v|64{-CLi{>?+SARz5<_+1v0D%F7V? zg23ECCm4?p50_||ySF6!wW}M69C?d7Y*pU^VC$+d5o8dj(;r#V&7vq)f*8JHl6~d= zIFxE=Zv|`RfpG=;gNOU^!P+)s=k)CE@($%Mcu1dTJnnP^Hf%Qlm|YZ#g-|Ds;((>y*OxjkDoB$71s++om)OC7$;vgL$^> zD_NtvDaEtVi#7pl=L8Z@Ik(&>*V)#DN*9XCtoxOyvMph~F#OL?QRAj-fT>FTmdo3X ziJEWF|G@6QviW&1?_AUmN9g_Ohxx}5ObuPEoqteQMb~bf0mTOn>3gqYK_M_N zWQEYGK#Q9&*|t!ng5{AAmOVmsR) z0HSpziaU;#$uxz{*$JvrnZwRCun;!uLRW)$&}Pd%xbh<(vE33x6ca8Ra{~UYpv#~W zmW&*m=E%ZlKLOQ+j%EI6-_|3ZMCx#(;Pusrvsb(Jc<0&-ZkJ6;Z5UgO0>O{eq{j&A zJj)K_2sPZaltMfmpb4Y4c&AW@)0@g7`Ozz)FH$N5XiBaiDC6r$w#(SVndz7{@NidM&ZS&+cY_6I(al}2%9kJxERpq$*Bj{IWO^8jZ(w>qs>i_$ zHk=)5FWH~I>mraB(`Hq~%P2+#yPI-x3R8l*CiU!jBc!leA^maRvpaHSq|V)jniX*J zOw#>HPx%m{%qp^(BzcHE42dtpG-#ZK*mz$T`mJ2Gc2d{(bMt&<$dcThYGX)m`aR;H zik5!w8CV>;wstpUQ9=*_otHh^1D2cN#-@kPnSpIWn$VXE=3ZSE)6&A3$F&>~1v0zT z)OX6ftyJ2=N9;!7wJZQ#hT{(KT!zUlJH~in4Lt_~yYaCJMNFrxUquaSs0lf7I!~Kp zLRdSf+>f2n_R7ESrf{2!^RZA6)N3|WVM&8WXbmD$Y8`#3{;IzGyQw!DBXI{_bu;2F z?M)5`{iJ_J7np;JjObxRBpb%bZfWApP@4xj_{EOFUxPh1YpB66FpT3Hp)=&ToyPshFk#(`z5qN6>zr!T`$%;re z65#oarNQly!GRW5&3_S`jv6*|CqXD5h8}V`7(KV9>QmPqqDcHshC?wMOMl*;Qh4|J zPQ95o_k$O+f3*EVyo4%-*)aF?gXqN_NWYFAFz0yCd+|rwNLGWes|;aFUKGo_qQ?!1 zh*;cy#Gccj4<$FbP+_4N~6DGx_2R z-ckFQhS+P+S~nX~K63Op*{s&5FtLWB-@82j`228l2V~Yd1~`v0G8A1Na+$wFfwiL= zFF9*PiJX4JE^BYSx!D3oI7Ou8sCS0w)l)SEUiYPM7m2i%SP+57z~MQ3q9Cm()_zSg zT0pMD=E5!l(=|gm14N!&Oh?+Y!#$!7EOpjk-ANf0;k{<@L!RZfHPHW+s9MT z`s>hWgjLNb6s%ucqdiY#VaHa@YiZXIi70*Z;1W6>UT$Y!wk$K zhK*E%`M{BBtB5#1#AN%Zvlr939OW**_ymM%Gjw=DC z+AKC;hU_bYfAnO!J1WfiatV1b%4xCK{B^ulSvmR8YBw;B(KYrc1)N!n+o&V6=X3pg z+7T0cAEOGVq<&NFc%H*oI~Bu!b^Pz);bA=!+i8NMcP^9dmLuW&F`AtAulaDP-=j^z z%{}!q2+P&zxVbNl66#X%^K=XNsS|%KA!FoQTDQN~p%!XEg>2)lv}}5g;KN?KlI5BcH0{(UaZPRn z@p7PQX{B1?Db%^Bf+ut{|HY&w6dSj85*Bg$c=s6D&3zrNjM9H2Jb}Hqh|4%5M62A` zV0i8x5$*-wSLD)ZT@Se+RVcqSqRkSp!h?F1LF{%5iw>iHJEH7c{1Sdl%5CV#-slEVJBpHEoM{Qbv8x z1RM|&tlF5DK`}t->A1VT{CTWGNowSf%wq3nxlt*?FMh<571P$0AQEf#@9g#KeD!qI z$~;Mxgi@xqPIvXseeavC1-7H3=lAA(M1&$kyuX_alQ#>G=;GCz*frTLu;Aw#L-c(e z{pK9l8q)GbFZfo#+{Dy{Qs&EEm(>fa9ls7x4H`=$CyYeXNp9CI^`Yh@+`a%qM;YII zq4ChkEM&A#=G>zZJmaG%sY(mTs&O37oQQRF{Jgqf2!jL_OL37S%h~PDN?D@!qGKa6 z=cFHTZN9#j;Oq8#o>S5aNkHzzbUdeRg$i%pE@gCBGxvu4M2t&kQ0sM>jGv=jvaQ$L z;CWI`rJarhovuta@%McuJ%dBV*2OS%W-3lmMO-X*#V(_(pVCTm#qF~qh{OL(SX|C9 zrIgsNB886=3MXwee)4|Yo7_>7_W`u(0m!xHgpaV|!I6@~h|Jv1 zcMH6Rl>_^{k0k;V2LVgW=pkbq@k!|OGN6|8fGkC5>_w=;Ct2^k@OtuB(MOkTuxU(Y zc(IsU?Ia5kQS1x==OtLI1-g?v{Z;*Sse1cPr{tY_ta_-3&N+GNP41|*a3!1%{*E}E zthmdyX}2Ue^5NRSTXgOpr8$P0lcy$VGzv%BOryS)*t9|gtM3yEs|RND=Jq7aLGUN- ze8-4Z=Gh)1dJparC!@M@1Kd(uNzbU3pRJ+>u~G5Ue>SmaaAxkYC93du6tk*OR!LfJ z$GqZ#Juen$A^<;k?M9Q0YwW#lShFnI?FYm95{VC8x2J+8$Q zoWcEfebBf8hyU|#mA|q%7Uh^lwdWcp&(8Hx*D8dp_B$VoifQ0zLTng>Z>)Z)@&vTj zf@-xxBdLVAKk;#PL!Q>82j0nnt?5S6b=j7j&7~udmmI#Oq3K$eLrJsO;HuVuSmUE~ zWN_dB?(7`5lBAu+nQkLC2Y((2fim?)5}QMUkp3sw$_ZU6zJPe)Qt6u;lLvdcHPo$` zE3HGJ*iC_sqFP1Tx#zmMokGQi=JiZcgFm~S|1nNmU~b_Hq%4jGqlHOMGh)D%jS%6aJtaM#&meOGc zzopo{X^9M+(B3bRm*Xff_%CfPEjWPM-ww8EO#sRhs5ytxe}MwE`SPnW6`~%xn}mfS z!YM`FPFem8qv}ScQ>EU$UQM?$YTvzF9)Dc7R^BbIJWTfT>FclGh*e_CL^bD9@SeFt zm=dzC>i@ROO4osspP%?DRyz|CAcWq#Q)}N+4jB_XT0`ccyHutFLGJ>?c?WONAkx;U z(tcc+x_tZEe|y@0y38+$x(QSj8#0AKe%@%Pld(W?@Ox-B>4(7lIwU%Gib*V@*J)6) zvY8OT59_!#>5_Es9r5^-`E=FFW}GZa`HLs5I;7$KyG0qTdEOASJ$s< z?XdWBLq;A{PQ^ZSvCie_y={E`%Yg^RF8vE1SS(<~NkI#=SgRdb@YqQobXr63*Y`HM zo`jEoi{4QtSHC+RE@!4cLYjL+=PnZqG%^%6nfUb8O|SN$sr{hl5`gzEp0q`>G1BexeYr;AUO@&wSWo1BfEQX~S3Hr-{PH%5h( zTC)C{#5y7P^E_XOU)_A_f60ZudocvhsxQ(TplPT&KNju$-dkksQmalmg{;Lzx2+p6 z%_kWE&83{KUI3CUbrvG?bKoa@sGw!wq^M&VjS31|YVnX^xp-rokHk{7!e`V=Yv!!K z0Ly-C%&m()dLqwiZ?=-(-a%dggmX=X7K*@n~qPn%h1j58V9=Q#*=B% zj;a@)Mps=mCp%_NOs?N`f$9SU7?mu!#J3enoUKBVJC+j*;q7+;Bw$xE^lKOL_$BIg zd>%;jk($LR(aj6vk~9kr9rZVdg7;XkNm|QuSW6V@{kJ&P+>O=t#Y;$1#e#+PT8C)R z^d3wyB`0yYF?-9)8&129({PV_5TTVQw!S`YpoGngS@H+Y*BZ*Oq(*^@LaH8Ulr;F& z-cSV~U_%}bP?X-_OlG@$z?NF9VUQoEMQJCnK*ZAx^+p`1cF(8b(V&KI`X-g7uZWCf zb%tT9EbD60w~gY2Z^eHPfLRc1YTwMiE3i%1(^J>bq+1?gbR9`qCLok{QCV~zuxQWI zXxT@`>jRwh?}TD0U~(Pw(64h8lk`Vhxvwlm1aUW5cf*U|otm!47PjD8VKu5U;{?pz z(7Rmv?LwewJhU|tOjh9h%z(w?Dlh^pE@fObLj&EU-~L+EZqEFXHgCGe>nT0IE}l7T>MXG&DpS)hjzo3TBpcLDA&T?YoI%}%P%YCw`lvAhv>=KcV{G>{J@ydX zz+`Sb1ZC~oe?S^z&}j@^I@hi2_l;fxNxyO0dfNQRdL1wsKQS^?F4*Jj2u@%l(!fpwBoeVNJHp zakUzCH0T51`~BOyCc7lM=tl4zhHP!gN4WKI`6#&-RYK=$U(QWRMo6k>P=Yu>F zv91D_Jn)1N05M?wdR)1(k(78>4D{4y#@UaC282s#qbRY;j`~^IjbLS*`s$JLmASE~ z^(kPdMk>SF>!4$hp)5S4Cqqw%Jy3S$cEwxeMeV7wHR?io@gcb-E(3B>i3-N-E+sJG zhBFeO`yf|t)o&b|`E~S8rHb+5X;ZpfQe3Pdlbjgc%O+D%wwy~iZ4huzo5@o|Pg_UT z6&~>f?dWNIi|Yj z!?*IKhU^jx8xv$kzW4?8@$~U)#kna|9cVnd_mjh7!pm9ktW&q9r!*Ok=|@Mt42O1B z)lIPFuAbi|!M18jecFGYTA(Nu#<)o`A4VXCu`9%1X~A)bYZ;mvWu1Yz54%j;mZaX) z@b6eFeDMX@>1YsoQOJW=dJrdzS~{Gv$~tb-+t=D}D4y>_Z;x=-O71AS|Bb&*$Ni#% z7f)qBLBCm4yliij&A+;C(2ogkc>T3z9x5en;4*&-QTbi`E=N5%=C>KA(6;Ei*YOFl zi?{Q9I!-m%f)63E+gDi!EjOh(X4%Z7#{A}LF*#4*Yq_K2+vVxv(dog=W02wvazx_; z@*aSf2p#xr$M46}>wa_eIU1vXnGj~joxBm5+=!SZU%R8z_0AON@b@qMf1v;09PqFm zL=^2$0g&fMWcydwurahUF}1KZaf#!#9b|wBF}py)VM2}T=AKqSF;7LqbOh2&G0J~q z6ls^V)mL(yGd&f#zgt{P)Z5|H+m^Qnz!V@FD@2%R@9Ecs=uTQc1+@>gt;;`P^uWtq zmk919{?Z3C6OzGOK$qo#sdQNjWgFNfityLma$Aojk+F11uTYOp9wsfR&l?YAW)<`h z7AWXUe~lv zf8$q*c@|hM<&m)NwZp0w6#Ghgn?JG&Y~O{o*jRxhyO;_fx}-czCDd9KNSR@5Z2r}> zIP{yBeL!=H$00)Xv!Crw>X^*6x4}ftUKHtf>PvBv>B> zBudYB)gp(@vH>E8wq~OU63r4BK2{{Hq=;km?G=WfAS(5z-6fEK`QgR%*g@j$@8S3T z!`H`OkeS9=KOJ8{T|-^%hwfM(@mwHjIs`u7Ztbn@sz1*w7y1p%(>n?&W*);RS@dW* z;4&c!6CEkE=<)`E9>n7 z(hSwXT|%Z!zziV-4C2-4>pt*Gt6flWN2rHN7~ZTmLfA38N`2do13`rvzS?5hx|}zd z+Qw#oPqM*jiN-tu2n#?zTThpO)led-0&IwzsD-i1SCN4#t$2^9vRe zWw4hIM`}FK8uEJR=z6`iOyK|2vs!xiA37ovj{OGIE+GO~WAsl|%u01=t1htD9yY9? zsAd3LS{DImFzPe<^bSuz6bFrZC*}tD2!Dij!@X*yIqkV*AF$MCBWjJbVnAh9kU&`Q z7h*TD&1%|+j(Zlp2YPa4(;FC-6(^{Qvw7dbscPuHEY-FurV8&%#37@2e|g=1x}Uu) z#rH}`SXo6>1k}{byCSs;K9&cHs;X)~MH!PyI_jVMuql$I)SF(7D8S&HmHtuX?cIba zKdEe19|$*$l)sKHzB}!z6EoE;$sG#o{Zle0Ui~x1QFpM)iMnm7sFwVC&%jq6;ln}) zsk#?k6`m=(9~-BcnnY9N|3sNk*}70|+Kd@g8dENZaw5u-vc7pdww@?37S>6dr;oFA zUft?U?)B$0qz-n8Hm+UjprvfQBNdgo3Hz4haDA;VDr!9tG_aO8Lz+Nol8f{&B5E!o zuZfLWvOF~zBRzoFxN$xq3qNH6v0aml{Q?Yga4fbM0NpSlbfSX{Da45|Mj@NE)+v;f zzGZh-2c$m$N?@b7%-}#`TeilyfQ0-&o;$LuT>H544iu6jfruS5AU9K9Z5y~dBSZ6B zDA^HcOfs4Z;TYrlCT zbW)ST#=jAFZ{$W|GLxjxGvdTn_vTq<%CNMk-HN{l`Gw8nxjA-^J{o^&uMcK-J^c9g z+*!+B`E_CGT})GOTvn~H? zE028c@q9(H3cne|`@ygSg5MGH<^0JO=~A2;^~zI=1vBp(=s&0VA2;S_;U9bak#cK( zPV)~%2C#85`=Q1uJO5^KM{`jLzJU#``%;P>5@D}041q62G^1a{O*w5MUE!OY8zPj7 z1eD5S^1k2Qi;BjO>z_&KyXg7(@Z{Y{entf8zXuZ!h#ir5r^sVP>;jxvvXipnk1#PO zr6BDGR%a4W?J52jTkim4+q1QMcki}s+qP}nwry)ScH6dX+qP|6yWL;^&w0YBjAFpfU0x!%&L+(41x z;uUF?kCya|O&vO*ip?RBPZi?#B=nix@#>N$3}v2n@qWMBIP+)@9e!+W=#6Rf#<3lK zq)hyAOF=`+8QNv*!T2R9Ap$v@Zp+^h28*V?Ae~GaQR&A;>}sv{F7O?O3p*CbsCybE z^tYZ+>kSxKq-T?Wx{%fa5*9U{y+H1)%ba^XFOLhaCZ-#$q%?w6mPCSZ<|&na?F8ApK;05w z=zi!tfrLt+thB*Zpa(#J1HGJDz}celU7r%gSVe(QTo-{EVm%MMbltw#r)rf!APAiT zBE@iFWNNzdX?qUT^>-yz7o5Cebs8O@v&l%`Rxj-QPnT}BV0cSHTcz+Z)C{~Cu+DL$ z(EHKcOHKZ~R&vJl+ca!EhEkOp*Y8Dfl+~6j)`(=92+^E3OGis0rw)U3@?KOF?%f&C zq59HedO=F?34ZisCiyFm+G=#RU}#=#jW0?l>WfFkv3Eo;XF;B>*9mR=u6++Vbuy&@T4mrQj8WytID27+nu zC?}{+d@$HLMH)~$JBJMrH~|=ksnVg^uq)EquvAs{@RmZfJ}tWO{Jd$UjTt^mIlysa zn@jasEue92700|95UWZ4B~T6qJ*xq_Y?%-_tb#BCMDXgMa;YStFjWk~RPg(-^N4Vs ze?F1zgG{zIf&74vo5mzb{>-!Nx)J13>H&1B0Y!qWNAp#{=)qRwL+d=W6ErHQSl-5? zFk0cjgJ3Qq86UpBkVpJ1FVM0D=8ST@)7@E~5X>@F=wvuFMVOVYEa&EJ$}bxkL-jU^y0T?r|lUTH6eNKR` z6p1)`ZtkIGO$^n}pR#w)(2!-%#3d+p`IrYrhBYwA#6_8IY)q>6P~dKMY#SI38@kJHo;qmuNi#?gd6A4`f8FUw`r$hpP=?Ozf-^jr_k%{yTr<>oP9Fg9415X0)uK`+G}HN{OKhInWA?eJ z#r{T(9}T-?C6)Z)BYS8jBVPs@#}iFhrsGz)UV8Z~eezbVaqTh}0MuhEzkIieKXh~N zN|obVX5t-@_3PB5){;A8H5%vg9GhQ%d)*(pW5nHRszv@C4r%GjV7K+M5|WUxk&*Hf zx@?AHvTUyLZ5Ch3W$>x^S1>Xs_Y1EM0?#>9L)XaLpqS72{@=J*r!MO!@v|jsgZgjJ zz}CR#pQae}jp&WmCk?=RxJ>{Tat$Voze^_mz-b_;_L(7U77gSP{>kJS^fGnCK4T_d zU7b?*qa8|*Ww3@)C)nBVQ4b$$-xED*Ll0)T06ED$-k_FJ=nXZnj~g`VTY)WC0*?Ct zb}*>k#F1e(6Av~4BqWr$o+cV!L*C>yt9hhrf6|%HUEllr$25?}1e%5zE1J19 z2fVM7cBh6;Eo>5GzQoXgi#T~ftR&}Kt$Cw zq=^fnFi%Vn!c)>k@+Ee)(#cA!&T8WvH?AcTIqy6%CFu$uSH;^$5=rLmrya7|z(SiF zAH;NjfxNt?%-q~GOd^607$Bxj8R-K;=3Iu63|WZ+9JA0{lkfOfd6*s({81+GJg+dc z=?E&B=gzWB!eX%*R>k>HH* z(6o&LJvO2snFAX$h?ziO%4mx=gvISoAWM~{85SBCbpZqz+UoFagDgY}=P_97#%cwmaJDWYyytilSt7$fXRJBL;whh-mz%1X}cp z*o#V!Whx7P)TdGx2T9_};-GYz?puL=z?nSR1%xjS3$S-IOhkf`qJ4n7-e?<1$9Q7Q zELFNvc+;3PDv9jqooy!$H>2J1QTXZT&!mVn7Xts&OZd0?I&)?a^b3y;L6;g*(q5Q9$5o!XmBdPH$u5Y18H0vzo8Fht z>v0#5CdbEd(-S!#Cg|5|SegfHz^p-20F@mbvG4lH!C8$(;s3*kj#WaGDsoJK`R zBmyspl4n8v3jd(N;x0n|W)@vdzpAg)h*6Q^C&P`(;zTR-ZHMEpmNyB}PS$hMkoKur zc21w^tN69(I=6cTaf-TYBz5&@NwN*EAC{P*j%F&+ANyLvydCmHhy>OY5@jIHu>?~Y zmDsV#F^SerXbg5U-XX##Gc-^D@V$?gaozox0nZxvjvJ~qOQ!aACpR1^0q>`irJ=4KhLuIKV?s4K{? zI=WDn>A9`iQk;}L&FBS9#7?YOQrzV-*%ZnfmY~pW_k9C)7n~40bS2H>&o)GCQ-~4A z+zdR?lds;eIU<{b66X+8Ks+Ewe5+T|P}bOwO1n$CJr~`;G$nz?elG4w3yq>?L+9o$ zokag=!~-71$KnMB;FMr&C7+U8Y)GNP| z$*Y>1Y5JqltR8nK$>TOpeF;3s)?8TA@fyBV0PS_O=+>syk#>N)-=L4E>;MJqenY9P61#xa*tBn{_^#_HomNi!TUbSkh)iclagh9@K)9p zt9*;18*)(piJQC!)*y)$D^3iv(jqaGg?8i#!7mnK$WkQ)o)LQ}v2A*g?yu)EUc9Oa z;vt{y&Cu|*AURr}3H^OieUmD70khhAG+)Fvs^3ths6OZx${Nijs`;e6R*rF+Np>K z;5jPK9G-ecEo|7?WR+z8hva-hx{j-DfhbK4d3^h!4m_kMn_BuBb@J* z4x{%&7$w|9wHxbx{Z~<;8|yu;1ZBZu!lg&P04v|9Mx)}%gR_ea$>#`F2agroRdPd( z96LpWWFYvbr|Uf_yeD0TOhuWkjX@-9}I=~>i9lS2mXQu#C{P2Sd1m% zBdX$5!ACg{cUSe6!e6mCs}Rsl9JXc$w1c2^-lXr_UufPK=Nc&azWpDCR)wC=rqZ^MsblyP~J z-~X#r8vM)~-QfNghNE*P;YMngZz8HOqVjQx zoYx;kbJbytE=v{L(RJ~+h7ItI-|zgJA|&Ynt$>=-yhy0@9-uUY6hFo?R*^O!K~$so z?ztn(BX4cn2pY-zz_xc5+4&>hA0hs@tZfAqk(Fe-OLW`SLmbRpu^b+%()|1s$5zs} zg2U8PXFhxyHO4TxG-Z%iX;sB-@ILtdU$tLBKbe>O%eU@74_o{*{`JrnMppkSP=|#7 zuc{l{9~0{XC$gUDCr9J|sk-?G{bpxvtoLsko68T4jgSrg%bNJdb@7C``~}hGE6hs) zK`bB$kFaiqB64oJ0##vsnbb8~*mYr7V`fcv=%@qHGx^TVWaLX}tZB;xC{{0?Bg-mw zwQR9zD*)XyUD6Y@7FIt<6?ZMG@9_)GvZ4sTKjf%iGBJOhoI*dDn=)%r60IM&Xu-8& z>ut?<8-Z(F*mhK*!=*!8yMN1)BTG*xv;3T8&T1h_^lI7K!GkyG&d{|(vtBwW17Tcm zJCjaBm-K>o;jh_1Xv?5;!s$EM?yX$M5GP$0?}fOwYwKbwx;CUXFfC>ZnRc@)MzhvV zW#5^%$g-=1MU;otzDQxxHB;H`qM0T!#Xe(Z1|VaQpL$0VUrwmY!CBB%@*)9Jt|nk)8{#5XcG*(E2{OLn~LD^Em{?=dX{ zK!Wv9I3i}nC(p)`Ac0#KHUkgEM8W~cn@YiNhB0LouEfzV_Q)engBgYUjENkD+&>qTo#_*q;I(jgl+J*+}SM1gEL zoq(p&7EMJrqv4&{mkmSC;jz4tKH4FJiG$CtzLvHrHWe)mBE(^mj{;FT!GchRxW29l zpEO(HpI@luodV@dj+{(fa9PtPK6f2qA8Ufkn}A9}0%>VL8eL*I7Ue0I2RbJp&llL4 zP(XRlmFBzePECZ??a5D=A6l99N?vBV8b)sNy2a2GNi%M>ctxCz_GtvE9PHJ3N0fR# z1~Pj2d?U*T0z%PQNTkocM4v)4C)m|&e)X3YpxV!%dpF08rKEE%N4S9n0SzyQjmkll z>Cz;_Ln0YpIy@FbzGDWrJ(ccO?E^jW%Kg`wJ(QWY`e_8hTz*|McSv_rn zd8}HCTc+E<6)wfIe$^{mtRVYACAr}cMH{ZYlXSlrv9xt$QTI?MADBOOS?W48zDMh- zXuqwfsseKQie?$ebuW}L5l66&wl%M_tXG#E>F*YEB-`@lB#_NTIbGU^YU=|R{&iPT z2~yRJ5VotZU6j_YcBb5w>u}jMf;KU*1ZoOw3OuYiToO4otew+f*k&&45Tn7^ zpRroR^H@2Y!HI-CyJCiQVS$@gtU9_%r#_#jD@S$@HK}i}ndsgpCt&%o>kpMnAgk+z z96LAkp1l6Ded2D0l^lJzk^en+&aVntc7xyQW3G`YrluF6uwIln^U0=AAKcg+RI!CE zw~o4g@AAD7`?wX@r&Q^f#}$UdQ_WZS5E1a^Jc973Elt3dR?IO3>IkBs`l!mSyaj$b zTJt%=_Q8$qeYE(*_+6m3+Dx01Ra0%BZ(OrK-uI+`uV$&Ql64H%*>{xEBurebZMOXV zIKy`v_(BEV2a@Q!xx-<^Ia)nBSX@0+TDPEubd@bI5Rf^mk1In_<}rBH z8$5Y`A@r3{zmp#?oeA1^wHkrO9p!B~UYqA7PN@~h(*lhY{ZCYWoYqP*ET$4C7E8^X z!$=fr8-@P-t?8+u2XCfY)tvP-)UZukt59X$d(2g|>P~4ntHwYtRvXQn8C7Mxu)M=I{}h#2?C%#nnc6l@%;4m4qT)%R8 z#*+OG{gRU`;?vbytQVHnhl`Bsj2R??igs)YvJ}R{uVidT)GE20igBQ1$R^Ep&BM=c zYah*WcbIyb8&J9R!GN}+)iboqWwnA*9(MX@Rk&`0&K8V%QZ8e(q5$_=20+|wxE4AU z_1vZgJ(+5ile-138tYkIC_-E0&6Z=BC~bRtfL}gbV4SChq_eCq|O%&bJOH%)xpq5t!ljng;8~W z^=N~eYiOH-tHd!grSk2?zVyeuliANE^)^7?OY_n*lf zr*ad?@}n0-f5wl!`!C(_f52=?)00xu6fzPj^5YZI)5{a``$vi(fr*Qalby;SCHQu7 zd?)xIKte!3K+YI?Bj6xFNVUNK(k1_di64pfbAK%sK2qwR@BfVdbN~Oa+K7JmZ`Llx zCisN5{}MKYFp!4-zD7;~1L@^x;_TvROHNP0i<1d+_!5 zqTCl#+!b+Zu)5mqyS#n#J7R&{Lrc*yZg}qE>23ex^7#HEQae6$?3Axidx1DWjd-eN z>@t1R#7;yq&VJ+v<3`G?XGTHd`;v)bkc7fOQ#3pEy7s!(vlc^dtV4ZPE-b`i*|vdy z_hHQmRHCipDa+en9I3>j8f2~%O2PZ+#!Osy(j-BT6(7jszxk}XrMZ9-d%?-Z2R{zIj~ub&nzKeu^2MEY5Dy422xK3RX{cP2k<8qdF* zAgHkO;O_zZgj1pqSn2>v<8WaDd0wOW+i)cfufD4|a)2kNh_($DGU*HDIz{Q8qNaa0 zEo`QgPPJbiKpJKV7sEC@Y0Y2Gmy_TE_dYDBpO~fy+q8=kOF5bfD{g7ZpfQH%($U}5 zpiJn`X7E@Z_k~U=as^tL;8*Zn`h9D_*~E&sPDuUUY)goZr8x(bLhDFkP}Ayx5)*D1)VFi;^C%=H_NaZ3qoG z2-6NvWd62H$FRK4h+d@mwe*4={gJGIxv-n3!of0bUXLg1V&S2=8QL;9L=cB7GS|z=VTs~YN*Corxb6c#m2u19&T+}$ zyXYpVL_HR;Ji?s9cnNBrLAqMzrP=!~T{hta53Ps4JG>yc*F({YO8ht~w;0u}oVLU* z8;QU+-zy-`0u#6!mSdcCHFuq6lYTB&dyYJ~Nx<%lSrsP;N>I{rqe!d3oFd&atTF1? zbU7Y0n4DZgOkIjKTLbnr=tFWpF_v#lDb(05iG3a4Q@XFnnBy=^?eOg_UD+yqA4o$Yv7e;X=M-JE;?94-6o4{_1NLQ*tHtE3>e=1pMlPa`O| zL#k@|&7B6b(g^vjRPadJNQpAm8aB|mBk5ZjQ0+?6$>`QD7d4^mqdu$OBFHbsVfaao z8qOnDYF%y}^2tbTl@Li_Tu~%bTR*lSQf;NUL`=zF4x?UNsX;+}sA7opxU|PH@x>0j zsgD;7(Z5R!6MalBa6x!5mjg|Y_fgWZU@jU1b1wgQnfjx}P$*ZC4D^Q9h7!H_(Q}VU zBk4C^RfX3Sme=SfiA~T`b>A z{0i;6bV{WEJrG${|4V5&`CNJR?AgrSklUh_1BM)38@L#le=so92-+sOnXJBljA+S= z%(n}rV^uzeOk%B)nm73##xdLjTEjF2RsRNztPeH~p%q?SY z!4lbaeJY`e=W06FCte$KS_N`dkp}Elg$!<~m^te>V8Re*cT(7;N8U-UBk5bn8*ITX z^DZVCX<>XWRQTQ4eG6ln(cmus7xQRJq;81AeV?L46z1UFThev2)J@8P?kd!9sC#%l zOeSxdlr8N6bM-#G0brat&M*bG_b3@QKCZ>8_HTtmRNf}2!6uM8JbiX);TXkE&9t6Q z#W@+B!rtoNOt>jh!rqijAM%M9dynZ}#i%1ktlaEY6QEwlc%AKFsW_rJW19p-T<)wB zE1GBqaiG}foH=1ty7aC?9pC^53fUDn6*6;>rf*I%-VEqK1fke&5p6`FVVJ=LuIx>a z<8FTkGQc=i7q7El&T!g=pkYHL~S@m{?N%hz7>pGPWK@6V; zqenL+dC_wo#m{!!Ojn9;Di~AQbx7~9Uh~a}eddyRAtDiZ#gv&cr({}+Y@I#UVzF_Z zqXNkEe}WK-n7@l;VoJU~8tg5T*;T9Tpoz5%*z%aa~!v`8gWUd|r?u*Y)O6rxdz6&t)hvsfz8*pCMgIg-CM@3Kox7baxb zhRBG6-{!M8^#I9Lu`|27kduI}#t0VvOP0H})dHVUIJNn6JC!fWfw7b1<`B!C{qWDo z-9v-ut4m$;SWQ^4X&Eqf8sF3%6VG4wqy>^|-kJ}_p7X?x_>Cs&%eD09A*2@BPk)6T z-y<0S>5V`N7`A;bQC+LM4B9h*+Ii=+D*c)#v=~=c*3|pA@ju`N2v08i$^L4O7wD@=Z7Eq{&Ilb zA;^DHh*Q(E^daHbvd-lXTo%(IC=879hp1ZCAe zvms$Q)e=k7rA!;8B|{o#tkN{myYp;5c=03C5*4*DMYeIjguNX5O)7`7;CiWG$6kxl zwT01sbvJvpv5hCsnkG(~d`KoOTyBNunIJqCykyk@ZspBc|8N7F$i&CdrY)HeR=k(U!;1WgzeTg!uVI>!5?}JzJ^5wqfLvo zMmC#BE&xSU!ze52kLAhcUxFC-Nm4oYai;8VAOz7i$}ZeP(XuF6p7;6BnavIL=l4-+4)~uv2DG;CvVnNo^XT zR^52KwbhC)=1!Qz*u4#U>8D}DyoZL2CK<@Q{{X#CQ}D4Lkez(wTX89vl= z!z+;UUwQW!kCtH+LMeM0Dy>chM##-aodiHaC;O+o%Q}U|0&ku8a$_Ehg%qY@_yrJ3io%jKymF~h781noV>%LZ-(|c! zBzXIv&FOk1%{yv=oZ|+(TjJn!X5h}0`$zf2-16L4J<(}nOT^#$iH!R6P6MenIAtRu z$YVtC#K$f$NI|d$(oX=TA2Cp1&L6lBe&gOS!1M?2rh)qy%|u@siQen#=!q;~fTy>I z7C&6z8``a7ru%}~(Jr$V$O$O#P-FC9xv2j_-?HV-&U>h@xIz7x^z%r56-v&2vFjM3YC3>k;hdoRP$d!9aluwh>l zeGaW=@fhU3)EhB$-ad*<3)xRkcH_W*Kur@|LQY}6B7G6^tgV%sc-2wnC22z$uu-(y zQ@{3j7nXtCCHi2UODsDw_{G_N2 zZ;^xRDQ@|)d6!$)HN0?J;U(l^>6I9z(z?R0TaOo;vcs;gUpTYQ;_WNf8-g*PQeG|V zrXWa8;*)TTH{BeD&w&&4__0hC(CVWfXef^MQZ@SW{l8rGOTWoWr=K{=_H$~?f2^;6 zGu^V(^_+f~ZhpVbK5*#I8i|U=vJM|~;@eYTZ6shv5X<775octIf#P!`BY@Qb8jsRs z`MdyQ6T#`bLf;7XziLh3KBMmT zgMMx#oz(2f5jp!nnW8mln28OSL(XAKM%PtXH$@pvSq1sV`mYrMd1lb0PMN{BKLJgh z=kImxx$I>$F-!*7u|g3I{I=_#BJEZ(+_vBYg$maMWVNe*+KeTk^1A}2));}PEl7Hy zvbP}8;|<8MIphWCSrz{P>1;rtQ}_SNiY!WX+gC>sdEL8N=Tj8pwM{k!XcjdnpWld` zrTPIsGGUyEbvH%Mg1djTaujt?DY&v%h1V;ECQE2{;cg@R5`NIuyt_adaHIYBr^J0H z1{x{|*w=pU!u)JYfDBr5$IK4qgy;q}&(Y&huMs@x2`Dp0Tl!;)@%KYqj9!aDV(;td z#IA2uWAvsnEA6iLp&25T5j9_c;0>FuH`p;=yO1^Tv_T&`aicBq;?M|Y8Q-_s+f9TA_i(m33W8q{v8Q1M zU(km?e_=6cy8Zv;;FR?(@6cvp!XN=XheyA_CJT#`Gt_{K#NR29L8IzAV+CpK0JMWb z>#C45eXf9NM30b*sQhvD5AC3O`Oh2MrCbmU)=7T>^E?Gb0)?F}s`;faYguj$Q0mo5E(RZirBLPTZZ<~w38mW!St zo0Nqpu)tTc(DHEh zDEFNvy-sJPr^*;$rFbwVaK*fMc&nu)vr}xRAJbU$IJFk_y;QEu1@-WBQNxr`AQ-w$ z$^2PL{gUza`RA=^Efzji%4R@CjTupmg<3p3#KJT<&2ml#v@uGC;XDrz-XxbmFd;nn zEK3c59OKG$OurneW)Sg2z7|qSu?cOgv(lLw}dbz|w zin%OSn6*7!%VRw^GimMC8s(Fj9A(fAy8KoX9hf)ub%=xvFyZY9ZdP(DH(tTUA^hV=GGlPWQk8yv}fcHeMlpCS343z9|CQ&yR zO|yqP&hHCd*_x)~%5oV-oB{&l?R+t=jCD}trB?&vLKq4X;>FfkOdR(Nd~E>vSsat~ zLtOlj+5j&Rf%jh>u7m}5Z_s%ZRw+Xb}+cZAa*OR{hOy2fE z8roo5*a%Z~R_!zP^j$3mezj~q%R>MhcP8!cDt4oP%=bO92R+PXAOMIukd12W?$;$8 zQaf+?eH1enZ9q9)@$6O}AEcOUTt7x6A5&l5O(<+ua-kz#RD3_E?6@8GKvI8eEb(#s za`P$me2ZrYwxliE>%q_$<&LZ;hhpXlC>vGj2)~xfLiT=_O3YvbO z>e&iD4%vdUC8ahMwespbEG?GaH&CD=H%g*-L{d_?hQ5Diljoz;e-mzPgWlK{$e^@= zB+BjDgJn5zbdO=w?AC_SeUQvypCaOPSeL475_c-}-f_#0uj4EjaiCQB^_RxxP(>ZQ z5$oA)OR_2>YOdeZ+%a{%flb!>mq z8{ePt&uJq6q&fe>xBdT^*7GYr#`Wwz^wUG6Jo&Wv)EJ;cpJ1OSq<|-+>}!#TN0~k# zS#G7ExTUP6fT*u-d7zx3qOXFXgs+0BC4+PVFC7|P3MG7DVX?`trPg53*4I`lbaYJg zTSvhEr5B1Kn2SSy)N#enPW*q=@&7R0bd+puALG;{Mejua+AA{3r}3Z=nv69GmzJI<{Hp#0pfXSm+lUt zjdgN+nl%Nu0NfnYgm~=Ddg@2zPz^x_hiXrVz$`;QXSGbuP>xNdl!ABE& z-CT;vj1WizOP_=Oy{4}gu}^$eDp%}{v(~}2n5@8@q_B?)%?Lwhl+cFlDf*U2DTm-F{5ROT7E&ywdoqSNBY3Emk!R zL#CpN(aK9I{NO2u-xZaFT0?$jpBa8jaAO8O7i&Pwh^fU`Ob!j}1isqe*00l}hn~;_ z*|f$}Ort1-mzF?+nD&hZf?R~fFNz|?em=ew$`-S(DDW-8r{8uJ;j0Q!x~EGiSLyI> zHiKW!snn*ug-{(XtwYyp08P8n*!jCJ-V=qnB%ZjnWW5OuDOP+J=i3io|HXCxXA)rq ztShq`)c3qCJPKD6b?4W|2b>YlPQ>pB`P8 zmpeuRg-y|F(v|!aV7*6;=&HvjhxK}9d-$17+Epl%ZnOnzw#Q#A*SmTz!bZp7>*I;d z?c}CVN=y>r$Y{}9^rxo4a{&j8?a) z#%19s&+cBCY1iSlLynlP0(YQdUXLMNIMqA-xyKSG3WnE={IQPiZUWJd>iiOiISylL7}+I zUy{&A!yazy&-}c4bm+>RL0`fO=x=?+u{Qh{6k zl)62D5G{k5YH^IYJqy;9z5^=~Uu}q0t}A*cC?hO3U22K}1>dXc6>VWoE}3fT+6)?R z9S|8~{6wA_MIX7sc@J_#o-{?WdXHgZPXZ+nvp{098nk5&oDZU=Q4_KQKhP)DF&AC7k0D2pfF=>ZZ$- z1vr&@GFEe;M#DG$hKJOA(Cj!4tW?hra=?bO;gWIU*<#NleLqo#j$BIaEm%mV?dCRd za$)>L-11I+&CH-3*xGahf%Oq`jjfo9e9f`&rv%Pka~tbgLKw zx`xNYP@Jx{gC1B3ob64~9OOyviK*Z&3)P|dIxQ7H zFHF6e6)8D)k8i4?1+RF1+n1gAI}a0j`I%4Tb>RFBx4KLWqs>D(2~`q=zLIWIR^0gLNJtI-LDF! z#;L0PrV|{MDAy5M^z*E%;Euk#8(Y=)7sQqgxKG4QOK6WrI}H8F%Z*LQCdrXPxty2E zFjxGA(r&D=BAVgV>)sMyL!UEu>gGs7H;^+2CR_Q^+9l!@^+l(iv{0_xfPD+J?sl%M zG;s-IT){$DfxjS;+H6c;t_=^&7WA_XM?z?{>w1{jC;g(18=S_7oMDx4_pLH#N#Rpj zj}~ST^v>JRGQC)J?XguG`0JNh?#3jn`199)9gg@89lW@afx}%cz37GD*CrwPD#T3F%iY~{^if-Gs)zFM*2|n zof@YZ9<{e#cNM&4H0Pp>+>o+{s{hcvem>;&A#fxi}X91u;X0x5=MYiM@>|P7aA$DX8dI93}J&< zIXiqERDoO@n9mJ2n{!92b%WRxmSt#Zm;5aOPM|A%V+NhcMvYC`lwq-@g4L0?8Zy*y zQosQzoE8Y>Fww!zI5`s$7-@Q`CofJn`-4|@J$Ls}!Drtj>6oS~`(>DtJBd$AOK_lo z)$p=A++C(z+X@T79Q~y2Q#h^P5}gXjU-0H+Jmof&T>#JSA{2$17paj*6(}2yHp6;1 zihtURAg`P?4!ffeUz^hqa6lVC_QtS2j{s7a__743B|1PvUv?SKqG*u>MPz+=KZZsj-b;p*5=~Z?4=u%nBAN%H$q7&x|Xdf01vb z#XV;ly}a9S=KR8fefmobBtJ-#yvNdu1S_th#IX5R?m|daYH5(xu1o~ti`_&>1Z|4+ z={VBY3jG8NfZ~wp5Ehlo%&RC-y=$&6tjABbjF z%laR^{tp^1v{uP4-mFfFTwq0=>&qt$L%MTFZ03&#)r$En?h~v|-ooUai_(vbB&lLCgZ`ap5E8%JC z_U|LwR)|U*1GTV1QK{B@YDs`fG?yuxQj(-bi>PhMwmcMkHbu>9^tC=m>565ngKd46 zgEf8<5L^uNFQKy;*8|W>f_kX%LA|=GFFzwFqDOlOwBs~pZxRgtQD}K+$)XwlOP@w+ zG+4%pDmofR#s9HSM3-9ZO3-RY^OcYO!05GjQ@1oYF@k24eZ>!61oQ&jaxv!kL)P~v zz-R)vugJ4CuD?Af-UE!fYKVvJccUQ28HQAK;C#)b9$~$WA?l~DfEh_|)J~}wa(0b* z#Ci*0xRP9Dfjyf*& z!vf%}U-oa0jM>AP_s2U!Z1p<-;Y?yVvTKrL*O}^)wBgSrH;)0XUr5loC06!jmONrs zeF6){#=4VEth~LGQEg?hBd+*h0U9!HHcEwi|47edZA92z5!>^AiN3#BEi<>&dT?yX zmW%glnJvh7)#~rMQ(0lQO{=AN5DYbFh(;w(#z3tWS*+3^cL!IJqNmW zd&d)Td_$e1s{`S!?Ni_|J!Szu$1QcC`OZ2g9;wPU-3OLV1_mRK5JBOU+gaC-I$Uh z$e3|w#1j#^#24Df4rhJ`yS!$Hd0Su*H!viokhC6bBTL5yGU<+V-yN=>Zz7YoVg}v3nXed>zD>cYQ9#7Cy;(Vw=av9Dk)jz+Dc+J zB%V1dR9WVe{+C-gN;U}~`sW9|%&@;xu0PSIT&}w6VQMcJz*u)WwpRkg8BnK@N}3&0 zh?C$hZ4_xvj#e=CJXg#*=z!J<99KoFAJ8fu`(-p3w5*MFN69jVb8kTdvGR9Wut6%? zr#$*SnlCuvu|<03X6^nX^7sE*mV#lb`1}6hC;TM6|H;IE2ywLLHt~9P8T80QIdqEM zK}%&ITg^O8%SlQU?z5Fs zjvvUzH%OxF42L$vv9w`p93nDKmO|<^jO^>XMbE)ph+N}7Bygepp)Y&fk1))IA9lOJ|rW{rhgAj5((y-`7Ol*HJ)TSPG??r_ILlhI_^itCwF^-$>uSIjyyHv}Uuj66wV$R3M z_1+8V$C90&qj5zje+{IC>hr0vx<>VqqK8=3_UI#9JsKM|8*)qacK0tL_4O3&o*Gr<9PDkoBC#s2pa38D?RKz*s&vvJEaI+&w;fLbv=~aXQhW zO*-XDu^DAT;3xLM6_FD?WuSD&5%mMsr9LSb6B|hxONg%y1M<7b%4UDq6N@(@|6EA; zUJUoe17X*@5j!Ag<=p^3vZHBm8=eHxmIHO$wOZAOl*qPW8gi@tUO+$YbIw)!LM~%A zmV*; zU>2Bk`pUGAReUjPjr73_D_-9Z9#u?I=Tgc&mj z61e^x@x;fcH^cW7&WUZb-XA3+e5A$&of;FU3U`C|XVeJVz4%;TFypaPtVQ!iE9%|_ z8;=&f(G%pgR~y=8CJ1i#1_-y%9;Esk?)Qo-Qi7s3!6Eq)lg8;5AY?aNfDri=$GPfjiQevR~mpnc@1%rffjs(>#GLs zmRaWeeyCwhG5|Ifn(jrPC?KlI6pOk&s`n^pHdIw7sx(D4sLd98K&Ez#A6rww6i#l!TU8SE{kt}g+CXOkNw{1ck2Z%cWWSd= zd;CsP&Q#;BD9#Cy8~~o42^awcM%?zVqgQT&Bq0S|r$_z3XRM;1AOc|oB|(a{8b$u= z2C6tIbxc0>vZn<*37h&<2cYI3$7KBK?#`FWHNBplt=@XQ@icxBG&`?m)rcMEL0TR) zaNCd_CCT3ryG7y&8aG;q%?kei(RNPpm37;;uh_P2+eXE~r4l!~CtstT{8*9DTIj`oD>KXGICCDKUj2tiyS8rooAjV6cH!2xUpj4mbOu zUAevlO;QiaB`KwxGS6lH?*98Mt+p3obML|KcI4#hVU}j9iKh0}$HWk<6fq32& zXOVqU@EgJ-E^;7;P>TGKLH$iy5ScviW>&mhMiiDgHh1@3O<+hEl$i2I+QY8B`{*%w zn6NKqm{rXVV3>Z*g58JqbU*CInM`LXB=@yW<3qxXa^J9{T7#0D+JjlKxM?3$d}#FP zF1})MzOzNmdW_C_gHt_lI3>dWq@dAOP)BWAQ}NzKy+5hd*U`|@p6P<+I$C!4=X6^%B2$hbDjMID&Za6z1H3U%>u&+{B7ZJ_|8E+41)N|;YyNa z)1R2=`o|4Mq;ErNLTgaQ2lu8M+eN2ZRmD&G_Mh3srQb^r%pe z@Tek;ETg!oMsr$+>{Z`6$xsYRiyG@e|9`q(WWTUsuK}m-Er3Y+Zy&(F2!Sd8j}Vv| z@Da8ED_y+!FG3(`vvN@+8t1e^J|w$Vq0MxnM11mw&6?l4hs1c}M$crZ;q7J}!6Qr+ zp#M*WyG*N{R|AjWbwUBb#~CnkcF0nWMkmdyH9v?oIlY_7(O8=5VB5x6MutYCrz|lV zC|%fYqS7pN0?{3`U3Ywd2NuRfm+aakZ~G@s^ik(iVzIigYfgZ1yTaVHHV=$#nZbWR zDf2YXAyrF2`%dWE@q-95+H%e!e9y>ZR(d|G3bb~C6$(9hnTEPzFS;%zV9@3Q3XFl%#d}iYoJ72R8H->@$WGI!-;Ifzt6RmSfDa z&NQBW$TGw6y70SJZ-xNT4nFS4kwA_eX;L5-kcx-h=dnLxH-n9l9_A$HtY_9x7Od%S zT*R@Q@O3qiAz}@!XVizDB5k}p7M$vMSgweR0E>lIJ-49TWFj`@h+?m2UM4{>kb1G7 zsKU_*&ZCH#yT#hK4gA!zM#a74uSTpgH8AcHQki8XBx?i)S&K;>j|`enT$m}9N2NGE z8uD}4SJG*1gwdu&GbPJ8TG0=S_p({49=EgEz7J86AXO!6gmL}ajzn-lstr`9YGbz< zst0A-QYcdigl1iB)!D-Yl5OTaKUiz zdwa%|*yr>2PjEGQOf1+O4ZQ{4vaBYxt35FqG}VAKSt$S{uQ-hBhaGgbv4>eH}8@1xe^$e=T5{EV5?=g1Nzs`@qgv z?${c$@DID(+8z+@aGkD%(bc%PPc<3gZt8=i#;(Jq(G1B7J0)!yH-~6IVN)0TzGoc9IIzs-$xu|#1XbbWhUx0naQS0cz(=B@ib^tf zG+(7V`ZSmm_+uyv6XsT9$fj=#WZ%?af`Mz({o{H)*OULn#Ldm&by)`$gH->dGcajO>1_3 zdc>h`6S&AR>!}t`-wGp7`z4k>2TbRskX!ePa4uZfG{egla|R!-1*dRefi=flBOpHD zERfr}!(7V*+lN*C@*m>trky=(xu`3ri>``R97?J3^ixZ+5|N66(eC@OE9yfbIg&YH8!TX5us3H z3JC6UX<)>Rhz$M*b?4X>_4%AAqJ@t3xJeo|c`$j9wP!J!XO+rfD|8E?cEYf-6gClM z>EIav(xe&UZ>Tv}%5?m2H}LUQ?GLTB9KF9WVv|sdF(#5dIhRu1tEi`UgoebKE)#A4 z)TU+&YbJ)=Z*s65ajO#jUkD4dLbTC4A%n02RwBLqb9^KLl7-u?{h;{ub z5bnkt*KLz72_Wr*X^m9Kr18J)Vp(X!IzwkXLQDayqxxPqm)8Ol#ZnMG~F!_!`bW`>wz(miDM zDxd+QU!9O31!!^&N+}G(pqh*g?EH$t(9jr;=yjcTufL)C`nz}c!{KeWAdnv(dLUVu570RLQVO9j}bnsK*K(a85LkS4KBqI#Puz3<$U%DTs@5J%YdQVOIZ$Y%+ zSJm2yDz85T1orcUQ!=xaT`^GVJmmG3<*BcX3gYay8X%YBN>B((#s1Sz8>=uoJ^IT}kXXm~c|O+hF@4X0{& z+!Hi1sX!1URF+I-stC@nKrWVdXcOVwiokjv!NE=<=M9H0F#Xo4}vXD1+I~RL6fhQ z9M6WhkhVDBBcZ@Iwyd0B)YNmK#Fm*3fc^R)RYOy3+f8>20SjRX8BB`rP$`^3^E+}4 z=nboa?d>4og!!qV*m!NV5;ZSXU?uk&5G4$;)_0Fpurb99_buM*{}*_xIAC|mDRw+i ziqa;#u(1NG7<&YXnu=i$_R1WJ+Vpb@(+#{RvAd#2QgeZky)aIZWtbXTQAo27Fv3FTWcYH!V2uh0ld|O<&pyzr6xFG zxt2W}9gcNyCOa)Y*;DPOy&&*d+@Os)Z{uQ7WlCAh9L6RL)nCsA3HGJHQ ziW-DkqbHz(OC;#`(Np(i@l8nAbJqBK-MG;|UERiwGl_CB?4P7?H$ALR{c~cL3vu&; zBGLqikMGVW+wIOQK3*lW6DB`rwn}VQ-lqSmmvR(LHJjs?ZryKwLz8dkSWiP|hi$hk zK}_#CEn;AM?7le&oI}TOIV=VK^tFY6&t3>q)IY5Zux@O_d2GI9anPF?7F&hK;{0jJ zer|(ftkLArWwF`*pJ~Vcy#4|>4iDD>uRkO}GwQ#Dzkk?(wyBo@HXur$0D$xfA-wU6 zZepJtXPs>jzfUfCI9#83;tXc}1cWZfh8USDUd4*!^qU`_N(r{(aANB^_E{KT?7PoH z(VZ+l`S<>fDFh7pu+*}GNGA&JXtZ5$ zv6ck*I0H5w!QQw0ah-fhF`3GEsh7}FLBq|9MQ*QjB1L>8l-w8j8O9gC_R+#oV0jSt z_ou8ApPu>Q$7Pnlm@sd`%Hc=cL{uvP45;t%h5?S5gBY(QG5<@+1!jCXz>uQ}wMGsZ zWhwm6DEY|DIfhQyQ)pv{qV|OYBHr2@1tFxah0C6BbJLHD0kDS1)(Vj4s+jV#?WMiS z^ZWZ+sMnY-pfh!xc_m4lCM_UViGdJuXqUs{4%u)6lah?9`nb`OctN&&Wg#wchd%H6 zj!?Q9+hjd*8ILN^5;7XrWD5dTdwWgmb*aKrIA72}PHLg1K4XH#?si1v@mk9{89$P8 zuC~!`LT%|a+YTJphf(~Z^;V)g*`by|(U_B8gLO3zMkz@ah0pm= z>HOTHZ`GM~jI`eD=e~heJ8ViUw0JTF;M=SrqVcjHSO0PyJzLV=l zP>6*Be3)(d2?)r>oX0)9GD#Q2zAV2k7l{;_7y>)coHxWr z>3Q>qtZJhNxVbGa!8*AlbxObASy^@J3t&AIm5LiP-|ktj<6fn$$@ZP>e6EyOIq_60 zgr+N2-iX6Td9ju!@p7LhIW%;g1AqfVV`|f{xkJCp9)|AsyO7K&{c?`xd~AEXzc2vu zr29)`ayRpt%J&tQFMLcqgwkB?ld9~^88;;y9F>Lc$dpX62dJGs%Fc9KDYKi*3L(xg zV2aea<*0P*e#LTC_?-s$sU{xVUzBq!uDKikWsUSH#F-g;3zZ_o0()HgsH~0hwk!Jf ze4T);mU*^bmAwVkpR3@=`MPs@C0rL}hKhfGI^Nux;HdFuRM;BrWbu{*jv-sma}&C@ zHvof3w6^7SQa;6p znro(R2%-s6xzm5fJ27}^Q+^)hnI3oF`Q7IApTqP2ya40spQ3dD{Y+An|E~Z31p$mv zw{_lNNB)wTc@fC(sSr_evDs0_VIM(>6((_{2nmuS93Z+;k=wsw5^c7C_d-ql4&^vas`C3l#qiq=JZ_DYx0ONQ_$ z=MWkU(JYN#Z8X(!98Kz?3A4UjXfhAIrKhK(_fh>dDYUIR4IKfYtH(RF@O(%li^8C7 zKfZ|&D%jnX9^;o&VqBN-ee8NQbSQ7nE=xSa8z9sAx9;?Afac{K7bc!gT4bYnpQvu} z#};!+2yYq0s9aoEEA5K7d9hkJ(}3%%cqCOn#LV~Xdo>aQx!L2~?A(UCf^5>oe^&4U2kPBxfs0n9#eZZ!lFcZh2L0(TAVl*Y#j4Y4qCMz@$_ zfgwH{h;{jH zXk_gn8&7>TQf9arhwvM62;Wd~FsrAgV$W?5Q3mM@%D|emsuTG2GSUkSykM5UbeZwY zzM_;=@S-$Kem8rUd4*9QrMCDg^O^O$V1Jdy2J>E6C>H#WrsV+D-=#jSmrrAyWM+Jr zh_D#t4eyR0givvN9M^r)K6QtWUh*`}>|V``9$Q69sWk9XHGEzuy4M+hM39wk6lWWa+Tnrf zHkjQlsWg=5qF-5w-*;D^iSV9;n>qTaK#lz*f{36jyGn45uX7r^@;fV4XBAScSxy#Z z2zXcyUZz7QvBI!_@KE!Uf3pmUHFp5MK-_}n-B2Zm-z=;tzy+QeNH2P=<*&ozg0#M3 z7@&g|ee6x`1G%P{2a{lw&nuTSCUO^bf+n5SDR>8c+Kva;sc*JZk1C38+{h(uJ8t~cNq#dN?c7vYt&Z=F;K1kGL_~y_It?8(RmM1QoU=W z`_MV-g_+f$q#j!x?v1)iJmn8R$nriJ%yJK*?Hzeura7mOT%cfx;^Jw_xbjRt1E=pl zmU`t7hzjrN*|ypN2a-IA3tm!fDIJ&rR(IRUD8~bU-?D&Qs1j;z6g3Jq+SSz!-&XY; z0WNNJdEOo#>ijb*{2F5_%&iA3MNFOW6LTSTCwa@vwy!DI=c~%p>q@B>;#05sTV%IY z=Y-`cwf?{BRk27_FwWAZx82)Kh9rKf_o}-hO)mxA0s6!Dgv8GtPRbnX&Bukv8C6DL zXzQjZ33rsuI4c#>NxP=n(!DB>wo9xDi8@!%WfPED{EnqM-k+t8aK84=w%XUGG#|c; zf0`=KC+jfvo2^TvPAbH99$?x!Jvs|7L-7yv>(igtb;(|%BmRg1e(eW)?5CQX=h~jGrrnUh$D|M|SZx<3-*xLL_nR36RdBSm2 zfsU!Qa}gzA^d8Fewtw~F94>&B_qH0+H(Fp zLVo9-u zW5KgM9=S~S=l{}R!ldF(*Z%Pn0UQYb)?og{2DFV4k`HD?6rYK|At1Nzaxkc3y4|(p z=)^{*Ep~y+g&nA8U0z0Ajk@jSA-nDC&|esQ)-(4iktr%eH#AkbPk5-J)EQBPbadFY z1QUtVdgm@;21@8#mYd#%Z7~rl9Io5O4zBiVt;MfV=KO%GDVoi*mWs+LRR56u>y+CK z+-b;f?xc^_9^bdRMK-4Ya-4B^X{vchCg~>s`g~#c-Nt3ow3cP)qRbLlArND`#{&(r zt}TItIJfmu|Ko}?NGUQ|z%zf{RA9*qYBrl!qWz&};ir{=i~oPLneTxa#fR~7R(BKi%7*Vzi?I)l4f9{ z3K-ni`#eJO!Tz@6_A^)AOoNEP6hT= z2PTJW6*b*p&vvG&E`6EnMMySuPjjlLRz9sHxWe##lU1yR>bXc}9~HNg1gFcceidRV zWS4NZY6BHVH_ux14VBAYbB(u&VEf!S-`^^xrB5Q2s-|3e2gI$sU~j8v9$z9NDydBt zd?j&%W{KaJ6S<5hM_LIxWQXR5RQSUjD> zc?qPz>>p`4JjC{EE}7sXkdvDQo)1gIc(7w8b?|bV6KXxE)xW}xThBTbe|7V;^pTy? zIl<8AgdfU$_lnJoxN$@`-`zZdABXA#Qu%G|@RhH{{+JUKjC520d;%-!+YbtH!c)4r zv2c3t3-Ki`pCy3E=Rziff%KN`eZj*~GW$$8W&NRQsT}{uG~Prkn04izRM9F4EU&Mu zl_b#Zy&HZk(#MW`3$nvqgAkSWo;v5`cCyQvpA(T^iRWZw#+N1^Nb^LSwxkZ24ng#Z z{H?yCsmi;c_nm6(gRwxaC1T6-d2R6BFOPZNz+NWN%yBT|Yc^?Be^P2;$J)<7JQZ|G zG0jnLlC}skVnjCbu7CV-2-0w2zb-||7*v&phGguAkSTAgQUDFoBW8+Px3(PT@2309*VPj>BQth92u@YYac}CHx$jP3(zIQaW&`uKiE)L4LWd`FmN}~&{ zZQDWx@kbpjteB`g*8?qjwYn7t{nm}du$?l8Y1aY8*!2XJ4mX2|TYQV^u@LUYGeD_#W6u4O7 z3tw?P=f00=S9s`^0MjQQ3fMPB*_pGRx)}h_*<FsvICanY7##x(-Bp-NX#2UTgvmY9_D`;m7Y^3q5#|zR+#bmE-k|HTr0__Fa;3Tv$ z3p2%*%v~cb+D_y=hgo4U-~R0W9a#d`fMj-K5ez|8QV(*@Z%$n(x!)KvLkB4u$LQ4x zDn5YB!#u>{9)5&N0*R@kBomugMb)E) zajdh?LTH7<+!8N(hpcTC3lsBO_U#_?23cVlrR)zuCu6N(l<2$69bu=y25cRsqDoaMxqAJ0a zMrCD@{q3H4+7b4=`>tU2Zw`RiYZu$tCBHXYRAQ`-IRf{1(w^QeDj5p7r#FvPD|KI1UtB^pt;$Twq>$hG@`=tbY*510acb9){e!o*Rb-V?=-?N}Zp^s)En4SgS{1L)JjA?z`)GAfu+b~B zk2A89fZ^PN9G%$Otnl!zMId&-Pi`jYA6{%c*4}Pl7c3fn`n_L1{XOR3{K{gBd{8L# znr!=3sbL*dY@nucV}DEfq7~&n&1B+9&XR*Bq?WvQpKmX2G$vFZao7>&={lTofII0_?ELnzU*|I?sKXy+-Sj7 z5?%9j$f2q^$@BAQxpVenB(v6P)pAR(Vu&`6~f zvo3`O3H0gTYL+LLKTRBD&zW+y7?8zuS670dKv}X7d~_3-4Hsbs<@vJcObi9E5MUdX zy+V_xe(;%pIvM!<#XiS(Bg8l>QaJUqnF;~bO;(ufI~_<{gv#ndl{Y=p!B-S6S;7VK z?5}xRzN*U$D*|$%<<>OH+o``dNsf+@oD~`m0uix}n>3zpeLYYZ^N21QF$LTt(2)Nr z7V}8_EH8mDQ7eR8Nbd&A3uHHA%gp3!{~0##3dQDq*9?)<7bTYfo@XmBRFBfV2f{j& z0TIE0SGvKVT#yO}4b>7W{_O=!5B|WA}ze zoEiAOC68Hkj|`OU7bv<}w+O95e4}Nl_09|O)#)hoc1;mpmee=5Ijaqo{(K zQ7WG%#Og^$b^OWmHr`k%l2&6!u8vft%`^tPkYvJ7B+Oh}(x6c-IdcyEu-22j05vSk z*a-AVf!sr93pG)$LhFOxu^)tG2>L1uc{}WT%X3q_L--0`NA(fRQe+)VMFSn;tDR(g*=| zOsm>#Mv$S_z9TWc(bvIBSO@DqFcxkn+)Vy9Y#m>lKRwYdiks&5=IL$4m&DkLo}~{g zGMy!tOuqBa=jI@;)D{6Br%q_UKlpQu7!N)PW9*?O)agy5F24`Hrqt82+Y->xl2!Xd zl!OE5clG+nr<&>$);1LCM2uD23X(L3GG^3I66jqt&AnS zjZA?{{6$HL3Fnuxr$h{3jLt}Z?)`u{+h8fwxZ_{VDYAi{j8xV<=W`1LsDR?+ zkVTM@JwZvG3d6onE%kzk9)=pNtNDaruSUNEPyb>or(|gh9&TW3dWpz;P)dUQF`TB# zNYx70ak;*+FjY%!aeJ3v{)qXera{b#Rl}PP*4TK{vCgazSWm^MLobD`=AC4Se5Tj| zWwvvMvE1XnL)GvN%wlI}PP%somVrS$?It1GmbR*93gu(^7cFhxFs>eWuxldJLz^;@_lLSj{jU=ZX@RkXQED3^Gfr-Fg1}IZZFq z8wi!$EBG3f?wug(+Xb|x+b#}$9yl3#BR3#5N9=r(?q!(ob6+QE!A`a9y>HsrdAf|O z+i_I`yGzR3)3hsxk6%VI-a7GW&YJERK9&yrIXe3x+n4nyJ%|(Nv)owHKtT5_ukK#D9+B&HArw%EKhrv%KULT|R54Y8Z zjijx;NIZA^4sb(PiW1z>3e5~-QCY%Oq0Jvp?`zfr|7lY--2vI zg(1);jq(Nh@@1dQ+#B);hmrY7Mof0p-4lFIw?ZiR;)GJS)QNSMMOnkMLD7PYa<`$F zQsS{4tOj%>6icvsJ=fwKF=M!FD}~0HGEc_P ze50gaCmy>{#PzC6w8tyDHMR79rv6TTe-a;?>7-z9-oL~fMZ;Iaza0!zHO)Qidnz#l zdyBLBQ?2RmcnRhtkuw~+qla9ypW40NIomsnlc%jyC#k&wXOc|1vXK=}_waV!vrvc~ z3bA;x)Gq{Tf3pA|*O+1D;}GD6LrGqfW6if?7t>OZkE)x@W0aW%zGDaE=WglqW5ZpQ zul7uPcG^JAF02v<+kC%5=7=?)kcp_wgvm8^c7*mkge{D_&!=-4urH}nXHDeuB{>`W zH!Zk`>~w2YxlmCmCh)m=4O*KM;a|dHXQ#S4cgiIqmGu874CtSV@c8(cybz!?OaQKb z4@*0nx&Uao^v3_+paX(*`zlhBvNYh@eT#lPeST2S@uy^Agh%v`Vw{DwMN|luh6fCdVn1hva6*mcK9~ z#LmXJp%K}%1m!Zw88FP*5HV1JN)}j?nU$QK?p#sF@1vZQjP8KBOHz~3kEk$z ztu_;q{D+Y7&+~;rq--(;91hU{M$3N-8O|<-fTtUxvSGI%i0Hd5@fxOxRGIS-7{6QM zS`u2kXeCL_F?*+`Pac6bg5$Pg3%tLRp&KXr3plp%Zu)34J0q!UbfT%8Ik=lyKJ8~z zx7|tG%B3Izf9#<5EDSBQw`=JJNqDRQA&qJw3+yP2GOa^*JlTM2wgehZh0~(!ykqOa zWmj<+Ohh-V`8wLUn_ZbY$ASc;?Y=3otb&?YK@4{T|2x-}P#?k&;u9_rJ#@w}d0L5u zk50(ku?1}|#>EHC+g2>(h%(V;%&%T3U{hGo5Pj-JaF+aJm$P4@tX>GwWKokwIrU3K zOo$nOwew9>&0HIT`cKYIpUhCVWD5)IlQ;zo0+&tnV{}A**aY);FQ*F^RH&ReW`?}< z3`S?VP5P7;%n3FhFPkd`n5qhvB;^14fYC(5B9)Lc`VeJJqT@9d zNqfsFiY3sFMa8v_8Ta6AB3vDNLqPofV8o{XeyLXE@S&%nOahiirmXWBevpqstXgb#QfSC$`0E4&9~;IEKEB6#S!{hNrg~>znu~`0aB`_meX(bF-;D zX%+^2x1y*NpG9%cte_|Lqxa3@|0OF19B5Xp0~TWqVBqC{EJh1om43SoZbV)l!7syv z!tj)QxoaVK*8pI#ph5|qrk{$7)#aB|n zG)0GYssIr0=9Z3L-_-v5%8Wq&Qn{-~jPwkRhgN?kw>2YuwI>F9c|*+@A#Y@0^^FNy zM}mvHCz8}aXudP#G)z0lUZ3#-^XiiWVW)FVJfyIeQvwv7K)Emka8XNF8JpxD8kWXB zdb9;1>s+n%ZwW*!n>mpSI+axHQ93L14c(C~Vh}1=Om0yO&y9Ak^%SfZY&Z=Uo&9_t zI4%L%U(7)|sPy!GYL|0NY8Hs5W4I8Nz(E>D8OXgy`VlG2Z5pHm6E+R7-?{7Vd%c8t zIUq@WcVt9Zj_;(_sJUrotA|(NN0kUD{^0n7^khZ$$RAHn0XycS`WBX~Jir9o=9a-b zc&WQ*=~|cy_&Bo~o`fh~qZ@PzXj$lbVU7&X7Vnn(Yc#rvIXSMDDpNdRA_p+lqq*?* z=~{XfX_hKk*m!{@)6Tk2qo5Sjpbco_oCs`@Zk)*FlWx3f8nt>%DamV#_Tq4H&);PF zf5Cv&M^MDXpLdfJAS1{%{<%G|Z|O%2qDJ`O5(QIpjMmbT5sPU6#~9>pgdkcbT`>D{CuJU3$O z?i40A5&zyuuIAy+cPiE3*?ST9tLCHs0AKTS*@{$`i!#r2zmb3TpYQ)EfP^cfWmo`2 z^?xSL|7*K*0f=<~gO6+chIN%7;&7h&jX$OmJSIbXH#kA!FsU%30qx~QWfo<#wS!Cn z?)0~x+0^>7u==bk{mylkC#9*{mJ<+(rdeH*kqNf)25Vnv8Kn;pt*C0n4!ujJAa8)H zuXXV$u=ThwF|{L|71eIvLdTx%RxPt@lx>qVu4gdK<(AoroY8K7Yy8TTqB_r3Sv7F~3R1MeoXxX-DLr@+-~-ny zj{u#YJgngs{X&khu*99XpJz(>Qf@R%W~3LWo*dGmq7)6d=0LG~Q?YDCFw57K&O_Y`o5=0GIVLkItUmUT(aQn4P z&q_{$K$gQSVYyfwrIt@e1qRZ=_%t$+9B~_4zt7`-yy?wFp^0>oCmHD_hJIb!(rsrx zd+ny6pY^^CQ`u^n8#N=;O0q3Pu%!Rq%3L?sQ9b)!S^3+@Ie8|NLUKhjfjDbMuM8V2 z5vi|s#VF{<-!^0%M3xBGUwpko+|@k@B}Z(1N##Q%7Fc{O9-N@*8^|Kk=HyIG4<z~yyX;b;IcbZoxc(Bf|38YSe+rfHs`XhLK;h&Axc;4K;9_ZOYVYboZ}I=F z68sl_D%j(#<1H+d@_)gn{`p!4c56u-0AW2Jur~g^Wx3lsnE-ySYPQb%>;U$Z*$aXc zH=hk5)T`Fd45Bb+!*dX;w)Sn8t00oG-F^-JjbQ1luV*WDWOhj@v%dA`leH!8-eRta zC!P3vUek?dhfbYzWkNb1|^NDN=%a7ar!r_ev)Wv z@Yt4IP6TrJc*8QccB^wdnLD6j%d;Da2$VlO802(Xjd$p!I~_Ud$j>lQ#k1G7cX+l% zqs0(<$95q(W&@l+emBQaAqYilH zr)p9aDwBDw6l1QeO7QO_$Y~R~SfJIY2*Fh|?PO}c4Ed(Dcga8pELLhW3j>7_H~;RMTJBzRy}Jm>#NrL&>jL!b!wH&H8PS+)KFcmWE{$8GFqe5*jkUirFs?Mz0Q5 z0ft#yhG3KMRLDWNL&)dg~H**E?*C}($ey|RD?MlUQ z<|E(WztTOyF$k64-8Nag#ZD`e_P2~i%}XfOxWiY8O#ZaM5csVCyvd{w?Z{< zJ%oo&L z!S}aT&2r|2Ms<=NEc>JEBYJ!Eo`VqkCqMs|j<0ZD1`cm!MQr9?ml^Jo_B>Tjob0e- zX@rK%P~!X2Ezt>?*a=s0PkUw}NIE%Y9SU5qKqJf!pxmi^`WiD~u41)XJ$OX^HUosH zmXF3oY_v)pE!(1F2LZ9rz+oA=wBN|1qeiYYrh*2%f^PdAu8QZScdqM@;m(srtt>$> zQcG=-gD5Tmy~Cix(w7yQ)T776!X67(u;J*boqg^lV#%6KD z{q6AOh|68tXtw&mxmMv}eyR}2aMBSSrL(+0==5fZRn6+$&e`XWKbuRf`+I7c4fY^v zIMFZwLH6uLyTspnJ7(>Rz0DUa<4yHP(C+_ghyX3zspbLBiaNyqz595W8q*thV_Vx3 zbKN=r9QVJuIzx6RWQph7k`m#jU={?23&4$^s4lbsAR2Cp&#r#UniZ~nUZ30*5eSm6 zZJwp;p3<*u967aT_tuj}uQ*5g$!K_do4p=sHF zNWTfGw(g?TTU116+q?L)vvXg1aJA&}*Yj6lu}6Nmdok1Ea|E!jvI5x?2hrFkZAw@; zRI(#ArGLINtGB3A1tG60HK~esAC5aiylHiYTq!{_q7XjtqkzLePs_P z)-QT~D+C_Cn)~P-2q6%c&sjXHZ7s<$D%Im(_Pj-I*fVG9rL-w=SW5ft_3jBKMMjv zL={+7b+-Gn+_$@bAw8O)-AO33aCFdQC2<=?6!R(~KL~pJ7;d7|LrDjQd^NC=@D0rO zY4j<9aByld%rL5w)0L~pYrKJDmsSY|lLpjF&_=U@fc4mJH^-Y2WwVmhh1Dz5BgPTS zEqKGC#&mYTDDC_#azp@9XVK5iU=lK&4E`gf98$S`UT!$_^akc%Q=RLAJ7huxpNML< zQ+MO#9n4&dDn$RHS!_&tKz;{HBVxY`ULMhG7L%Ih81T3&MO#gr>waG#a0Rdx4y4i@}HX_^}=8;`vk(Jus(OwwMPC~4jz1%oWiLc zOZUau&qaokv2qHOf+LQZW`@Kmbe&_&`CCnPY`G0frbe3HWaH(-L8{6LUzy+%cHS zgaq$jnhtAUpq1x~{c;Rw5neP27VYc~0j2yT&SR3tX|HY&k-wMyl9;304PYkOXDM{! z7HG+dh9LUjmf1S1(mtyAoRT}IxDAAkz1Y={W^`zlG|N0;t-UBT_DZ{#e`(zk-6Oi>xeqej6?w!pa15`Qbq6PKNr z{}~4T-B592+EFOU?Vl9C1QKBwl3~lDGmRAn=C{5|6wFF=g*F_u@_i^$*OfQ9z{y*4 z_+#92ykVa@l{S&AghE%|P+-xDPS(|@i!2c`p<4Y#5N^a|`T~2#pWJ%8DeA9G4%en zBbHu=>>&gs#X>n2Lf?39%G9z9HItdLNbQnPN)wGeiwiOxE2{yaswag8wVwJ@VYMK* znsWXTClFiGJe@eFTv7MSvfj(nQ6h$?Xm2-7Rvq4-?M4mlbz#Xu=P6UfeWIQ4+GxU8v=Dt~D*`uvkHF1<4zX3>xv}>In7t-gL|;k}=fP zSv0dbGj1B#WtCGD0>VF6`-4TPfXyoyp$6^NUg5kp__PrI~jt3 z>=k5AV|GQ3u&QXLZbdo6HW&LVPjStc8GnCpc+Xm*D4FC#bL`t2#y6DGqVL-Am){#h zDbhoKdQOh-69TrtpiGZar<3f%zNZh@xp+s$LU^@tMxM;(t9Of8gNdZ8HIu}ap}EsR zOPwEsfPJc5{|{MP_+_#mQN|s=Tr$ea96S+92)DO$qezdRh_-ynv*)Bo;oVmouro^~ z>{(kNh`O0hTas(y@19_;ni=Z+u61K-KdoT;n#Ocumov6(;8$Y>kHUNjz<{`0GTK>$ zJ&T|c(r?i0*z-@xtc9XLeA@90(^a__Y3^S`b)FI}6))IO1T#OA>1vyP$t;4W^$of~7d6w5OJ2oSkJ- zM7o3i+-{)n`10J!8=(KtmJfiZF=Q%@1lu$n}4RD*8YkN$1^l!9Dx#)!;Bscrv8R|N!~v*)|;?jU7~B}N;d5n6P9mEH^| zMq ze0jJRqH_wc*PBsgidd1=*3j?W>9y`2KM-k-H0Wz+Ax$X#Im>p$9#|txGea1l&qzJF zW-1Z@ofV}YbJ6t;K|rdqfPR-H5zUj};7*rsGSYp`;i-4wt(}%|RHLtEJ_F<)v#)J> z8TU-zMCi+}Fl%=<>nL%P;JUPU?!=yKN_UF-*ROGhq0c)+Him5^b)rM3J(I`qX^@u= zsvx7mU@er#VqeW45Y0%}VkiwAS34=*8C*#^U2)GO-2T1ujayRW5Q_xy=VIIyqNuMOXkYq@vv2XpUaHZdU7 zLk_Pzc0qGMc#41&fTMX2)!Eo3U{OkT#d-VS;ZXzZ0#Xxq<=Vk`fyLt@p4_|+KPKALzg{FadVq!0!_Pi+W5DW zR&t-r^coZ>SPJ*2M28L=c5SW@-M7#ztc#*MsM|z7YTz=YN)j7iD6=+F3XGG1lCRuuC7}-Emm+)edf}_g25m2HYLbN@SeT-m%D_cpy zZZ2!f^M`#|7a%C5=ny}*;p;!*+D_kEw1T)Nf#^GKLH>RJ2BSZ0?Tu*k^&BOqxdE4k(16hX8bR7 zs?^_B&i@~WI5#4$y+?#HU9R-=8zN?8ocHbG;aV^A=a%hPt@&hmMy!M7E-0v%!uBXZ z)&0;e$q~R(FAm0$3gbQ+B#L=rF_hp~)}87) z;DC+y+Lqj%;b2TVL{&HCjMoTdH8l9c$C8s^q*I}tYB1!db9|p|2{6wh2r}xv@eZ0j`8S$~*CVmklftx`Ncb#>M zd=zcZui>*1aHEUT30-1pmG_MA!gqi-RBsE{Xc!oalRMAS^kt7~6;{334l5|*e6*NE zOj6DCsc0a4*c<)lCbNGo&{pD?ldbQNUNZWBt-JpRAugf=Y}VOsS3w_nrJytag%Ee! zO2(-EL5NONISJP7Wd5AO#a1K?rQwd5d(KzQcqZS~XA=5(bfDShY`eNkbF@Fc-g(d8 z@1Z!Z-MHSN%ts@Dbs!x-V2iJIq^c-;A#IIic7xG6v?O}<61PSv7VE}ZZ-qieZfy>A zXzKL2_bXW$c~q~GZ7OO;nb+DDPE1J9fq6c;;XW$#KaW zHt8Q&aefOj|i7r zf7z=C^LCoUB#cfrEHc;(<@;duINCx^t!Ra>@QjX z{;$eV6-vs&y+h*2sI`fGET-0PdWb4agL~?dj}d7er#fn*83#7j4PLHQp&STY`GX^U z+L!-nWYkfBI$|2ls~VbKggPmi{U3Tby&Q1z4?Vo|pT1^mlQj8<9zJ~2!}|ZFhwLw& z`+(yI18G&}^9Jkc1$%8O%x6s;iYmt>ll1BA_9I7zo7oKdX>JaIddxoP!IyyE&|KE= zofcz*s8Nb+^R0i;!%637CG7v39_IW*57D%~=^@zvgC2VSw1L|e`G3(vt!heyP$&7+ z|DcC~nVpO*yv0G#f9^nLr=PLyLc2y;DSgPYc;ItvmtCp!ekzt+697{TAF-?l1oQIf z+-p|0R=%C+3Y^wbHEI)wx7CmakpFbZfLm=NH0mos3&!(c(H!aXX23-^{Bw^@o&n@O z^?K0ryu!S|ea_cAFIqM8v65c&gIY4yfv(LE?jL%nlpH?S%9S4|Q4R_Wm8O1Cxv9eg zBMNe?=2$nt(`|e-N``@zkQJi%b2pq9e}gU>Gron}1seV}!)O>ykmtq| zC}0hj3Dv#A`26Gln;za+7NOqYHW>71aSc7t^#*5wm0GJPl$mjT#^{^-a;%jkpSovv zFoBVsR5D13ai>_&M_2*BGF-N7SyhNKf_ygMFskSjx3KsCL)UK+ppuELGR-&IctW~3 z8iHOe%|;7S1vErDbIV<-zt)Kol2P(Z=Tv~4I{;Kh?liBG4d)@K)d8|JB+6YQ$^W8< zxc@^Bmvw?!k8*tfO%J=Nlph#w{eFpl)#JL6CzPvynrh>xgj>K-yZ$#lyh-x>>pKX` zR*qb#FOnfjU4bUEDbpBziO|Eb16Xo2Ii9Ul(S| z57#;|Np+T7H+U_)T8IHVjhqL5={=w@egSaw>khr~V{XGIS8I)-u73@GoYB&-+Yu$9 zBqmL?C}{a5+Yaj`9Hy_2oLiNs{?Q?|-MBN87Ss=T^z2VqcYVSqnv^VcR8it@kv3a{ z<2(SvB9CLuC_JS6|W zb0ha{jlj=-Lh9)?Vym6=o8aZ#{Z)fjFgBI&`0GO)!L+ABaWVjAOn0MM!@$vZ*Z$%) z7?}gjLgwdp=Rn{9-EW8Eu!2is@~!>$(p3(i9a_wuqPMzjw#Xo+e)O&gNdSs4d|;aD zwBYR2ukQ7aVmuAS+jW9@&h4v-Op&$|}q@@p@T>X<9OTx4eS+lbEYDQHphZ zA3yxHU-#Wz-RRo_;S4Pe)UB+tci_MhTgA6kGlAyx4Zj=E7(MClP2|{DCi5pP_9ybi znDv%XfpHu@3dkfmCKD4CG!>TP1|Q({<>k$`%Xese=fbLqWy|`+LyrWa35PwJ4o-? z(up*Sfu1ubIKA|zg_-&@FWE8Ej^mt8?N$~b+$80I(DWsk!@Ac=O_e}ti0J2`p^nE+ zSEb(Iq-zC`1)HZGZHUPzVlx%!L&t7JI1}6T1u8vahjw5=e~Lm~o_z5gTWeZ6ac)k9 zxXe!79&Wha{*?)Mh;yCear1jWB4JKgoYia8gW>ptPiC1Qdivh16VxG?$zQdRowgin zyW%GwK-qx7rqk|RhXqIJjs-JD=@YPix~;~FwOw(Tq$RAuq6p2uZA~;&x5Y@#ic6>_ zT=RrL>i>2zM4g%pAco^*ST+P;Idbn2ruA`ihVOn7AssgNM{j1I!>XRQIBYXRlnb_3 zJs|ml|8Aq~?o~tOHoVdGhK0rM$bk>Y+#HV0nJHd1qEz*%nUp)u^>_Pq502h2y7kWT zh%}%UKRHVO(!6M8i09tCD?V)yYvh6=i)T)VDJ0_`&QC9U^)rq1klju0D!DY>4~BaX z_WisMuRAnLCE_6*8itKouNSmhA!@the3&hA$e(2qf0FLs^sqkV%#AcMO$)j?QPHEm zK^YoUVgOFk-<`HZ%zlMl9Ze&u>y zQeSDKPSpeL70rF$A>xeL%%a^dGTyMR6LM9cy84onx=hcNuTvWbTj&~-_rg$~M>PtL zX2u$1u&~jga=J;gz>17ac-&r8%3*$_Nz->5fQi@h2vCl(ctvesOifzPI}J{z|5Pg0 zN0p03M`Nr@<&Zo!Kz-;-7sT1I{I@;S3C-n3gZ^K8c<-l}Pv~)eAG|yzz_o_K#72E~ z$RhraJ^as2e*a7Yxi;E)Qofg2hTrM`f2ybdw>w;n=KpTv2rs-0`4?7@zXW9sM2r;_ zfnP`;6j1C;JQzDt2ncgwRh;2u^Lf}d2$sL~Q9zLpAeai-1kD#dYMDA#@~6pzL~_gI zPoQczzBUUGUCE${#Q=dp@0LW#(JI7vpOoefuNd~AvKr#rTbU)24NsQnNCO;tR9ax$uP5*Yr1NrT^;XkS*kV;-kF5lVasq(H!L)`vuh z)S~YBlN?H#or1{vlkdTe^tQ6FyfIkZ6E?+0`^(wx<#3YM#8%XRJW;ICZ$wK; z-qsZq5oHYK_npM9pq?(&m($EgLvb*eky@M(sC!g!0+l`h{RG1jg7Ul@qc&o)rzWUj zr?!44w?rp!#cK?(q#5;h1t&P%htdP|Kr{I+i=F89pi( zHSz&v3YvcDPr)cgHPp3IP6(tf>d~c(GhzXUlOp+(<%^}NnMS%%%&Cv#aQk8 zrz)}RA$J#ZxHUDFAlT={+@$qu0FFe7WBc;+`>zzbJZ$}ZTR4BA)Pt58-wk8xOzNpA zkof8{V7+obBh$&|V1+KIJUCr#I^&82jDvv{4{xPR^mbf?90I{k)G%o*52|BZ3TKP8 z4FH{Yd8t)1MwS2& zZsYmKPO|35;og1ZlnZSx&OscP%|la|3LXX=b**xZ_Z6`D8nRwp%(doo*WR{7>-2tF zQl4s@G?8Y~Ce2xy(LV*2i?z~+9c>b5IdY~!5QC!E^H%fC2$rIp7M%VnN9YU6FScXP zAd2rzG`5)EUfT#(T|k5tu+O3qQv7}w#+CQhQbN>rY}k430B7t~{r(ong6E11{RZhG zCs|a>a1D$|Ck~#|rGq47%!sSLTyx}W$nQpY=La=%FssHsP_~8}vP^U_S7=}QOFJ3B z0W-wv!SouU-;MMNvA4azhDLtz^WssbD_3_5zsEsZKym5_#c7H;td^N^QIWwYrxNc?FYknyc*_*WN4xn4JJ| zq>XM_GbYzZKoDY0_qx3HX4H`dgmZqDfUt1w(mYB{Yi4$)|U-8 z)CtY05qLm3G%UupZjI;;FogsjO79u0e`1q&^|Qu$Peql;0fCA_S`S^EN#AJ`g;0!3 zQeDu}4X3V?W+mr6IxO@~A{`ZJUm{i25r^Ee944C765LJPqDEX^dMEIP(H`S$O^|^AB{}civ{N%5*lJm3YF?|us z{fpUI(Pk&BZ-?7?2f+Wtv+ZMGqf`2^I%U=7FnwY1cikmbC4qOY_pQ^hU6r#6TpkZoI-c z`~i-UDNms9Z>KcDOj4`V5Eo4xKo<%&u`?1$3`7D9B+=8y{y7TDc=(GvWM63h@bPgg zBV#H3u~>TBV#_LHjYYa=6f|LNh}TT8Ku6Nu%6()dPzbs}hV82Pk)7;N)@J+d(qr3e z+u-hE)uX!ean0gO{hvo34euwQsWCfjxau=(msG~gjJKFgyXQ1$Z-#_7{xMoq+@{12 z{oUfBV%Vd{$ELS+3p`uvaw{tzI&V{akL`*s8|0_ByT= zkB{OjbSBM(8u5`L2k8$S*MeIXO-oXD#%ZIm(CMzWDvxJ$^U;*H;4X_nEOr|TmtVej z_8W>m1RiN>-I7AbE@{77c?Zxl6ZV^EEUL>COk{bcuYzZspv8{Ee+PJ;7E#SOI;}2Dy z9M9493y4H#vB`DM2 zp1rE9T^2FDzQO0Gb&?j|5z{7+f$-38InIGApex>bhmE{_vOMNOyUfQ17~VS*+YNs3 zGWNu1yy`9mzTE1+86}l%RpYd)$kXc8O%SeSN0}5Qo|KzGY>hP{Bod)Hvj= zx)2RW140*%j!IOyCSMUUlem4;)PD3N@;4qsZr0$^qMm+Yz?))qR%eN z5nV2`axHHqgG^3m}uC&){cI0 zNYpWrYQ=A5<|aZ&%o!IEE0XUPn4RKCNEg?M%2}(LKL>YWSwhzHd5m*2$8~h2hi;@z zI(XY5xYk7_6|xUxe5^&}qFIW0h+2>Q{hPto%D+=)PH0X~x6vc^X#VxbepQc zUZ@01nPieQ)}r8MY=}n3C$^NCFS%5)S6TNv6k0-Za8+!zy*!pWWjF|-8evy-2@_#_ zUsURHI_1zet_5&BP2ZGPejN+ra>SXTQ~6b(`uXl-lctln|zz4M)e ztjEi0q>gtGy}wuLt1Sk9<%#yNPl_uzc_@p(@#-pKjjI6A9r&+ag`gM`2X@R>W?5Kq zjE_fz27^J#xoouO>_>|vKsX1BxWFn`z+ycbiD~Jxd?+1;SnBbnj%MfHZ=Y0=b=c+K z?a>7Ku-7fO@q`C(*Mw~=M{r*;s?}c#rE+_P7gMEI&)z@7Vng)qZs1@XJD3|GZ*#=%bx zh9jJmpLJL80r-=q8zd8r+|4`IFE^KoCnlVRa%7Pr+s>Coh@EpK~Jn@@A#ACs42=BYK&k?^r)A=K%9IdQ*k1m%BJ1m9T!aDYJSa8jq0?m zE=7rgmN&WAl_q~8%KSlt7T(^;hgX4@3v=W0x;AE4Iv z_go(r;vWE?MO{cqf)VvBu6z9N0B+=bz6yMxUtYcpMZOHRZ}Ot z2v{$@Nwc)fBHP%`@(@*fLgk#V+A?1w-YS+#x(08U7pex?uJB%0xgyF>?%G(_9a-b5 zzuc$tpIUHbnKaDx#3Lzm-__Lo9MIfb?w931J zm7fIUni>dy1!k6+5+tFb?JZ9h$4hfc*uF)0eZd3rxu^GdPb0c~K>24rgHW)Sxb%dMKngLvcx3y0;gDgnk3Y8N$m)j^#@nSOD=P#q_|3yL)^0b1k5^m9Jx$|A zarM5-q>{;ldtmm@O?@9&jUV*I!eNUP>|pk=Lu|4A{rQ; zZI1xKqBxu7LBrtdnQoiXu;&GjdMoq4GCn^@tOa(d675%X#Gn#$m6BBxCiGq8YDcoj z9z7I}YxeILhRd;&kr@g21Suj*QEtl9U=lrI*Y^+KCr>uLm=$jIU>!Kq|6(3XsDQ)D z%P_{&_H&hUAba#kOXfAyq&-nmlFMeeNC(e&c0R78R;eCzdagtm@lEDp2j!4Fu^)JM z?L2!~SKVE7B=BxYq=_y(y%~hvYC+|@dgZhSOmvHDm7-OY#itu#HNhhoO{p;_HRO3>yXMJ7D8gq1vO=GQf1 z(wrfwyzfCR77bp}>4w)N-TmzCB z@k2jQJxn75S*<|L<;L>XSCLVNKY!~WpKpq)Tc5CCb}_tb$UXzA9gPB2E5_Lov~T(e zA_>ToL7E=s*ov3Oqj4{~o#z0%2lCZJbqVESfR&^mI}VA}=jN0ts5O-RrjVPb{2|ZXM_^vysT5Ou z91o*O`wCm2ux1%I4wZXR3a-jHpQ8r$;}ExY+kTZ93)F z=#PvaqtZG>NqLe9@*+MO_8 zLLT`2w7Cy!!juY#XVOD}GIU`|xzkXfij1xi&tMW(^TMy+*`R+K-0K;2ga;cp?sh(d zly!^Zz@xYSm>A~gz|J8^tDh8#Gt^QjO7-|5N=UCDJ-vDYRc4wo(l>J99(r_W6!1m$ zjm|mYVnbiw8#Wgm!sA@j+}0&AD}Mj=z26F0GQx7? z{$i-2kKJq|BWoTF;8Ho?DHB$(t6tuN)z%>1!sZ~SspWOCKi~bFZfDnSI7z;wr!QTe zbpV8A4EhZ2&Fa+s#Ony7BmgG4G(`v?t~=KbS^wO?GPqSD4C_qeW=+mT{gdjiq2QmQ zP-u{s5Z}l|L8k!2;n*!jBer%y_k8XIZ%w!xciF!~tfrWzN;&@!$RERZF~*6bj{K-Wtj&$sNC5!OTC)94$n$y&l}>OWD9dg_a$6W9 z&@;q3+JsrRDspU}{m3~xsFIRN=daiRQW=;Y1pt%Mfb4aUOG`1l4j*H^CBilUmuYSg zWz-HzIj34H#QQ~gzbxI4W z?g$4`=u#i+m8R98sF)AiEa5t(Pw~fzifjydISbX!HyccKVOJw>A7>Ca!2WKRz=kqz zUIxEQo#Z2Q6EF;}!rIkNtBM!L zTI!xu8&s!-1qx~k?3HdrbYg5(o3Mp-iY<^1BNj3&8)-27W=B=6*2skoXWS@fC>p*rH+oRTpG>l<~nYegFd;QWO^+k(~C`W5o@7 zrADQo3hZ3Xg6`}ys<4=?y`_B`_mzIop+D+fPX=FMx56k3^3?QGqO8DTKf;86V&^E< z?Nprv>w$7~7gxp0N7UGsvJCAW$Yt->Vl>Fambc1_`h(7t_|PjTIf_=*ZC%!#h?AUG60#pFDT*JRkCL?V&z+~lTMKUcKo@DpPvWbF z*_A~>ch|vKr7bV_+`w&05|$XN=qWj(qJ2Tu`%y0+uw4|(Ttfib5m=Ryfo30-a`U|J zZ&23j%Mw7eIsrD8E5X=4s~WLRlk;c76#6owz1i8I*eESZ|H|CN0h$SPlwo5n?^Xy$ zIL4x&Xm4C<-eivOCdukU(obLEun9vig!8sIg9gzzkfcH%CS2`Et@CA_!O>F8_<~O$ zO*wTIUTv{Mh)X)i5Yu5>$dy!Vi9S8|8bktU7#PbtAp<;!g%e7k1F3y%`^=S_#S50q znL#5tq`JYPT@+5G^`|5TQ^X>cRwNTOGv|UJ$AG;n==6-Hap`Te{J6G{u*|%V*s0WI z)j!4Z?pM~?6!F;RLDHM1R=m zv>Ms%tz@id7s=C*3->J=R{ee4m&Q>IF7w4xGMuoW>wcug$b*Zp8L!R2jkzqA>jW;B zN9?ov)xUhU@@&?oRhNAQ%yUwkEtqRO*P2Pijt=6^p3J(9Ab|$csm*V^`O61i3vb_& z2(iYX$b6}s20xGa9~mgp2Q?5U@%JX%WIg7{bS8Te0u;jJ5f(BQ`>3ilQco70GsH}H z`Rfq%{SfEr_HyE(!}Ge;3xlHUke3;59A=`5D#jKh&F0J+s+2KMoBx=?Q-G3xX%Iii$9mlK6wT7zO)T^Z^i!aBWhr@zVW?1xiL*FpnpC(&rT*^WrPs`l6{zsOW-y>GJy1=} z@{E9#7rZ2-Tk90zTt|{4&_5hfW^R3KU<|-ZYCOn-Eg@l%^O?u&NX6e=y0+>i^cJB; zSXg(^-+ax^0M@2>gFR!)u#iiKy#EuhH*pS^h^Wb=zNPCh#=9)fH{_g0Y$ZS+ls%uzr#m#HTc)} z(A=WQ6)WqQ!>dS)k%nk}ML9lIB#9-pgkR=FDI~A5tEm%RW}~a{Q9NyjFbnmzBVqrl zRM0R%)RjV`1h>e6r1JSEC%ygNeOR;Xuc9t006H(6g95<$H(hxB{P1>NwrS1@@Rm#- z_bTWHPBM%e>7rk{M>Jatz-f47x+x_tMKHXVe zUR7F&~6w!=nAh=`6RHv0RGqaD=DA zoF5j#YEX*da3@1w$)1;XXXav5W1qXBNplY|dv6S#Tu3csKaCRq0%)Q}_X$;Bh*lq5 zh$zu@@b`(g!KQ)Xhh6Cgzl-LgulRH}S!0%z%!WOll5IV#M~Sb4fsgv~2c zrf=6P zl`zOu{fI*$s9>c|DO>0=WyJOxZW0BEL{zqatlub9;*}jBMPs2~ujUsq&AE$U?9d3^ zQ#+`tN;a}=^RQsWo0NtaL{4p5&aR#%RL3T0-e@#Nxe`K3YMoJ1=Pnzp5YKWds$%u)CS>~k zIr)sBGH(f`t{gC?g_uem2S&tD!{XN-zk+x|FIfC!sP9E0Ts^Fh4XMK8=ci~ZiewH( ze8rSy@{Y{u*3tkp6rxoNxEu#4)<7}l-F4Q8-hCHwsa{@rYp?fPJ)b%&cdvy5XKa(0izv z&*FTYQjR~$fvjFBQ5t^R-s?v4wr6C6YGZpi+N177LETq^nLi|1-kEZ2WY~HmVTBI_ z5gNL{+_*XF>(k{S?JVAB!bA95#kRc#=Z7x!UgfrN_fJt!ApP@JhD5KMGcljL4CRo} zCmRt;e%)r+s6WUakdDRyg1rDf!o|;Qopn)7RKYF@ru4#zKd#z%1&{&74;Omy4MA3>&6Dj1!oHT41mB z6i;tCoUB0Vl|AmyWylpv1)Z7B-FNbN-UlL1^K(12gRRltyKmtg7bhaw+hbLwQBJSt zWB@rdl=~dLXBO-pVVLjgk!HSTe8vUdO_%V7nA?4FS}fgH%?j3J*tGt^cwK3gL=Q+B zh>~Zf$uB9~hMv>|vR+1?0uTJ=-;}G~1+kBt>c3^)3)rHt*ZDBCAzW`IpAH{_zH3|u za9Er}I71p7<8;Q5Dv)r4zw+UyGdmOWJEE)0i~(O9cY}A!q-D0(z~fx&J7%p?+E>(g zWn;H{n7k5K7W8_X$ifvg@I@~+O~)C)U1qY2Uz*wuVBlmEgDKGRRVPA^5Q81$zJOey zE~o^-Y&B%e{s3K3QH^c~0b14~tpKSC!||sy_Hjj{8vIvY@lX45RX&&uYIg{Ur!2A03%E9T0yb2DVEYJ2U6(&yWd63jS!9CtXl8W1c zx|0MFf4!cCAGc;KAo97Ea-jdLYL9^`f-4pu?l=5WbCoU*ovnm#ZLMHY_0Y##kG-!$NI+mX8!fZ%l0$F zZs82T{}BBJ);UqBdy$156EWoacgEFn%3z;=1RN9L%FhS2t9hX9S!i103=F<2VuXh^ zi0a1ZPzR^L1@W(o`qfp2znd-;ZfsTbBB#m=K!5r3dJ{g&!t4&h^7`aj{d)Dfxu@D! zr`FCsnLL!#63#qN(2Ms7n&siL z#giEK*k`!vQ^AXF>z<+0zfJKZJmg6|yf;n3i@z5O4GWeTbps#?_n`AP<4Ubrn7p}F zdsC0Zz-kqHOPNJ9R>DpzmX?FF?pUAP^>ouVEeOxYOYf+D5Q$s?)*O(EH<|nvGHI!s zfj-UqhRDY!L0GuSMFwSlgsrV7k1OA+furaQtt-;GQGMq!`ijF@G3jFIX9Vy@^33Xw zK#U#n<1gZxVpF0pIJ+E*2(w?076P^M9@M~5r49Ij;sRKU%hk5;r0~X7?KB6yDogGA zkVW^fVce3T*>FsHQ;+mu^oV~;fX3?%euK)6Ltb#|sM`v?JLTY4r!7gMZ#}~%E#l*D z3PGNG9uw_vibzOB22Tfmf9L>)I&)ig=U-dWOr98TtN*jXGrJw&IvlT?f+LG9mH}B- zogJRPmguIcu)Ajxp~z6c%1A8wT&0(6psRc%CL1jidXrTrA^gW(B4<7mKX!(MOA z7Tjzt4sh=>V5|YBV9rm@t?fQuJ6m4~wGyw+L#gj96RxT&USGIQz`H1z zgdrv-n}~`rs~~FYg77M|H6}|J+5z1>Pc66caKZB71UA>qS+$t8TBypnl6VyG(GPhl z9~`>bVY$>AZfoWqr1}QHY)A4ttp0=0MHwgOtY$zXW!vYQ>MwMR)aM0}oE@w3SL6sMJ|ct1^T!OskMk;3LYQKWi^ zt2RI>f#dIMmIAfogyPj-<>kHGmA$Y9)gmSK_{*|rqJobYh@#C?tSSP5@fI*@1k>4O zEkOm8SPtV+AIcq>Uv#=6UqT1g=~O90x9FdoJvpV7gaM0kPiBVUCp;H0?s<7zCvsHg zae~@KlA~^3M9x2wULwZ{Lr!C9cd0eBq*R}9a`hBB;gDq+>@&=Lo6u;hBB_&UW-i@8)xlMATnrfPb0A_c(3#>PI7iwN0403{dSgHhAs%&8kvI%QGw@@zUNUj z+m(C6vgC_LsN3s`6+N;mBvMXVr`ejRm>&~Lt-39{UY5bpIT~y>ebM>~WnrGAG35Sa zKcD%vFT?E`DEPJUkZbT)1!EZ5yK}62FHCu2e?C2H9J+O<6;i!K*xVDb4Z+Gmp;E{GSV=-+_jg=TZ)CLJ93|zjJ zg8zjeR`3C)Lch64dk`FfLMsIO$_go>t3acPpHjtNtHQ!U+T@p3M85W{KmexZi;Mx< zNBM~9k!2xAZWo$keu#BK@h7f{YD0=Cot=dor?{g>X?M8QsH%g1=H}V~u9~!tLIS(R zNglkZ#^MXAsT*{GmTf_R;L6bj?{J>Z8g5bS4oBLH3FHbk#C{d|egLI8x5W)TeYwDc zhV|~lr$N(YeZ@+Ih}!-)?Y#sVBDcVwf$MFDb-PUmv!l~%jSwx&`GahSmhriMZo8iW zm(OJ1rJ7{1U6durdC?bs;Oi2`!K6gDX|K|YEqA)CA{sQjXg2+jCP(f&vyv#yMZUG) zOc>0(eNSK->Ld~F6eWEX^ip$oXF(QUN(69e8ZYMLxMQuysOnxN>abX^ORkEETVP7E z%7=t$-|1g^I~_Q?_jR}A@EtTXhWnU@}&4Es0EC*TK7;+mXj+i95UBZ*UJ~ zgmZ`C%a6f7-2a}kU}&3DWleN3EM}WQ>niXZKb3a-*%5nr_KYPbScWA2+LSSmpgEVO zI1$%wm(lW{U!4@`LN+?0D;4;3DNi-V$A6k{X(z$ja9Obn4^lM&ZuF!0sgA0mI3afii{u4Eo#hOVPi>1GT0EWz=AkD)^ z7B7Z~1&Ka-@VO%)(pY<&!%jpyCtm8l2pv7Sjns{+W%ZbrQ+@ei-!OjfWG#YfU-j1k z4rmQKZb+Qg=Lhh-43CPZe{-m0$677ML`%-BnG7Gd0h+#}EL2%NT$Tl~a%@F8d9c$W z7ycb_zyEZS$o&UUdq>97sJB*b4XN-hmGM@;Rk-;D_0&PmP>{H9^i+$2%g#%|9P?Py zPk-(UWUEO?KPapE!J0hvN{|{bu!}tJ$GsjAVSFKg|3@5eT|}}&ie0}F?zEq?+U0Qz zhP)+MCwXrKW1-^Vit{%UM6q!FDNo;Y>O>JQzHSOJJ&6rBU~L?*^tBsmG$9VBTR8T>V~_1a%!H*TtFTn!;vA0*C6QQQ~6 zi3c6QJUw+I>4`I(?D;&L0u5k#dbx-SFvfIiwl)Wkloz*cf4Cm27#XUFm}(|-!v+Eb z0(da25BbsWj|In_ma1>XE+cagm=og+5+=7ZT3T=RuySg&}5*9h~p`AVU^dxck zy>n;r$mZdNC7p#0(&3&@-{bKoRx-W$Uvms?3Sm}k z$U^+0$H?7xPbuB?80K%O_N?gOcFyqcaHjn`x-tv$4YJ585)NH6XoWy+?s5uLZ0=IC zZrm6?Tw zDz$!AN=!hRqUDjrOMC_9%}vwYGb;B>JpJ)iiO^cq5N^X*{vf34y4S|v#&;VC&;JYRUGe%0Y8%|=*H#3B2|{$=@NNPyHY=7lf+x*8=5y5b zQ}31U_c{;pv%A0hhY$AW)Abd2)oqxtwru9X;bAYSA8{5gP9}4hq=fA?ZVYMM#+cTA zPMre{;9xV8%C`C75Uhjknk}m#%&u=~sM6N-{1IRaOxI#40}l`JTtM8MXmLPX1?t0E z@1D{mK}{XnBw49H5Arbe`fcZ&Nr#Ij`E(LD5AHDFCG5MLu$E-R?FU_w(5lvLQR;5$ zTgO$4CR-NC8<)106|RuiGo>q~^%boo=K~(5hF;e$MA-Y56MKolZYh*_GJmzVNFn!G;ypK~^7jR{_#VEwXL3Ld+bnjXPt zfD*o(m%xQ_uv}RXDRZ&p;P~3(!SzmMYHL@&O@H;BjjVKq} zpB^8V`9$Ch-q$Pn&+Z15PJvFPg~uL{#!4q6>B@&7>@Cryh|kwY*a^Jovpud@*vLK> zN8BgFzTXb^i?aSLb|U=dHp3mMKR=rT$CgCoEK95J&ev4Bvkvve6`_rP4;vwU+%|EP z7UAZ;!k~+85PeXp&S~phwQ`_&>2n$@i4r`0$c{kTk|F_1J3ROD~x#Bd4;TOHD$b!CR6yQ`r}*<{_L(5kY{YEuH`~K;K{0yw=A{X3|k%jpdpyq zBCf;T{q);KZqfzpXd8B(6`8l-)nfnxS06FLyJ`3TgDbq=&27Tl@k#gA_3n@0G}c26y2ZJ(t-Ym= z4kN2>Fdnu$EAXNTo@+JBAf!)*uQzol3H zKAQK@zf!dAFa3o+=I>gJy;J@yf92oQ@()k>OZY4QCd)dxX*bnb5_l#8^gY|whj%}` z(1d^McSd;dn?|_zYr{0eZp$0ZZ!G^P{;8qg4qt?&V9#Vp!^N!E;?aJ# zjJvw8QFz^yz07Kcv=(I=>lM3)g-x5S0knqL$X0EJDP}ms%uAh;cb!?5Lc2-VVZvzL zm~DE3FErsR&2*ueE;7?zv&=>l?lZ%HNx#ahyTyb*0Plp~4o_=MyUA;ki61n1-fM;r zoB6VtA2R7+ZDp4BC(ZOhlb@%|`u@d)|H$O;muCL!W`1U}(HGNh+D*G@H|?g~wEOGb z{{&D=0|XQR000O8-GE{)+Qr465di=I!~p;R2><{9b7^dBc`k2aYF&`eN&_(v#%H@l zbd}F;!$ecWNjerE^Au#>`^biN}r&h_zwC6J$Uiv$vV3m zCEdU;%zS(qzKrj<5I?i+F#s$;eke~wpa;UVP(z-eaJ)sJTHI+%sv<+=&GaRNz}Y3` zOf$<@K|TuOcA!35=OSc%rIoze@{gK(#1>Bd{gd6}gBCe|{OqJJ(!}uaT5gOkUdmX` zBQr3E_iUD>Bb18P$ZeD;?g0&@`uot&1mN1akxJduz|Igv-Iz)~UiM&u9(QUJ4&pks zLT;GaLMii9O||sC`km|TE|a}~4?)^-B6~VCTB_Jva<{9b7^dBc`kZsa9q1%lx)GaG}^Xp z+qP}(wr$(CZQJhd-L`Gpw)OUT_j}`e=hmn(YGwY&Raq-4X3Ur~6{LYdPyhe`AOIe{ z4e6+bHHfPIjd+0o03iQ;Dv2t{aL_5p%G%5eA_Wn^fX;O@=k~>r>u<}+2Vt-h1Cj|u zwbfl$O6okEkdxeDU?%ovh%CAJtfEa?vDsow`&cu08$URx4RC{vnj)*uqr)(ro2x3s zf~b*rPS+cgvPuG+j5Q)Q8wYjRH7uh`VjO2wC)LRB^+xYRA5@2yc1=js7ps0pQbve?=%K{hV*y=|KA-&`WVu|bv0m# z{2OTi{NEjM{%1!`suWVRV+~8xW7EgS2gg*h%Hec0N)jp*vL}fr$BC-;5;3BPDygcV zK*8>%j;6Yfau!mRfl9ijj;*?(Nc0lK^ymQp_g43mhIHNYbiLRh005;B003bBW(^$8 zoal^PRBY@v*${qYej+cS4W(O=%RVXU1vI&100*IP?6wg=(uovX5kgQ%)@55wdwtx* zCtRCm{3Unpb@MulcE+0&gdlq9OnZf!=1n3{7;WVYJfQNfTG=wsQmnD(r3r`gfI{ay^CTnVYZ7Ei5d|Db44b zmzsIz8i!42^oTgMs@In2DCZNIOY)pGmxT>zazYDNB*j=x($g*r%r~N62b#MsJ5IW7 z*}C}8%*e~OdASqK2q}J%TP>lj^pn!7X{I!t(W5a&k4Q3omFgA=={g0Vz%vjC=Mzv! z$R!98F`gYihJ&aUs6GP7LZm!ui1~~#aAA;RD$U=K#%@NP{;JE+1w7l$-X>qfcq&!b zmO?)j@Swxin*x(V{hV_@^>EJtb$ofUX2}!cz$`#jNM3za)&?Hg(+|nqF6Zo0KrBL$ zF*5LC2=EYsMkl<1VCf;m5j!<_tIaK^)QRVC$EwMk%HjW!@|wXn`|8j6^O=syT{7ZT zl{?7kXU`@A4t;yr87`w71bBOHeuTR%Bbtj+GE<(;os7Rjo>8MYBBniKe;n;=I;|my zNjW2A?hL&NwG&q^{}WV5o%hfb_{3POBxBf@jG3MED<}p9kZ+xXR0@RKfw-$!|My*p zAP(r(csZR)W}WXvK3a4lF41YQw713$rzED$RPES>4O=+_<7==uR;{z&0(ftMwC{3nSsK6FDE zZ{77F!jvLC;^^xFAe%BHhO@>-^Dc^?Mb_)KC`Pd9o%Gvz-15_jXU7*7J-OhM6muO4 zrq6UOmC0KQiwbxO*XhCGI6EWiZu}M=!)^=9^p$|o;O*R-`GC$Cbt>a<} zxojIdDj#%t$BU}jhw+&Xz6m6q&jU#mQkQ9)b31$irPf3n_yowkL2v|s1ZZEc;r&Qn zy3>F3kv2*!Rjj@%;0e4~xmZHt5lOZ-R;2t{nOr~CnliH?g>P)cYs=Zok^J63P2#0D zrsLG)H``uhhmhfu5|10FB4=Ct^bj=DX;f<9HYXdkiIgePga;u$6M1zi3O*M z9F=Lrw(ddBO2g1NQ#*K(XCa=$dh0tulWU6wMGkY`BDF`dW0&$(0+_mE4R8 zTU)Q3mFJ;Y|KE4NEJk~C+D*AMHh23|?v~?vJ*Rzy4;EY%y}(I)@>Z2>Ce{iL_2VGiy@=zM#_S+*XZ8xw(QGls1$6 zpBna3zYdzQm(nT`%jI%4ohI^r>@4S;u==3m@Lf1$ZpC!24xX?1?YSc;o9JmLh#P{L zd3pNdU0w$Zm<}dy zrb0$tu`-Kw3(D^39kbprCYKGYZ|<_xS+hOL0ExePV$2Ho+Df+GXtsi}VwHLcrKwAh zT6gH0Tb)8T1d(NN@I1TxHmIg?ey3*?Yn&x9#J#suGagNj#u{C!3q6c*I>aNZb16qA zYH1Z9-5tN)maPiz%%mV%V9O9TL!2v$}6`T~y#ml2&!pbNdFE1&E5`U$6~##JUS zEcJP*gppu#tSo`g66?wb!(1a@dgowQ$cpg7zm8BfBHMLDeV(fq?-K66pV32nygoum3Fcccc3Z{oghE|F@8fg|)MV zEuGQ-xuBqg@^UnBc5$?&V4&pof%@;Su|K#RGy6|}AY%Xkfc~2`vN5JJic#0HI~YUq zW$P_8Qw8D{MtX7Snhv+m$Y)FkZOk@rrsgaKq#kLtHiOih@#EK7MsEwqXi6}xue#LL zQ%n0y8~K(E+KMkbf8#G+Yv4Gs6Hwnuc*pgS*nJ4@{{+?}l16K?P9uwU@0ZR5H^~&Q zMnHOv8KGB18nLr7_0evUb!huESBN~sgNRw*x=m`}*P5xJkldBpbO61E_v5J_*uEs3 zUPTw7tFf4TM<|v~)th_ir;aKry>;|^Fp?ZVvEQQWzD6d zh1T5;C2g-Bv-w)AcgNvE-zryGprwvta&Hm;`PzK&U_0tjKej<YnAj}9={J4Np=nA$4|)S zw@(<|Uy{gWeL@qiB1tYc?;2JD1)d)g9gn$pu~1qtY~5!;g!Y>zR_OPs7dw0m2RRu0 z&iqxk&Px$@_pe`~w@AG06Zlz5z8zXl_R?XHYlu4R>5gcNg+OcSm$X&scoY$_86ZGM zd__otTwvl1d)^h4IbTYO*eB`P$o3?@rH(_j2rN5p{VU$NO4C+`M+Q!W>q#}(eXcJe z;NsMHG%&Ml?357Nq8^j>EpCwcIZGM*+kZk(V|vNF3d5D+a;JIdJY>WZWBNF3v6M9h z(69%QI#*9Lr7WdWlB`G^K)zqrD$Kf;x??!*(gwNcph?dOt*i6rdJdm9mt2W?m9mi{ zS<-eeiFFgi&OxJrT6Nv#t#{&i-??7h0z;H68pS#vSLMzkapUv6c;|MOExGm=Qw*RT zOO77F3@$z_mwe8!25)pH{-|;01-gaQ)xX|7mjlk0N%AO8z)Bq$pY?oegZ>Cw!x8f# zgN8G0k<3F2Luigue-i&}&xzR`m4rq1Sz6BTn?n8ir)4I-De&0O@8gJVMu487Dyv=~ zjf+&o=dZtxlJ)lF`(k_;T_aJD-S;w+(>zxTPK7F%3ZV_l%LZ7N+0UO&XUpXKCzj0T z?$!(<@lO+HEPL74*(TvIz^+OtW^0UJmMMlR(>{cp(q3E}covE6_M6}Ad~Q?U&FOVE zYA5UK)YDJqTK2KFHk}{62VJFUz{`483DThK%v$XM;|-CeJzyJ7+5|i8FMxN_*hIj# zh;``rNUgu6$dgLQ3#4c)5NT&V+7=n_J!OY5i@dGLa@f?wT9MRj?ajcM)_6~(9m0A()bSYt&^-_Ccl&FWfF+6f1`kc;Ry-DS}Nz>m3Zz**I zK$Q_@4GaF@0hW;{-fi0l2uE6)fO**QQJ#~C8khIUT3ozS1$voK2ZcZp!AOn1m~?$D zc9Twk>FudeDI^wWaAm;E_4j8?49n_hMJ4|Gb9bliD23`hkJ>c&C=iW*X(bNyR{jUVmY*WfMcbs5t=t2?~w{3Cyn| zEL1X4DK*B6=URbvx>)`!gO0f~R85*5L1NCM2$POR9%RC*8hYsK4KE?sKsg4n46-nOh8P@MY@W$r7D9A6y8=~OwHOWv z`07N!Ly4D~8uhqKGcujD)mg7;+QHGpA1`i~0iRZzDsS4fMLTLTy>W)} zF^AHF!P!6fryJ|qAN)-Cy$XiN{o`jS<#xdiM%b$w%6O& zs5?{+0xdQ@J3>hJ^CuNq?Aj3&3`&tl3)5D5@DBGhK0wds3hB^G#0!@FPfBJ^fLRHyBu$ zcRmpI??C$BS>@KDkZ@(nlK!6qj{y7zOjNJrnu2D-O|*5JHV!oNna27W)na&M?Rpq* zxvwY4SNgSPQfZ{C;aC5Tc0@PM1r~-z;~d-k)Q`>rM@PQwh?>M>!V!YjiDOy>ijVYq zVC`XFXR2x`#*oFRtMVy9+eRK>hWy7-V?ApVqh?VjdTH~U5ff|%Fj94qiXplQ0uAwT z8@IuTMvO7kQin*8yV1|>F5q%!+}Dmn%2Vjh&@U+y^I5;N+8)v?UL%9?m3o>#{tEiH ziW*l}!;en|>;g|e@c*rN;AHDpaQ@j*1m~ht1=5C?7UOZ19t@x_OC?*a3XC30a zSs}STXJt8{qUT&T@bkEN(N|kP0iINw3Dc$~N5)4cG?VHH4OB+5BU}qmij_7cV`ARP zeT9dI(U^a6CV2`k_u=n9PfL_YX=LR=@usVm6G|c7jK%$iXwlS<*xde3cH5_!cH7e- z4U1VdmSeWtm#ADUUVQTCM}!r-i)6~ESF^KHZqjNv@HQQdHBCWPRX6;&b*%C7oj}U3 z?_p-~oDQ3GGf1Om#MEc4wU(OD&(BdR6c3?oM%cJgJVxrkP$^fCUR<)68ye0Zu-YL# zdvzV-es-Pu!-rFQ7G#P2U7M#XeUr$7)A3xxd7$JmGEiI0kD|Z)IS_M3 z+eSr5;o&z~Op%F`e7YG3+Q?9mQtc09ez>6rH>+PPsJSX_}L0Knl zKU!dc)=3Et1h+~e`+D2d$%k7w>H~+}one2RzG8Q0_WX;z&y8Ze((B-GBuSKqB5>2- z7dL&CU8c>O^#JiF_im9V=5~0o&jrITfLrP-@P=~Zs(0Jwc#lRge-Fg zU~dCO_7v9NIM}S!CT|g2bx3zIGXrH(Ya@Z_)v=44jgYtFgj`F2JK8OA6{Vbj=BT9k35KKu7xuCDTeON+7DUM zwPX4iOo~anPAh!P7Twt#UCSqkvr{0Tla{tcG+*`LOjT>|fEq7Q%dB)1KV3F;vcTj+ z!V6kp7RACXU?v=m+;8Ht^g1WiX3)xhH4BTTrN1x146&vJ)E1}>T5A1~?t&Af*mgT& z-W)`oHI7R2!uE&)yNO}yU3^L;yCj6IWiQ0M)1$jS*OEVV70lVja;bL3Ot(T-Y2^jG zVq2gt;f?2hJugkK!xYQV;Rtk;h9Bi2>W~GQ!%#ACQ2whwk$IH=2s~V1I6~ALM|RGg zrq|A`KXoH%bd-{fEsE3@N`$`cIaG(_!TNUw^m2IlI(eB-hv{oN*s{pX#e`d(7qhRW z&A04B%Nr|R&}Jq?D|--d%aXPB34I>nTSOL5_d{FH(<#dCo)GPKob~s@7}WV{Q5YT< zR*jZCUB8ao{O_`7mhbg*<9)X#W_;2u_>nR_m_2n@Tpm`frrlX6p;Ni1g)9=OHpC8l zzz1{(irM)2*utY1eWS09fFonE)iY35^bg?w#qz^HEN=yT(((QS@fPC$cu2-3rcVE$ ztY#Ir`4{zD<`>Ek7{xX7YNM$stJqeF!e~|mL(7p=HnE?Gf+FIfJXIp4*px?Lepgrb zLeO#%?F?P(^p5ZSZ<;sb=lL;AuZUZ~FX|+?rV7?K%OXvwkbS^;yD}1b;ObjKcw!q8 zyNG!tdJa!`@0f)mQ)HVWikLa;!5iP(nax}X=~tH3?CyRZ`P2;e)geecl{B+BWE!TGRpkS&XP|y`UW}Op(>o z%sr-9n|Vt%f_clu%A-t^s$#W-rfex&Pu!smlSb>CWuxWm{mbRc1f(8w=iLbWU5PYl zf}8yVgQf4m5l}9l4*6Tmr1yRE)MmsZgTx(o+B=3#x7HO2SS!C5cUPuJH>3+z(%&Lk zjH{b_OC-;O+crjBS;JpXh$4_WvUzYf?rQ_2o>-$GwWPNsb#B~4@yzy3uX|d}Zsx@u zsm#MbXzj*Q6^s`)J5=wVGUOw0-?I};GXH6yR2=5qKj#v=!<%F9+n}$5otLnV3wMLE z?jhMEUw8It`FZp>1Kc=sb!l)7@cc!~!&+exYd-$zmuuBNrs>BE3RZ3LV z<>k_1$#T22$o(TxwuUvlUW$#?mQInr<&rOlgYa|(NjXf>OQDQ>ASpH_ygckErz}6;w~@KtckcjY#fZLaR9VTVkGxD*{2tKoG?thsd@tb5s`sB3pOh2t93su_eWn zg_nY)anIeBq%#oNWGVg>R{M!V-XJO97c9y>iy zEi*l~!x=EOKADJ@ujzDk&B8-ELfYi(Z1En~0WFkdcPb z!jIy)gqZLKt%OVAB6x?Hnx)_@tw2}+=hPl>gcSWz6m_EUkX6yh8eynpNj}bznrUh+ zm63$mEHoa~)lo<^DzvZ1u7z!sEum6@4x7gaQg_rfnHjKnGiT>T91V=^0YNCHQzx_KJM~=#wpIrZ~$QJ54gHfte4IGJ0`0>*Vq+@5M6wLNRvV8 zIe{<9>f6-X3jL6b?0^$CRr`Sv+SxC1T7%eSJ2iu$lty(sM%db#p%2?JCdg|uDYc)N zQ7)Su&;~yMD+J2Tlv^jRjpi7L?=DL&B0FIzB;b*amhX1RY@k2G)_s!4V@E|jfPOF!x7{~zWhI0LMk%UfId=c7q(PqcyJ8d4~t0h4twZ?a7AoUW~ zw|U6kWaZb!I_-aKUmjLyYAbBM^H|4^!kHpBeH6l7x?lLXsNgxVMW=jveCU}zAkM+1 z16Hr^sKkL01{an}E$y-mPD@X-e67&j)tp?MliY1eC=znUf-6^HHmJjeqYY)w=aEV< zgn6BUt27p-yGi(I$nDdZp2Uh_Z?tgEYWQJ)ZV6Yf-(MjAa!5hpd#OvDe ztvd>92j>O5?WG5M*s~}w<}v;CJmaQk_<8+<#W@RMcPi?2!~y4HsX$oSnWTxU4Z}bSB+il z|5>~z3#$i8a|bZbkI@PgGZNF|fDZyd{hm;Qo=|e{C88b`1U<+KQiLR|I`zKRHLH8>_xcupSByYAvBVmeSz^zs9si z8Ew`l^74q;b^Y5mVX#3A67@3p`d0ghC6uY651nfs?B!=b1#CcCs*x0?*o+sM^nK7! zc7Vp^p#GRgi*wmH!{ZqB5NL8pJ8p`k#5m2a>6zDoFnxR}Zt;RmvTV-sFma3Ui6Kei za$g9NG%Q)Nm<%Z{Q2ME*;nlEn+uEx)@G|1P%;1bQ9J3~9==ESkCg_E3FGP64Iz;TS2G*88;h%aD|7vDhp(BM81^y=TX~FrrQ-)2l#o5O{;ol z{_Mr?!wa*k2f(S?QhN^r%jF0psu+mRnLuSU?@or~EGTGi3uNvNEY(`rkU;qH_*RptK=~rzQPPoz z+7^+tN0LS%&QI&Cs@x%~B@&EHSJp@m$z; zxg_u?>%GvucPUfw-tQ9o2J4P4T<7^f2lML!xDY}Cb0g8QbwoNSI~}AN#}h5=_t_wU zQo66!FHs8Nv}s&wq7n97z85?d2HB%gGS%`N-ZSL@$B%t#PIwKk);&biXmhTlB zXU#P!aEyi~;dwCiO?RH%Nm?$sP@v)yhzr|AjkJun{{a%^|(CRD|cMU(Mak8nPR z+8)nKOgXK8H$;=Y!9eyr^LE29NS}JKm=8E6^TXo0;))%O-Vb;U1NW|NMxnGP*r(|V zQYzpkm`Cl*+?GXW9$`^!Cfu6f$rnR^*F`(h84s*z9_z*GRg1cWZ!=d2KR{eGnWsf* zUn|ilkUN>*=F#pu;L8@Mjr7Uw@UeqvLp)$f%QX7X*LF$Ev#`gfg_Q%(W3W1VS1>Nu z6KYWPhqPWuu|O7%(WY(>DWeH9Q-NRxl$CPD-4R6&0|ZzWw*kn3=*HXdE5$AM{u?(! z*ySlzF|hSq@)GTh@(0o#259CJ&M28TqWsaG6?0pYzqN8yJK`E);GTy^Spt*^Ew%=K zX0zM%cr+ahu(S^%`2HYaa9|uF3TyN}87Lv57S_E(9;rG9L- zqby93#fm7xmuIsA#pjv#7HB(tNWu1^G(EI}Y`Rj^C#%H9>$iHBy`m6pS_)j8nchR@ z(RL2Qk#~rmoC-VSyew}MQ<;ZET24agDU5Wu9d^8QKe~VjLLWt5$k8Yxk-C9p*kx}> zp%pl&4bR2zu9fB+^fo3D!(^s6b!AR-mevC*i}gAJI7skCkSK zZTTX7$Z|&Hgzq~k@J6?*3;2`}*A6!Os~R)ebtQvWWdjR|{hdn-t#@HHwS0KsqO?b> zZ}*34lOtt17Q;M#>>oI3H~rJ@t$yyNX-QMIj@0A;$q>heRppI4!M&xbangNA_SjNg zBb$P)tx~Z9>mLMK+Z!9iPJ%v(*zR5>bI|L!YbOvtb}!~lI7&nb3fNSe^H!3xd-)HT z%PPh8$_hG8J3q@+WIC^S8~V!)w;hk&nQ3b#7I%DEz9}o@WYP!RvW}~X6n96;aI-px z*5RdV0gLz4oc*oguSx@Vek1rVzOJ~tyCUm;CEf@hrEIO9RbSl=RpvTD&RLVd}JUo zMues27zvRv_8EGhrBVp7LxMTr&qxNqykXS{@8e2mi^wIj-0qtcpx%$So}{6tIJ`=q z;Y)n&u*weOqjG}}Ud?vf{jkEc3Ld+m9Acam zkmHoY{DW4uRMxe4n6H#1Yg@2!0#eXP#t%GJMFg$m)P4u2$h%x#*V_`K)XUyv~gv$@Te6$gFJZ(&8BMHFp;)X7ft8Y7ZnJ6 zy^XiE}d9cOE( zdtP>GZA^OM0VS3cu0^H{R=)5rCne@N*eJ1IpM~IzP5RbTCSAO#)7_Pb|61aC>rS|m zS^x#1Kl7I$8=5?WpEl#mH=o9o08Ci2%pZWkjgSafF+luDxOv>19t-bOh~yN@zwaX4 zP2aAG^@yPhl)QFpT=5s}NM^4j36F9PcrJJM7+ixcP%f4#A9WP_rk*fAp;ZkiaIu@=@0L*BgoAQ|dcx1C3IAP2!68pb$ryxgiGvk-86Wy;cvdL1aV3 zRFROJX1(tFDIwLEMKBcQ@Z=Vpy6BZYJdWaESuKpt@VNb8T8y zMVmopb*T=`+ig(o`u)UfTuM1cZLFLRj~?+-Rjgn)_O6L9mQaWD=AqraHzIv$ZyxY@ z2W)e3#)_2DZuxT-Wu+lf)Iio&E{kJl(yT%A47a?qTxV#1d^|GGtjKsI!j5SO{kv-3 z%&ZY>(t3aaAJ(1KgJmoEL{$TUigl}H- zetztTCC%kv>j|(LWfL%GZ+L2LRMkc+{Xr$T9GZ1rzoo-nURo!MEJEVMl9my!*DvIN zkV?kRdsY(Niga+M&)moJeiZZ(@EM~9$Gf06#LI({#0io?&B%54V_wxrf&X#7X51G4 z20+`4a}m952vrPh*g@EwaH>~_&J2D}(k+4J#&$%A^;^7e@ts|^+(O;7)&b~s^izJF zy}2&$=j!tM6V){Zhi@uwB_j(p?9q3N1CT|S3CEh$7{DIxACsP0mKn$Z$&L4oTkc?-g$QsPqy0e? zTZTV8JO(e|wz0&0tY9|V^`j#Q&Ok+vBu_sTAtveQL8Ud4dcmZ3dc_uwzKp}?p+DgN zo%NQvQqq+G0svS8|4-IyV_-yQZla`PwfQfw^!%U(Hg3>aB{{=~fUzNI*^1zfCtR0= zFr5@n5HYwm;BG9O^vdgo)s5s1af+XA6~!T&IiJKck8ySqU+bon2=XTAB6tX%JQq|b z$DN81Wl$|I_SB+8M9FTW=xm!W`*MiIIz5!TcA$$gL={{|%GrT4B@h8TFI1Fb{k`HV znCs@F3<77GHpVlavnsyM9BjoVSyZ}%KUO%$3L@za5c^)Ji5SJB0qTCV-w1TP+Xa(3 zOdd!mZ&VpFjk%_;as#~JbemvsQ2axCdMRNRw9T(+-YbE=6Imo`GZtI@^2?OjidLT<@JkzO72O! zq~&d15rzz^sGM*#oYY>woEov!6e81e@Oo9p7eQF;R)fLb!0CZIQ->J5dQSw$&cE&0 zl>UeL^i+^Jr*Iuo{~q--hHTiRU2Rb97k}4kbjqcx4m zd=uUupk`kv^^*!sYJkd8foKGy^pO0$ap#in*iZ7h*MJC-$tZ8qxxO-Xy%XvZ4XM&3 zh0W-xSRvbSfjT?0ra6Zd&Sh#8yQcJ$&1!gYS++ieEA~N-8B1F+;K>?d&j6xPB z-`5yuD^Ni%Yy-%&#G+hVR7@V3{Y0*~<{JHFzFgapIT=GC^pqv0wyoj(F+_yW#Lf|5r zFsr-5USt>^q~*sq1YV+Lk+oNODXN(n`W(%E;&DTic`)r}07VBd_f3#;;Y8-4QL@0_ z@MFw_#)vf%=S`t%rw^&?_3z`cbtp=KwB%Auc>{I1;Sye-{5#wl(yAG)zu@!AQs&38&qvJs>Xw+?|o-j%)uGkGAigP!5S1>(+E@F zge?DGaM;0Q&C#^hC#=@srga>dVM43dwabhqK>oVt+^P4&mv)$QI{ zE!K5SOYv+havYC_E4M^X#6Q|~l#}Li@Gr?+9+E+d2@7J{7K%fgOVXb)2pMPDWm>pf zp}Fc%!<~VXvW+gYDOOg-ZyUq*6Cj3n=9LoO2ZDc(mSawzSRVrtu|HhcG)`fSFACK)!%A zYBbWAQA;lQ(1c~;y5&xhObG-^@kGE40YVGraS+^1XSQl{hk2w3-1DrNthNA*VCFW1 z^WXOS9N63Y48+}TSuOYgYL2VeOKSZSfvfEPrli1^Af5XvolqSz=){~BZXqlHF>O?5d%7d=%F;m-b@^Jxj2+uOWr zIuyCg=N(+@-(!YDzG#*?5yjZo{07QnGdd_8`IJD|6uY)lsw>NPZlaCPq_#aMl;hMEQpdw zxJMDmX9A(gLBEyx&dI-6F7Ivl1erR8;9zs zc--U*-nX*W-PK&|hOyu7Cs=C0TJz%RO3%>(A>+X_pgPlZ*<<33T!wRV;zvXN>-_Vw zueQosfm`NN^4H2#y9I!7R<}(~vZo?ZdyrVMG!Y|%zH&R5KyJRPs@4ae(JnxV;*Tg; zL$E9zTnE9Sb5)T=C*}QARiKYugK4jOUR9$tOj?>IG64u!rfG*j;Dx?&eoeWN7kEOGB) zQe!A%MWxVi z;)XFT(yC8utQ==z#=^F4dolq($|FL0N`w zkF7P`Z5)4wAuXmsXVnv*|9&FG8^K#X6O_iP%unnJkW-Z0j0w?Fvf(SzZ94IWMNK29 zSV%<8Of7eH#W6ObpbNF_4=|ZkmUleGtehqMir*GG}3iapPjF@PdwpvOrv(*Z1$@oveUSt7Vg&=|?R%M0r zIbun)rn5QDYH>0!48R|n%mti3Ft?+37G>0dDQoGxM#REe>i^k{ds|cvfGqa@fGh1Y zp%t=YoyJ0>a|@X2d*!B)v-u1yJ$QbwZZjQYwRNu`KHrdqrQ6u*ihvIwVf%BaK)LT# zl4P7*Y&6JJ9&TiKOW|S#f#)!&O;Kx=Rf#Mf9ziU9y#?HQT?}p($2~8<%>J$~HqfU0 z)2SFWZcheWg{m)CbS5N=J7TLksGU^nI#>aVhH?UOCPlUj6gmF< zFNGflC|#Mk-`gHE%sw(oRg3J>GVmq}NC0pXumy8H#VD`G8l(h+c6J|sFc*-K&0tf+ zTjSmV7^xj?-50WF>*l|JV}Yaj1AXTuP4j*$K?`fZ`cNlnntsIqXUj*Oz}b8S1v}P0 z=H>aX&ubt1;?iHx#K`UMSsN`q_dXWy7}@&L$(3dB=up`_u*b*>4oU?@cqU5osEeD0 zXHQi0@62Jp^G!iFQm&VEnovh^$KdgroOizz6u+8sT{(-O6_sScy6NR?+uYU~nw*)~ zkx5rc?w>7^!zN_T)gWQ59Co)_fI2mYSyA8F;1Bax8pnQL#SWB2b|F8d9D6-mZC%)z znt!pPq8}jX%p{OQle_E~K)cH1=S;bknHPzLbff+6jV!cjlnB1-MU&{@4!VVc2sE`~nXvI0hUd=cIGtl1 z!Q1>jS>X+&Ja~hK$MYw?x#Ok<<7+lxa#x+|l>|rx@fe;g|B2fCd^E@F)SMr~jU&sv z@tl{>gU;&jAU{V%!oAkvTMD#6l|l6bx|S{;8_6a@)|1K!Ge;B>xHtt9lKbQanJv7KS-&kLg~yqO!a8OS3Q;x=Zcweb80g85j9W!-xbClaO2u>L ziSRckhhJ=Xf61^FU`+kQr-#3tGl?nDs#@X^kD1u=L^27AP5OUVt&LJjlX$#ot2c*j zGOo_B-M*2d=+aN9JbiKj+p?Ej$6{g|WUzY_HO1bt3aY@ue%j8yZhRd*UXLVk$7_jz z%hB%PM7blThbX(Ycy{6*wW`ASNw0iWL3%OiopDv70Hd4EUHCru{0l&T;r}}&9kzpr zqWzbW@&Nr$>B+{x%EZ*d+QcQE*LIKrCdBL#1&0YWzMFem0mVEG4bu@wBh{$jgHfbi z(pFE&anAHi5;|$b3)V99hkkJD#Z$l!u zm-t5y%uGlIZvkDF2d2tpJ(O)=k0`=lW7};bjzq@NC8JU;I%Sx&v>|^yl$lk~Ls+zg z*>-5z98Bh;HB*hOB)xp&0BS&$zb_y(ZcQzhC|GS2)ZzDmx7J&-xFb5N`YucI23XF9 zhIPgVzf#Prz;YRngmteSR*j(8Px8n7u~lIE9<0UYDjeD6Q~=Qx=#u))B;Z zWJS^IUl$f!(3+$F^^+p$a4@v}v*v>Szc6ZN{I3tPTUFNXkPVsdPj6tKu3>?Co4~!U zqvMJz(UKKr;uebz4UAYJk%7qqy=2WH>`QOjU;)m=bGsm%FWwB#V?SX9{5(snxlHTj z5q%~0jtiP>5ygkXeFtjx4linycheZ&qP3i@^JmcHN2zss;k_}E=$FDz(#wIOj-;u0Yeub*nR{!#Su~HEcDYFO)3%LnFQ6Z0S+I58vlr33 zNb3b}k`#1}#vb^J+4t|Xx_}9?b()!>y{FMqjAi6qUewsg>b;jgf-MaZr^D5MH|gxg zSxVO$CZrZD>Xw!Bo=~Fs*yfaOpSOIPl&F+MZr z4un)m=o*J5v@7jm^-9+%EGb`Of0KRTEPR};e=rgwdpX#&w!)qQD8=neH6+?vjFLeeil{# z4FB%7MXDjjoHNsF*qtX@6jhw39#>nNQ-kbLsJ$G5{t6#vOy4FmT;BJjgJ)Oe+BYLc)zC=mE`s= z>21=cPM)m#S{NM2!V1gWoTw}zjOx~T^779f+$is1dFr&L{z$Ec{@DH%9L!N4T;Ja+ zcZ1KuYaTQ6O0MjP=^MTUYTu-LJhFS}-315tlk{J7Zl%-l=&+l=_MkG1*ltOM$C3pEi zl$~S{h*dbXB2l*eNuql+Q1UKuNQ4>4hlc!BZ-x4?NNuXOG*b#deRW`cioiYKeGrUT`d3{9M4Y=ag(7mf^yPQW>dD7vf_oh#f z8~-MMxpM={t;GBC1{wn@-p>lWHT}vTlmDo}MZ; zAc(IPIe~{>BIRPewQ~C{#G1J~`tIn%XYZGg##-v9)6{LWW5P_~;n!xi-$PAV2dZ7$ zCjt$A-B;#d$M?}_ZRxcPYCyoSH(dre3<3|T=xVbL#lT@F>Don$H2M9n;zNl}2}svJ zYO{y>KL)0g8J&?y%JzQ}gucAv-az};dJ_w6GvUtCH2_XUEW)2Lni72VR{?4AEDBL5 zl9UaIkKQ=(gv9!u?e81+E^fSW^rZFm;B3*j%O~V{@VzZdh(_qfZUX3aD!_93>WHJh z0!|4)V@Wq9MPgLo?V5C1vLtjFlrCDr%v6Q*s6l6urwTC!4U^lVGst99rFj1Fr>M7h z>n7(WvXA1^-tGw710KT1HoG4Jt9KFIr1x93G`l)F`rh#K&Is8we5t0wpJKFFWF*s(Fe* z#VJNC3U*#}8j2HZC_0H*hbRXRA|1{;V<+In%iyb-itgm_r%3;Ndr}J<6m!9v7MU+@ zD&Cjcl@_|Pr=cy10M1nHl@VI0itU7VDhaAX4*ZkIM|Vh9nj^3Vfe@PTY54^w{s8Fw zL+?3p?(wW3-fbGBMcjyYRB~x}YKFHI2b<0r)dyc(B8Dk9Hs>~IWD>JpAMw*(o}7hg zd=5B#4dfvx8wv&=OQMtQEu6RZ*H}%++cHW2Dk0^h%Ial@YE8JvYE7!tC?5ewjo2&H zNKz(+%W&OKAR?61?0{&RA!8HM{_Jf)v9Nozgtote@WM76$T|+eSbc<1Sa7UYfP26#OJ2B{mtJ9_gCjjZ{e2zdji4v(sM+f9Zcc@MlCBPOT23rH8 z1!7D-Vs*o=B0a?IvtADuJf0>cx3^?TG`po%U*OI)ufJcHT(3|$rEbbso2H&O0xaCb z6%6^xn;2JrUEVrPMl#AQ+|xqXDrvVKZ(!OBL8s8*Jzgc8XR;bnt4B6y)0Xx~1C0Qu z5l->+ej1a|YhLn_|EMWQyAYw;w9lFb@J~x(mrDwA;;YmvJWxZt{(NE?$}NxCWCm4c zTw_Z6w0->+Hw>Lt+1k&ybNk2yHl*V z`W(U|r>UFHvqd1z%;5Zva-V3}7EFG6MEY5WHIcjm*79iZ)1?`#Xj^Un^VRnV)4beR zX>@FN$}SnYQD%|PM>${__ah$Q$nXyko(Jrln;>n0dahL-g{S61YAds*J>T1zonxHd z76(nS2T;NiE9j(lQ*&S+T8yG>kaoeCUUb(UUjP2JTk!jDdOI&c6yW%0=+FP3wtrg#n}0{3V$}5P zHaU>|O8G$RpoR@E2^BpLdf5q9pHA?y-Gp3_p)m_Q&P=aTT+@&sI?r} z)JPT749OyVDNR&woCbD{ix%wK?11zi8vX?QKdqf*R2^Fq?|~q}J-9m%+=FX^ySux) z2MfWS;O_43?(XjH?vHtM?+o0@%cpnv)Mv4Nr&o3D-rXhtS{~UU>tkA=gU!%_1Fjge zsJQ#ZaKBPM44%Q&YZ_17`2-Yq(m6ti>#N$*4XE2Qc51JqxC=?d?ZB>=rZEAeTOzRH z6he_hOH0uiyIQQXIQeBQw4r<#DuV;JtRcjvXCQyWRy+3s2Bj9dkk7Vf!~hm&&1F?d-*$Epzbr^wLDj+`+sq^$9yQG~>x>k^G*fSmCDT87od09HmM0qEyj zG^UqZ1~C#@`T^UgW%l6jfM_FRNt}-Q9Yr5_Uju?4kY7MrK`9tL1|%ZU4J8R}=) z=JG_Kej?DyD+m}cLxtWWbc>fHOD>RxaCGqN=s-0MdUWH&LWJ$;jrHF|vcXkToUa%< z)JDZZIjjxp#Krg;ZK#sgK5K6-CECx#B5;J!y@B$cAQC{bzdq6lPgX#$7L$cfTZ@u`z?$N26fiLLB!=9sXU z-KW+$dzIucclE#K6Rm%JJ076e=4<25v;58z3n4(zROjX_6WONpGc^kFW#J42|_jscj2Qj zcr%Ap8fGoj$Pm5;OX!8uenVj=wo5)+T?zS8e(pi^@aI`bjlf*9K+wb!pYI?FwG9NX zah#0~zK;Bu15%&TUL6-`3A_u^GzUvV8RlIf2anvrm~_C8Lq*>V=OpI3Zzd2fs!dI> zVnCxxyohO~3*5A#S!fm3WA$cC5P}bC!D4wE?o(Beu_OG>^7AW75v-TYgAhbHVXOD# zv>YDl`VYDxcX;|7c7prh*if6#bTYb~bRDbVnT0VM_x9S;o??@Z3b!lF+Z@zvI)N?I zz^>rjMPF>&%G=B5O|UUUk+g&=_7mmGO$H(-zh(!%*kXD@#`8OlOCc9+`0BdWl}ww( z{+ibQrIz^pmpC)+mXmlJtn74M>nANYos6`BlQ0V_u){-Jd;3obViWWsbTu3}i}uxk zOON(nC4ADAE9Pd-HnlEU)vlR+*fp)#UOI<`VRsDRGB02=D!DutaPNQ*d$8xpgTGDF zWX|{A7jT)l8ZIfpW?UMLXC(!ju%qgVai%UfGocn3T=CrL z9HWCpZj=)a$rNi`jeFKB7>%%9C7Ha^%SA6jDsCV{^;monU zF{r~##u>g(tlW~e_r)@T5T==ifCFu%=(B4gbxbpKo99$?fE~XDcIDQNlwIFqq_ysN z3Z{#+_@16Bbc9IZ3jigs2xfwE)mSOUvl-9hk|wA&jnY*4{q>Dk8rP|Zy1=C|#8_;f zS9Otq2^365V4^<={igKP`Q;o6WaH8k^EXORZ=d@)_VnwDE`3~8qSh$rC0eDXmx6I_ z&fD>ZUX1`8@M^O;n!~GYJLIQ0Ru(rOR3LYaM2NJCrG&hfepe8C0tVCWW(ub-+>sn@ zyD0sSuTht{+vfr6^Gg<`M_P>_u&3DEoIy0;OwL913ls>*?U#QUmmnU0jx3>Lddy( zR&I8|&n5bz`5sC}^Wy6aw0!qCp9*PT_sH#!2YN_F^N7$-m}*Yd0eD(Xi3KdGSD9Hw z;kPY_z)$xz`k`y;0bQKcd&g93vV1GOJv86k%li6Hb;PGht^a7E4%(RIF?@}rG5pnB zU}ctOnmU=WM6f-3uz*lR!i!|cUv=38nK z6Sk*I$VlDJ{e1+?1JeDe7V8TXm4d)`IRGZ+(&q0C<<)||_b_C$`Mh#YMo5&M#g*-` z@)R@Veo^Yi1c7WaoA@#=4v`v?_s?tgV*Yud4bCrmkBnJJ7`%E_XY-iczo2Zv%Ne+$ z?CKeUL!~5qnF0hZN%9JH2Lz(VSE7y~w3<`KhI9hut07Q{F3?Kd@L-PX%eTtT;dj6n zsYvLIv*nPrr2 zyT0qGLfIklpf;GXqMn+Lia5i85(5>pFlFm9rfqfxw&sl3jYF-u=EcRx@i)|Xy^I7J z+b_o=r>c04ED(H3BXqOMS6a{caigWV#WhUQ($S^Mqf2Uq^Arwk!^zz|{=8VnpKfAI`{T zkLBDB4gg^I>E8-SHhR|fMmnz#v~H+R5({6i4IWAykA(BE5)p3K?0vr!dIF=X`PTs~ z6qDN;B!1JjWG^=0%{6!Nco=e_-(c~qmj3y)?dB2cady+dX}e}mcMoCR7s%U!w|Y+? z%GI8yI78HPBjX0l+_*X=9fjGw*OV(mw4W%#S9bEyvZ*IuXt3zQwPAB-b+>%;RA6Kc z>Oq+Cy(TPOo(I*0-7V3Cm}DYwz{C0J!wQa=IeX}g9hvsay*^vKs$=pao`Ut+kvQU^ zgI01eB*;KzBC=B*w^hi1WrQjWb(41olkTmZBWQ~m-jAFN$def?sL$mB))!aXm-iAZ zk3Xi-w!W!zZK3^8E{qloqd{SO{K0i$T67CW7hBjrpt^dDcQ!!paB|) zZTf8a=uenFcxN|_g>VrE-ZazubU%vAI+cxP>nYFA%bbKF)@s8Y;vUC(C%B(E6t}jN z1xbTzC;D7Lp`5`4laUQ~Ek?lPp|u0)LZH^XM^q2wW^cKvpHX^>DKB|Cz| z?RGxlz*xJQFFZvTmUhCZcSlzRPms+nK7iBq;|Uf%y&<*bRBl0z&I=_OAH$@0+72!1 zAbs=)u#lZtrX(s&Yl`$Br!hv#csu`4yjUkarw|gM`Nd#9j&xRNC()vEAkk0U05DE| zZlddc(GM1wmM)y9jjW%}Y#jyI$|xDJ2}~7o6gtR&Z4i%5)gmFZCSf}y+#;cLr*Pw- z+;a9*C(JfZ;}2BeE#ZxA7f*QGCP=8pMrJt$z=dUTw^QwUvC9Ih?s_RdQyeUPv>_@& zxmEWc+zrZhzhg&-O*66l=5p~El0>wjn?B@8HGXttBy5w36A7s2-$m#`s}2+GHv0mA zx)rX|L;0oMS{2TF5mWK5C4qp&%N;erK!32t8MMR>+=0XFVl(F?G_oSH?4pZ)MBWmrXI2u9s%Il<4X zJZuO{>XW;wr4|p74yYn;q8BkGP6O-{Rc4?4vnt=vFdoeQ>jc)Ti^+s{VHe>*Oe06R zelThZ6AS@e7tzGm@V7oI%?C={tgRIQ<6o+Nuy%B+3^qq5!#lp{f@Dw)wlA#=!jIht ziB}4im5rxp+U(TTqQhLNkkHqM-x)R#sPI9KJefDDgagdywmM_qq zwTTer=>n6$ps)y>TJ@}!?Aqkj(JUrwyoDkAf`Pr*^~JL2rv`Xlc{&VlY({06T>&%` zXZoT&EA(S$st%g*{g;)FXL+;SjLW)e#yz5E6{`#zTuPO@ z>K>!%ij}nrm|;Dx^uc`7i{<@!0FIuBZwJgF7?B{VA+g^Vw;$W z11A`egL|1S@`bERodiLkeIDv?JSc)%s;EN1=(rZ!hMZUWxzQ5KnsvW-s?9Lg0Q#SA(`s&u3n&kxf-4s~8s7}ONnE`f@!W8A(5drX>sjY zr_~#hu9BHD)JM69K<`_|9$@P|CigorR1#$UQLn5vdo$c(jyRZg#JPLy?a>fR(a1E- zOHel^Y|~M#R#l-nZjO|Bm2L|Sn1T^PG6C5*J8x$h|Jfp^M9*JN=vQv&-4 zjcjOsolUCy)+Rcp!c)7=k(GcxkJ^WdL5k}Vqm3y@sp9jo170+pMih^MI#uP+n0N}5 z*~Xdt9zhNg|MKiF#+>PR)@3wsmL64wdf|w&mx-5ubS#z2XDx@m9_9SsZ~pb5XRB>( zLZ$Qnqo10dnl*=kC|ZV$h_OhKn(t>|0ZSEO9;wO)QmM>7xuGt!&Hdt4Bs2s#gw8la z6{y(q?RDUCnG0!C#3~*jZg(kT@KN(%{#4b^|5W+T>!mi3czsnW1OE5>ppC88>nXd* zp1i&({i_WdIp>-WaW~Xx{Mt8L8f{eYC>6r=sCfzxj31h|A}Pjn{-wEMLo(Yg5D8)B zj-$oFVJ$4hj>UF$fW;l4sXaY48d_8WkJY!iQ1++&QV!B!Y3q=1%*Pu1XkpYm>q+SK zpo@;iL=-u{L);EuPBkn`&ZMQqA%yNqc!@j)DJA6Bzvliu-L5OjA81$V-sXvt1?;YcrTiyGf@G)Hxii;l}4|!atA?7$ZhX2Ug+6J=_~#= zMCz@^l*P^s32=jogSB5{cu}ys!vl5Y_UxThYnX;NI|E<=^-E@nhm9|%W9Hahi%ZKf zT$`{e%Ir1OEQrb(bl*!Pk(z*>h1SGCct101Ez}ZXYtUkxH8DBKFL?d*$aKz;;EWr-rWyk9G zkP@SX+bY*-L6C)wC1wOa@i~k4A&9lsCi1pdmtzHe<8p>>vTf!IG*BEl8a$~#xSV}`DMyJn?pja%jGnsNUx>~_trTIL$KSR_Kz}59ETLH{0CE1KM zPfE9?doaMa(G2z4##x1DYm!Q+c#?Q>N4@w)fDI7IXD?=m)OAZ0>Ox&uejz&h<)h0= zSq6Z~cnMIJ`iqx9QU-TTkxywD6jT*{pLZzVMk)u7a-1mv?;2|`P)mb&H1QL0ree`| zNwhX-9h+08KWE}OImUM4;(Ov1%BY3EyyXnkxj!!R9n>`t$F>w1g0RSF!I$(D>*ZU?)p7_9kAbq*g}j0)D+ z36#*n7^EQ(S;JnV`6yYTAWxX`ykqi8Kvgsl8k^r?+`YK-G0kTDLD7b?GQ|CJQU!Ci zbiyoBx#*qpae4@gZ=kYN{V9{Y$TFw&g10sV ziGDBL%Opy6p!)XoM$-xs!f*ZE2yHjN+efj;kdXvQ=l3mYk9u?EMij`m%K}IpAMQS}%u@ zV047LD+?`xBlKG)g`)a})d!Tn&HpSk=T~7y>C?bM>|7JrnkovTA>I7hvjrfvLAJ}u zB0_{AHFouy^^55=vyn0&_a!H<*rj%FKMf<6YW%))FR)VKlMoCSVacbaRvUG9>vvik zY>zh=w-I)XbYC;ygU3stg0+0!Xu7%aMH?vxcd{V5VKE%LIuO_zCyfut1L%Q(-1YFx zSF2(Jx9}RSDDR^eCg8Xk>P5O!6r$d0oB>#49lh511sFf zAiv<3lOpFm79N@>o#f}7DvnTt&A8--#)$pJm>3%B(VtyzyPN@NDhn)dqTPIM>BnY$ zxoprb==yJ^@BVdTkxA9W|MqJ02cUnKMc6o*Q5nibtcZKlAa$3lk)azD9_vFfIi%6% zNk$b)>cTP3b!}^UtP_Ja(jKpw8BN42U)?0x+$T-YmkRM=Ko#NtT;^^l2@$f#m}BZl zed2JN?D=GR0P0$jaD7^}F`rsk{i6f|*!B!tWw!gguV0d%dNe0yl4sM`V0l7l?x>DOa+JRu+Yq> zxFS>nG;ya7A+*pbVCs-ZP$#Rw5t0Z#9B2J-M$yhut&Grg z2oX8Mb~PUk^ugSXOXm}X4c*;&9e*WTCSEiwY}r0Y%cWq@;|b0!T6e>6smZFvXjW)2 zn_1+jL&WPqs&gNGO^+5N?6>ms2Z@D4FGBF5gH-3;Sa6FfpWH$~H}Q4#drp1&M|E8W zqNRx3>ygG^y56=%W_lKOw*Md1W6;+34)$@-)BjgHMoMn574!9Z1qS@z8;FC2weIW6 zk~gzSV1avvYT-39Fs2b-cjZVQWT7=;7c#@K&zY&)1H%VTpcO>2TwL6GelSu%XsdH1 zW}3g*nVX6TJ>D86;ybtFe28RFkwV%B_L>6uM%7!yKAGitQ6wE+Mao|lorP<4PkK-p zZAXQEWVKh1a}j|IMwJMwsyozm%_lL=e!{bw@9GmD+EHzkR4zZMn-J63I{@9MEB0&g zWGasIyCJ3tG}>ZDVckx{ORYG98?ggyWTzHEd&jcVujzzGBzo{z&jl;@dHR|;2G{)^gJRYd1{%w_@WrC()@WBq zCc4Vx^ZQ7X>8!QhXMo($0_h0qUup=5ci#QKXo4M zgUMAZHumf#_!G2Wh%Ezg>i~(aK=tB}Wop2Bl4gDzp@YH}#pS{Y0tQN0zymqVND@y83?dy)cy?g_A(l|t-akw}Yc*bR9LYu@N(AqIJpS z`hH~tI-{GfH0rys<}bfUD14ksmU8sOzWOPB1ry8z_babTxza;8&^##{xqH7G<~xEC~|KyP+|mUOXK9>E6@!BH%{SP5@zW_TGAv#Iba^AJgCuJID&2T^1I zjE~d6$FcePrIUp?-oqx)lggWVaByxPC>i3`eEkfl;t$FegtWxGQa38$h+^({@17Zt z1|jD@jsTzWVTc2MX@Tf#Xp;}uaZW2_=WB8H$?4(S26G0umrWXkpRhrqJ|-^HAupfE zBm1}?NQHlEq!qWan-rU8<_)I*itMK1-oKk{sN7C^D5;c z4fGal#!>isY*;Sbvg~i^?tq%t5Mml>7p4O;5G^B9NbwUs+Xs|chWwwVx)1GV){oS+2k#X-RFv=%}0k z#@2=jNS#bWF-7#^%h>ZMybp*1|wf0O>m7PfOBfJh|KHw)w z@>sCd0G402LySj&e*BWfdxjf9+0fy+(ri|Ddf~ie=sBc^Uvn+rd)ok+OBe)%g!rzYyz&t>f2`qiMP`H)@c| zPBLUBt8-gFbomh3=54DO5pS3#P%Q;CJsVEXWM`z=RgJZ6sL%*T^C(u#~b2NfxOgK*%SG+Owj$8b33>9}D$cy^0e zM2}v6s=+Tb9x~~;O{9?XNSy=z^G;-6Zy)UNAt!ywzeC0m_EcN2(H&@BxsKN?K%sVVskezngTUsrXtN%bH zn(l+FQ?tP+79Lh!#6K3(kr%{`xP}lhv{$&;<=ux=R*K~r9Mm;gI#>A1*|Wdva29We z%+QctIwH$n6@k4x1AFRaPV&HGx1}sCyOt>-23{mi7fnA7p`DH=OI@%o%U01(3nQAR z7-YsVlo+L>Ot096@t%U;s{3Sjyu2?WOOpc73FsQ(`(i=&z+iD+vyRJFGEH7epj~1i zc|!+i5=Q|Gazw?~aeR#Z+zvq-8=$;1wuMm!m1g0-?PS7IyTQ3nMX^C0F&t(mfw)-y z#=fWN&>Svbax-7_V)%2W#Kc%fSmYl&$j@>HI4C6O8u$1`yZ5!IajOp-1 zmd6#JZIn*jYQ7e1B5EPvI3#zaTsJfcqx;nhrF}jD?*Ys9n#KDeTo==?e}U!v%{Pci zWMd!w^JE@l!Bq+yy;cr2dXdWK-w{K{iu=L?Ls~Q+ktFk`lwt4=Sc#$6%?sU zPXVtb97+spsEbNT@_t_6J$wL{ z@}F;Wh;&n~@WBt#Qo#%tuh`3|fWxYW9cycIprrCQo(-1yG9^)Uyxx_R{3*{=zR4zxWdO8`MdD>!c|8dlTlNv-Haw(IQ!RqDvYwur0Md&lngM;N-=$<^8s`_Coiq7cST&U zrd70+JFO&4^pqjI`zBR6ZR2O2FjP8`%plo!)zzOEYvWZPstzjm@aGx}WUBhEX2rRs z{M>MS@z|KaYnXWiR6xUhPN9!0(}0OocmfYBo${E2@^5ZfE4?SV>ay)WeP;QV!Pu{@ z1_HWD;UZ4%N<8Mro*Hye!Vvip0tu_D6<@hR_b%W1f%+3iZTxT$o~Rt@mUjU}pzu6t zsRpe|%G6vF8rqBCH)6wK>wt?|nOlcjXzv9opW@=gSwSV&7;7ZGB;t`y?7l(`Stln# z+i-;r%cmbnsWv;B8P*=*$UlCOFR}ugY}~J+E)d(=FMnQuA0S-XJO%~}&hYt?=OtV> z#>SE}T*EGBs#7Z`ZfAEna-@1V?cXb<)hvJ_tINCq|}I`lCWE zJSTcg_L;#f#Z#Xk*!Ym8D`VsSO7%Py&o0Y^Ok`d1Yv6`tCX|N5D#|w>WCD@I!ULL# z5g#wsnCxzP_F{Fc3#!MaqG!;o6unwL(9kU>K~BUu#XPc;dRig8m#%X!!U~-y?HG7& zAbY?cS%G8oG6&8%FIXA+qnoKOG;JPf0AoV3SM$Tv7Z-_2Vl}ZtQTaMA`6G=*!6j)? zw&s0tJErOZ4RagU^_udc!5VuTdD$UwFfp@vril=XxYZvS&LgPx)Elh*Cl=!7ACQVp zMCt08FSD6t;3Gc9jn?|k7Z-V)oClhaPlmG=GyyLr`~c`t$q5#Qpv;no$)TI56$m=? zwa_TJPL?Z#VJtX2KL~M|;l)`HL z#8i!&->iqPXWx9}2LM6?jG!t^w-=ieSaFh-8;f}=z-TD`zG{DR#?mF(g+OTl7iy5_ zuI6PA%<@lO8xcj)iPa1|6-Hgt7oeuy_Hl-kDHH4CrnA)|S)xrkrbo{8xzlSLoK$64 zADB^U1?E15oOzBD1hFzw(O}b(bCgvrx45YVmGp#WL5%1`mpZnGWsRBMDbfz*RFy$7 zw6(+W0m1MQ%~Br*Dk`>V=p&27??1el4ySjtCDSjRmWd6oYnO!{S=B9z%sIQrN*b2` zICuQ?t7*kXVaqBa1J3MgW=;4yIVXHGxhOdww6ITMgH#OO2{ttA6I5?vv9-|(7*uh5 zshr!Dm@KeBf?gFKowCj{LYlOXfua;<3K?T+pU!-mVgX6&-31Q!<&)pdY+hj|-$+ZY zIs4L=VpXpoWF7?)!Y4{^Wt<-SXxx&x+%S7J2peYqeQXC5mIqV*tYNeJMXHoIjyl)T zkrDeIEAkrluHrmohUR%N8$+g_@`dvI$rf$;Gv3MWMGrthLQfZCU#@J@h|h}@H@qDI z*`tr!n-yh9_p~2OHeP$)0f9&X{$I0N2?74~0R+GW`1j{OlUpJF`U(&L6#!t(q`_{r9T1?` z+u?kr9T3-v>Hi+TMgQ;6)VJvIwFq4U4%*uO<{eLMRn`hSO{zD08Y{yj4F9d`#N z82b$u03t02`#0S8(-YrvT|xeyrT8cAYEss3x$oz?z2&ljznSv(Cv++caPWW8|F21J zZ_(c1Z|1)J3EfJY|J$>EKL+kCx()oVp>Th~a*LM!7W;nI%3Ev&!ha^O{0WS^TKQY> z`xzW>!Iwz?naJ@cu;<{%;D3VucOb%Ba4X8+;}PC*k+?(Nx!YgA^H1)39q6}QJeOj?Ei{9zr`lt{73TnkITch?zaYhuhjb%OpX6v-QGVg5U}RolHbctz9l!3 z{6~cHPhd^_&fkLH3kJRgtC0U&KJbq&T;2OW)c=(-drL*3`b*gCPZzEg2KBcW?!B_s zTkHz;e{{C~xH5!?ertvI+9q$o)l7dYo&3=umdAc;hxh&SZ@KyG|Lvy#|LxLv z-$wqH{KWBhQ~95`sp*)%HSzl%&bQoI-oH9J|LDI~)4w(F``)Ry*czd~JE{KYzCnw> zHSqho@wZ$=iNCAJ|6~SFCcNL8;eDz0TkfsIe+sw%xH53pert&LWw&p^zS3`saR0a+ zvF-d8{l3uSE!tf5zhxhP+(U;CeoKB|jq#RDp!Rod#vk_$?bF|0z4s~ix7-+wzZ39( zx_X-ZM8Cay@3Wk5xh~rO&3XRO->xrzd&ci`d2h)lI)7#M{&d3J>g2y&&F|Az@9x5S zZ<1JlLgSuO{ni%mvr=!-GkSmLsQ&240e8RkiTBa!cei-szhc*abmGjHzpxe~*eH^3v>d@-i~k^8!eL1Tdg;-Ap-s z(d2sDvT}hKEX06h{E@A-R}~W4_b22ew-}fSz3IYBuHLI?la{PD7}MTX^j=2y_G$xM zV526;f9KI*7|+dA(I|?mP{^Dl zoE#^p+KEStAgX{tNfts%R007CnwL13=s3ulOI8FZ>XVuof(1*%M!-fe^tU)|imR0O(#eB;~0H$}Q zv^Q`)tYL^c{#sVg9SGf`vY22X_;^4vsbGVGQZI#@Dtk#1eE_6*(WP?xecfjVk!wQO zW=x^exl>DPVB3NtTURKn;vdVrgr=G&@k`?(9@9VHU+EZyL6pnA*TdJG@=2`lky4qVcmM4ljF^!>BY-uw1CM} zc+Bt^LFZ?E+(=YVnKHEi)4sfc4{xtfV%HX>A#WEpqPBQlV`+<}8Mj+KBhJVA)dN)y_v^hP$~+ze7(KmzP~-yu zq5qgmWX!$BoWU?B+SYD;50n+6+09~jwZxC7W^k@VxPk`)kF11^$w8Ov(54_jAsb!V zKbAm!UFrLVBjt-wHddY%R$@%s1Hn+2%j_wixI|u#AYeeA)tcU$YXo$gqYl zT25g7ZcsK~Me&7BcEu%*F7_|IG<)o}(6Mj&h|y8edS6vl1?2P* z&DNLeSuAHFiC`UTZ`okks3||z+biKnvEj{4B%hCVytE6|(gP`aaZ^zVRMm(Owym^T zlGdtmqS}+|blx+BG1j*LZVqS;II2Bb7CAGhn^$MpVJ`0!qt}@t*Uy>rA0n@mk3%n} z4+Wz#=JB+L8f80MVGrc3I7f|{CUYXs0rtDTT2DNZn%2e;-erRT+lZp%UgMS8fIZC7$uJ_L3*t3bQ{b?aII&r3=j}(M(b_5X z7H&<>4BUCM)T-yLW}ru`+uMYy@;_p)VpMm_Dp=JA`>@+-XKY@Lh46)>Qn#DO+rC}y z+MtN?$w7nWVX}rEv?xROLMQ!#>@$!+OOa2hV9>vIpjB>L?XGo|mE&_ZgIKpn9x#(s zytYP;xg;W~N|)A}aa+i!9{`82$jjgF`I9{Hvu zn}IhNo;%aBi*?wN)EyRCaP&D&+_ zZD~Z~)&mFLj`^FZRUxYxnEJ5WPp86l8+g8G*qeG8s~HWr-#Q5DYR$FSrKsyVJ>P#8hDsQ?HSE`#x(oy;2F2E6vQI `~)i)^_TDRUrDeYt-@TiWu?@7m7hR!-(NbcV#gCaj!|j0uQr z%ndE+%!pv2{?BI=l(0~q4#rN-4mK3@lw97hQ2+gNF@T-7AAe&|FD3v0=Q%X{w*DO^1WK;&);<@R!^|$rj^;mi%ZJP56VIdZa_DzDjPb*Gn z4@Oze-#UsBobe2)}LppCbcZge0M+xpbLy>h8hECZzlDqD$~spW6^Sbm17F(s=Cg(?2Y7mhWYcIald)K#U7X<|YVxvWZauAZ zruF&&+BiqF6t?L>XZHGUB^f?o|I?i2iD{asU8^{$jH9`z@|Lz726OmN2F8aPv@!kp zEI!NQfzTOco-lRtt{u{6&g#6lU z4s9P;(A(mgeVrC)JP%Ox_!IC_v4bsNqGp4h;1RYuJ!`2*1R7f~h4Y-o-0B+z+(Ujr z2wFAX*mtemfLguRk|UJH!of|guC|VZ$+F$h#m=liIUHqswDd#`H#aLl4_L0qn=JWogaWy&)t9n??Z`cHy1#%=vOhh_br;+y2s zzj1&S5oVM|%g_r9(ls)#EnasSvWcho=)L?s;e|nc?uwSw;wRC0C1|b{bfvC2$b>cp zp8omfSRg%c922Z-c^kA_^z(UI^AthN0=D1Gs9j^5uhlr1w3fMp~j;43j! z)ztlKH=VO?gN@0)Z`&6KcA%5~no$fwpy!-Nk`zxaCdYubNeXgn+ywN6HZpVDr>R!l z+^I7wjZ)l71&yYUmMUYf;{gA2AbU>-u3Jq$9oydHq9Kxf)MNEs0tI3mL73vG8#6GNiMqdSRBD6!{Fd%R$X z2`M#5@;1J}1LeV52{1W1K+V90y=V%^y^QoU@k5WLRIVl+>q%@N9PkHV9+0@N|+q{hfmI6Zyqy&V2C?Lxa#yX{iykTIRc-fQOryI3% zO+J=fV!eunH{~AIA>18C-6R!F?*^Q_A1)oS4MALNWHYZe&Ice?uI1!T=Q65*Tbg&b za`a=cdZR|aw1}w;(IkJ=6C)Up47>`I6wd&un-}b!aghdNVHVu6R8LjkBgVnr0>x%y zIu zabiAH_`}F;8*_$H|E>Utc`P+bC)obJUr{0&Yv}Gh`MO2wCiPHf4SFQhExZ9Xi#J`$ zhVGEL=73%wFy0Jzgc8SVj2wpm&wNcQL?H={w;6h<8MGc>k6l_gR_HR-etHG0^m>~rxLePW**Aq-BHGi0RxyY6vs89oj5cMD~QmAy%}o4^<^*< zoMUb2I_DK*@MSrLt|leI9=RtHGO=fDxe0S>mW9an`C}b68`nQH0GWX= zP$Cht50NY^$+t)S{S|WC8kJpiaamE<@o_nCn>RJ%^_Z@t9yLT5u$)yZ=Gf%uz}?~7 znOEYGC60dP3%-Ale5H>p_XS^VTpxFL*1_v9LpG7yPAo?2N>^twOxu-WfVO-=h_#&d zDIwS%^w?v?Dp~S!egJ^I7JDX;O;W5l5Di%+Qb|U>Jb)-s{B8M{-D*0p!6Vkhh8+CX zUnOaW$S#UqIXy+3gnw!c;Sj!Mx!c;z2^fXbTE2GD_@eC@yGU=2us!Wa!-7o8L2%Ofrtg?|UfhxwNw0ZpKN)-fC3PljHq%_LXFLxhx5|F`DfIdr%K%7k z22jGX9dL>2Sl(sQodeV@IHgzX)jpxey11~W-M>#nLKGrCIUl6JIB6F-L9^|k#{gOp zmJ4`O=`!YWYr4k+o6sj{cTnmYtv0`LD5}`Sq_HLUVX5k2A1iiN4LD(zs%4`RS6B=7 zP)IS#0_}e8TA<^H3~Y2RuSN_j{E4@Gu@3$M13)}$~*N!+n60!cXL;p zJNWXf>EdK5N95AN6_)rOiNfPS%a)xGmR_6<4>xd0One;eTCy5C8Uh;;O)BP=3oFIe zdrCwTo|@(kh`PCI4Nlx1hG1~y3$b-tU4%M({FD6p6&f3*=AwwgjHB#{;oXRA;`^yn zv?*=V*|!s--RzL4#iG<&m*;PK#i|!dIIiuZj4u)oelY6@wJa)_?V7B$vN^8~r^06P1pMDltaw!;>`|h3?9e6E<&XiT%`ch^3 z7G99Fg!!SNrs{fkn}JxDHCOnzL8U?vC8N5?u}J5Nz^hjzYrK2dhbtO$;qJ~NZ#&(J zoEL0C_+VGJcOZX9(rA2#h3}t^Gq8@ss1!+~7e*x6f()6NEk z$S?|_mcI^{)ue$S<`tk#0V`~=n3fLM{ zDL8H*dL$0dW(V&~xPK8(>@ClI_0u0M9EpTmUy(8Iz8PTEM#mf^M0v~zo`kqX1}R9^ z0QyPbjAI5$tc63jp&z^(2H1h1y>tj~!`YZiL(zL3ZC#N?Oo)t*(2|D>0t4F(tPCG; zTe=n2LOB8DT^h_@Z0El~7~3}7Ir$F_m3JtMDc|mDz5mR#zo5M#9~<)yJoxzz-qn!4 zq%2A2Z+JE3`6lah%ox9F%=Sfocqi=P(C+_HQe}jZ?KT7MxKQq?0dV01 zjFfYp7p;Pp&q6h(9jZUDh8&Zna*{bwK@Uxa?UeZ-(xu>KxmH%e(T5rSp<6T%LO1J3a zp|DA>uFukGDPf72A_C4)Xn;3DmI;cOK*HWFa4-0H`re;QzyNuBC?dx2>p7zVUfb61 zk;R*woRYuwXi{4^$lY5jqPCNy>)+9HdFZ-Hs;a6srf-=FI?8gWUV-@$MgY3I?24$J zugnC{Y$lnyS%ZL|6V?eD5oY4FHEH6OlqXM$TCncu_y+H}Ne@!`)CA_acpl;wuUmI{ z_1z zLrgz$>Cc;pi^sE%9<&oWQsJy6;6{&jl(07Nv z6CQlmt@*BL)7*m#Ha3hic!@}~{OsQ?zpcmC&d%;x+Tp+I=DQ6UmyhGm&OSm7Wii3s z`HKTW&rrPvvFk_su^d1dh;$BHy%xSt+6z#GOj1A*)3?^W61F{~?G1o^Z6=@A?#mH7 zc|)6^H>#V8jZ{F*<4DHTS6Vek8%$dU`o#II7Xy1_(xy$D!gV|WPyZ{}@7{Ob&unIx z^0#G$CLRp29hfHTQ8L&u=L3Td*8pU-ZFt&>Bc=Ae0-;eKg{&(~ex!$BIM#EAd>YU+dPu&Y2`5|i6Jd1HC<*&+ znt}!I;CS^o`mjoHb-xoKy_Z8sJMIuOLiZvMjT zd|QAVMq}617WS0*1})#g{YbY7BJc?~D^^STbDA;aAwE{ORX?fkZESMSr@AR-OPQ5! z&+Et(iQ15c&tLF{O~(uT1iwSb3S>sVpPi)1hGc1Y6sw%?M{WMYAHM?;5;@vATmYkp zW^`cP75@)0pOexA{EZs)UfaLW$XhV>nD_l>UO+x=_Po~Z09`sIX-k6I!%+#uz~QMS@J1a$Z~Eu@<$m4 zP~`XLLd7bSe%~Lc$nxPab)g4Hk3_1Tap85QZ0Rl$W`RY%(#6(?^GCU#bm@&hmb$8p z{+5b|;{sRAOGmewnlig3wtBHm#gEhL(Lc)-%3RP7PZzaJnT3L(J5>cfOKg!NuycvL?B%PpaZDZ$;$*16co-aq0r!z_ea)nEF|d{yP3 zlPW&0D0JecuD=+MN{)IK7BM6C2w*iX4|*;tGnSmpv7q2xVozkhL6mk>JqzTsam%m9 zGt8;Eb)i{Sf0}aJ(I~r7ztPAfrT1k#n9}Dxl`G>$Y$^vMf5{^5;i7GEcf$?2(2=ce zKB=mZVZ<#YG})H!6aqBqdpDo5R9&%OubOke|af-Z;V|2(I%NQ`N^V zN1(J8b~OM;bVP46^M5Y0%tBO#gJE<*C*8=;g6FbM-t_ayUlX61SP=au%?@y0yJ7;%qM*jMv@t zoGGUR;#Xy{GPc_TyQL7fv1A(Cmz5@ry<*s~4z?pI*F){w&D@GOEmMinB+GQ`FVXt^ zY#492?_{nDvx>@b)wF_f!*n58<#6xh40D@E*RwztkIzl#&FQp5BhXCZw5I1g7(09&mv6U=E{R6H&uq-MrcmI_$8_&@&`Iz%ybT$R ziKwM#*HKxC^ntztHHBd^VPWuh1s%CM=BClQ7oP>JL!cluF6`&Vd>m!xF5KY+6uG^B;nVE-O z<^OVIlX*&|q!m~WN@ky$%oYx}XN02}y@-tSPuBn&;dcF|An_$VNQM=VDW$rEjw$Ip zkm|{RwX=W+lUW_Kyi$T4py5?aafsdj-4%^wY04UK5^Rp=;X1v_@-cZT;u%rt#Gn{b zuEVlgH2RPOj3V-L)OsO#^qnV+SBy*Z{pn=5?EUYw3{XF%ZSy%SAzTp z5gR)=*gDV|YAadWZqWZnVy|A@0AVnDizpLTF(W2S^D|E@kzg4Qc4K!j;woO=_~Gp( zshbu*`rMjybd|f04^LXf90=As*O%9F;u_Rx1?G9}knRbji*s~+nlk~o0NfhafPC!B zei}gIPz^?bfbK|)z$(Z1$7;TI<;0bHX&yEv64L%Ge9d;*U&H~DoB#zy#W*vR)8wWE zteZA(R?xQjwtamc#R8O$*Zh=CoU9eWYUXr602G@A>GURp-T36u%u72@jdb2yj=j>- z_|5qE>61_vrW53ZIqo1;#lcHSuM)vSj8cZ+Kq}>yA=kP%jOvDky8^-d+|5rlnGjL6 z+t-P~2vg}AX|>O6^T^Jql*P zX_4gEv1(@yTMn1jy*}dDrD^0L=b+M6SY(D3LiqIN#_G4QazNQeZbGDp%m4V=DJ@oyYMq|=f1l{S}HhirH z(7Y#&Q?U2yHCdEL>Va2B-j~>zYRPx;Z|C6~@V|W(GjP2j=y%t6!~D<8udlk<>D&A& zCeEtXwpbhp-@l3pypk;XbMUJ2YNB8^1tf`jcmu@Q@pVOoLlkh>G@Ztu(h`-QkLXdI zzX>T}eI7aPz9v()mC9tB?ExAc2^T93E?!G;F|h=C_+s3_|(hrqnnfFLk;6L=t$ygacpNBvFbEB>Dx5p$4^$%XLMe zoAbabQCNx4<*;&u2~#D7b`<3;L0O>NUqOq4F~HxJEShrGr*Ho6LMZ zl4JY~(oHvqk$RfpCOC73R&UjCp3>81(Q|ei*F_64m2}yNvONXa?njOM-|Ek;kfLoc zk+Jl5@A~@ErdrJB{obg2hYVd%M}h|!)^SSpVy9$T(~po zOBni-1?bKq5zmQsCkEQ&8}z7X?@cW~99*96z*L|VxaH4iI{b;yGnuKE#+f^^;Y{c| zv7-pohFRshV|D{G!{RcerWsHPJgeW(7w6?tsHd+@VemHqQ7|V?J=PoXTUaT&dm}@D-5%01j2!>OZL|jX zSSj|O(jRpNnobqz&q%ZFIV|35$dvm#mU%GNaG}K@G=(5QX*_6j zo&;3=EeN#7fw$(8apc)%&nNphRfdULPU$OLOrh)HHgtS(+UKi#1%Pp}|2ARLB*dKj1Rv48NO& zVJo71NYJ`X*=~{4-j5|vdMfJA)oaC_MxPW!_;@(q_uE@Ek({Pf0LxCO!gb`zo)vr0aN5-nBx_o$YPX&R_Rn}wW}RF z{~4f~pvGc^#xIhH7H@+?U?uX2C+~=3nXN)ZnjEg9Pzm+oX+8Nw_ zvsInhu+kAgucU{gwzwG|bY&rj^<0Fn2@!;|Mbvz7(msa%6J9j`l9{Clss!H`s?4j5a9H# z{B?68l7$@~ zc9PSl*(V-YE&Yb4;TkOLpQ=L*DQZL&Ug5&n#cm`#vU?sji47LIyK$x%FRq_;EJr(9 zHtcQG2uJurn$4ph5G~xWuVB+0pGzo4wOE5p6jK{vmy;cN{!mwAca>{scYWw{gt9x% zJ76#QKe(Wo+j!0!+xGz$tj@*%hNM|UK zwIOkd1*`-&$E|Am_dQNYqJwb}#g2iMujg~gl)@(ZP>kJL$5|e=_dYij{1ucL_R8ne z&PIx^Gcm%)eVg>1z^(ZX(Zx2^)41G0XGerAtkLEeK>^G6CQJ5U_qVk$MV0`C^9Z^E zdMLhsrPe4})#suaqOY2$?j2o_K%^6;6>o2b3_XAD?@~i6DY|AF+F`B!RpawV@NbZ> zC53AA*Bo7B+|h=e&MC25@@3d?nr1a#BC)iAH*BNk_y5 zYXsdN$NoA7NL%L17NC*n1QmVVV?2+hLlzX3r4Y-)-0+wYVYMFu7FZUz{p*6OiFLz? zx9RK_#P>*pWAp~2Q8RUO<>qc$xL8>(_sDr}RP_u*v6&wKoMrg>Va=HfgbnxfLINy5 zM4PhD(uWKuuA;=S^pJg8woyW|p zC{eR#_E%V!pM2MM>ArQ9`1ZxgJ7vlyRzh|(l2@5a<4S)KVo@@K>-zix`c3Eb`qr@X z*$0OdA1*!l(9`0caddaNO zpz!G)pe9n4?`l^~5og`P+y5m!1Sf~AH2rpl9sGLjFCqpox1}=-R@VM)H%0MgMf%yd zsi?6ML>d#qOYu<4ge4It2D{5wt$wGUTI-+KOW(ljFkk$Bem8^>UbooqKlJpTOQbNeN#=XW#(IrczYm1h|zInp(BNLsJ4w zqNQBfgo-pRMnr8}w)LU#t2ug3y}#`_T1PB%1AP0Z0=(&qknm!Je;I?#r~!aZ63ktN z5BkmR@5(cxB1Vk6KnHG9&KBWNq(bXMYc}o33w=77;ZQj%n&?`^tP9qlVkVl6}DFtHuPl z0ar>A+z}{Md(O8kno-u^q=pK~wCBk2%8zyAn4sucp*gLB`BGL!OAxWxmjUc6hTpxRrHV ztlL8U_`zW@h2)JOYsc<0x=GxZG^fy@sJ?(Eq=TIID&M+YrB~OConqaM%`s@K>8Cn! zapv0GZP4hE>=Rm8sf9Xio&frVy#8!D>f{uaYfFi_-~{IEP-U4fdLY+u)ErVkjIU36 znGrw7JU`+uxxBxsM`?ZF0OLIwIG%}+=fGWtD(SXN!H$A^bkStFxtc*Z3tX`qV1t^c z@LZK`zQAkv?3Xd%FtXNGouw<7PJM-qB+5VKLHcRvU-B6D=splcC*~PhTXhGIC_n!z z9R5MOPSCZ@q(>Rf{iE0uxLgie!6MNbDjD5G3Ap%|ly!f0 zL2{W{Fl!hq04l7*eA+cve{=9@B=UH-ewOFufUSaR;!rlBQ4)1`B(yP}r5#882#Ik9 zPuw%kc-p8+j+>wFB{P$|G>g~olM$~H&d0}%z6*c`zyGnrZ}3i5`?1}SMEY5ezvq*7@E!(Rm?Pi*v;V9jK>$ky ziYNcHBf?=`k6uTwv#PUrqW#djJ2Uf+J-&D@4)T0y+B17O^GzG|MF9_zHJab+*~-Jm z({7cU!;jq~E&3B=MO^@)3u}G{cXG2QdSXrkvoBgZpeRhVKJm9Nt=4EFSz0I_RXVkl zyp+86ELPv;E7f|836Y<~8&5<|^o)VZ z4Oi3`M2F_Ia9nIObv!YlCJfm3B0GouVP7o4km74G@n*+>rBNfb+m{?AP)GJ-jklIw6F zjjp>L8z+xD9jt4EcG{<0Wb@0frO8E@dyu3cQ{=!Brex~!J^vez9G2Y;!!A2CU9rhc z&s%+FhHoz3Sr8hZA4YAsTByLY<%>bd$c-nqNgp!`bGSx*h3idz+ts7y@QV*k)|AxX{&$-k8fZ@Ybxb;r{Z$~M3&59CR$wL zYcPt@w90ySEK4B4sA4R1deIs*3T65X8cNczGNgrIeo@h~n|x)1G%ep8+U8`2%%~9* z@FQ1dmq8EVwshIim_|vC?gBW?NA7JBZFYq0E!e>2!P;2idI}lC3@hXyRdaP|O;L_J ziiYBRes_K?k|ZRvIzo&pIQVoJO&*|ceOfTivw`q?H^6vB zcAzys@FB;3!e5?lxA^gr>Mvax)fvrCB`WLgdJcyYQF0=rV`Hk_C0p@%}8*BO<7TIP8zGz|1G62@*8g9j3sGzDT zluJ6js`seq*3{LfsN6>=CL^&vZAs*Tl*7Ogx1l5wyN=n zcFO&Jv)v(y8(o9Yt(?xSBa7!SWqk47-e*o#kbb$VF)cppg+cu>{R2ikX)`x{S5CK2 zY)ZY(S>tZ@Xv#)Tpwi8_cyV|2y5(9^J{@cBRm(R0;PmhNP!ni%L=$z>C5v|oS#=_d zG7C|HDx<=h5A;a>*kIeN0epL_%Msv^a&J9zDk*H0jTRbOv#hfXcF3LftvM_ctJK4P zi@R*-U8J8`ku7kosRpTuV`&o zkaqm)>6P1|NXfu9=+Qn27^~?gi9s2`NRi_#$538e!4#*YPAH~d_ch_B;L@Jz0o45B znT+1t-1ySCW;Swi{kj5Pb8UOT@APEifYCMqVMG0tT)jbdPXND~VE z*pB4ljOsqcj*@eQdJWu(RLUqr!AN?e)QBoy25HP_?4(!oI`FV#H34IxGC!HTBA%*j zL1i??rZ+IF6z}7)Dde(z4wFiz>B^;zC_qbt{R#eaD&!?5{|DSHHew)~K$7g~kJ`HwKN4BM z?VMf@fR>(~idsGv7Ss73WIzG&jQ8LJn~*+J;7BdOMM zaL!xp-%oK9iUa+Qs=pLuRBnt4MNJ1FqQhg)_i^P*3!N>hmgBUJo9t=Ix4|YW<0=-uC+DwhR|cH&HSp$Cq2@Yr{TQOAOiiD5yNoT3af>^>BuOt&MzW zg}xlVzCYA-^4LN4YFq(dVeU(|1k0ALBNfCe#$p&~x+nDpB=5tj0_%{5hY!Y^JB4Q& zl||3GWC&D$OC5f>$SAfXOHUi7R2$ak0b@gZF9uqvJ2*PJD4sry$1rhl=^$49k-agU zQg$PmBdRTX4D%O?RZ79#MR~|C4HV(klH&p$g5&Z~()6OHYV{c{(l=elM12uR4Jyn> z-TzK|GT&G*H@}!>8|FVczqS7Vw4^7iYT9nHqWGlve}*o?NEIzfY;musM36Kq6-J=4 z&&cONuxb=o%_NA&C2d-*`+T^GPc&@yOoiy*ZPnsGL0A6j`;<5a;|XTwaoTB3)zQ8cM8c;uD;9C3E#cxOo4nxqKddnw#IW9*c|&l7B9 zuolQCMo>|Z)aEHDFL)eU(Ur5#>XU0Z^n?UR#VMPQGs-wpyZazXkHl%i?OD9*{}Oa? zvB&oKvaEb{1BY%B5K*8}N7mQXqdeQ3#2 zhAZPiDfUNY3OMjEn5b3ri%LyKBGdNBwmPPz;`jq87Y7N-Yz<&s3K%)t%zZmR&pqpu zoXftdM9R|x6HdVunHB;v2A~i%7*ugcAn`>78Irk_3KL_&Vk6!X4(p@zRxRqunT}Bk zKA7BB&60IEoz1p=2nzTq%9*3|8#gw@{EL!pAX=51d(DtN$TQ{w8H&Kv8>(xLZblF+ zvmbduI!o3mf3IEcbb4bB)@pP#?F_GZAjYeeEMZV(y-e=z&KVN=ye@}=s?efiKJ_3ALKXHLpkG3fcLo7=1Y0yV zgS7RnP6G(+PPY0wq^t51(L65AU>MA@X8D3R!3_IA&zbI78Zz;Yx?I{G;qP%At_9Il zIXKVM>0xi{0wu?9!lY33Neen9tm(IgsX<^;H0S0U#+eCHh$H?DyVOzjr`|2qMN}*pr8m#Fm^Owr`dbeo8tSTEAVBv!gXOF zxp22d9gr@=(k;$-7}1p8I*U9-NGAH1Bp78_bN2QOhZt*S&A^N=y2>c_NqkN$@%1PMnhK;QjSwMJ561QwjI0M zX9(#{YSbIQnkSH`&dKhnuECAZoVZulL?kk}ITa~#IysH!n`BC=I*4eO%+DQO`_x7^ zblY$Ww=~mnpsQCO21^)6!v`!lqrpqBwaL13V_eUucYe9WqV3>2$ujDw6wTZTBF*?D zl)U)Q}DC6A5?OZUSOawYxvfiwY5t#;dUBZbdJQzM+li8oWxT znK*+VzSfc=vaF(LUV20eWjP1$(CV;>^Rk~>)VZo%df2aWilD%iO8nUH%Gwn6+;rAQ zDO}w!I9x9>-^FEAuLy=DO+w^`Gw+MX=Kt72MCstjCAtV`ZPU42oU9IZSl8N}hMU(6 zT;l>DpoyQW_J?5t+YhrzP9o^aWfb@x?Z%$EzARRDmR<+&7tx60M~E~L{B*XN+9_-_Kga7Zx&WCLwB5D7p+6DTLOlGZb zX>4L{W$YZsV>3t(6Kr~cg2RX!*UdF8k7AaJhUoyLo?@8)&LG?_VWX?)FlTZme1EsN zn5eVMtFt3#2Y|^>G**Z((caUq4$+;oaRzD^VpErY$l#8byCELbOZ=@1W-2I+w}39g z4O8j79>O}XM-=X-zU{gZOCoLIoL-?8l{`#ZQlB>-!o(urE+kUSWHYpE1}6R9lA%Uc zoL08c1_+H?UBf8?Ruc(z_;ui=`I;o=fX?!FmpN$zEPF%UD*c^LG5Upnxs+Sns@E2) zT0rzW>3#m#GN64A)_ijnj_hK}pXieED3wrSjX!0Ep|RPZX>llqhiyQ8irYR|j&m5# zXtsBD)r?R>CjObUAF(K8n@Q@GI-7kX#$880A2nd>2x2>;yzr&XnHd+f`sn|2OKpE| zsrQy9*Xl2M5Doi(vaGGqZ`gk`=<d9?_Ix|F*1N>HO(!c}X$${iYL>Rmdy2-zJ>Q%ymysrU zhH%FFBCC z3-yD2XGpuY$2lR;v%xReW}aIBX}ha@mLe5Kj#e*cl5L7vQQ!Q3a_78Q(q>er5d@mk~$T3O&KstBna=1=)X z(<$~u<)3{G1A!lNO9AMIs{`_kMAbu%cu9k0s1V4(d1`YFC^#0SEq+M;zYbM!IH#zj zk^#VoC`=hjl;P~(0US&pP|^}Q`&mpPyGza3$h4IlgS)WgJ3zzJ@O>wG4))x!wb0KD)Wm(oAzdcC?T=3S|dQILIvRs>@ z0-B<~hxmN&n9?%*F=O||VrxcP&6Lbf5>-@%w!Jj_V9;Qu;K9VW4&{PrRG(vK|K89_ znBES2c4)D`3Jo_FtC0(m`4+No{*i*<>wOQH`J2;>us@=`zL!ATMgDu!4lxq}k`z{1 z1r6nxMOdSVRFr@AVXjRfsf@p-F5O6l1`tWD5cD&fA=#imD&)VTW=7HnU| z@Jl%`QPG=D*UOoW(j#n0M8OzHfk;>?MdFWd!2Lc~)rf^TB#LFdVL^K3)>K|D>b7;f za%^PvhZ2}yb!;bcMQDyNz8jhg&)S1|qlJb}&e~Fdm!KT0VE}h6ex>-(NwEo5P`0JQ zE0dL2a3AQ30zO&J9YY?)D`;S+}?P8bN{@E`C{w>zmOC@ z!qbQ2=}x;Nlb1*F+@z7%>~^vB>if*4S_xbJbh9a5$@at64;0x>w&e^|R_IR4GWg8C z!xB1{+upk!-#@5m4!h+5F>h;dxU9uc1>Lg>f6In8?5E}{COe(k5s@`GOm;DI)_+#m zhJTyfy3DrPzoGv-^!c+L9c}!EK1AsM!<{;s(ivK(T>aJ;$bEd&{NLb$n|`#D2V~eA zEQ5G`vPmOhx{QN?~wAoffNR)BP7Q|;iym*v~Fdave+cz;Uf_Nf7eQpY_q;W}& z2X|Jfc=*w>F|lJ3_jPGLBo^S#(G?j zu`Jn=z)a5*Y(gkP^Sa1>)UjRae>YpRY&c&cTnk#GcSUKN8dI>Y3ni+7eX?1@3#6LA zTfnU+Qw>j1s|v9LD)aJ$Tx4y>KfKxVFCrtVg|#FM z1jkSZzhFZ>{ZVyFnnRz|Zkh^=aVu74)ItV>Jd1Vy%dC8du>a}h@Toes0~yxMr!&j+ z&il@bH)n>s_I1VJh;31w6~DGtkY2T1FKg#WziP?7@8#{y?+=j|B4=Ouk)|R<4fC!-nY5IW#zj4Btk#N~HI~IOq|suFv@rtht&rvs;f<0`0Ucjn)<`KgLoO`yJs) zYQgj|v&!HRc7EG~zg9L;jl!ofGqYB05wwTALSb|E$2Ie9!sGv;h%8rbx%&cE#No$gACkwYT8G3dc z`3j!#iiIcK$Wd;L`AMA2*GV=db?3lu?A4Ic9Mi+5sx~+u4MQQ~P zbL6+k*0JTNWb9$Zd{y9s67ab?4#QW7Z7jCA8|QV6=sDPt0b>h^G}sJdT=J;2jqI)~ z>h63Um$`;vwoaL)1<98^|H$#Cb9yCA8*zr5XMZ}*)DrioK{PUSjcT%J%MMeYx#y(` zMbk4CDu;SU8dZOuJcoH7_P{(0Qnty3$&(i*e&*e3Wn%Z=-i1ob&gfI-K1Y`hjY+OY z4O}zCt}^x|4s1_IesyER2lG+A9qkWDWXF-it1c0NRU!M%K_g{Io5z3m6Zp^K7hCrnrS*H7K!o@|exHrL z^=~0sw5qk^1`EQs)XXbyUQfB8f|J#bDmEjbs6zocrH4_mIgc?OLK0g6A4;APargJj zAdQaLm_%(3Jur<6>P(NpTWx~r5{>C$MC#h{)%*GVK1){@9{w9s=C{mYhB9&&!Py&i zdM`2TlZ;(R5NNX`N|nJ>$8i*qlRD)3a)Hr2#FmbZmdS6Z}BcCle?{LiuT_3)vrEsHe4441!D>t*ff{Q%|bITmCbwWQ!i z^FDs<;-4*sW1#on2WHpE#c@}&a#2}M zH@Z0h4GELKXo3kgrt#n5Wct0x?e9i%GHEJ zN$6ank8%5Gg#V76S?#%pj<|_v=Cv@L_Gs=?Pie^8@c-vqr~V3{{CeK#@Xje+9s z_kxyXyCD%Zhs>OHRqz>MCaePQ2*KRLML|sN>he8zf%xe}Gl&CglFAMsH_Py^kT86i zzLKSeGyC!q5eVPi+*jypl9=Xo5oBy^>c+DhhIkdNk1Xb{|{ z^V@U0vnPENUGTtT_gHWGB)w`6pFCtKn^`=X>D;yo6;dc+B&xYR5Vdd8hXfH6Zslhi z4BBA;YBv~M&B@gi=c3-22tIaKU+}S?1)5p=$^RPqhy~(c&5kMn!qv5N? z=>)&NqVKPT9ChqT;RUuPp9>jpkjEvHI3{=>d4epN*~xbgaoUaz-KlG`Q->skV%Weg zX+3WK706FV)QUg0*K+s-X>KX-;tWpRf#NhAW{|L&g501h7p$jT^=&N4dhGLew8)(bhSMn*BVI?@|?op8z%c97|LGMMQaOw~L3vP^kSD!xEU8_CYulz#1= zb_PPze=PCF${QKh)3a@{0|Fp^5*xIn+)^?y1E}hgYwlA~=sqRXRcg`Jr4t2)S*h72UI$CSq z7*l?FFAgs`bb-HyHT!r8q=*YB^UdhONq+JpRq5{H53?5|H z!CT#MB}`(!<~~AMz_3|xI&C=XW>b)e?jlVhR%ICBm~(1R5F>|UjwEQ zNwB2-rcc> zfZi>&5t)Oy#Cp~U$82~^3zr;hO7qRgQUeA`yB+|Bt=nEgsCt3KO0?s9_?*2CNdAX~ z>egQI1X<1EHp6V{Xz*czrPPUS!BSEdm;!$$l0zXHr~g%GCu=9J)4tQmWW5 zZW@0anXhGR=~zgn#^3^OeAmBvaSrXzMDVaPWE-IGOLPsg!$Wd~;%Oww3bQ`8=+Se- zTz}?b!vTP8UCq7kQoCPy8nhTqA>CVCJGrz9b!{th&<;yG(XmwB_&~t9>-J5UNBXdM z_)_ZBV;2n_!mnyI!rm>el3EwMqRcNlJ>UJkxRKcCF%zVN?*aUgyBDI?AgCD0g4Pj> zp(*3b$sa%@<;z^#^Tn&agY%(VNz9gOcIYLLUrf2o(DM?gYL3{TW}Q@U`~|xmcji9m z;~Z>77Z&!l4Hovnvakk`ih64-=&Gl3^IcLAhu-U`d&JdWi?@N|oaW;2C8+!*`{x3+ z5P-L^1A*f{f?4-_m0rN}Z~ZxDUkkS-R>h)ed19IztR@W^GLM(KR8B6*!_1i%*JIkXYPB_U+}u=BJI_sA(-z-${`%pqw|_dXEzV zXkAkb9&T>yweHU~TcAQj60dvSx-svP2l#9jmstB_^@6Acuaob85eK0>MrD*q%Hf)P=?&Zzru=Uh@3Jpt~Gs|zp&TN)C=-X?h{QJ>J{8Dl%1E!l#YtpTHp!e?w4}VJg6)t`tf~z zqOm$xQcw@}Y-cEI)08@21ZP3?G^e<0GBl zbqQoC*ORk$bFM|*k~{4+S9==qwa<-nUslpDec>xrHs#RR!ENORd0IqqdgJ4hOKdXY zD2V7ai#4K6AJdF>c5>&PX_jY2|@P-Xak=x39F7 zFu>)b8)huR%Z6kNtix3e4~go5BKzcSvdfW&4UR{F^JH|!n=%hT{X~@fXvr!O?_d&$l#Dn8 zCe3V4kjKPo~c(UG~%2O5k`8ykh&KP&d*exXs=xL^N8S2_RMX%$glBH^z@{^x(l8#@PM z8UuYN$!YmnS7^CeR~0#Cr8-5i!=rI(Ao>SKg?(k{{w^V4IH3P3MKb*zhu;24KmS*v z|FwCD{~1T$%IZHu{onmky-htpWp}gbM5e_2z-P~|Dl=hnUEX%Q1mqmHVaMF;T8`s$ zVriv#uEAO)@i1GLD_#izJc<~P9Z0?jud>opqvQ~cSRz3LU&Uy4r6VhQ{KSIFV)V|F zt8JZX=hzM^GE~X_mVQEBh2u2=5heP0nzW?CxvG#1>c$O!AQrdPI1GZ=ZG}*tDCR2& zu`dHY$AsX%=yg1R{=Zi(IL9A~fL|rb{{EjIVs7(GKU*tm|JGC?dBgm2q&13>{!M?S z_lX~hT=+1-`GGG5GfKwTLewB-j5sd_TYh>hN%Ng7a0IT|UvfUiG|Sy|iUDbo4tZ@G zB5h2WPF?i=aMyNvHZJNrQrN2_Q{^AEgiSNz#lEa*2%M zE=iJDtasxLJ1Haas33OF7rS*L{rzpy3P)C|Tr$>`lb->!VP>sgE4hO$rA5~KZ|lSv z)+@bnxk&2Opj9|T$f6i8h%J(PewG29EXLYQrO`QdI{%Yiqc-Wp2c8~DjbpXx%dFqX z%V`7VxK!q$xFn^R{8~dpKDc8(3=3h2FSidfJn809dFkkZqTr`;Hzm$DsiK8smEtb} zkg|bSXX?y>w}6jT4ABp!vtp?)wx^907z`gQes~yH^z3ktFjR+8MLEvYTqyp?B_-V8 z5tsGYuw70yqh}?FZ8@HwRw68YW0e>|wh~~=#|$l|iB^yyykzPeVb*pc<37R!h4wzQ zdpWuUq6Ws`!pIj4r=S|>nAe=LQ2eklY=Qz*IF8z@5m1$LR z!iyv(u_pHXv3o3MiVb7VaVgAw3j~Iyr63iPTS?xdfqJa9&xmJ%$BS#^J4k@d4#V%>1TIH&k&@9Q$&n)QS*cG6#LD00n!hC*3TAz z@368f0jvWPy6f5Z{PY2)Vi`q6K1{JLxXPFwxu}eLtyWP{sQY47pAM|CDnVJGn{&zg z|29)_B2@IQaPQ2(c)oujdXi@D)%d>f2rX}i(!)Cl>=o8^*5$?kA)IOrjtjGnM6 z9?hU7Y{S@A^k<1$fYX_+?9;3+oRj% z{dHdV@Q&=XJK^>Uy(nf&R^ZCNUul)_MscxPQn zTp@u1a&hd!fTi1_abBuX{`SI2z;)S2rG0{dQl533o|Om)?GkA3z}#kmjeR2sx&v}@ zJ3;gKYUQ@}ehal=Rxj%FarJz8%*yti$sF-0SKu+(=2xL+8CayJqI7F}NA#)@={iks z1h zPB%hmqSHxwj6VUKfX}X3tfjg}VQ0#q9Ucb*?LOKyc-H0%&`%|MQb7&5$ZAv-iZ+y5 zG`T)ll$%93E3ovgbLK~z@(cLyQ4f-(NvG>1i@3pss0dXKKL~(3B8-SwAKyW1)Gvdy zq_~r$K5@=Li8TMKJY1<3148BvP$pTS5b#&|gFRK!m*;tC#F3veoEq7)5{y=uB7us2 zhLuxC%NjUFXMQiys3mpB)*)MZI!^sH)fZ;4;4F@!emZPd*_`P9b+p_$doh|(W3g(! zrBgmkmCJhD%Aq81Msc7amD_pp_`WV`JI?iT3N~c{Hj@k|83@mBi_~vFHG(ln8E-Ks zH?bDjA?^CA1n3Bge&xBGu)1Syqu9c|R<^%}o7O~Adm@lpuJae7P!09@;Zw9|wZwzM z7vu(JM_6bd(O}10`lcN0Ia^djRiKs<{hxDArlKcb#|B)1n4X`n5xuvqm5-Dos>}&! zL2d;4KAd+VEv+v_Hchx}n!b#D;z-bfn(+s{~)d|&3pCoI4*doXN7X7 zK2}q~f3=h3Ci_kYQWwE9yO3m!&$Mvl1&Wuj0NnelpO>#|b3+ROoTxa|4RUwt9*mNr zqQz(V#{+=`En_DQ=Ud+n`{}Jw<02jhp4d6~J!=l?m?MV0;DZrfZp* zeCt2M;94QweCV3Nclah_=f!q!~`ZvFii#iU!1N-nO! zyu@s$RNk>)O$;&qOSP8sFLr0F5 zM1|EfDht1OyeK?cjx|x>KMfgER^8CnlU#olbhMaolu6#43J>%*v5>+a_1LbV$R#FE zCfYb;2{YI!VU21@LPQu&xp3t>vOkg7b}HmzM@cNPU1Sn&YLcq9Oryr_%Pf^!VM2Un ziW|~X2Gx=nQ_ud`8^VC_7w9S+7n)5^W@@Q;zeuk|O%@%{aBJU@u+G1?!3rol%RXR6 z4hO6Zo;D0EZ>yo6C@1+%(+AVEwxTNn40-pGM@Fg6;wyUZ`ImE3AZH3Q|IbqgX!=kC4uBvp zxDRhNE9(=XMRaV>RxDW}D0AbM0)I?9uG*)ct*=9M zs3>YALPu|g>^PSfGY7l2#h{g1TJ6sD<;iY(o!)@0;8?*?t8ncETHns6D%p0j>vO|Q z*BQM9sy<@j7I!U0`|b9N1k_+@7XdIehvykn+@uQ*l&x zMfEbbYrvpUa*=(iR2e8hlq4ORy z%6Lu?Me@PXZg=-92+imcKjboqWr{|#{XNh+L;w_d(jbqwFHic}#I-&bZv=sdaMWl= z)ivJxbSs#YJC;9XOO-%-S%@ht>o0PkLC!WfgY2Z^ecm>`zv4vvFwqM9UX+i{gm$Y z&e`5s%v?>aT5-({Xrm;em5t0e>c{uPl|xogfeXQ%a4Y(gtAF--T%rH+{L@aXYN zjp&_IW=E;cgPB7)`n)=qfA=M2ip+^T?nFmJ-=+m8!JTf6N+)tM`FL&@k3maQe4HyN zjI0!A$4;39_~QQmZW#3+Z}9l|n55uWn)qK&{^Jcg88}$d82c{_v>c_-G%>!CBQV0ty@qd|#@GIz&=0*+aOPbQs&7S)s)4iyQYc!4R2LBY}C z-Wh59A<{v?;691TU&IcjI3)??h#bvtwHc4_zp^-6zw@f}B|WS?{;dWHK^Dre-LyWl zlO4<2?tEN(?s)GQK3uJN)^sjgez}rK^YT)p%KfOQRWKw=w%+3=Sq5vQ2XU$K&sIyrEWS!-+FGQM5G8Vy@x*Z}xNX_8EcIZLJ{AX=;by1ud_lJmLum)< zx)jV}zo~Hjuk%8g0bRF%<=|@X1z?d`uXED!yfzxygBgrXlcsTQA%-rXW_K{kX z&i0PL%RY@#s(d+~liN2SiS829+rEFCYaba2{mkv`Pp8|g`u4j?O>Tvm7ru&hJq1O> zWEJc%+I*{%=H89$H5Hw*2pNq{zJG0!wQx_Ewg3!;M@Zy2hi(9FcpDuz^AE`KnTzbR zo|~X~A585w`9Uk#lVWgddldNcY7aBZsyk{XXxETt)N5P7+$v78D9Xqs-s)NfJR$um zD#9Q_iuI|n$=mh7nh=MCuAZHgs7xL-C<&s6x^nhJQ~`b{=DWm;oWqpT)d16?UzO=K zXIY-vTt}78-ue0-VQf9B_7P}Ea$$F~S8q{UEAPt}oh*>g)*U4(Hc>;+}AcLY; zWzU#s*uB?Jpg1HNm`Jq}wzKk*z$E5Piis4-_X^F=u_dHS8bsx6R4raZx-qT58~HpZ zxS8X-dNRT`)2AGL?BU%SqLYi*hcds`BlA$L#5_f9{v94>vbFQ?R#*^N(9>=9i9K8V zKtcJ@?R(B78!+gZEzxLhtK9@N=PyJ!@yAb-YqNNs0!~s}yqRr}mHF`{$DCwO)^eHd zxPsj78k?SE?H*~vPBrzyok8=&)WnBg%>{Mwd_d;=NDi-wt#ww$QKyau z!`H&^i7sQnPyD+Yl5*!_Ynb;VirO4l{YYwJyR>&}<|Renxs$K{>XPt3)r&aue=y-^`K-Z6 z1}bn=oMs*U<)AqtNLlVhAE7NzU)%*}9~KpQK8){D=x0C!*jBy?Tm=L%R{PR({-~o86S@>8v$eevR`=P!t{A$;(lp6?S)4>K1yEPu|J zV1Jj#+1PF4h~pr`cR^9S5=|qmFjb<(y}I@!3wIDoJ#W8-#q0*?-9J;L(49xoA96Y) zb{2~{JXgSVd8wTdz@$A<GbrN)XjIB7O&JY%Ye!&9 zp7%Qx@#ss4q-wVeYjoAkV^_zSlHNYQNcVhj=8GPf>0f+;||20bZm7Lh2nb(d=_L^fb zJlJ6c*ao&)yE-P=^$fbA8O$lhBeH1;rbJTdN*#xWSJl4(ss5CiCOkij@_N7xeDw7IUu` z%-6dk^O2@`v!wRGbxO(f$s;J|@0NitjK&}O65;SA3U&|&7;<@($MdjhWzo777Zc2^ zYxS}O0TB&!ua0MJ!Qyz^m0_ch+u2^*^6=M1&qiyDLmA&c#5MwZR7no2x?&JXc}gj& ziIWDda`peR$(}tGPU{XH7)C3xQji$&`2;DV%8~CX)1i|*<2DYCKc~*NyqOj5^j$|iIgmX2q$Ts4>e62*DamCsU8O^2y}F-Q(`rNndOX{J|M(z%5zqf^9w+bEywPfW zF~Ftc)U6CRv&=&UflLv2I~W>@$CS4{+yz#tP0Pczl>*f%V?rLT$RB4(H9F@tg} zLLVpdm@F}-^Naq203|GEY=u@uebG-u$`_?_*BBUF*2uDLFZ0g> zTHePacS2x=3L0j}bo;Ozhqhib;T6Od0M9#V$6LAXaN&3%T+9jWr~c(Qgu6q{}T)b(=F5j2?zh4cS-iS|{Tm z)v5`0c%8dJ{3v|#6rh%;dA5?3ap^wtzVBtyH4sE{{Dt?H?%h75Ssg%SR4x`^p$|zX z@BY+MzYcIGO@23sQ++^V)XQ8zk08EAh#sLlbda)CB&QLv#=P7L1+}IM5(>Em%0Kel z1Nat&UP`egrwP!SgdWd1=V2Y>nW_t2d^0n7YiGPty#&oD*2Qg`rjF1~w{I|KGx{4H z8FkcBa;m)kLS$X=y4z=;Zy3?ud=iT>ll(W;MTt^5+nJB;VQikx{$}bID+r481N!u1 z2ulN>GiKB7%>hVwu`2D;l$2*#KyTu66w`t}i+}}n7XE3v=(9dDCz#dah+TzzT1w^M zWQP$-Ssmb4D}R>Qhoji64I-PFYjIe)mi3@^vzs2 z$DUmpg?!NiWAn~9SP&Yw-ga!^wH|(tVJo<^#|;Wa3rQ50MyXxBMe6#6hjSt+*St}S?gFJm&)aCg|LEs?aDrkjt0>-76&;^J+G_7<=*#9C%aD5 zS;{p%efi3qqjq@au%mAJvjHlucuGq-PBx9d3kX3T?pbWjmyaCSD(*@<}du zW!WuoZc7t*dWJYB+i;t9MUI_|Ke-o2HBvGe{8gI(Dnm14+JK}qK>J5}5wP2;|Sdt##|f|#1Z!~IKBHq)x*+a8grCW_l?o?W8hJ1g zjGL7V#S@Q=DU7Eo%@Wnjb4aFYKqCd^$#Szg&5hl}e~_~!U}xdoC8eLZjcnLdFDoBG zG0H`oxC+UdT=U;Rsz0^Eq8budhWm%~!AcXSNn+tjESnDA^?+u^7@zzThR{L5MRDK| z$Z6j_SKYBz>r@JBKrYoR=`Oybi%Qr!+d5}(-sy)O2ctjrW$+aCs*JP2&&|FiDhe$R zB2D=xcTeKn&((=BpD4%na8$f~MNRA|D^MQ+T=$`tVt^*MeN^7mCoKXMPGk$kDI$;b zw=c=%tD98?qlnoaMZek^EUnk^Sj>m86yb?!F}5TXH)D zxk@{I6Wuh;tu6_AxDCfCZF_s<1?^B0v&34*Ov@1#9|*EOj(Pin>>*p_8EK=QfYc}% zY7S5-w=VdR0JGj+mubhS<6~jE;g27%suAh7xO^v0qpdJHm|qNwjnN_xuFg*$p_)QQ z8#UMSZijM2pf3rE_Q$8?Pvr`45wATZ|Me3NpEUA@zwC%NY!dwdN-pwc!qJJ+x?Is6 z9xKO4DEtP{lv8Kn)e$=eyQTvVH5;`9Uroc37|{2qL%@fGhPHYTGQJJ4cPR{Z3f#Ye%*bq+klsNpi0}9c z&&vObn@(F%EiIAvxUtEhNWiiPmfkX(sD&#M8qpk5y<6b0N|{495u!#-;sh=ZQ{}O( z>^K3N!R9=s)yU~=Cu2puN|^y)d~DOO9vtAlHi>R>T_~BB;e-L+@Fy)n8eW3Qd~XG8 z&SSCKz<0eqVV^swh4S6bw_Tr6UGWpJ$W3dtWUljCZzUBwIf}n{G4C}72N=$vwz%`* zuN;0ay8lQfz#NAl^P_Se{yyb@W}wIz)mA_)1MVo#f9gxQK(L9@{=uNMP;!or`rv`z=8tPDc73;h!%P>ufCZm*)=ePBX3S_zDh zww6|GG__>aJc4n+qn6a%)IPFT<4M`kZoew3bV4lu^cT#nxr#D;gprCh`OBXmHE!6?-oTzG|6@ip_}{?exQnvaq(ux!ic6qpy(|Ce*=yehJR`Tp3M8y zaz2eY0ZBty9}#=IJxtxUQ7u(jd?o%e0tSRK)3VP8@{Z~8Jo)-#Yjawu*JWDY$XFk_ zg+3A_+T3%Szd*H6YAG2}ftvmtMX(*xdb``nPaizm*>|Na1tc za7bNxsFs@L6&^7^WLZeB-Z|2xfjC!Sa5S{S!sgV_L>o7``6wHvjF?5vcLAd-4R34t z*1Dg-M}!)Fal_GI>pdqEP>13J=7K5HQZ57hu{3ah@)9-)L6b>+ThDQvcSW9W#3i4| zTAmQ@&Lol@9Y1w7S5|OX544^82=uJ1XXH^{t}tFnGR<2D8JF*xs^Vj%^n6Y%3I(Obx$C> z?D$c1AQ(~A09Pw~cnXa?MGo(yD9A$X0^&RnsGAYAN2X9dG4e zmyhsf_|Wgz!m`B;Gy9aoyI72ohHzt5IU!9XnI)}^U*=3HG{3s1r5jCVv#01;JbjlS z8|A($@!+Oh&?r&VjY6Xgr`VCW`t>g-y~F-vc&jW_aSxR?8ZWG)g0>3@T}0!;=uSh9 zS?(F&woE?v8t^7|3bZ@vl7EJ03|kxJ6MTg_HsQaDz~6-stm;iiB^zjI4eUMtJf@)I zarE|p?xG>TCcR8@75~uh1(U_Nln@DSePqXP_yRhH!Zb6BV$E!PnJvd>6^A2s+HKwX zhD7mU0p*S(BUqO6GJk<-2s7vs+?eE;{FYp>rqzD!W*q^e$GY(k1vP_>vQU4Qy!ey( zmc3ba+_X_|3yxz?M2*T{NxmvZVFE1+d6NoEh85?FaS)$a!rdox(&MyaJxwOro~p=| za`>kcTovYm@K9F6a&*TB8TxAW{PYKNSK~T|yiHA-N3gj^6UdYzY9WUibW=Y8$nA2(5_TxrmvZ+$$4YQ@{ z^W|bJUYQ2P6l`PyTIvKyv-X1_cOPn|4K>O6Lf&U)Lv^1aqx3P%>jHyszD8!*TKeHm zw+J_1k4fvqVW!$=YzjdIYjsN5BG+kSw)Y6rXzeHjWryd+%_1dU*&$L?7W$1^ei5_W zhe*aQjj(;Sqner&W2-o(PSqXt;uDm?!F zigu!i79d17OxdQNNSy9%O#maITJ_r36WWS(5RCZ`-F2c5znSmamDP{VM*p?T>5EE_ zdRS1#cF9JvsNFZyp2A6A@NR40L+uXHGY`;?K3Q>8GT&BL6);ztpX|lJ6A0(5b1l(J z-A@Mnr@Dn~&i85Mgp*wG+SM|p(T|<|UPK=UMmC5Jwx^SQ>TYC|110E%W8#(FX{Tm} z?GIvBxF8^*kt>YNyOV(dJs#5Tk^?4O_`@2uoo!fuG^x)T_sxg@;A8*>m+cHm-gg&b zz7Ltop3egcQ?@ryar{s-JuaRdFIFv&Jej#6kW#*>PBb;lm`<-s0F7=dd-vHpYEzM!aH{ z-%D5`XUnB@xkJJYBax2A)Y47K5k)Xq$My~pSUFQZ?*2Ze@?5i*HGq{OroN*_8BY`V z7QmKR>wP6N+m2_e;QAHM2lJV7B~rl`X7i8Td|r=12s8ZLj-4Ruw2vO!xThsahz<^z zHR+Ty8@ZVPj!l)mC!bk`dnf1?d-|kV@0s86K@T%!yrCBM-<+1qk2Q0Gb(yy9rReXg z?UHDL$wSfd%rpgMMLUpF`T#a7Xw#rUg6-dwYd(c>&s*vwGM|NP(O4UN=sI9-_mVHi zPr<)bbRdW2C727i;VE`^EU5x9H|RSbUIw!Z5x*0fy39D>)oCwiuS|MYXB`~&t$|ba z8l^*3op%mar>E&VQFURzkEtwdVH01>Qp-%dA?$S)yZE)4-4Hr<4iSg~EnjUCF}Wm{$8SBnYwA- zKJ*sR($7IM&^$1{AU;WWIQb?M6Y)SpTZ?UT4v2s_wP(;y!$dY}pHf_#>A0*PydM@n zrQUYmnf8kp+Wb#3KOo(c)p}RiSh0~KZilmOR?~(D{Qp2P;BWkWQF>a3I$nilG%i5k zdLsYvum)4z86WFn7rG)Gx~kvYWCpnFLEyyI#4K^DylES(eBW-tWm}p*fLYz1-KyWN z-M04C`ssECL`$N)vqS2W3`hl?f#qBCob!P(-^ybOka@*IfB^?_34E{H)4!Wi`e5$4 z_TOmI8*52a?Rt!})jc*F(jmJ{wJ~>?Lv|h$0bh)%;yWe~6VS5vp&Sv%D$ZK5H^ox7 z;(v1VZ5{vP9|zkA0PP(gz){N=(>`|WYUxfr9ZY#PYNzF{(El>-q;(+=BejCH$QShH zJ%MC-x^D9#!a4OFt@&2)rrUmG=nm*mJc|f@QIF_PSMcWV$3(@1VMf{1mV|xMJE5h;a2wemOC z_CfT@9*jhY`{&PJ%r(uXL}7SwJrWu2un{8!Z0$3wfvrj#_y^fldp$l+$Dy0T2S>Hr z0{EsPZQx55&C`}~TZU%SDfvS^%9GJE;Uf_ew>RViA}1bc(YdQ(JM7_{gI}GtESbLj z0*kbmkGmxlY5sLwbg(5dF%1bc1Mu^y3lQSMeZ_-+eOWVQa-yTLbdzUpC(vy)K`#|s z7E3G>yrMQIqF_DAT~%Rk-!xK@p^%l4Nc6QvKgCc_`A$qWMkeeoyFo&@)I%isBH8m~ z$a&L2f87q$d_7+K(RIi~16IL;pPXCAW5I^H`6~%>K&pSPu^M7EL7j)vz(poPRZqOJ zXak>jNiZ2*OiVTj1$|CI)Xo+DU1)n;mM*LdvUP!4Zu9Ai<;xjlzLm3PDSNF*m2oxc zB=Bnx{9HaHY^%#^xjn+p+#^`^LmQ(L(f_!%6uyTtUd~0$m|9!9us{L>TruhJ8P1rT zGF-g`7QKL>7$X-Kc`tZm0KNUtppQ zgc{y#u2oA=0XdGtWXzXxR|bksPvl4F$R>j-b>trHo3k&syqX|zN$$nmDB_Ig3fdz- zfBQ_1$|7D+r&w~#-J8(mPx4#T1VQL|9PJ*phL)7-3wEBqA}1`8EQ3R)gb;YpeY%#~IBl76-iIXl zR8`4ZxI~Ln?`FE&{#5gvJu+A(&HZ^4Ru%7!{?%FTF6%!;*GvE1m9~*9{ElYk;35>j z`Q%?es&1!xe^i!y=>%nGL$Rt)c9mGlS?fGUGY#WwQmI|9ZO_{(Bqmpb&2}KhK%pYs zi!_!zfb8!pzs_}peG>)04lYt1-kM-6BYRJtOV4Pi^$j`fJucyZbGNa07Z(7$%vFbb z0q<(^_|qSPVg`97U-$DZq?Kf{SMjq;@)#cv2m=kb!CxrulUf#wccu;a6&S>a^oWIu z*)1r!Vp4A0WVoL}1;>2RgP^NlAn(XNDwd=1{tgV zj38*`RtgRZUaas7M1_89iS{TY5}8&A=A9K>L{EW66EC%fzg~rfg|x*#y_kIcRRJGF z%?}A3c!2U5!!z4bj@&*h*WwuSjG{EYg=$lZDTAGb9J{2ePib$o-MFTUfA;Ry5w@1J zfkFbS%~>9_rOxsPqNNvjk(O;y0RP6x758|7&IWc#>;YTan+fO!Ce&dK>2V0THLuMb zEn}t7lZN%-%eP6>bz{|9gpk^Sg!WMa6@gozbm(@+al?Mg(fs86RwGmkW8o;rv29|0 zklX%m;PopRpp(8VmaDP^IWOAcA3QyRc<9ua4xKf6v6XJuH3Y+^H_etm(&R`37uFKx zc}VvTTZzM2_n(POBi+Qp-J+!Lg5GK#9xO=W%SqZ?nkGxRxgMAsv8sAENxCdH8HNIeCf)0gsIe|sWtufFk=M61vws4W?b zNSaG&iZgMYP8qF$g|#V>9wg%vx^jVU*UB^#JiM2MwoYQqJ#J=Af)EnQ>5_tHIBo|z z=MC4W0_uNliXBd}(fV$BF44~WFHj32^F`(d99$4|QkcEN^4}?V5Q6@S&9QGnQxd~E_#b{_L9i;ADZEL5roa!r22Sy3|XX}wv z2dYp<*uZt{IHB=c-(P?WGCV3?0j*(@UF-GelWn?3R3_Vl))5w0)YC_~Bf;W+G1F}duDfrA z^UUKde*?I$kgTV`{UNLyhwJjytAXl3K(6wAp7;Aigz<#51HR&U8zNI2Q|$+paAy2n z)UHq4(B-W_y2<+^8Hg72ps4^6${@KbcI zb62&B1Td9Vp(4k^VMC?rg6)cD1m<*WRsSub%@ba2Dg1Fjegkh%zxrEVVdigvEjZdP zthKe5J^b`MOKTU#dOlw8CeN2FTsv_WC9-ftoYdx$m)6EYYSw?i#@jfy%V-kFJ3Ht9 zMknzAK-kQ|#jfyNzdxg=@Y=l|`*)B*+}4LgT;zs;+$grKflfDo=uxol+{bLZXm^Qa zji6A5nO!Y)!WT}2(k}5woJ%As_1%hovF8KS!wU$=*cDfWf?it36cGfHk(`zT5}ZdX zEe6UD!OQ{)!h!l)g=z)uGhIJhEDLGn_~}W23Fut-4PnRU;?-8q9zHk=k!W_F_{r?2 zPVcI;&wm#=O9g+)VE)Zi4k>iA`NDsYD3fD`t_$Q))w$!uzEQI1^du)`7}@6vx$gJW zas9%KO&h`(+=}1;+KJ${uyHAY3d5n+Wptyh%KTq|1rr(TDw`o?e<-ddtM@=CuKGwQ zE?j1S%sQ_mpc}DkY^^;b1f3(~WET2I6ge^312}018Qd+i&HAB6r_x?BxQi0*&^}%t|qp_BhkM`T9H@Vt)LN!|_I(VpNzSLYleE z9UBk;koJ>NW9Xm308Ci!Y!8vJDa7LUstecWSwtrL{Iz@5f8NWNZ7fl&|IBjU6ZY8y zTL(OxV5+q#nAOe<;F{m9d{)rw0cI|z(U^Cac8Ro^I=zC)o@}U5I)PUAb_J3qsve+ui^;K*zt<4Bd!&5L*-rXJ-;zB0P3le-d9HUr3Vy z4Mbx?>nEJQ()a2QgoNkKl&^E=wXqvJD4+Bif52n}&%6O}B$@k|J`S1+4LG(MQ{h(6 zOLB|5ekhqnua!4Bv`kD4XsdRH=h7uMz z@ui(R_3|QiB-wqid}j0X#+1&+0_yT8pzrf6&Ahvd-^r6z94UfGV7k+%Ev9$h)M_1g z8s%X+S6xZ`(e^x;Z^pH?bxNiCSgvRe>ArI(f_1xF0RMSP=$+pd8~QQyB-Hor>Yk(O z{o@av6B=814S9RAJ2Q|={x;LV+K@9_-f#2D@LFy8W4ns^AyK=E*_!H8(0zBR!GaUy zr3ZG0*46k(`=3`o8lHrOZ@osgOy-eb9D9PdAG^4rzJTB4ueizIrfZnd-|R6v_-@cV zI`6qgwnfmZwq&9HG2`SOd*_rM`V0&ARQuL+u)7y{57;vST|HTa1%}yVRf)%LnY2Q{ zwhy_5Dz*=4Id{q$Sc%4(H8DVaq^F3A&D&M5-O%WR8*q|oH>lMVsBdliQPyNz=1IlK8wA1Ffw7Qeq>E=m=PXq<`y%j*`_<%ysI$k+6QzkdvuMn)_ z**)27^n+o#qdNA=4L5M}+Q37l+CD)^>HN;0g&mCLekk?idDQ7%01X<;)N(wJf6q9` zTp8D*vn$NQ!<5>;t0g8O%uw^m5+r_t^58wpSXc@fm z|3Ua{-Hq*o?eB%P1)3&!o$0p?u=U#kzzz6;_*A_8f!G1{h1!l}Folm97~M+*#A3zt zf%l^M#CVOqed)jP`;GGuzIz9I|M+5kzuew{*4&2+>&Rvu9Uu3T`V(d2U}rIhOG?421Z;opn4T|R5u0n)V@$-u#Zy%rL+ zCRrX4)d2glHhQGCNKjLUwMbSQEC4-CzyGpxE~KNyQ+&EfTSpJ*a1stZ&X~(G;ts>E z$*46OcE}BPjqMYv#Zzrd2RjEW!0b~Yby(?AN5t3)g--+YP}&0ooxKjDw(nsb5H)v$}L5qzYZ%DG{h8$P{4Vc3aZ znVng7m>TPH+81BbSJu+i1e6eB+TPjnzU~Vx&n+=6AaiH7=Xv=Q<74(VOr&P&3*J}F zSDoOtAXDs!m-*LfY=$8#W{W3u!R^KqDfX45nrj-6ROL?()z+MvwkK`PPX_ANp=x2| zb%om-E!ykTdLkUNiyA8}iIlZBr)Ax}KGGXC0y5`iwlkVNRW-%Iog?v^He>^>wYNyJ zWFem@n0KOFY^8m^t_w+knY`~e^54BpD%}FzN{i2ZK+V<8#?sYK!C2d(%aPyj&oGm? zF&Fz>aWGK>EKWEtMgt^{4ok8DZT2Gk7Pg~ZX@9?4gT|LdEbdb5uW#1$b; zNJfnjzwTQ&%8POG-l5S%HwnKeRp)hdZ`wIfy$v``ltl4gzGVM_+mRvyN;^LZM>k(( zu8)i7EMKBrv=bHl$UDiry0N|Q`Ty1JRvTZXwix^rghi;4tzz`UO651-cUic;ddgb) zS3TU(=&fxjsEPkFlcMm?%icS5b-N|=gEWOAAT0p^4yY&fd5G9#V^*_O6am_eHTq8*U@IcF@{0`u;ABEc>u8hxiUzpLbyL zwwf)GEvXbn%0Nel3yY2@m2sT3;^pkail)?>KEbH{&YpxuQH;pGQS{=hUpOBMS?-(< zEjU~BzWPKm&dwqWJJe=mN<+c@uidW%xa=%4d90g0VilK>`tS9k0A|TlSW4{d^dUDl zIWK08adKm_x{dS5IF$ZBMCZ#-AZ6F~l=Z;Io%qZ0({=1F)3P9R$8dXNb$4+L3}K}W z9Zm};ef-m~ukvr3- zy>`xML#cvSbPtnz=k#?c!Ws&z-G+;oCC!CD1RA7;E%5&D8YM_5P1KEhz%Z^C6OKnm zpR2)~zYTJ)8*B_uF65R!s1kle+y#E#u)3J2wdBLJ^~3P%o?~#~hv06nw^;R?C*x(V zSE1>O_A8j@_(mhDTk)I9_h@JF9#-~E@|E(3WP+pJob~^r;v9m6;khW?wr$&Xzir#L zZQHhO+qP}nwmsj>>Yq(2t1MELo7{7rlNAjlcQT-7-mTRzH@@!qV81IjQTO{S(e^j1 zA(j)4w_F0~JTTwC0(Lk~zFe9%w?T*<)Ayl1q`rBWJmBA|J&v!Ks}4SIp|4TiJZZl< z0ko?AL4^m=8EjeGDeM_Lnm>x)ih?~jz2Fl4Ib(^Tk?OU>1>e@_uFg6I_nqXPY0J=N zG!v{V)UL1)nXDSX=Fs(VRhv*sQ;wl&shmW&9F0`LE{QdRLGzt-8_z&`mILY;=YkA6 zrX}5`X;I``<{^KHzRBvYkzhW6yWl-IIV+j239G~id=`>5Eo?kH!pqrVD)=lhjx8 znP-8dyt3)f-;v~zpi%vK>mMLdvjzY4-pUmU>NX!S#3K* zOP%;RNnl2VQL`=)=aj<&u>qW70&|+>B=CjG@cQ3?Lj}uiV;h1SIxEeWYX$mV$-Mmh zceqawUiXL739c?|(w%<#X>V`L-srn_1iq#lMgSUqUkW+leDJ|$d7<2V`)-kZ&20;* zN+O}-nP<}A{teO-Y33<4fqzg(uKE8o&xnkDN>aKvALBB;hS6kyev)>Mg3vhqzORev z7l-ffHEpBmbSKqkiJ2L~-mFtgh?65%$8C}+ZUJFSKELMYK=wB~5+rw)`ezY@chV*Q z>Ava*;<;HO!yR(92->D^3Q|5P%d|ZAe&$@=&?WWw!3%6U5P5O2XjZOkIW}>kE{zPu z)OBlG;Igq@rGhW!{qHwPu|9@$BpT;tKCS=&3<3YUZ=M$R+FeG;)&s39o2@omtu{CR zZ```Q-TA+hmsgKBuOqLs)pABllizU_4QeXW>2zk);s62p|JEP?!0Um%C=X!`ul$X1 z|8HS}KOd?Hs&V^y%JIp~X=ox)#D4!-7v{6qk@zdSsR?j{dL-aPNa2SJQBsj*sd>8O??bL+LMdW_N5pj&fN0pqNaes=1;ehMcS_s^P%$1b5jr?4(9X zpzLT?A~tMrmvvT}A}K>0GiCCX@w*q%J7Ij~uvAwW@n!TXUok~-5op;m(BmA+tY9Wq z?_f*45_ResetL^OWPL>m0(H`E5!E{uFz?W3cfh|rT#-+V#Q_&q{fKXD3xMxET!&vX zF_}sf#bzT|sb!<3u`%#5<;KYaXBJ5$DwIa@2=cLr%2y=D!f>jJ%6$HT+mhJQ&R9n@ z#gqWa&eGVL&I0jgq~YgtfWJ4@x8zXgohRp>bpil@5(EGM{XbJ!oSE$NXl-TdYqkvp zUt?b)`U2Pzt%Rw6l$W3^9Yz4)1@_mii2REYC|Zbu^5Ux|S~6Zf+r#AAS*G8lZnrK^ zTv4v0St!8-o)^+yAz7y~MDiFmConwukF}Z`OmoLO0u?TFG%<#Pyf`;>QCiwi^;0avSVbkNi6g?iwbU3A>Coi-bt?{m}RQ>`8y z$TJX>z6n~i1vSq}i&Yk-EIA8BjG}SkOg<@>Xpk3Np!xmG2oPt;^5Wy95J-%3Bx(&g{o3C$c9G{t_ND2iU(Z=RTe?VkdQ&4pmaP$1lw0$bjH{ zyw)-4if};Oy=;AhyJ(3sqZFBxa%Xd*`-E~8ia3c%d5!#VZmhU!2*V{fiH&bzdLUbn z)#(0^mBn-3=26~<)vHO2*3+Uha-OLvz(C{ea)Okhg0}+NtJMGAbixVX&R5+zb0m)z zRiM8_rA}p?4d3*6)oBP|$Zzs_C=08;?oHk$Dw0xGjkk8w_AKrEcYI%rf|p2xY#Bvu zhu*4@3Zxty-pB8MIF^~G)z2DxE3H7MxQP8*i1R}iO&s8t6r|P%!Jf0DnYbX7l9yJP zd$*fAF1sX@?RWW-_5+rY{Fhs}qDW11?nM6SCP)Xlg|`KpTv}7-N9?G@!3$@szX1zZ z%+fSn806ZkBK`yB8;GSrpa!SOx#&1w!(BT61T^{;Kd=i(BX$2Kk6`}iEQDdV^Flb7OvHP5 zeg#C3#Y7z1G%ET;7nvurdeurHT7QxAyyda|xD;VFhK|PDv7dzEgbP(V=S-V2p#>EM zt`aO?+wljfQt3qdHsp)K-GQxO=>El?LcQ5a?IlzFL%#9Q3NK`F}^4myEt;~~<2A*6t+0TIJyMw`qc zR*0%GyoMa|c&rd<#~dWKWxEl8$psCux|{U`E0Ey9*k8m$i=2H-52{DOb^WS0fUg4Q z#T|5h_xvY=KW9XWkkJnSFth(Bgde)*{$B8E_jG2(aNS;{H>9p&9|D#)I=C!XFY5+wK0|Oy~{6iSi)X0t`Rt7OfOz%;U%f>ouH! z7@M?_IZGn^LE3!VL29xKcdZJB)Z*-ZGh9B!5$6Zib1+va+}lb}ungW*l9GjzKrC@U zKGIZ@2k|G2QGCnau%mpQ>7ZZ3gBX4)4{^#_N8>2dgRGl<`WE$rj6RuFX8>Dnqp113MDAf)MGTjYd$Iu6@&OR zG2YK#w=|O}eB{d;tG5Z`&{TR!p;ygpr3BoYzj(2&8Y9-x5r~z{mh_#6^{Uthm)VfE zNQF3c;>emq_UL;}bCzBInSXSz!(nVY;#>=tTlaC(K}?Z#Zb2T79hl+a@p+`93l5zQ zM`m|oyL?8vE-8+XUn8{c3&k~G*JUkb=I|o&^mA{WalBWJaN6eo)aye0XE+Sx+U*=Z z!XA`MjNy-|0rspxp&3FwozD}F0mk~{^>Bt2m5Oy_qI1i_|3tG27!zMAD5}%I6y*Xv zd3%oAw97!223u`++qkUJ#5)NP(dTJ64fVb$*}7}q8rWc%;t5$&Ar-IbcAlw~BghVt zVB&Dk)Ah|(Uh3dmW`<&wP0Bdj)276XClfo0rBeyb8*R@uOkCweDMn^#fl9E0+qauq z19dxHOkk*w8~-T<0+0crs`C8_6bF%pm?M)9-BUuHclG`WSyn!(LPk&X;!zQtpzl;o z6EKH#H3>eXO|0j6rmr?0c|X_}E6+-_<>H@8QSP{4;IutYg)4^(eIIzHrRk#NU(FcB za^7p?X_wz=_Y&6kNBthBU{i_sgRSs~pJQ-tZen0{EN=EICadV`D5*JucX@C!0Vx|1 z5D*ezAO~@=L8=)L0EmEe{-*;0wa-`gNAv7f^ab;?$NKr#79SPT(iB3Qv+&oEpCA0_ z$l~DY&|IRQfBYKoc~{rK*N(&dCFe(A1OVXwo5kA5Sjrr!u-3?pA@pc+Ma!ZDdWa_K z>2Q$=*ETn9CJk;g&1P46N&{MqXVJnIw4D8Lw5B0y2R&{s$xu_*xxAtz^(Bq{kqWyR zNzd(fM6YYL&(VM^zbENF_7cDD19AHYvPzsNYSk!99OZhKHVeW&fl?>R?-_$xpeBsf z(8TnzV4LV-{>7pe&NCbouCdoCW4XVUSy2$bowDf+&=dN0RDr+VOOmZCf?iP7knSx; zkt(~A<#kaOOGR}|sm1EItu`fwOBxX1m@^>Ruxhk+g|x)4*)m`MLZT6coAx?qGUjOl zpSxd{>hVJ|FMb$5IB#w^kBG0QkQr_E#prdF;;sB7*cxRRH4bMoQ&JSNx&udQQ-{~| zp;_%Vb|AP%rKXWz5^Lyahxqrg>3y%yeW}3LDqtpo8v`e;BP_T?iE~6Fc^{*=xlVpq zyz7HeXyx}b6q?iHa}x>V@K`Zw~H#BsX_)^VOMF$Y;w^>pS5m&cZ-9pRDEm_Vel=*ke`f;>Dc zP!yo)vU6JFcIdJ9ACCYeluUy)!iBGPGE3xe^wjNs=9)^|@rtellaDJEi#Gs6_m3vc zd$u0T&YAqT+~E|oGh}(CZcs5nykwUg#5*H)y#oH?A7eaFg@rf`fl-VX>S_oRm zJXXmM>CbvDVgolNSmaehbM`Jv@aMD4gshkHetqulDBMQWKevFYN|zueN_qIKt}iz6 z<@NZ>&>KUCSRsDrjVWn~M-5swgeo1X0Cs8$Og(L5E>G5M>i9o(W%}%P6^7_R4%v*x zYh!JL?0})aR+7ThDq1gV*d5C<_+KxY(fdIKDO*82=@)WzuV%vaDQvK%lW%_O<&1) zlH@pau{jNbh1tJNG|W3*lQ4#;?wSe5_2psBgk|fSnQ67>j^k9D`Dmm;RvKJ|qt*|^ z0-(b>VNq415QVj1n|w8f_4|8+-Qylelwh$(KB?j}&Ey7*gYtgfNDfnmrvk05Ey&m+ z@!e0jA2+b^A9&-Xx3w3A(7^xB)PB+R{5A=MaIz;su#=}%Wn{!0WwU~A>iGVvPPZNJ z{(j~wTnJ@~CgP1Vr9t|OqL*QEc~}P{k0aq{_N-oy#7URL(jJ%{r3(mu3Zf}2^zS}k zY68Ws%@#O>m}aKG$NGapZc;c_+S`PtcDE9!XNEj@2tVS0cua4)vk$FnlC1y5O@#s_ z37VO`N&ocAo0&As)VV!7-bWZ@I?DApo0HP*!ep=gg;!@&!FA}S*W+16W|XLDi#!Sx{ioOnMr|?bu{Ws zGr*-&{g);vwu4z&CKFGs45j?xj!?heP7tr}i2C(E-X{dbZW&+{$o3v~0ZG zg5qyaM%~L&LX9`8L|Xzv=eK8BFnvgDmP17jtZfI zTJy5S#QPtGN;Xm%;Pv^85(uU z49UXNs;Y!lB50tPQ%s(B*rb3l<;_Tpw;`hzI94C9d8vT;wIJU|Bh!jkG)itz#MFo9 z#b7e{v`H&$Z(ifsgiF*oQg7*u$4y8yDr3VZPH&#?iN!T|e-vWbG1SxD{vo{H@qg}V zoU9ha+nY=#{^kM40epi=E7u)o2AU4ZG`nQ6!LdALjDBLR7`mI>cw*Rf)RB*?eYTh? zS`=3usQtyd3bW6GqJ@ec;cR^`$ISwXiS=HGXAT<;A_lHT7-@n;#yxxL-x%nbRa#Px z#*dU&JyHs6iQ?&pevc^_@me7lnJSQbT0CVTB3pwoD7qv>5_UoY!9F-(w+)1gMl&ue zhKa{_EzI4}?K_%nuf+;YDxJ^H(^DcpY4kO3;w@6^5(hn`cxLkbLVdPHVyUSO#mRwQ z1Ih8-|JAtf8(*o}|8A(r{w))h!el0*~AYDa01bK0_NiJgT+U`a|9XHLO)pl{ctA**=p zPqSJ_rFiqe>({=rCTXUS<i-z4Pqa=|_FbD1^b7H$X={D@Rh>(r@OGWdHIJrc^U9@J)AF=BKT?$Nu#L z4mXe<&A-O?$0PXt17MO*+r)6@@Gm4Ji; zX_F-S^4waU2-D)Y1P!E>d7_O>tR{5J&U1lIiLg$rf~w(w*wY=MOoeB zSg+pK#w!rmp-zBg>DCgHg!{@xNi0uNEzv|R02~3cwD5cqG+k?yw36Y{gM+B%2T;2Z zRJkEywc-r9D&X7?9Iou@b;V3z*LKRXTLf%?$xckDYM9ECs2j|$2ei9@C~q7np~oK& zM)kL1&u1z<0Gr-(91VX1yOE~F*VTWB?F8^~M7gx1tY8yTe4 zC&P)^wmWQm<|1D)ouBk&g^nsM>7yTjX($C*Mk|NawERi94MZ+pcjY$R#SzY7jg@>F zd<_TciZHm;@s=d%A_=ZBp&#yED(d>TmdNLVI=wOKSm8P%-6p7NaRS<9sFhE55Oe0s zOD|J5gfcaM0O6b*ihn|Q84sE4SHmC5$HbCZsjDL^*kzi*VzX{qi=5vHW4FfPsgu8k5SS(-*t- zeb;D~diUaVb*$&p1{PL&g-J4ji*{ux}!l+pwv+oLW5MnHVo(05AF;ex$*w7 zK3IhAQ&bn@Pi)k%!Yr@)48Q+3@;JmtV+ZQJ`0xw-fOh!jEeF~a&}SyVw;wXPa5Xs!w(G?k#t){qw-NOV}hqe4`&o-C&CtEToQIPZvf1EX{G z9DDa;m&tx~_Q5D!7p~P$e@W6_3bo2UMI=)Z@6+$m#f0R!f2k$tZitQ474AXe2`A@% zmmWf-WSm75na+7NfW5bsF{2G}p_aOGed~+&u?&kr>r?qmcvTQp?P)Ffi&PaS*KXi# z#PBboV~lffHqOsdWrAQ9-9Ma71DzQ;M+*80_BO`0<-C}m@azl{NXBUTelkGf1a~beQBf8wSCm)wqI$>pLnzvLv%R`DS z&|_+3vPe3q(y%4C)S6ODZo2?BN%Shqr0C@8XX<1Mq!`cXYzN|7CxXQyFzW|6sN`+{ zQJyXj?n7(3_|4~O*>spVXc*URlRH$VZ50(#ow^U*O|4X%y%<_`agRtNx+=>{iexTm zi%nEVV@OXfoG6~F(Zino)(W^dSG|a!rMQj6#dcfhVft03&P#K~_H+cdVtR<*{AN@U zH5#3bTlp@J>6qAluL)V2>CYlx8RvAH?+mGHD9h-6E59x%C#^mf+AXN@mT-ea&+XOX z!{eC)c$>q?#ljx;{##^fNYen(+S6(1xq;Hl>%GRPUJ7EXav1zTMN)a?U}ysvz2%fRc^0o9CLMj7H@EBt?t~w*iUj zjiHL%m7LA`$+{t2`jz*x$=iU>Fo@@IxtCwqQTW>rbZTO}C8RdY?21Rax$W zUl6DuM*LP+u!`ed%P=>B8c1NAA7O+rY`m4hNf{l8NXu;>g4ZUffpjD}BrUMmVQwe2 zm>FTinDQ4z^(#VXmw<8~oq1^zow}&OLQN9M*`wTcgzn#{9U?-ZqvkXNl4Qzjx`=Kz zBdz}|Lr#;tr%9G0RR>(zG{YH71uU>ko!+3`ar5X;?@@smrQ~)A9yhN%Ei-TH5GKQ^ zhe^g%!N)}YT7?Mg(O>;(#|7#{1(&!fD;f`54MWD)@3MW+P2tMU3uoS~397{JY#Y6K zXt&qzr)Ibo=OH4Z=zyK}CGXEE?@J*P6(#EPj;*#wlx|=_R(Ps%d_w5LVBBFxaQZ!1 zO|aAfk$YH1X30KH4Zk|T*)pDeFv^btic8@`yvo8jmO;6(#J|~uObbiel!V|78Wy~j z6$Nn?s^+?}+7O#$+5*J@xU4Yi@#WAkvb~6f5H7MK*Cx6{rdu?pFY&^Ogr51suYxU#|a2vpyR&wFQk8$ac!b)sNXm zkIk&~ta}2o|85`sMk!~f>;d$z;oCbEs?%nExXG&it*xVmA?SGfizf+Oat6>(Ty8CI zLjA-?U;87oseA<>Zf?*!Y6h*FaI*##B#XLmi>_~G7Qk;Yl8sw2Q?}%#E6`=(&V%s* zP=id)Bx{k^#++h=-_c3Y5pf$(lI$nM9KTQB*vQv0;#o>+8pH^-DvFcjLg>6UeZw)0 zUlBSlt4NR~vdBt|!R8<*$ArpP4q+00&?HJ(R^?>|kWRbXBJM|#eFdae$YAsAf+%nW zr7MDNIH1W*V2lG?ggX8>Cj`r?dn0bTE|`v;a@*h?R*?#jwv4)&6TBd;wt0;28lS9< za^3h@>*1-ITT)y1KBe2=>SctYSec z?UH!67{6Ic&mE35uxqxTwR|`5vxQWv+tVZXJ04iHcWESQ`hB?ig8cGk&r;v$;=%=w zv-@@>eJdbE7{H#U7{1zksNsgP0zU)o zx+wwoT5qCYIA#2K;W;Wbd-wPW8u>5R;zo7pG7N0?)x*0~gK>N$OJB7`l)u9`jDB5u zaW-1c*smp+LyC%jNszguoQ>FHxu-%~5RQFcs&;6jn>(Eal}ve2T3euE3d~WEG(1o% zqX2fBKdHq|rF$>PLj`VS5=9ygho|FOpZtdKA#Tb7A=#}>1&*ekNJ)xG&5k$iGCfNB zzHWJy;VZyEluAzl)0hmwF%X(1kq*Y~i&hJhJ}L_vVO>}b&B{eq4JgE}pg~cKas+bU zW1wVwXRXsmI0ZSRMJP-coR!L0gle>CtP`tWm04}jZEy<~M{pbaPLoh1m;%0gRuG{U z1oBw^=02lCRVFB_exEgBML`cODt9dWHT$~<$aWYTseZ%PqT~PfpcbQZ{io4Q4qXK< z=>*O&7q79}nGo0^nLB-w@ee1pkBF4VM*1U-91o%Q#3o;qq3S&%#~I2f$At%2yGZc+ z%u6!3>X;34D($c^+O9XCH%D|HbOzV?3cIRTsvZvt&XTr(J9Y5@xNo#s6w_vv{P8h- z!{uj-&7fWY2I+y*E zEXrwvW9SIu1;N}=oZB|Cc$j0R_99~~fWgO`()J-xrqO!#k-;JAK7vr<&`}Q}k%dO1 zF&&1IPX4o^)H6{m^J{QSj^AWdv=xZ%R&bx$M}E_X%R_proK zxDt!T?IvUF4H_q3R$PbQ!hjy?Lux3K_r~4S6N{D1 z>I9%cCd%mpL>r-($RFuI1NiZahwMDWmR@49<+m5cHu7%&h{pIPe4skDGb?$K8@k?Z z7VbvU2Whd~L`$F?0Fxct-##R)iwfGh<4j>ou5=4k4gB3BN~X%w^!Iw?ZV0-m z3cSB!Q_%|^cf;&j9}`&y(vAgLs~2LpnSM+0)Qr=V2sn%r3k;Ebv>cjc7qL`Fhy}lp@tWS-RNG z^meL<8J>ZH4cT_){sg*^-~&3!|Vxe$-O#1zZt{F_Vw6JY^9ivr>RQSaOQv$PS_i959GFS{vYa!1?IbJ@p9f+b=e|;Q9%r3S<3? z_9N0w%p>?BE|~c#@+?ILd*Sy&E~=AOQeTUsGWQ{t!G3O-m}NJI#G!P>lU?o!<&D^~CSjoi`K~qKY=aforKgHvwPYT;UX(-$F3DD*8Rvf1 zr|BgUR>voa^B0}HX4XS6@cGR4D25$D9a&}>;Y1pV&`-G@jZzY?yv{~x1*=U`1sy5~ z)?P7gt&>^MdcI&B0=A0ChF&S$YqVf>;BtPw0oDA&Y-)nph3-+I-+Zx~7QVR*C*4X7^fC+@LP?eJy?tz|?N{2-s@z-@l9pbFOni|Ch zpeuY3%`I%~VcEcc5$m_Qq)zi!?N;One6IATG8~e^kWlN&Sx>5oOQ8oiX%$Ht4`+l{eR5h!kAllDzqVXFrvR)A4& z%h^9Q2X&IbZob6t^u4w1U0p<1zNEVl_$Aggxhi@)FbV3sMd+GqO*4s3HBb%gA84(< zd$Q?2TTwPG((Mr|3r|r0&YoKk8Ap46Mx}rPG=8fCCZK7;<`g7_o+Nv(&yn8?D8cQ> zRk!NsLFPDz;nQ`y)b+$L=m3Z6#ukyQ41!9Y$b#|*=3C)0;1Z)t;#=T!zV0*%tv?1_ z4DhU{&Hjj5Os8_V_=h9H9_&_S@$p&WO?3b5Rie}aZ=MMt#8U0EGkF^mFp373oMJ#G zFur1X=9ef!GzbN9?$3#X^>-VrK-?WknnjJ1Hf`T#q2%wzwdEEUlyP)R<{e0R-yB7m zLY+we90Pa8 zcD4x0Ztfb6K@4iVxz-WDqPxf!U@0avt|>gUJxf?rCrpJl`P>keg-K}%SgsJae1Ziw zBoe=Pp!qp&Q>e9$c^*f|pz)5%-C(8XL7s#3C1}!-@~79+lI}_!c;FajqsAX44}Axz zwkof-xTn`8lUQlhI{+!pON_$vsEU#DSr6rfQbo=EJO0PJfH9lh!J75T@^RimIWlq3 zz>&7TB><6<4muh;c*x%+sMPFW(tKZz$`i!n0X0)S}fe;_6vLY8_mf&KEu$Yr?0HkHGw?Ag z4C1#k(vwx`FBcs#mm(tuLs(ls$Z8z17n@R(o#kG3Gzy={U$>y)d;!H7zs;=SKZB>d zV9@&dBIZYh)sHpoh(o1IZfoEeMQ@qI$hUk1v5XEvaG-=vc)K1|_*wyDp<(5O_-xaj z+b>GOmGooHTC-l{GnOfdN9lD3LN0WcnI~Yblq|)@k6pKb*BH1nC7a--AM*xEg*inEO)1?5v>+I z{Q>b;b5?>(Xju5~VjhQh-h_9^^2=qv#5UV0i=JcTBHQg}Zhj@yD_6j5gLzNO;@|%T znM##PSc)&Vl2G#jtqKE^Md#Gm$Yq+W;jH(xFS-l}6u8)U{sjN(KdlGb=|21VUWb#; zoakRc)?=98zwK6n%qGeO5JSu>Q*kc#{2%u<%^6~J1 z(eJl54Et2;vu(W;5kt)Ki^P%0@u3ouU7QP)uqJvA6uWtjpvCq^51ke8?f>Pxq;@DS zrT_o|s007Wty&rB3!B*%78|vE(APhI=Yz4?&TEiz4u$zQ5L#?R?#GgArv)?QpvWOG zwzKWq(qunRUWKm29K$(8=Gmf-5N2`a4Kv3%xFYFYl_o6S-ej1&Q0`Zn)DICpP>CUHvRiBs4q zV=~2bl-4-{cZkApiQ(}0K)IB^okEh0GH2T^gLm6@TD)W~{)uccpPQ#hgxA##?p`j` z$l<#$%LHMmsSlBKE^eNYb|}$LD*NO7{7k|f+byJ!JzytLE47d!HPmjusV_@{o+Ee; zplWRpy^IP{6!{uWj|G#T?&IPaKzX|aWiX~*oy~eVh1q>FVk+QzzcIp=sVR9Cm_1_( z#4hsCZMz%{GavHH@Z&Nyj+F_bi#CSg*n{^Z!0Vm^i}lHMp8@)eOdw!D!8~^UJLm4r zEI4g?>b=5x@2UT2WWF)2>ihxvvV%htQQWfrRzv3q{=<*BzvJZkEjmDH*=vWTE7qHJ zvs{{K6!xD%`heqYRcf*7bj}aG|yqL&8FWM*Y+qzD+mDB&CD6ViX1y0f>+7<6?e>?2{$%~P$^_8Ar|#a zUr3(HO&5WZly1Wf#hc98!bOYxPeT&dik+1m|H;B%`k{v{ci3N&G*9xCMk*AX2-_Fl z>2INmY#mm$(QFj);7k;Cl+4{0eOj8u94dRb@7V9P`yfD>-;}zW?bbi!E*v!~g@x_i z>u2`$GTl}e9Lx4eA01^~9?rULVp>_Kf8k8avnUIM+T*1=j>m#)StFX{#(REkU9^l; z={0}MDm_7+L=Q{bH91iw3K!hAFo!yI&)@zCQs#fOBj=1Mddod|iSn1cmFOxyvC%~g zg{dshwr9y+*6qv2YFI%bT5`JgR2f4TP`_3U8rbc>2;f!UN6@9uco5=tywxxmUQT%XZli3Dt{^K*2tzq;Uo!#0WEnW@8aj1 z>QTHTLCIM9PbvnOgA_f-fA=_?CEl&eJ$A17LnKU4*e!PSGP(93Un0R)ERuxGoL8t5 zZaD;SaW|E6hM~@ySfX^5J}1psx;tpJCK+7abxjd5y_gdTFPI1bW*J8dqLJ;bVVG0P z3(#8wk2en&YHKM=<7NB^*S4Q57%FdwYHv&s5FSv)*Le$8=QH(Uk$!bhC)nq~z?t!2WOm2Hw(dCNdam}F*11NTf*JEzCaSsdb6J;_~bq(qo zW8f8^jIo307MdiqsCiIUW?+8e%=jKU2qk+k+?WE0fHSE`{mCB(+iI#7D$Ww}}zJ}mhF#Uhni z1Z~b^mMJB-t_ZKJ5DyceZQo%l+ptxR29@6Vn5j<>U~Vx{ol_2Ap=d2ZDD4H){OQ@R z4;arZG_R6ZukM$+;A9vGR;{&6MU(OWcAjl}Q_=1FmiAg3?mKTL^q9@{={1^^_LmH+ zy0VX#Hv(`z7VVGfGB}nsmwk7y7(<`cdJUTeeW|Bt)rc!wE}6=_jIFQS>}t@iy2wa9 zSkpM-#D!9~3Cj)hZMq~UojTsrPiW&M3PeIe8*ZXS3S~(x<}pHGnr)b9wrdr1T*?pS z1SB=a&^1x2s*c)W54|E2gvR+)1IaEzro4MpYovC~eA*~R2}s&Jbi4zlZOC`8hAiz$ zrR5t7_6g_47;QIX4aKp=}UFX7RICyKX=Ax<1$ z_|1HXJ7pi3e=2|Vcl%;;vmm}T&fz)GNQTI9y_pW4tr&ma&?`D7`!SB+nV`zTfqRaz z*G!^(qga#lnF^hbK_*woKpgTLS$bV2;Qj_VP0V)!>aQSkxJ@NWvO!>nU6#9VA4Bi9 zHLmWgXkUjm?A?;9TlQ-{9bQPzEdUW74KU|(Eje!(9mZ&fIyoJR3H@GuKQ-31PHF~d zohm)9O)7VR`rE6v$;dXA5h-}Zt2eM95(o7m)8J}@ z4-`15B#4lo{3xsB$LR!F)OqQu6tPNcW|A=hLa3Kogz@hHJwU?0hx9u7%5)^4`;K9T zn~WJZ>bb4YY2BI|rchj(#7&h!K14zP`A-)YA@`1kCtft*HKoX%s1}VcD%|;nwPbE0 zBzOE7_b~h^y|gmE%k?=&UjE^97k@<84lx$V0}Pa^7&9l4 zB&63{wA{WNNH}*tu0D!!xA$52!9I=5jledAMM!lX(uvhHI3iu*7iTAK#W`EiINTX1 z8c`UDlCVZ$fWS+lF2Mq3)*=k8E+Ckzfs*s4-hK`kbb_yP8q>xr@JDXepz?XY{* z=6YC8f_ME3S7@WyP7z-^rZ2o7-2jCI5T1n;$&fG{Us~aAFq`4LfY-K1B{dP@%l>8( zhtpjtVn?1HW6OV-37yNzyq(*hu2IKB7ml=fbd`Mw0;9@^*49nzPFfeYM*M1i^BfNR zKno$0H0tVlGP#1=q18!4y{BdnCM5qhfVEXHeoh+!)M6h6Mic=G@>|xo3WLp#r6&G3 z3}vKUtdz5=#xXNIQTEYQ2WH2l3+ox@ql{KhU+0zM25Ir zU0irZn%2!_gpsWoSNuW|A8+##G{%z@Vg3UlEKNvne-fCUd~6u>o{?r zvK(e8bb*Az)$bAnj|i}&YFVt61lGDhPIR7uG(c%xg8-JI^8^@Ra26_X$8t=;$5y^*BDSMgdmVa)g(hw25=p(t(KqrXN3Z8Z?`ap{>Xb&15-%((0mHba+tn@^2&BOG_EfpXT+~pZbQm z0JYI5XH>A*2|E4K>!dWH=>vwA*WI_?mKoQm#ifqm-(Gx3$=3R1q(3}?!Ix7xf5)9l zqH(siHOsg%o~^OF)PW&rz!^iijDl6lf4m(Yo&b$c59qe14va0@7%zR_^lvRa+kENw zQUwO9tsIzkNF}|RGZ{&w9Dy~TWja(wwW*IWw_z1md5-cGmpWins3VXgnMf-%3g_=P zeF#1ng-%At-WDFq^gkv^m8k1Qrh76daR7VddQd0c5sJDotYVNLS66&L2K4xZ8GWT; zt)pE)j0#+v9rQ-CtJ6Mzqky6hV4pKmnI~Ur0cflKPkC~SOy3azvnjEh{ta(XQ0~=# zrzanEb5{6Yhl_gi!{ax18rZbFZ~xHlFg89HCsIuA&*e9G>c_^R;3Pps+{q-L%A>ME z%;c1x@1_mHO6GUde_#`YgFv)%eoQ2H_*bvUE)QB#ZuIxkMFx3*WYGP5(* z6C~6mZu4jphsca)R|pJha9rCo{kd4fG!*tW_Tit@u*Q7#M&Oc#T?zS0aJ+c6Y;@K$ zGW`z?uS!C2u^(?T3(CnX{4{G0mOt1sHAXbrSyxsv0x;>|4SQs*(zk0KkJo8!RGyH@ zp{6z;CBQiGqO!_NqGMKmP%c98R+j{w(%`_xFTD&x;5tJBAy`@rGwL5OL(gWH4b2ldEA3S$DYW0JB~_0kF41A9o2F!Q$WN)9x!rg{vtNNy;;Vtmb3APVu+`@ zAF|Wtf@Ux82>8TA276Wyw4j;=QUqRrJ5%ZKuqVg_SF_rd!M*$k@8tBTxa832@lxR1 z4)O%+Qa;iqLucVT5%ju*b`5sK39pmiBVr9i1_Bc!u0k5;`YI}%fE!62rX7E!h^(J@ za@HH)%QVG%6TgnZGHAQwHTq~tLdG&e2f0k)pcL5PY~^d(G0rFAqP0Zq+HdRJBuAW1 zBktMB!}P4({U+*B^`(D?%fk9{m?J0`Dm4!g<1*GCg_$5DWj_7XYGM>6lia&4s@TJ9 zm}+P1cX|_w&KKp%d3+oJw;I#5#|#azjqANoSVwjnp(^_aeK%)&ZM|`Mb>m1J#;hXz zrxtDxggb~!!zj91-CYmyS}F(MCF;CY1UwlpavW3&0gAF_b>9EIe?#;89sF^V;?uDQkok_}%Yfrde{_GWo$0*>&&!Y(0-6R(u-2PqWm zEUL;)ILtmvA0PNSFiNz*JVpWQ%Ch74$q9)!$QFbQDRw zkcet}h!zD08?8>55HJDMV?0B6EoHZ<4>&vQ)J2d@zY8;G#Ag8d%_CLaA$@g%=tKG% z3!Q0=I1)DK18(^WM{k+zwuG@;*pglIWHx^+R^j4#(8HK`eqUHYpkK)2y@aZjmnAYb zq_-@8)hq_EI2BMBTU_C8C0Y}o;bqmU!4j9{+9CeD)EZ+;pO0^NDGTtHnif$esMjjA-RS{ zR*Xh-nVRyHD_{7rewu8X*XEs>T%MxW(x&6ED~-jvCW+vdLVkOI|HCGBbt7X07pyFC zjul4QOnqbcBDqFML#b!vm*jIm)i#O0uaLohVImUqABk z-Yl^mH;?AHZs-yxLYgkbQi_GTpjd0~ezFp2E-sBM81-T`ms^L|;rNV&Ejet(LGy?| z<*u$(bpl1nB$le)s_LqZw@S275qZ|?i>C4i^LN`S zQb{sZH^hwV2qJcMt2auXgDVv)|u>>?}}@|)a4y4 z4hU62#q6nedugW|B~oRxOGg(%)W^WB^638)xnyCOCZHt~r1itl0)BwKlj{n?{r zQ7&(2cI1I}jlXyWbuo3QZj>q=W{C6xDd!D1e}!YM(L{6Nhr@2l^=P-dBd2a{NknVY65& zn_K;t-7aoJq@D_#@&yZ(!cGp&HHy|+i@7Bn|# zg~$9PS$iFRf!zygxmWDP)97`+0}B3@^sMK6LgI#LYEzn*x@`-X8Luf^V_rv>9%>h< zd-=|G&;6Xx+}#F(h2#^`aa**Nt5Ha(iLkeSCVd z6+HzIb%+cH^cI)j{}m?>1T+OAs|`e8!wWzQ&oOc~cjquJO2YY?ENClF>h{5(oMVg- zuENnmq|o{!QRu}Y|48Q`9*j927W%DX7xLL4Zd2LDq6Ee7~v3OAORw@^d{YU24 zDX`gfqva0|Z}rZrKDk(r-Y1u_+S8^6^u5C=?+JDZa*M*%bE4 z2UePdnUf$f`Ra!h+}nM$%m20Ji41MSd@#Gn3Lq;&GnmJiiRAsF259j}1EoNbm<$^p zx6APmJp7q^bBFy#XWQ-YT>SE~Z@thyMSkpY-$N@EE_yy{3v}*6)$jOu8D7*2Bn!!J zB*9K9VyL`-lj*F{NaBo{Os6?GtsL@HE?|~W2E_;lo3vHPJZ`L1;{N+kR^H}*MRrEk z7eX3a3(Kk)3^(1L+ zoUn?tEWVso-%H(NRe0Kx97fB%otIc62ITPzG7I)Jh_vOzzhUqol*~QyD7-=&0$Sv} zuTid)m1PYiK^vAZR(a0x>vLE8`Da2gJQOpA535rq4Q7 z0$c&o<@Q7EF~il~P?3-_gp71Uspl%{PVwO^GHd3$_cCjRH`r3j6U;xv$nmO*bzwVSq? zg4WqsRzMpGFspo%f~Z*$c@ykL1z9Ns_nkB@<|eL|Nn8&WfRK4_@c~Ny3vm7|bjRs% z`%q1=YlBrRvK{WG>}cU`8QO*do;8cP0@K^I2eX3|l!1msDO8u_hs-ucrj8dSga)+!j&gysHx zz+aDkWd47+I;SAff@Mv&ZQHhO+qP}nwr$()-FA2Hwr$()yHDJSm^o8#tDb5_{<&&Z zR%U+mJcyy?DdW-cC`#3rpEKNn-b z-45c}0kT_;KHQ9Fq1B6JAmjk&7d~+U?2$;7V&dROqV5%PXr%pUgkajh#h^wqd`7NA zbws?w*UftH=sbC3r0wk{k}Tb&YWjOKto42R={ofaoTYY?>e*#^>_9YI!>BOtli3*R z{<=F{vSLh=G+T>8YgCr)c=iSx(1PW2d%Sw2Ip$4RO4Z_Q7K>>w62P$l<%n|kPkva* zbJltfNxv1865R-e8!fY0V0ZG;M(NT}P6yRX)I18pe|~(7Feho_*G<4w&5n{a%h_C3 z!(}cf+`HNy4@X8Rf}eXQcu{mi4lW$=zfdMy+cum~AZr_n(*D3$k#sB9bbR0p5|>wI z&oqk?%uMfn#X03$tf9&Hd5L^zhX2Dr0vrU{yr|hLM;B-(y(-~ai65a z>{2vKoE7IZz0M4fLv0#S1Mz5wfCgF5~@|VV-N8vx5dM+X${O zh(vu>;->6ufUgx(WRu`FuuNf?V7YBy-WfLIlR2Et#s140sXW)yT+jiE{EX|!Do%g; zIZanV5~fo5)2ZjOil_Jc)2e;*SUSPEJbj8M*@Fn#w za9I$IT&+3U&A;?X<)pS`?Z9bgr$_Z5Nj_)s<3QPI*W+U|#+aN@6TjF9Ij7;o;4gbQ z@*%W=_ZH8?tL2|SZ%kd4(=Rl>n}@sSw%Q{l*!kLI&8e*PS6f>tOTMBNXKhIWbqQvI z$cIu^#XbkjEjAkMYU3*42_NeRKW%b4aY{e$Cn^k>r2ejnyb$?xY86#kcHc`U?icq4kwDde?w^mIv z$Ga(QOQ8=sRWNXS4dHN^If4I>8uu#@SSeap!fc!QP}Zq2ar2&)f4+KPr`sFcPBqqlI*exjIuu+{8luR~H#4JX~w5 z7d;I}ayT?g-U2{s^~qz}5Y#oz?1Stlth@o?c_xH8a$hiW(+yC_9PH3leL%+R%7pkI zqW2Hw_{h9I2#4CmVQ03E5QYmSgXt2ls|4fGG#ce#SkVng99Qd=9v!{IQ{fprxlr_OPMMXIa>W6f4#kU-`ei65Uji{77zddx7ZI$(N|erQgZXgcM?fa^Ejz@L&#C#WJH^8b{~_ zlRgVw^by7)$09MLh z(8EQyfcyi!zydBUjCrC<2p+#Rkm1rFFD$wXb4qg3Wlx4cS0yXkU?fm1^(Vrz6nd+r zNYes!#rWAw1|bOEYQV@7`$kzcp^^A&=HZcA3b7`AIv7EO)3EyWs09b_;sd^m(B0z$ z$1Uh{Z%rY4)`h7n*9EtFKQojO`}JjGG0!MD4yv7cdJ|{KhAWVEvA=F_OH|)xb8>U) zRJMUpB(Wug>IM0DQWlJeyw420cg@I4X!MagPMQ$i_U)o;B~>PS-n-#+BDha>(PZXz2i+mF1B;Gw zz)S}#)|?bHyP^0Z%CQ{nQHQypRPBJH0z1!5AXFnoO9$6xnNiGM`I@by zw$~A+AcV5aumE7&(z9l3B3Bt^m+Vs&mjK*8P`BfixD?%8qmtGe52&)}mbZV00GAMn zeP{sE1_-ktr)3Sw(Pqrq!z8i_w%7%g_wVOeb*$CO@UH$+#$gSce0A5v07w)WF@qw0 zi0`terT1eTD3ikl>3-@6-aufBH)c@f^jnEIw%rup@%4)79h;|s zmygnDrQ%w#1P$eDTRDO(donYk&(J6k8WhtI}}S7oTI%f8BjU{G9vKAjIWvYG>C6 zJbHm}fLe4_>1IH8m=%*oF*&BeV)9?$vFDNH|CM&M2m;nHp$Uz5`l;Eu4a|~$6usj~ zi9H@%!nF9ja^yo<>c5U($Af!Gh(1Ql$!A!}EdzRJ$wq?GRHlj$tn*3;STabO{ zZwR&q$r~I)!0;P`6Q2U|6MG0w{}>=dw**mrrmR`>e-B-a*q&%xAtASwOOH!z&wTrW zOam``SE5})qofA)yK@4Noh+Q(!X7UN^}aHgG{66Gk`t3i$sI|(ZhSytKJrt%7zGKm zVak4EqJvAsN_w5Oelhy-EQFn*_ll3vl=ycMu4?|6vDH`b4|j~&QFL{I86;dv;*$vk zLMQnEnOd$QIt`SY|UoR#)#uNaZPK-uGKw%gHTO)n!l%96xfX;C@R2^TnH>imNsKZRt6ua);%Sxej!utZY zjK-q8thgwSp+F>H)Mf_LOQtegH?X#on6+5p+Rl@ak@0)>C6AsM5Ufr5F{1J+kAH2; ze58n7nkUt@X5SslVF{ytlW~+0%NGC$n>LE}E3bwV@$fJl0mCE0yz}SB5Zeo216EO- z%QR)0r4(wTpFd2x5KHxxD$yT9^!@e!Mf2Ne;0pVfVY-Y&4xaF5#?9i7x8UFa4BpOn zp(NP6R$j!o>fu}LD&&!%_3L5rq;TRx9vhGl?N+aR`%t`qimTsO0clW@H?c_k7TZkd z+4lajy5Do5{Pw8*ZbIZw9q{$rDU2=aq8^FF6w* zf=zFAaFODMuJ^2_Pz$%@Qw*xRJnk^Am= zuc{1vxdYWUPKnO8o+vC3Mt3`shRfAXbF!ht2z$dDSpQLBEAUMpqGmjE z5-M5is3(GQMzKi`?q7vJ8sxm?2uOwRBL;kNE@~F!^F>Ys^YU8&403*UMVEf_@Msxn zbUEd*HTg3(xS(s36qt>WGN?`{T;l<@2=TJZM1(D5hTJ4uM1?Np4u=I>PA@9t(`<5w z@G5(>`?0p@@*bOH5*4FjW}Kk?p{9=Q%GX|vQ$W=>UX=XGI5fU3gj7PEs;~H4u#;|m z#^T|!%#B|sPWKo|A}xj4d`FV3el8{?Hp!95kQJx9qGv+YaLCtepFja!sCA3N@1@&X zs59P(%J+4ofdL~^xU2&L{tcs;EyHkIfkRhD%%>zQO+-ysMbUmDJO5646@Wed1m-Ur z+bs(eH2OPq$Urt+fF@g0Y+hL+bsv?cHEA?#7)1yZ8CG7=NszXi9a~4e6(5U;!?m!y zP6{Cvu4&*12w8wQ;36E3CMmJ@g7%IAa}}BE`!%8aAn!c3+dPN&<{Ewzl&dCnF?H8} zcuM|W62;>~h;2KCn%sR)J1!lI{PP9gl|Fm0;6Cv(~==%aP#NwTP3|3IcFo3$~ z^TVrm?R?aK!KJopYEc0W^{f0E++3<)*u=?(xO>lnOcY?-=xbpH&sHjb9(X~?Yqgc5!R1@^2xk2IZ?gL&wAa>3Z!h?!>S0 z!DZclr>Dl5dp2*yO#LAu#`;E#1TA5Jm*nkAVb%K`pa>Cw-KyKL7rp%>FD#>$?R<6D`?0$LMOu_D0Moe4F{9V+1<#`t$A>% zWY_9(H84+&EK31Qc*DwR=;D0~?iEgNu49XPvCL<>hC9`{@or6&A_&%s5jB_yb$^fJ zNTo6jCim3Krgd21Le*bt(aJ6wngYH!h#H*>YZvB^6#o*Gcx&X9{gpf0NVZGolfD>V zo|rEc&WhYIvN@i-BX$5vNn?=Q1 zHPu2+ySNn3R6A(cj37iICct$LZhLdg-*w7e=>n~%pqo3!mba^`HR=cQrdEGy^LdID za(^fa3-QUj;GkA%M6Q};llMa^9@+|w_rS^N1w45$Y;{ETGLZ_Yh|JIn19QuyZ)8w}>eQUc1r1<-V7zZS&FvCqcu9c&;@!R#y&f(_7V zU=}+p5CB72**mX?!tq&nO+T zUjaewNedhbEeb?bmk*Ok|OSU2gTEutXQ^Q$Ai_aXbS$!=Dq zw#$*ucCP>C$3uUrxHQPambaqa^-RFua~2ZvZS#38aTx|HQJK8*YjPTrX}gS$nfO@r zSp|XeX%CZ#a-~=1O9DqNQs#+GAGPK;Y>Nf+vzEIl`qyIgV8$VI-o`GpN3gvWVU%N3 z>!&T(bW4ZN05ZLNkR`t*;c!}98wn`0_EQ|%_cQQXTI}?3By>QX>M3U5 zPL(1BC3OXwYpWbBGo#?MoNkcOuk>a`!ylpdMx??RJ0WlkI3i+B9BYyb0HU|wx&D^&XUTb!Sj zm&F<$NTC%L6VWJj{7`0;U;o5c2 zDHGaKd6){1z|Ni0_)hWB;74V7_E+V7=CYJ6!NXUT3i#*svmmy1<&v^{BJWQx<##nK zHs@&;yd(RP#n%SAHkPf*9R=#(Q-voKd<=e88xiHG%TH;ikucLH9Rj4`aa{4pfFUi- zNZg26wz!5yFrgDUV1VFiO&+)qby8yiLGYGFScsBp~=Cdm@t~0TI;dxkTj{ z!cv&J>qqe3{pV(ajjZkFl!ADiH6Ckr1XWuFd`q55NXq%8zGM-IvtJi9Y+U04og)GQ zssd(6L*5sOfEmZLHJA8+gJV~g?W2SX8?oxopLx`(AE)0J^m-Y*ZA!b(DIZ+DorblV z{TRcGKgP%=deuyt7asIkCCrL|z3fPt2&rQAO-|r~GUK+ljCyD5;^)*qY$6x6qbVaZ zu#gVHQNgYH#vY0d-9x~x$1hj8D%Kfc?A*WxfX~uqk>RoQ<;Ev#y3x{8j5^s3RFhY% z%QO*_m@d20B#Bu8d7&%A0v`O#*0f7VM%HsiIjoGF6Z9V6Psf0ewsGiQjO~~ARvH_+ zg9yyuK}w`wATaHEKxY~WrGic;nCce#dd({^C7lUh>+D@~8DN53Txuq!?hl#^PyKG9 z#pPl3XvqpP6KK-DE9nr*D$KAmfH;5<{k~Krof<(>yv_M3sMiQBgK)JK(Gz!U!vlN7 zXxTB5uYfIjL~24hk)oV@b_G`0qKRUkM{xSI8dP)YFYYeGi?&?3!#(pji}fII(yt`MdbXaQ->9P~ief z(FddJ8n~id%0MLpLemK&ejUWKc6QNpR66|2)0WRSTd{+3vBA2-ua7ICV-(L{kEV5I zfUIeqEY=#7XOtoJjlf<6fpxs~-SjcuoG4*;od@VaJPygT6!Z816f_3H6YqQYk1m*K z3&Dx^I}Iseae?v33Gb0h$UBP)C(b94L?Gz&*S1LDNV3|2@gnx zw2$a?0VObZ*+h9u3=|bqzkGL!T`?-~c&8jnz*{V91_kM050-mm$1!cg9Gma)X9p_zCXt>OP&05k4IvT=dVEd$8ama6!_%i9{w0VNC~L2AYf(h8gBJ;JTm?@`x2ZFYhoJyc2)v)ZgUx=QR+O) zeK^J?B1w|qTdFgIT2QjLLZ37%oa`m)266O)h_)|iQu(G#{xi;0{uI>C1`_EXK|*k&%W@<0w2u5>v9B2tkaS)*j8yxEP0fah0MT+ zT9g+=FfrM-!35|9^N-|@pC0!;08b(VCzPs-NCh|4azj&vCTEfoN6%kC&M8{?uH#6Q zFHn-))vPbDv#Wl)wplT(Z)`K@kLt3%);n6D*ZgE=XoRM><={vBM7wcLk&R1=VqG~t zpPQxES9hsB5ov2#m=SZ3Zy#4pir%DZo}8AGgnRXk$oSFZ%D}m&FReu%o@n3_(oGFb z8$|r1O%_`85xNYX()ah5hUHY0lqA^2~{QP^n2_ecf?*2R3ju3dKypam5)jYHA4kKOs0nQy1f9NpQ6 zed+Cwt8t>_^6>AA)gyR;f4b-zN2Vg?q-afq_acF7dQD;>HVWRQFe7Kl{E4I(s?^0G z|8q3y`cc={;$r79R(y}(^!V_g@o^cL-y6X zi5I|yR+59SRx4w^md1B62+-OKjJ9b9a~zH&LIqt&I%$>rk@T-Qo>GBRD6(APJ za(Kd)IZA_z1aSrO>H)+g2tFM1ZwIkO=An;``_)tfpM)@aTRI=yCc)a6ITr{-&LKBe ze7L89tyt+({_SXA-llzV*!P zC}B*Kp3%9i0UftCD*^?j5B_N%~`h>$oLzIwkaxf{FT`Vi)-8f+vU_R*7qhE2v;tQyq6BMdvFP>JnsKYo)Dm zp9g~{OVp1<7vZ<}2helIO030Q)K^6!t>!gUg203UFC%((m#Cpz{G+oC>b|Bu3B1?N zfBkVf{qfq44V^ny{6O?MX4Geh;7FA1r23&1FsSdMt7~pShJ&V1KLvzvL!}$f>+pGK zC?kDw!Kg+p8WVX)7{{WKegK)o$gmYBnn5sC8|+Gp`>Mt-ZH)6s-|nb6xmd@veg>RH@ls zu1MdITl6DnfgLXaBI^X658_R&`n{6O{ICmy2hm232O)u=gIycVmsKsB-G`a*9{YaH zAVHX2xcFEtgtA?OJB~e9L<$JlyL83VIx~(US;IGVlKdBZcd%pSrefPB;T}u*c|uh9 zW)-*PWEwzayUiq!yd1qD&-H*KVguX%mB&%?sKs_Ab;WVS4FojCgNGX>@< z&aP*<=x#Wn?~|bL$&pHPdK&Kip!5Yro(6uUu9xau5ayWUq0wS#XJLu!OtQUf;sau( z5Yg>GXDJr2cMD8&X;jA>07o29r1_%(X>ViZfr->yc}M+-AZb~5k8}jCXaW!uzt}(4 z`2JCv9LljXL^hW^neFA^V24kEd9dR14O4LdKZzF7GWKN&@RTnO zAphPl0@%+o@XXpG8GhAKj@snZ+VN%Le18+n8LT5+7AqvbL9mFAjBb&TK7X9#yv_eU zVLdCKQDGvHSecXA$j1UEBW^Z%R7V?-1tp>-qji_@fY*9KN12i&q0q~$OWX2=!MF;J zO$iW3o^FL%44*0)FfEv#f_@e7}6sU zmrX1y0EP+0%!*v8gyGtSN7*O0a>dEMp%~UWxz}bw8Y91_sD#k;3=A6U-@$qXKXi)5aQ zc{T{&+s$J~QaA1CXN!F!7XEx ze;1%$3}Vu1Gz~0P76I4fz+RgF5Ni($bJ22$SF-RC zX_3ryMy6a$q!HX313!ecTIOj>wMb3dQDgL!YVp831P2EmwWEmS9_v{EKngT=4>g#weM7d+JS|RpbDSu7p8K z@^gQ7ly;p}R&5hfjBsC*LzkVi-$_W*c@viy%S}i&- zND%Swt%#>28%)gPyTLOxbFx1o`#U;_896$-c)z19*A#vJ@Y1{o5w}cJxEqS@Gw~L$ z)jqFu6x!7r^l|1ynQotYVgX2O4k%qEHn|Qhzr(BbAzX&l9rr6CZv!S=3$QvH0ej?+Pf+z4i8#blhnw0W?I=|6A-GVY zu-q3SRHhMKZrW1S+Av7?9P5j^P?>$q7TP*gds4tsCTR#Z-=X>MIB?}EU{{GslQFFH}_pSpxK8{&n4(_ z5l!i#2KMj(dtaE!J@gy5m(tL7r%@7u>5=@C06$z|ZXCI^ZUfzv+Ppk8aaK8o$tYtA zMrpB3{aV<4UeIpUr-}QYKlDV>$v|_EXIT56MuM;X29A2oaZ_qcvU*Ylx<-Va!r&H2 z;(*XjA|tDgJ~7{0aDv#_1%H^^LKVSM&Gvh*O$L>^2Rh|N8wGJ0am>gAJ2ZYqd&|$~ zaOm`%nDw8G-ki&Zhc(1Cj_|n;yC+Sr%k2~5wyEY|4%yinQr^C8u{Zi-&hJFh#!&NZ zQ{=X+deLl%tO)lwNZd3d1CPJ{vPVdo7~_9G zn&24^s6t`)sKNO-2VB^ISJ9sfY%n@~S0rv-3-JMN2HKc>ROo=5N&>Z`qEt%DgURT4 z5v_arCAwHK(y!;3oB%>PsP!`x1+uUv2$d+N zQ%vWqD~Q-a*0#G2HZCl$hn}wXauV>pZ4?r|DOxWEKGYkKnTe_$KU$G#w%rVa$b;(V zY{o|g-z6CdWf7xGK%I7|+u3eJS7KA)NNM@u@ly*Gxr0Hu$8V-EPv9`Qi|W*uskWqY z*OJIQr4au4Bva+IJv7f_P~l3PCRlf0Ue3p`K2*i8f}?u9JH>)Fsrslh8|f_l+H&x@ zU(4vX&hP|L5g787D~zXJ42V?m0D`BAa)$bH~rQ7`o{6H4B{c=FatH3!=a|aYDxZ|;`1gn*r zT+%_t+KAp`HySd$42ags)DG9SxCN!kKR6iH6eL~6uqNptIY^Yd>J@_3BqtZzbO?o; zD#w?sWaG}lT*2EP=l4sbZvx7;*{Uz1L)hG)_ty)+C(zm80Rw}cxqDAKCDmac9Zh1^ z8KN_gy4$M18fJ*z98U$<;O?XV5qE@lU6`KXgWyUd7b{c#C>EmSA@`Db z$sC{=QO+k=drK&#Ha`53dgei$rJD+oG0}an-U~A!O9>mInq?#HU}$ zxU%zlF>Cxhwo1-NclpE$8;b}_t(jxqmUgu0d2$f5Ijp1QO;N6d} z8EE{-1U|z_uYvhdoLx!JVvA=9U@X+6{y4ORjvgsx#M&sV_|8TDP8=&bKx(PjcH-;E zU3LKo>x{knob^yNfaQ(txlZW7z}W0r7Ksquv5b#7LtOE^gkAGZj&^W@pAaP{a(N6a@GyYexEj_#S01D=&2AJ&Y<0!UBx1#qS~0f`n?Fr5@WQJ7tU3c>Z%I!Dnd zmqs08NW;Oy58;@3&>XSc9pweUI^I#{b>7T7;v?y)=J9gVj61Q(LDt11pWIB5NE`>x zBVpan^=?9Gpx#vjZ37+P?+m+k^Quej%Crm0ERu-50#_cJJ9MwyRzx|TGHCTZtP-2O zTN7SyzUy-Y4j=>^Q$Qutj-HLI;h2<)9qmcgZ$a_XYvu3suSjb>RKOAd-74X)K!-e57wIYpJWy`vH|^(n+mFy>4oovSU}G&XaGaslpGB~_5IrFG~Y zaNrK{uM$2O6;+$%8FBRRE&rbkxN`Rv(nb2*v`E-`>-11O&1Kr?Y0mC(DXg?#4)?F8 zYReHZ!zn5v;F&9HGubyTPI4dSP6|%^mIislU=^4hNH&&BWEFd(#@2Z#3>8P8%AC#A z44MXkAU#yP+@={Op{$npz#WsEw!KBw-c-E7C!b}uJwsJ`*MGhfB1)&^olwI{O~e8BVSK`( z0}#@q^vacENtt7drS4Iz^}bpndwSOlsSJ4*HYTe?i7{YrX%==ElUa zA4r$@%^bfcZ#dl>+w%|lbtf3qcA%czJw)7bOzaTe>D<)sdz8QN#yxA-;mPS!Df|u5 zbrt)E3>m_AR`VtR$ zkT;P1n%NE7g$C;dtxovW=DUlh)7k#yU;0gD@|G4Y{E%L|l1HyY1$%Bszv*dO(Y}Iu z_IGLf>0k;8_p=Ut-5|3cSeEgp&i$GvOdIpF4uAcAwC{Ys`n@juJzTge{=HuC*cJOp z`x?G?SANg$s65Z;W4-^xn`z(D-09=u`aSDYTkK=K``oE)U&AWwlKXt&rH{S zyN*a?U-kH}379xfs=cKdo2tL z-i5sdR8?K~zJ2I!q`SKtC8Y$F4(aX&0qKwskdl;c1f;vWyFnx+q`TqUywCIge}atn zgRzBk#_&3md(AcPwb!2K>>ANoq@;BL1-CoKB^zf!Q^A|*D~@;{Y^OQ7YnAD(4$X#S zmENgS#*k@&RsK7sq5|uPMxvs*HG-=*wV?}5$%039j>oq@GpYuYPcc?CZnK#MnS9l; zCERO0t+6Mptf3pWqd2ZVA|HKeQW>`T8oj+9-*Ekw-ea&6Z2l^lTzj4Q$J`6#s}SWI zP2}vcD?C^aY6Y;f4<3zaV>{Yg!JgiC%o&qE7Xp#-ywf`{VL_m0m>|%$V8}acQFFc( z+344GVqlO9gh6LEV(s642Nr5#aYaky;6YL64o*`n(A`l*+IxrYm7vyh}+ zDoX40L(wv=gOM?4?XzZ%jEUDE_4$Rs#;eRiQGGM|9@+wtvu@06L^D?^_VKib;2K(( zp6arMuNA~a>h^*jSL9H0uUYRyC_J0mF|+;DyxmYp=Yszkz23L4j!xC*;Oa zpxcRSlQHy^KZjnoFRF#hZ0{0!GjXDCft=R3;TI+Q5Uq5i$H;HRHY|m$HX?P|}qKKX|LYiX`@52tf6)(6< znKJ7@*8YIk+n(C9Hv6NE$Os;y`GBbDQr>t=+vA#ONL_cPLZ?)Lb65fp(d{b5ua_StO99X=TsToz@x}4p5p*I0^`;krp{o2Totr6@r z0V*Li-k=XNUNPJO2|e`jO!m6hX?%#bX2^OIp$G3YLcgmBkGG5$CaK1nO*^VH>26+e zD;#{b$JZ7xD%?ZAZQapOtxZXGjsJQx5Nnj(Wlw+G<)Mat)Q{{TCwTjV&->1r6q?9P z+4>qok8%2r{3U{RG+5nhCP*SHZ{oK0^uTfO8g*fwDIt=PMKZV~EZdGODKcD%;mmBk z^11o>Ofo#nnLZPFYIggwV+f0}Nc=q1-^=9uO75Bsg_eX3w@ol9`DND-eb2rVm5i2+ z6TO2_)0jkb;7s1IcotfL0r^}`nA3?WS2KudH#tz=R~Kp!m3=s=`Rb-KSjLatY79Dc#g-@ql$x=^gcso{VO@210hVF(fD<0!kaaXImQ9e08ORfgK8Ip52N zGlVVT^79F~LOdUbvtaHQuX8+y3vcM;Hhm^rHgeob zxT(!3z=$%L=NM&YugR!%YZrh(EHV|c-ZEosvZ<7<{>?yt2|9X^XR9&9H(bG+BmIqC zbD4OJEs2s$-9fJD_$F(1b^-HDa7$;?ZRBrlZ}7Y@(%?@GyIB+>FN6GL{rTS>!L2Ul zz^ytXNl^(tPnM~;)8x?mLc!P(Tg#9f8(7f+W5=4Airela4OU0G*3weL(-(aBN<`{1|u;0xYetnSAjp+tQ!e+@P5#|1~` zr1o_lETOTjM|^uMooIj_GtLi+Y;!)Hlta*Hdl!?5FM5B*uW1QRm?6L|6GGh%tDEcF z07{j8al;vF)Awg~xlFy@N}d&y#obYo^(XE_kU5@>b;Pxrk}mKQ>WvDQ}c@)dvL=~GEvc@$qS$T(z?@|YTS7b zKWwa)W!On0fIV5PN*%yjJ-Uq^C(wwWj^3A&+BZA+4Bl&?6w~3;XH&B&`;AHXzC?=8 zI92)Yn(VSRc8@r*kP_*^4v{yGpkj!#sNcFhPlf))+8jKVKrHj zMb(B0&3BuyiPpg1)kyQ2RTkHDElXItJYY2V7dT-Duf!+lK`NMyLG`1YGzx9MbyIXf znlE3()r02RqVjOLRgh(MmQGGu-fSR;;08{;fXPcV>l|N!SQ}Pg^bQOL?faQEGUzeVlp|(P{Ao>{6@$Ok7O}%(;k^(@Hm~atXKOyMlOxcHDs&P_*H;(z@Eg%&_$!XaBi0@$a z?&KPr4f|PL1vfp<$lI~v>Me-~NN~SOwvMhDgfPCPsxx3@O5!3X4Za>d3??CR$O*{+ z&C=N>noKseGY~Kdg?#x$j}_6qQQ>j3Z7sPXy;BR1>`3DTi@i7`3<)Bx5&OzxfjnVs zb6S-BtYlj{dtX0-s?DrVr;!#buBw~UNMTJ3M-VE80@v^Gyd~an9_>x!&h!%reV znoW}C^!K-gW8cF;=R{R*fAfj9QMCAtM89m+573+(X(6i0)->Z0ud(d;2JoOW$)%N@ zc3W>jcb2|Azk&07&$j}gJA@&pl5)-pC&#oh+2r_`bk@0Hr@;p3RsxNqy z6ZpMcJVNAB<08)a!8UkEI2NHOH=robfLk1?nSvy>WXUOXDUB&<)^b#yQCMfL=9o}y z=9n0D&_wl1guO|5^HEk_-Uz;&VEJI=1dT}C+jbrD{Eo4w+3H0+AtWdjbm&<{oC!(0?}@trbR3TM~C8O&m0q-MnqL*{u2cWO%&E?Lseky+N~ zb}CxK$)9@_6_7NG3&K2nRINMYhS>(K4 zEd0i}04v(SKGD=@3sDQ_1s=_)&Om+ZvyaMg`nbAm-R6fnZ&RaVY3s0 zVp)`?ZXqF+9~ap@+a8egd3+3GtT#MXtuU{PTl<3g%ZYljj9z|gL1-=DgKI}GTO5W` zT2=K%&oSD-LELz?yBDQ~!a@H%K_j%)M2os3oH`$UG!cC*rrJOVurbA?; zsgF?_fl=J2V;% zd*u7;>RXo2Qb`VI#3W&K#h3bL6`XK#Rjqmt#b*%}En-L*+9oqNdNc&y^(v`rnx#e+ ztYlG>?Ft=9o$g~MvnCGAGA_k|D!36Y@InI0Xfk3yH@Xlk!2;RqGvX13J|>Ssf8UJe0gZ?3?lnN<&L7W59#xHDwfhN+;&I71%#%Yo$uFG$eRN?aQS; z^?py^;wbFfUB|eH;y|p^=2w?I1KAS@x=uTvy+Sx7H0Bqqve$hJj5`(|<`BjYJJMkE zq_b%UkdibV_Ba_cXPpZidlT4j@DH7>CoY-6+HO9^V`wyRsOIE%RI|6`t1-4r9jT$5Cc9G`#xTIxcyCTf_W!9g4Spc>s8=gBrd#% z73ziXueqr>G<~G9`QJU{-)6R{l+yH`3)q!u{&w!bLZZhBkH^Cr>&`lQLxe$@|-7zL2mUgp*=`mHhZ z0QcQPq@g^->Ygvpr7wF1jnnlB*B7cYM3R8cQzf~M<$ZO?EJ;53(DyiakbBaeuXezu zRwpvl(YIihy~SnHg%@$S1L9IBSY`Nc%G$!nkyX^9W@a(EK4b-4#EYQbn5xK>5B9c% zj|ET~AqCr0OEd}o)F6tsI$C(99M`rnLeVDVJafdoBk#GFG<`x`iL5=`kD}zY_~Q2N zwj9JHkh>-d0op*l+55brYbIm-!`IOAZTrO{gTSVzll|w_H_eI7b&Qn#VuKVQX#Bt^ zpl8ycq*u>L#m-}l!Cblg*4_0|HiTKIve7X)%~iar)@6GwztFdF)$8W?}sxc10wrIt81sok*2++VOX-mRkMef%-WX89`>=W}qjj)+gKP0jHg>g{=vUJ}utUUt+G&m{@8 zlv62uM{If~jEb@mzo1)OWeGk59kE+7kMa|h-RtuZeDc?-Q&uBv4b#dbHzh&IEt**`+TWg^ z=T7(IU|jF2ErJT+v~0R*jkofyV~8Pk>R4D5UwVrv85@(#x#v)W4rU-vghk@x8-n@x z|3}c-l69TL4m2$Xk*&J zBo5KSMr<>Uwd~s0KhldyWx3$V64=&dp&H@HS3lTZ3{QIx2$iyi<(HjDg_ME-2yr+F=rcV3XQh!F>n z!s_^gOoeI~V$eTY@A?*wPSo$GH(&<3U(S z7RcU)Zta5@k<^=eR*P~2^d3DjtVz(rV;1(SwFki*27cs=H^uY?^Anre6ZLOs=RIo> zA;Vg#T?w3LDW-3w*bL9T9I!ZpttPKE^1GL;NyCMNThH~^xV-(>5Ax# zlO4^+vYf%GiQufe2O7&av556xkB8FEMR56w}^ySs@w*O^0w(M`oS75zDA zzA3kit{jqb!4|+HNtQH!^YShu^T4KvMK}R{abYCEJE& z)QysG`)y>KLOEMev0CxRM>ZxF$d@h!FUEoio>xeKqLQORVH8a{q%yNsYY+XerIpJ| zzYBOuMvz4gC;CJ3Y`>!e5Ry=4C#@f;E?D~^^*WHW(D26s-G z#JEg8Hdh0^FIT^K&Bn`k*?_ZI=_FH@lzX)O*(AKE84Xr)iElB*0DGVvJ*J~41AhH; zLQ1`w;Ip$)!-=J9wY_oK1?*Tx2dz@S`5ZnttHPM^=Zrgb3*@$K6jYPCe!O)?*+*Y~ zm}hFTFEOQ8KD#TZaNH_5FN^h1Ir_kYw$c2_sAd@}qOQ;0^}Ov!fDe6Q%$iJL@fT9f zN(Nlz{7@C}se{op8--*ad?Q6j>*onF5}zl$!4YHitKkbas4%+8fT=664fOK8S~p#= zsZlg^yGT6w<*nzZV|VcBuu0{M?IKkE1UJtyD&cmf*H}~|#E^M^VK15@_RwSzo$>6N z?#(Lw_bav~Ld4Krb!p5TR8P}4*B?Z${N+@S7xbj_Dlv zdjtrbFKx5}9Sxbp$8n6;`Yak;tKvBmBx~QXzp}tj;3uq{xEeW{%jrP^b-mh>7KQZjD9X-d+`pN~}k8*2mkw*IDdN;KjFy@%EBD4YWl65c8mD?*FSJlT zI(0SwyK~ZA9k`Q{%tm{mfz@1dVFw&Rz}2!ZxLt+edo~0YEKw?>A8E5C&k`fvA&5g< zIV|HD<=VB-t5+-D5>Z;>loCV=Wh=DT9v8q!)#^;43W_Wn*4&=~8|6G7UnsKxY=OVENh%HvN&a zx}t^s>w9d+-O{eMmtUwRIB&ecr-^!bEWuwpzS@zYA9yY}L>6WTgSKFrxpjH)V~{xW zYBUDLFN4c~AsGAx3)%#Z3^)=i1{a#3q8it&xoXr^DbkzYz9nQ@$wr{^kiZ z}!&Bk9ze=Szc<|M014B1y z5;`JJrm0@$`6)@5X5|t1ekiuD9mZNGbV#^Za}{_V)n)fw!U*$H|IP)B+ z6Zt?jJ4J%yQCM}R{Mtk)wO4bYa>O2{T>Z-Nt=M-9$|M2W#9|uzm_1wad83b+2HzF) zLgX*axA>~i->L_s?>K%5-_+|en-tfIUH5*GN!K@m5}Rak2@~0Rp&2!kHb?vpnsWl? zimyPuueR4Cftp}?bT#JP{9bt0PyASguO|}1QMIFaPX0A-!2GeTx8*e(WVSrSl24uY z5E^zFpCc`tF3}m}&{+IHz;)VS!W^kz&W)z>E{I`Z=DvKp0E*b7wO=j`cC6))h!5GXwR9VSQ0x>rI99Z< z{A~G5=dKcR%XlD6A3j3F>^eR&w(ld6ma_0wdF|Ij3#KNk?x6*?=-3K>-8+fmi=;sY z?Kb`QlP`Ps3ro0*LOs7GuTpaT4zX7Eyp1_XNf()AJL=Lu5smGys%QC>ph!Y+G7@oi z%Q$Xj`8sdza>r>%o!+Ql>+LPGHg8S-qJD{ct*d@hhPF71g7f)1|EhWamai6lCd5V} z)GiMDin!IwYD=D{HMpM77B=|DDEq>Ukujlmk;ZYRcwO$+%fHLr_#CWT>PFKAdC0GcMnMh`&4P@?Dxa@yMYtKoeLpK%t)m}RI6x59+ETCl+a7lKNmw{1!O zN-HJsT7hF{up43uXEltEk7~Vs* z=ZgBJ*u?u41xt2c9r`&5Thk4kmx>UNgg2KXC-J;~tqRAH9ddD!eDI7ww!^?RW` zh4w*3=hcjlHfS#QT7#8Ev=`Z|>x~D~v~n zMx$(#`j!e!kE`jDks61I6@rZKhq5yyTMz3-q`zGo4@8_*jMJ^8AVCMZ0dj2;0+SWq zsKv3ts8D}uxYZgoAAxriS8m|@B=w((ff|HnIli3>G%r@yUN6G{sOP;{j0MpO3jLB zzdNTp+h0{htmHAfn$o@4%4lo+Gu2ntDXd1#qdTfnld{qKHN3$RTc0H3${o~|BCY(6 z-J+gxuO^!I%SfInX4(}9$L$p_#snYEKq(9V*oG3{SAY#07I2T#+!vIUhJXaF)q-F_ zzQ8<2_K>I000)7-LxDihz_a!ay5>y!6N-D*vn;4L7MZswIjQoD1cHb8Br?-|~ z@?4=WRTnCusCLXZA(&%Yc!hr3hA&X9j){`b@blQlUylT3xrx11?muJ`D@j?_AZ9*e z6o}WFmmw!D4hq3%t{F;ul>k*DA!~*ez2lUPTBP? zgN+D<5%&GJTj6%P235w%+f(HX8wXN`an%+BQ^Nq9Atbu$bu{AZ0XR$bg-ysJ?b@X^ zW#4SWQ<&&$t1v;0vm9Fv+HuLUkr_MJh9zF-y2*@MBG;m$QkXED_s5fO>zoAC_xcMi>`m7?+N|74BEx2B ztnI6Blr99SE+8J}pDasv#~_e@;xK>YpUH&cYwI}{#1}b2cM!~?D_GJ_%pX*t5pk3e zMZfCtzl+&a4P?ZNOdQ8QU663+c~ft7MhVk5O1|JqQP>xJx9;ic?gF&ntTU%H`WBX$ zUYk#Uc-OK5KRJ#cs;fVcQ``bwm%!2LOVbT2A)ZF)Yo-5c8ub{fg^$#Ugn`F`ANng8 zvcdaG40K^hQLdLFT?k4X0$y_J0_J#;t+b=X?TjWPWE?N+8v8`Nx^;q)`HWN9#zm}( zbxY@!co^BjMSQbGWh0y#3Ud_Vz4PUKh5Klcdndw=%)r0kuBI33LR6ZC#gwFj$;A-p z3oE6fNi#&Pa9`7x$m3xLXX?i@#@ue^x^AUF)oc^Q!NxGd^#p#EP|L8X=WL^LlwdG! zNLe;s9NCs;%hf8;u{Sy+UW20157E+ zI)(u3UX1~ zm1!&q$7yPL&~uO96VNlL6a~KOXZTH>v3$6zGTQO3xr<9TU6LC@HH*?m4?V4qr>g*> z{i681Ige|bgH_N{z;pgN6BdS&-eq>e8V!e^f2jmSgEjmZYrt0Mo+Jg)4DfmI*`lWj zZHj#F0}G~$j3(~7^%?}_csatUEmb@a>!oO>MHk1M;|QRH(|9Fjv<~|>BwaWzy=%cB zb69`kno`BXchF{(jEVTU>T~wd*DXEYyJBtktS!j1%$q{aeU-PeW1pb+wXuj6s{0+y zjy|99Hm17G?<7OkRw$Q>X>v@OJhAX{313P~QJlIceg;YZAJL)=>n&A0j^XYV;RRR4 zBR?-m%@CY?3B?V~m%57JZN}fkm+0hph=de7b@feqW_bo+8wJ!RvUmT)K@J)_lX!1e zwteTv|9kgMQMAowwq2rc$L(~`!o!RwOnv334F&=+LfqHj`-*F4YGn-6-0(RwUm;Zg zB9(nYf1wuV?oBS|2o5SVA259rYnAzSuZhJt5nA`N!G!rrtV@ul@D%U$f}lR$-8$}E zHW(K{#y)N_sv)gs-LNj?0c^}kVctt@Re3CQxliVDD&X&*7vle%91u&j!jtZS;ftlC zx31Cg)kw5aMC3qp1Nxj5)0ZeUtOqK@!KS%le;_Z#}-oT`x7CK2P+azWN~WN-k-x zb$QBI|txz#a~Q=(5X81z-@^AVDC&`9StA zmP{rSk@Ig_g-|~h#rio-<2Xj+$6&3B=$D>K;8)JSdo}Kd5FV2PJ6Zk{$HlqMfn)Fz zvQp({a637E)3oY#Xl|!myf|p3UOTWKDGBBeOWg!vi^c{b1xe;jX zg$iM8VAZj}6G+_f>`CS(D3>QOjn>uxo~+B@ zJ1*@c_mk+B0YCi*%hXZ~(m|7ZI zJ326#to*{`lhqE6l@<Ow4t@=uY=|FB?-BbHwh&tBStP&``FZkAjiuVuUG`o!*Tyb=`za< zj5#m-KX&6}ZD#;XJ>_|;WpT_#F7!Q?g7FUM$nZHnj37v3-``O11(o?`%!%==syJa& zT)Jb~dp~)NjfzP(A-+g1^4={t4HD$cU*277p3E|il51y22};(WnZiq8GBWopNB-z> zkATDcLCdHXq_~P74~H)Pwlt7VjUv7LjSA`^_K6f*%x;a1fDKw~>{k@y(L=)k5lyhP zwUy%6iZ2V$p=Ms>OKXl`U@VHqFW zp#8313p3MA^1h~|&o|lna8qZUufvOirEMI{it{F$zAI?d4P(TdxRnnkdB@3NBMO39 zEQ?6?^28P$y4{ciLy&$AxdDv!C=f2zg$Q>j8?5~U2_fl9QZ5;#vd@G*i&9pxZAhVjjTJ7`Zst6j_qu!IQ!=pb~Z#WJ8g*;Q_~O7&3-%{zU3orL+SaJSU2-I%SYG6 zZ>aAYzvO+H!{~;NHr`k;!Uv55ww2>w&Fsikp=5>`nddDU@Y#KnhVdNQ}UKpdt7 zmU7$iV&{k~ZfZDOFKa2mz^?q*QpA#*cUhOtj>VNH6bb!V?R)TmmuqAz39h7LopI^p zQ5V7amd_V(@au8Fn-B}TzlE)vX&cmH#(nejLJPg<(ozO*U6Hrj-?;1A9o3krD*`d@ zNgSp2P?($K=xTCkg_-8kRcdV2`^#5H*a&D9cIJ`4djF>NE1EeakU*Ut2XDt4=hjRS(LlOObHvJokIRmRc1g__J9&=5w-cx>$(cDpGIG?+z( zlyKljaP>FcC7}YWP8E%>crtDA3j4xzzF^nBhED$maf;1=qw&V2MTe1y5V!xMvhaXu zDm$W0!Rsb%_QX$!^d5FE_WUQ2^B6vwFFQAe=7O{|u2yes z`kGlATxyPf%v_UJ#y8LG6Xbhs15gdUgkzmRNhGmo8NF z2e!Ny<%r4&H8KQ?f+!|$;|petw($H9#PoZLn_;pYt{J16p6_*9c;f$P^pUxt^Ag@? zeppic1>P9J(h2$mQR>}9QzJ$-rg|rj; zt|>P19ryX7QCxi4>)G7-yPNB4R$`$9i(QA&5zROkj|C6lYw&0OU5aNB%9&Q0sKbkG zPZ2$-6&x*26T6Vku8rrKM}B6_HF#nQcw-jvRG3KJ48LAxC(11aYC-fh<)TQpI={&I zIb@F)wDM~RU-qDQw7EgWccktVbP}MzOrA(p3f0_G6lHq##rGMWTBChMgE{ynYczz?PHE}41p`18>NQiLTh<&$aPKBT^A zWU)es^`mSNxl>JuAksC}VbIC*#wRF@HIAc;!czQ3&EO7!G^Ru%5-FrgfhC^c4Zgr( zt=?UV`X(V_N_3hQI}ipfXOj^6Q>W!TRNh|3NOgc$emwI~e_Se?k%(Sao`{mQ<9M;2 z>y1y7vhrKL&w8b(S5ok0dn(Qi0xxk@K9OKwGmNrE+G4o)N2hVyK#aG)D--YQt8V^a zLy4t~Hgt8~D7XPWhc8rjL%V^@zjM&hj_f23+x^42@cmZRFauQ&p|X(^gR%(F*p)VI zJFsJqw(J%s5fmB)jQF6*J~y5|TJ_5D5NO~R7+3p(-Uz~5~l3U(?c%M5X+%yk&X zZQNJ<=SY~b+@1}Vq&>=ttF{|1xUs4~6TfK8h(Mo0>wNure0yGUy_@5)E25eP?snir zssJtEVy;rs^qQxh2$6tPdj7YI;$YoKF@*#*4Q6Tv&+9Ulh~AiagY^}wD^b%=CDK+g z!`bz{{rFmDEH*~v$^5u0rxO_m4gz>c^(@(bRlO~lq%DbzaqR)9!d5%HweJQDMnap5 zgV$wI_*IQFMPq(#z>+43htP(Hx!*BVTX=#iIsVqkiT(7lAzHFr1HW2GAtj<_mEx$+ ztq!6?&Adqpw^O4S$_RfW>U)p!h zR{mFd2a)UWuVdHC92n)Q*JQy+WF=QG`mIn4>JMErSoMT6porLS6~Zds&78bYoUYjX z5<;E&ZNS7fVS3$1Z|b*e`{x|+lB>L{L8x>+t$bb&2HnW4xU5$=(ooT}siTKuy7-Vt ziUp7vLQ2g#4kN^TaC|2jdtjgBJtWpYE8z`6sl!UL6#s^$useDFHpv^GzFy%SpAq+x z9&ShQAz7)gsgv-VkE;w{%DeOU=t@{yEG&Mz#D6!591O!Kt)*ryU@5co@8ex5Zhni; z?-x$h-q7lNdYMwc7kw7xf)|hzO(4YkmRDJ$BT}q1^Eh*hcKhmGVOHMf&y_FHNh43- z_wtwG`du_vF5Vgpgzb>=M=|?JxsAJhGWucZ)Qd}K#`KZ5iJD;VtB+yuN7_yLJR7!o z1G2pEB{Qp59be$1W9S>V1sXZqmMPrO*76~>WW7caU)iMv7kp3)DRgWtGoq}3*Ua36 z&w%ET@G8^Cm=unVl^64={Dp@3o`#hElf#XFs`w~wwj{NgVyq`#fmSl1{K}vS&$;7R zblU=Ay^`3i11DZ=!`kq?9aDE5UWJm@?3|T{K>(?|9ao#|=kM%gIpc&|@|xMcwR%pN z%#}M#u_uBurgs)7L`bkIq7g=#0UJF#E66`xKPI2^L`=o*z+s}iU8+L~CYd|mm^+fP zlcy=#3T*H~hk|uGbAvy+C^cXe!)dGKr5JcOAYlx~XF`yAb0av!=tRh;B;&!muRREk z*ov5xoX#!qjrOxd>I4FVMp0lj`>z&zsaqiqtm7<tsPS?vmWZbjHW%rEP@o3;eTbNAW{WsnF-aIrgy(^zwmqGL3+4nSiz7%-aHdNEg#BbL2d*M$#d zI!V!x=MOPTq*y}Fiulg0&Jtvmp#&+D{>(*)c1lo+4sHAeU#GW3wZXx4^^fZA!adDU z>Q3_P%P)tdMFL0YKR1dq6rC{Cew|zC7`+Hl5N3~&OB5T>o4k7KvcM(hu(|efE*D=h z(EGhFopcA+Nak0SNHrP zZZB23O}f5((C~{87bbOCT9tTnwS@TO?=I=i5;m)ZTj^WGQ#Z8Rtxac`8>#46`rlMZ z-YEM~GN=ieP*Etq%V8>b)qQL($&SsQm%4GLx@n(^UzBK& zlD$xhr!$QEle+;WM=?gO9X-&H=iBaQwYfzOwlAaxS^C@Ag7v?(9j&)QpQml$jO%CQ z5nb7CeE#mlDq!3GagcWfgW4g7ldFu3biFs%!t%PVX|CYb#w;eCH&c0e_BT4yo&$o_ zo4qJUf~${N&q^4?5(jZ}NE4ClOixL+BTZdyiP$a`K(ALLWu_)n&QVJ~Wfw1Sh#Utw zWcXf4(oaS&)Idmgt^5wbH2&2}7d2Qks~}EC%VY zDbLoDDb~Lq$HD^` z$iZ8+Lu@Ys_tnG-Y)Cs`kS$R|_!hQ_&zk13V>$4-4-cnMs~_~zuCi6NZ?sF^NqPnI z$o(!mBB#jbBaJQ7@|zbkT&3p4w1F=;d_$h&Z&$07{qz}#V?<9J=M*bkGf=@mE|?dm zl~7a8xv2SRWA%lj>{s+b{gz3_E6=NqT)#c%>Xw+Yfs^!pHyT5qKm~SEBaZ^Du%gzm zy#*}hskV8z&LdSyEutffB{B7enCB;krUXz(jU>(CJ-$LgX9xl0SYKe*OlQj0g!Y@9 ztbfMpzI7>WVy7;q;dV8C72db=qew*-E}(OcC(J0cr;E^Dwf5{6jSxNh?}=>ZU}isN zc;Y^xHa$}AY~`5Ak97gRj_FhFYr8Y+cvz>++6g&&od&tEO^F$mU;0b;Z;{FV-p8a* z$Y9SxboeHNfMZSxhg_Ab`8C&-<2!ax79&1hHI=(MqOwh zrzfj&YZX5YerjUyVq<8Pvl7|0HNixIapWL4hQ?lC&iOs3_5YSD1hHUATW^Ee|~~M@?x?wJWR5$U&Dh){__+V2nX1w zj^cM-Yy|^#`#K#iw1SbiaMd{ikN-ql0BF0cax5v}e^~$r{QpDWb4G#V9?h%z7n?}Q z;{jVx>fkZk2e@SO1quv~5!l06{Ldc7f5X0Kivs&9x^~9)O!^OE#^k3 z@Jf1i=B8Hqc1$M!3!TaX8TwSnC3KE8!~m%6FLc8_+R@a)!PM%1N8QZ&?XRfE05vjh zHq@X12tDEbY2BYHLjbz#TLRlg4{v@~#Yon(G0Q&>cJp{Wy`!D!^YV6ey`2-El%`Cf_NelLcDfsmVk3$PDE&Y=N;jC36>93F-I zNDCdZ_9ww1$gSrkz>HP`@)+_#$SU+8kg4_mrV3Sd|3yUr65?fsu5Tj{Y9IRJaOs#q zAWL0+yT{-z&Z|FlAbBG=AjDL~;CK;eg(hQxIb{{NfGpr0duaqsJVhc#?4 zBamg!0geA}}zn;(^VkU#rh$;J#w!PW!w^&22C$6pbvzW~VA z28NH4xTS&o&$*GBPVg7^UI{@C!R`~F#D53459bE0Fu=73E*Cur_fbA9+D`r@#67k| z^^K<#FqJK_9t$ii4gy)}TK@mk9-WXMPjaysKdg)Za&iFzKODI4um9!#@6y9X`j-s% z%?YyScUnNAfwF<)AvfaV8| z0D}cWdN7}%RQ_c@>86kH58V{-3*hS>ug)n*#Q^+%e>}t+{ulqGqdvkv<*4^~90CKjpZO;7>X3 zJ^W*||71BZ`p8pU1m#II3KV|Co@YlC^hJ#@7dnmtE;mB8x6R$ z^H6W$h=19C+3+LuQ#O2$4l6zl(Et*J0$A}s3OnW>^b=P6i2alm-?IZ=g>B3L>1GY2 z%0qT%(jV-HwdxVu>j^u?0PMIk^c|lcFmrwau|H&YCI8F*+mi1x*FOAlHbC-(CEv%5 zYJW%P1F&=dDk%18|FCUKb-p|mH*Q3`-T1&T1boT$-sN_XNN6- zk#qx&hifd}>VMGxuPNq#;Ykjep2X`|%|vknQz-SXmF@7q_1IK@b{s#?#2=;Hx)_P_S67LZ@HB0$uxd^_UZ*FJ=}}6P)`X48e;+be>we6)C<1>oo z;y&dA_uPlgw109ri|)Bkc)(-w6CQ9+e%K-UC%Lv5ApceWA7P)W|M%F3Es%d=SxUkG zuOae(Y5Y{}zehjpZTu5m3ZS2;`;S9@qVC^wA2vAs$%U!{2mM|1A7THm=0gGH0R)l+ PzCC~~fQD9}c7pyt%Tql9 literal 0 HcmV?d00001 diff --git a/src/sh/bsh/junk/silly3.zip b/src/sh/bsh/junk/silly3.zip new file mode 100755 index 0000000000000000000000000000000000000000..6a977a8600888bba869d23732c1d190aebd4a749 GIT binary patch literal 559955 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�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

pj~bQysd3@24COO}*jpQ*^F# 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ðj&y+s^Lw$MPjw=x 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 z

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

i)5aQc{T{&+s$J~QaA1 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

A{3;EcV@hu9=~y>i$;BDBjNc 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 literal 0 HcmV?d00001 diff --git a/src/sh/bsh/mac.h b/src/sh/bsh/mac.h new file mode 100755 index 00000000..e69de29b diff --git a/src/sh/bsh/macro.c b/src/sh/bsh/macro.c new file mode 100755 index 00000000..00f7263c --- /dev/null +++ b/src/sh/bsh/macro.c @@ -0,0 +1,234 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" +#include "sym.h" + +static char quote; /* used locally */ +static char quoted; /* used locally */ + + + +static char * copyto(endch) + register char endch; +{ + register char c; + + while ( (c=getch(endch))!=endch && c + ) { pushstak(c|quote) ; } + zerostak(); + if ( c!=endch ) { error(badsub) ; } +} + +static skipto(endch) + register char endch; +{ + /* skip chars up to } */ + register char c; + while ( (c=readc()) && c!=endch + ) { switch ( c ) { + + case SQUOTE: skipto(SQUOTE); break; + + case DQUOTE: skipto(DQUOTE); break; + + case DOLLAR: if ( readc()==BRACE + ) { skipto('}'); + ; } + } + ; } + if ( c!=endch ) { error(badsub) ; } +} + +static getch(endch) + char endch; +{ + register char d; + +retry: + d=readc(); + if ( !subchar(d) + ) { return(d); + ; } + if ( d==DOLLAR + ) { register int c; + if ( (c=readc(), dolchar(c)) + ) { struct namnod * n=NULL; + int dolg=0; + char bra; + register char * argp, * v; + char idb[2]; + char * id=idb; + + if ( bra=(c==BRACE) ) { c=readc() ; } + if ( letter(c) + ) { argp=(char *)relstak(); + while ( alphanum(c) ) { pushstak(c); c=readc() ; } + zerostak(); + n=lookup(absstak(argp)); setstak(argp); + v = n->namval; id = n->namid; + peekc = c|MARK;; + } else if ( digchar(c) + ) { *id=c; idb[1]=0; + if ( astchar(c) + ) { dolg=1; c='1'; + ; } + c -= '0'; + v=((c==0) ? cmdadr : (c<=dolc) ? dolv[c] : (char *)(dolg=0)); + } else if ( c=='$' + ) { v=pidadr; + } else if ( c=='!' + ) { v=pcsadr; + } else if ( c=='#' + ) { v=dolladr; + } else if ( c=='?' + ) { v=exitadr; + } else if ( c=='-' + ) { v=flagadr; + } else if ( bra ) { error(badsub); + } else { goto retry; + ; } + c = readc(); + if ( !defchar(c) && bra + ) { error(badsub); + ; } + argp=0; + if ( bra + ) { if ( c!='}' + ) { argp=(char *)relstak(); + if ( (v==0)^(setchar(c)) + ) { copyto('}'); + } else { skipto('}'); + ; } + argp=absstak(argp); + ; } + } else { peekc = c|MARK; c = 0; + ; } + if ( v + ) { if ( c!='+' + ) { for (;;) { while ( c = *v++ + ) { pushstak(c|quote); ; } + if ( dolg==0 || (++dolg>dolc) + ) { break; + } else { v=dolv[dolg]; pushstak(' '|(*id=='*' ? quote : 0)); + ; } + } + ; } + } else if ( argp + ) { if ( c=='?' + ) { failed(id,*argp?argp:badparam); + } else if ( c=='=' + ) { if ( n + ) { assign(n,argp); + } else { error(badsub); + ; } + ; } + } else if ( flags&setflg + ) { failed(id,badparam); + ; } + goto retry; + } else { peekc=c|MARK; + ; } + } else if ( d==endch + ) { return(d); + } else if ( d==SQUOTE + ) { comsubst(); goto retry; + } else if ( d==DQUOTE + ) { quoted++; quote^=0200; goto retry; + ; } + return(d); +} + +char * macro(as) + char * as; +{ + /* Strip "" and do $ substitution + * Leaves result on top of stack + */ + register char savqu =quoted; + register char savq = quote; + struct filehdr fb; + + push(&fb); estabf(as); + usestak(); + quote=0; quoted=0; + copyto(0); + pop(); + if ( quoted && (stakbot==staktop) ) { pushstak(0200) ; } + quote=savq; quoted=savqu; + return(fixstak()); +} + +static comsubst() +{ + /* command substn */ + struct fileblk cb; + register char d; + register char * savptr = fixstak(); + + usestak(); + while ( (d=readc())!=SQUOTE && d + ) { pushstak(d) ; } + + { + register char * argc; + trim(argc=fixstak()); + push(&cb); estabf(argc); + } + { + register struct trenod * t = makefork(FPOU,cmd(EOFSYM,MTFLG|NLFLG)); + int pv[2]; + + /* this is done like this so that the pipe + * is open only when needed + */ + chkpipe(pv); + initf(pv[INPIPE]); + execute(t, 0, 0, pv); + close(pv[OTPIPE]); + } + tdystak(savptr); staktop=movstr(savptr,stakbot); + while ( d=readc() ) { pushstak(d|quote) ; } + await(0); + while ( stakbot!=staktop + ) { if ( (*--staktop&0177)!='\n' + ) { ++staktop; break; + ; } + ; } + pop(); +} + +#define CPYSIZ 512 + +subst(in,ot) + int in, ot; +{ + register char c; + struct fileblk fb; + register int count=CPYSIZ; + + push(&fb); initf(in); + /* DQUOTE used to stop it from quoting */ + while ( c=(getch(DQUOTE)&0177) + ) { pushstak(c); + if ( --count == 0 + ) { flush(ot); count=CPYSIZ; + ; } + ; } + flush(ot); + pop(); +} + +static flush(ot) +{ + write(ot,stakbot,staktop-stakbot); + if ( flags&execpr ) { write(output,stakbot,staktop-stakbot) ; } + staktop=stakbot; +} + diff --git a/src/sh/bsh/main.c b/src/sh/bsh/main.c new file mode 100755 index 00000000..0e471a2d --- /dev/null +++ b/src/sh/bsh/main.c @@ -0,0 +1,216 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" +#include "dup.h" +#include "sym.h" +#include "timeout.h" +#if 1 /* Nick */ +#include +#else +#include +#endif +#include +#include + +int output = 2; +static char beenhere = 0; +char tmpout[20] = "/tmp/sh-"; +struct fileblk stdfile; +struct fileblk * standin = &stdfile; +/* Nick #include */ + +extern int exfile(); + +#if 0 /* Nick */ +extern struct blk *bloktop; /*=BLK(end);*/ /*top of arena (last blok)*/ +#endif + + +main(c, v) + int c; + char * v[]; +{ + register int rflag=ttyflg; + + /* initialise storage allocation */ + stdsigs(); +#if 0 /* Nick */ + end = sbrk(0); + bloktop = (struct blk *)end; +#endif + setbrk(BRKINCR); + addblok((unsigned)0); + + /* set names from userenv */ + getenv(); + + /* look for restricted */ +/* IF c>0 ANDF any('r', *v) THEN rflag=0 FI */ + + /* look for options */ + dolc=options(c,v); + if ( dolc<2 ) { flags |= stdflg ; } + if ( (flags&stdflg)==0 + ) { dolc--; + ; } + dolv=v+c-dolc; dolc--; + + /* return here for shell file execution */ + setjmp(subshell); + + /* number of positional parameters */ + assnum(&dolladr,dolc); + cmdadr=dolv[0]; + + /* set pidname */ + assnum(&pidadr, getpid()); + + /* set up temp file names */ + settmp(); + + /* default ifs */ + dfault(&ifsnod, sptbnl); + + if ( (beenhere++)==0 + ) { /* ? profile */ + if ( *cmdadr=='-' + && (input=pathopen(nullstr, profile))>=0 + ) { exfile(rflag); flags &= ~ttyflg; + ; } + if ( rflag==0 ) { flags |= rshflg ; } + + /* open input file if specified */ + if ( comdiv + ) { estabf(comdiv); input = -1; + } else { input=((flags&stdflg) ? 0 : chkopen(cmdadr)); + comdiv--; + ; } + } else { +#if 0 /* Nick... FIX THIS!! */ + *execargs=dolv; /* for `ps' cmd */ +#endif + ; } + + exfile(0); + done(); +} + +static int exfile(prof) +char prof; +{ +#if 1 /* Nick */ + time_t mailtime; + time_t nulltime; +#else + register long int mailtime = 0; +#endif + register int userid; + struct stat statb; + +#if 1 /* Nick */ + memset(&mailtime, 0, sizeof(time_t)); + memset(&nulltime, 0, sizeof(time_t)); +#endif + /* move input */ + if ( input>0 + ) { Ldup(input,INIO); + input=INIO; + ; } + + /* move output to safe place */ + if ( output==2 + ) { Ldup(dup(2),OTIO); + output=OTIO; + ; } + + userid=getuid(); + + /* decide whether interactive */ + if ( (flags&intflg) || ((flags&oneflg)==0 && +#if 1 /* Nick */ + isatty(output) && isatty(input)) +#else + gtty(output,&statb)==0 && gtty(input,&statb)==0) +#endif + ) { dfault(&ps1nod, (userid?stdprompt:supprompt)); + dfault(&ps2nod, readmsg); + flags |= ttyflg|prompt; ignsig(KILL); + } else { flags |= prof; flags &= ~prompt; + ; } + + if ( setjmp(errshell) && prof + ) { close(input); return; + ; } + + /* error return here */ + loopcnt=breakcnt=peekc=0; iopend=0; + if ( input>=0 ) { initf(input) ; } + + /* command loop */ + for (;;) { tdystak(0); + stakchk(); /* may reduce sbrk */ + exitset(); + if ( (flags&prompt) && standin->fstak==0 && !eof + ) { if ( mailnod.namval + && stat(mailnod.namval,&statb)>=0 && statb.st_size +#if 1 /* Nick */ + && memcmp(&statb.st_mtime, &mailtime, sizeof(time_t)) + && memcmp(&statb.st_mtime, &nulltime, sizeof(time_t)) +#else + && (statb.st_mtime != mailtime) + && mailtime +#endif + ) { prs(mailmsg) + ; } +#if 1 /* Nick */ + memcpy(&mailtime, &statb.st_mtime, sizeof(time_t)); +#else + mailtime=statb.st_mtime; +#endif + prs(ps1nod.namval); alarm(TIMEOUT); flags |= waiting; + ; } + + trapnote=0; peekc=readc(); + if ( eof + ) { return; + ; } + alarm(0); flags &= ~waiting; + execute(cmd('\n',MTFLG),0); + eof |= (flags&oneflg); + } +} + +chkpr(eor) +char eor; +{ + if ( (flags&prompt) && standin->fstak==0 && eor=='\n' + ) { prs(ps2nod.namval); + ; } +} + +settmp() +{ + itos(getpid()); serial=0; + tmpnam=movstr(numbuf,&tmpout[TMPNAM]); +} + +Ldup(fa, fb) + register int fa, fb; +{ +#if 1 /* Nick */ + dup2(fa, fb); +#else + dup(fa|DUPFLG, fb); +#endif + close(fa); +#if 0 /* Nick... FIX THIS!! */ + ioctl(fb, FIOCLEX, 0); +#endif +} diff --git a/src/sh/bsh/mode.h b/src/sh/bsh/mode.h new file mode 100755 index 00000000..7d2d756e --- /dev/null +++ b/src/sh/bsh/mode.h @@ -0,0 +1,164 @@ + +/* + * UNIX shell + */ + + +#define BYTESPERWORD (sizeof(char *)) + +/* the following nonsense is required + * because casts turn an Lvalue + * into an Rvalue so two cheats + * are necessary, one for each context. + */ +/* Nick union { int _cheat; } _cheatah; */ +#define Lcheat(a) (*(int *)&(a)) /* Nick (((_cheatah)a)._cheat) */ +#define Rcheat(a) ((int)(a)) + + +/* address puns for storage allocation */ +typedef union { + struct forknod * _forkptr; + struct comnod * _comptr; + struct parnod * _parptr; + struct ifnod * _ifptr; + struct whnod * _whptr; + struct fornod * _forptr; + struct lstnod * _lstptr; + struct blk * _blkptr; + struct namnod * _namptr; + char * _bytptr; + } address; + + +/* for functions that do not return values */ +/* Nick struct void {int vvvvvvvv;}; */ + + +/* heap storage */ +struct blk { + struct blk * word; +}; + +#define BUFSIZ 64 +struct fileblk { + int fdes; + unsigned flin; + char feof; + char fsiz; + char * fnxt; + char * fend; + char * *feval; + struct fileblk * fstak; + char fbuf[BUFSIZ]; +}; + +/* for files not used with file descriptors */ +struct filehdr { + int fdes; + unsigned flin; + char feof; + char fsiz; + char * fnxt; + char * fend; + char * *feval; + struct fileblk * fstak; + char _fbuf[1]; +}; + +struct sysnod { + char * sysnam; + int sysval; +}; + +/* this node is a proforma for those that follow */ +struct trenod { + int tretyp; + struct ionod * treio; +}; + +/* dummy for access only */ +struct argnod { + struct argnod * argnxt; + char argval[1]; +}; + +struct dolnod { + struct dolnod * dolnxt; + int doluse; + char dolarg[1]; +}; + +struct forknod { + int forktyp; + struct ionod * forkio; + struct trenod * forktre; +}; + +struct comnod { + int comtyp; + struct ionod * comio; + struct argnod * comarg; + struct argnod * comset; +}; + +struct ifnod { + int iftyp; + struct trenod * iftre; + struct trenod * thtre; + struct trenod * eltre; +}; + +struct whnod { + int whtyp; + struct trenod * whtre; + struct trenod * dotre; +}; + +struct fornod { + int fortyp; + struct trenod * fortre; + char * fornam; + struct comnod * forlst; +}; + +struct swnod { + int swtyp; + char * swarg; + struct regnod * swlst; +}; + +struct regnod { + struct argnod * regptr; + struct trenod * regcom; + struct regnod * regnxt; +}; + +struct parnod { + int partyp; + struct trenod * partre; +}; + +struct lstnod { + int lsttyp; + struct trenod * lstlef; + struct trenod * lstrit; +}; + +struct ionod { + int iofile; + char * ioname; + struct ionod * ionxt; + struct ionod * iolst; +}; + +#define FORKTYPE (sizeof(struct forknod)) +#define COMTYPE (sizeof(struct comnod)) +#define IFTYPE (sizeof(struct ifnod)) +#define WHTYPE (sizeof(struct whnod)) +#define FORTYPE (sizeof(struct fornod)) +#define SWTYPE (sizeof(struct swnod)) +#define REGTYPE (sizeof(struct regnod)) +#define PARTYPE (sizeof(struct parnod)) +#define LSTTYPE (sizeof(struct lstnod)) +#define IOTYPE (sizeof(struct ionod)) diff --git a/src/sh/bsh/msg.c b/src/sh/bsh/msg.c new file mode 100755 index 00000000..3e56b5cd --- /dev/null +++ b/src/sh/bsh/msg.c @@ -0,0 +1,145 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + + +#include "defs.h" +#include "sym.h" + +char version[] = "\nVERSION sys137 DATE 1978 Nov 6 14:29:22\n"; + +/* error messages */ +char badopt[] = "bad option(s)"; +char mailmsg[] = "you have mail\n"; +char nospace[] = "no space"; +char synmsg[] = "syntax error"; + +char badnum[] = "bad number"; +char badparam[] = "parameter not set"; +char badsub[] = "bad substitution"; +char badcreate[] = "cannot create"; +char illegal[] = "illegal io"; +char restricted[] = "restricted"; +char piperr[] = "cannot make pipe"; +char badopen[] = "cannot open"; +char coredump[] = " - core dumped"; +char arglist[] = "arg list too long"; +#if 1 /* Nick */ +char execformat[] = "exec format error"; +char tooshort[] = "too short"; +char noalign[] = "not aligned"; +#endif +char txtbsy[] = "text busy"; +char toobig[] = "too big"; +char badexec[] = "cannot execute"; +char notfound[] = "not found"; +char badfile[] = "bad file number"; +char badshift[] = "cannot shift"; +char baddir[] = "bad directory"; +char badtrap[] = "bad trap"; +char wtfailed[] = "is read only"; +char notid[] = "is not an identifier"; + +/* built in names */ +char pathname[] = "PATH"; +char homename[] = "HOME"; +char mailname[] = "MAIL"; +char fngname[] = "FILEMATCH"; +char ifsname[] = "IFS"; +char ps1name[] = "PS1"; +char ps2name[] = "PS2"; + +/* string constants */ +char nullstr[] = ""; +char sptbnl[] = " \t\n"; +char defpath[] = ":/bin:/usr/bin"; +char colon[] = ": "; +char minus[] = "-"; +char endoffile[] = "end of file"; +char unexpected [] = " unexpected"; +char atline[] = " at line "; +char devnull[] = "/dev/null"; +char execpmsg[] = "+ "; +char readmsg[] = "> "; +char stdprompt[] = "$ "; +char supprompt[] = "# "; +char profile[] = ".profile"; + + +/* tables */ +struct sysnod reserved[] = + { + {"in", INSYM}, + {"esac", ESSYM}, + {"case", CASYM}, + {"for", FORSYM}, + {"done", ODSYM}, + {"if", IFSYM}, + {"while", WHSYM}, + {"do", DOSYM}, + {"then", THSYM}, + {"else", ELSYM}, + {"elif", EFSYM}, + {"fi", FISYM}, + {"until", UNSYM}, + { "{", BRSYM}, + { "}", KTSYM}, + {0, 0}, + }; + +char * sysmsg[] = + { + 0, + "Hangup", + 0, /* Interrupt */ + "Quit", + "Illegal instruction", + "Trace/BPT trap", + "IOT trap", + "EMT trap", + "Floating exception", + "Killed", + "Bus error", + "Memory fault", + "Bad system call", + 0, /* Broken pipe */ + "Alarm call", + "Terminated", + "Signal 16", + }; + +char export[] = "export"; +char readonly[] = "readonly"; +struct sysnod commands[] = + { + {"cd", SYSCD}, + {"read", SYSREAD}, +/* + {"[", SYSTST}, +*/ + {"set", SYSSET}, + {":", SYSNULL}, + {"trap", SYSTRAP}, + {"login", SYSLOGIN}, + {"wait", SYSWAIT}, + {"eval", SYSEVAL}, + {".", SYSDOT}, + {"newgrp", SYSLOGIN}, + {readonly, SYSRDONLY}, + {export, SYSXPORT}, + {"chdir", SYSCD}, + {"break", SYSBREAK}, + {"continue", SYSCONT}, + {"shift", SYSSHFT}, + {"exit", SYSEXIT}, + {"exec", SYSEXEC}, + {"times", SYSTIMES}, + {"umask", SYSUMASK}, + {0, 0}, + }; + diff --git a/src/sh/bsh/n.bat b/src/sh/bsh/n.bat new file mode 100755 index 00000000..56be55cf --- /dev/null +++ b/src/sh/bsh/n.bat @@ -0,0 +1,137 @@ +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ args +@if errorlevel 1 goto failure +del args.r01 +as-z80 -l -o args.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ blok +@if errorlevel 1 goto failure +del blok.r01 +as-z80 -l -o blok.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ builtin +@if errorlevel 1 goto failure +del builtin.r01 +as-z80 -l -o builtin.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ cmd +@if errorlevel 1 goto failure +del cmd.r01 +as-z80 -l -o cmd.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ ctype +@if errorlevel 1 goto failure +del ctype.r01 +as-z80 -l -o ctype.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ data +@if errorlevel 1 goto failure +del data.r01 +as-z80 -l -o data.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ error +@if errorlevel 1 goto failure +del error.r01 +as-z80 -l -o error.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ expand +@if errorlevel 1 goto failure +del expand.r01 +as-z80 -l -o expand.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ fault +@if errorlevel 1 goto failure +del fault.r01 +as-z80 -l -o fault.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ io +@if errorlevel 1 goto failure +del io.r01 +as-z80 -l -o io.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ macro +@if errorlevel 1 goto failure +del macro.r01 +as-z80 -l -o macro.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ main +@if errorlevel 1 goto failure +del main.r01 +as-z80 -l -o main.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ msg +@if errorlevel 1 goto failure +del msg.r01 +as-z80 -l -o msg.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ name +@if errorlevel 1 goto failure +del name.r01 +as-z80 -l -o name.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ print +@if errorlevel 1 goto failure +del print.r01 +as-z80 -l -o print.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ service +@if errorlevel 1 goto failure +del service.r01 +as-z80 -l -o service.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ setbrk +@if errorlevel 1 goto failure +del setbrk.r01 +as-z80 -l -o setbrk.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ stak +@if errorlevel 1 goto failure +del stak.r01 +as-z80 -l -o stak.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ string +@if errorlevel 1 goto failure +del string.r01 +as-z80 -l -o string.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ word +@if errorlevel 1 goto failure +del word.r01 +as-z80 -l -o word.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ xec +@if errorlevel 1 goto failure +del xec.r01 +as-z80 -l -o xec.s01 +@if errorlevel 1 goto failure + +link-z80 -f bsh +@if errorlevel 1 goto failure +ihex2bin -l bsh.i86 ..\..\..\bin\banked\bsh +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/sh/bsh/name.c b/src/sh/bsh/name.c new file mode 100755 index 00000000..0b36d4e3 --- /dev/null +++ b/src/sh/bsh/name.c @@ -0,0 +1,320 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + +extern char chkid(); + + +struct namnod ps2nod = { NULL, NULL, ps2name}, + fngnod = { NULL, NULL, fngname}, + pathnod = { NULL, NULL, pathname}, + ifsnod = { NULL, NULL, ifsname}, + ps1nod = { &pathnod, &ps2nod, ps1name}, + homenod = { &fngnod, &ifsnod, homename}, + mailnod = { &homenod, &ps1nod, mailname}; + +struct namnod * namep = &mailnod; + + +/* ======== variable and string handling ======== */ + +syslook(w,syswds) + char * w; + struct sysnod syswds[]; +{ + register char first; + register char * s; + register struct sysnod * syscan; + + syscan=syswds; first = *w; + + while ( s=syscan->sysnam + ) { if ( first == *s + && eq(w,s) + ) { return(syscan->sysval); + ; } + syscan++; + ; } + return(0); +} + +setlist(arg,xp) + register struct argnod * arg; + int xp; +{ + while ( arg + ) { register char * s=mactrim(arg->argval); + setname(s, xp); + arg=arg->argnxt; + if ( flags&execpr + ) { prs(s); + if ( arg ) { blank(); } else { newline(); ; } + ; } + ; } +} + +int setname(argi, xp) + char * argi; + int xp; +{ + register char * argscan=argi; + register struct namnod * n; + + if ( letter(*argscan) + ) { while ( alphanum(*argscan) ) { argscan++ ; } + if ( *argscan=='=' + ) { *argscan = 0; + n=lookup(argi); + *argscan++ = '='; + attrib(n, xp); + if ( xp&N_ENVNAM + ) { n->namenv = n->namval = argscan; + } else { assign(n, argscan); + ; } + return; + ; } + ; } + failed(argi,notid); +} + +replace(a, v) + register char * *a; + char * v; +{ + free(*a); *a=make(v); +} + +dfault(n,v) + struct namnod * n; + char * v; +{ + if ( n->namval==0 + ) { assign(n,v) + ; } +} + +assign(n,v) + struct namnod * n; + char * v; +{ + if ( n->namflg&N_RDONLY + ) { failed(n->namid,wtfailed); + } else { replace(&n->namval,v); + ; } +} + +int readvar(names) + char * *names; +{ + struct fileblk fb; + register struct fileblk * f = &fb; + register char c; + register int rc=0; + struct namnod * n=lookup(*names++); /* done now to avoid storage mess */ + char * rel=(char *)relstak(); + + push(f); initf(dup(0)); + if ( lseek(0,0L,1)==-1 + ) { f->fsiz=1; + ; } + + for (;;) { c=nextc(0); + if ( (*names && any(c, ifsnod.namval)) || eolchar(c) + ) { zerostak(); + assign(n,absstak(rel)); setstak(rel); + if ( *names + ) { n=lookup(*names++); + } else { n=0; + ; } + if ( eolchar(c) + ) { break; + ; } + } else { pushstak(c); + ; } + } + while ( n + ) { assign(n, nullstr); + if ( *names ) { n=lookup(*names++); } else { n=0; ; } + ; } + + if ( eof ) { rc=1 ; } + lseek(0, (long)(f->fnxt-f->fend), 1); + pop(); + return(rc); +} + +assnum(p, i) + char * *p; + int i; +{ + itos(i); replace(p,numbuf); +} + +char * make(v) + char * v; +{ + register char * p; + + if ( v + ) { movstr(v,p=alloc(length(v))); + return(p); + } else { return(0); + ; } +} + + +struct namnod * lookup(nam) + register char * nam; +{ + register struct namnod * nscan=namep; + register struct namnod * *prev; + int LR; + + if ( !chkid(nam) + ) { failed(nam,notid); + ; } + while ( nscan + ) { if ( (LR=cf(nam,nscan->namid))==0 + ) { return(nscan); + } else if ( LR<0 + ) { prev = &(nscan->namlft); + } else { prev = &(nscan->namrgt); + ; } + nscan = *prev; + ; } + + /* add name node */ + nscan=(struct namnod *)alloc(sizeof *nscan); + nscan->namlft=nscan->namrgt=NULL; + nscan->namid=make(nam); + nscan->namval=0; nscan->namflg=N_DEFAULT; nscan->namenv=0; + return(*prev = nscan); +} + +static char chkid(nam) + char * nam; +{ + register char * cp=nam; + + if ( !letter(*cp) + ) { return(0); + } else { while ( *++cp + ) { if ( !alphanum(*cp) + ) { return(0); + ; } + ; } + ; } + return((-1)); +} + +static int (*namfn)(); +namscan(fn) + int (*fn)(); +{ + namfn=fn; + namwalk(namep); +} + +static int namwalk(np) + register struct namnod * np; +{ + if ( np + ) { namwalk(np->namlft); + (*namfn)(np); + namwalk(np->namrgt); + ; } +} + +int printnam(n) + struct namnod * n; +{ + register char * s; + + sigchk(); + if ( s=n->namval + ) { prs(n->namid); + prc('='); prs(s); + newline(); + ; } +} + +static char * staknam(n) + register struct namnod * n; +{ + register char * p; + + p=movstr(n->namid,staktop); + p=movstr("=",p); + p=movstr(n->namval,p); + return(getstak(p+1-ADR(stakbot))); +} + +int exname(n) + register struct namnod * n; +{ + if ( n->namflg&N_EXPORT + ) { free(n->namenv); + n->namenv = make(n->namval); + } else { free(n->namval); + n->namval = make(n->namenv); + ; } +} + +int printflg(n) + register struct namnod * n; +{ + if ( n->namflg&N_EXPORT + ) { prs(export); blank(); + ; } + if ( n->namflg&N_RDONLY + ) { prs(readonly); blank(); + ; } + if ( n->namflg&(N_EXPORT|N_RDONLY) + ) { prs(n->namid); newline(); + ; } +} + +int getenv() +{ + register char * *e=environ; + + while ( *e + ) { setname(*e++, N_ENVNAM) ; } +} + +static int namec; + +int countnam(n) + struct namnod * n; +{ + namec++; +} + +static char * *argnam; + +int pushnam(n) + struct namnod * n; +{ + if ( n->namval + ) { *argnam++ = staknam(n); + ; } +} + +char * *setenv() +{ + register char * *er; + + namec=0; + namscan(countnam); + argnam = er = (char **)getstak(namec*BYTESPERWORD+BYTESPERWORD); + namscan(pushnam); + *argnam++ = 0; + return(er); +} diff --git a/src/sh/bsh/name.h b/src/sh/bsh/name.h new file mode 100755 index 00000000..cbbaa4cc --- /dev/null +++ b/src/sh/bsh/name.h @@ -0,0 +1,25 @@ + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + + +#define N_RDONLY 0100000 +#define N_EXPORT 0040000 +#define N_ENVNAM 0020000 +#define N_ENVPOS 0007777 + +#define N_DEFAULT 0 + +struct namnod { + struct namnod * namlft; + struct namnod * namrgt; + char * namid; + char * namval; + char * namenv; + int namflg; +}; diff --git a/src/sh/bsh/print.c b/src/sh/bsh/print.c new file mode 100755 index 00000000..1bbf65ef --- /dev/null +++ b/src/sh/bsh/print.c @@ -0,0 +1,98 @@ + + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + +char numbuf[6]; + + +/* printing and io conversion */ + +newline() +{ prc('\n'); +} + +blank() +{ prc(' '); +} + +prp() +{ + if ( (flags&prompt)==0 && cmdadr + ) { prs(cmdadr); prs(colon); + ; } +} + +int prs(as) + char * as; +{ + register char * s; + + if ( s=as + ) { write(output,s,length(s)-1); + ; } +} + +int prc(c) + char c; +{ + if ( c + ) { write(output,&c,1); + ; } +} + +prt(t) + long int t; +{ + register int hr, min, sec; + + t += 30; t /= 60; + sec=t%60; t /= 60; + min=t%60; + if ( hr=t/60 + ) { prn(hr); prc('h'); + ; } + prn(min); prc('m'); + prn(sec); prc('s'); +} + +prn(n) + int n; +{ + itos(n); prs(numbuf); +} + +itos(n) +{ + register char *abuf; register unsigned a, i; int pr, d; + abuf=numbuf; pr=0; a=n; + for ( i=10000; i!=1; i/=10 + ) { if ( (pr |= (d=a/i)) ) { *abuf++=d+'0' ; } + a %= i; + ; } + *abuf++=a+'0'; + *abuf++=0; +} + +stoi(icp) +char * icp; +{ + register char *cp = icp; + register int r = 0; + register char c; + + while ( (c = *cp, digit(c)) && c && r>=0 + ) { r = r*10 + c - '0'; cp++ ; } + if ( r<0 || cp==icp + ) { failed(icp,badnum); + } else { return(r); + ; } +} + diff --git a/src/sh/bsh/service.c b/src/sh/bsh/service.c new file mode 100755 index 00000000..9f352da9 --- /dev/null +++ b/src/sh/bsh/service.c @@ -0,0 +1,384 @@ + + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include /* Nick, for wait() to waitpid() translation macro */ +#include "defs.h" + + +extern int gsort(); + +#define ARGMK 01 + +extern int errno; +extern char * sysmsg[]; + +/* fault handling */ +#if 1 /* Nick */ +#include +#else +#define ENOMEM 12 +#define ENOEXEC 8 +#define E2BIG 7 +#define ENOENT 2 +#define ETXTBSY 26 +#endif + + + +/* service routines for `execute' */ + +int initio(iop) + struct ionod * iop; +{ + register char * ion; + register int iof, fd; + + if ( iop + ) { iof=iop->iofile; + ion=mactrim(iop->ioname); + if ( *ion && (flags&noexec)==0 + ) { if ( iof&IODOC + ) { subst(chkopen(ion),(fd=tmpfil())); + close(fd); fd=chkopen(tmpout); unlink(tmpout); + } else if ( iof&IOMOV + ) { if ( eq(minus,ion) + ) { fd = -1; + close(iof&IOUFD); + } else if ( (fd=stoi(ion))>=USERIO + ) { failed(ion,badfile); + } else { fd=dup(fd); + ; } + } else if ( (iof&IOPUT)==0 + ) { fd=chkopen(ion); + } else if ( flags&rshflg + ) { failed(ion,restricted); + } else if ( iof&IOAPP && (fd=open(ion,1))>=0 + ) { lseek(fd, 0L, 2); + } else { fd=create(ion); + ; } + if ( fd>=0 + ) { rename(fd,iof&IOUFD); + ; } + ; } + initio(iop->ionxt); + ; } +} + +char * getpath(s) + char * s; +{ + register char * path; + if ( any('/',s) + ) { if ( flags&rshflg + ) { failed(s, restricted); + } else { return(nullstr); + ; } + } else if ( (path = pathnod.namval)==0 + ) { return(defpath); + } else { return(cpystak(path)); + ; } +} + +int pathopen(path, name) + register char * path, * name; +{ + register int f; + + do { path=catpath(path,name); + } while ( (f=open(curstak(),0))<0 && path ); + return(f); +} + +char * catpath(path,name) + register char * path; + char * name; +{ + /* leaves result on top of stack */ + register char * scanp = path, + * argp = locstak(); + + while ( *scanp && *scanp!=':' ) { *argp++ = *scanp++ ; } + if ( scanp!=path ) { *argp++='/' ; } + if ( *scanp==':' ) { scanp++ ; } + path=(*scanp ? scanp : 0); scanp=name; + while ( (*argp++ = *scanp++) ); + return(path); +} + +static char * xecmsg; +static char * *xecenv; + +int execa(at) + char * at[]; +{ + register char * path; + register char * *t = at; + + if ( (flags&noexec)==0 + ) { xecmsg=notfound; path=getpath(*t); + namscan(exname); + xecenv=setenv(); + while ( path=execs(path,t) ); + failed(*t,xecmsg); + ; } +} + +static char * execs(ap,t) + char * ap; + register char * t[]; +{ + register char * p, * prefix; + + prefix=catpath(ap,t[0]); + trim(p=curstak()); + + sigchk(); + execve(p, &t[0] ,xecenv); + switch ( errno ) { + + case ENOEXEC: +#if 1 /* Nick */ + failed(p, execformat); + + case ETOOSHORT: + failed(p, tooshort); + + case ENOALIGN: + failed(p, noalign); + + case ESHELL: +#endif + flags=0; + comdiv=0; ioset=0; + clearup(); /* remove open files and for loop junk */ + if ( input ) { close(input) ; } + close(output); output=2; + input=chkopen(p); + + /* set up new args */ + setargs(t); + longjmp(subshell,1); + + case ENOMEM: + failed(p,toobig); + + case E2BIG: + failed(p,arglist); + + case ETXTBSY: + failed(p,txtbsy); + + default: + xecmsg=badexec; + case ENOENT: + return(prefix); + } +} + +/* for processes to be waited for */ +#define MAXP 20 +static int pwlist[MAXP]; +static int pwc; + +postclr() +{ + register int *pw = pwlist; + + while ( pw <= &pwlist[pwc] + ) { *pw++ = 0 ; } + pwc=0; +} + +int post(pcsid) + int pcsid; +{ + register int *pw = pwlist; + + if ( pcsid + ) { while ( *pw ) { pw++ ; } + if ( pwc >= MAXP-1 + ) { pw--; + } else { pwc++; + ; } + *pw = pcsid; + ; } +} + +int await(i) + int i; +{ + int rc=0, wx=0; + int w; + int ipwc = pwc; + + post(i); + while ( pwc + ) { register int p; + register int sig; + int w_hi; + + { + register int *pw=pwlist; + p=wait(&w); + while ( pw <= &pwlist[ipwc] + ) { if ( *pw==p + ) { *pw=0; pwc--; + } else { pw++; + ; } + ; } + } + + if ( p == -1 ) { continue ; } + + w_hi = (w>>8)&0377; + + if ( sig = w&0177 + ) { if ( sig == 0177 /* ptrace! return */ + ) { prs("ptrace: "); + sig = w_hi; + ; } + if ( sysmsg[sig] + ) { if ( i!=p || (flags&prompt)==0 ) { prp(); prn(p); blank() ; } + prs(sysmsg[sig]); + if ( w&0200 ) { prs(coredump) ; } + ; } + newline(); + ; } + + if ( rc==0 + ) { rc = (sig ? sig|SIGFLG : w_hi); + ; } + wx |= w; + ; } + + if ( wx && flags&errflg + ) { exitsh(rc); + ; } + exitval=rc; exitset(); +} + +extern char nosubst; + +trim(at) + char * at; +{ + register char * p; + register char c; + register char q=0; + + if ( p=at + ) { while ( c = *p + ) { *p++=c&0177; q |= c ; } + ; } + nosubst=q&0200; +} + +char * mactrim(s) + char * s; +{ + register char * t=macro(s); + trim(t); + return(t); +} + +char * *scan(argn) + int argn; +{ + register struct argnod *argp = (struct argnod *)(Rcheat(gchain)&~ARGMK); + register char * *comargn, * *comargm; + + comargn=(char **)getstak(BYTESPERWORD*argn+BYTESPERWORD); + comargm = comargn += argn; + *comargn = ENDARGS; + + while ( argp + ) { *--comargn = argp->argval; + if ( argp = argp->argnxt + ) { trim(*comargn); + ; } + if ( argp==0 || Rcheat(argp)&ARGMK + ) { gsort(comargn,comargm); + comargm = comargn; + ; } + /* Lcheat(argp) &= ~ARGMK; */ + argp = (struct argnod *)(Rcheat(argp)&~ARGMK); + ; } + return(comargn); +} + +static int gsort(from,to) + char * from[], * to[]; +{ + int k, m, n; + register int i, j; + + if ( (n=to-from)<=1 ) { return ; } + + for ( j=1; j<=n; j*=2 ); + + for ( m=2*j-1; m/=2; + ) { k=n-m; + for ( j=0; j=0; i-=m + ) { register char * *fromi; fromi = &from[i]; + if ( cf(fromi[m],fromi[0])>0 + ) { break; + } else { char * s; s=fromi[m]; fromi[m]=fromi[0]; fromi[0]=s; + ; } + ; } + ; } + ; } +} + +/* Argument list generation */ + +int getarg(ac) + struct comnod * ac; +{ + register struct argnod * argp; + register int count=0; + register struct comnod * c; + + if ( c=ac + ) { argp=c->comarg; + while ( argp + ) { count += split(macro(argp->argval)); + argp=argp->argnxt; + ; } + ; } + return(count); +} + +static int split(s) + register char * s; +{ + register char * argp; + register int c; + int count=0; + + for (;;) { sigchk(); argp=locstak()+BYTESPERWORD; + while ( (c = *s++, !any(c,ifsnod.namval) && c) + ) { *argp++ = c ; } + if ( argp==staktop+BYTESPERWORD + ) { if ( c + ) { continue; + } else { return(count); + ; } + } else if ( c==0 + ) { s--; + ; } + if ( c=expand(((struct argnod *)(argp=endstak(argp)))->argval,0) + ) { count += c; + } else { /* assign(&fngnod, argp->argval); */ + makearg(argp); count++; + ; } + Lcheat(gchain) |= ARGMK; + } +} diff --git a/src/sh/bsh/setbrk.c b/src/sh/bsh/setbrk.c new file mode 100755 index 00000000..b2c662c9 --- /dev/null +++ b/src/sh/bsh/setbrk.c @@ -0,0 +1,30 @@ + + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + +setbrk(incr) +{ +#if 1 /* Nick, allows for signed increment */ + register char *a; + + if (brkend == NULL) + { + brkend = (char *)sbrk(0); + } + a = brkend; + brkend += incr; + brk(brkend); +#else + register char * a = (char *)sbrk(incr); + brkend=a+incr; +#endif + return (int)a; +} diff --git a/src/sh/bsh/stak.c b/src/sh/bsh/stak.c new file mode 100755 index 00000000..af13d65b --- /dev/null +++ b/src/sh/bsh/stak.c @@ -0,0 +1,83 @@ + + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + +char * stakbot=nullstr; + + + +/* ======== storage allocation ======== */ + +char * getstak(asize) + int asize; +{ /* allocate requested stack */ + register char * oldstak; + register int size; + + size=round(asize,BYTESPERWORD); + oldstak=stakbot; + staktop = stakbot += size; + return(oldstak); +} + +char * locstak() +{ /* set up stack for local use + * should be followed by `endstak' + */ + if ( brkend-stakbotADR(x) + ) { free(stakbsy); + stakbsy = stakbsy->word; + ; } + staktop=stakbot=max(ADR(x),ADR(stakbas)); + rmtemp(x); +} + +stakchk() +{ + if ( (brkend-stakbas)>BRKINCR+BRKINCR + ) { setbrk(-BRKINCR); + ; } +} + +char * cpystak(x) + char * x; +{ + return(endstak(movstr(x,locstak()))); +} + diff --git a/src/sh/bsh/stak.h b/src/sh/bsh/stak.h new file mode 100755 index 00000000..6d21834f --- /dev/null +++ b/src/sh/bsh/stak.h @@ -0,0 +1,78 @@ + + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +/* To use stack as temporary workspace across + * possible storage allocation (eg name lookup) + * a) get ptr from `relstak' + * b) can now use `pushstak' + * c) then reset with `setstak' + * d) `absstak' gives real address if needed + */ +#define relstak() (staktop-stakbot) +#define absstak(x) (stakbot+Rcheat(x)) +#define setstak(x) (staktop=absstak(x)) +#define pushstak(c) (*staktop++=(c)) +#define zerostak() (*staktop=0) + +/* Used to address an item left on the top of + * the stack (very temporary) + */ +#define curstak() (staktop) + +/* `usestak' before `pushstak' then `fixstak' + * These routines are safe against heap + * being allocated. + */ +#define usestak() {locstak();} + +/* for local use only since it hands + * out a real address for the stack top + */ +char * locstak(); + +/* Will allocate the item being used and return its + * address (safe now). + */ +#define fixstak() endstak(staktop) + +/* For use after `locstak' to hand back + * new stack top and then allocate item + */ +char * endstak(); + +/* Copy a string onto the stack and + * allocate the space. + */ +char * cpystak(); + +/* Allocate given ammount of stack space */ +char * getstak(); + +/* A chain of ptrs of stack blocks that + * have become covered by heap allocation. + * `tdystak' will return them to the heap. + */ +extern struct blk * stakbsy; + +/* Base of the entire stack */ +extern char * stakbas; + +/* Top of entire stack */ +extern char * brkend; + +/* Base of current item */ +extern char * stakbot; + +/* Top of current item */ +extern char * staktop; + +/* Used with tdystak */ +char * savstak(); + diff --git a/src/sh/bsh/string.c b/src/sh/bsh/string.c new file mode 100755 index 00000000..03e752a2 --- /dev/null +++ b/src/sh/bsh/string.c @@ -0,0 +1,57 @@ + + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" + + +/* ======== general purpose string handling ======== */ + + +char * movstr(a,b) + register char * a, * b; +{ + while ( *b++ = *a++ ); + return(--b); +} + +int any(c,s) + register char c; + char * s; +{ + register char d; + + while ( d = *s++ + ) { if ( d==c + ) { return((-1)); + ; } + ; } + return(0); +} + +int cf(s1, s2) + register char * s1, * s2; +{ + while ( *s1++ == *s2 + ) { if ( *s2++==0 + ) { return(0); + ; } + ; } + return(*--s1 - *s2); +} + +int length(as) + char * as; +{ + register char * s; + + if ( s=as ) { while ( *s++ ); ; } + return(s-as); +} + diff --git a/src/sh/bsh/sym.h b/src/sh/bsh/sym.h new file mode 100755 index 00000000..8dbad1ca --- /dev/null +++ b/src/sh/bsh/sym.h @@ -0,0 +1,47 @@ + + +/* + * UNIX shell + */ + + +/* symbols for parsing */ +#define DOSYM 0405 +#define FISYM 0420 +#define EFSYM 0422 +#define ELSYM 0421 +#define INSYM 0412 +#define BRSYM 0406 +#define KTSYM 0450 +#define THSYM 0444 +#define ODSYM 0441 +#define ESSYM 0442 +#define IFSYM 0436 +#define FORSYM 0435 +#define WHSYM 0433 +#define UNSYM 0427 +#define CASYM 0417 + +#define SYMREP 04000 +#define ECSYM (SYMREP|';') +#define ANDFSYM (SYMREP|'&') +#define ORFSYM (SYMREP|'|') +#define APPSYM (SYMREP|'>') +#define DOCSYM (SYMREP|'<') +#define EOFSYM 02000 +#define SYMFLG 0400 + +/* arg to `cmd' */ +#define NLFLG 1 +#define MTFLG 2 + +/* for peekc */ +#define MARK 0100000 + +/* odd chars */ +#define DQUOTE '"' +#define SQUOTE '`' +#define LITERAL '\'' +#define DOLLAR '$' +#define ESCAPE '\\' +#define BRACE '{' diff --git a/src/sh/bsh/timeout.h b/src/sh/bsh/timeout.h new file mode 100755 index 00000000..4f1dcbfd --- /dev/null +++ b/src/sh/bsh/timeout.h @@ -0,0 +1,11 @@ + + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#define TIMEOUT 0 diff --git a/src/sh/bsh/word.c b/src/sh/bsh/word.c new file mode 100755 index 00000000..bf2873bb --- /dev/null +++ b/src/sh/bsh/word.c @@ -0,0 +1,133 @@ + + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" +#include "sym.h" + + +/* ======== character handling for command lines ========*/ + + +word() +{ + register char c, d; + register char *argp=locstak()+BYTESPERWORD; + int alpha=1; + + wdnum=0; wdset=0; + + while ( (c=nextc(0), space(c)) ); + if ( !eofmeta(c) + ) { do { if ( c==LITERAL + ) { *argp++=(DQUOTE); + while ( (c=readc()) && c!=LITERAL + ) { *argp++=(c|0200); chkpr(c) ; } + *argp++=(DQUOTE); + } else { *argp++=(c); + if ( c=='=' ) { wdset |= alpha ; } + if ( !alphanum(c) ) { alpha=0 ; } + if ( qotchar(c) + ) { d=c; + while ( (*argp++=(c=nextc(d))) && c!=d + ) { chkpr(c) ; } + ; } + ; } + } while ( (c=nextc(0), !eofmeta(c)) ); + argp=endstak(argp); + if ( !letter(((struct argnod *)argp)->argval[0]) ) { wdset=0 ; } + + peekc=c|MARK; + if ( ((struct argnod *)argp)->argval[1]==0 && (d=((struct argnod *)argp)->argval[0], digit(d)) && (c=='>' || c=='<') + ) { word(); wdnum=d-'0'; + } else { /*check for reserved words*/ + if ( reserv==0 || (wdval=syslook(((struct argnod *)argp)->argval,reserved))==0 + ) { wdarg=(struct argnod *)argp; wdval=0; + ; } + ; } + + } else if ( dipchar(c) + ) { if ( (d=nextc(0))==c + ) { wdval = c|SYMREP; + } else { peekc = d|MARK; wdval = c; + ; } + } else { if ( (wdval=c)==0 + ) { wdval=EOFSYM; + ; } + if ( iopend && eolchar(c) + ) { copy(iopend); iopend=0; + ; } + ; } + reserv=0; + return(wdval); +} + +nextc(quote) + char quote; +{ + register char c, d; + if ( (d=readc())==ESCAPE + ) { if ( (c=readc())=='\n' + ) { chkpr('\n'); d=nextc(quote); + } else if ( quote && c!=quote && !escchar(c) + ) { peekc=c|MARK; + } else { d = c|0200; + ; } + ; } +#if 1 /* Nick */ + else if (quote == 0 && d == '#') /* shell comment */ + { + while ((d = readc()) && d != '\n') + ; /* scan ahead to eof or newline */ + } +#endif + return(d); +} + +readc() +{ + register char c; + register int len; + register struct fileblk * f; + +retry: + if ( peekc + ) { c=peekc; peekc=0; + } else if ( (f=standin, f->fnxt!=f->fend) + ) { if ( (c = *f->fnxt++)==0 + ) { if ( f->feval + ) { if ( estabf(*f->feval++) + ) { c=0; + } else { c=' '; + ; } + } else { goto retry; /* = c=readc(); */ + ; } + ; } + if ( flags&readpr && standin->fstak==0 ) { prc(c) ; } + if ( c=='\n' ) { f->flin++ ; } + } else if ( f->feof || f->fdes<0 + ) { c=0; f->feof++; + } else if ( (len=readb())<=0 + ) { close(f->fdes); f->fdes = -1; c=0; f->feof++; + } else { f->fend = (f->fnxt = f->fbuf)+len; + goto retry; + ; } + return(c); +} + +static readb() +{ + register struct fileblk * f=standin; + register int len; + + do { if ( trapnote&SIGSET ) { newline(); sigchk() ; } + } while ( (len=read(f->fdes,f->fbuf,f->fsiz))<0 && trapnote ); + return(len); +} + diff --git a/src/sh/bsh/xec.c b/src/sh/bsh/xec.c new file mode 100755 index 00000000..0d95525e --- /dev/null +++ b/src/sh/bsh/xec.c @@ -0,0 +1,423 @@ + + +/* + * UNIX shell + * + * S. R. Bourne + * Bell Telephone Laboratories + * + */ + +#include "defs.h" +#include "sym.h" + +static int parent; + +extern struct sysnod commands[]; + + + +/* ======== command execution ========*/ + + +execute(argt, execflg, pf1, pf2) + struct trenod * argt; + int *pf1, *pf2; +{ + /* `stakbot' is preserved by this routine */ + register struct trenod * t; + char * sav=savstak(); + + sigchk(); + + if ( (t=argt) && execbrk==0 + ) { register int treeflgs; + int oldexit, type; + register char * *com; + + treeflgs = t->tretyp; type = treeflgs&COMMSK; + oldexit=exitval; exitval=0; + + switch ( type ) { + + case TCOM: + { + char * a1; + int argn, internal; + struct argnod * schain=gchain; + struct ionod * io=t->treio; + gchain=0; + argn = getarg(t); + com=scan(argn); + a1=com[1]; gchain=schain; + + if ( (internal=syslook(com[0],commands)) || argn==0 + ) { setlist(((struct comnod *)t)->comset, 0); + ; } + + if ( argn && (flags&noexec)==0 + ) { /* print command if execpr */ + if ( flags&execpr + ) { argn=0; prs(execpmsg); + while ( com[argn]!=ENDARGS + ) { prs(com[argn++]); blank() ; } + newline(); + ; } + + switch ( internal ) { + + case SYSDOT: + if ( a1 + ) { register int f; + + if ( (f=pathopen(getpath(a1), a1)) < 0 + ) { failed(a1,notfound); + } else { execexp(0,f); + ; } + ; } + break; + + case SYSTIMES: + { + long int t[4]; times(t); + prt(t[2]); blank(); prt(t[3]); newline(); + } + break; + + case SYSEXIT: + exitsh(a1?stoi(a1):oldexit); + + case SYSNULL: + io=0; + break; + + case SYSCONT: + execbrk = -loopcnt; break; + + case SYSBREAK: + if ( (execbrk=loopcnt) && a1 + ) { breakcnt=stoi(a1); + ; } + break; + + case SYSTRAP: + if ( a1 + ) { char clear; + if ( (clear=digit(*a1))==0 + ) { ++com; + ; } + while ( *++com + ) { int i; + if ( (i=stoi(*com))>=MAXTRAP || i1 + ) { setargs(com+argn-argc); + ; } + } else if ( ((struct comnod *)t)->comset==0 + ) { /*scan name chain and print*/ + namscan(printnam); + ; } + break; + + case SYSRDONLY: + exitval=N_RDONLY; + case SYSXPORT: + if ( exitval==0 ) { exitval=N_EXPORT; ; } + + if ( a1 + ) { while ( *++com + ) { attrib(lookup(*com), exitval) ; } + } else { namscan(printflg); + ; } + exitval=0; + break; + + case SYSEVAL: + if ( a1 + ) { execexp(a1,&com[2]); + ; } + break; + + case SYSUMASK: + if (a1) { + int c, i; + i = 0; + while ((c = *a1++) >= '0' && + c <= '7') + i = (i << 3) + c - '0'; + umask(i); + } else { + int i, j; + umask(i = umask(0)); + prc('0'); + for (j = 6; j >= 0; j -= 3) + prc(((i>>j)&07) + '0'); + newline(); + } + break; + + default: + internal=builtin(argn,com); + + } + + if ( internal + ) { if ( io ) { error(illegal) ; } + chktrap(); + break; + ; } + } else if ( t->treio==0 + ) { break; + ; } + } + + case TFORK: + if ( execflg && (treeflgs&(FAMP|FPOU))==0 + ) { parent=0; + } else { while ( (parent=fork()) == -1 + ) { sigchk(); alarm(10); pause() ; } + ; } + + if ( parent + ) { /* This is the parent branch of fork; */ + /* it may or may not wait for the child. */ + if ( treeflgs&FPRS && flags&ttyflg + ) { prn(parent); newline(); + ; } + if ( treeflgs&FPCL ) { closepipe(pf1) ; } + if ( (treeflgs&(FAMP|FPOU))==0 + ) { await(parent); + } else if ( (treeflgs&FAMP)==0 + ) { post(parent); + } else { assnum(&pcsadr, parent); + ; } + + chktrap(); + break; + + + } else { /* this is the forked branch (child) of execute */ + flags |= forked; iotemp=0; + postclr(); + settmp(); + + /* Turn off INTR and QUIT if `FINT' */ + /* Reset ramaining signals to parent */ + /* except for those `lost' by trap */ + oldsigs(); + if ( treeflgs&FINT + ) { signal(INTR,1); signal(QUIT,1); + ; } + + /* pipe in or out */ + if ( treeflgs&FPIN + ) { rename(pf1[INPIPE],0); + close(pf1[OTPIPE]); + ; } + if ( treeflgs&FPOU + ) { rename(pf2[OTPIPE],1); + close(pf2[INPIPE]); + ; } + + /* default std input for & */ + if ( treeflgs&FINT && ioset==0 + ) { rename(chkopen(devnull),0); + ; } + + /* io redirection */ + initio(t->treio); + if ( type!=TCOM + ) { execute(((struct forknod *)t)->forktre,1); + } else if ( com[0]!=ENDARGS + ) { setlist(((struct comnod *)t)->comset,N_EXPORT); + execa(com); + ; } + done(); + ; } + + case TPAR: + rename(dup(2),output); + execute(((struct parnod *)t)->partre,execflg); + done(); + + case TFIL: + { + int pv[2]; chkpipe(pv); + if ( execute(((struct lstnod *)t)->lstlef, 0, pf1, pv)==0 + ) { execute(((struct lstnod *)t)->lstrit, execflg, pv, pf2); + } else { closepipe(pv); + ; } + } + break; + + case TLST: + execute(((struct lstnod *)t)->lstlef,0); + execute(((struct lstnod *)t)->lstrit,execflg); + break; + + case TAND: + if ( execute(((struct lstnod *)t)->lstlef,0)==0 + ) { execute(((struct lstnod *)t)->lstrit,execflg); + ; } + break; + + case TORF: + if ( execute(((struct lstnod *)t)->lstlef,0)!=0 + ) { execute(((struct lstnod *)t)->lstrit,execflg); + ; } + break; + + case TFOR: + { + struct namnod * n = lookup(((struct fornod *)t)->fornam); + char * *args; + struct dolnod * argsav=0; + + if ( ((struct fornod *)t)->forlst==0 + ) { args=dolv+1; + argsav=useargs(); + } else { struct argnod * schain=gchain; + gchain=0; + trim((args=scan(getarg(((struct fornod *)t)->forlst)))[0]); + gchain=schain; + ; } + loopcnt++; + while ( *args!=ENDARGS && execbrk==0 + ) { assign(n,*args++); + execute(((struct fornod *)t)->fortre,0); + if ( execbrk<0 ) { execbrk=0 ; } + ; } + if ( breakcnt ) { breakcnt-- ; } + execbrk=breakcnt; loopcnt--; + argfor=(struct dolnod *)freeargs(argsav); + } + break; + + case TWH: + case TUN: + { + int i=0; + + loopcnt++; + while ( execbrk==0 && (execute(((struct whnod *)t)->whtre,0)==0)==(type==TWH) + ) { i=execute(((struct whnod *)t)->dotre,0); + if ( execbrk<0 ) { execbrk=0 ; } + ; } + if ( breakcnt ) { breakcnt-- ; } + execbrk=breakcnt; loopcnt--; exitval=i; + } + break; + + case TIF: + if ( execute(((struct ifnod *)t)->iftre,0)==0 + ) { execute(((struct ifnod *)t)->thtre,execflg); + } else { execute(((struct ifnod *)t)->eltre,execflg); + ; } + break; + + case TSW: + { + register char * r = mactrim(((struct swnod *)t)->swarg); + t=(struct trenod *)((struct swnod *)t)->swlst; + while ( t + ) { struct argnod * rex=((struct regnod *)t)->regptr; + while ( rex + ) { register char * s; + if ( gmatch(r,s=macro(rex->argval)) || (trim(s), eq(r,s)) + ) { execute(((struct regnod *)t)->regcom,0); + t=0; break; + } else { rex=rex->argnxt; + ; } + ; } + if ( t ) { t=(struct trenod *)((struct regnod *)t)->regnxt ; } + ; } + } + break; + } + exitset(); + ; } + + sigchk(); + tdystak(sav); + return(exitval); +} + + +execexp(s,f) + char * s; + int f; +{ + struct fileblk fb; + push(&fb); + if ( s + ) { estabf(s); fb.feval=(char **)f; + } else if ( f>=0 + ) { initf(f); + ; } + execute(cmd('\n', NLFLG|MTFLG),0); + pop(); +} + diff --git a/src/sh/msh/Makefile b/src/sh/msh/Makefile new file mode 100755 index 00000000..a7bc0b46 --- /dev/null +++ b/src/sh/msh/Makefile @@ -0,0 +1,17 @@ +# Makefile for sh + +CFLAGS = -O2 #-D_POSIX_SOURCE +LDFLAGS = -static + +OBJ = sh1.o sh2.o sh3.o sh4.o sh5.o sh6.o + +all: sh + +sh: $(OBJ) + cc $(LDFLAGS) -o $@ $(OBJ) + +$(OBJ): sh.h + +clean: + rm -f sh *.o *.bak core + diff --git a/src/sh/msh/msh.lnk b/src/sh/msh/msh.lnk new file mode 100755 index 00000000..6d248765 --- /dev/null +++ b/src/sh/msh/msh.lnk @@ -0,0 +1,18 @@ +-k ..\..\..\lib +-l libcb.lib +-l libsysb.lib +-l libiar.lib +-m +-u +-i +-o msh +-bl RCODE=0x8100 +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\..\lib\c0b.rel +sh1 +sh2 +sh3 +sh4 +sh5 +sh6 diff --git a/src/sh/msh/n.bat b/src/sh/msh/n.bat new file mode 100755 index 00000000..917f65fb --- /dev/null +++ b/src/sh/msh/n.bat @@ -0,0 +1,49 @@ +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ sh1 +@if errorlevel 1 goto failure +del sh1.r01 +as-z80 -l -o sh1.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ sh2 +@if errorlevel 1 goto failure +del sh2.r01 +as-z80 -l -o sh2.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ sh3 +@if errorlevel 1 goto failure +del sh3.r01 +as-z80 -l -o sh3.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ sh4 +@if errorlevel 1 goto failure +del sh4.r01 +as-z80 -l -o sh4.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ sh5 +@if errorlevel 1 goto failure +del sh5.r01 +as-z80 -l -o sh5.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ sh6 +@if errorlevel 1 goto failure +del sh6.r01 +as-z80 -l -o sh6.s01 +@if errorlevel 1 goto failure + +link-z80 -f msh +@if errorlevel 1 goto failure +ihex2bin -l msh.i86 ..\..\..\bin\banked\msh +@if errorlevel 1 goto failure + +copy sh.1 \uzi\bin\man + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/sh/msh/sh.1 b/src/sh/msh/sh.1 new file mode 100755 index 00000000..1cb61240 --- /dev/null +++ b/src/sh/msh/sh.1 @@ -0,0 +1,261 @@ +.TH SH 1 +.SH NAME +sh, ., break, case, cd, continue, eval, exec, exit, export, for, if, read, readonly, set, shift, trap, umask, wait, while \- shell +.SH SYNOPSIS +\fBsh\fR [\fB\-eiknqstvxu\fR] [\fB\-c \fIstr\fR] \fB[\fIfile\fR]\fR +.br +.de FL +.TP +\\fB\\$1\\fR +\\$2 +.. +.de EX +.TP 20 +\\fB\\$1\\fR +# \\$2 +.. +.SH OPTIONS +.FL "\-c" "Execute the commands in \fIstr\fR" +.FL "\-e" "Quit on error" +.FL "\-i" "Interactive mode; ignore QUIT, TERMINATE, INTERRUPT" +.FL "\-k" "Look for name=value everywhere on command line" +.FL "\-n" "Do not execute commands" +.FL "\-q" "Change qflag from sig_ign to sig_del" +.FL "\-s" "Read commands from standard input" +.FL "\-t" "Exit after reading and executing one command" +.FL "\-v" "Echo input lines as they are read" +.FL "\-x" "Trace" +.FL "\-u" "Unset variables" +.SH EXAMPLES +.EX "sh script" "Run a shell script" +.SH DESCRIPTION +.PP +.I Sh +is the shell, which forms the user's main interface with the system. +On startup, the shell reads /etc/profile and $HOME/.profile, if they exist, +and executes any commands they contain. The Minix shell has most of the +features of the V7 (Bourne) shell, including redirection of input and output, +pipes, magic characters, background processes, and shell scripts. A brief +summary follows, but whole books have been written on shell programming alone. +.LP +Some of the more common notations are: +.PP +.in +2.45i +.ta 2i 2.2i +.ti -2.2i +date # Regular command +.ti -2.2i +sort file2 # Redirect \fIstdin\fR and \fIstdout\fR +.ti -2.2i +cc file.c 2>error # Redirect \fIstderr\fR +.ti -2.2i +a.out >f 2>&1 # Combine standard output and standard error +.ti -2.2i +sort >file2 # Append output to \fIfile2\fR +.ti -2.2i +sort file2 & # Background job +.ti -2.2i +(ls \-l; a.out) & # Run two background commands sequentially +.ti -2.2i +sort with no command name, modify shell I/O +.ti -2i +exit [n] exit a shell program, with exit value n +.ti -2i +export [var] export var to shell's children; list exported variables +.ti -2i +pwd print the name of the current working directory +.ti -2i +read var read a line from stdin and assign to var +.ti -2i +readonly [var] make var readonly; list readonly variables +.ti -2i +set -f set shell flag (+f unsets flag) +.ti -2i +set str set positional parameter to str +.ti -2i +set show the current shell variables +.ti -2i +shift reassign positional parameters (except ${0}) one left +.ti -2i +times print accumulated user and system times for processes +.ti -2i +trap arg sigs trap signals sigs and run arg on receipt +.ti -2i +trap list trapped signals +.ti -2i +umask [n] set the user file creation mask; show the current umask +.ti -2i +wait [n] wait for process pid n; wait for all processes +.in -2.25i +.LP +The shell also contains a programming language, which has the following +operators and flow control statements: +.PP +.in +3.50i +.ta 2i 3.25i +.ti -3.25i +# Comment The rest of the line is ignored +.ti -3.25i += Assignment Set a shell variable +.ti -3.25i +&& Logical AND Execute second command only if first succeeds +.ti -3.25i +|| Logical OR Execute second command only if first fails +.ti -3.25i +(...) Group Execute enclosed commands before continuing +.in -3.50i +.PP +.in +2.25i +.ta 2i +.ti -2i +for For loop (for ... in ... do ... done) +.ti -2i +case Case statement ((case ... ) ... ;; ... esac) +.ti -2i +esac Case statement end +.ti -2i +while While loop (while ... do ... done) +.ti -2i +do Do/For/While loop start (do ... until ...) +.ti -2i +done For/While loop end +.ti -2i +if Conditional statement (if ... else ... elif ... fi) +.ti -2i +in For loop selection +.ti -2i +then Conditional statement start +.ti -2i +else Conditional statement alternative +.ti -2i +elif Conditional statement end +.ti -2i +until Do loop end +.ti -2i +fi Conditional statement end +.in -2.25i +.SH "SEE ALSO" +.BR echo (1), +.BR expr (1), +.BR pwd (1), +.BR true (1). diff --git a/src/sh/msh/sh.h b/src/sh/msh/sh.h new file mode 100755 index 00000000..c4cf37ec --- /dev/null +++ b/src/sh/msh/sh.h @@ -0,0 +1,400 @@ +#include +#include +#include +#include + +/* Need a way to have void used for ANSI, nothing for K&R. */ +#ifndef _ANSI +#undef _VOID +#define _VOID +#endif + +/* -------- sh.h -------- */ +/* + * shell + */ + +#define LINELIM 2100 +#define NPUSH 8 /* limit to input nesting */ + +#define NOFILE 20 /* Number of open files */ +#define NUFILE 10 /* Number of user-accessible files */ +#define FDBASE 10 /* First file usable by Shell */ + +/* + * values returned by wait + */ +#define WAITSIG(s) ((s)&0177) +#define WAITVAL(s) (((s)>>8)&0377) +#define WAITCORE(s) (((s)&0200)!=0) + +/* + * library and system defintions + */ +#ifdef __STDC__ +typedef void xint; /* base type of jmp_buf, for not broken compilers */ +#else +typedef char * xint; /* base type of jmp_buf, for broken compilers */ +#endif + +/* + * shell components + */ +/* #include "area.h" */ +/* #include "word.h" */ +/* #include "io.h" */ +/* #include "var.h" */ + +#define QUOTE 0200 + +#define NOBLOCK ((struct op *)NULL) +#define NOWORD ((char *)NULL) +#define NOWORDS ((char **)NULL) +#define NOPIPE ((int *)NULL) + +/* + * Description of a command or an operation on commands. + * Might eventually use a union. + */ +struct op { + int type; /* operation type, see below */ + char **words; /* arguments to a command */ + struct ioword **ioact; /* IO actions (eg, < > >>) */ + struct op *left; + struct op *right; + char *str; /* identifier for case and for */ +}; + +#define TCOM 1 /* command */ +#define TPAREN 2 /* (c-list) */ +#define TPIPE 3 /* a | b */ +#define TLIST 4 /* a [&;] b */ +#define TOR 5 /* || */ +#define TAND 6 /* && */ +#define TFOR 7 +#define TDO 8 +#define TCASE 9 +#define TIF 10 +#define TWHILE 11 +#define TUNTIL 12 +#define TELIF 13 +#define TPAT 14 /* pattern in case */ +#define TBRACE 15 /* {c-list} */ +#define TASYNC 16 /* c & */ + +/* + * actions determining the environment of a process + */ +#define BIT(i) (1<<(i)) +#define FEXEC BIT(0) /* execute without forking */ + +/* + * flags to control evaluation of words + */ +#define DOSUB 1 /* interpret $, `, and quotes */ +#define DOBLANK 2 /* perform blank interpretation */ +#define DOGLOB 4 /* interpret [?* */ +#define DOKEY 8 /* move words with `=' to 2nd arg. list */ +#define DOTRIM 16 /* trim resulting string */ + +#define DOALL (DOSUB|DOBLANK|DOGLOB|DOKEY|DOTRIM) + +Extern char **dolv; +Extern int dolc; +Extern int exstat; +Extern char gflg; +Extern int talking; /* interactive (talking-type wireless) */ +Extern int execflg; +Extern int multiline; /* \n changed to ; */ +Extern struct op *outtree; /* result from parser */ + +Extern xint *failpt; +Extern xint *errpt; + +struct brkcon { + jmp_buf brkpt; + struct brkcon *nextlev; +} ; +Extern struct brkcon *brklist; +Extern int isbreak; + +/* + * redirection + */ +struct ioword { + short io_unit; /* unit affected */ + short io_flag; /* action (below) */ + char *io_name; /* file name */ +}; +#define IOREAD 1 /* < */ +#define IOHERE 2 /* << (here file) */ +#define IOWRITE 4 /* > */ +#define IOCAT 8 /* >> */ +#define IOXHERE 16 /* ${}, ` in << */ +#define IODUP 32 /* >&digit */ +#define IOCLOSE 64 /* >&- */ + +#define IODEFAULT (-1) /* token for default IO unit */ + +Extern struct wdblock *wdlist; +Extern struct wdblock *iolist; + +/* + * parsing & execution environment + */ +#if 1 /* Nick */ +extern struct s_env + { + char *linep; + struct io *iobase; + struct io *iop; + xint *errpt; + int iofd; + struct s_env *oenv; + } env; +#else +extern struct env { + char *linep; + struct io *iobase; + struct io *iop; + xint *errpt; + int iofd; + struct env *oenv; +} e; +#endif + +/* + * flags: + * -e: quit on error + * -k: look for name=value everywhere on command line + * -n: no execution + * -t: exit after reading and executing one command + * -v: echo as read + * -x: trace + * -u: unset variables net diagnostic + */ +extern char *flag; + +extern char *null; /* null value for variable */ +extern int intr; /* interrupt pending */ + +Extern char *trap[_NSIG+1]; +Extern char ourtrap[_NSIG+1]; +Extern int trapset; /* trap pending */ + +extern int heedint; /* heed interrupt signals */ + +Extern int yynerrs; /* yacc */ + +Extern char line[LINELIM]; +extern char *elinep; + +/* + * other functions + */ +#ifdef __STDC__ +int (*inbuilt(char *s ))(void); +#else +int (*inbuilt())(); +#endif + +#ifndef _PROTOTYPE /* Nick #ifdef __FreeBSD__ */ +#define _PROTOTYPE(x,y) x ## y +#endif + +_PROTOTYPE(char *rexecve , (char *c , char **v , char **envp )); +_PROTOTYPE(char *space , (int n )); +_PROTOTYPE(char *strsave , (char *s , int a )); +_PROTOTYPE(char *evalstr , (char *cp , int f )); +_PROTOTYPE(char *putn , (int n )); +_PROTOTYPE(char *sh_itoa , (unsigned u , int n )); +_PROTOTYPE(char *unquote , (char *as )); +_PROTOTYPE(struct var *lookup , (char *n )); +_PROTOTYPE(int rlookup , (char *n )); +_PROTOTYPE(struct wdblock *glob , (char *cp , struct wdblock *wb )); +_PROTOTYPE(int subgetc , (char ec , int quoted )); /* Nick, formerly int ec */ +_PROTOTYPE(char **makenv , (void)); +_PROTOTYPE(char **eval , (char **ap , int f )); +_PROTOTYPE(int setstatus , (int s )); +_PROTOTYPE(int waitfor , (int lastpid , int canintr )); + +_PROTOTYPE(void onintr , (int s )); /* SIGINT handler */ + +_PROTOTYPE(int newenv , (int f )); +_PROTOTYPE(void quitenv , (void)); +_PROTOTYPE(void err , (char *s )); +_PROTOTYPE(int anys , (char *s1 , char *s2 )); +_PROTOTYPE(int any , (int c , char *s )); +_PROTOTYPE(void next , (int f )); +_PROTOTYPE(void setdash , (void)); +_PROTOTYPE(void onecommand , (void)); +_PROTOTYPE(void runtrap , (int i )); +_PROTOTYPE(void xfree , (char *s )); +_PROTOTYPE(int letter , (int c )); +_PROTOTYPE(int digit , (int c )); +_PROTOTYPE(int letnum , (int c )); +_PROTOTYPE(int gmatch , (char *s , char *p )); + +/* + * error handling + */ +_PROTOTYPE(void leave , (void)); /* abort shell (or fail in subshell) */ +_PROTOTYPE(void fail , (void)); /* fail but return to process next command */ +_PROTOTYPE(void warn , (char *s )); +_PROTOTYPE(void sig , (int i )); /* default signal handler */ + +/* -------- var.h -------- */ + +struct var { + char *value; + char *name; + struct var *next; + char status; +}; +#define COPYV 1 /* flag to setval, suggesting copy */ +#define RONLY 01 /* variable is read-only */ +#define EXPORT 02 /* variable is to be exported */ +#define GETCELL 04 /* name & value space was got with getcell */ + +Extern struct var *vlist; /* dictionary */ + +Extern struct var *homedir; /* home directory */ +Extern struct var *prompt; /* main prompt */ +Extern struct var *cprompt; /* continuation prompt */ +Extern struct var *path; /* search path for commands */ +Extern struct var *shell; /* shell to interpret command files */ +Extern struct var *ifs; /* field separators */ + +_PROTOTYPE(int yyparse , (void)); +_PROTOTYPE(struct var *lookup , (char *n )); +_PROTOTYPE(void setval , (struct var *vp , char *val )); +_PROTOTYPE(void nameval , (struct var *vp , char *val , char *name )); +_PROTOTYPE(void export , (struct var *vp )); +_PROTOTYPE(void ronly , (struct var *vp )); +_PROTOTYPE(int isassign , (char *s )); +_PROTOTYPE(int checkname , (char *cp )); +_PROTOTYPE(int assign , (char *s , int cf )); +_PROTOTYPE(void putvlist , (int f , int out )); +_PROTOTYPE(int eqname , (char *n1 , char *n2 )); + +_PROTOTYPE(int execute , (struct op *t , int *pin , int *pout , int act )); + +/* -------- io.h -------- */ +/* io buffer */ +struct iobuf { + unsigned id; /* buffer id */ + char buf[512]; /* buffer */ + char *bufp; /* pointer into buffer */ + char *ebufp; /* pointer to end of buffer */ +}; + +/* possible arguments to an IO function */ +struct ioarg { + char *aword; + char **awordlist; + int afile; /* file descriptor */ + unsigned afid; /* buffer id */ + long afpos; /* file position */ + struct iobuf *afbuf; /* buffer for this file */ +}; +Extern struct ioarg ioargstack[NPUSH]; +#define AFID_NOBUF (~0) +#define AFID_ID 0 + +/* an input generator's state */ +struct io { + int (*iofn)(_VOID); + struct ioarg *argp; + int peekc; + char prev; /* previous character read by readc() */ + char nlcount; /* for `'s */ + char xchar; /* for `'s */ + char task; /* reason for pushed IO */ +}; +Extern struct io iostack[NPUSH]; +#define XOTHER 0 /* none of the below */ +#define XDOLL 1 /* expanding ${} */ +#define XGRAVE 2 /* expanding `'s */ +#define XIO 3 /* file IO */ + +/* in substitution */ +#define INSUB() (env.iop->task == XGRAVE || env.iop->task == XDOLL) + +/* + * input generators for IO structure + */ +_PROTOTYPE(int nlchar , (struct ioarg *ap )); +_PROTOTYPE(int strchar , (struct ioarg *ap )); +_PROTOTYPE(int qstrchar , (struct ioarg *ap )); +_PROTOTYPE(int filechar , (struct ioarg *ap )); +_PROTOTYPE(int herechar , (struct ioarg *ap )); +_PROTOTYPE(int linechar , (struct ioarg *ap )); +_PROTOTYPE(int gravechar , (struct ioarg *ap , struct io *iop )); +_PROTOTYPE(int qgravechar , (struct ioarg *ap , struct io *iop )); +_PROTOTYPE(int dolchar , (struct ioarg *ap )); +_PROTOTYPE(int wdchar , (struct ioarg *ap )); +_PROTOTYPE(void scraphere , (void)); +_PROTOTYPE(void freehere , (int area )); +_PROTOTYPE(void gethere , (void)); +_PROTOTYPE(void markhere , (char *s , struct ioword *iop )); +_PROTOTYPE(int herein , (char *hname , int xdoll )); +_PROTOTYPE(int run , (struct ioarg *argp , int (*f)(_VOID))); + +/* + * IO functions + */ +_PROTOTYPE(int eofc , (void)); +_PROTOTYPE(int getc , (int ec )); +_PROTOTYPE(int readc , (void)); +_PROTOTYPE(void unget , (int c )); +_PROTOTYPE(void ioecho , (char c )); /* Nick, formerly int c */ +_PROTOTYPE(void prs , (char *s )); +_PROTOTYPE(void sh_putc , (char c )); /* Nick, formerly int c */ +_PROTOTYPE(void prn , (unsigned u )); +_PROTOTYPE(void closef , (int i )); +_PROTOTYPE(void closeall , (void)); + +/* + * IO control + */ +_PROTOTYPE(void pushio , (struct ioarg *argp , int (*fn)(_VOID))); +_PROTOTYPE(int remap , (int fd )); +_PROTOTYPE(int openpipe , (int *pv )); +_PROTOTYPE(void closepipe , (int *pv )); +_PROTOTYPE(struct io *setbase , (struct io *ip )); + +extern struct ioarg temparg; /* temporary for PUSHIO */ +#define PUSHIO(what,arg,gen) ((temparg.what = (arg)),pushio(&temparg,(gen))) +#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen))) + +/* -------- word.h -------- */ +#ifndef WORD_H +#define WORD_H 1 +struct wdblock { + short w_bsize; + short w_nword; + /* bounds are arbitrary */ + char *w_words[1]; +}; + +_PROTOTYPE(struct wdblock *addword , (char *wd , struct wdblock *wb )); +_PROTOTYPE(struct wdblock *newword , (int nw )); +_PROTOTYPE(char **getwords , (struct wdblock *wb )); +#endif + +/* -------- area.h -------- */ + +/* + * storage allocation + */ +_PROTOTYPE(char *getcell , (unsigned nbytes )); +_PROTOTYPE(void garbage , (void)); +_PROTOTYPE(void setarea , (char *cp , int a )); +_PROTOTYPE(int getarea , (char *cp )); +_PROTOTYPE(void freearea , (int a )); +_PROTOTYPE(void freecell , (char *cp )); + +Extern int areanum; /* current allocation area */ + +#define NEW(type) (type *)getcell(sizeof(type)) +#define DELETE(obj) freecell((char *)obj) diff --git a/src/sh/msh/sh1.c b/src/sh/msh/sh1.c new file mode 100755 index 00000000..51299f8a --- /dev/null +++ b/src/sh/msh/sh1.c @@ -0,0 +1,970 @@ +#define Extern extern +#include /* Nick sys/types.h> */ +#include +#define _NSIG NSIGS /* Nick NSIG */ +#include +#include +#include "sh.h" +/* -------- sh.c -------- */ +/* + * shell + */ + +/* #include "sh.h" */ + +int intr; +int inparse; +char flags['z'-'a'+1]; +char *flag = flags-'a'; +char *elinep = line+sizeof(line)-5; +char *null = ""; +int heedint =1; +#if 1 /* Nick */ +struct s_env env = { line, iostack, iostack-1, + (xint *)NULL, FDBASE, (struct s_env *)NULL }; +#else +struct env e = { line, iostack, iostack-1, + (xint *)NULL, FDBASE, (struct env *)NULL }; +#endif + +extern char **environ; /* environment pointer */ + +/* + * default shell, search rules + */ +char shellname[] = "/bin/sh"; +char search[] = ":/bin:/usr/bin"; + +_PROTOTYPE(void (*qflag), (int)) = (int (*)(int))SIG_IGN; /* Nick cast */ + +_PROTOTYPE(int main, (int argc, char **argv )); +_PROTOTYPE(int newfile, (char *s )); +_PROTOTYPE(static char *findeq, (char *cp )); +_PROTOTYPE(static char *cclass, (char *p, int sub )); +_PROTOTYPE(void initarea, (void)); + +int main(argc, argv) +int argc; +register char **argv; +{ + register int f; + register char *s; + int cflag; + char *name, **ap; + int (*iof)(); + + initarea(); + if ((ap = environ) != NULL) { + while (*ap) + assign(*ap++, !COPYV); + for (ap = environ; *ap;) + export(lookup(*ap++)); + } + closeall(); + areanum = 1; + + shell = lookup("SHELL"); + if (shell->value == null) + setval(shell, shellname); + export(shell); + + homedir = lookup("HOME"); + if (homedir->value == null) + setval(homedir, "/"); + export(homedir); + + setval(lookup("$"), sh_itoa(getpid(), 5)); + + path = lookup("PATH"); + if (path->value == null) + setval(path, search); + export(path); + + ifs = lookup("IFS"); + if (ifs->value == null) + setval(ifs, " \t\n"); + + prompt = lookup("PS1"); + if (prompt->value == null) +#ifndef UNIXSHELL + setval(prompt, "$ "); +#else + setval(prompt, "% "); +#endif + + if (geteuid() == 0) { + setval(prompt, "# "); + prompt->status &= ~EXPORT; + } + cprompt = lookup("PS2"); + if (cprompt->value == null) + setval(cprompt, "> "); + + iof = filechar; + cflag = 0; + name = *argv++; + if (--argc >= 1) { + if(argv[0][0] == '-' && argv[0][1] != '\0') { + for (s = argv[0]+1; *s; s++) + switch (*s) { + case 'c': + prompt->status &= ~EXPORT; + cprompt->status &= ~EXPORT; + setval(prompt, ""); + setval(cprompt, ""); + cflag = 1; + if (--argc > 0) + PUSHIO(aword, *++argv, iof = nlchar); + break; + + case 'q': + qflag = SIG_DFL; + break; + + case 's': + /* standard input */ + break; + + case 't': + prompt->status &= ~EXPORT; + setval(prompt, ""); + iof = linechar; + break; + + case 'i': + talking++; + default: + if (*s>='a' && *s<='z') + flag[*s]++; + } + } else { + argv--; + argc++; + } + if (iof == filechar && --argc > 0) { + setval(prompt, ""); + setval(cprompt, ""); + prompt->status &= ~EXPORT; + cprompt->status &= ~EXPORT; + if (newfile(name = *++argv)) + exit(1); + } + } + setdash(); + if (env.iop < iostack) { + PUSHIO(afile, 0, iof); + if (isatty(0) && isatty(1) && !cflag) + talking++; + } + signal(SIGQUIT, (sig_t)qflag); /* Nick cast */ + if (name && name[0] == '-') { + talking++; + if ((f = open(".profile", 0)) >= 0) + next(remap(f)); + if ((f = open("/etc/profile", 0)) >= 0) + next(remap(f)); + } + if (talking) + signal(SIGTERM, (sig_t)sig); /* Nick cast */ + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + signal(SIGINT, (sig_t)onintr); /* Nick cast */ + dolv = argv; + dolc = argc; + dolv[0] = name; + if (dolc > 1) + for (ap = ++argv; --argc > 0;) + if (assign(*ap = *argv++, !COPYV)) + dolc--; /* keyword */ + else + ap++; + setval(lookup("#"), putn((--dolc < 0) ? (dolc = 0) : dolc)); + + for (;;) { + if (talking && env.iop <= iostack) + prs(prompt->value); + onecommand(); + } +} + +void +setdash() +{ + register char *cp, c; + char m['z'-'a'+1]; + + cp = m; + for (c='a'; c<='z'; c++) + if (flag[c]) + *cp++ = c; + *cp = 0; + setval(lookup("-"), m); +} + +int +newfile(s) +register char *s; +{ + register f; + + if (strcmp(s, "-") != 0) { + f = open(s, 0); + if (f < 0) { + prs(s); + err(": cannot open"); + return(1); + } + } else + f = 0; + next(remap(f)); + return(0); +} + +void +onecommand() +{ + register i; + jmp_buf m1; + + while (env.oenv) + quitenv(); + areanum = 1; + freehere(areanum); + freearea(areanum); + garbage(); + wdlist = 0; + iolist = 0; + env.errpt = 0; + env.linep = line; + yynerrs = 0; + multiline = 0; + inparse = 1; + intr = 0; + execflg = 0; + setjmp(failpt = m1); /* Bruce Evans' fix */ + if (setjmp(failpt = m1) || yyparse() || intr) { + while (env.oenv) + quitenv(); + scraphere(); + if (!talking && intr) + leave(); + inparse = 0; + intr = 0; + return; + } + inparse = 0; + brklist = 0; + intr = 0; + execflg = 0; + if (!flag['n']) + execute(outtree, NOPIPE, NOPIPE, 0); + if (!talking && intr) { + execflg = 0; + leave(); + } + if ((i = trapset) != 0) { + trapset = 0; + runtrap(i); + } +} + +void +fail() +{ + longjmp(failpt, 1); + /* NOTREACHED */ +} + +void +leave() +{ + if (execflg) + fail(); + scraphere(); + freehere(1); + runtrap(0); + exit(exstat); + /* NOTREACHED */ +} + +void +warn(s) +register char *s; +{ + if(*s) { + prs(s); + exstat = -1; + } + prs("\n"); + if (flag['e']) + leave(); +} + +void +err(s) +char *s; +{ + warn(s); + if (flag['n']) + return; + if (!talking) + leave(); + if (env.errpt) + longjmp(env.errpt, 1); + closeall(); + env.iop = env.iobase = iostack; +} + +int +newenv(f) +int f; +{ +#if 1 /* Nick */ + register struct s_env *ep; +#else + register struct env *ep; +#endif + + if (f) { + quitenv(); + return(1); + } +#if 1 /* Nick */ + ep = (struct s_env *) space(sizeof(*ep)); +#else + ep = (struct env *) space(sizeof(*ep)); +#endif + if (ep == NULL) { + while (env.oenv) + quitenv(); + fail(); + } + *ep = env; + env.oenv = ep; + env.errpt = errpt; + return(0); +} + +void +quitenv() +{ +#if 1 /* Nick */ + register struct s_env *ep; +#else + register struct env *ep; +#endif + register fd; + + if ((ep = env.oenv) != NULL) { + fd = env.iofd; + env = *ep; + /* should close `'d files */ + DELETE(ep); + while (--fd >= env.iofd) + close(fd); + } +} + +/* + * Is any character from s1 in s2? + */ +int +anys(s1, s2) +register char *s1, *s2; +{ + while (*s1) + if (any(*s1++, s2)) + return(1); + return(0); +} + +/* + * Is character c in s? + */ +int +any(c, s) +register int c; +register char *s; +{ + while (*s) + if (*s++ == c) + return(1); + return(0); +} + +char * +putn(n) +register int n; +{ + return(sh_itoa(n, -1)); +} + +char * +sh_itoa(u, n) +register unsigned u; +int n; +{ + register char *cp; + static char s[20]; + int m; + + m = 0; + if (n < 0 && (int) u < 0) { + m++; + u = -u; + } + cp = s+sizeof(s); + *--cp = 0; + do { + *--cp = u%10 + '0'; + u /= 10; + } while (--n > 0 || u); + if (m) + *--cp = '-'; + return(cp); +} + +void +next(f) +int f; +{ + PUSHIO(afile, f, filechar); +} + +void +onintr(s) +int s; /* ANSI C requires a parameter */ +{ + signal(SIGINT, (sig_t)onintr); /* Nick cast */ + intr = 1; + if (talking) { + if (inparse) { + prs("\n"); + fail(); + } + } + else if (heedint) { + execflg = 0; + leave(); + } +} + +int +letter(c) +register c; +{ + return((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'); +} + +int +digit(c) +register c; +{ + return(c >= '0' && c <= '9'); +} + +int +letnum(c) +register c; +{ + return(letter(c) || digit(c)); +} + +char * +space(n) +int n; +{ + register char *cp; + + if ((cp = getcell(n)) == 0) + err("out of string space"); + return(cp); +} + +char * +strsave(s, a) +register char *s; +int a; +{ + register char *cp, *xp; + + if ((cp = space(strlen(s)+1)) != NULL) { + setarea((char *)cp, a); + for (xp = cp; (*xp++ = *s++) != '\0';) + ; + return(cp); + } + return(""); +} + +void +xfree(s) +register char *s; +{ + DELETE(s); +} + +/* + * trap handling + */ +void +sig(i) +register int i; +{ + trapset = i; + signal(i, (sig_t)sig); /* Nick cast */ +} + +void runtrap(i) +int i; +{ + char *trapstr; + + if ((trapstr = trap[i]) == NULL) + return; + if (i == 0) + trap[i] = 0; + RUN(aword, trapstr, nlchar); +} + +/* -------- var.c -------- */ +/* #include "sh.h" */ + +/* + * Find the given name in the dictionary + * and return its value. If the name was + * not previously there, enter it now and + * return a null value. + */ +struct var * +lookup(n) +register char *n; +{ + register struct var *vp; + register char *cp; + register int c; + static struct var dummy; + + if (digit(*n)) { + dummy.name = n; + for (c = 0; digit(*n) && c < 1000; n++) + c = c*10 + *n-'0'; + dummy.status = RONLY; + dummy.value = c <= dolc? dolv[c]: null; + return(&dummy); + } + for (vp = vlist; vp; vp = vp->next) + if (eqname(vp->name, n)) + return(vp); + cp = findeq(n); + vp = (struct var *)space(sizeof(*vp)); + if (vp == 0 || (vp->name = space((int)(cp-n)+2)) == 0) { + dummy.name = dummy.value = ""; + return(&dummy); + } + for (cp = vp->name; (*cp = *n++) && *cp != '='; cp++) + ; + if (*cp == 0) + *cp = '='; + *++cp = 0; + setarea((char *)vp, 0); + setarea((char *)vp->name, 0); + vp->value = null; + vp->next = vlist; + vp->status = GETCELL; + vlist = vp; + return(vp); +} + +/* + * give variable at `vp' the value `val'. + */ +void +setval(vp, val) +struct var *vp; +char *val; +{ + nameval(vp, val, (char *)NULL); +} + +/* + * if name is not NULL, it must be + * a prefix of the space `val', + * and end with `='. + * this is all so that exporting + * values is reasonably painless. + */ +void +nameval(vp, val, name) +register struct var *vp; +char *val, *name; +{ + register char *cp, *xp; + char *nv; + int fl; + + if (vp->status & RONLY) { + for (xp = vp->name; *xp && *xp != '=';) + putc(*xp++); + err(" is read-only"); + return; + } + fl = 0; + if (name == NULL) { + xp = space(strlen(vp->name)+strlen(val)+2); + if (xp == 0) + return; + /* make string: name=value */ + setarea((char *)xp, 0); + name = xp; + for (cp = vp->name; (*xp = *cp++) && *xp!='='; xp++) + ; + if (*xp++ == 0) + xp[-1] = '='; + nv = xp; + for (cp = val; (*xp++ = *cp++) != '\0';) + ; + val = nv; + fl = GETCELL; + } + if (vp->status & GETCELL) + xfree(vp->name); /* form new string `name=value' */ + vp->name = name; + vp->value = val; + vp->status |= fl; +} + +void +export(vp) +struct var *vp; +{ + vp->status |= EXPORT; +} + +void +ronly(vp) +struct var *vp; +{ + if (letter(vp->name[0])) /* not an internal symbol ($# etc) */ + vp->status |= RONLY; +} + +int +isassign(s) +register char *s; +{ + if (!letter((int)*s)) + return(0); + for (; *s != '='; s++) + if (*s == 0 || !letnum(*s)) + return(0); + return(1); +} + +int +assign(s, cf) +register char *s; +int cf; +{ + register char *cp; + struct var *vp; + + if (!letter(*s)) + return(0); + for (cp = s; *cp != '='; cp++) + if (*cp == 0 || !letnum(*cp)) + return(0); + vp = lookup(s); + nameval(vp, ++cp, cf == COPYV? (char *)NULL: s); + if (cf != COPYV) + vp->status &= ~GETCELL; + return(1); +} + +int +checkname(cp) +register char *cp; +{ + if (!letter(*cp++)) + return(0); + while (*cp) + if (!letnum(*cp++)) + return(0); + return(1); +} + +void +putvlist(f, out) +register int f, out; +{ + register struct var *vp; + + for (vp = vlist; vp; vp = vp->next) + if (vp->status & f && letter(*vp->name)) { + if (vp->status & EXPORT) + write(out, "export ", 7); + if (vp->status & RONLY) + write(out, "readonly ", 9); + write(out, vp->name, (int)(findeq(vp->name) - vp->name)); + write(out, "\n", 1); + } +} + +int +eqname(n1, n2) +register char *n1, *n2; +{ + for (; *n1 != '=' && *n1 != 0; n1++) + if (*n2++ != *n1) + return(0); + return(*n2 == 0 || *n2 == '='); +} + +static char * +findeq(cp) +register char *cp; +{ + while (*cp != '\0' && *cp != '=') + cp++; + return(cp); +} + +/* -------- gmatch.c -------- */ +/* + * int gmatch(string, pattern) + * char *string, *pattern; + * + * Match a pattern as in sh(1). + */ + +#define CMASK 0377 +#define QUOTE 0200 +#define QMASK (CMASK&~QUOTE) +#define NOT '!' /* might use ^ */ + +int +gmatch(s, p) +register char *s, *p; +{ + register int sc, pc; + + if (s == NULL || p == NULL) + return(0); + while ((pc = *p++ & CMASK) != '\0') { + sc = *s++ & QMASK; + switch (pc) { + case '[': + if ((p = cclass(p, sc)) == NULL) + return(0); + break; + + case '?': + if (sc == 0) + return(0); + break; + + case '*': + s--; + do { + if (*p == '\0' || gmatch(s, p)) + return(1); + } while (*s++ != '\0'); + return(0); + + default: + if (sc != (pc&~QUOTE)) + return(0); + } + } + return(*s == 0); +} + +static char * +cclass(p, sub) +register char *p; +register int sub; +{ + register int c, d, not, found; + + if ((not = *p == not) != 0) + p++; + found = not; + do { + if (*p == '\0') + return((char *)NULL); + c = *p & CMASK; + if (p[1] == '-' && p[2] != ']') { + d = p[2] & CMASK; + p++; + } else + d = c; + if (c == sub || (c <= sub && sub <= d)) + found = !not; + } while (*++p != ']'); + return(found? p+1: (char *)NULL); +} + +/* -------- area.c -------- */ +#define REGSIZE sizeof(struct region) +#define GROWBY 256 +#undef SHRINKBY /* 64 */ +#define FREE 32767 +#define BUSY 0 +#define ALIGN (sizeof(int)-1) + +/* #include "area.h" */ + +struct region { + struct region *next; + int area; +}; + +/* + * All memory between (char *)areabot and (char *)(areatop+1) is + * exclusively administered by the area management routines. + * It is assumed that sbrk() and brk() manipulate the high end. + */ +static struct region *areabot; /* bottom of area */ +static struct region *areatop; /* top of area */ +static struct region *areanxt; /* starting point of scan */ + +void +initarea() +{ + while ((int)sbrk(0) & ALIGN) + sbrk(1); + areabot = (struct region *)sbrk(REGSIZE); + areabot->next = areabot; + areabot->area = BUSY; + areatop = areabot; + areanxt = areabot; +} + +char * +getcell(nbytes) +unsigned nbytes; +{ + register int nregio; + register struct region *p, *q; + register i; + + if (nbytes == 0) + abort(); /* silly and defeats the algorithm */ + /* + * round upwards and add administration area + */ + nregio = (nbytes+(REGSIZE-1))/REGSIZE + 1; + for (p = areanxt;;) { + if (p->area > areanum) { + /* + * merge free cells + */ + while ((q = p->next)->area > areanum && q != areanxt) + p->next = q->next; + /* + * exit loop if cell big enough + */ + if (q >= p + nregio) + goto found; + } + p = p->next; + if (p == areanxt) + break; + } + i = nregio >= GROWBY ? nregio : GROWBY; + p = (struct region *)sbrk(i * REGSIZE); + if (p == (struct region *)-1) + return((char *)NULL); + p--; + if (p != areatop) + abort(); /* allocated areas are contiguous */ + q = p + i; + p->next = q; + p->area = FREE; + q->next = areabot; + q->area = BUSY; + areatop = q; +found: + /* + * we found a FREE area big enough, pointed to by 'p', and up to 'q' + */ + areanxt = p + nregio; + if (areanxt < q) { + /* + * split into requested area and rest + */ + if (areanxt+1 > q) + abort(); /* insufficient space left for admin */ + areanxt->next = q; + areanxt->area = FREE; + p->next = areanxt; + } + p->area = areanum; + return((char *)(p+1)); +} + +void +freecell(cp) +char *cp; +{ + register struct region *p; + + if ((p = (struct region *)cp) != NULL) { + p--; + if (p < areanxt) + areanxt = p; + p->area = FREE; + } +} + +void +freearea(a) +register int a; +{ + register struct region *p, *top; + + top = areatop; + for (p = areabot; p != top; p = p->next) + if (p->area >= a) + p->area = FREE; +} + +void +setarea(cp,a) +char *cp; +int a; +{ + register struct region *p; + + if ((p = (struct region *)cp) != NULL) + (p-1)->area = a; +} + +int +getarea(cp) +char *cp; +{ + return ((struct region*)cp-1)->area; +} + +void +garbage() +{ + register struct region *p, *q, *top; + + top = areatop; + for (p = areabot; p != top; p = p->next) { + if (p->area > areanum) { + while ((q = p->next)->area > areanum) + p->next = q->next; + areanxt = p; + } + } +#ifdef SHRINKBY + if (areatop >= q + SHRINKBY && q->area > areanum) { + brk((char *)(q+1)); + q->next = areabot; + q->area = BUSY; + areatop = q; + } +#endif +} diff --git a/src/sh/msh/sh2.c b/src/sh/msh/sh2.c new file mode 100755 index 00000000..f0f83133 --- /dev/null +++ b/src/sh/msh/sh2.c @@ -0,0 +1,801 @@ +#define Extern extern +#include /* Nick sys/types.h> */ +#include +#define _NSIG NSIGS /* Nick NSIG */ +#include +#include +#include "sh.h" + +/* -------- csyn.c -------- */ +/* + * shell: syntax (C version) + */ + +typedef union { + char *cp; + char **wp; + int i; + struct op *o; +} YYSTYPE; +#define WORD 256 +#define LOGAND 257 +#define LOGOR 258 +#define BREAK 259 +#define IF 260 +#define THEN 261 +#define ELSE 262 +#define ELIF 263 +#define FI 264 +#define CASE 265 +#define ESAC 266 +#define FOR 267 +#define WHILE 268 +#define UNTIL 269 +#define DO 270 +#define DONE 271 +#define IN 272 +#define YYERRCODE 300 + +/* flags to yylex */ +#define CONTIN 01 /* skip new lines to complete command */ + +/* #include "sh.h" */ +#define SYNTAXERR zzerr() +static int startl; +static int peeksym; +static int nlseen; +static int iounit = IODEFAULT; + +static YYSTYPE yylval; + +_PROTOTYPE(static struct op *pipeline, (int cf )); +_PROTOTYPE(static struct op *andor, (void)); +_PROTOTYPE(static struct op *c_list, (void)); +_PROTOTYPE(static int synio, (int cf )); +_PROTOTYPE(static void musthave, (int c, int cf )); +_PROTOTYPE(static struct op *simple, (void)); +_PROTOTYPE(static struct op *nested, (int type, int mark )); +_PROTOTYPE(static struct op *command, (int cf )); +_PROTOTYPE(static struct op *dogroup, (int onlydone )); +_PROTOTYPE(static struct op *thenpart, (void)); +_PROTOTYPE(static struct op *elsepart, (void)); +_PROTOTYPE(static struct op *caselist, (void)); +_PROTOTYPE(static struct op *casepart, (void)); +_PROTOTYPE(static char **pattern, (void)); +_PROTOTYPE(static char **wordlist, (void)); +_PROTOTYPE(static struct op *list, (struct op *t1, struct op *t2 )); +_PROTOTYPE(static struct op *block, (int type, struct op *t1, struct op *t2, char **wp )); +_PROTOTYPE(static struct op *newtp, (void)); +_PROTOTYPE(static struct op *namelist, (struct op *t )); +_PROTOTYPE(static char **copyw, (void)); +_PROTOTYPE(static void word, (char *cp )); +_PROTOTYPE(static struct ioword **copyio, (void)); +_PROTOTYPE(static struct ioword *io, (int u, int f, char *cp )); +_PROTOTYPE(static void zzerr, (void)); +_PROTOTYPE(void yyerror, (char *s )); +_PROTOTYPE(static int yylex, (int cf )); +_PROTOTYPE(int collect, (int c, int c1 )); +_PROTOTYPE(int dual, (int c )); +_PROTOTYPE(static void diag, (int ec )); +_PROTOTYPE(static char *tree, (unsigned size )); +_PROTOTYPE(void printf, (char *s )); + +int +yyparse() +{ + startl = 1; + peeksym = 0; + yynerrs = 0; + outtree = c_list(); + musthave('\n', 0); + return(yynerrs!=0); +} + +static struct op * +pipeline(cf) +int cf; +{ + register struct op *t, *p; + register int c; + + t = command(cf); + if (t != NULL) { + while ((c = yylex(0)) == '|') { + if ((p = command(CONTIN)) == NULL) + SYNTAXERR; + if (t->type != TPAREN && t->type != TCOM) { + /* shell statement */ + t = block(TPAREN, t, NOBLOCK, NOWORDS); + } + t = block(TPIPE, t, p, NOWORDS); + } + peeksym = c; + } + return(t); +} + +static struct op * +andor() +{ + register struct op *t, *p; + register int c; + + t = pipeline(0); + if (t != NULL) { + while ((c = yylex(0)) == LOGAND || c == LOGOR) { + if ((p = pipeline(CONTIN)) == NULL) + SYNTAXERR; + t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS); + } + peeksym = c; + } + return(t); +} + +static struct op * +c_list() +{ + register struct op *t, *p; + register int c; + + t = andor(); + if (t != NULL) { + if((peeksym = yylex(0)) == '&') + t = block(TASYNC, t, NOBLOCK, NOWORDS); + while ((c = yylex(0)) == ';' || c == '&' || (multiline && c == '\n')) { + if ((p = andor()) == NULL) + return(t); + if((peeksym = yylex(0)) == '&') + p = block(TASYNC, p, NOBLOCK, NOWORDS); + t = list(t, p); + } + peeksym = c; + } + return(t); +} + + +static int +synio(cf) +int cf; +{ + register struct ioword *iop; + register int i; + register int c; + + if ((c = yylex(cf)) != '<' && c != '>') { + peeksym = c; + return(0); + } + i = yylval.i; + musthave(WORD, 0); + iop = io(iounit, i, yylval.cp); + iounit = IODEFAULT; + if (i & IOHERE) + markhere(yylval.cp, iop); + return(1); +} + +static void +musthave(c, cf) +int c, cf; +{ + if ((peeksym = yylex(cf)) != c) + SYNTAXERR; + peeksym = 0; +} + +static struct op * +simple() +{ + register struct op *t; + + t = NULL; + for (;;) { + switch (peeksym = yylex(0)) { + case '<': + case '>': + (void) synio(0); + break; + + case WORD: + if (t == NULL) { + t = newtp(); + t->type = TCOM; + } + peeksym = 0; + word(yylval.cp); + break; + + default: + return(t); + } + } +} + +static struct op * +nested(type, mark) +int type, mark; +{ + register struct op *t; + + multiline++; + t = c_list(); + musthave(mark, 0); + multiline--; + return(block(type, t, NOBLOCK, NOWORDS)); +} + +static struct op * +command(cf) +int cf; +{ + register struct op *t; + struct wdblock *iosave; + register int c; + + iosave = iolist; + iolist = NULL; + if (multiline) + cf |= CONTIN; + while (synio(cf)) + cf = 0; + switch (c = yylex(cf)) { + default: + peeksym = c; + if ((t = simple()) == NULL) { + if (iolist == NULL) + return((struct op *)NULL); + t = newtp(); + t->type = TCOM; + } + break; + + case '(': + t = nested(TPAREN, ')'); + break; + + case '{': + t = nested(TBRACE, '}'); + break; + + case FOR: + t = newtp(); + t->type = TFOR; + musthave(WORD, 0); + startl = 1; + t->str = yylval.cp; + multiline++; + t->words = wordlist(); + if ((c = yylex(0)) != '\n' && c != ';') + peeksym = c; + t->left = dogroup(0); + multiline--; + break; + + case WHILE: + case UNTIL: + multiline++; + t = newtp(); + t->type = c == WHILE? TWHILE: TUNTIL; + t->left = c_list(); + t->right = dogroup(1); + t->words = NULL; + multiline--; + break; + + case CASE: + t = newtp(); + t->type = TCASE; + musthave(WORD, 0); + t->str = yylval.cp; + startl++; + multiline++; + musthave(IN, CONTIN); + startl++; + t->left = caselist(); + musthave(ESAC, 0); + multiline--; + break; + + case IF: + multiline++; + t = newtp(); + t->type = TIF; + t->left = c_list(); + t->right = thenpart(); + musthave(FI, 0); + multiline--; + break; + } + while (synio(0)) + ; + t = namelist(t); + iolist = iosave; + return(t); +} + +static struct op * +dogroup(onlydone) +int onlydone; +{ + register int c; + register struct op *list; + + c = yylex(CONTIN); + if (c == DONE && onlydone) + return((struct op *)NULL); + if (c != DO) + SYNTAXERR; + list = c_list(); + musthave(DONE, 0); + return(list); +} + +static struct op * +thenpart() +{ + register int c; + register struct op *t; + + if ((c = yylex(0)) != THEN) { + peeksym = c; + return((struct op *)NULL); + } + t = newtp(); + t->type = 0; + t->left = c_list(); + if (t->left == NULL) + SYNTAXERR; + t->right = elsepart(); + return(t); +} + +static struct op * +elsepart() +{ + register int c; + register struct op *t; + + switch (c = yylex(0)) { + case ELSE: + if ((t = c_list()) == NULL) + SYNTAXERR; + return(t); + + case ELIF: + t = newtp(); + t->type = TELIF; + t->left = c_list(); + t->right = thenpart(); + return(t); + + default: + peeksym = c; + return((struct op *)NULL); + } +} + +static struct op * +caselist() +{ + register struct op *t; + + t = NULL; + while ((peeksym = yylex(CONTIN)) != ESAC) + t = list(t, casepart()); + return(t); +} + +static struct op * +casepart() +{ + register struct op *t; + + t = newtp(); + t->type = TPAT; + t->words = pattern(); + musthave(')', 0); + t->left = c_list(); + if ((peeksym = yylex(CONTIN)) != ESAC) + musthave(BREAK, CONTIN); + return(t); +} + +static char ** +pattern() +{ + register int c, cf; + + cf = CONTIN; + do { + musthave(WORD, cf); + word(yylval.cp); + cf = 0; + } while ((c = yylex(0)) == '|'); + peeksym = c; + word(NOWORD); + return(copyw()); +} + +static char ** +wordlist() +{ + register int c; + + if ((c = yylex(0)) != IN) { + peeksym = c; + return((char **)NULL); + } + startl = 0; + while ((c = yylex(0)) == WORD) + word(yylval.cp); + word(NOWORD); + peeksym = c; + return(copyw()); +} + +/* + * supporting functions + */ +static struct op * +list(t1, t2) +register struct op *t1, *t2; +{ + if (t1 == NULL) + return(t2); + if (t2 == NULL) + return(t1); + return(block(TLIST, t1, t2, NOWORDS)); +} + +static struct op * +block(type, t1, t2, wp) +int type; +struct op *t1, *t2; +char **wp; +{ + register struct op *t; + + t = newtp(); + t->type = type; + t->left = t1; + t->right = t2; + t->words = wp; + return(t); +} + +struct res { + char *r_name; + int r_val; +} restab[] = { + "for", FOR, + "case", CASE, + "esac", ESAC, + "while", WHILE, + "do", DO, + "done", DONE, + "if", IF, + "in", IN, + "then", THEN, + "else", ELSE, + "elif", ELIF, + "until", UNTIL, + "fi", FI, + + ";;", BREAK, + "||", LOGOR, + "&&", LOGAND, + "{", '{', + "}", '}', + + 0, +}; + +int +rlookup(n) +register char *n; +{ + register struct res *rp; + + for (rp = restab; rp->r_name; rp++) + if (strcmp(rp->r_name, n) == 0) + return(rp->r_val); + return(0); +} + +static struct op * +newtp() +{ + register struct op *t; + + t = (struct op *)tree(sizeof(*t)); + t->type = 0; + t->words = NULL; + t->ioact = NULL; + t->left = NULL; + t->right = NULL; + t->str = NULL; + return(t); +} + +static struct op * +namelist(t) +register struct op *t; +{ + if (iolist) { + iolist = addword((char *)NULL, iolist); + t->ioact = copyio(); + } else + t->ioact = NULL; + if (t->type != TCOM) { + if (t->type != TPAREN && t->ioact != NULL) { + t = block(TPAREN, t, NOBLOCK, NOWORDS); + t->ioact = t->left->ioact; + t->left->ioact = NULL; + } + return(t); + } + word(NOWORD); + t->words = copyw(); + return(t); +} + +static char ** +copyw() +{ + register char **wd; + + wd = getwords(wdlist); + wdlist = 0; + return(wd); +} + +static void +word(cp) +char *cp; +{ + wdlist = addword(cp, wdlist); +} + +static struct ioword ** +copyio() +{ + register struct ioword **iop; + + iop = (struct ioword **) getwords(iolist); + iolist = 0; + return(iop); +} + +static struct ioword * +io(u, f, cp) +int u; +int f; +char *cp; +{ + register struct ioword *iop; + + iop = (struct ioword *) tree(sizeof(*iop)); + iop->io_unit = u; + iop->io_flag = f; + iop->io_name = cp; + iolist = addword((char *)iop, iolist); + return(iop); +} + +static void +zzerr() +{ + yyerror("syntax error"); +} + +void +yyerror(s) +char *s; +{ + yynerrs++; + if (talking && env.iop <= iostack) { + multiline = 0; + while (eofc() == 0 && yylex(0) != '\n') + ; + } + err(s); + fail(); +} + +static int +yylex(cf) +int cf; +{ + register int c, c1; + int atstart; + + if ((c = peeksym) > 0) { + peeksym = 0; + if (c == '\n') + startl = 1; + return(c); + } + nlseen = 0; + env.linep = line; + atstart = startl; + startl = 0; + yylval.i = 0; + +loop: + while ((c = getc(0)) == ' ' || c == '\t') + ; + switch (c) { + default: + if (any(c, "0123456789")) { + unget(c1 = getc(0)); + if (c1 == '<' || c1 == '>') { + iounit = c - '0'; + goto loop; + } + *env.linep++ = c; + c = c1; + } + break; + + case '#': + while ((c = getc(0)) != 0 && c != '\n') + ; + unget(c); + goto loop; + + case 0: + return(c); + + case '$': + *env.linep++ = c; + if ((c = getc(0)) == '{') { + if ((c = collect(c, '}')) != '\0') + return(c); + goto pack; + } + break; + + case '`': + case '\'': + case '"': + if ((c = collect(c, c)) != '\0') + return(c); + goto pack; + + case '|': + case '&': + case ';': + if ((c1 = dual(c)) != '\0') { + startl = 1; + return(c1); + } + startl = 1; + return(c); + case '^': + startl = 1; + return('|'); + case '>': + case '<': + diag(c); + return(c); + + case '\n': + nlseen++; + gethere(); + startl = 1; + if (multiline || cf & CONTIN) { + if (talking && env.iop <= iostack) + prs(cprompt->value); + if (cf & CONTIN) + goto loop; + } + return(c); + + case '(': + case ')': + startl = 1; + return(c); + } + + unget(c); + +pack: + while ((c = getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n")) + if (env.linep >= elinep) + err("word too long"); + else + *env.linep++ = c; + unget(c); + if(any(c, "\"'`$")) + goto loop; + *env.linep++ = '\0'; + if (atstart && (c = rlookup(line))!=0) { + startl = 1; + return(c); + } + yylval.cp = strsave(line, areanum); + return(WORD); +} + +int +collect(c, c1) +register c, c1; +{ + char s[2]; + + *env.linep++ = c; + while ((c = getc(c1)) != c1) { + if (c == 0) { + unget(c); + s[0] = c1; + s[1] = 0; + prs("no closing "); yyerror(s); + return(YYERRCODE); + } + if (talking && c == '\n' && env.iop <= iostack) + prs(cprompt->value); + *env.linep++ = c; + } + *env.linep++ = c; + return(0); +} + +int +dual(c) +register c; +{ + char s[3]; + register char *cp = s; + + *cp++ = c; + *cp++ = getc(0); + *cp = 0; + if ((c = rlookup(s)) == 0) + unget(*--cp); + return(c); +} + +static void +diag(ec) +register int ec; +{ + register int c; + + c = getc(0); + if (c == '>' || c == '<') { + if (c != ec) + zzerr(); + yylval.i = ec == '>'? IOWRITE|IOCAT: IOHERE; + c = getc(0); + } else + yylval.i = ec == '>'? IOWRITE: IOREAD; + if (c != '&' || yylval.i == IOHERE) + unget(c); + else + yylval.i |= IODUP; +} + +static char * +tree(size) +unsigned size; +{ + register char *t; + + if ((t = getcell(size)) == NULL) { + prs("command line too complicated\n"); + fail(); + /* NOTREACHED */ + } + return(t); +} + +/* VARARGS1 */ +/* ARGSUSED */ +void +printf(s) /* yyparse calls it */ +char *s; +{ +} + diff --git a/src/sh/msh/sh3.c b/src/sh/msh/sh3.c new file mode 100755 index 00000000..f25fabcb --- /dev/null +++ b/src/sh/msh/sh3.c @@ -0,0 +1,1161 @@ +#define Extern extern +#include /* Nick sys/types.h> */ +#include +#define _NSIG NSIGS /* Nick NSIG */ +#include +#include +#include +#include +/* Nick #include */ +#include +#include +/* Nick #undef NULL */ +#include "sh.h" + +/* -------- exec.c -------- */ +/* #include "sh.h" */ + +/* + * execute tree + */ + +static char *signame[] = { + "Signal 0", + "Hangup", + (char *)NULL, /* interrupt */ + "Quit", + "Illegal instruction", + "Trace/BPT trap", + "Abort", + "EMT trap", + "Floating exception", + "Killed", + "Bus error", + "Memory fault", + "Bad system call", + (char *)NULL, /* broken pipe */ + "Alarm clock", + "Terminated", +}; +#define NSIGNAL (sizeof(signame)/sizeof(signame[0])) + + +_PROTOTYPE(static int forkexec, (struct op *t, int *pin, int *pout, int act, char **wp, int *pforked )); +_PROTOTYPE(static int parent, (void)); +_PROTOTYPE(int iosetup, (struct ioword *iop, int pipein, int pipeout )); +_PROTOTYPE(static void echo, (char **wp )); +_PROTOTYPE(static struct op **find1case, (struct op *t, char *w )); +_PROTOTYPE(static struct op *findcase, (struct op *t, char *w )); +_PROTOTYPE(static void brkset, (struct brkcon *bc )); +_PROTOTYPE(int dolabel, (void)); +_PROTOTYPE(int dochdir, (struct op *t )); +_PROTOTYPE(int doshift, (struct op *t )); +_PROTOTYPE(int dologin, (struct op *t )); +_PROTOTYPE(int doumask, (struct op *t )); +_PROTOTYPE(int doexec, (struct op *t )); +_PROTOTYPE(int dodot, (struct op *t )); +_PROTOTYPE(int dowait, (struct op *t )); +_PROTOTYPE(int doread, (struct op *t )); +_PROTOTYPE(int doeval, (struct op *t )); +_PROTOTYPE(int dotrap, (struct op *t )); +_PROTOTYPE(int getsig, (char *s )); +#if 1 /* Nick */ +_PROTOTYPE(void setsig, (signal_t n, sig_t f)); +#else +_PROTOTYPE(void setsig, (int n, void (*f)())); +#endif +_PROTOTYPE(int getn, (char *as )); +_PROTOTYPE(int dobreak, (struct op *t )); +_PROTOTYPE(int docontinue, (struct op *t )); +_PROTOTYPE(static int brkcontin, (char *cp, int val )); +_PROTOTYPE(int doexit, (struct op *t )); +_PROTOTYPE(int doexport, (struct op *t )); +_PROTOTYPE(int doreadonly, (struct op *t )); +_PROTOTYPE(static void rdexp, (char **wp, void (*f)(), int key)); +_PROTOTYPE(static void badid, (char *s )); +_PROTOTYPE(int doset, (struct op *t )); +_PROTOTYPE(void varput, (char *s, int out )); +_PROTOTYPE(int dotimes, (void)); + +int +execute(t, pin, pout, act) +register struct op *t; +int *pin, *pout; +int act; +{ + register struct op *t1; + int i, pv[2], rv, child, a; + char *cp, **wp, **wp2; + struct var *vp; + struct brkcon bc; + + if (t == NULL) + return(0); + rv = 0; + a = areanum++; + wp = (wp2 = t->words) != NULL + ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY) + : NULL; + + switch(t->type) { + case TPAREN: + case TCOM: + rv = forkexec(t, pin, pout, act, wp, &child); + if (child) { + exstat = rv; + leave(); + } + break; + + case TPIPE: + if ((rv = openpipe(pv)) < 0) + break; + pv[0] = remap(pv[0]); + pv[1] = remap(pv[1]); + (void) execute(t->left, pin, pv, 0); + rv = execute(t->right, pv, pout, 0); + break; + + case TLIST: + (void) execute(t->left, pin, pout, 0); + rv = execute(t->right, pin, pout, 0); + break; + + case TASYNC: + i = parent(); + if (i != 0) { + if (i != -1) { + setval(lookup("!"), putn(i)); + if (pin != NULL) + closepipe(pin); + if (talking) { + prs(putn(i)); + prs("\n"); + } + } else + rv = -1; + setstatus(rv); + } else { + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + if (talking) + signal(SIGTERM, SIG_DFL); + talking = 0; + if (pin == NULL) { + close(0); + open("/dev/null", 0); + } + exit(execute(t->left, pin, pout, FEXEC)); + } + break; + + case TOR: + case TAND: + rv = execute(t->left, pin, pout, 0); + if ((t1 = t->right)!=NULL && (rv == 0) == (t->type == TAND)) + rv = execute(t1, pin, pout, 0); + break; + + case TFOR: + if (wp == NULL) { + wp = dolv+1; + if ((i = dolc) < 0) + i = 0; + } else { + i = -1; + while (*wp++ != NULL) + ; + } + vp = lookup(t->str); + while (setjmp(bc.brkpt)) + if (isbreak) + goto broken; + brkset(&bc); + for (t1 = t->left; i-- && *wp != NULL;) { + setval(vp, *wp++); + rv = execute(t1, pin, pout, 0); + } + brklist = brklist->nextlev; + break; + + case TWHILE: + case TUNTIL: + while (setjmp(bc.brkpt)) + if (isbreak) + goto broken; + brkset(&bc); + t1 = t->left; + while ((execute(t1, pin, pout, 0) == 0) == (t->type == TWHILE)) + rv = execute(t->right, pin, pout, 0); + brklist = brklist->nextlev; + break; + + case TIF: + case TELIF: + if (t->right != NULL) { + rv = !execute(t->left, pin, pout, 0) ? + execute(t->right->left, pin, pout, 0): + execute(t->right->right, pin, pout, 0); + } + break; + + case TCASE: + if ((cp = evalstr(t->str, DOSUB|DOTRIM)) == 0) + cp = ""; + if ((t1 = findcase(t->left, cp)) != NULL) + rv = execute(t1, pin, pout, 0); + break; + + case TBRACE: +/* + if (iopp = t->ioact) + while (*iopp) + if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) { + rv = -1; + break; + } +*/ + if (rv >= 0 && (t1 = t->left)) + rv = execute(t1, pin, pout, 0); + break; + } + +broken: + t->words = wp2; + isbreak = 0; + freehere(areanum); + freearea(areanum); + areanum = a; + if (talking && intr) { + closeall(); + fail(); + } + if ((i = trapset) != 0) { + trapset = 0; + runtrap(i); + } + return(rv); +} + +static int +forkexec(t, pin, pout, act, wp, pforked) +register struct op *t; +int *pin, *pout; +int act; +char **wp; +int *pforked; +{ + int i, rv, (*shcom)(); + register int f; + char *cp; + struct ioword **iopp; + int resetsig; + char **owp; + + owp = wp; + resetsig = 0; + *pforked = 0; + shcom = NULL; + rv = -1; /* system-detected error */ + if (t->type == TCOM) { + while ((cp = *wp++) != NULL) + ; + cp = *wp; + + /* strip all initial assignments */ + /* not correct wrt PATH=yyy command etc */ + if (flag['x']) + echo (cp ? wp: owp); + if (cp == NULL && t->ioact == NULL) { + while ((cp = *owp++) != NULL && assign(cp, COPYV)) + ; + return(setstatus(0)); + } + else if (cp != NULL) + shcom = inbuilt(cp); + } + t->words = wp; + f = act; + if (shcom == NULL && (f & FEXEC) == 0) { + i = parent(); + if (i != 0) { + if (i == -1) + return(rv); + if (pin != NULL) + closepipe(pin); + return(pout==NULL? setstatus(waitfor(i,0)): 0); + } + if (talking) { + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + resetsig = 1; + } + talking = 0; + intr = 0; + (*pforked)++; + brklist = 0; + execflg = 0; + } + if (owp != NULL) + while ((cp = *owp++) != NULL && assign(cp, COPYV)) + if (shcom == NULL) + export(lookup(cp)); +#ifdef COMPIPE + if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) { + err("piping to/from shell builtins not yet done"); + return(-1); + } +#endif + if (pin != NULL) { + dup2(pin[0], 0); + closepipe(pin); + } + if (pout != NULL) { + dup2(pout[1], 1); + closepipe(pout); + } + if ((iopp = t->ioact) != NULL) { + if (shcom != NULL && shcom != doexec) { + prs(cp); + err(": cannot redirect shell command"); + return(-1); + } + while (*iopp) + if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) + return(rv); + } + if (shcom) + return(setstatus((*shcom)(t))); + /* should use FIOCEXCL */ + for (i=FDBASE; itype == TPAREN) + exit(execute(t->left, NOPIPE, NOPIPE, FEXEC)); + if (wp[0] == NULL) + exit(0); + cp = rexecve(wp[0], wp, makenv()); + prs(wp[0]); prs(": "); warn(cp); + if (!execflg) + trap[0] = NULL; + leave(); + /* NOTREACHED */ +} + +/* + * common actions when creating a new child + */ +static int +parent() +{ + register int i; + + i = fork(); + if (i != 0) { + if (i == -1) + warn("try again"); + } + return(i); +} + +/* + * 0< 1> are ignored as required + * within pipelines. + */ +int +iosetup(iop, pipein, pipeout) +register struct ioword *iop; +int pipein, pipeout; +{ + register u; + char *cp, *msg; + + if (iop->io_unit == IODEFAULT) /* take default */ + iop->io_unit = iop->io_flag&(IOREAD|IOHERE)? 0: 1; + if (pipein && iop->io_unit == 0) + return(0); + if (pipeout && iop->io_unit == 1) + return(0); + msg = iop->io_flag&(IOREAD|IOHERE)? "open": "create"; + if ((iop->io_flag & IOHERE) == 0) { + cp = iop->io_name; + if ((cp = evalstr(cp, DOSUB|DOTRIM)) == NULL) + return(1); + } + if (iop->io_flag & IODUP) { + if (cp[1] || (!digit(*cp) && *cp != '-')) { + prs(cp); + err(": illegal >& argument"); + return(1); + } + if (*cp == '-') + iop->io_flag = IOCLOSE; + iop->io_flag &= ~(IOREAD|IOWRITE); + } + switch (iop->io_flag) { + case IOREAD: + u = open(cp, 0); + break; + + case IOHERE: + case IOHERE|IOXHERE: + u = herein(iop->io_name, iop->io_flag&IOXHERE); + cp = "here file"; + break; + + case IOWRITE|IOCAT: + if ((u = open(cp, 1)) >= 0) { + lseek(u, (long)0, 2); + break; + } + case IOWRITE: + u = creat(cp, 0666); + break; + + case IODUP: + u = dup2(*cp-'0', iop->io_unit); + break; + + case IOCLOSE: + close(iop->io_unit); + return(0); + } + if (u < 0) { + prs(cp); + prs(": cannot "); + warn(msg); + return(1); + } else { + if (u != iop->io_unit) { + dup2(u, iop->io_unit); + close(u); + } + } + return(0); +} + +static void +echo(wp) +register char **wp; +{ + register i; + + prs("+"); + for (i=0; wp[i]; i++) { + if (i) + prs(" "); + prs(wp[i]); + } + prs("\n"); +} + +static struct op ** +find1case(t, w) +struct op *t; +char *w; +{ + register struct op *t1; + struct op **tp; + register char **wp, *cp; + + if (t == NULL) + return((struct op **)NULL); + if (t->type == TLIST) { + if ((tp = find1case(t->left, w)) != NULL) + return(tp); + t1 = t->right; /* TPAT */ + } else + t1 = t; + for (wp = t1->words; *wp;) + if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp)) + return(&t1->left); + return((struct op **)NULL); +} + +static struct op * +findcase(t, w) +struct op *t; +char *w; +{ + register struct op **tp; + + return((tp = find1case(t, w)) != NULL? *tp: (struct op *)NULL); +} + +/* + * Enter a new loop level (marked for break/continue). + */ +static void +brkset(bc) +struct brkcon *bc; +{ + bc->nextlev = brklist; + brklist = bc; +} + +/* + * Wait for the last process created. + * Print a message for each process found + * that was killed by a signal. + * Ignore interrupt signals while waiting + * unless `canintr' is true. + */ +int +waitfor(lastpid, canintr) +register int lastpid; +int canintr; +{ + register int pid, rv; + int s; + int oheedint = heedint; + + heedint = 0; + rv = 0; + do { + pid = wait(&s); + if (pid == -1) { + if (errno != EINTR || canintr) + break; + } else { + if ((rv = WAITSIG(s)) != 0) { + if (rv < NSIGNAL) { + if (signame[rv] != NULL) { + if (pid != lastpid) { + prn(pid); + prs(": "); + } + prs(signame[rv]); + } + } else { + if (pid != lastpid) { + prn(pid); + prs(": "); + } + prs("Signal "); prn(rv); prs(" "); + } + if (WAITCORE(s)) + prs(" - core dumped"); + if (rv >= NSIGNAL || signame[rv]) + prs("\n"); + rv = -1; + } else + rv = WAITVAL(s); + } + } while (pid != lastpid); + heedint = oheedint; + if (intr) + if (talking) { + if (canintr) + intr = 0; + } else { + if (exstat == 0) exstat = rv; + onintr(0); + } + return(rv); +} + +int +setstatus(s) +register int s; +{ + exstat = s; + setval(lookup("?"), putn(s)); + return(s); +} + +/* + * PATH-searching interface to execve. + * If getenv("PATH") were kept up-to-date, + * execvp might be used. + */ +char * +rexecve(c, v, envp) +char *c, **v, **envp; +{ + register int i; + register char *sp, *tp; + int eacces = 0, asis = 0; + + sp = any('/', c)? "": path->value; + asis = *sp == '\0'; + while (asis || *sp != '\0') { + asis = 0; + tp = env.linep; + for (; *sp != '\0'; tp++) + if ((*tp = *sp++) == ':') { + asis = *sp == '\0'; + break; + } + if (tp != env.linep) + *tp++ = '/'; + for (i = 0; (*tp++ = c[i++]) != '\0';) + ; + execve(env.linep, v, envp); + switch (errno) { + case ENOEXEC: +#if 1 /* Nick */ + return "executable format error"; + case ENOALIGN: + return "file is not aligned"; + case ETOOSHORT: + return "file is too short, or hole"; + case ESHELL: +#endif + *v = env.linep; + tp = *--v; + *v = env.linep; + execve("/bin/sh", v, envp); + *v = tp; + return("no Shell"); + + case ENOMEM: + return("program too big"); + + case E2BIG: + return("argument list too long"); + + case EACCES: + eacces++; + break; + } + } + return(errno==ENOENT ? "not found" : "cannot execute"); +} + +/* + * Run the command produced by generator `f' + * applied to stream `arg'. + */ +int +run(argp, f) +struct ioarg *argp; +int (*f)(); +{ + struct op *otree; + struct wdblock *swdlist; + struct wdblock *siolist; + jmp_buf ev, rt; + xint *ofail; + int rv; + + areanum++; + swdlist = wdlist; + siolist = iolist; + otree = outtree; + ofail = failpt; + rv = -1; + if (newenv(setjmp(errpt = ev)) == 0) { + wdlist = 0; + iolist = 0; + pushio(argp, f); + env.iobase = env.iop; + yynerrs = 0; + if (setjmp(failpt = rt) == 0 && yyparse() == 0) + rv = execute(outtree, NOPIPE, NOPIPE, 0); + quitenv(); + } + wdlist = swdlist; + iolist = siolist; + failpt = ofail; + outtree = otree; + freearea(areanum--); + return(rv); +} + +/* -------- do.c -------- */ +/* #include "sh.h" */ + +/* + * built-in commands: doX + */ + +int +dolabel() +{ + return(0); +} + +int +dochdir(t) +register struct op *t; +{ + register char *cp, *er; + + if ((cp = t->words[1]) == NULL && (cp = homedir->value) == NULL) + er = ": no home directory"; + else if(chdir(cp) < 0) + er = ": bad directory"; + else + return(0); + prs(cp != NULL? cp: "cd"); + err(er); + return(1); +} + +int +doshift(t) +register struct op *t; +{ + register n; + + n = t->words[1]? getn(t->words[1]): 1; + if(dolc < n) { + err("nothing to shift"); + return(1); + } + dolv[n] = dolv[0]; + dolv += n; + dolc -= n; + setval(lookup("#"), putn(dolc)); + return(0); +} + +/* + * execute login and newgrp directly + */ +int +dologin(t) +struct op *t; +{ + register char *cp; + + if (talking) { + signal(SIGINT, SIG_DFL); + signal(SIGQUIT, SIG_DFL); + } + cp = rexecve(t->words[0], t->words, makenv()); + prs(t->words[0]); prs(": "); err(cp); + return(1); +} + +int +doumask(t) +register struct op *t; +{ + register int i, n; + register char *cp; + + if ((cp = t->words[1]) == NULL) { + i = umask(0); + umask(i); + for (n=3*4; (n-=3) >= 0;) + putc('0'+((i>>n)&07)); + putc('\n'); + } else { + for (n=0; *cp>='0' && *cp<='9'; cp++) + n = n*8 + (*cp-'0'); + umask(n); + } + return(0); +} + +int +doexec(t) +register struct op *t; +{ + register i; + jmp_buf ex; + xint *ofail; + + t->ioact = NULL; + for(i = 0; (t->words[i]=t->words[i+1]) != NULL; i++) + ; + if (i == 0) + return(1); + execflg = 1; + ofail = failpt; + if (setjmp(failpt = ex) == 0) + execute(t, NOPIPE, NOPIPE, FEXEC); + failpt = ofail; + execflg = 0; + return(1); +} + +int +dodot(t) +struct op *t; +{ + register i; + register char *sp, *tp; + char *cp; + + if ((cp = t->words[1]) == NULL) + return(0); + sp = any('/', cp)? ":": path->value; + while (*sp) { + tp = env.linep; + while (*sp && (*tp = *sp++) != ':') + tp++; + if (tp != env.linep) + *tp++ = '/'; + for (i = 0; (*tp++ = cp[i++]) != '\0';) + ; + if ((i = open(env.linep, 0)) >= 0) { + exstat = 0; + next(remap(i)); + return(exstat); + } + } + prs(cp); + err(": not found"); + return(-1); +} + +int +dowait(t) +struct op *t; +{ + register i; + register char *cp; + + if ((cp = t->words[1]) != NULL) { + i = getn(cp); + if (i == 0) + return(0); + } else + i = -1; + setstatus(waitfor(i, 1)); + return(0); +} + +int +doread(t) +struct op *t; +{ + register char *cp, **wp; + register nb; + register int nl = 0; + + if (t->words[1] == NULL) { + err("Usage: read name ..."); + return(1); + } + for (wp = t->words+1; *wp; wp++) { + for (cp = env.linep; !nl && cp < elinep-1; cp++) + if ((nb = read(0, cp, sizeof(*cp))) != sizeof(*cp) || + (nl = (*cp == '\n')) || + (wp[1] && any(*cp, ifs->value))) + break; + *cp = 0; + if (nb <= 0) + break; + setval(lookup(*wp), env.linep); + } + return(nb <= 0); +} + +int +doeval(t) +register struct op *t; +{ + return(RUN(awordlist, t->words+1, wdchar)); +} + +int +dotrap(t) +register struct op *t; +{ + register int n, i; + register int resetsig; + + if (t->words[1] == NULL) { + for (i=0; i<=_NSIG; i++) + if (trap[i]) { + prn(i); + prs(": "); + prs(trap[i]); + prs("\n"); + } + return(0); + } + resetsig = digit(*t->words[1]); + for (i = resetsig ? 1 : 2; t->words[i] != NULL; ++i) { + n = getsig(t->words[i]); + xfree(trap[n]); + trap[n] = 0; + if (!resetsig) { + if (*t->words[1] != '\0') { + trap[n] = strsave(t->words[1], 0); + setsig(n, (sig_t)sig); /* Nick cast */ + } else + setsig(n, SIG_IGN); + } else { + if (talking) + if (n == SIGINT) + setsig(n, (sig_t)onintr); /* Nick cast */ + else + setsig(n, n == SIGQUIT ? SIG_IGN + : SIG_DFL); + else + setsig(n, SIG_DFL); + } + } + return(0); +} + +int +getsig(s) +char *s; +{ + register int n; + + if ((n = getn(s)) < 0 || n > _NSIG) { + err("trap: bad signal number"); + n = 0; + } + return(n); +} + +#if 1 /* Nick */ +void setsig(signal_t n, sig_t f) +#else +void +setsig(n, f) +register n; +_PROTOTYPE(void (*f), (int)); +#endif +{ + if (n == 0) + return; + if (signal(n, SIG_IGN) != SIG_IGN || ourtrap[n]) { + ourtrap[n] = 1; + signal(n, f); + } +} + +int +getn(as) +char *as; +{ + register char *s; + register n, m; + + s = as; + m = 1; + if (*s == '-') { + m = -1; + s++; + } + for (n = 0; digit(*s); s++) + n = (n*10) + (*s-'0'); + if (*s) { + prs(as); + err(": bad number"); + } + return(n*m); +} + +int +dobreak(t) +struct op *t; +{ + return(brkcontin(t->words[1], 1)); +} + +int +docontinue(t) +struct op *t; +{ + return(brkcontin(t->words[1], 0)); +} + +static int +brkcontin(cp, val) +register char *cp; +int val; +{ + register struct brkcon *bc; + register nl; + + nl = cp == NULL? 1: getn(cp); + if (nl <= 0) + nl = 999; + do { + if ((bc = brklist) == NULL) + break; + brklist = bc->nextlev; + } while (--nl); + if (nl) { + err("bad break/continue level"); + return(1); + } + isbreak = val; + longjmp(bc->brkpt, 1); + /* NOTREACHED */ +} + +int +doexit(t) +struct op *t; +{ + register char *cp; + + execflg = 0; + if ((cp = t->words[1]) != NULL) + setstatus(getn(cp)); + leave(); + /* NOTREACHED */ +} + +int +doexport(t) +struct op *t; +{ + rdexp(t->words+1, export, EXPORT); + return(0); +} + +int +doreadonly(t) +struct op *t; +{ + rdexp(t->words+1, ronly, RONLY); + return(0); +} + +static void +rdexp(wp, f, key) +register char **wp; +void (*f)(); +int key; +{ + if (*wp != NULL) { + for (; *wp != NULL; wp++) + if (checkname(*wp)) + (*f)(lookup(*wp)); + else + badid(*wp); + } else + putvlist(key, 1); +} + +static void +badid(s) +register char *s; +{ + prs(s); + err(": bad identifier"); +} + +int +doset(t) +register struct op *t; +{ + register struct var *vp; + register char *cp; + register n; + + if ((cp = t->words[1]) == NULL) { + for (vp = vlist; vp; vp = vp->next) + varput(vp->name, 1); + return(0); + } + if (*cp == '-') { + /* bad: t->words++; */ + for(n = 0; (t->words[n]=t->words[n+1]) != NULL; n++) + ; + if (*++cp == 0) + flag['x'] = flag['v'] = 0; + else + for (; *cp; cp++) + switch (*cp) { + case 'e': + if (!talking) + flag['e']++; + break; + + default: + if (*cp>='a' && *cp<='z') + flag[*cp]++; + break; + } + setdash(); + } + if (t->words[1]) { + t->words[0] = dolv[0]; + for (n=1; t->words[n]; n++) + setarea((char *)t->words[n], 0); + dolc = n-1; + dolv = t->words; + setval(lookup("#"), putn(dolc)); + setarea((char *)(dolv-1), 0); + } + return(0); +} + +void +varput(s, out) +register char *s; +int out; +{ + if (letnum(*s)) { + write(out, s, strlen(s)); + write(out, "\n", 1); + } +} + + +#define SECS 60L +#define MINS 3600L + +int +dotimes() +{ +#if 0 /* NICK VERY TEMPORARY PLEASE FIX THIS !! */ + struct tms tbuf; + + times(&tbuf); + + prn((int)(tbuf.tms_cutime / MINS)); + prs("m"); + prn((int)((tbuf.tms_cutime % MINS) / SECS)); + prs("s "); + prn((int)(tbuf.tms_cstime / MINS)); + prs("m"); + prn((int)((tbuf.tms_cstime % MINS) / SECS)); + prs("s\n"); +#endif + return(0); +} + +struct builtin { + char *command; + int (*fn)(); +}; +static struct builtin builtin[] = { + ":", dolabel, + "cd", dochdir, + "shift", doshift, + "exec", doexec, + "wait", dowait, + "read", doread, + "eval", doeval, + "trap", dotrap, + "break", dobreak, + "continue", docontinue, + "exit", doexit, + "export", doexport, + "readonly", doreadonly, + "set", doset, + ".", dodot, + "umask", doumask, + "login", dologin, + "newgrp", dologin, + "times", dotimes, + 0, +}; + +int (*inbuilt(s))() +register char *s; +{ + register struct builtin *bp; + + for (bp = builtin; bp->command != NULL; bp++) + if (strcmp(bp->command, s) == 0) + return(bp->fn); + return((int(*)())NULL); +} + diff --git a/src/sh/msh/sh4.c b/src/sh/msh/sh4.c new file mode 100755 index 00000000..006650cc --- /dev/null +++ b/src/sh/msh/sh4.c @@ -0,0 +1,769 @@ +#define Extern extern +#include /* Nick sys/types.h> */ +#include +#include +#include +#include +#define _NSIG NSIGS /* Nick NSIG */ +#include +#include +#include "sh.h" + +#define NAME_MAX 255 /* Nick just arbitrary */ + +/* -------- eval.c -------- */ +/* #include "sh.h" */ +/* #include "word.h" */ + +/* + * ${} + * `command` + * blank interpretation + * quoting + * glob + */ + +_PROTOTYPE(static int expand, (char *cp, struct wdblock **wbp, int f )); +_PROTOTYPE(static char *blank, (int f )); +_PROTOTYPE(static int dollar, (int quoted )); +_PROTOTYPE(static int grave, (int quoted )); +_PROTOTYPE(void globname, (char *we, char *pp )); +_PROTOTYPE(static char *generate, (char *start1, char *end1, char *middle, char *end )); +_PROTOTYPE(static int anyspcl, (struct wdblock *wb )); +_PROTOTYPE(static int xstrcmp, (char *p1, char *p2 )); +_PROTOTYPE(void glob0, (char *a0, unsigned int a1, int a2, int (*a3)(char *, char *))); +_PROTOTYPE(void glob1, (char *base, char *lim )); +_PROTOTYPE(void glob2, (char *i, char *j )); +_PROTOTYPE(void glob3, (char *i, char *j, char *k )); +_PROTOTYPE(char *memcopy, (char *ato, char *from, int nb )); + +char ** +eval(ap, f) +register char **ap; +int f; +{ + struct wdblock *wb; + char **wp; + char **wf; + jmp_buf ev; + + wp = NULL; + wb = NULL; + wf = NULL; + if (newenv(setjmp(errpt = ev)) == 0) { + while (*ap && isassign(*ap)) + expand(*ap++, &wb, f & ~DOGLOB); + if (flag['k']) { + for (wf = ap; *wf; wf++) { + if (isassign(*wf)) + expand(*wf, &wb, f & ~DOGLOB); + } + } + for (wb = addword((char *)0, wb); *ap; ap++) { + if (!flag['k'] || !isassign(*ap)) + expand(*ap, &wb, f & ~DOKEY); + } + wb = addword((char *)0, wb); + wp = getwords(wb); + quitenv(); + } else + gflg = 1; + return(gflg? (char **)NULL: wp); +} + +/* + * Make the exported environment from the exported + * names in the dictionary. Keyword assignments + * will already have been done. + */ +char ** +makenv() + +{ + register struct wdblock *wb; + register struct var *vp; + + wb = NULL; + for (vp = vlist; vp; vp = vp->next) + if (vp->status & EXPORT) + wb = addword(vp->name, wb); + wb = addword((char *)0, wb); + return(getwords(wb)); +} + +char * +evalstr(cp, f) +register char *cp; +int f; +{ + struct wdblock *wb; + + wb = NULL; + if (expand(cp, &wb, f)) { + if (wb == NULL || wb->w_nword == 0 || (cp = wb->w_words[0]) == NULL) + cp = ""; + DELETE(wb); + } else + cp = NULL; + return(cp); +} + +static int +expand(cp, wbp, f) +register char *cp; +register struct wdblock **wbp; +int f; +{ + jmp_buf ev; + + gflg = 0; + if (cp == NULL) + return(0); + if (!anys("$`'\"", cp) && + !anys(ifs->value, cp) && + ((f&DOGLOB)==0 || !anys("[*?", cp))) { + cp = strsave(cp, areanum); + if (f & DOTRIM) + unquote(cp); + *wbp = addword(cp, *wbp); + return(1); + } + if (newenv(setjmp(errpt = ev)) == 0) { + PUSHIO(aword, cp, strchar); + env.iobase = env.iop; + while ((cp = blank(f)) && gflg == 0) { + env.linep = cp; + cp = strsave(cp, areanum); + if ((f&DOGLOB) == 0) { + if (f & DOTRIM) + unquote(cp); + *wbp = addword(cp, *wbp); + } else + *wbp = glob(cp, *wbp); + } + quitenv(); + } else + gflg = 1; + return(gflg == 0); +} + +/* + * Blank interpretation and quoting + */ +static char * +blank(f) +int f; +{ + register c, c1; + register char *sp; + int scanequals, foundequals; + + sp = env.linep; + scanequals = f & DOKEY; + foundequals = 0; + +loop: + switch (c = subgetc('"', foundequals)) { + case 0: + if (sp == env.linep) + return(0); + *env.linep++ = 0; + return(sp); + + default: + if (f & DOBLANK && any(c, ifs->value)) + goto loop; + break; + + case '"': + case '\'': + scanequals = 0; + if (INSUB()) + break; + for (c1 = c; (c = subgetc(c1, 1)) != c1;) { + if (c == 0) + break; + if (c == '\'' || !any(c, "$`\"")) + c |= QUOTE; + *env.linep++ = c; + } + c = 0; + } + unget(c); + if (!letter(c)) + scanequals = 0; + for (;;) { + c = subgetc('"', foundequals); + if (c == 0 || + f & (DOBLANK && any(c, ifs->value)) || + (!INSUB() && any(c, "\"'"))) { + scanequals = 0; + unget(c); + if (any(c, "\"'")) + goto loop; + break; + } + if (scanequals) + if (c == '=') { + foundequals = 1; + scanequals = 0; + } + else if (!letnum(c)) + scanequals = 0; + *env.linep++ = c; + } + *env.linep++ = 0; + return(sp); +} + +/* + * Get characters, substituting for ` and $ + */ +int +subgetc(ec, quoted) +register char ec; +int quoted; +{ + register char c; + +again: + c = getc(ec); + if (!INSUB() && ec != '\'') { + if (c == '`') { + if (grave(quoted) == 0) + return(0); + env.iop->task = XGRAVE; + goto again; + } + if (c == '$' && (c = dollar(quoted)) == 0) { + env.iop->task = XDOLL; + goto again; + } + } + return(c); +} + +/* + * Prepare to generate the string returned by ${} substitution. + */ +static int +dollar(quoted) +int quoted; +{ + int otask; + struct io *oiop; + char *dolp; + register char *s, c, *cp; + struct var *vp; + + c = readc(); + s = env.linep; + if (c != '{') { + *env.linep++ = c; + if (letter(c)) { + while ((c = readc())!=0 && letnum(c)) + if (env.linep < elinep) + *env.linep++ = c; + unget(c); + } + c = 0; + } else { + oiop = env.iop; + otask = env.iop->task; + env.iop->task = XOTHER; + while ((c = subgetc('"', 0))!=0 && c!='}' && c!='\n') + if (env.linep < elinep) + *env.linep++ = c; + if (oiop == env.iop) + env.iop->task = otask; + if (c != '}') { + err("unclosed ${"); + gflg++; + return(c); + } + } + if (env.linep >= elinep) { + err("string in ${} too long"); + gflg++; + env.linep -= 10; + } + *env.linep = 0; + if (*s) + for (cp = s+1; *cp; cp++) + if (any(*cp, "=-+?")) { + c = *cp; + *cp++ = 0; + break; + } + if (s[1] == 0 && (*s == '*' || *s == '@')) { + if (dolc > 1) { + /* currently this does not distinguish $* and $@ */ + /* should check dollar */ + env.linep = s; + PUSHIO(awordlist, dolv+1, dolchar); + return(0); + } else { /* trap the nasty ${=} */ + s[0] = '1'; + s[1] = 0; + } + } + vp = lookup(s); + if ((dolp = vp->value) == null) { + switch (c) { + case '=': + if (digit(*s)) { + err("cannot use ${...=...} with $n"); + gflg++; + break; + } + setval(vp, cp); + dolp = vp->value; + break; + + case '-': + dolp = strsave(cp, areanum); + break; + + case '?': + if (*cp == 0) { + prs("missing value for "); + err(s); + } else + err(cp); + gflg++; + break; + } + } else if (c == '+') + dolp = strsave(cp, areanum); + if (flag['u'] && dolp == null) { + prs("unset variable: "); + err(s); + gflg++; + } + env.linep = s; + PUSHIO(aword, dolp, quoted ? qstrchar : strchar); + return(0); +} + +/* + * Run the command in `...` and read its output. + */ +static int +grave(quoted) +int quoted; +{ + register char *cp; + register int i; + int pf[2]; + + for (cp = env.iop->argp->aword; *cp != '`'; cp++) + if (*cp == 0) { + err("no closing `"); + return(0); + } + if (openpipe(pf) < 0) + return(0); + if ((i = fork()) == -1) { + closepipe(pf); + err("try again"); + return(0); + } + if (i != 0) { + env.iop->argp->aword = ++cp; + close(pf[1]); + PUSHIO(afile, remap(pf[0]), quoted? qgravechar: gravechar); + return(1); + } + *cp = 0; + /* allow trapped signals */ + for (i=0; i<=_NSIG; i++) + if (ourtrap[i] && signal(i, SIG_IGN) != SIG_IGN) + signal(i, SIG_DFL); + dup2(pf[1], 1); + closepipe(pf); + flag['e'] = 0; + flag['v'] = 0; + flag['n'] = 0; + cp = strsave(env.iop->argp->aword, 0); + areanum = 1; + freehere(areanum); + freearea(areanum); /* free old space */ + env.oenv = NULL; + env.iop = (env.iobase = iostack) - 1; + unquote(cp); + talking = 0; + PUSHIO(aword, cp, nlchar); + onecommand(); + exit(1); +} + +char * +unquote(as) +register char *as; +{ + register char *s; + + if ((s = as) != NULL) + while (*s) + *s++ &= ~QUOTE; + return(as); +} + +/* -------- glob.c -------- */ +/* #include "sh.h" */ + +/* + * glob + */ + +#define scopy(x) strsave((x), areanum) +#define BLKSIZ 512 +#define NDENT ((BLKSIZ+sizeof(struct dirent)-1)/sizeof(struct dirent)) + +static struct wdblock *cl, *nl; +static char spcl[] = "[?*"; + +struct wdblock * +glob(cp, wb) +char *cp; +struct wdblock *wb; +{ + register i; + register char *pp; + + if (cp == 0) + return(wb); + i = 0; + for (pp = cp; *pp; pp++) + if (any(*pp, spcl)) + i++; + else if (!any(*pp & ~QUOTE, spcl)) + *pp &= ~QUOTE; + if (i != 0) { + for (cl = addword(scopy(cp), (struct wdblock *)0); anyspcl(cl); cl = nl) { + nl = newword(cl->w_nword*2); + for(i=0; iw_nword; i++) { /* for each argument */ + for (pp = cl->w_words[i]; *pp; pp++) + if (any(*pp, spcl)) { + globname(cl->w_words[i], pp); + break; + } + if (*pp == '\0') + nl = addword(scopy(cl->w_words[i]), nl); + } + for(i=0; iw_nword; i++) + DELETE(cl->w_words[i]); + DELETE(cl); + } + for(i=0; iw_nword; i++) + unquote(cl->w_words[i]); + glob0((char *)cl->w_words, cl->w_nword, sizeof(char *), xstrcmp); + if (cl->w_nword) { + for (i=0; iw_nword; i++) + wb = addword(cl->w_words[i], wb); + DELETE(cl); + return(wb); + } + } + wb = addword(unquote(cp), wb); + return(wb); +} + +void +globname(we, pp) +char *we; +register char *pp; +{ + register char *np, *cp; + char *name, *gp, *dp; + int dn, j, n, k; + DIR *dirp; + struct dirent *de; + char dname[NAME_MAX+1]; + struct stat dbuf; + + for (np = we; np != pp; pp--) + if (pp[-1] == '/') + break; + for (dp = cp = space((int)(pp-np)+3); np < pp;) + *cp++ = *np++; + *cp++ = '.'; + *cp = '\0'; + for (gp = cp = space(strlen(pp)+1); *np && *np != '/';) + *cp++ = *np++; + *cp = '\0'; + dirp = opendir(dp); + if (dirp == 0) { + DELETE(dp); + DELETE(gp); + return; + } + dname[NAME_MAX] = '\0'; + while ((de=readdir(dirp))!=NULL) { + /* XXX Hmmm... What this could be? (abial) */ + /* + if (ent[j].d_ino == 0) + continue; + */ + strncpy(dname, de->d_name, NAME_MAX); + if (dname[0] == '.') + if (*gp != '.') + continue; + for(k=0; kw_words; + for (i=0; iw_nword; i++) + if (anys(spcl, *wd++)) + return(1); + return(0); +} + +static int +xstrcmp(p1, p2) +char *p1, *p2; +{ + return(strcmp(*(char **)p1, *(char **)p2)); +} + +/* -------- word.c -------- */ +/* #include "sh.h" */ +/* #include "word.h" */ + +#define NSTART 16 /* default number of words to allow for initially */ + +struct wdblock * +newword(nw) +register int nw; +{ + register struct wdblock *wb; + + wb = (struct wdblock *) space(sizeof(*wb) + nw*sizeof(char *)); + wb->w_bsize = nw; + wb->w_nword = 0; + return(wb); +} + +struct wdblock * +addword(wd, wb) +char *wd; +register struct wdblock *wb; +{ + register struct wdblock *wb2; + register nw; + + if (wb == NULL) + wb = newword(NSTART); + if ((nw = wb->w_nword) >= wb->w_bsize) { + wb2 = newword(nw * 2); + memcopy((char *)wb2->w_words, (char *)wb->w_words, nw*sizeof(char *)); + wb2->w_nword = nw; + DELETE(wb); + wb = wb2; + } + wb->w_words[wb->w_nword++] = wd; + return(wb); +} + +char ** +getwords(wb) +register struct wdblock *wb; +{ + register char **wd; + register nb; + + if (wb == NULL) + return((char **)NULL); + if (wb->w_nword == 0) { + DELETE(wb); + return((char **)NULL); + } + wd = (char **) space(nb = sizeof(*wd) * wb->w_nword); + memcopy((char *)wd, (char *)wb->w_words, nb); + DELETE(wb); /* perhaps should done by caller */ + return(wd); +} + +_PROTOTYPE(int (*func), (char *, char *)); +int globv; + +void +glob0(a0, a1, a2, a3) +char *a0; +unsigned a1; +int a2; +_PROTOTYPE(int (*a3), (char *, char *)); +{ + func = a3; + globv = a2; + glob1(a0, a0 + a1 * a2); +} + +void +glob1(base, lim) +char *base, *lim; +{ + register char *i, *j; + int v2; + char *lptr, *hptr; + int c; + unsigned n; + + + v2 = globv; + +top: + if ((n=(int)(lim-base)) <= v2) + return; + n = v2 * (n / (2*v2)); + hptr = lptr = base+n; + i = base; + j = lim-v2; + for(;;) { + if (i < lptr) { + if ((c = (*func)(i, lptr)) == 0) { + glob2(i, lptr -= v2); + continue; + } + if (c < 0) { + i += v2; + continue; + } + } + +begin: + if (j > hptr) { + if ((c = (*func)(hptr, j)) == 0) { + glob2(hptr += v2, j); + goto begin; + } + if (c > 0) { + if (i == lptr) { + glob3(i, hptr += v2, j); + i = lptr += v2; + goto begin; + } + glob2(i, j); + j -= v2; + i += v2; + continue; + } + j -= v2; + goto begin; + } + + + if (i == lptr) { + if (lptr-base >= lim-hptr) { + glob1(hptr+v2, lim); + lim = lptr; + } else { + glob1(base, lptr); + base = hptr+v2; + } + goto top; + } + + + glob3(j, lptr -= v2, i); + j = hptr -= v2; + } +} + +void +glob2(i, j) +char *i, *j; +{ + register char *index1, *index2, c; + int m; + + m = globv; + index1 = i; + index2 = j; + do { + c = *index1; + *index1++ = *index2; + *index2++ = c; + } while(--m); +} + +void +glob3(i, j, k) +char *i, *j, *k; +{ + register char *index1, *index2, *index3; + int c; + int m; + + m = globv; + index1 = i; + index2 = j; + index3 = k; + do { + c = *index1; + *index1++ = *index3; + *index3++ = *index2; + *index2++ = c; + } while(--m); +} + +char * +memcopy(ato, from, nb) +register char *ato, *from; +register int nb; +{ + register char *to; + + to = ato; + while (--nb >= 0) + *to++ = *from++; + return(ato); +} diff --git a/src/sh/msh/sh5.c b/src/sh/msh/sh5.c new file mode 100755 index 00000000..b41a79f5 --- /dev/null +++ b/src/sh/msh/sh5.c @@ -0,0 +1,675 @@ +#define Extern extern +#include /* Nick sys/types.h> */ +#include +#define _NSIG NSIGS /* Nick NSIG */ +#include +#include +#include "sh.h" + +/* -------- io.c -------- */ +/* #include "sh.h" */ + +/* + * shell IO + */ + +static struct iobuf sharedbuf = {AFID_NOBUF}; +static struct iobuf mainbuf = {AFID_NOBUF}; +static unsigned bufid = AFID_ID; /* buffer id counter */ + +struct ioarg temparg = {0, 0, 0, AFID_NOBUF, 0}; + +_PROTOTYPE(static void readhere, (char **name, char *s, int ec )); +_PROTOTYPE(void pushio, (struct ioarg *argp, int (*fn)())); +_PROTOTYPE(static int xxchar, (struct ioarg *ap )); +_PROTOTYPE(void tempname, (char *tname )); + +int +getc(ec) +register int ec; +{ + register int c; + + if(env.linep > elinep) { + while((c=readc()) != '\n' && c) + ; + err("input line too long"); + gflg++; + return(c); + } + c = readc(); + if (ec != '\'' && env.iop->task != XGRAVE) { + if(c == '\\') { + c = readc(); + if (c == '\n' && ec != '\"') + return(getc(ec)); + c |= QUOTE; + } + } + return(c); +} + +void +unget(c) +int c; +{ + if (env.iop >= env.iobase) + env.iop->peekc = c; +} + +int +eofc() + +{ + return env.iop < env.iobase || (env.iop->peekc == 0 && env.iop->prev == 0); +} + +int +readc() +{ + register c; + + for (; env.iop >= env.iobase; env.iop--) + if ((c = env.iop->peekc) != '\0') { + env.iop->peekc = 0; + return(c); + } + else { + if (env.iop->prev != 0) { + if ((c = (*env.iop->iofn)(env.iop->argp, env.iop)) != '\0') { + if (c == -1) { + env.iop++; + continue; + } + if (env.iop == iostack) + ioecho(c); + return(env.iop->prev = c); + } + else if (env.iop->task == XIO && env.iop->prev != '\n') { + env.iop->prev = 0; + if (env.iop == iostack) + ioecho('\n'); + return '\n'; + } + } + if (env.iop->task == XIO) { + if (multiline) + return env.iop->prev = 0; + if (talking && env.iop == iostack+1) + prs(prompt->value); + } + } + if (env.iop >= iostack) + return(0); + leave(); + /* NOTREACHED */ +} + +void +ioecho(c) +char c; +{ + if (flag['v']) + write(2, &c, sizeof c); +} + +void +pushio(argp, fn) +struct ioarg *argp; +int (*fn)(); +{ + if (++env.iop >= &iostack[NPUSH]) { + env.iop--; + err("Shell input nested too deeply"); + gflg++; + return; + } + env.iop->iofn = fn; + + if (argp->afid != AFID_NOBUF) + env.iop->argp = argp; + else { + env.iop->argp = ioargstack + (env.iop - iostack); + *env.iop->argp = *argp; + env.iop->argp->afbuf = env.iop == &iostack[0] ? &mainbuf : &sharedbuf; + if (isatty(env.iop->argp->afile) == 0 && + (env.iop == &iostack[0] || + lseek(env.iop->argp->afile, 0L, 1) != -1)) { + if (++bufid == AFID_NOBUF) + bufid = AFID_ID; + env.iop->argp->afid = bufid; + } + } + + env.iop->prev = ~'\n'; + env.iop->peekc = 0; + env.iop->xchar = 0; + env.iop->nlcount = 0; + if (fn == filechar || fn == linechar) + env.iop->task = XIO; + else if (fn == gravechar || fn == qgravechar) + env.iop->task = XGRAVE; + else + env.iop->task = XOTHER; +} + +struct io * +setbase(ip) +struct io *ip; +{ + register struct io *xp; + + xp = env.iobase; + env.iobase = ip; + return(xp); +} + +/* + * Input generating functions + */ + +/* + * Produce the characters of a string, then a newline, then EOF. + */ +int +nlchar(ap) +register struct ioarg *ap; +{ + register int c; + + if (ap->aword == NULL) + return(0); + if ((c = *ap->aword++) == 0) { + ap->aword = NULL; + return('\n'); + } + return(c); +} + +/* + * Given a list of words, produce the characters + * in them, with a space after each word. + */ +int +wdchar(ap) +register struct ioarg *ap; +{ + register char c; + register char **wl; + + if ((wl = ap->awordlist) == NULL) + return(0); + if (*wl != NULL) { + if ((c = *(*wl)++) != 0) + return(c & 0177); + ap->awordlist++; + return(' '); + } + ap->awordlist = NULL; + return('\n'); +} + +/* + * Return the characters of a list of words, + * producing a space between them. + */ +int +dolchar(ap) +register struct ioarg *ap; +{ + register char *wp; + + if ((wp = *ap->awordlist++) != NULL) { + PUSHIO(aword, wp, *ap->awordlist == NULL? strchar: xxchar); + return(-1); + } + return(0); +} + +static int +xxchar(ap) +register struct ioarg *ap; +{ + register int c; + + if (ap->aword == NULL) + return(0); + if ((c = *ap->aword++) == '\0') { + ap->aword = NULL; + return(' '); + } + return(c); +} + +/* + * Produce the characters from a single word (string). + */ +int +strchar(ap) +register struct ioarg *ap; +{ + register int c; + + if (ap->aword == NULL || (c = *ap->aword++) == 0) + return(0); + return(c); +} + +/* + * Produce quoted characters from a single word (string). + */ +int +qstrchar(ap) +register struct ioarg *ap; +{ + register int c; + + if (ap->aword == NULL || (c = *ap->aword++) == 0) + return(0); + return(c|QUOTE); +} + +/* + * Return the characters from a file. + */ +int +filechar(ap) +register struct ioarg *ap; +{ + register int i; + char c; + struct iobuf *bp = ap->afbuf; + + if (ap->afid != AFID_NOBUF) { + if ((i = ap->afid != bp->id) || bp->bufp == bp->ebufp) { + if (i) + lseek(ap->afile, ap->afpos, 0); + do { + i = read(ap->afile, bp->buf, sizeof(bp->buf)); + } while (i < 0 && errno == EINTR); + if (i <= 0) { + closef(ap->afile); + return 0; + } + bp->id = ap->afid; + bp->ebufp = (bp->bufp = bp->buf) + i; + } + ap->afpos++; + return *bp->bufp++ & 0177; + } + + do { + i = read(ap->afile, &c, sizeof(c)); + } while (i < 0 && errno == EINTR); + return(i == sizeof(c)? c&0177: (closef(ap->afile), 0)); +} + +/* + * Return the characters from a here temp file. + */ +int +herechar(ap) +register struct ioarg *ap; +{ + char c; + + + if (read(ap->afile, &c, sizeof(c)) != sizeof(c)) { + close(ap->afile); + c = 0; + } + return (c); + +} + +/* + * Return the characters produced by a process (`...`). + * Quote them if required, and remove any trailing newline characters. + */ +int +gravechar(ap, iop) +struct ioarg *ap; +struct io *iop; +{ + register int c; + + if ((c = qgravechar(ap, iop)&~QUOTE) == '\n') + c = ' '; + return(c); +} + +int +qgravechar(ap, iop) +register struct ioarg *ap; +struct io *iop; +{ + register int c; + + if (iop->xchar) { + if (iop->nlcount) { + iop->nlcount--; + return('\n'|QUOTE); + } + c = iop->xchar; + iop->xchar = 0; + } else if ((c = filechar(ap)) == '\n') { + iop->nlcount = 1; + while ((c = filechar(ap)) == '\n') + iop->nlcount++; + iop->xchar = c; + if (c == 0) + return(c); + iop->nlcount--; + c = '\n'; + } + return(c!=0? c|QUOTE: 0); +} + +/* + * Return a single command (usually the first line) from a file. + */ +int +linechar(ap) +register struct ioarg *ap; +{ + register int c; + + if ((c = filechar(ap)) == '\n') { + if (!multiline) { + closef(ap->afile); + ap->afile = -1; /* illegal value */ + } + } + return(c); +} + +void +prs(s) +register char *s; +{ + if (*s) + write(2, s, strlen(s)); +} + +void +putc(c) +char c; +{ + write(2, &c, sizeof c); +} + +void +prn(u) +unsigned u; +{ + prs(sh_itoa(u, 0)); +} + +void +closef(i) +register int i; +{ + if (i > 2) + close(i); +} + +void +closeall() +{ + register u; + + for (u=NUFILE; u= 0 && fd < env.iofd); + for (i=0; ih_tag = evalstr(s, DOSUB); + if (h->h_tag == 0) + return; + h->h_iop = iop; + iop->io_name = 0; + h->h_next = NULL; + if (inhere == 0) + inhere = h; + else + for (lh = inhere; lh!=NULL; lh = lh->h_next) + if (lh->h_next == 0) { + lh->h_next = h; + break; + } + iop->io_flag |= IOHERE|IOXHERE; + for (s = h->h_tag; *s; s++) + if (*s & QUOTE) { + iop->io_flag &= ~ IOXHERE; + *s &= ~ QUOTE; + } + h->h_dosub = iop->io_flag & IOXHERE; +} + +void +gethere() +{ + register struct here *h, *hp; + + /* Scan here files first leaving inhere list in place */ + for (hp = h = inhere; h != NULL; hp = h, h = h->h_next) + readhere(&h->h_iop->io_name, h->h_tag, h->h_dosub? 0: '\''); + + /* Make inhere list active - keep list intact for scraphere */ + if (hp != NULL) { + hp->h_next = acthere; + acthere = inhere; + inhere = NULL; + } +} + +static void +readhere(name, s, ec) +char **name; +register char *s; +int ec; +{ + int tf; + char tname[30]; + register c; + jmp_buf ev; + char line [LINELIM+1]; + char *next; + + tempname(tname); + *name = strsave(tname, areanum); + tf = creat(tname, 0600); + if (tf < 0) + return; + if (newenv(setjmp(errpt = ev)) != 0) + unlink(tname); + else { + pushio(env.iop->argp, env.iop->iofn); + env.iobase = env.iop; + for (;;) { + if (talking && env.iop <= iostack) + prs(cprompt->value); + next = line; + while ((c = getc(ec)) != '\n' && c) { + if (ec == '\'') + c &= ~ QUOTE; + if (next >= &line[LINELIM]) { + c = 0; + break; + } + *next++ = c; + } + *next = 0; + if (strcmp(s, line) == 0 || c == 0) + break; + *next++ = '\n'; + write (tf, line, (int)(next-line)); + } + if (c == 0) { + prs("here document `"); prs(s); err("' unclosed"); + } + quitenv(); + } + close(tf); +} + +/* + * open here temp file. + * if unquoted here, expand here temp file into second temp file. + */ +int +herein(hname, xdoll) +char *hname; +int xdoll; +{ + register hf, tf; + + if (hname == 0) + return(-1); + hf = open(hname, 0); + if (hf < 0) + return (-1); + if (xdoll) { + char c; + char tname[30]; + jmp_buf ev; + + tempname(tname); + if ((tf = creat(tname, 0600)) < 0) + return (-1); + if (newenv(setjmp(errpt = ev)) == 0) { + PUSHIO(afile, hf, herechar); + setbase(env.iop); + while ((c = subgetc(0, 0)) != 0) { + c &= ~ QUOTE; + write(tf, &c, sizeof c); + } + quitenv(); + } else + unlink(tname); + close(tf); + tf = open(tname, 0); + unlink(tname); + return (tf); + } else + return (hf); +} + +void +scraphere() +{ + register struct here *h; + + for (h = inhere; h != NULL; h = h->h_next) { + if (h->h_iop && h->h_iop->io_name) + unlink(h->h_iop->io_name); + } + inhere = NULL; +} + +/* unlink here temp files before a freearea(area) */ +void +freehere(area) +int area; +{ + register struct here *h, *hl; + + hl = NULL; + for (h = acthere; h != NULL; h = h->h_next) + if (getarea((char *) h) >= area) { + if (h->h_iop->io_name != NULL) + unlink(h->h_iop->io_name); + if (hl == NULL) + acthere = h->h_next; + else + hl->h_next = h->h_next; + } else + hl = h; +} + +void +tempname(tname) +char *tname; +{ + static int inc; + register char *cp, *lp; + + for (cp = tname, lp = "/tmp/shtm"; (*cp = *lp++) != '\0'; cp++) + ; + lp = putn(getpid()*1000 + inc++); + for (; (*cp = *lp++) != '\0'; cp++) + ; +} diff --git a/src/sh/msh/sh6.c b/src/sh/msh/sh6.c new file mode 100755 index 00000000..aa4ae0b3 --- /dev/null +++ b/src/sh/msh/sh6.c @@ -0,0 +1,9 @@ +#define Extern + +#include /* Nick sys/types.h> */ +#include +#define _NSIG NSIGS /* Nick NSIG */ +#include +#include +#include "sh.h" + diff --git a/src/sh/sash/build-b.ban b/src/sh/sash/build-b.ban new file mode 100755 index 00000000..4e0087f4 --- /dev/null +++ b/src/sh/sash/build-b.ban @@ -0,0 +1,59 @@ +iccz80 -S -w -mb -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmds +@if errorlevel 1 goto failure +del cmds.r01 +as-z80 -l -o cmds.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_dd +@if errorlevel 1 goto failure +del cmd_dd.r01 +as-z80 -l -o cmd_dd.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_ed +@if errorlevel 1 goto failure +del cmd_ed.r01 +as-z80 -l -o cmd_ed.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_grep +@if errorlevel 1 goto failure +del cmd_grep.r01 +as-z80 -l -o cmd_grep.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_ls +@if errorlevel 1 goto failure +del cmd_ls.r01 +as-z80 -l -o cmd_ls.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_tar +@if errorlevel 1 goto failure +del cmd_tar.r01 +as-z80 -l -o cmd_tar.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\sash +@if errorlevel 1 goto failure +del sash.r01 +as-z80 -l -o sash.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\utils +@if errorlevel 1 goto failure +del utils.r01 +as-z80 -l -o utils.s01 +@if errorlevel 1 goto failure + +link-z80 -f sash +@if errorlevel 1 goto failure +ihex2bin -l sash.i86 ..\..\..\..\bin\banked\sash +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/sh/sash/build-l.ban b/src/sh/sash/build-l.ban new file mode 100755 index 00000000..31726896 --- /dev/null +++ b/src/sh/sash/build-l.ban @@ -0,0 +1,59 @@ +iccz80 -S -w -ml -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmds +@if errorlevel 1 goto failure +del cmds.r01 +as-z80 -l -o cmds.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_dd +@if errorlevel 1 goto failure +del cmd_dd.r01 +as-z80 -l -o cmd_dd.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_ed +@if errorlevel 1 goto failure +del cmd_ed.r01 +as-z80 -l -o cmd_ed.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_grep +@if errorlevel 1 goto failure +del cmd_grep.r01 +as-z80 -l -o cmd_grep.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_ls +@if errorlevel 1 goto failure +del cmd_ls.r01 +as-z80 -l -o cmd_ls.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\cmd_tar +@if errorlevel 1 goto failure +del cmd_tar.r01 +as-z80 -l -o cmd_tar.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\sash +@if errorlevel 1 goto failure +del sash.r01 +as-z80 -l -o sash.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\..\include\ -DNDEBUG ..\utils +@if errorlevel 1 goto failure +del utils.r01 +as-z80 -l -o utils.s01 +@if errorlevel 1 goto failure + +link-z80 -f sash +@if errorlevel 1 goto failure +ihex2bin -l sash.i86 ..\..\..\..\bin\large\sash +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/sh/sash/cmd_dd.c b/src/sh/sash/cmd_dd.c new file mode 100755 index 00000000..f1b7cc49 --- /dev/null +++ b/src/sh/sash/cmd_dd.c @@ -0,0 +1,226 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * The "dd" built-in command. + */ +#include "sash.h" + +#ifdef CMD_DD + +#define PAR_NONE 0 +#define PAR_IF 1 +#define PAR_OF 2 +#define PAR_BS 3 +#define PAR_COUNT 4 +#define PAR_SEEK 5 +#define PAR_SKIP 6 + +typedef struct { + char *name; + int value; +} PARAM; + +static PARAM params[] = { + "if", PAR_IF, + "of", PAR_OF, + "bs", PAR_BS, + "count",PAR_COUNT, + "seek", PAR_SEEK, + "skip", PAR_SKIP, + NULL, PAR_NONE +}; + +static long getnum __P((char *)); + +/* + * Read a number with a possible multiplier. + * Returns -1 if the number format is illegal. + */ +static long getnum(cp) + char *cp; +{ + long value; + + if (!isdecimal(*cp)) + return -1; + for (value = 0; isdecimal(*cp); ++cp) { + value *= 10; + value += *cp - '0'; + } + switch (*cp++) { + case 'm': case 'M': value <<= 20; break; + case 'k': case 'K': value <<= 10; break; + case 'b': case 'B': value <<= 9; break; + case 'w': case 'W': value <<= 1; break; + case '\0': + return value; + default: + return -1; + } + if (*cp) + return -1; + return value; +} + +void do_dd(argc, argv) + int argc; + char **argv; +{ + PARAM *par; + int blocksize; + int infd, outfd; + int incc, outcc; + char *buf, *str, *cp, *infile, *outfile; + long count, seekval, skipval, intotal, outtotal; + char localbuf[1024]; + + infile = outfile = NULL; + seekval = skipval = 0; + blocksize = BUFSIZ; + count = 0x7fffffffL; /* ??? not used */ + + while (--argc > 0) { + str = *++argv; + if ((cp = strchr(str, '=')) == NULL) { + fprintf(stderr, "Bad dd argument\n"); + return; + } + *cp++ = '\0'; /* remove '=' */ + for (par = params; par->name; par++) { + if (strcmp(str, par->name) == 0) + break; + } + switch (par->value) { + case PAR_IF: + if (infile) { + fprintf(stderr, "Multiple input files are illegal\n"); + return; + } + infile = cp; + break; + + case PAR_OF: + if (outfile) { + fprintf(stderr, "Multiple output files are illegal\n"); + return; + } + outfile = cp; + break; + + case PAR_BS: + if ((blocksize = (int)getnum(cp)) <= 0) { + fprintf(stderr, "Bad block size value %s\n", cp); + return; + } + break; + + case PAR_COUNT: + if ((count = getnum(cp)) < 0) { + fprintf(stderr, "Bad count value %s\n", cp); + return; + } + break; + + case PAR_SEEK: + if ((seekval = getnum(cp)) < 0) { + fprintf(stderr, "Bad seek value %s\n", cp); + return; + } + break; + + case PAR_SKIP: + if ((skipval = getnum(cp)) < 0) { + fprintf(stderr, "Bad skip value %s\n", cp); + return; + } + break; + + default: + fprintf(stderr, "Unknown dd parameter %s=%s\n",str,cp); + return; + } + } + if (infile == NULL) { + fprintf(stderr, "No input file specified\n"); + return; + } + if (outfile == NULL) { + fprintf(stderr, "No output file specified\n"); + return; + } + buf = localbuf; + if (blocksize > sizeof(localbuf)) { + if ((buf = malloc(blocksize)) == NULL) { + fprintf(stderr, "Can't allocate buffer\n"); + return; + } + } + intotal = outtotal = 0; + if ((infd = open(infile, 0)) < 0) { + perror(infile); + if (buf != localbuf) + free(buf); + return; + } + if ((outfd = creat(outfile, 0666)) < 0) { + perror(outfile); + close(infd); + if (buf != localbuf) + free(buf); + return; + } + if (skipval) { + if (lseek(infd, skipval * blocksize, 0) < 0) { + while (skipval-- > 0) { + if ((incc = read(infd, buf, blocksize)) < 0) { + perror(infile); + goto cleanup; + } + if (incc == 0) { + fprintf(stderr, "End of file while skipping\n"); + goto cleanup; + } + } + } + } + if (seekval) { + if (lseek(outfd, seekval * blocksize, 0) < 0) { + perror(outfile); + goto cleanup; + } + } + while ((incc = read(infd, buf, blocksize)) > 0) { + intotal += incc; + cp = buf; + if (intflag) { + fprintf(stderr, "Interrupted\n"); + goto cleanup; + } + while (incc > 0) { + if ((outcc = write(outfd, cp, incc)) < 0) { + perror(outfile); + goto cleanup; + } + outtotal += outcc; + cp += outcc; + incc -= outcc; + } + } + if (incc < 0) + perror(infile); + +cleanup: + close(infd); + if (close(outfd) < 0) + perror(outfile); + if (buf != localbuf) + free(buf); + printf("%d+%d records in\n", intotal / blocksize, + (intotal % blocksize) != 0); + printf("%d+%d records out\n", outtotal / blocksize, + (outtotal % blocksize) != 0); +} +#endif /* CMD_DD */ + \ No newline at end of file diff --git a/src/sh/sash/cmd_ed.c b/src/sh/sash/cmd_ed.c new file mode 100755 index 00000000..05b35f77 --- /dev/null +++ b/src/sh/sash/cmd_ed.c @@ -0,0 +1,1227 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * The "ed" built-in command (much simplified) + */ +#include "sash.h" + +#ifdef CMD_ED + +#define USERSIZE 1024 /* max line length typed in by user */ +#define INITBUFSIZE 1024 /* initial buffer size */ + +typedef int NUM; +typedef int LEN; + +typedef struct LINE LINE; +struct LINE { + LINE *next; + LINE *prev; + LEN len; + char data[1]; +}; + +static LINE lines; +static LINE *curline; +static NUM curnum; +static NUM lastnum; +static NUM marks[26]; +static BOOL dirty; +static char *filename; +static char searchstring[USERSIZE]; + +static char *bufbase; +static char *bufptr; +static LEN bufused; +static LEN bufsize; + + +static void docommands(); +static void subcommand(); +static BOOL getnum(); +static BOOL setcurnum(); +static BOOL initedit(); +static void termedit(); +static void addlines(); +static BOOL insertline(); +static BOOL deletelines(); +static BOOL printlines(); +static BOOL writelines(); +static BOOL readlines(); +static NUM searchlines(); +static LEN findstring(); +static LINE *findline(); + +void do_ed(argc, argv) + char **argv; +{ + if (!initedit()) + return; + + if (argc > 1) { + filename = strdup(argv[1]); + if (filename == NULL) { + fprintf(stderr, "No memory\n"); + termedit(); + return; + } + + if (!readlines(filename, 1)) { + termedit(); + return; + } + + if (lastnum) + setcurnum(1); + + dirty = FALSE; + } + + docommands(); + + termedit(); +} + + +/* + * Read commands until we are told to stop. + */ +static void docommands() +{ + char *cp; + int len; + NUM num1; + NUM num2; + BOOL have1; + BOOL have2; + char buf[USERSIZE]; + while (TRUE) { + intflag = FALSE; + printf(": "); + fflush(stdout); + + if (fgets(buf, sizeof(buf), stdin) == NULL) + return; + + len = strlen(buf); + if (len == 0) + return; + + cp = &buf[len - 1]; + if (*cp != '\n') { + fprintf(stderr, "Command line too long\n"); + do { + len = fgetc(stdin); + } while ((len != EOF) && (len != '\n')); + + continue; + } + + while ((cp > buf) && isblank(cp[-1])) + cp--; + *cp = '\0'; + + cp = buf; + while (isblank(*cp)) + *cp++; + + have1 = FALSE; + have2 = FALSE; + + if ((curnum == 0) && (lastnum > 0)) { + curnum = 1; + curline = lines.next; + } + + if (!getnum(&cp, &have1, &num1)) + continue; + + while (isblank(*cp)) + cp++; + + if (*cp == ',') { + cp++; + if (!getnum(&cp, &have2, &num2)) + continue; + + if (!have1) + num1 = 1; + + if (!have2) + num2 = lastnum; + + have1 = TRUE; + have2 = TRUE; + } + + if (!have1) + num1 = curnum; + + if (!have2) + num2 = num1; + + switch (*cp++) { + case 'a': + addlines(num1 + 1); + break; + + case 'c': + deletelines(num1, num2); + addlines(num1); + break; + + case 'd': + deletelines(num1, num2); + break; + + case 'f': + if (*cp && !isblank(*cp)) { + fprintf(stderr, "Bad file command\n"); + break; + } + + while (isblank(*cp)) + cp++; + if (*cp == '\0') { + if (filename) + printf("\"%s\"\n", filename); + else + printf("No filename\n"); + break; + } + + cp = strdup(cp); + if (cp == NULL) { + fprintf(stderr, "No memory for filename\n"); + break; + } + + if (filename) + free(filename); + filename = cp; + break; + + case 'i': + addlines(num1); + break; + + case 'k': + while (isblank(*cp)) + cp++; + + if ((*cp < 'a') || (*cp > 'a') || cp[1]) { + fprintf(stderr, "Bad mark name\n"); + break; + } + + marks[*cp - 'a'] = num2; + break; + + case 'l': + printlines(num1, num2, TRUE); + break; + + case 'p': + printlines(num1, num2, FALSE); + break; + + case 'q': + while (isblank(*cp)) + cp++; + if (have1 || *cp) { + fprintf(stderr, "Bad quit command\n"); + break; + } + + if (!dirty) + return; + + printf("Really quit? "); + fflush(stdout); + + buf[0] = '\0'; + fgets(buf, sizeof(buf), stdin); + cp = buf; + while (isblank(*cp)) + cp++; + if ((*cp == 'y') || (*cp == 'Y')) + return; + break; + + case 'r': + if (*cp && !isblank(*cp)) { + fprintf(stderr, "Bad read command\n"); + break; + } + + while (isblank(*cp)) + cp++; + if (*cp == '\0') { + fprintf(stderr, "No filename\n"); + break; + } + + if (!have1) + num1 = lastnum; + + if (readlines(cp, num1 + 1)) + break; + + if (filename == NULL) + filename = strdup(cp); + break; + + case 's': + subcommand(cp, num1, num2); + break; + + case 'w': + if (*cp && !isblank(*cp)) { + fprintf(stderr, "Bad write command\n"); + break; + } + while (isblank(*cp)) + cp++; + + if (!have1) { + num1 = 1; + num2 = lastnum; + } + + if (*cp == '\0') + cp = filename; + if (cp == NULL) { + fprintf(stderr, "No file name specified\n"); + break; + } + + writelines(cp, num1, num2); + break; + + case 'z': + switch (*cp) { + case '-': + printlines(curnum - 21, curnum, FALSE); + break; + case '.': + printlines(curnum - 11, curnum + 10, FALSE); + break; + default: + printlines(curnum, curnum + 21, FALSE); + break; + } + break; + + case '.': + if (have1) { + fprintf(stderr, "No arguments allowed\n"); + break; + } + printlines(curnum, curnum, FALSE); + break; + + case '-': + if (setcurnum(curnum - 1)) + printlines(curnum, curnum, FALSE); + break; + + case '=': + printf("%d\n", num1); + break; + + case '\0': + if (have1) { + printlines(num2, num2, FALSE); + break; + } + + if (setcurnum(curnum + 1)) + printlines(curnum, curnum, FALSE); + break; + + default: + fprintf(stderr, "Unimplemented command\n"); + break; + } + } +} + + +/* + * Do the substitute command. + * The current line is set to the last substitution done. + */ +static void subcommand(cp, num1, num2) + char *cp; + NUM num1; + NUM num2; +{ + int delim; + char *oldstr; + char *newstr; + LEN oldlen; + LEN newlen; + LEN deltalen; + LEN offset; + LINE *lp; + LINE *nlp; + BOOL globalflag; + BOOL printflag; + BOOL didsub; + BOOL needprint; + if ((num1 < 1) || (num2 > lastnum) || (num1 > num2)) { + fprintf(stderr, "Bad line range for substitute\n"); + return; + } + + globalflag = FALSE; + printflag = FALSE; + didsub = FALSE; + needprint = FALSE; + + if (isblank(*cp) || (*cp == '\0')) { + fprintf(stderr, "Bad delimiter for substitute\n"); + return; + } + + delim = *cp++; + oldstr = cp; + + cp = strchr(cp, delim); + if (cp == NULL) { + fprintf(stderr, "Missing 2nd delimiter for substitute\n"); + return; + } + *cp++ = '\0'; + + newstr = cp; + cp = strchr(cp, delim); + if (cp) + *cp++ = '\0'; + else + cp = ""; + + while (*cp) + switch (*cp++) { + case 'g': + globalflag = TRUE; + break; + + case 'p': + printflag = TRUE; + break; + + default: + fprintf(stderr, "Unknown option for substitute\n"); + return; + } + + if (*oldstr == '\0') { + if (searchstring[0] == '\0') { + fprintf(stderr, "No previous search string\n"); + return; + } + oldstr = searchstring; + } + + if (oldstr != searchstring) + strcpy(searchstring, oldstr); + + lp = findline(num1); + if (lp == NULL) + return; + + oldlen = strlen(oldstr); + newlen = strlen(newstr); + deltalen = newlen - oldlen; + offset = 0; + + while (num1 <= num2) { + offset = findstring(lp, oldstr, oldlen, offset); + if (offset < 0) { + if (needprint) { + printlines(num1, num1, FALSE); + needprint = FALSE; + } + + offset = 0; + lp = lp->next; + num1++; + continue; + } + + needprint = printflag; + didsub = TRUE; + dirty = TRUE; + + /* If the replacement string is the same size or shorter than the + * old string, then the substitution is easy. */ + if (deltalen <= 0) { + memcpy(&lp->data[offset], newstr, newlen); + + if (deltalen) { + memcpy(&lp->data[offset + newlen], + &lp->data[offset + oldlen], + lp->len - offset - oldlen); + + lp->len += deltalen; + } + + offset += newlen; + if (globalflag) + continue; + + if (needprint) { + printlines(num1, num1, FALSE); + needprint = FALSE; + } + + lp = nlp->next; + num1++; + continue; + } + + /* The new string is larger, so allocate a new line structure and + * use that. Link it in in place of the old line structure. */ + nlp = (LINE *) malloc(sizeof(LINE) + lp->len + deltalen); + if (nlp == NULL) { + fprintf(stderr, "Cannot get memory for line\n"); + return; + } + nlp->len = lp->len + deltalen; + + memcpy(nlp->data, lp->data, offset); + + memcpy(&nlp->data[offset], newstr, newlen); + + memcpy(&nlp->data[offset + newlen], + &lp->data[offset + oldlen], + lp->len - offset - oldlen); + + nlp->next = lp->next; + nlp->prev = lp->prev; + nlp->prev->next = nlp; + nlp->next->prev = nlp; + + if (curline == lp) + curline = nlp; + + free(lp); + lp = nlp; + + offset += newlen; + + if (globalflag) + continue; + + if (needprint) { + printlines(num1, num1, FALSE); + needprint = FALSE; + } + + lp = lp->next; + num1++; + } + + if (!didsub) + fprintf(stderr, "No substitutions found for \"%s\"\n", oldstr); +} + + +/* + * Search a line for the specified string starting at the specified + * offset in the line. Returns the offset of the found string, or -1. + */ +static LEN + findstring(lp, str, len, offset) + LINE *lp; + char *str; + LEN len; + LEN offset; +{ + LEN left; + char *cp; + char *ncp; + cp = &lp->data[offset]; + left = lp->len - offset; + + while (left >= len) { + ncp = memchr(cp, *str, left); + if (ncp == NULL) + return -1; + + left -= (ncp - cp); + if (left < len) + return -1; + + cp = ncp; + if (memcmp(cp, str, len) == 0) + return (cp - lp->data); + + cp++; + left--; + } + + return -1; +} + + +/* + * Add lines which are typed in by the user. + * The lines are inserted just before the specified line number. + * The lines are terminated by a line containing a single dot (ugly!), + * or by an end of file. + */ +static void addlines(num) + NUM num; +{ + int len; + char buf[USERSIZE + 1]; + while (fgets(buf, sizeof(buf), stdin)) { + if ((buf[0] == '.') && (buf[1] == '\n') && (buf[2] == '\0')) + return; + + len = strlen(buf); + if (len == 0) + return; + + if (buf[len - 1] != '\n') { + fprintf(stderr, "Line too long\n"); + do { + len = fgetc(stdin); + } while ((len != EOF) && (len != '\n')); + return; + } + + if (!insertline(num++, buf, len)) + return; + } +} + + +/* + * Parse a line number argument if it is present. This is a sum + * or difference of numbers, '.', '$', 'x, or a search string. + * Returns TRUE if successful (whether or not there was a number). + * Returns FALSE if there was a parsing error, with a message output. + * Whether there was a number is returned indirectly, as is the number. + * The character pointer which stopped the scan is also returned. + */ +static BOOL + getnum(retcp, rethavenum, retnum) + char **retcp; + BOOL *rethavenum; + NUM *retnum; +{ + char *cp; + char *str; + BOOL havenum; + NUM value; + NUM num; + NUM sign; + cp = *retcp; + havenum = FALSE; + value = 0; + sign = 1; + + while (TRUE) { + while (isblank(*cp)) + cp++; + + switch (*cp) { + case '.': + havenum = TRUE; + num = curnum; + cp++; + break; + + case '$': + havenum = TRUE; + num = lastnum; + cp++; + break; + + case '\'': + cp++; + if ((*cp < 'a') || (*cp > 'z')) { + fprintf(stderr, "Bad mark name\n"); + return FALSE; + } + + havenum = TRUE; + num = marks[*cp++ - 'a']; + break; + + case '/': + str = ++cp; + cp = strchr(str, '/'); + if (cp) + *cp++ = '\0'; + else + cp = ""; + num = searchlines(str, curnum, lastnum); + if (num == 0) + return FALSE; + + havenum = TRUE; + break; + + default: + if (!isdecimal(*cp)) { + *retcp = cp; + *rethavenum = havenum; + *retnum = value; + return TRUE; + } + + num = 0; + while (isdecimal(*cp)) + num = num * 10 + *cp++ - '0'; + havenum = TRUE; + break; + } + + value += num * sign; + + while (isblank(*cp)) + cp++; + + switch (*cp) { + case '-': + sign = -1; + cp++; + break; + case '+': + sign = 1; + cp++; + break; + + default: + *retcp = cp; + *rethavenum = havenum; + *retnum = value; + return TRUE; + } + } +} + + +/* + * Initialize everything for editing. + */ +static BOOL + initedit() +{ + int i; + bufsize = INITBUFSIZE; + bufbase = malloc(bufsize); + if (bufbase == NULL) { + fprintf(stderr, "No memory for buffer\n"); + return FALSE; + } + + bufptr = bufbase; + bufused = 0; + + lines.next = &lines; + lines.prev = &lines; + + curline = NULL; + curnum = 0; + lastnum = 0; + dirty = FALSE; + filename = NULL; + searchstring[0] = '\0'; + + for (i = 0; i < 26; i++) + marks[i] = 0; + return TRUE; +} + + +/* + * Finish editing. + */ +static void termedit() +{ + if (bufbase) + free(bufbase); + bufbase = NULL; + bufptr = NULL; + bufsize = 0; + bufused = 0; + + if (filename) + free(filename); + filename = NULL; + + searchstring[0] = '\0'; + + if (lastnum) + deletelines(1, lastnum); + + lastnum = 0; + curnum = 0; + curline = NULL; +} + + +/* + * Read lines from a file at the specified line number. + * Returns TRUE if the file was successfully read. + */ +static BOOL + readlines(file, num) + char *file; + NUM num; +{ + int fd; + int cc; + LEN len; + LEN linecount; + LEN charcount; + char *cp; + if ((num < 1) || (num > lastnum + 1)) { + fprintf(stderr, "Bad line for read\n"); + return FALSE; + } + + fd = open(file, 0); + if (fd < 0) { + perror(file); + return FALSE; + } + + bufptr = bufbase; + bufused = 0; + linecount = 0; + charcount = 0; + + printf("\"%s\", ", file); + fflush(stdout); + + do { + if (intflag) { + printf("INTERRUPTED, "); + bufused = 0; + break; + } + + cp = memchr(bufptr, '\n', bufused); + if (cp) { + len = (cp - bufptr) + 1; + if (!insertline(num, bufptr, len)) { + close(fd); + return FALSE; + } + + bufptr += len; + bufused -= len; + charcount += len; + linecount++; + num++; + continue; + } + + if (bufptr != bufbase) { + memcpy(bufbase, bufptr, bufused); + bufptr = bufbase + bufused; + } + + if (bufused >= bufsize) { + len = (bufsize * 3) / 2; + cp = realloc(bufbase, len); + if (cp == NULL) { + fprintf(stderr, "No memory for buffer\n"); + close(fd); + return FALSE; + } + + bufbase = cp; + bufptr = bufbase + bufused; + bufsize = len; + } + + cc = read(fd, bufptr, bufsize - bufused); + bufused += cc; + bufptr = bufbase; + + } while (cc > 0); + + if (cc < 0) { + perror(file); + close(fd); + return FALSE; + } + + if (bufused) { + if (!insertline(num, bufptr, bufused)) { + close(fd); + return -1; + } + linecount++; + charcount += bufused; + } + + close(fd); + + printf("%d lines%s, %d chars\n", linecount, + (bufused ? " (incomplete)" : ""), charcount); + + return TRUE; +} + + +/* + * Write the specified lines out to the specified file. + * Returns TRUE if successful, or FALSE on an error with a message output. + */ +static BOOL + writelines(file, num1, num2) + char *file; + NUM num1; + NUM num2; +{ + int fd; + LINE *lp; + LEN linecount; + LEN charcount; + if ((num1 < 1) || (num2 > lastnum) || (num1 > num2)) { + fprintf(stderr, "Bad line range for write\n"); + return FALSE; + } + + linecount = 0; + charcount = 0; + + fd = creat(file, 0666); + if (fd < 0) { + perror(file); + return FALSE; + } + + printf("\"%s\", ", file); + fflush(stdout); + + lp = findline(num1); + if (lp == NULL) { + close(fd); + return FALSE; + } + + while (num1++ <= num2) { + if (write(fd, lp->data, lp->len) != lp->len) { + perror(file); + close(fd); + return FALSE; + } + + charcount += lp->len; + linecount++; + lp = lp->next; + } + + if (close(fd) < 0) { + perror(file); + return FALSE; + } + + printf("%d lines, %d chars\n", linecount, charcount); + + return TRUE; +} + + +/* + * Print lines in a specified range. + * The last line printed becomes the current line. + * If expandflag is TRUE, then the line is printed specially to + * show magic characters. + */ +static BOOL + printlines(num1, num2, expandflag) + NUM num1; + NUM num2; + BOOL expandflag; +{ + LINE *lp; + unsigned char *cp; + int ch; + LEN count; + if ((num1 < 1) || (num2 > lastnum) || (num1 > num2)) { + fprintf(stderr, "Bad line range for print\n"); + return FALSE; + } + + lp = findline(num1); + if (lp == NULL) + return FALSE; + + while (!intflag && (num1 <= num2)) { + if (!expandflag) { + write(STDOUT, lp->data, lp->len); + setcurnum(num1++); + lp = lp->next; + continue; + } + + /* Show control characters and characters with the high bit set + * specially. */ + cp = lp->data; + count = lp->len; + if ((count > 0) && (cp[count - 1] == '\n')) + count--; + + while (count-- > 0) { + ch = *cp++; + if (ch & 0x80) { + fputs("M-", stdout); + ch &= 0x7f; + } + if (ch < ' ') { + fputc('^', stdout); + ch += '@'; + } + if (ch == 0x7f) { + fputc('^', stdout); + ch = '?'; + } + fputc(ch, stdout); + } + fputs("$\n", stdout); + + setcurnum(num1++); + lp = lp->next; + } + + return TRUE; +} + + +/* + * Insert a new line with the specified text. + * The line is inserted so as to become the specified line, + * thus pushing any existing and further lines down one. + * The inserted line is also set to become the current line. + * Returns TRUE if successful. + */ +static BOOL + insertline(num, data, len) + NUM num; + char *data; + LEN len; +{ + LINE *newlp; + LINE *lp; + if ((num < 1) || (num > lastnum + 1)) { + fprintf(stderr, "Inserting at bad line number\n"); + return FALSE; + } + + newlp = (LINE *) malloc(sizeof(LINE) + len - 1); + if (newlp == NULL) { + fprintf(stderr, "Failed to allocate memory for line\n"); + return FALSE; + } + + memcpy(newlp->data, data, len); + newlp->len = len; + + if (num > lastnum) + lp = &lines; + else { + lp = findline(num); + if (lp == NULL) { + free((char *) newlp); + return FALSE; + } + } + + newlp->next = lp; + newlp->prev = lp->prev; + lp->prev->next = newlp; + lp->prev = newlp; + + lastnum++; + dirty = TRUE; + + return setcurnum(num); +} + + +/* + * Delete lines from the given range. + */ +static BOOL + deletelines(num1, num2) + NUM num1; + NUM num2; +{ + LINE *lp; + LINE *nlp; + LINE *plp; + NUM count; + if ((num1 < 1) || (num2 > lastnum) || (num1 > num2)) { + fprintf(stderr, "Bad line numbers for delete\n"); + return FALSE; + } + + lp = findline(num1); + if (lp == NULL) + return FALSE; + + if ((curnum >= num1) && (curnum <= num2)) { + if (num2 < lastnum) + setcurnum(num2 + 1); + else if (num1 > 1) + setcurnum(num1 - 1); + else + curnum = 0; + } + + count = num2 - num1 + 1; + + if (curnum > num2) + curnum -= count; + + lastnum -= count; + + while (count-- > 0) { + nlp = lp->next; + plp = lp->prev; + plp->next = nlp; + nlp->prev = plp; + lp->next = NULL; + lp->prev = NULL; + lp->len = 0; + free(lp); + lp = nlp; + } + + dirty = TRUE; + + return TRUE; +} + + +/* + * Search for a line which contains the specified string. + * If the string is NULL, then the previously searched for string + * is used. The currently searched for string is saved for future use. + * Returns the line number which matches, or 0 if there was no match + * with an error printed. + */ +static NUM + searchlines(str, num1, num2) + char *str; + NUM num1; + NUM num2; +{ + LINE *lp; + int len; + if ((num1 < 1) || (num2 > lastnum) || (num1 > num2)) { + fprintf(stderr, "Bad line numbers for search\n"); + return 0; + } + + if (*str == '\0') { + if (searchstring[0] == '\0') { + fprintf(stderr, "No previous search string\n"); + return 0; + } + str = searchstring; + } + + if (str != searchstring) + strcpy(searchstring, str); + + len = strlen(str); + + lp = findline(num1); + if (lp == NULL) + return 0; + + while (num1 <= num2) { + if (findstring(lp, str, len, 0) >= 0) + return num1; + + num1++; + lp = lp->next; + } + + fprintf(stderr, "Cannot find string \"%s\"\n", str); + + return 0; +} + + +/* + * Return a pointer to the specified line number. + */ +static LINE * + findline(num) + NUM num; +{ + LINE *lp; + NUM lnum; + if ((num < 1) || (num > lastnum)) { + fprintf(stderr, "Line number %d does not exist\n", num); + return NULL; + } + + if (curnum <= 0) { + curnum = 1; + curline = lines.next; + } + + if (num == curnum) + return curline; + + lp = curline; + lnum = curnum; + + if (num < (curnum / 2)) { + lp = lines.next; + lnum = 1; + } + else if (num > ((curnum + lastnum) / 2)) { + lp = lines.prev; + lnum = lastnum; + } + + while (lnum < num) { + lp = lp->next; + lnum++; + } + + while (lnum > num) { + lp = lp->prev; + lnum--; + } + + return lp; +} + + +/* + * Set the current line number. + * Returns TRUE if successful. + */ +static BOOL + setcurnum(num) + NUM num; +{ + LINE *lp; + lp = findline(num); + if (lp == NULL) + return FALSE; + + curnum = num; + curline = lp; + + return TRUE; +} +#endif /* CMD_ED */ +/* END CODE */ diff --git a/src/sh/sash/cmd_grep.c b/src/sh/sash/cmd_grep.c new file mode 100755 index 00000000..29c65a05 --- /dev/null +++ b/src/sh/sash/cmd_grep.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * The "grep" built-in command. + */ +#include "sash.h" + +#ifdef CMD_GREP + +static BOOL search __P((char *, char *, BOOL)); + +/* + * See if the specified word is found in the specified string. + */ +static BOOL search(string, word, ignorecase) + char *string; + char *word; + BOOL ignorecase; +{ + char *cp1, *cp2; + int lowfirst, ch1, ch2, len = strlen(word); + + if (!ignorecase) { + while (TRUE) { + if ((string = strchr(string, word[0])) == NULL) + return FALSE; + if (memcmp(string, word, len) == 0) + return TRUE; + string++; + } + } + /* Here if we need to check case independence. + * Do the search by lower casing both strings. + */ + lowfirst = *word; + if (isupper(lowfirst)) + lowfirst = tolower(lowfirst); + while (TRUE) { + while (*string && + *string != lowfirst && + (!isupper(*string) || (tolower(*string) != lowfirst))) + ++string; + if (*string == '\0') + break; + cp1 = string; + cp2 = word; + do { + if (*cp2 == '\0') + return TRUE; + ch1 = *cp1++; + if (isupper(ch1)) + ch1 = tolower(ch1); + ch2 = *cp2++; + if (isupper(ch2)) + ch2 = tolower(ch2); + } while (ch1 == ch2); + string++; + } + return FALSE; +} + +void do_grep(argc, argv) + int argc; + char **argv; +{ + FILE *fp; + long line; + BOOL tellname; + char *word, *name, *cp, buf[1024]; + BOOL ignorecase = FALSE; + BOOL tellline = FALSE; + + argc--; + argv++; + if (**argv == '-') { + argc--; + cp = *argv++; + while (*++cp) { + switch (*cp) { + case 'i': ++ignorecase; break; + case 'n': ++tellline; break; + default: + fprintf(stderr, "Unknown option -%c\n",*cp); + return; + } + } + } + word = *argv++; + argc--; + tellname = (argc > 1); + while (argc-- > 0) { + name = *argv++; + if ((fp = fopen(name, "r")) == NULL) { + perror(name); + continue; + } + for (line = 0; fgets(buf, sizeof(buf), fp); ) { + if (intflag) { + fclose(fp); + return; + } + line++; + cp = &buf[strlen(buf) - 1]; + if (*cp != '\n') + fprintf(stderr, "%s: Line too long\n", name); + if (search(buf, word, ignorecase)) { + if (tellname) printf("%s: ", name); + if (tellline) printf("%d: ", line); + fputs(buf, stdout); + } + } + if (ferror(fp)) + perror(name); + fclose(fp); + } +} +#endif /* CMD_GREP */ + \ No newline at end of file diff --git a/src/sh/sash/cmd_ls.c b/src/sh/sash/cmd_ls.c new file mode 100755 index 00000000..94e671e6 --- /dev/null +++ b/src/sh/sash/cmd_ls.c @@ -0,0 +1,347 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * The "ls" built-in command. + */ +#include "sash.h" +#ifdef CMD_LS + +#include +#include +#include +#include +#include + +#define LISTSIZE 256 + +#ifdef S_ISLNK +#define LSTAT lstat +#else +#define LSTAT stat +#endif + +/* + * Flags for the LS command. + */ +#define LSF_LONG 0x01 +#define LSF_DIR 0x02 +#define LSF_INODE 0x04 +#define LSF_MULT 0x08 + +static char **list; +static int listsize; +static int listused; + +static void lsfile __P((char *, struct stat *, int)); + +/* + * Do an LS of a particular file name according to the flags. + */ +static void lsfile(name, statbuf, flags) + char *name; + struct stat *statbuf; + int flags; +{ + static char username[12]; + static int userid; + static BOOL useridknown; + static char groupname[12]; + static int groupid; + static BOOL groupidknown; + int len; + + struct passwd *pwd; + struct group *grp; + char buf[PATHLEN], *cp = buf; + + *cp = '\0'; + if (flags & LSF_INODE) { + sprintf(cp, "%5d ", statbuf->st_ino); + cp += strlen(cp); + } + if (flags & LSF_LONG) { + cp += strlen(strcpy(cp, modestring(statbuf->st_mode))); + sprintf(cp, "%3d ", statbuf->st_nlink); + cp += strlen(cp); +#if 0 + if (!useridknown || (statbuf->st_uid != userid)) { + if ((pwd = getpwuid(statbuf->st_uid)) != NULL) + strcpy(username, pwd->pw_name); + else sprintf(username, "%d", statbuf->st_uid); + userid = statbuf->st_uid; + useridknown = TRUE; + } + sprintf(cp, "%-8s ", username); + cp += strlen(cp); + if (!groupidknown || (statbuf->st_gid != groupid)) { + if ((grp = getgrgid(statbuf->st_gid)) != NULL) + strcpy(groupname, grp->gr_name); + else sprintf(groupname, "%d", statbuf->st_gid); + groupid = statbuf->st_gid; + groupidknown = TRUE; + } + sprintf(cp, "%-8s ", groupname); + cp += strlen(cp); +#endif + if (S_ISDEV(statbuf->st_mode)) + sprintf(cp, "%-8d ", statbuf->st_rdev); + else sprintf(cp, "%8ld ", sizeval(&statbuf->st_size)); + cp += strlen(cp); + sprintf(cp, " %-12s ", timestring(&statbuf->st_mtime)); + } + fputs(buf, stdout); + fputs(name, stdout); +#ifdef S_ISLNK + if ((flags & LSF_LONG) && S_ISLNK(statbuf->st_mode)) { + if ((len = readlink(name, buf, PATHLEN - 1)) >= 0) { + buf[len] = '\0'; + printf(" -> %s", buf); + } + } +#endif + fputc('\n', stdout); +} + +void do_ls(argc, argv) + int argc; + char **argv; +{ + static char *def[2] = {"-ls", "."}; + + char *cp, *name, **newlist, fullname[PATHLEN]; + struct stat statbuf; + struct dirent *dp; + BOOL endslash; + int i, flags; + DIR *dirp; + + if (listsize == 0) { + if ((list = (char **) malloc(LISTSIZE * sizeof(char *))) == NULL) { + fprintf(stderr, "No memory for ls buffer\n"); + return; + } + listsize = LISTSIZE; + } + listused = 0; + flags = 0; + if ((argc > 1) && (argv[1][0] == '-')) { + argc--; + for (cp = *(++argv) + 1; *cp; ++cp) { + switch (*cp) { + case 'd': flags |= LSF_DIR; break; + case 'i': flags |= LSF_INODE; break; + case 'l': flags |= LSF_LONG; break; + default: + fprintf(stderr, "Unknown option -%c\n", *cp); + return; + } + } + } + if (argc <= 1) { + argc = 2; + argv = def; + } + if (argc > 2) + flags |= LSF_MULT; + while (--argc > 0) { + name = *(++argv); + endslash = (*name && (name[strlen(name) - 1] == '/')); + if (LSTAT(name, &statbuf) < 0) { + perror(name); + continue; + } + if ((flags & LSF_DIR) || (!S_ISDIR(statbuf.st_mode))) { + lsfile(name, &statbuf, flags); + continue; + } + /* Do all the files in a directory. */ + if ((dirp = opendir(name)) == NULL) { + perror(name); + continue; + } + if (flags & LSF_MULT) + printf("\n%s:\n", name); + while ((dp = readdir(dirp)) != NULL) { + if (intflag) + break; + if (dp->d_name[0] == '\0') + continue; + fullname[0] = '\0'; + if ((*name != '.') || (name[1] != '\0')) { + strcpy(fullname, name); + if (!endslash) + strcat(fullname, "/"); + } + strcat(fullname, dp->d_name); + if (listused >= listsize) { + newlist = realloc(list, + ((sizeof(char **)) * (listsize + LISTSIZE))); + if (newlist == NULL) { + fprintf(stderr, "No memory for ls buffer\n"); + break; + } + list = newlist; + listsize += LISTSIZE; + } + if ((list[listused] = strdup(fullname)) == NULL) { + fprintf(stderr, "No memory for filenames\n"); + break; + } + listused++; + } + closedir(dirp); + /* Sort the files. */ + qsort((char *) list, listused, + sizeof(char *), (cmp_func_t)namesort); /**/ + /* Now finally list the filenames. */ + for (i = 0; i < listused; i++, free(name)) { + name = list[i]; + if (LSTAT(name, &statbuf) < 0) { + perror(name); + continue; + } + if ((cp = strrchr(name, '/')) != 0) + ++cp; + else cp = name; + lsfile(cp, &statbuf, flags); /**/ + } + listused = 0; + } + fflush(stdout); +} +#endif /* CMD_LS */ + +#ifdef CMD_LS_LIGHT +#include "sys\stat.h" +#include +#define MINOR(dev) ((uchar)(dev)) +#define MAJOR(dev) ((uchar)((dev) >> 8)) + +int devdir(stat) + int stat; +{ + stat &= S_IFMT; + + switch (stat) { + case S_IFDIR: return 'd'; + case S_IFPIPE: return 'p'; + case S_IFBLK: return 'b'; + case S_IFCHR: return 'c'; + case S_IFLNK: return 'l'; + } + return '-'; +} + +char *prot(stat) + int stat; +{ + static char _prots[8][4] = { + "---", "--x", "-w-", "-wx", + "r--", "r-x", "rw-", "rwx" + }; + return _prots[stat & 7]; +} + +void lsfiles(d, path, wide) + int d; + char *path; + int wide; +{ + int i, fd, pathsize; + direct_t buf; + char *dname; + struct stat statbuf; + + pathsize = strlen(path); + while (read(d, (char *) &buf, sizeof(direct_t)) == sizeof(direct_t)) { + if (buf.d_name[0] == '\0') + continue; + dname = path; + dname[pathsize] = '\0'; + if (strcmp(path,".") != 0) { + strcat(dname, "/"); + } else dname = path + pathsize; + strncat(dname, buf.d_name, DIRNAMELEN); + fd = open(dname, O_SYMLINK); + i = (fd >= 0) ? fstat(fd, &statbuf) : + stat(dname, &statbuf); + if (i) { + perror(dname); + if (fd >= 0) + close(fd); + continue; + } + if ((statbuf.st_mode & S_IFMT) == S_IFDIR) + strcat(dname, "/"); + if (wide==0) { + if (S_ISDEV(statbuf.st_mode)) + printf("%3d,%-5d", + MAJOR(statbuf.st_rdev), + MINOR(statbuf.st_rdev)); + else printf("%-9ld", statbuf.st_size); + printf(" %c%s%s%s %2d @%-5u %s", + devdir(statbuf.st_mode), + prot(statbuf.st_mode >> 6), + prot(statbuf.st_mode >> 3), + prot(statbuf.st_mode >> 0), + statbuf.st_nlink, + statbuf.st_ino, + dname); + if ((statbuf.st_mode & S_IFMT) == S_IFLNK) { + dname[0] = 0; + i = read(fd, dname, 128); + dname[i] = 0; + printf(" -> %s", dname); + close(fd); + } + } else { + printf("%s",dname); + i = strlen(dname) + 1; + if ((statbuf.st_mode & S_IFMT) == S_IFLNK) putchar('@'); + else if (((statbuf.st_mode & S_IFMT) != S_IFDIR) && + ((statbuf.st_mode & S_IEXEC)+ + (statbuf.st_mode & S_IGEXEC)+ + (statbuf.st_mode & S_IOEXEC) !=0 )) putchar('*'); + else i--; + if (i < 16) putchar('\t'); + if (i < 8) putchar('\t'); + } + if (!wide) putchar('\n'); + } + if (wide) putchar('\n'); +} + +void do_ls(argc, argv) + int argc; + char **argv; +{ + int d,wide = 1; + struct stat statbuf; + char path[512]; + + if (argc == 1) strcpy(path,"."); + if (argc == 2) + if (strcmp(argv[1],"-l") == 0) { + wide = 0; + strcpy(path,"."); + } else strcpy(path,argv[1]); + if (argc == 3) { + if (strcmp(argv[1],"-l") != 0) { + fprintf(stderr,"Unknown option %s\n",argv[1]); + return; + } + wide = 0; + strcpy(path,argv[2]); + } + if (lstat(path, &statbuf) != 0) perror(path); + else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) perror(path); + else if ((d = open(path, 0)) < 0) perror(path); + else { + lsfiles(d, path, wide); + close(d); + } + return; +} +#endif /* CMD_LS_LIGHT */ diff --git a/src/sh/sash/cmd_tar.c b/src/sh/sash/cmd_tar.c new file mode 100755 index 00000000..b038a716 --- /dev/null +++ b/src/sh/sash/cmd_tar.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * The "tar" built-in command. + */ +#include "sash.h" +#ifdef CMD_TAR + +#include + +/* + * Tar file format. + */ +#define TBLOCK 512 +#define NAMSIZ 100 + +union hblock { + char dummy[TBLOCK]; + struct header { + char name[NAMSIZ]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char mtime[12]; + char chksum[8]; + char linkflag; + char linkname[NAMSIZ]; + char extno[4]; + char extotal[4]; + char efsize[12]; + } dbuf; +} dblock; + +static BOOL inheader; +static BOOL badheader; +static BOOL badwrite; +static BOOL extracting; +static BOOL warnedroot; +static BOOL eof; +static BOOL verbose; +static long datacc; +static int outfd; +static char outname[NAMSIZ]; + +static void doheader __P((struct header *)); +static void dodata __P((char *, int)); +static void createpath __P((char *, int)); +static long getoctal __P((char *, int)); + +static void doheader(hp) + struct header *hp; +{ + int cc, mode, uid, gid, chksum; + BOOL hardlink, softlink; + long size, mtime; + char *name; + + /* If the block is completely empty, then this is the end of the + * archive file. If the name is null, then just skip this header. + */ + if (*(name = hp->name) == '\0') { + for (cc = TBLOCK; cc > 0; cc--) { + if (*name++) + return; + } + eof = TRUE; + return; + } + mode = getoctal(hp->mode, sizeof(hp->mode)); + uid = getoctal(hp->uid, sizeof(hp->uid)); + gid = getoctal(hp->gid, sizeof(hp->gid)); + size = getoctal(hp->size, sizeof(hp->size)); + mtime = getoctal(hp->mtime, sizeof(hp->mtime)); + chksum = getoctal(hp->chksum, sizeof(hp->chksum)); + if ((mode < 0) || (uid < 0) || (gid < 0) || (size < 0)) { + if (!badheader) + fprintf(stderr, "Bad tar header, skipping\n"); + badheader = TRUE; + return; + } + badheader = FALSE; + badwrite = FALSE; + hardlink = ((hp->linkflag == 1) || (hp->linkflag == '1')); + softlink = ((hp->linkflag == 2) || (hp->linkflag == '2')); + if (name[strlen(name) - 1] == '/') mode |= S_IFDIR; + else if ((mode & S_IFMT) == 0) mode |= S_IFREG; + if (*name == '/') { + while (*name == '/') + name++; + if (!warnedroot) + fprintf(stderr, "Absolute paths detected, removing leading slashes\n"); + warnedroot = TRUE; + } + if (!extracting) { + if (verbose) + printf("%s %3d/%-d %9l %s %s", + modestring(mode), + uid, gid, size, + timestring(mtime), name); + else printf("%s", name); + if (hardlink) + printf(" (link to \"%s\")", hp->linkname); + else if (softlink) + printf(" (symlink to \"%s\")", hp->linkname); + else if (S_ISREG(mode)) { + inheader = (size == 0); + datacc = size; + } + printf("\n"); + return; + } + if (verbose) + printf("x %s\n", name); + if (hardlink) { + if (link(hp->linkname, name) < 0) + perror(name); + return; + } + if (softlink) { +#ifdef S_ISLNK + if (symlink(hp->linkname, name) < 0) + perror(name); +#else + fprintf(stderr, "Cannot create symbolic links\n"); +#endif + return; + } + if (S_ISDIR(mode)) { + createpath(name, mode); + return; + } + createpath(name, 0777); + inheader = (size == 0); + datacc = size; + if ((outfd = creat(name, mode)) < 0) { + perror(name); + badwrite = TRUE; + return; + } + if (size == 0) { + close(outfd); + outfd = -1; + } +} + +/* + * Handle a data block of some specified size. + */ +static void dodata(cp, count) + char *cp; + int count; +{ + int cc; + + if ((datacc -= count) <= 0) + inheader = TRUE; + if (badwrite || !extracting) + return; + while (count > 0) { + if ((cc = write(outfd, cp, count)) < 0) { + perror(outname); + close(outfd); + outfd = -1; + badwrite = TRUE; + return; + } + count -= cc; + } + if (datacc <= 0) { + if (close(outfd)) + perror(outname); + outfd = -1; + } +} + +/* + * Attempt to create the directories along the specified path, except for + * the final component. The mode is given for the final directory only, + * while all previous ones get default protections. Errors are not reported + * here, as failures to restore files can be reported later. + */ +static void createpath(name, mode) + char *name; + int mode; +{ + char *cp, *cpold, buf[NAMSIZ]; + + strcpy(buf, name); + cp = strchr(buf, '/'); + while (cp) { + cpold = cp; + cp = strchr(cp + 1, '/'); + *cpold = '\0'; + if (mkdir(buf, cp ? 0777 : mode) == 0) + printf("Directory \"%s\" created\n", buf); + *cpold = '/'; + } +} + +/* + * Read an octal value in a field of the specified width, with optional + * spaces on both sides of the number and with an optional null character + * at the end. Returns -1 on an illegal format. + */ +static long getoctal(cp, len) + char *cp; + int len; +{ + long val; + + while ((len > 0) && (*cp == ' ')) { + cp++; + len--; + } + if ((len == 0) || !isoctal(*cp)) + return -1; + for (val = 0; (len > 0) && isoctal(*cp); --len, ++cp) { + val <<= 3; + val += *cp - '0'; + } + while ((len > 0) && (*cp == ' ')) { + cp++; + len--; + } + if ((len > 0) && *cp) + return -1; + return val; +} + +void do_tar(argc, argv) + int argc; + char **argv; +{ + char *cp, *str, *devname, buf[8192]; + BOOL createflag, listflag, fileflag; + int devfd, cc, blocksize; + long incc; + + createflag = FALSE; + extracting = FALSE; + listflag = FALSE; + fileflag = FALSE; + verbose = FALSE; + badwrite = FALSE; + badheader = FALSE; + warnedroot = FALSE; + eof = FALSE; + inheader = TRUE; + incc = 0; + datacc = 0; + outfd = -1; + blocksize = sizeof(buf); + + for (str = argv[1]; *str; str++) { + switch (*str) { + case 'f': fileflag = TRUE; break; + case 't': listflag = TRUE; break; + case 'x': extracting = TRUE; break; + case 'v': verbose = TRUE; break; + case 'c': + case 'a': + fprintf(stderr, "Writing is not supported\n"); + return; + default: + fprintf(stderr, "Unknown tar flag -%c\n", *str); + return; + } + } + if (!fileflag) { + fprintf(stderr, "The 'f' flag must be specified\n"); + return; + } + if (argc < 3) { + fprintf(stderr, "Missing input name\n"); + return; + } + devname = argv[2]; + if (extracting + listflag != 1) { + fprintf(stderr, "Exactly one of 'x' or 't' must be specified\n"); + return; + } + if ((devfd = open(devname, 0)) < 0) { + perror(devname); + return; + } + while (TRUE) { + if ((incc == 0) && !eof) { + while (incc < blocksize) { + cc = read(devfd, &buf[incc], blocksize - incc); + if (cc < 0) { + perror(devname); + goto done; + } + if (cc == 0) + break; + incc += cc; + } + cp = buf; + } + if (intflag) { + if (extracting && (outfd >= 0)) + close(outfd); + close(devfd); + return; + } + if (inheader) { + if ((incc == 0) || eof) + goto done; + if (incc < TBLOCK) { + fprintf(stderr, "Short block for header\n"); + goto done; + } + doheader((struct header *) cp); + cp += TBLOCK; + incc -= TBLOCK; + continue; + } + if ((cc = incc) > datacc) + cc = datacc; + dodata(cp, cc); + if (cc % TBLOCK) + cc += TBLOCK - (cc % TBLOCK); + cp += cc; + incc -= cc; + } +done: close(devfd); +} +#endif /* CMD_TAR */ diff --git a/src/sh/sash/cmds.c b/src/sh/sash/cmds.c new file mode 100755 index 00000000..5336baf7 --- /dev/null +++ b/src/sh/sash/cmds.c @@ -0,0 +1,915 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Most simple built-in commands are here. + */ +#include "sash.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Nick */ +#pragma warn -par + +#ifdef CMD_SLEEP +void do_sleep(argc, argv) + int argc; + char *argv[]; +{ + int sec = 1; + + if (argc > 1) + sec = atoi(argv[1]); + sleep(sec); +} +#endif /* CMD_SLEEP */ + +#ifdef CMD_ECHO_LIGHT +void do_echo(argc, argv) + int argc; + char *argv[]; +{ + BOOL first = TRUE; + BOOL nonl = FALSE; + + if (argc > 1 && strcmp(argv[0],"-n") == 0) { + --argc; + ++argv; + ++nonl; + } + while (--argc > 0) { + if (!first) + fputc(' ', stdout); + first = FALSE; + fputs(*++argv, stdout); + } + if (!nonl) + putchar('\n'); + fflush(stdout); +} +#endif /* CMD_ECHO_LIGHT */ + +#ifdef CMD_ECHO +static BOOL __doesc(p, _nonl) + char *p; + BOOL _nonl; +{ + int i, n; + BOOL nonl = _nonl; + char ch; + + while ((ch = *p++) != 0) { + if (ch == '\\') { + switch (*p++) { + case 'c': nonl = 1; continue; + case 'a': ch = 7; break; + case 'b': ch = '\b'; break; + case 'f': ch = '\f'; break; + case 'n': ch = '\n'; break; + case 'r': ch = '\r'; break; + case 't': ch = '\t'; break; + case 'v': ch = '\v'; break; + case '\\': ch = '\\'; break; + case 'x': + n = 0; + for (i = 2; --i >= 0; ++p) { + ch = *p - '0'; + if (ch > 'a'-'0') + ch = *p - 'a' + 10; + else if (ch > 'A'-'0') + ch = *p - 'A' + 10; + if (ch < 0 || ch > 15) + break; + n <<= 4; + n += ch; + } + ch = n; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + n = 0; + for (i = 3, --p; --i >= 0; ++p) { + ch = *p - '0'; + if (ch < 0 || ch > 7) + break; + n <<= 3; + n += ch; + } + ch = n; + break; + default: ch = *p; break; + } + } + fputc(ch, stdout); + } + return (nonl); +} + +void do_echo(argc, argv) + int argc; + char *argv[]; +{ + BOOL first = 1, esc = 0, nonl = 0; + char *p; + int i; + + for (i = 1; i < argc; ++i) { + p = argv[i]; + if (p[0] == '-') { + for (++p; *p; ++p) { + switch (*p) { + case 'n': nonl = 1; break; + case 'e': esc = 1; break; + default: goto Print; + } + } + } + else break; + } +Print: for (; i < argc; ++i) { + p = argv[i]; + if (!first) + fputc(' ', stdout); + first = 0; + if (esc) + nonl = __doesc(p, nonl); + else fputs(p, stdout); + } + if (!nonl) + fputc('\n', stdout); +} +#endif /* CMD_ECHO */ + +#ifdef CMD_PWD +void do_pwd(argc, argv) + int argc; + char *argv[]; +{ + char buf[PATHLEN]; + + if (getcwd(buf, PATHLEN) == NULL) { + perror("Can't get current directory"); + return; + } + fputs(buf, stdout); + putchar('\n'); + fflush(stdout); +} +#endif /* CMD_PWD */ + +void do_cd(argc, argv) + int argc; + char *argv[]; +{ + char *path; + + if (argc > 1) + path = argv[1]; + else { + if ((path = getenv("HOME")) == NULL) { + fprintf(stderr, "No HOME environment variable\n"); + return; + } + } + if (chdir(path) < 0) + perror(path); +} + +#ifdef CMD_CHROOT +void do_chroot(argc, argv) + int argc; + char *argv[]; +{ + char *path = argv[1]; + + if (chroot(path) < 0) + perror(path); +} +#endif + +#ifdef CMD_MKDIR +void do_mkdir(argc, argv) + int argc; + char *argv[]; +{ + while (--argc > 0) { + if (mkdir(argv[1], 0777) < 0) + perror(argv[1]); + argv++; + } +} +#endif /* CMD_MKDIR */ + +#ifdef CMD_MKNOD +void do_mknod(argc, argv) + int argc; + char *argv[]; +{ + char *cp; + int major; + int mode = 0666; + + if (strcmp(argv[2], "b") == 0) + mode |= S_IFBLK; + else if (strcmp(argv[2], "c") == 0) + mode |= S_IFCHR; + else { + fprintf(stderr, "Bad device type\n"); + return; + } + for (major = 0, cp = argv[3]; isdecimal(*cp); ++cp) { + major *= 10; + major += *cp - '0'; + } + if (*cp || (major < 0) || (major > 255)) { + fprintf(stderr, "Bad major number\n"); + return; + } + if (mknod(argv[1], mode, major) < 0) + perror(argv[1]); +} +#endif /* CMD_MKNOD */ + +#ifdef CMD_RMDIR +void do_rmdir(argc, argv) + int argc; + char *argv[]; +{ + while (--argc > 0) { + if (rmdir(argv[1]) < 0) + perror(argv[1]); + argv++; + } +} +#endif /* CMD_RMDIR */ + +#ifdef CMD_SYNC +void do_sync(argc, argv) + int argc; + char *argv[]; +{ + sync(); +} +#endif /* CMD_SYNC */ + +#ifdef CMD_RM +void do_rm(argc, argv) + int argc; + char *argv[]; +{ + struct stat sbuf; + int j; + + while (--argc > 0) { + j = lstat(argv[1], &sbuf); + if (j != 0) j = stat(argv[1], &sbuf); + if (j == 0) { + if ((sbuf.st_mode & S_IFDIR) != 0) { + fprintf(stderr, "rm: %s is a directory\n",argv[1]); + return; + } + } + if ((j != 0) || (unlink(argv[1]))) perror(argv[1]); + argv++; + } +} +#endif /* CMD_RM */ + +#ifdef CMD_CHMOD +void do_chmod(argc, argv) + int argc; + char *argv[]; +{ + int mode = 0; + char *cp = argv[1]; + + while (isoctal(*cp)) + mode = (mode << 3) + (*cp++ - '0'); + if (*cp) { + fprintf(stderr, "Mode must be octal\n"); + return; + } + for (--argc, ++argv; --argc > 0; ++argv) { + if (chmod(argv[1], mode) < 0) + perror(argv[1]); + } +} +#endif /* CMD_CHMOD */ + + +#ifdef CMD_CHOWN +void do_chown(argc, argv) + int argc; + char *argv[]; +{ + int uid; + char *cp = argv[1]; + struct stat statbuf; + + if (isdecimal(*cp)) { + for (uid = 0; isdecimal(*cp); ++cp) { + uid *= 10; + uid += *cp - '0'; + } + if (*cp) { + fprintf(stderr, "Bad uid value\n"); + return; + } + } + else { + struct passwd *pwd = getpwnam(cp); + + if (pwd == NULL) { + fprintf(stderr, "Unknown user name\n"); + return; + } + uid = pwd->pw_uid; + } + for (--argc, ++argv; --argc > 0; ) { + argv++; + if ((stat(*argv, &statbuf) < 0) || + (chown(*argv, uid, statbuf.st_gid) < 0)) + perror(*argv); + } +} +#endif /* CMD_CHOWN */ + +#ifdef CMD_CHGRP +void do_chgrp(argc, argv) + char *argv[]; +{ + int gid; + struct stat statbuf; + char *cp = argv[1]; + + if (isdecimal(*cp)) { + for (gid = 0; isdecimal(*cp); ++cp) { + gid *= 10; + gid += *cp - '0'; + } + if (*cp) { + fprintf(stderr, "Bad gid value\n"); + return; + } + } + else { + struct group *grp = getgrnam(cp); + + if (grp == NULL) { + fprintf(stderr, "Unknown group name\n"); + return; + } + gid = grp->gr_gid; + } + for (--argc, ++argv; --argc > 0; ) { + argv++; + if ((stat(*argv, &statbuf) < 0) || + (chown(*argv, statbuf.st_uid, gid) < 0)) + perror(*argv); + } +} +#endif /* CMD_CHGRP */ + +#ifdef CMD_TOUCH +void do_touch(argc, argv) + int argc; + char *argv[]; +{ + int fd; + char *name; + struct utimbuf now; + + time(&now.actime); + now.modtime = now.actime; + while (--argc > 0) { + name = *(++argv); + if ((fd = open(name, O_CREAT | O_WRONLY | O_EXCL, 0666)) >= 0) { + close(fd); + continue; + } + if (utime(name, &now) < 0) + perror(name); + } +} +#endif /* CMD_TOUCH */ + +#ifdef CMD_MV +void do_mv(argc, argv) + int argc; + char *argv[]; +{ + char *srcname, *destname, *lastarg = argv[argc - 1]; + int dirflag = isadir(lastarg); + + if ((argc > 3) && !dirflag) { + fprintf(stderr, "%s: not a directory\n", lastarg); + return; + } + while (argc-- > 2) { + srcname = *(++argv); + if (access(srcname, 0) < 0) { + perror(srcname); + continue; + } + destname = lastarg; + if (dirflag) + destname = buildname(destname, srcname); + if (rename(srcname, destname) >= 0) + continue; + if (errno != EXDEV) { + perror(destname); + continue; + } + if (!copyfile(srcname, destname, TRUE)) + continue; + if (unlink(srcname) < 0) + perror(srcname); + } +} +#endif /* CMD_MV */ + +#ifdef CMD_LN +void do_ln(argc, argv) + int argc; + char *argv[]; +{ + int dirflag; + char *srcname, *destname, *lastarg; + + if (argv[1][0] == '-') { + if (strcmp(argv[1], "-s")) { + fprintf(stderr, "Unknown option\n"); + return; + } + if (argc != 4) { + fprintf(stderr, "Wrong number of arguments for symbolic link\n"); + return; + } +#ifdef S_ISLNK + if (symlink(argv[2], argv[3]) < 0) + perror(argv[3]); +#else + fprintf(stderr, "Symbolic links are not allowed\n"); +#endif + return; + } + /* Here for normal hard links. */ + lastarg = argv[argc - 1]; + dirflag = isadir(lastarg); + if ((argc > 3) && !dirflag) { + fprintf(stderr, "%s: not a directory\n", lastarg); + return; + } + while (argc-- > 2) { + srcname = *(++argv); + if (access(srcname, 0) < 0) { + perror(srcname); + continue; + } + destname = lastarg; + if (dirflag) + destname = buildname(destname, srcname); + + if (link(srcname, destname) < 0) { + perror(destname); + continue; + } + } +} +#endif /* CMD_LN */ + +#ifdef CMD_CP +void do_cp(argc, argv) + char *argv[]; +{ + char *srcname, *destname, *lastarg = argv[argc - 1]; + BOOL dirflag = isadir(lastarg); + + if ((argc > 3) && !dirflag) { + fprintf(stderr, "%s: not a directory\n", lastarg); + return; + } + while (argc-- > 2) { + destname = lastarg; + srcname = *++argv; + if (dirflag) + destname = buildname(destname, srcname); + copyfile(srcname, destname, FALSE); + } +} +#endif /* CMD_CP */ + +#ifdef CMD_MOUNT +void do_mount(argc, argv) + int argc; + char *argv[]; +{ + char *str; + BOOL ro = FALSE; + + for (--argc, ++argv; argc > 0 && **argv == '-'; ) { + for (--argc, str = *argv++; *++str; ) { + switch (*str) { + case 'r': + ro = TRUE; + break; + default: + fprintf(stderr, "Unknown option -%c\n",*str); + return; + } + } + } + if (argc != 2) { + fprintf(stderr, "Wrong number of arguments for mount\n"); + return; + } + if (mount(argv[0], argv[1], ro) < 0) + perror("mount failed"); +} +#endif /* CMD_MOUNT */ + +#ifdef CMD_MOUNT +void do_umount(argc, argv) + int argc; + char *argv[]; +{ + if (umount(argv[1]) < 0) + perror(argv[1]); +} +#endif /* CMD_MOUNT */ + +#ifdef CMD_CMP +void do_cmp(argc, argv) + int argc; + char *argv[]; +{ + long pos; + int fd1, fd2; + int cc1, cc2; + struct stat statbuf1, statbuf2; + char *bp1, *bp2, buf1[BUFSIZ], buf2[BUFSIZ]; + + if (stat(argv[1], &statbuf1) < 0) { + perror(argv[1]); + return; + } + if (stat(argv[2], &statbuf2) < 0) { + perror(argv[2]); + return; + } + if ((statbuf1.st_dev == statbuf2.st_dev) && + (statbuf1.st_ino == statbuf2.st_ino)) { + printf("Files are links to each other\n"); + return; + } + if (memcmp(&statbuf1.st_size,&statbuf2.st_size,sizeof(statbuf1.st_size))) { + printf("Files are different sizes\n"); + return; + } + if ((fd1 = open(argv[1], 0)) < 0) { + perror(argv[1]); + return; + } + if ((fd2 = open(argv[2], 0)) < 0) { + perror(argv[2]); + close(fd1); + return; + } + for (pos = 0; ; ) { + if (intflag) + goto closefiles; + if ((cc1 = read(fd1, buf1, sizeof(buf1))) < 0) { + perror(argv[1]); + goto closefiles; + } + if ((cc2 = read(fd2, buf2, sizeof(buf2))) < 0) { + perror(argv[2]); + goto closefiles; + } + if ((cc1 == 0) && (cc2 == 0)) { + printf("Files are identical\n"); + goto closefiles; + } + if (cc1 < cc2) { + printf("First file is shorter than second\n"); + goto closefiles; + } + if (cc1 > cc2) { + printf("Second file is shorter than first\n"); + goto closefiles; + } + if (memcmp(buf1, buf2, cc1) == 0) { + pos += cc1; + continue; + } + for (bp1 = buf1, bp2 = buf2; *bp1++ == *bp2++; ++pos) + ; + printf("Files differ at byte position %ld\n", pos); + goto closefiles; + } + +closefiles: + close(fd1); + close(fd2); +} +#endif /* CMD_CMP */ + +#ifdef CMD_CAT_MORE +void do_cat(argc, argv) + int argc; + char *argv[]; +{ + do_cat_more(argc,argv,CMDCAT); +} + +void do_more(argc, argv) + int argc; + char *argv[]; +{ + do_cat_more(argc,argv,CMDMORE); +} +#endif + +#ifdef CMD_MORE +void do_more(argc, argv) +#endif +#ifdef CMD_CAT_MORE +void do_cat_more(argc, argv, mode) +#endif +#if defined(CMD_MORE) || defined(CMD_CAT_MORE) + int argc; + char *argv[]; +#ifdef CMD_CAT_MORE + int mode; +#endif +{ + FILE *fp; + int ch, line, col, tty = STDIN_FILENO; + char *name, buf[80]; + BOOL viastdin = FALSE; +#if 1 /* Nick */ + struct sgttyb state; + int raw; +#endif + + if (argc < 2) { + if (isatty(STDIN_FILENO)) { + return; + } else { + viastdin = TRUE; + argc++; + tty = open(_PATH_CONSOLE, O_RDONLY); + } + } +#if 1 /* Nick */ + if (isatty(tty)) + { + gtty(tty, &state); + raw = state.sg_flags; + state.sg_flags &= ~CBREAK; + state.sg_flags |= RAW; + stty(tty, &state); + } +#else + ioctl(tty, TTY_RAW); +#endif + while (--argc > 0) { + if (!viastdin) { + name = *(++argv); + if ((fp = fopen(name, "r")) == NULL) { + perror(name); + continue; + } + } else fp = stdin; + if (!viastdin) +#ifdef CMD_CAT_MORE + if (mode == CMDMORE) +#endif + printf("<< %s >>\n", name); + line = 1; + col = 0; + while (fp && ((ch = fgetc(fp)) != EOF)) { + switch (ch) { + case '\r': + col = 0; + break; + case '\n': + line++; + col = 0; + break; + case '\t': + col = ((col + 1) | 0x07) + 1; + break; + case '\b': + if (col > 0) + col--; + break; + default: + col++; + } + putchar(ch); + if (col >= 80) { + col -= 80; + line++; + } + if +#ifdef CMD_CAT_MORE + ( +#endif + (line < 24) +#ifdef CMD_CAT_MORE + || (mode==CMDCAT)) +#endif + continue; + if (col > 0) + putchar('\n'); + printf("--More--"); + if (argc > 1) + printf(" (Next file: %s)", *(argv+1)?*(argv+1):"none"); + fflush(stdout); + if ((intflag) || (read(tty, buf, 1) < 0)) { + if (fp) + fclose(fp); + goto End; + } + ch = buf[0]; + if (ch == ':') { + putchar(':'); + if ((intflag) || (read(tty, buf, 1) < 0)) { + if (fp) + fclose(fp); + goto End; + } + ch = buf[0]; + } + putchar('\n'); + switch (ch) { + case 'P': + case 'p': + argc += 2; + argv -= 2; + fclose(fp); + fp = NULL; + break; + case 'N': + case 'n': + fclose(fp); + fp = NULL; + break; + case '\'': + argc++; + argv--; + fclose(fp); + fp = NULL; + break; + case 'Q': + case 'q': + fclose(fp); + goto End; + case '\n': + case '\r': + --line; + continue; + } + col = 0; + line = 1; + } + if (col > 0) putchar('\n'); + if (fp && !viastdin) + fclose(fp); + } +End: +#if 1 /* Nick */ + if (isatty(tty)) + { + state.sg_flags = raw; + stty(tty, &state); + } +#else + ioctl(tty, TTY_COOKED); +#endif + if (viastdin) close(tty); +} +#endif /* CMD_MORE / CMD_CAT_MORE */ + +void do_exit(argc, argv) + int argc; + char *argv[]; +{ + exit(argc > 1 ? atoi(argv[1]) : 0); +} + +#ifdef CMD_SET +void do_setenv(argc, argv) + int argc; + char *argv[]; +{ + int len; + char *p, **env = environ; + + if (argc == 1) { + while (*env) + printf("%s\n", *env++); + return; + } + if (argc == 2) { + len = strlen(p = argv[1]); + if (p[len-1] != '=') { + for (; *env; ++env) { + if (strlen(*env) > len && + env[0][len] == '=' && + memcmp(p, *env, len) == 0) { + printf("%s\n", &env[0][len + 1]); + break; + } + } + return; + } + p[len-1] = '\0'; + unsetenv(p); + return; + } + setenv(argv[1], argv[2], 1); +} +#endif /* CMD_SET */ + +#ifdef CMD_UMASK +void do_umask(argc, argv) + int argc; + char *argv[]; +{ + char *cp; + int mask; + + if (argc <= 1) { + mask = umask(0); + umask(mask); + printf("%03o\n", mask); + return; + } + for (mask = 0, cp = argv[1]; isoctal(*cp); ++cp) { + mask <<= 3; + mask += *cp - '0'; + } + if (*cp || (mask & ~0777)) { + fprintf(stderr, "Bad umask value\n"); + return; + } + umask(mask); +} +#endif /* CMD_UMASK */ + +#ifdef CMD_KILL +void do_kill(argc, argv) + int argc; + char *argv[]; +{ + char *cp; + int pid, sig = SIGTERM; + + if (argv[1][0] == '-') { + cp = &argv[1][1]; + if (strnicmp(cp,"SIG",3) == 0) + cp += 3; + if (stricmp(cp, "HUP") == 0) sig = SIGHUP; + else if (stricmp(cp, "INT") == 0) sig = SIGINT; + else if (stricmp(cp, "QUIT") == 0) sig = SIGQUIT; + else if (stricmp(cp, "KILL") == 0) sig = SIGKILL; + else if (stricmp(cp, "TERM") == 0) sig = SIGTERM; + else { + for (sig = 0; isdecimal(*cp); ++cp) { + sig *= 10; + sig += *cp++ - '0'; + } + if (*cp) { + fprintf(stderr, "Unknown signal\n"); + return; + } + } + argc--; + argv++; + } + while (--argc > 0) { + for (pid = 0, cp = *++argv; isdecimal(*cp); ++cp) { + pid *= 10; + pid += *cp - '0'; + } + if (*cp) { + fprintf(stderr, "Non-numeric pid\n"); + return; + } + if (kill(pid, sig) < 0) + perror(*argv); + } +} +#endif /* CMD_KILL */ + diff --git a/src/sh/sash/n.bat b/src/sh/sash/n.bat new file mode 100755 index 00000000..45efc5bf --- /dev/null +++ b/src/sh/sash/n.bat @@ -0,0 +1,14 @@ +md build-l +cd build-l +copy ..\sash-l.lnk sash.lnk +copy ..\build-l.ban n.bat +call n +cd .. + +md build-b +cd build-b +copy ..\sash-b.lnk sash.lnk +copy ..\build-b.ban n.bat +call n +cd .. + diff --git a/src/sh/sash/readme b/src/sh/sash/readme new file mode 100755 index 00000000..f0fe48ab --- /dev/null +++ b/src/sh/sash/readme @@ -0,0 +1,50 @@ +April 14, 1993 + +This is release 1.0 of sash, my stand-alone shell for Linux. + +The purpose of this program is to make replacing of shared libraries +easy and safe. It does this by firstly being linked statically, and +secondly by including many of the standard utilities within itself. +Read the sash.1 documentation for more details. + +Type "make install" to build and install the program and man page. + +David I. Bell +dbell@pdact.pd.necisa.oz.au + +--- readme.elk + +This is a slightly modified version of sash which works under ELKS. + +- Chad +----------------------------------------------------------------------- +30th April 1997 +Added config.h to configure in the various built in commands. This is +essentially so that + +a) a simple shell without builtins + +b) a medium size shell with some useful builtins, but not too much bulk + +c) a full stand alone shell with all the high level features + +can all be built from the one source tree. +Just edit config.h and comment out the #defines for the builtins you don't +want. + +8th May 1997 +Added stand_alone/ subdirectory which contains stand alone versions of +almost all the builtin commands. These can be used in association with a +sash compiled without these commands, or with any other shell. + +To install take a root disk with init and login from the elkscmd/initlogin +directory in the bin directory. Install sash as /bin/sh, and copy the +binaries from the stand-alone directory into the bin directory of the disk. + +- Alistair Riddoch +----------------------------------------------------------------------- +This is a (almost heavily) modified version of SASH that works with UZIX. +Commands and features were added and enhanced and bugs were fixed. + +Adriano Cunha + \ No newline at end of file diff --git a/src/sh/sash/sash-b.lnk b/src/sh/sash/sash-b.lnk new file mode 100755 index 00000000..e59e1b2f --- /dev/null +++ b/src/sh/sash/sash-b.lnk @@ -0,0 +1,20 @@ +-k ..\..\..\..\lib +-l libcb.lib +-l libsysb.lib +-l libiar.lib +-m +-u +-i +-o sash +-bl RCODE=0x8100 +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\..\..\lib\c0b.rel +cmds +cmd_dd +cmd_ed +cmd_grep +cmd_ls +cmd_tar +sash +utils diff --git a/src/sh/sash/sash-l.lnk b/src/sh/sash/sash-l.lnk new file mode 100755 index 00000000..4e242523 --- /dev/null +++ b/src/sh/sash/sash-l.lnk @@ -0,0 +1,18 @@ +-k ..\..\..\..\lib +-l libcl.lib +-l libsysl.lib +-l libiar.lib +-m +-u +-i +-o sash +-bl RCODE=0x8100 +..\..\..\..\lib\c0l.rel +cmds +cmd_dd +cmd_ed +cmd_grep +cmd_ls +cmd_tar +sash +utils diff --git a/src/sh/sash/sash.1 b/src/sh/sash/sash.1 new file mode 100755 index 00000000..375dfada --- /dev/null +++ b/src/sh/sash/sash.1 @@ -0,0 +1,338 @@ +.TH SASH 1 +.SH NAME +sash \- stand-alone shell with built-in commands +.SH SYNOPSYS +.B sash +.SH DESCRIPTION +The +.B sash +program is a stand-alone shell which is useful for recovering from certain +types of system failures. In particular, it was created in order to cope +with the problem of missing shared libraries. +You can also use +.B sash +to safely upgrade to new versions of the shared libraries. +.PP +.B Sash +can execute external programs, as in any shell. There are no restrictions +on these commands, as the standard shell is used to execute them if there +are any meta-characters in the command. +.PP +More importantly, however, is that many of the standard system commands +are built-in to +.BR sash . +These built-in commands are: +.PP +.NF + -chgrp, -chmod, -chown, -cmp, -cp, -dd, -echo, + -ed, -grep, -kill, -ln, -ls, -mkdir, -mknod, + -more, -mount, -mv, -printenv, -pwd, -rm, -rmdir, + -sync, -tar, -touch, -umount +.FI +.PP +These commands are generally similar to the standard programs with similar +names. However, they are simpler and cruder than the external programs, +and so many of the options are not implemented. The restrictions for each +built-in command are described later. +.PP +The built-in commands which correspond to external programs begin with a +dash character in order to distinguish them from the external programs. +So typing "ls", for example, will attempt to run the real +.B ls +program. +If "-ls" is typed, then the built-in command which mimics +.B ls +is called. +.PP +For the built-in commands, filenames are expanded so that asterisks, +question marks, and characters inside of square brackets are recognised +and are expanded. However, no other command line processing is performed. +This includes quoting of arguments, specifying of file redirection, and +the specifying of a pipeline. +.PP +If an external program is non-existant or fails to run correctly, then +the "alias" built-in command may be used to redefine the standard command +so that it automatically runs the built-in command instead. For example, +the command "alias ls -ls" redefines "ls" to run the built-in command. +This saves you the pain of having to remember to type the leading dash +all of the time. +.PP +The "help" command will list all of the built-in commands in +.B sash . +Each built-in command is described below in more detail. +.PP +.TP +.B alias [name [command]] +If +.I name +and +.I command +are provided, this defines an alias for a command +with the specified name, which executes the specified command, with +possible arguments. If just +.I name +is provided, then the definition +of the specified command alias is displayed. If nothing is provided, +then the definitions of all aliases are displayed. When defining an +alias, wildcards are not expanded. +.TP +.B cd [dirname] +If +.I dirname +is provided, then the current directory is changed to the +dirname. If +.I dirname +is absent, then the current directory is changed +to the user's home directory (value of the $HOME environment variable). +.TP +.B -chgrp gid filename ... +Change the group id for the specified list of files. The +.I gid +can +either be a group name, or a decimal value. +.TP +.B -chmod mode filename ... +Change the mode of the specified list of files. The +.I mode +argument +can only be an octal value. +.TP +.B -chown uid filename ... +Change the owner id for the specified list of files. The +.I uid +can +either be a user name, or a decimal value. +.TP +.B -cmp filename1 filename2 +Determines whether or not the specified filenames have identical data. +This says that the files are links to each other, are different sizes, +differ at a particular byte number, or are identical. +.TP +.B -cp srcname ... destname +Copies one or more files from the +.I srcname +to the +.IR destname . +If more +than one srcname is given, or if destname is a directory, then all +the srcnames are copied into the destname directory with the same +names as the srcnames. +.TP +.B -dd if=name of=name [bs=n] [count=n] [skip=n] [seek=n] +Copy data from one file to another with the specified parameters. +The +.I if +and +.I of +arguments must be provided, so stdin and stdout cannot +be specified. The +.I bs +argument is the block size, and is a numeric +value (which defaults to 512 bytes). +.I Count +is the number of blocks +to be copied (which defaults to end of file for the input file). +.I Skip +is the number of blocks to ignore before copying (seek is used +if possible, and the default is 0). +.I Seek +is the number of blocks to +seek in the output file before writing (and defaults to 0). Any of +the numeric decimal values can have one or more trailing letters +from the set 'kbw', which multiplies the value by 1024, 512, and 2 +respectively. The command reports the number of full blocks read +and written, and whether or not any partial block was read or written. +.TP +.B -echo [args] ... +Echo the arguments to the -echo command. Wildcards are expanded, so +this is convenient to get a quick list of filenames in a directory. +The output is always terminated with a newline. +.TP +.B -ed [filename] +Edit the specified file using line-mode commands. The following +.B ed +commands are provided: = c r w i a d p l s f k z and q. +Line numbers can be constants, ".", "$", "'x", +.RI / string / +and simple +arithmetic combinations of these. The substitute command and the +search expression can only use literal strings. There are some +small differences in the way that some commands behave. +.TP +.B exec filename [args] +Execute the specified program with the specified arguments. +This replaces +.B sash +completely by the executed program. +.TP +.B exit +Quit from +.BR sash . +.TP +.B -grep [-in] word filename ... +Display lines of the specified files which contain the given word. +If only one filename is given, then only the matching lines are +printed. If multiple filenames are given, then the filenames are +printed along with the matching lines. +.I Word +must be a single word, +(ie, not a regular expression). If -i is given, then case is +ignored when doing the search. If -n is given, then the line +numbers of the matching lines are also printed. +.TP +.B help +Displays a list of built-in commands. +.TP +.B -kill [-signal] pid ... +Sends the specified signal to the specified list of processes. +.I Signal +is a numberic value, or one of the special values HUP, INT, +QUIT, or KILL. +.TP +.B -ln [-s] srcname ... destname +Links one or more files from the +.I srcname +to the specified +.IR destname . +If there are +multiple srcnames, or destname is a directory, then the link is +put in the destname directory with the same name as the source name. +The default links are hard links. Using -s makes symbolic links. +For symbolic links, only one srcname can be specified. +.TP +.B -ls [-lid] filename ... +Display information about the specified filesnames, which may be +directories. The normal listing is simply a list of filenames, +one per line. The options available are -l, -i, and -d. The -l +option produces a long listing given the normal 'ls' information. +The -i option also displays the inode numbers of the files. The +-d option displays information about a directory, instead of the +files within it. +.TP +.B -mkdir dirname ... +Creates the specified directories. They are created with the +default permissions. +.TP +.B -mknod filename type major minor +Creates a special device node, either a character file or a block +file. +.I Filename +is the name of the node. +.I Type +is either 'c' or 'd'. +.I Major +is the major device number. +.I Minor +is the minor device number. +Both of these numbers are decimal. +.TP +.B -more filename ... +Type out the contents of the specified filenames, one page at a +time. For each page displayed, you can type 'n' and a return to go +to the next file, 'q' and a return to quit the command completely, +or just a return to go to the next page. +.TP +.B -mount [-t type] devname dirname +Mount a filesystem on a directory name. The -t option specifies the +type of filesystem being mounted, and defaults to "minix". +.TP +.B -mv srcname ... destname +Moves one or more files from the +.I srcname +to the +.IR destname . +If multiple srcnames are given, or if destname is a directory, then +the srcnames are copied into the destination directory with the +same names as the srcnames. Renames are attempted first, but if +this fails because of the files being on different filesystems, +then a copies and deletes are done instead. +.TP +.B -printenv [name] +If +.I name +is not given, this prints out the values of all the current +environment variables. If +.I name +is given, then only that environment variable value is printed. +.TP +.B prompt [word] ... +Sets the prompt string that is displayed before reading of a +command. A space is always added to the specified prompt. +.TP +.B -pwd +Prints the current working directory. +.TP +.B quit +Exits from +.BR sash . +.TP +.B -rm filename ... +Removes one or more files. +.TP +.B -rmdir dirname ... +Removes one or more directories. The directories must be empty +for this to be successful. +.TP +.B setenv name value +Set the value of an environment variable. +.TP +.B source filename +Execute commands which are contained in the specified filename. +.TP +.B -sync +Do a "sync" system call to force dirty blocks out to the disk. +.TP +.B -tar [xtv]f devname [filename] ... +List or restore files from a tar archive. This command can only +read tar files, not create them. The available options are xtvf. +The f option must be specified, and accepts a device or file +name argument which contains the tar archive. If no filename is +given, all files in the archive are listed or extracted. Otherwise, +only those files starting with the specified filenames are done. +Leading slashes in the tar archive filenames are removed. +.TP +.B -touch filename ... +Updates the modify times of the specifed files. If a file does not +exist, then it will be created with the default protection. +.TP +.B umask [mask] +If +.I mask +is given, sets the "umask" value used for initializing the +permissions of newly created files. If +.I mask +is not given, then the +current umask value is printed. The mask is an octal value. +.TP +.B -umount filename +Unmounts a file system. The filename can either be the device name +which is mounted, or else the directory name which the file system +is mounted onto. +.TP +.B unalias name +Remove the definition for the specified alias. +.SH WARNINGS +.B Sash +should obviously be linked statically, otherwise it's purpose is lost. +.PP +The system is still vulnerable to unrunnable shared versions of +.B init +and +.B sh. +A patch to the kernel to run +.B sash +directly instead of +.B init +if the proper keyword is given to +.B lilo +would be very useful. +.PP +Several other system commands might be necessary for system recovery, +but aren't built-in to +.BR sash . +Among these are +.B uncompress +and +.BR fsck . +.SH AUTHOR +David I. Bell diff --git a/src/sh/sash/sash.c b/src/sh/sash/sash.c new file mode 100755 index 00000000..503bd780 --- /dev/null +++ b/src/sh/sash/sash.c @@ -0,0 +1,1048 @@ +/* Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Stand-alone shell for system maintainance for Linux. + * This program should NOT be built using shared libraries. + */ + +/* Changes: + * + * 1999-2001: Adriano Cunha + * some bugfix + * added background processing ('&') + * added 'light' versions of ls/cat/more + * added option -c + * allow comments in command line ('#') + * shell scripts can't define the shell used. used environment SH + * ls_light/background process/command() bugfix + * background processes now tell their pid + * new version of 'echo' with escape sequences handling + * default prompt now is user@node$ + * if SASH is the primary shell, it executes ~/.loginrc + * added stdin/stdout redirection (>, <, >>) + * added pipe capability between two commands + * added '!!' command (repeat last command line) + */ + +#include "sash.h" +#include +#include +#include +#include +#include +#include +#include +#include /* Nick */ +#pragma warn -par + +#if defined(MSX_UZIX_TARGET) || defined(PC_UZIX_TARGET) +#define UZIX +#endif + +void do_prompt(int argc, char **argv); /* prototype added by Nick */ + +static char *version = "1.0f"; + +typedef struct { + char *name; + char *usage; + void (*func) __P((int, char **)); + unsigned char minargs; + unsigned char maxargs; +} CMDTAB; + +typedef struct { + char *name; + char *value; +} ALIAS; + +static ALIAS *aliastable; +static int aliascount; + +static FILE *sourcefiles[MAXSOURCE]; +static int sourcecount; + +static BOOL intcrlf = TRUE; +static char *prompt; + +static int stdinfd_bkp; +static int stdoutfd_bkp; + +BOOL intflag; + +BOOL _coption = FALSE; + +#ifdef UZIX +BOOL inscript = FALSE; +static FILE* scriptfd; +#define in_script inscript = TRUE +#define not_in_script inscript = FALSE +#else +#define in_script +#define not_in_script +#endif + + + +static void readfile __P((char *name)); +static void command __P((char *cmd)); +static BOOL trybuiltin __P((int argc, char **argv)); +static void runcmd __P((int argc, char **argv)); +static ALIAS *findalias __P((char *name)); +static void showprompt __P((void)); +static void catchint __P((signal_t)); +static void catchquit __P((signal_t)); +static void command2 __P((int argc, char *argv[])); +static void restoreredir __P((void)); + +static CMDTAB cmdtab[] = { +#ifdef CMD_ALIAS + "alias", "[name [command]]", do_alias, 1, MAXARGS, +#endif + "cd", "[dirname]", do_cd, 1, 2, +#ifdef CMD_CHGRP + "chgrp", "gid filename ...", do_chgrp, 3, MAXARGS, +#endif +#ifdef CMD_CAT_MORE + "cat", "filename ...", do_cat, 1, MAXARGS, +#endif +#ifdef CMD_CHMOD + "chmod", "mode filename ...", do_chmod, 3, MAXARGS, +#endif +#ifdef CMD_CHOWN + "chown", "uid filename ...", do_chown, 3, MAXARGS, +#endif +#ifdef CMD_CHROOT + "chroot", "dir", do_chroot, 2, 2, +#endif +#ifdef CMD_CMP + "cmp", "filename1 filename2", do_cmp, 3, 3, +#endif +#ifdef CMD_CP + "cp", "srcname ... destname", do_cp, 3, MAXARGS, +#endif +#ifdef CMD_DD + "dd", "if=name of=name [bs=n] [count=n] [skip=n] [seek=n]", do_dd, 3, MAXARGS, +#endif +#ifdef CMD_ECHO_LIGHT + "echo", "[-n] [args] ...", do_echo, 1, MAXARGS, +#endif +#ifdef CMD_ECHO + "echo", "[-ne] [args] ...", do_echo, 1, MAXARGS, +#endif +#ifdef CMD_ED + "ed", "[filename]", do_ed, 1, 2, +#endif +#ifdef CMD_EXEC + "exec", "filename [args]", do_exec, 2, MAXARGS, +#endif + "exit", "[status]", do_exit, 1, 2, +#ifdef CMD_GREP + "grep", "[-in] word filename ...", do_grep, 3, MAXARGS, +#endif +#ifdef CMD_HELP + "help", "", do_help, 1, MAXARGS, +#endif +#ifdef CMD_KILL + "kill", "[-sig] pid ...", do_kill, 2, MAXARGS, +#endif +#ifdef CMD_LN + "ln", "[-s] srcname ... destname", do_ln, 3, MAXARGS, +#endif + "logout", "", do_exit, 1, 1, +#ifdef CMD_LS + "ls", "[-lid] filename ...", do_ls, 1, MAXARGS, +#endif +#ifdef CMD_LS_LIGHT + "ls", "[-l] [dirname]", do_ls, 1, 3, +#endif +#ifdef CMD_MKDIR + "mkdir", "dirname ...", do_mkdir, 2, MAXARGS, +#endif +#ifdef CMD_MKNOD + "mknod", "filename type major minor", do_mknod, 5, 5, +#endif +#if defined(CMD_CAT_MORE) || defined(CMD_MORE) + "more", "filename ...", do_more, 1, MAXARGS, +#endif +#ifdef CMD_MOUNT + "mount", "[-t type] devname dirname", do_mount, 3, MAXARGS, +#endif +#ifdef CMD_MV + "mv", "srcname ... destname", do_mv, 3, MAXARGS, +#endif + "prompt", "string", do_prompt, 2, MAXARGS, +#ifdef CMD_PWD + "pwd", "", do_pwd, 1, 1, +#endif + "quit", "", do_exit, 1, 1, +#ifdef CMD_RM + "rm", "filename ...", do_rm, 2, MAXARGS, +#endif +#ifdef CMD_RMDIR + "rmdir", "dirname ...", do_rmdir, 2, MAXARGS, +#endif +#ifdef CMD_SET + "set", "[name[ value]]", do_setenv, 1, 3, +#endif +#ifdef CMD_SLEEP + "sleep", "[sec]", do_sleep, 1, 2, +#endif + "source", "filename", do_source, 2, 2, +#ifdef CMD_SYNC + "sync", "", do_sync, 1, 1, +#endif +#ifdef CMD_TAR + "tar", "[xtv]f devname filename ...", do_tar, 2, MAXARGS, +#endif +#ifdef CMD_TOUCH + "touch", "filename ...", do_touch, 2, MAXARGS, +#endif +#ifdef CMD_TRACE /* Nick */ + "trace", "{on}", do_trace, 1, 2, +#endif +#ifdef CMD_UMASK + "umask", "[mask]", do_umask, 1, 2, +#endif +#ifdef CMD_MOUNT + "umount", "filename", do_umount, 2, 2, +#endif +#ifdef CMD_ALIAS + "unalias", "name", do_unalias, 2, 2, +#endif + { NULL }, + "?", "", runcmd, 1, MAXARGS +}; + +#ifdef CMD_HELP +void do_help(argc, argv) + int argc; + char **argv; +{ + CMDTAB *cmdptr; + + for (cmdptr = cmdtab; cmdptr->name; cmdptr++) + printf("%-10s %s\n", cmdptr->name, cmdptr->usage); +} +#endif /* CMD_HELP */ + +void closefiles() { + while (--sourcecount >= 0) { + if (sourcefiles[sourcecount] != stdin +#ifdef UZIX + && ((inscript && sourcefiles[sourcecount] != scriptfd) || !inscript) +#endif + ) + fclose(sourcefiles[sourcecount]); + } +} + +void execfile(argc, argv) + int argc; + char *argv[]; +{ + int i; + + execvp(argv[0], argv); + if (errno == ESHELL) { + for (i = argc+1; i > 0; --i) + argv[i] = argv[i-1]; + argv[0] = getenv("SH"); + execvp(argv[0], argv); + } + perror(argv[0]); +} + +#ifdef CMD_TRACE /* Nick */ +void do_trace(argc, argv) + int argc; + char **argv; +{ + if (argc == 1) + systrace(0); + else systrace(atoi(argv[1])); +} +#endif + +#ifdef CMD_ALIAS +void do_alias(argc, argv) + int argc; + char **argv; +{ + char *name, *value, buf[CMDLEN]; + ALIAS *alias; + int count; + + if (argc < 2) { + count = aliascount; + for (alias = aliastable; count-- > 0; alias++) + printf("%s\t%s\n", alias->name, alias->value); + return; + } + name = argv[1]; + if (argc == 2) { + alias = findalias(name); + if (alias) + printf("%s\n", alias->value); + else fprintf(stderr, "Alias \"%s\" is not defined\n", name); + return; + } + if (strcmp(name, "alias") == 0) { + fprintf(stderr, "Cannot alias \"alias\"\n"); + return; + } + if (!makestring(argc - 2, argv + 2, buf, CMDLEN)) + return; + value = malloc(strlen(buf) + 1); + if (value == NULL) { + fprintf(stderr, "No memory for alias value\n"); + return; + } + strcpy(value, buf); + alias = findalias(name); + if (alias) { + free(alias->value); + alias->value = value; + return; + } + if ((aliascount % ALIASALLOC) == 0) { + count = aliascount + ALIASALLOC; + if (aliastable) + alias = (ALIAS *) realloc(aliastable, sizeof(ALIAS *) * count); + else alias = (ALIAS *) malloc(sizeof(ALIAS *) * count); + if (alias == NULL) { + free(value); + fprintf(stderr, "No memory for alias table\n"); + return; + } + aliastable = alias; + } + alias = &aliastable[aliascount]; + alias->name = malloc(strlen(name) + 1); + if (alias->name == NULL) { + free(value); + fprintf(stderr, "No memory for alias name\n"); + return; + } + strcpy(alias->name, name); + alias->value = value; + aliascount++; +} + +void do_unalias(argc, argv) + int argc; + char **argv; +{ + ALIAS *alias; + + while (--argc > 0) { + if ((alias = findalias(*++argv)) == NULL) + continue; + free(alias->name); + free(alias->value); + aliascount--; + alias->name = aliastable[aliascount].name; + alias->value = aliastable[aliascount].value; + } +} +#endif /* CMD_ALIAS */ + +/* + * Look up an alias name, and return a pointer to it. + * Returns NULL if the name does not exist. + */ +static ALIAS *findalias(name) + char *name; +{ + ALIAS *alias; + int count = aliascount; + + for (alias = aliastable; count-- > 0; alias++) { + if (strcmp(name, alias->name) == 0) + return alias; + } + return NULL; +} + +void do_source(argc, argv) + int argc; + char **argv; +{ + in_script; + readfile(argv[1]); + not_in_script; +} + +#ifdef CMD_EXEC +void do_exec(argc, argv) + int argc; + char **argv; +{ + char *name = argv[1]; + + if (access(name, 4)) { + perror(name); + return; + } + closefiles(); + execv(name, argv); + perror(name); + exit(1); +} +#endif + +void do_prompt(argc, argv) + int argc; /* Nick */ + char **argv; +{ + char *cp, buf[CMDLEN]; + + if (!makestring(argc - 1, argv + 1, buf, CMDLEN)) + return; + if ((cp = malloc(strlen(buf) + 2)) == NULL) { + fprintf(stderr, "No memory for prompt\n"); + return; + } + strcpy(cp, buf); + strcat(cp, " "); + if (prompt) + free(prompt); + prompt = cp; +} + +void wr1(s) + char *s; +{ + write(STDOUT, s, strlen(s)); +} + +/* + * Display the prompt string. + */ +static void showprompt() { +#if 1 /* Nick has revised this to allow prompt expansion on the fly */ + char *p, *q, *r; + struct utsname name; + char buf[PATHLEN]; + + p = prompt ? prompt : "> "; + for (q = p; *q; q++) + { + if (*q == '\\') + { + write(STDOUT, p, q-p); + p = ++q; + switch (*q) + { + case 'u': + ++p; + if ((r = getenv("USER")) == NULL) + { + wr1("someone"); + } + else + { + wr1(r); + } + break; + case 'h': + ++p; +#if 0 /* Nick */ + wr1("somehost"); +#else + if (uname(&name) == -1) + { + wr1("somehost"); + } + else + { + wr1(name.nodename); + } +#endif + break; + case 'w': + ++p; + if (getcwd(buf, PATHLEN) == NULL) + { + wr1("somewhere"); + } + else + { + wr1(buf); + } + break; + } + } + } + wr1(p); +#else + wr1(prompt ? prompt : "> "); +#endif +} + +static void catchint(t) + signal_t t; +{ + signal(SIGINT, (sig_t)catchint); /* Nick cast */ + intflag = TRUE; + if (intcrlf) + wr1("\n"); +} + +static void catchquit(t) + signal_t t; +{ + signal(SIGQUIT, (sig_t)catchquit); /* Nick cast */ + intflag = TRUE; + if (intcrlf) + wr1("\n"); +} + +#ifdef PIPECMD +static BOOL pipecmd(argc, argv) + int argc; + char *argv[]; +{ + int i, npipes = 0, pipe_fd[2], pid1, pid2, thepipe; + + for (i=0; i < argc; i++) if (!strcmp(argv[i], "|")) { + npipes++; + thepipe = i; + } + if (npipes == 0) return FALSE; + if (npipes > 1) { + printf("sh: only one pipe allowed\n"); + return TRUE; + } + if (pipe(pipe_fd) < 0) { + perror("pipe failed"); + return TRUE; + } + if ((pid1 = fork()) < 0) { + perror("fork failed"); + goto piperr; + } + if (!pid1) { + closefiles(); + close(pipe_fd[0]); /* close pipe_read, stdout */ + close(1); /* stdout = pipe_write */ + dup2(pipe_fd[1], 1); + argv[thepipe] = 0; + _coption = FALSE; + command2(thepipe, argv); + exit(1); + } + if ((pid2 = fork()) < 0) { + perror("fork failed"); + goto piperr; + } + if (!pid2) { + closefiles(); + close(pipe_fd[1]); /* close pipe_write, stdin */ + close(0); /* stdin = pipe_read */ + dup2(pipe_fd[0], 0); + for (i = thepipe+1; i < argc; i++) argv[i-thepipe-1] = argv[i]; + i = argc - thepipe - 1; + argv[i] = 0; + _coption = FALSE; + command2(i, argv); + exit(1); + } + close(pipe_fd[1]); + close(pipe_fd[0]); + for (i=0; i<2;) if ((npipes=wait(&thepipe))==pid1 || npipes==pid2) i++; +piperr: close(pipe_fd[0]); + close(pipe_fd[1]); + return TRUE; +} +#endif + +void reportchildexit(int pid, int status) { + if (status & 0x00ff) { + fprintf(stderr, "pid %d: %s (signal %d)\n", pid, + (status & 0x80) ? "core dumped" : "killed", + (status & 0x7f)); + } else { + fprintf(stderr, "pid %d: Done\n"); + } +} + +/* Setup redirection */ +int redir(argc, argv) + int *argc; + char *argv[]; +{ + int i, redirected, fd, ffd, total; + char *err; + + total = 0; + redirected = 0; + stdinfd_bkp = -1; + stdoutfd_bkp = -1; + for (i = 1; i < *argc; i++) { + if (!strcmp(argv[i],"<")) { + fd = open(argv[i+1], O_RDONLY); + ffd = fileno(stdin); + redirected = 1; + } + if (!strcmp(argv[i],">")) { + fd = creat(argv[i+1], 0666); + ffd = fileno(stdout); + redirected = 1; + } + if (!strcmp(argv[i],">>")) { + fd = open(argv[i+1], O_WRONLY|O_APPEND); + ffd = fileno(stdout); + redirected = 1; + } + if (redirected) { + if (fd < 0) { + err = argv[i+1]; + goto redirerr; + } + if (ffd == fileno(stdout)) { + stdoutfd_bkp=dup(ffd); + } + if (ffd == fileno(stdin)) { + stdinfd_bkp=dup(ffd); + } + if (dup2(fd, ffd) < 0) { + err = "redirection"; +redirerr: restoreredir(); + perror(err); + return -1; + } + close(fd); + argv[i] = 0; + argv[i+1] = 0; + total += 2; + } + redirected = 0; + } + *argc = *argc - total; + return 0; +} + +static void restoreredir() { + if (stdinfd_bkp != -1) { + close(STDIN_FILENO); + dup2(stdinfd_bkp, STDIN_FILENO); + close(stdinfd_bkp); + stdinfd_bkp = -1; + } + if (stdoutfd_bkp != -1) { + close(STDOUT_FILENO); + dup2(stdoutfd_bkp, STDOUT_FILENO); + close(stdoutfd_bkp); + stdoutfd_bkp = -1; + } +} + +/* Execute the specified command */ +static void runcmd(argc, argv) + int argc; + char *argv[]; +{ + int pid1 = 0, pid2 = 0, status = 0, bgp = 0; +#if 1 /* Nick */ + struct sgttyb state; +#endif +#if 0 + register char *cp; + BOOL magic = FALSE; + + for (cp = cmd; *cp; cp++) { + if ((*cp >= 'a') && (*cp <= 'z') || + (*cp >= 'A') && (*cp <= 'Z') || + isdecimal(*cp) || + isblank(*cp)) + continue; + if ((*cp == '.') || (*cp == '/') || (*cp == '-') || + (*cp == '+') || (*cp == '=') || (*cp == '_') || + (*cp == ':') || (*cp == ',')) + continue; + magic = TRUE; + } + if (magic) { + printf("%s: no such file or directory\n", cmd); + return; + } +#endif + /* No magic characters in the command, so do the fork and exec ourself. + * If this fails with ENOEXEC, then run the shell anyway since it might + * be a shell script. + */ + bgp = (strcmp(argv[argc-1],"&") == 0); + if (bgp) argv[--argc] = 0; + if ((pid1 = fork()) < 0) { + perror("fork failed"); + return; + } + if (pid1) { + status = 0; + intcrlf = FALSE; + if (bgp) + printf("[%d]: %s\n", pid1, argv[0]); + else { + for (;;) { + pid2 = wait(&status); + if (pid2 == pid1) break; + if (pid2 < 0) { + if (errno == EINTR) continue; + break; + } + reportchildexit(pid2, status); + } + if (status & 0x00ff) reportchildexit(pid1, status); + } + intcrlf = TRUE; +#if 1 /* Nick */ + if (isatty(STDIN_FILENO)) + { + gtty(STDIN_FILENO, &state); + state.sg_flags = XTABS|CRMOD|ECHO|COOKED; /* default */ + stty(STDIN_FILENO, &state); + } +#else + ioctl(STDIN_FILENO, TTY_COOKED); +#endif + return; + } + /* We are the child, so run the program. */ + /* First close any extra file descriptors we have opened. */ + /* UZIX maintins a global list of opened files. So we can't close + * the script file, if we are under a script. + */ + while (--sourcecount >= 0) { + if (sourcefiles[sourcecount] != stdin +#ifdef UZIX + && ((inscript && sourcefiles[sourcecount] != scriptfd) || !inscript) +#endif + ) + fclose(sourcefiles[sourcecount]); + } + /* Redirect the output and input if specified and execute application */ + if (redir(&argc, argv) == 0) execfile(argc, argv); + exit(1); +} + +/* Try to execute a built-in command. + * Returns TRUE if the command is a built in, whether or not the + * command succeeds. Returns FALSE if this is not a built-in command. + */ +static BOOL trybuiltin(argc, argv) + int argc; + char **argv; +{ + char *newargv[MAXARGS+1]; + int oac, newargc, matches, redirstat; + CMDTAB *cmdptr = cmdtab - 1; + + do { + cmdptr++; + if (cmdptr->name == NULL) { + ++cmdptr; + break; + } + } while (strcmp(argv[0], cmdptr->name)); + + /* Give a usage string if the number of arguments is + * too large or too small (or --help given). + */ + redirstat = redir(&argc, argv); + if ((argc < cmdptr->minargs) || (argc > cmdptr->maxargs) || + argc == 2 && !strcmp(argv[1], "--help") && cmdptr->func != runcmd) { + fprintf(stderr, "usage: %s %s\n", + cmdptr->name, cmdptr->usage); +builtinend: restoreredir(); + return TRUE; + } + /* Check here for several special commands which do not + * have wildcarding done for them. + */ + if ( + (cmdptr->func == do_prompt) +#ifdef CMD_ALIAS + || (cmdptr->func == do_alias) +#endif +#ifdef CMD_LS_LIGHT + || (cmdptr->func == do_ls) +#endif + ) { + if (redirstat == 0) { + (*cmdptr->func)(argc, argv); + goto builtinend; + } + return TRUE; + } + /* Now for each command argument, see if it is a wildcard, and if so, + * replace the argument with the list of matching filenames. + */ + newargv[0] = argv[0]; + newargc = 1; + for (oac = 0; ++oac < argc; ) { + if ((matches = expandwildcards(argv[oac], MAXARGS - newargc, + newargv + newargc)) < 0) + return TRUE; + if ((newargc + matches) >= MAXARGS) { + fprintf(stderr, "Too many arguments\n"); + goto builtinend; + } + if (matches == 0) + newargv[newargc++] = argv[oac]; + else newargc += matches; + } + newargv[newargc] = NULL; + if (redirstat == 0) { + (*cmdptr->func)(newargc, newargv); + goto builtinend; + } + return TRUE; +} + +/* Parse and execute one null-terminated command line string. + * This breaks the command line up into words and go execute it, + * being it a builtin command, alias or external application. + */ +static void command(cmd) + char *cmd; +{ + char **argv; + int argc; + + intflag = FALSE; + freechunks(); + while (isblank(*cmd)) + cmd++; + if ((*cmd == '\0') || !makeargs(cmd, &argc, &argv)) + return; + command2(argc, argv); +} + +/* + * This checks to see if the command is an alias, expands wildcards + * and executes the command. + */ +static void command2(argc, argv) + int argc; + char *argv[]; +{ + ALIAS *alias; + int s; + char *buf, *cmd; + + /* Search for the command in the alias table. If it is found, + * then replace the command name with the alias, and append + * any other arguments to it. + */ + if ((alias = findalias(argv[0])) != NULL) { + if ((buf = malloc(PATHLEN+1)) == NULL) { + fprintf(stderr, "No memory\n"); + return; + } + cmd = strcpy(buf, alias->value); + while (--argc > 0) { + strcat(cmd, " "); + strcat(cmd, *++argv); + } + s = makeargs(cmd, &argc, &argv); + free(buf); + if (!s) + return; + } + /* Now look for the command in the builtin table, + * and execute the command if found. + */ +#ifdef PIPECMD + if (pipecmd(argc, argv)) return; +#endif + if (trybuiltin(argc, argv)) + return; + /* Not found, run the program along the PATH list. */ + if (_coption) { + if (!access(argv[0], 4)) execvp(argv[0], argv); + perror(argv[0]); + return; + } + runcmd(argc, argv); +} + +/* Read commands from the specified file. + * A null name pointer indicates to read from stdin. + */ +static void readfile(name) + char *name; +{ + FILE *fp; + int cc, pid; + BOOL ttyflag; + /* making buf static doesn't causes stack going 512 bytes deep */ +#ifdef MSX_UZIX_TARGET + static char buf[CMDLEN]; + static char bufold[CMDLEN]; +#else + char buf[CMDLEN]; + char bufold[CMDLEN]; +#endif + + if (sourcecount >= MAXSOURCE) { + fprintf(stderr, "SASH: nesting too deep\n"); + return; + } + fp = stdin; + if (name) { + if ((fp = fopen(_findPath(name), "r")) == NULL) { + perror(name); + return; + } + } + sourcefiles[sourcecount++] = fp; +#ifdef UZIX + if (inscript) scriptfd = fp; +#endif + ttyflag = isatty(fileno(fp)); + while (TRUE) { + if (ttyflag) { + fflush(stdout); + showprompt(); + } + if (intflag && !ttyflag && (fp != stdin)) { + fclose(fp); + sourcecount--; + return; + } + memset(buf, 0, CMDLEN); + if (fgets(buf, CMDLEN - 1, fp) == NULL) { + if (ferror(fp) && (errno == EINTR)) { + clearerr(fp); + continue; + } + break; + } + cc = strlen(buf); + if (buf[cc - 1] == '\n') + cc--; + while ((cc > 0) && isblank(buf[cc - 1])) + cc--; + buf[cc] = '\0'; + if (buf[0]=='!' && buf[1]=='!') { + cc = CMDLEN - 1 - strlen(buf) + 2 - strlen(bufold); + if (cc > 0) { + strcat(bufold, &buf[2]); + strcpy(buf, bufold); + } else strcpy(buf, bufold); + } + if (buf[0] != 0) strcpy(bufold, buf); + if (buf[0] != '#') command(buf); + pid = wait(&cc); /* Nick waitpid(WAIT_ANY, &cc, WNOHANG); */ + if (pid > 0) reportchildexit(pid, cc); + } + if (ferror(fp)) { + perror("Reading command line"); + if (fp == stdin) + exit(1); + } + clearerr(fp); + if (fp != stdin) + fclose(fp); + sourcecount--; +} + +void readprofile(path, name) + char *path, *name; +{ + char *buf; + + if ((buf = malloc(PATHLEN+1)) == NULL) { + fprintf(stderr, "SASH: no memory for profile %s\n", name); + exit(1); + } + /* read profile */ + strcpy(buf, path); + if (buf[strlen(buf)-1]!='/') strcat(buf, "/"); + strcat(buf, name); + if ((access(buf, 0) == 0) || (errno != ENOENT)) { + in_script; + readfile(buf); + not_in_script; + } + free(buf); +} + +void main(argc, argv) + int argc; + char **argv; +{ + char *cp, *buf; + int i = 0; + +/* printf("silly\n"); */ +/* fflush(stdout); */ + if (argc == 1) { + printf("SASH (ver. %s)\n", version); + fflush(stdout); + } + + signal(SIGINT, (sig_t)catchint); /* Nick cast */ + signal(SIGQUIT, (sig_t)catchquit); /* Nick cast */ + + if (getenv("PATH") == NULL) + setenv("PATH", _PATH_DEFPATH, 0); + if (getenv("SH") == NULL) { + setenv("SH", _PATH_BSHELL, 0); + i = 1; + } +/* printf("silly1\n"); */ +/* fflush(stdout); */ + if ((cp = getenv("HOME")) != NULL) { + readprofile(cp, ".aliasrc"); + readprofile(cp, ".sashrc"); + } +/* printf("silly2\n"); */ +/* fflush(stdout); */ + if (strcmp(argv[1],"-c") == 0) { + if ((buf = malloc(PATHLEN+1)) == NULL) { + fprintf(stderr, "SASH: no memory for prompt\n"); + exit(1); + } + strcpy(buf, ""); + for (i = 2; i < argc; i++) { + strcat(buf, argv[i]); + strcat(buf, " "); + } + strcat(buf,"\0"); + _coption = TRUE; + command(buf); + free(buf); + exit(0); + } + if (i == 1) readprofile(cp, ".loginrc"); +#if 1 /* Nick has modified this so that the prompt is expanded on the fly */ + prompt = "\\u@\\h:\\w$ "; +#else + if ((cp = getenv("USER")) != NULL) { + struct utsname name; + + if ((buf = malloc(20)) != NULL) { + strcpy(buf, ""); + strcpy(buf, cp); + strcat(buf, "@"); + if (uname(&name) != -1) { + strcat(buf, name.nodename); + strcat(buf, "\\w$"); /* Nick */ + cp = argv[1]; + argv[1] = buf; + do_prompt (2, argv); + argv[1] = cp; + } + free(buf); + } + } +#endif +/* printf("silly3\n"); */ +/* fflush(stdout); */ + if (argc > 1) do_source(argc, argv); else readfile(NULL); + exit(0); +} + diff --git a/src/sh/sash/sash.h b/src/sh/sash/sash.h new file mode 100755 index 00000000..cf1c99f6 --- /dev/null +++ b/src/sh/sash/sash.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Definitions for stand-alone shell for system maintainance for Linux. + */ +#include +#include +#include +#include +#include +#include +#include "sashcfg.h" + +#define PATHLEN 256 +#define CMDLEN 256 /* 512 *//* 32k is too little memory... */ +#define MAXARGS 200 +#define ALIASALLOC 20 +#define STDIN 0 +#define STDOUT 1 +#define MAXSOURCE 10 + +#ifndef isblank +#define isblank(ch) (((ch) == ' ') || ((ch) == '\t')) +#endif +#define isquote(ch) (((ch) == '"') || ((ch) == '\'')) +#ifndef isdecimal +#define isdecimal(ch) (((ch) >= '0') && ((ch) <= '9')) +#endif +#ifndef isoctal +#define isoctal(ch) (((ch) >= '0') && ((ch) <= '7')) +#endif + +typedef unsigned char BOOL; + +#define FALSE ((BOOL) 0) +#define TRUE ((BOOL) 1) + +extern BOOL intflag; + +extern void do_alias(int argc, char *argv[]); +extern void do_cd(int argc, char *argv[]); +extern void do_chroot(int argc, char *argv[]); +extern void do_exec(int argc, char *argv[]); +extern void do_exit(int argc, char *argv[]); +extern void do_prompt(int argc, char *argv[]); +extern void do_source(int argc, char *argv[]); +extern void do_umask(int argc, char *argv[]); +extern void do_unalias(int argc, char *argv[]); +extern void do_help(int argc, char *argv[]); +extern void do_ln(int argc, char *argv[]); +extern void do_cp(int argc, char *argv[]); +extern void do_mv(int argc, char *argv[]); +extern void do_rm(int argc, char *argv[]); +extern void do_chmod(int argc, char *argv[]); +extern void do_mkdir(int argc, char *argv[]); +extern void do_rmdir(int argc, char *argv[]); +extern void do_mknod(int argc, char *argv[]); +extern void do_chown(int argc, char *argv[]); +extern void do_chgrp(int argc, char *argv[]); +extern void do_sync(int argc, char *argv[]); +extern void do_more(int argc, char *argv[]); +extern void do_cmp(int argc, char *argv[]); +extern void do_touch(int argc, char *argv[]); +extern void do_trace(int argc, char *argv[]); +extern void do_ls(int argc, char *argv[]); +extern void do_dd(int argc, char *argv[]); +extern void do_tar(int argc, char *argv[]); +extern void do_mount(int argc, char *argv[]); +extern void do_umount(int argc, char *argv[]); +extern void do_setenv(int argc, char *argv[]); +extern void do_pwd(int argc, char *argv[]); +extern void do_echo(int argc, char *argv[]); +extern void do_kill(int argc, char *argv[]); +extern void do_grep(int argc, char *argv[]); +extern void do_ed(int argc, char *argv[]); +extern void do_sleep(int argc, char *argv[]); + +extern void do_cat(int argc, char *argv[]); +extern void do_cat_more(int argc, char *argv[], int mode); + +extern char *modestring __P((int mode)); +extern char *timestring __P((time_t *t)); +extern BOOL isadir __P((char *name)); +extern BOOL copyfile __P((char *srcname, char *destname, BOOL setmodes)); +extern char *buildname __P((char *dirname, char *filename)); +extern int expandwildcards __P((char *name, int maxargc, char **retargv)); +extern int namesort(char **, char **); +extern BOOL match __P((char *text, char *pattern)); +extern BOOL makeargs __P((char *cmd, int *argcptr, char ***argvptr)); +extern BOOL makestring __P((int argc, char *argv[], char *buf, int buflen)); +extern char *getchunk __P((int size)); +extern void freechunks __P((void)); +extern long sizeval __P((off_t *)); + +/* END CODE */ diff --git a/src/sh/sash/sashcfg.h b/src/sh/sash/sashcfg.h new file mode 100755 index 00000000..508ab074 --- /dev/null +++ b/src/sh/sash/sashcfg.h @@ -0,0 +1,89 @@ +/* Config file for sash. + * Comment out #define for commands you do not require + */ + +/* SASH: size without any defined command: 26162 bytes (MSX) */ + +/* nice: alias, cp, echo, help, kill, ls, mkdir, more, set, + pwd, rm, rmdir */ + +/* Nick #define CMD_ALIAS /* Includes unalias. 1048 bytes; 891 bytes (HTC). --*/ +/* Nick #define CMD_CAT_MORE /* ? bytes; ? bytes (HTC) */ +/*#define CMD_CHGRP /* 2164 bytes */ +/* Nick #define CMD_CHMOD /* 260 bytes */ +/*#define CMD_CHOWN /* 2080 bytes */ +/* Nick #define CMD_CHROOT /* ? bytes; 45 bytes (HTC) --*/ +/*#define CMD_CMP /* 904 bytes */ +/*#define CMD_CP /* 1108 bytes; 1266 bytes (HTC) */ +/*#define CMD_DD /* 2524 bytes */ +#define CMD_ECHO /* 264 bytes; 208 bytes (HTC) */ +/*#define CMD_EXEC /* ? bytes; ? bytes (HTC) */ +/*#define CMD_ECHO_LIGHT/* ? bytes; ? bytes (HTC) */ +/*#define CMD_ED /* 8300 bytes */ +/*#define CMD_GREP /* 144 bytes; 971 bytes (HTC) */ +#define CMD_HELP /* 88 bytes; 66 bytes (HTC) --*/ +#define CMD_KILL /* 532 bytes; 534 bytes (HTC) */ +/*#define CMD_LN /* 716 bytes */ +/*#define CMD_LS /* 7092 bytes; 4050 bytes (HTC) */ +/* Nick #define CMD_LS_LIGHT /* ? bytes; 1208 bytes (HTC) */ +/* Nick #define CMD_MKDIR /* 140 bytes; 144 bytes (HTC) */ +/*#define CMD_MKNOD /* 516 bytes */ +/*#define CMD_MORE /* 608 bytes; 615 bytes (HTC) */ +/*#define CMD_MOUNT /* 600 bytes. Includes umount */ +/*#define CMD_MV /* 1272 bytes */ +#define CMD_SET /* 260 bytes; 325 bytes (HTC) */ +#define CMD_PWD /* 928 bytes; 781 bytes (HTC) --*/ +/* Nick #define CMD_RM /* 140 bytes; 101 bytes (HTC) */ +/*#define CMD_RMDIR /* 140 bytes; 400 bytes (HTC) */ +#define CMD_SYNC /* 80 bytes; 17 bytes (HTC) --*/ +/*#define CMD_TAR /* 5576 bytes */ +/*#define CMD_TRACE /* Nick */ +/*#define CMD_TOUCH /* 236 bytes */ +#define CMD_UMASK /* 272 bytes; 259 bytes (HTC) --*/ +#define CMD_SLEEP /* bytes; 224 bytes (HTC) --*/ + +#define PIPECMD /* enable pipe (two external commands only) */ + +#ifdef CMD_LS +#ifdef CMD_LIGHT_LS +#error CMD_LS and CMD_LIGHT_LS defined. Must be exclusive. +#endif +#endif + +#ifdef CMD_MORE +#ifdef CMD_CAT_MORE +#error CMD_MORE and CMD_CAT_MORE defined. Must be exclusive. +#endif +#endif + +#ifdef CMD_CAT_MORE +#define CMDCAT 1 +#define CMDMORE 2 +#endif + +#ifdef CMD_CP +#define FUNC_COPYFILE +#define FUNC_ISADIR +#define FUNC_BUILDNAME +#endif + +#ifdef CMD_MV +#define FUNC_COPYFILE +#define FUNC_ISADIR +#define FUNC_BUILDNAME +#endif + +#ifdef CMD_LN +#define FUNC_ISADIR +#define FUNC_BUILDNAME +#endif + +#ifdef CMD_LS +#define FUNC_MODESTRING +#define FUNC_TIMESTRING +#endif + +#ifdef CMD_TAR +#define FUNC_MODESTRING +#define FUNC_TIMESTRING +#endif diff --git a/src/sh/sash/utils.c b/src/sh/sash/utils.c new file mode 100755 index 00000000..51eba4ad --- /dev/null +++ b/src/sh/sash/utils.c @@ -0,0 +1,477 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Utility routines. + */ +#include "sash.h" + +#include +#include +#include +#include + +#define BUF_SIZE 1024 + +#define CHUNKINITSIZE 4 + +typedef struct chunk CHUNK; +struct chunk { + CHUNK *next; + char data[CHUNKINITSIZE]; /* actually of varying length */ +}; + +static CHUNK *chunklist; + +/* Allocate a chunk of memory (like malloc). + * The difference, though, is that the memory allocated is put on a + * list of chunks which can be freed all at one time. You CAN NOT free + * an individual chunk. + */ +char *getchunk(size) + int size; +{ + CHUNK *chunk; + + if (size < CHUNKINITSIZE) + size = CHUNKINITSIZE; + size += sizeof(CHUNK) - CHUNKINITSIZE; + if ((chunk = (CHUNK *)malloc(size)) == NULL) + return NULL; + chunk->next = chunklist; + chunklist = chunk; + return chunk->data; +} + +/* Free all chunks of memory that had been allocated since the last + * call to this routine. + */ +void freechunks() { + while (chunklist) { + CHUNK *chunk = chunklist; + + chunklist = chunk->next; + free((char *) chunk); + } +} + +#ifdef FUNC_MODESTRING +/* + * Return the standard ls-like mode string from a file mode. + * This is static and so is overwritten on each call. + */ +char *modestring(mode) + int mode; +{ + static char buf[12]; + strcpy(buf, "----------"); + + /* Fill in the file type. */ + if (S_ISDIR(mode)) buf[0] = 'd'; + if (S_ISCHR(mode)) buf[0] = 'c'; + if (S_ISBLK(mode)) buf[0] = 'b'; +#ifdef S_ISLNK + if (S_ISLNK(mode)) buf[0] = 'l'; +#endif + /* Now fill in the normal file permissions. */ + if (mode & S_IRUSR) buf[1] = 'r'; + if (mode & S_IWUSR) buf[2] = 'w'; + if (mode & S_IXUSR) buf[3] = 'x'; + + if (mode & S_IRGRP) buf[4] = 'r'; + if (mode & S_IWGRP) buf[5] = 'w'; + if (mode & S_IXGRP) buf[6] = 'x'; + + if (mode & S_IROTH) buf[7] = 'r'; + if (mode & S_IWOTH) buf[8] = 'w'; + if (mode & S_IXOTH) buf[9] = 'x'; + + /* Finally fill in magic stuff like suid and sticky text. */ + if (mode & S_ISUID) buf[3] = ((mode & S_IXUSR) ? 's' : 'S'); + if (mode & S_ISGID) buf[6] = ((mode & S_IXGRP) ? 's' : 'S'); + if (mode & S_ISVTX) buf[9] = ((mode & S_IXOTH) ? 't' : 'T'); + return buf; +} +#endif /* FUNC_MODESTRING */ + +#ifdef FUNC_TIMESTRING +/* + * Get the time to be used for a file. + * This is down to the minute for new files, but only the date for old files. + * The string is returned from a static buffer, and so is overwritten for + * each call. + */ +char *timestring(t) + time_t *t; +{ + time_t now; + struct tm *ttime,*tnow; + int ty, tyd; + char *str; + static char buf[26]; + + time(&now); + tnow = localtime(&now); + ty = tnow->tm_year; + tyd = tnow->tm_yday; + ttime = localtime(t); + str = ctime(t); + strcpy(buf, &str[4]); + buf[12] = '\0'; + if ((ttime->tm_year != ty) || (ttime->tm_yday > tyd)) { +/* if ((t > now) || (t < now - 365 * 24 * 60 * 60L)) {*/ + strcpy(&buf[7], &str[20]); + buf[11] = '\0'; + } + return buf; +} +#endif /* FUNC_TIMESTRING */ + +#ifdef FUNC_ISADIR +/* + * Return TRUE if a filename is a directory. + * Nonexistant files return FALSE. + */ +BOOL isadir(name) + char *name; +{ + struct stat statbuf; + + if (stat(name, &statbuf) < 0) + return FALSE; + return S_ISDIR(statbuf.st_mode); +} +#endif /* FUNC_ISADIR */ + +#ifdef FUNC_COPYFILE +/* + * Copy one file to another, while possibly preserving its modes, times, + * and modes. Returns TRUE if successful, or FALSE on a failure with an + * error message output. (Failure is not indicted if the attributes cannot + * be set.) + */ +BOOL copyfile(srcname, destname, setmodes) + char *srcname; + char *destname; + BOOL setmodes; +{ + int rfd, wfd; + int rcc, wcc; + char *bp, *buf; + struct stat statbuf1, statbuf2; + struct utimbuf times; + + if (stat(srcname, &statbuf1) < 0) { + perror(srcname); + return FALSE; + } + if (stat(destname, &statbuf2) < 0) { + statbuf2.st_ino = -1; + statbuf2.st_dev = -1; + } + if ((statbuf1.st_dev == statbuf2.st_dev) && + (statbuf1.st_ino == statbuf2.st_ino)) { + fprintf(stderr, "Copying file \"%s\" to itself\n", srcname); + return FALSE; + } + if ((rfd = open(srcname, 0)) < 0) { + perror(srcname); + return FALSE; + } + if ((wfd = creat(destname, statbuf1.st_mode)) < 0) { + perror(destname); + close(rfd); + return FALSE; + } + buf = malloc(BUF_SIZE); + while ((rcc = read(rfd, buf, BUF_SIZE)) > 0) { + if (intflag) { +Err: close(rfd); + close(wfd); + return FALSE; + } + for (bp = buf; rcc > 0; bp += wcc, rcc -= wcc) { + if ((wcc = write(wfd, bp, rcc)) < 0) { + perror(destname); + goto Err; + } + } + } + if (rcc < 0) { + perror(srcname); + goto Err; + } + close(rfd); + if (close(wfd) < 0) { + perror(destname); + return FALSE; + } + if (setmodes) { + chmod(destname, statbuf1.st_mode); + chown(destname, statbuf1.st_uid, statbuf1.st_gid); + times.actime = statbuf1.st_atime; + times.modtime = statbuf1.st_mtime; + utime(destname, ×); + } + return TRUE; +} +#endif /* FUNC_COPYFILE */ + +#ifdef FUNC_BUILDNAME +/* + * Build a path name from the specified directory name and file name. + * If the directory name is NULL, then the original filename is returned. + * The built path is in a static area, and is overwritten for each call. + */ +char *buildname(dirname, filename) + char *dirname; + char *filename; +{ + char *cp; + static char buf[PATHLEN]; + + if ((dirname == NULL) || (*dirname == '\0')) + return filename; + if ((cp = strrchr(filename, '/')) != NULL) + filename = cp + 1; + strcpy(buf, dirname); + strcat(buf, "/"); + strcat(buf, filename); + return buf; +} +#endif /* FUNC_BUILDNAME */ + +/* Sort routine for list of filenames */ +int namesort(p1, p2) + char **p1; + char **p2; +{ + return strcmp(*p1, *p2); +} + +/* Routine to see if a text string is matched by a wildcard pattern. + * Returns TRUE if the text is matched, or FALSE if it is not matched + * or if the pattern is invalid. + * * matches zero or more characters + * ? matches a single character + * [abc] matches 'a', 'b' or 'c' + * \c quotes character c + * Adapted from code written by Ingo Wilken. + */ +BOOL match(text, pattern) + char *text, *pattern; +{ + int ch; + BOOL found; + char *retrypat = NULL; + char *retrytxt = NULL; + + while (*text || *pattern) { + switch (ch = *pattern++) { + case '*': + retrypat = pattern; + retrytxt = text; + break; + + case '[': + found = FALSE; + while ((ch = *pattern++) != ']') { + if (ch == '\\') + ch = *pattern++; + if (ch == '\0') + return FALSE; + if (*text == ch) + found = TRUE; + } + if (!found) { + pattern = retrypat; + text = ++retrytxt; + } + /* fall into next case */ + case '?': + if (*text++ == '\0') + return FALSE; + break; + + case '\\': + if ((ch = *pattern++) == '\0') + return FALSE; + /* fall into next case */ + default: + if (*text == ch) { + if (*text) + text++; + break; + } + if (*text) { + pattern = retrypat; + text = ++retrytxt; + break; + } + return FALSE; + } + if (pattern == NULL) + return FALSE; + } + return TRUE; +} + +/* Expand the wildcards in a filename, if any. + * Returns an argument list with matching filenames in sorted order. + * The expanded names are stored in memory chunks which can later all + * be freed at once. Returns zero if the name is not a wildcard, or + * returns the count of matched files if the name is a wildcard and + * there was at least one match, or returns -1 if either no filenames + * matched or too many filenames matched (with an error output). + */ +int expandwildcards(name, maxargc, retargv) + char *name; + int maxargc; + char *retargv[]; +{ + DIR *dirp; + struct dirent *dp; + int dirlen, matches; + char *patt, *cp1, *cp2, *cp3, dirname[PATHLEN]; + + if ((patt = strrchr(name, '/')) != NULL) + patt++; + else patt = name; + cp1 = strchr(name, '*'); + cp2 = strchr(name, '?'); + cp3 = strchr(name, '['); + if ((cp1 == NULL) && (cp2 == NULL) && (cp3 == NULL)) + return 0; + if ((cp1 && (cp1 < patt)) || + (cp2 && (cp2 < patt)) || + (cp3 && (cp3 < patt))) { + fprintf(stderr, "Wildcards only implemented for last filename component\n"); + return -1; + } + dirname[0] = '.'; + dirname[1] = '\0'; + if (patt != name) { + memcpy(dirname, name, patt - name); + dirname[patt - name - 1] = '\0'; + if (dirname[0] == '\0') { + dirname[0] = '/'; + dirname[1] = '\0'; + } + } + if ((dirp = opendir(dirname)) == NULL) { + perror(dirname); + return -1; + } + dirlen = strlen(dirname); + if (patt == name) { + dirlen = 0; + dirname[0] = '\0'; + } + else if (dirname[dirlen - 1] != '/') { + dirname[dirlen++] = '/'; + dirname[dirlen] = '\0'; + } + matches = 0; + while ((dp = readdir(dirp)) != NULL) { + if (dp->d_name[0] == 0 || + !strcmp(dp->d_name, ".") || + !strcmp(dp->d_name, "..") || + !match(dp->d_name, patt)) + continue; + if (matches >= maxargc) { + cp1 = "Too many filename matches\n"; +Err: fprintf(stderr, cp1); + closedir(dirp); + return -1; + } + if ((cp1 = getchunk(dirlen + strlen(dp->d_name) + 1)) == NULL) { + cp1 = "No memory for filename\n"; + goto Err; + } + if (dirlen) + memcpy(cp1, dirname, dirlen); + strcpy(cp1 + dirlen, dp->d_name); + retargv[matches++] = cp1; + } + closedir(dirp); + if (matches == 0) { + fprintf(stderr, "No matches\n"); + return -1; + } + qsort((char *) retargv, matches, sizeof(char *), (cmp_func_t)namesort); + return matches; +} + +/* Take a command string, and break it up into an argc, argv list. + * The returned argument list and strings are in static memory, and so + * are overwritten on each call. The argument array is ended with an + * extra NULL pointer for convenience. Returns TRUE if successful, + * or FALSE on an error with a message already output. + */ +BOOL makeargs(cmd, argcptr, argvptr) + char *cmd; + int *argcptr; + char ***argvptr; +{ + char *cp; + int argc; + static char strings[CMDLEN + 1]; + static char *argtable[MAXARGS + 1]; + + /* Copy the command string and then break it apart + * into separate arguments. + */ + memset(strings, 0, CMDLEN); + for (argc = 0, cp = strcpy(strings, cmd); *cp; ) { + if (argc >= MAXARGS) { + fprintf(stderr, "Too many arguments\n"); + return FALSE; + } + argtable[argc++] = cp; + while (*cp && !isblank(*cp)) + cp++; + while (isblank(*cp)) + *cp++ = '\0'; + } + argtable[argc] = NULL; + *argcptr = argc; + *argvptr = argtable; + return TRUE; +} + +/* Make a NULL-terminated string out of an argc, argv pair. + * Returns TRUE if successful, or FALSE if the string is too long, + * with an error message given. This does not handle spaces within + * arguments correctly. + */ +BOOL makestring(argc, argv, buf, buflen) + int argc; + char **argv, *buf; + int buflen; +{ + while (argc-- > 0) { + int len = strlen(*argv); + + if (len >= buflen) { + fprintf(stderr, "Argument string too long\n"); + return FALSE; + } + strcpy(buf, *argv++); + buf += len; + buflen -= len; + if (argc) + *buf++ = ' '; + buflen--; + } + *buf = '\0'; + return TRUE; +} + +/* Calculate long size from off_t */ +long sizeval(p) + off_t *p; +{ + return *p; +} + \ No newline at end of file diff --git a/src/simple/adduser.c b/src/simple/adduser.c new file mode 100755 index 00000000..c6ef63dd --- /dev/null +++ b/src/simple/adduser.c @@ -0,0 +1,185 @@ +/* + * adduser.c + * author: Adriano Cunha + * description: add a new user account + * comments: heavily based on adduser 1.0 (by Craig Hagan + * and modified by Chris Cappuccio + * ) + */ + +/* to do: + * - a better way of adding a new line to passwd (using putpwent) + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PASSWD_FILE _PATH_PASSWD +#define DEFAULT_SHELL _PATH_BSHELL +#define DEFAULT_HOME _PATH_HOME +#define DEFAULT_GROUP 100 +#define FIRST 10 /* First useable UID */ +#define DEFAULT_PERMS 0755 /* Perms for the users home directory */ + +FILE *bull; /* Bullshit way to find a shadow password file */ +int unused_uid,nag; + +int find_unused(int begin) { + int trial; + struct passwd *pw; + + trial = begin - 1; + printf("\nChecking for an available UID after %d:\n",FIRST); + while ((pw = getpwuid(++trial)) != NULL) printf("%d...",trial); + if (trial!=begin) putchar('\n'); + printf("First unused UID is %d.\n", trial); + return(trial); +} + +void found_shadow() { + printf("Your system is using shadow password.\n"); + printf("Feature not supported. Program aborted.\n"); + fclose(bull); + exit(1); +} + +void main() { + char foo[64]; + char uname[9],person[32],passwd[9],dir[32],shell[32],salt[3]; + unsigned int group,uid; + int bad=0,i,correct=0; + time_t tm; + struct passwd *pw; + FILE *passwd_file; /* Yep, it's a file allright */ + + unused_uid = FIRST; + if (getuid()!=0) { + printf("You don't have access to add a new user.\n"); + printf("Only root can add new users to the system.\n"); + exit(1); + } + if ((bull=fopen("/etc/shadow","r"))!=NULL) found_shadow(); + if ((bull=fopen("/etc/passwd","r"))==NULL) { + printf("Fatal error: password file not found.\n"); + exit(1); + } + while (!correct) { /* loop until a "good" uname is chosen */ + +getlogin: + printf("\nLogin to add (^C to quit): "); + fflush(stdout); + gets(uname); + if (strlen(uname)>8) { + printf("The login name must be maximum 8 characters long.\n"); + goto getlogin; + } + for (i=0;i='A') && (uname[i]<='Z')) || + ((uname[i]>='a') && (uname[i]<='z')) || + ((uname[i]>='0') && (uname[i]<='9')))) { + printf("Invalid character in login.\n"); + goto getlogin; + } + } + if (nag=getpwnam(uname) != NULL) { + printf("Login in use. Choose another one.\n"); + goto getlogin; + } + + putchar('\n'); + unused_uid = find_unused(++unused_uid); + + printf("\nEditing information for new user [%s]:\n",uname); + printf("\nFull name: "); + fflush(stdout); + gets(person); + + printf("GID [%d]: ",DEFAULT_GROUP); + fflush(stdout); + gets(foo); + group=atoi(foo); + if (group==0) group=DEFAULT_GROUP; + + printf("UID [%d]: ",unused_uid); + fflush(stdout); + gets(foo); + uid=atoi(foo); + if (uid==0) uid=unused_uid; + if ((pw=getpwuid(uid))!=NULL) { + printf("\nWarning: UID [%d] already in use, this would conflict with\n",uid); + printf("who already owns this user ID. [%s]'s UID has been reset to\n",uname); + printf("the last unused UID: [%d].\n",unused_uid); + uid=unused_uid; + } + + fflush(stdin); + printf("Home Directory [%s/%s]: ",DEFAULT_HOME,uname); + fflush(stdout); + gets(dir); + if (!strcmp(dir,"")) sprintf(dir,"%s/%s",DEFAULT_HOME,uname); + + fflush(stdin); + printf("Shell [%s]: ",DEFAULT_SHELL); + fflush(stdout); + gets(shell); + if (!strcmp(shell,"")) sprintf(shell,"%s",DEFAULT_SHELL); + + fflush(stdin); + printf("Password [%s]: ",uname); + fflush(stdout); + gets(passwd); + if (!strcmp(passwd,"")) sprintf(passwd,"%s",uname); + time(&tm); + salt[0]=(tm.t_time & 0x0f)+'A'; + salt[1]=((tm.t_time & 0xf0) >> 4)+'a'; + salt[2]=0; + + printf("\nInformation for new user [%s]:\n",uname); + printf("Home directory: [%s]\nShell: [%s]\n",dir,shell); + printf("Password: [%s]\nUID: [%d]\nGID: [%d]\n",passwd,uid,group); + printf("\nIs this correct? [y/N]: "); + fflush(stdout); + fflush(stdin); + gets(foo); + bad=correct=(foo[0]=='y'||foo[0]=='Y'); + if (bad!=1) printf("\nUser [%s] not added.\n",uname); + } + + printf("\nAdding login [%s]...\n",uname); + strcpy(foo,PASSWD_FILE); +#if 1 /* Nick */ + strcat(foo,"~"); +#else + strcat(foo,".old"); +#endif + if ((passwd_file=fopen(foo,"w")) == NULL) { + printf("Error creating password backup file.\n"); + exit(1); + } + setpwent(); + for (i=0;(pw=getpwent())!=NULL;++i) { + if (putpwent(pw,passwd_file)==-1) { + printf("Error writing password backup file.\n"); + exit(1); + } + } + endpwent(); + fclose(passwd_file); + if (i<1) printf("Can't backup password file.\n"); + passwd_file=fopen(PASSWD_FILE,"a"); + fprintf(passwd_file,"%s:%s:%d:%d:%s:%s:%s\n" + ,uname,crypt(passwd,salt),uid,group,person,dir,shell); + fflush(passwd_file); + fclose(passwd_file); + + printf("Making directory [%s]...\n",dir); + mkdir(dir,DEFAULT_PERMS); + + chown(dir,uid,group); + printf("Done.\n"); +} diff --git a/src/simple/align.c b/src/simple/align.c new file mode 100755 index 00000000..6ce97c17 --- /dev/null +++ b/src/simple/align.c @@ -0,0 +1,129 @@ +/* align.c + * descripton: change files position on disk + * author: Archi Schekochikhin + * Adriano Cunha + * license: GNU Public License version 2 + */ + +#include /* for stdout */ +#include +#include /* for O_RDONLY */ +#include /* for XIP_ALIGN */ +#include +#include +#include +#include + +#if 0 +void wr(char *s) { + write(STDERR_FILENO, s, strlen(s)); +} + +int getint(p, p1) + char *p; + char **p1; +{ + int v = 0; + for (v = 0; *p >= '0' && *p <= '9'; ++p) { + v *= 10; + v += *p - '0'; + } + *p1=p; + return v; +} +#endif + +int main(argc, argv) + int argc; + char **argv; + { + int i, fd, er = 0, ncreate = 0, nsymlink = 0, verbose = 0; + struct utimbuf utim; + struct stat statbuf; + char *p; + time_t now, mytimet; + int errs = 0; + + if (argc < 2) + { + printf("usage: align [-c] [-s] [-v] filename ...\n"); + fflush(stdout); + return 0; + } + argc--; + argv++; + while ((argc > 0) && (**argv == '-')) + { + argc--; + p = *argv++; + while (*++p) + switch (*p) + { + case 'c': + ncreate = 1; + break; + case 's': + nsymlink = 1; + break; + case 'v': + verbose = 1; + break; + default: + printf("unknown option %s\n", p); + fflush(stdout); + return 1; + } + } + + for (i = 0; i < argc; i++) + { + er = 0; + p = argv[i]; + if (nsymlink) + { + fd = open(p, O_SYMLINK); + if (fd >= 0) + { + close(fd); + if (verbose) + { + printf("skipping symlink %s\n", p); + fflush(stdout); + } + continue; + } + } + fd = open(p, O_RDONLY); + if (fd < 0) + { + if (errno == ENOENT && ncreate == 0) + { + fd = creat(p, 0666); + } + } + if (fd < 0) + { + er = -1; + } + else + { + er = falign(fd, XIP_ALIGN); + close(fd); + } + if (er) + { + fprintf(stderr, "can't align "); + fflush(stderr); + perror(p); + errs++; + } + else if (verbose) + { + printf("align %s\n", p); + fflush(stdout); + } + } + + return errs; +} + diff --git a/src/simple/banner.c b/src/simple/banner.c new file mode 100755 index 00000000..746921d6 --- /dev/null +++ b/src/simple/banner.c @@ -0,0 +1,162 @@ +/* banner - print a banner Author: Brian Wallis */ + +/***************************************************************** + * + * SYSVbanner.c + * + * This is a PD version of the SYS V banner program (at least I think + * it is compatible to SYS V) which I wrote to use with the clock + * program written by: + ** DCF, Inc. + ** 14623 North 49th Place + ** Scottsdale, AZ 85254 + * and published in the net comp.sources.misc newsgroup in early July + * since the BSD banner program works quite differently. + * + * There is no copyright or responsibility accepted for the use + * of this software. + * + * Brian Wallis, brw@jim.odr.oz, 4 July 1988 + * + *****************************************************************/ + +#include +#include + +/* added by Nick, lifted from include/curses.h */ +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); + +char *glyphs[] = { + " @@@ @@ @@ @ @ @@@@@ @@ @@@ ", + " @@@ @@ @@ @ @ @ @ @@@ @ @ @ @@@ ", + " @@@ @ @ @@@@@@@@ @ @@ @ @@ @ ", + " @ @ @ @@@@@ @ @@@ @ ", + " @@@@@@@ @ @ @ @ @ @ ", + " @@@ @ @ @ @ @ @ @@ @ @ ", + " @@@ @ @ @@@@@ @ @@ @@@@ @ ", + + " @@ @@ @", + " @ @ @ @ @ @ ", + " @ @ @ @ @ @ ", + " @ @ @@@@@@@ @@@@@ @@@ @@@@@ @ ", + " @ @ @ @ @ @@@ @ ", + " @ @ @ @ @ @ @@@ @ ", + " @@ @@ @ @@@ @ ", + + " @@@ @ @@@@@ @@@@@ @ @@@@@@@ @@@@@ @@@@@@@", + " @ @ @@ @ @@ @@ @ @ @ @@ @ ", + "@ @ @ @ @ @ @@ @ @ @ @ ", + "@ @ @ @ @@@@@ @@@@@ @@@@@@@ @@@@@ @@@@@@ @ ", + "@ @ @ @ @ @ @ @@ @ @ ", + " @ @ @ @ @ @ @ @ @@ @ @ ", + " @@@ @@@@@ @@@@@@@ @@@@@ @ @@@@@ @@@@@ @ ", + + " @@@@@ @@@@@ @@@ @ @ @@@@@ ", + "@ @@ @ @@@ @@@ @ @ @ @", + "@ @@ @ @@@ @ @@@@@ @ @", + " @@@@@ @@@@@@ @@@ @ @ @@ ", + "@ @ @ @@@ @ @@@@@ @ @ ", + "@ @@ @ @@@ @ @ @ ", + " @@@@@ @@@@@ @@@ @ @ @ @ ", + + " @@@@@ @ @@@@@@ @@@@@ @@@@@@ @@@@@@@@@@@@@@ @@@@@ ", + "@ @ @ @ @ @@ @@ @@ @ @ @", + "@ @@@ @ @ @ @ @@ @ @@ @ @ ", + "@ @ @ @@ @@@@@@@ @ @ @@@@@@ @@@@@ @ @@@@", + "@ @@@@ @@@@@@@@ @@ @ @@ @ @ @", + "@ @@ @@ @@ @@ @@ @ @ @", + " @@@@@ @ @@@@@@@ @@@@@ @@@@@@ @@@@@@@@ @@@@@ ", + + "@ @ @*@ @@ @ @ @ @@ @@@@@@@@", + "@ @ @ @@ @ @ @@ @@@@ @@ @", + "@ @ @ @@ @ @ @ @ @ @@ @ @@ @", + "@@@@@@@ @ @@@@ @ @ @ @@ @ @@ @", + "@ @ @ @ @@ @ @ @ @@ @ @@ @", + "@ @ @ @ @@ @ @ @ @@ @@@ @", + "@ @ @@@ @@@@@ @ @ @@@@@@@@ @@ @@@@@@@@", + + "@@@@@@ @@@@@ @@@@@@ @@@@@ @@@@@@@@ @@ @@ @", + "@ @@ @@ @@ @ @ @ @@ @@ @ @", + "@ @@ @@ @@ @ @ @@ @@ @ @", + "@@@@@@ @ @@@@@@@ @@@@@ @ @ @@ @@ @ @", + "@ @ @ @@ @ @ @ @ @ @ @ @ @ @", + "@ @ @ @ @ @ @ @ @ @ @ @ @ @ @", + "@ @@@@ @@ @ @@@@@ @ @@@@@ @ @@ @@ ", + + "@ @@ @@@@@@@@ @@@@@ @ @@@@@ @ ", + " @ @ @ @ @ @ @ @ @ @ ", + " @ @ @ @ @ @ @ @ @ @ ", + " @ @ @ @ @ @ ", + " @ @ @ @ @ @ @ ", + " @ @ @ @ @ @ @ ", + "@ @ @ @@@@@@@ @@@@@ @ @@@@@ @@@@@@@", + + " @@@ ", + " @@@ @@ @@@@@ @@@@ @@@@@ @@@@@@ @@@@@@ @@@@ ", + " @ @ @ @ @ @ @ @ @ @ @ @ @", + " @ @ @ @@@@@ @ @ @ @@@@@ @@@@@ @ ", + " @@@@@@ @ @ @ @ @ @ @ @ @@@", + " @ @ @ @ @ @ @ @ @ @ @ @", + " @ @ @@@@@ @@@@ @@@@@ @@@@@@ @ @@@@ ", + + " ", + " @ @ @ @ @ @ @ @ @ @ @ @@@@ ", + " @ @ @ @ @ @ @ @@ @@ @@ @ @ @", + " @@@@@@ @ @ @@@@ @ @ @@ @ @ @ @ @ @", + " @ @ @ @ @ @ @ @ @ @ @ @ @ @", + " @ @ @ @ @ @ @ @ @ @ @ @@ @ @", + " @ @ @ @@@@ @ @ @@@@@@ @ @ @ @ @@@@ ", + + " ", + " @@@@@ @@@@ @@@@@ @@@@ @@@@@ @ @ @ @ @ @", + " @ @ @ @ @ @ @ @ @ @ @ @ @ @", + " @ @ @ @ @ @ @@@@ @ @ @ @ @ @ @", + " @@@@@ @ @ @ @@@@@ @ @ @ @ @ @ @ @@ @", + " @ @ @ @ @ @ @ @ @ @ @ @ @@ @@", + " @ @@@ @ @ @ @@@@ @ @@@@ @@ @ @", + + " @@@ @ @@@ @@ @ @ @ @", + " @ @ @ @ @@@@@@ @ @ @ @ @ @ @ @ @ ", + " @ @ @ @ @ @ @ @ @@ @ @ @ @", + " @@ @ @ @@ @@ @ @ @ ", + " @@ @ @ @ @ @ @ @ @ @", + " @ @ @ @ @ @ @ @ @ @ ", + " @ @ @ @@@@@@ @@@ @ @@@ @ @ @ @" +}; + +int main(argc, argv) +int argc; +char *argv[]; +{ + int a, b, c, len, ind; + char line[80]; + + if (argc < 2) { + printf("usage: banner string ...\n"); + return(0); + } + for (argv++; --argc; argv++) { + len = strlen(*argv); + if (len > 10) len = 10; + for (a = 0; a < 7; a++) { + for (b = 0; b < len; b++) { + if ((ind = (*argv)[b] - ' ') < 0) ind = 0; + for (c = 0; c < 7; c++) { + line[b * 8 + c] = glyphs[(ind / 8 * 7) + a][(ind % 8 * 7) + c] == '@' ? ind + ' ' : ' '; + } + line[b * 8 + 7] = ' '; + } + for (b = len * 8 - 1; b >= 0; b--) { + if (line[b] != ' ') break; + line[b] = '\0'; + } + printf("%s\n", line); + } + printf("\n"); + } + return(0); +} diff --git a/src/simple/basename.c b/src/simple/basename.c new file mode 100755 index 00000000..410420ac --- /dev/null +++ b/src/simple/basename.c @@ -0,0 +1,55 @@ +/* basename.c + */ +#include +#include + +static void remove_suffix(name, suffix) + register char *name, *suffix; +{ + register char *np = name + strlen(name); + register char *sp = suffix + strlen(suffix); + + while (np > name && sp > suffix) { + if (*--np != *--sp) + return; + } + if (np > name) + *np = '\0'; +} + +char *basename(name) + char *name; +{ + char *base = rindex(name, '/'); + + return base ? base + 1 : name; +} + +void strip_trailing_slashes (path) + char *path; +{ + char *last = path + strlen(path) - 1; + + while (last > path && *last == '/') + *last-- = '\0'; +} + +int main(argc, argv) + int argc; + char **argv; +{ + char *line; + + if (argc == 2 || argc == 3) { + strip_trailing_slashes(argv[1]); + line = basename(argv[1]); + if (argc == 3) + remove_suffix(line, argv[2]); + write(STDOUT_FILENO, line, strlen(line)); + write(STDOUT_FILENO,"\n",1); + return 0; + } else { + write(STDOUT_FILENO, "usage: basename name [suffix]\n",30); + return 1; + } +} diff --git a/src/simple/bogomips.c b/src/simple/bogomips.c new file mode 100755 index 00000000..c5a8565e --- /dev/null +++ b/src/simple/bogomips.c @@ -0,0 +1,147 @@ +/* + * Standalone BogoMips program + * + * Based on code Linux kernel code in init/main.c and + * include/linux/delay.h + * + * For more information on interpreting the results, see the BogoMIPS + * Mini-HOWTO document. + * + * version: 1.3 + * author: Jeff Tranter (Jeff_Tranter@Mitel.COM) + * + * Modified: jun/99, by Adriano Cunha + * added MSXDOS_BOGOMIPS and HIGH_PRECISION compiling options + * + * What is the idea for calculating BogoMIPS? + * Check, in one second of processing, how many loops your machine can + * execute. + */ + +#include +#include + +#ifdef CLASSIC_BOGOMIPS +/* the original code from the Linux kernel */ +static __inline__ void delay(int loops) +{ + __asm__(".align 2,0x90\n1:\tdecl %0\n\tjns 1b": :"a" (loops):"ax"); +} +#endif + +#ifdef QNX_BOGOMIPS +/* version for QNX C compiler */ +void delay(int loops); +#pragma aux delay = \ + "l1:" \ + "dec eax" \ + "jns l1" \ + parm nomemory [eax] modify exact nomemory [eax]; +#endif + +#ifdef PORTABLE_BOGOMIPS +/* portable version */ +static void delay(unsigned long loops) +{ + long i; + for (i = loops; i >= 0 ; i--) + ; +} +#endif + +#ifdef MSXDOS_BOGOMIPS +static long htimi1; +static char htimi2; +static unsigned char clocks_per_sec; + +#ifdef CLOCKS_PER_SEC +#undef CLOCKS_PER_SEC +#endif +#ifdef clock() +#undef clock() +#endif + +#define CLOCK_ADDR 0xf975 +#define clock() *(uchar *)CLOCK_ADDR +#define CLOCKS_PER_SEC clocks_per_sec + +void init_clock_count() +{ +#asm + global _clocks_per_sec + ld a,(0FCC1h) + ld hl,2Bh + call 000Ch + ld (_clocks_per_sec),a +#endasm + if ((clocks_per_sec & 0x80) == 0) clocks_per_sec = 60; + else clocks_per_sec = 50; + htimi1=*(long *)0xfd9a; + htimi2=*(char *)0xfd9e; + asm("di"); + *(uchar *)0xfd9a=0x21; + *(uint *)0xfd9b=CLOCK_ADDR; + *(uchar *)0xfd9d=0x34; + *(uchar *)0xfd9e=0xc9; + asm("ei"); +} + +void end_clock_count() +{ + asm("di"); + *(long *)0xfd9a=htimi1; + *(char *)0xfd9e=htimi2; + asm("ei"); +} +#endif + +int +main(void) +{ + unsigned long loops_per_sec = 1; + unsigned long ticks; + +#ifdef MSXDOS_BOGOMIPS + init_clock_count(); +#endif + + printf("Calibrating delay loop.. "); + fflush(stdout); + + while ((loops_per_sec <<= 1)) { + /* this loops until we have waste one second of more of processing + doing a certain number of loops */ +#ifdef MSXDOS_BOGOMIPS + ticks = 0; + clock() = 0; +#else + ticks = clock(); +#endif + delay(loops_per_sec); + ticks = clock() - ticks; + if (ticks >= CLOCKS_PER_SEC) { +#ifdef MSXDOS_BOGOMIPS + end_clock_count(); +#endif + loops_per_sec = (loops_per_sec / ticks) * CLOCKS_PER_SEC; +#ifdef HIGH_PRECISION + printf("ok - %lu.%02lu%02lu BogoMips\n", + loops_per_sec/500000, + (loops_per_sec/5000) % 100, + (loops_per_sec/50) % 100 + ); +#else + printf("ok - %lu.%02lu BogoMips\n", + loops_per_sec/500000, + (loops_per_sec/5000) % 100 + ); +#endif + return 0; + } + } +#ifdef MSXDOS_BOGOMIPS + end_clock_count(); +#endif + printf("failed\n"); + return -1; +} diff --git a/src/simple/build-b.ban b/src/simple/build-b.ban new file mode 100755 index 00000000..9675ef8a --- /dev/null +++ b/src/simple/build-b.ban @@ -0,0 +1,1042 @@ +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\adduser +@if errorlevel 1 goto failure +del adduser.r01 +as-z80 -l -o adduser.s01 +@if errorlevel 1 goto failure + +link-z80 -f adduser +@if errorlevel 1 goto failure +ihex2bin -l adduser.i86 ..\..\..\bin\banked\adduser +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\align +@if errorlevel 1 goto failure +del align.r01 +as-z80 -l -o align.s01 +@if errorlevel 1 goto failure + +link-z80 -f align +@if errorlevel 1 goto failure +ihex2bin -l align.i86 ..\..\..\bin\banked\align +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\banner +@if errorlevel 1 goto failure +del banner.r01 +as-z80 -l -o banner.s01 +@if errorlevel 1 goto failure + +link-z80 -f banner +@if errorlevel 1 goto failure +ihex2bin -l banner.i86 ..\..\..\bin\banked\banner +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\basename +@if errorlevel 1 goto failure +del basename.r01 +as-z80 -l -o basename.s01 +@if errorlevel 1 goto failure + +link-z80 -f basename +@if errorlevel 1 goto failure +ihex2bin -l basename.i86 ..\..\..\bin\banked\basename +@if errorlevel 1 goto failure + +rem bogomips doesn't work under tc because too much use of z80 inline assembler +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\bogomips +rem @if errorlevel 1 goto failure +rem del bogomips.r01 +rem as-z80 -l -o bogomips.s01 +rem @if errorlevel 1 goto failure + +rem link-z80 -f bogomips +rem @if errorlevel 1 goto failure +rem ihex2bin -l bogomips.i86 ..\..\..\bin\banked\bogomips +rem @if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cal +@if errorlevel 1 goto failure +del cal.r01 +as-z80 -l -o cal.s01 +@if errorlevel 1 goto failure + +link-z80 -f cal +@if errorlevel 1 goto failure +ihex2bin -l cal.i86 ..\..\..\bin\banked\cal +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cat +@if errorlevel 1 goto failure +del cat.r01 +as-z80 -l -o cat.s01 +@if errorlevel 1 goto failure + +link-z80 -f cat +@if errorlevel 1 goto failure +ihex2bin -l cat.i86 ..\..\..\bin\banked\cat +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cdiff +@if errorlevel 1 goto failure +del cdiff.r01 +as-z80 -l -o cdiff.s01 +@if errorlevel 1 goto failure + +link-z80 -f cdiff +@if errorlevel 1 goto failure +ihex2bin -l cdiff.i86 ..\..\..\bin\banked\cdiff +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cgrep +@if errorlevel 1 goto failure +del cgrep.r01 +as-z80 -l -o cgrep.s01 +@if errorlevel 1 goto failure + +link-z80 -f cgrep +@if errorlevel 1 goto failure +ihex2bin -l cgrep.i86 ..\..\..\bin\banked\cgrep +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chgrp +@if errorlevel 1 goto failure +del chgrp.r01 +as-z80 -l -o chgrp.s01 +@if errorlevel 1 goto failure + +link-z80 -f chgrp +@if errorlevel 1 goto failure +ihex2bin -l chgrp.i86 ..\..\..\bin\banked\chgrp +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chmod +@if errorlevel 1 goto failure +del chmod.r01 +as-z80 -l -o chmod.s01 +@if errorlevel 1 goto failure + +link-z80 -f chmod +@if errorlevel 1 goto failure +ihex2bin -l chmod.i86 ..\..\..\bin\banked\chmod +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chown +@if errorlevel 1 goto failure +del chown.r01 +as-z80 -l -o chown.s01 +@if errorlevel 1 goto failure + +link-z80 -f chown +@if errorlevel 1 goto failure +ihex2bin -l chown.i86 ..\..\..\bin\banked\chown +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cksum +@if errorlevel 1 goto failure +del cksum.r01 +as-z80 -l -o cksum.s01 +@if errorlevel 1 goto failure + +link-z80 -f cksum +@if errorlevel 1 goto failure +ihex2bin -l cksum.i86 ..\..\..\bin\banked\cksum +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cmp +@if errorlevel 1 goto failure +del cmp.r01 +as-z80 -l -o cmp.s01 +@if errorlevel 1 goto failure + +link-z80 -f cmp +@if errorlevel 1 goto failure +ihex2bin -l cmp.i86 ..\..\..\bin\banked\cmp +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cp +@if errorlevel 1 goto failure +del cp.r01 +as-z80 -l -o cp.s01 +@if errorlevel 1 goto failure + +link-z80 -f cp +@if errorlevel 1 goto failure +ihex2bin -l cp.i86 ..\..\..\bin\banked\cp +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cr +@if errorlevel 1 goto failure +del cr.r01 +as-z80 -l -o cr.s01 +@if errorlevel 1 goto failure + +link-z80 -f cr +@if errorlevel 1 goto failure +ihex2bin -l cr.i86 ..\..\..\bin\banked\cr +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\crc +@if errorlevel 1 goto failure +del crc.r01 +as-z80 -l -o crc.s01 +@if errorlevel 1 goto failure + +link-z80 -f crc +@if errorlevel 1 goto failure +ihex2bin -l crc.i86 ..\..\..\bin\banked\crc +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cron +@if errorlevel 1 goto failure +del cron.r01 +as-z80 -l -o cron.s01 +@if errorlevel 1 goto failure + +link-z80 -f cron +@if errorlevel 1 goto failure +ihex2bin -l cron.i86 ..\..\..\bin\banked\cron +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\date +@if errorlevel 1 goto failure +del date.r01 +as-z80 -l -o date.s01 +@if errorlevel 1 goto failure + +link-z80 -f date +@if errorlevel 1 goto failure +ihex2bin -l date.i86 ..\..\..\bin\banked\date +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dd +@if errorlevel 1 goto failure +del dd.r01 +as-z80 -l -o dd.s01 +@if errorlevel 1 goto failure + +link-z80 -f dd +@if errorlevel 1 goto failure +ihex2bin -l dd.i86 ..\..\..\bin\banked\dd +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\df +@if errorlevel 1 goto failure +del df.r01 +as-z80 -l -o df.s01 +@if errorlevel 1 goto failure + +link-z80 -f df +@if errorlevel 1 goto failure +ihex2bin -l df.i86 ..\..\..\bin\banked\df +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dhry +@if errorlevel 1 goto failure +del dhry.r01 +as-z80 -l -o dhry.s01 +@if errorlevel 1 goto failure + +link-z80 -f dhry +@if errorlevel 1 goto failure +ihex2bin -l dhry.i86 ..\..\..\bin\banked\dhry +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\diff +@if errorlevel 1 goto failure +del diff.r01 +as-z80 -l -o diff.s01 +@if errorlevel 1 goto failure + +link-z80 -f diff +@if errorlevel 1 goto failure +ihex2bin -l diff.i86 ..\..\..\bin\banked\diff +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dirname +@if errorlevel 1 goto failure +del dirname.r01 +as-z80 -l -o dirname.s01 +@if errorlevel 1 goto failure + +link-z80 -f dirname +@if errorlevel 1 goto failure +ihex2bin -l dirname.i86 ..\..\..\bin\banked\dirname +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\diskusag +@if errorlevel 1 goto failure +del diskusag.r01 +as-z80 -l -o diskusag.s01 +@if errorlevel 1 goto failure + +link-z80 -f diskusag +@if errorlevel 1 goto failure +ihex2bin -l diskusag.i86 ..\..\..\bin\banked\diskusag +@if errorlevel 1 goto failure + +rem dosread is not necessary for the hytech system (no floppy drive) +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dosread +rem @if errorlevel 1 goto failure +rem del dosread.r01 +rem as-z80 -l -o dosread.s01 +rem @if errorlevel 1 goto failure + +rem link-z80 -f dosread +rem @if errorlevel 1 goto failure +rem ihex2bin -l dosread.i86 ..\..\..\bin\banked\dosread +rem @if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dtree +@if errorlevel 1 goto failure +del dtree.r01 +as-z80 -l -o dtree.s01 +@if errorlevel 1 goto failure + +link-z80 -f dtree +@if errorlevel 1 goto failure +ihex2bin -l dtree.i86 ..\..\..\bin\banked\dtree +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\du +@if errorlevel 1 goto failure +del du.r01 +as-z80 -l -o du.s01 +@if errorlevel 1 goto failure + +link-z80 -f du +@if errorlevel 1 goto failure +ihex2bin -l du.i86 ..\..\..\bin\banked\du +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\echo +@if errorlevel 1 goto failure +del echo.r01 +as-z80 -l -o echo.s01 +@if errorlevel 1 goto failure + +link-z80 -f echo +@if errorlevel 1 goto failure +ihex2bin -l echo.i86 ..\..\..\bin\banked\echo +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ed +@if errorlevel 1 goto failure +del ed.r01 +as-z80 -l -o ed.s01 +@if errorlevel 1 goto failure + +link-z80 -f ed +@if errorlevel 1 goto failure +ihex2bin -l ed.i86 ..\..\..\bin\banked\ed +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\expr +@if errorlevel 1 goto failure +del expr.r01 +as-z80 -l -o expr.s01 +@if errorlevel 1 goto failure + +link-z80 -f expr +@if errorlevel 1 goto failure +ihex2bin -l expr.i86 ..\..\..\bin\banked\expr +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\false +@if errorlevel 1 goto failure +del false.r01 +as-z80 -l -o false.s01 +@if errorlevel 1 goto failure + +link-z80 -f false +@if errorlevel 1 goto failure +ihex2bin -l false.i86 ..\..\..\bin\banked\false +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fgrep +@if errorlevel 1 goto failure +del fgrep.r01 +as-z80 -l -o fgrep.s01 +@if errorlevel 1 goto failure + +link-z80 -f fgrep +@if errorlevel 1 goto failure +ihex2bin -l fgrep.i86 ..\..\..\bin\banked\fgrep +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\file +@if errorlevel 1 goto failure +del file.r01 +as-z80 -l -o file.s01 +@if errorlevel 1 goto failure + +link-z80 -f file +@if errorlevel 1 goto failure +ihex2bin -l file.i86 ..\..\..\bin\banked\file +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\find +@if errorlevel 1 goto failure +del find.r01 +as-z80 -l -o find.s01 +@if errorlevel 1 goto failure + +link-z80 -f find +@if errorlevel 1 goto failure +ihex2bin -l find.i86 ..\..\..\bin\banked\find +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fld +@if errorlevel 1 goto failure +del fld.r01 +as-z80 -l -o fld.s01 +@if errorlevel 1 goto failure + +link-z80 -f fld +@if errorlevel 1 goto failure +ihex2bin -l fld.i86 ..\..\..\bin\banked\fld +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fortune +@if errorlevel 1 goto failure +del fortune.r01 +as-z80 -l -o fortune.s01 +@if errorlevel 1 goto failure + +link-z80 -f fortune +@if errorlevel 1 goto failure +ihex2bin -l fortune.i86 ..\..\..\bin\banked\fortune +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\grep +@if errorlevel 1 goto failure +del grep.r01 +as-z80 -l -o grep.s01 +@if errorlevel 1 goto failure + +link-z80 -f grep +@if errorlevel 1 goto failure +ihex2bin -l grep.i86 ..\..\..\bin\banked\grep +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\gres +@if errorlevel 1 goto failure +del gres.r01 +as-z80 -l -o gres.s01 +@if errorlevel 1 goto failure + +link-z80 -f gres +@if errorlevel 1 goto failure +ihex2bin -l gres.i86 ..\..\..\bin\banked\gres +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\head +@if errorlevel 1 goto failure +del head.r01 +as-z80 -l -o head.s01 +@if errorlevel 1 goto failure + +link-z80 -f head +@if errorlevel 1 goto failure +ihex2bin -l head.i86 ..\..\..\bin\banked\head +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\id +@if errorlevel 1 goto failure +del id.r01 +as-z80 -l -o id.s01 +@if errorlevel 1 goto failure + +link-z80 -f id +@if errorlevel 1 goto failure +ihex2bin -l id.i86 ..\..\..\bin\banked\id +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\inodes +@if errorlevel 1 goto failure +del inodes.r01 +as-z80 -l -o inodes.s01 +@if errorlevel 1 goto failure + +link-z80 -f inodes +@if errorlevel 1 goto failure +ihex2bin -l inodes.i86 ..\..\..\bin\banked\inodes +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\kill +@if errorlevel 1 goto failure +del kill.r01 +as-z80 -l -o kill.s01 +@if errorlevel 1 goto failure + +link-z80 -f kill +@if errorlevel 1 goto failure +ihex2bin -l kill.i86 ..\..\..\bin\banked\kill +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\lpd +@if errorlevel 1 goto failure +del lpd.r01 +as-z80 -l -o lpd.s01 +@if errorlevel 1 goto failure + +link-z80 -f lpd +@if errorlevel 1 goto failure +ihex2bin -l lpd.i86 ..\..\..\bin\banked\lpd +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\lpr +@if errorlevel 1 goto failure +del lpr.r01 +as-z80 -l -o lpr.s01 +@if errorlevel 1 goto failure + +link-z80 -f lpr +@if errorlevel 1 goto failure +ihex2bin -l lpr.i86 ..\..\..\bin\banked\lpr +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ls +@if errorlevel 1 goto failure +del ls.r01 +as-z80 -l -o ls.s01 +@if errorlevel 1 goto failure + +link-z80 -f ls +@if errorlevel 1 goto failure +ihex2bin -l ls.i86 ..\..\..\bin\banked\ls +@if errorlevel 1 goto failure + +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\man +rem @if errorlevel 1 goto failure +rem del man.r01 +rem as-z80 -l -o man.s01 +rem @if errorlevel 1 goto failure + +rem link-z80 -f man +rem @if errorlevel 1 goto failure +rem ihex2bin -l man.i86 ..\..\..\bin\banked\man +rem @if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mkdir +@if errorlevel 1 goto failure +del mkdir.r01 +as-z80 -l -o mkdir.s01 +@if errorlevel 1 goto failure + +link-z80 -f mkdir +@if errorlevel 1 goto failure +ihex2bin -l mkdir.i86 ..\..\..\bin\banked\mkdir +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mknod +@if errorlevel 1 goto failure +del mknod.r01 +as-z80 -l -o mknod.s01 +@if errorlevel 1 goto failure + +link-z80 -f mknod +@if errorlevel 1 goto failure +ihex2bin -l mknod.i86 ..\..\..\bin\banked\mknod +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\more +@if errorlevel 1 goto failure +del more.r01 +as-z80 -l -o more.s01 +@if errorlevel 1 goto failure + +link-z80 -f more +@if errorlevel 1 goto failure +ihex2bin -l more.i86 ..\..\..\bin\banked\more +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mount +@if errorlevel 1 goto failure +del mount.r01 +as-z80 -l -o mount.s01 +@if errorlevel 1 goto failure + +link-z80 -f mount +@if errorlevel 1 goto failure +ihex2bin -l mount.i86 ..\..\..\bin\banked\mount +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ncheck +@if errorlevel 1 goto failure +del ncheck.r01 +as-z80 -l -o ncheck.s01 +@if errorlevel 1 goto failure + +link-z80 -f ncheck +@if errorlevel 1 goto failure +ihex2bin -l ncheck.i86 ..\..\..\bin\banked\ncheck +@if errorlevel 1 goto failure + +rem iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ncr +rem @if errorlevel 1 goto failure +rem del ncr.r01 +rem as-z80 -l -o ncr.s01 +rem @if errorlevel 1 goto failure + +rem link-z80 -f ncr +rem @if errorlevel 1 goto failure +rem ihex2bin -l ncr.i86 ..\..\..\bin\banked\ncr +rem @if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\od +@if errorlevel 1 goto failure +del od.r01 +as-z80 -l -o od.s01 +@if errorlevel 1 goto failure + +link-z80 -f od +@if errorlevel 1 goto failure +ihex2bin -l od.i86 ..\..\..\bin\banked\od +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\passwd +@if errorlevel 1 goto failure +del passwd.r01 +as-z80 -l -o passwd.s01 +@if errorlevel 1 goto failure + +link-z80 -f passwd +@if errorlevel 1 goto failure +ihex2bin -l passwd.i86 ..\..\..\bin\banked\passwd +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pathchk +@if errorlevel 1 goto failure +del pathchk.r01 +as-z80 -l -o pathchk.s01 +@if errorlevel 1 goto failure + +link-z80 -f pathchk +@if errorlevel 1 goto failure +ihex2bin -l pathchk.i86 ..\..\..\bin\banked\pathchk +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pr +@if errorlevel 1 goto failure +del pr.r01 +as-z80 -l -o pr.s01 +@if errorlevel 1 goto failure + +link-z80 -f pr +@if errorlevel 1 goto failure +ihex2bin -l pr.i86 ..\..\..\bin\banked\pr +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\printenv +@if errorlevel 1 goto failure +del printenv.r01 +as-z80 -l -o printenv.s01 +@if errorlevel 1 goto failure + +link-z80 -f printenv +@if errorlevel 1 goto failure +ihex2bin -l printenv.i86 ..\..\..\bin\banked\printenv +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ps +@if errorlevel 1 goto failure +del ps.r01 +as-z80 -l -o ps.s01 +@if errorlevel 1 goto failure + +link-z80 -f ps +@if errorlevel 1 goto failure +ihex2bin -l ps.i86 ..\..\..\bin\banked\ps +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pwd +@if errorlevel 1 goto failure +del pwd.r01 +as-z80 -l -o pwd.s01 +@if errorlevel 1 goto failure + +link-z80 -f pwd +@if errorlevel 1 goto failure +ihex2bin -l pwd.i86 ..\..\..\bin\banked\pwd +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\readall +@if errorlevel 1 goto failure +del readall.r01 +as-z80 -l -o readall.s01 +@if errorlevel 1 goto failure + +link-z80 -f readall +@if errorlevel 1 goto failure +ihex2bin -l readall.i86 ..\..\..\bin\banked\readall +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\reboot +@if errorlevel 1 goto failure +del reboot.r01 +as-z80 -l -o reboot.s01 +@if errorlevel 1 goto failure + +link-z80 -f reboot +@if errorlevel 1 goto failure +ihex2bin -l reboot.i86 ..\..\..\bin\banked\reboot +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\renice +@if errorlevel 1 goto failure +del renice.r01 +as-z80 -l -o renice.s01 +@if errorlevel 1 goto failure + +link-z80 -f renice +@if errorlevel 1 goto failure +ihex2bin -l renice.i86 ..\..\..\bin\banked\renice +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\rm +@if errorlevel 1 goto failure +del rm.r01 +as-z80 -l -o rm.s01 +@if errorlevel 1 goto failure + +link-z80 -f rm +@if errorlevel 1 goto failure +ihex2bin -l rm.i86 ..\..\..\bin\banked\rm +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\rmdir +@if errorlevel 1 goto failure +del rmdir.r01 +as-z80 -l -o rmdir.s01 +@if errorlevel 1 goto failure + +link-z80 -f rmdir +@if errorlevel 1 goto failure +ihex2bin -l rmdir.i86 ..\..\..\bin\banked\rmdir +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\roff +@if errorlevel 1 goto failure +del roff.r01 +as-z80 -l -o roff.s01 +@if errorlevel 1 goto failure + +link-z80 -f roff +@if errorlevel 1 goto failure +ihex2bin -l roff.i86 ..\..\..\bin\banked\roff +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\setclock +@if errorlevel 1 goto failure +del setclock.r01 +as-z80 -l -o setclock.s01 +@if errorlevel 1 goto failure + +link-z80 -f setclock +@if errorlevel 1 goto failure +ihex2bin -l setclock.i86 ..\..\..\bin\banked\setclock +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sort +@if errorlevel 1 goto failure +del sort.r01 +as-z80 -l -o sort.s01 +@if errorlevel 1 goto failure + +link-z80 -f sort +@if errorlevel 1 goto failure +ihex2bin -l sort.i86 ..\..\..\bin\banked\sort +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\split +@if errorlevel 1 goto failure +del split.r01 +as-z80 -l -o split.s01 +@if errorlevel 1 goto failure + +link-z80 -f split +@if errorlevel 1 goto failure +ihex2bin -l split.i86 ..\..\..\bin\banked\split +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\su +@if errorlevel 1 goto failure +del su.r01 +as-z80 -l -o su.s01 +@if errorlevel 1 goto failure + +link-z80 -f su +@if errorlevel 1 goto failure +ihex2bin -l su.i86 ..\..\..\bin\banked\su +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sum +@if errorlevel 1 goto failure +del sum.r01 +as-z80 -l -o sum.s01 +@if errorlevel 1 goto failure + +link-z80 -f sum +@if errorlevel 1 goto failure +ihex2bin -l sum.i86 ..\..\..\bin\banked\sum +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sync +@if errorlevel 1 goto failure +del sync.r01 +as-z80 -l -o sync.s01 +@if errorlevel 1 goto failure + +link-z80 -f sync +@if errorlevel 1 goto failure +ihex2bin -l sync.i86 ..\..\..\bin\banked\sync +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tail +@if errorlevel 1 goto failure +del tail.r01 +as-z80 -l -o tail.s01 +@if errorlevel 1 goto failure + +link-z80 -f tail +@if errorlevel 1 goto failure +ihex2bin -l tail.i86 ..\..\..\bin\banked\tail +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tar +@if errorlevel 1 goto failure +del tar.r01 +as-z80 -l -o tar.s01 +@if errorlevel 1 goto failure + +link-z80 -f tar +@if errorlevel 1 goto failure +ihex2bin -l tar.i86 ..\..\..\bin\banked\tar +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tee +@if errorlevel 1 goto failure +del tee.r01 +as-z80 -l -o tee.s01 +@if errorlevel 1 goto failure + +link-z80 -f tee +@if errorlevel 1 goto failure +ihex2bin -l tee.i86 ..\..\..\bin\banked\tee +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ter +@if errorlevel 1 goto failure +del ter.r01 +as-z80 -l -o ter.s01 +@if errorlevel 1 goto failure + +link-z80 -f ter +@if errorlevel 1 goto failure +ihex2bin -l ter.i86 ..\..\..\bin\banked\ter +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\termcap +@if errorlevel 1 goto failure +del termcap.r01 +as-z80 -l -o termcap.s01 +@if errorlevel 1 goto failure + +link-z80 -f termcap +@if errorlevel 1 goto failure +ihex2bin -l termcap.i86 ..\..\..\bin\banked\termcap +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\test +@if errorlevel 1 goto failure +del test.r01 +as-z80 -l -o test.s01 +@if errorlevel 1 goto failure + +link-z80 -f test +@if errorlevel 1 goto failure +ihex2bin -l test.i86 ..\..\..\bin\banked\test +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tget +@if errorlevel 1 goto failure +del tget.r01 +as-z80 -l -o tget.s01 +@if errorlevel 1 goto failure + +link-z80 -f tget +@if errorlevel 1 goto failure +ihex2bin -l tget.i86 ..\..\..\bin\banked\tget +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\time +@if errorlevel 1 goto failure +del time.r01 +as-z80 -l -o time.s01 +@if errorlevel 1 goto failure + +link-z80 -f time +@if errorlevel 1 goto failure +ihex2bin -l time.i86 ..\..\..\bin\banked\time +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\top +@if errorlevel 1 goto failure +del top.r01 +as-z80 -l -o top.s01 +@if errorlevel 1 goto failure + +link-z80 -f top +@if errorlevel 1 goto failure +ihex2bin -l top.i86 ..\..\..\bin\banked\top +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\touch +@if errorlevel 1 goto failure +del touch.r01 +as-z80 -l -o touch.s01 +@if errorlevel 1 goto failure + +link-z80 -f touch +@if errorlevel 1 goto failure +ihex2bin -l touch.i86 ..\..\..\bin\banked\touch +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tr +@if errorlevel 1 goto failure +del tr.r01 +as-z80 -l -o tr.s01 +@if errorlevel 1 goto failure + +link-z80 -f tr +@if errorlevel 1 goto failure +ihex2bin -l tr.i86 ..\..\..\bin\banked\tr +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\true +@if errorlevel 1 goto failure +del true.r01 +as-z80 -l -o true.s01 +@if errorlevel 1 goto failure + +link-z80 -f true +@if errorlevel 1 goto failure +ihex2bin -l true.i86 ..\..\..\bin\banked\true +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ualign +@if errorlevel 1 goto failure +del ualign.r01 +as-z80 -l -o ualign.s01 +@if errorlevel 1 goto failure + +link-z80 -f ualign +@if errorlevel 1 goto failure +ihex2bin -l ualign.i86 ..\..\..\bin\banked\ualign +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\umount +@if errorlevel 1 goto failure +del umount.r01 +as-z80 -l -o umount.s01 +@if errorlevel 1 goto failure + +link-z80 -f umount +@if errorlevel 1 goto failure +ihex2bin -l umount.i86 ..\..\..\bin\banked\umount +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uname +@if errorlevel 1 goto failure +del uname.r01 +as-z80 -l -o uname.s01 +@if errorlevel 1 goto failure + +link-z80 -f uname +@if errorlevel 1 goto failure +ihex2bin -l uname.i86 ..\..\..\bin\banked\uname +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uniq +@if errorlevel 1 goto failure +del uniq.r01 +as-z80 -l -o uniq.s01 +@if errorlevel 1 goto failure + +link-z80 -f uniq +@if errorlevel 1 goto failure +ihex2bin -l uniq.i86 ..\..\..\bin\banked\uniq +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uudecode +@if errorlevel 1 goto failure +del uudecode.r01 +as-z80 -l -o uudecode.s01 +@if errorlevel 1 goto failure + +link-z80 -f uudecode +@if errorlevel 1 goto failure +ihex2bin -l uudecode.i86 ..\..\..\bin\banked\uudecode +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uuencode +@if errorlevel 1 goto failure +del uuencode.r01 +as-z80 -l -o uuencode.s01 +@if errorlevel 1 goto failure + +link-z80 -f uuencode +@if errorlevel 1 goto failure +ihex2bin -l uuencode.i86 ..\..\..\bin\banked\uuencode +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\wc +@if errorlevel 1 goto failure +del wc.r01 +as-z80 -l -o wc.s01 +@if errorlevel 1 goto failure + +link-z80 -f wc +@if errorlevel 1 goto failure +ihex2bin -l wc.i86 ..\..\..\bin\banked\wc +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\which +@if errorlevel 1 goto failure +del which.r01 +as-z80 -l -o which.s01 +@if errorlevel 1 goto failure + +link-z80 -f which +@if errorlevel 1 goto failure +ihex2bin -l which.i86 ..\..\..\bin\banked\which +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\whoami +@if errorlevel 1 goto failure +del whoami.r01 +as-z80 -l -o whoami.s01 +@if errorlevel 1 goto failure + +link-z80 -f whoami +@if errorlevel 1 goto failure +ihex2bin -l whoami.i86 ..\..\..\bin\banked\whoami +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\yes +@if errorlevel 1 goto failure +del yes.r01 +as-z80 -l -o yes.s01 +@if errorlevel 1 goto failure + +link-z80 -f yes +@if errorlevel 1 goto failure +ihex2bin -l yes.i86 ..\..\..\bin\banked\yes +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/simple/build-l.ban b/src/simple/build-l.ban new file mode 100755 index 00000000..2eef51d1 --- /dev/null +++ b/src/simple/build-l.ban @@ -0,0 +1,1042 @@ +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\adduser +@if errorlevel 1 goto failure +del adduser.r01 +as-z80 -l -o adduser.s01 +@if errorlevel 1 goto failure + +link-z80 -f adduser +@if errorlevel 1 goto failure +ihex2bin -l adduser.i86 ..\..\..\bin\large\adduser +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\align +@if errorlevel 1 goto failure +del align.r01 +as-z80 -l -o align.s01 +@if errorlevel 1 goto failure + +link-z80 -f align +@if errorlevel 1 goto failure +ihex2bin -l align.i86 ..\..\..\bin\large\align +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\banner +@if errorlevel 1 goto failure +del banner.r01 +as-z80 -l -o banner.s01 +@if errorlevel 1 goto failure + +link-z80 -f banner +@if errorlevel 1 goto failure +ihex2bin -l banner.i86 ..\..\..\bin\large\banner +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\basename +@if errorlevel 1 goto failure +del basename.r01 +as-z80 -l -o basename.s01 +@if errorlevel 1 goto failure + +link-z80 -f basename +@if errorlevel 1 goto failure +ihex2bin -l basename.i86 ..\..\..\bin\large\basename +@if errorlevel 1 goto failure + +rem bogomips doesn't work under tc because too much use of z80 inline assembler +rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\bogomips +rem @if errorlevel 1 goto failure +rem del bogomips.r01 +rem as-z80 -l -o bogomips.s01 +rem @if errorlevel 1 goto failure + +rem link-z80 -f bogomips +rem @if errorlevel 1 goto failure +rem ihex2bin -l bogomips.i86 ..\..\..\bin\large\bogomips +rem @if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cal +@if errorlevel 1 goto failure +del cal.r01 +as-z80 -l -o cal.s01 +@if errorlevel 1 goto failure + +link-z80 -f cal +@if errorlevel 1 goto failure +ihex2bin -l cal.i86 ..\..\..\bin\large\cal +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cat +@if errorlevel 1 goto failure +del cat.r01 +as-z80 -l -o cat.s01 +@if errorlevel 1 goto failure + +link-z80 -f cat +@if errorlevel 1 goto failure +ihex2bin -l cat.i86 ..\..\..\bin\large\cat +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cdiff +@if errorlevel 1 goto failure +del cdiff.r01 +as-z80 -l -o cdiff.s01 +@if errorlevel 1 goto failure + +link-z80 -f cdiff +@if errorlevel 1 goto failure +ihex2bin -l cdiff.i86 ..\..\..\bin\large\cdiff +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cgrep +@if errorlevel 1 goto failure +del cgrep.r01 +as-z80 -l -o cgrep.s01 +@if errorlevel 1 goto failure + +link-z80 -f cgrep +@if errorlevel 1 goto failure +ihex2bin -l cgrep.i86 ..\..\..\bin\large\cgrep +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chgrp +@if errorlevel 1 goto failure +del chgrp.r01 +as-z80 -l -o chgrp.s01 +@if errorlevel 1 goto failure + +link-z80 -f chgrp +@if errorlevel 1 goto failure +ihex2bin -l chgrp.i86 ..\..\..\bin\large\chgrp +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chmod +@if errorlevel 1 goto failure +del chmod.r01 +as-z80 -l -o chmod.s01 +@if errorlevel 1 goto failure + +link-z80 -f chmod +@if errorlevel 1 goto failure +ihex2bin -l chmod.i86 ..\..\..\bin\large\chmod +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\chown +@if errorlevel 1 goto failure +del chown.r01 +as-z80 -l -o chown.s01 +@if errorlevel 1 goto failure + +link-z80 -f chown +@if errorlevel 1 goto failure +ihex2bin -l chown.i86 ..\..\..\bin\large\chown +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cksum +@if errorlevel 1 goto failure +del cksum.r01 +as-z80 -l -o cksum.s01 +@if errorlevel 1 goto failure + +link-z80 -f cksum +@if errorlevel 1 goto failure +ihex2bin -l cksum.i86 ..\..\..\bin\large\cksum +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cmp +@if errorlevel 1 goto failure +del cmp.r01 +as-z80 -l -o cmp.s01 +@if errorlevel 1 goto failure + +link-z80 -f cmp +@if errorlevel 1 goto failure +ihex2bin -l cmp.i86 ..\..\..\bin\large\cmp +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cp +@if errorlevel 1 goto failure +del cp.r01 +as-z80 -l -o cp.s01 +@if errorlevel 1 goto failure + +link-z80 -f cp +@if errorlevel 1 goto failure +ihex2bin -l cp.i86 ..\..\..\bin\large\cp +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cr +@if errorlevel 1 goto failure +del cr.r01 +as-z80 -l -o cr.s01 +@if errorlevel 1 goto failure + +link-z80 -f cr +@if errorlevel 1 goto failure +ihex2bin -l cr.i86 ..\..\..\bin\large\cr +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\crc +@if errorlevel 1 goto failure +del crc.r01 +as-z80 -l -o crc.s01 +@if errorlevel 1 goto failure + +link-z80 -f crc +@if errorlevel 1 goto failure +ihex2bin -l crc.i86 ..\..\..\bin\large\crc +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\cron +@if errorlevel 1 goto failure +del cron.r01 +as-z80 -l -o cron.s01 +@if errorlevel 1 goto failure + +link-z80 -f cron +@if errorlevel 1 goto failure +ihex2bin -l cron.i86 ..\..\..\bin\large\cron +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\date +@if errorlevel 1 goto failure +del date.r01 +as-z80 -l -o date.s01 +@if errorlevel 1 goto failure + +link-z80 -f date +@if errorlevel 1 goto failure +ihex2bin -l date.i86 ..\..\..\bin\large\date +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dd +@if errorlevel 1 goto failure +del dd.r01 +as-z80 -l -o dd.s01 +@if errorlevel 1 goto failure + +link-z80 -f dd +@if errorlevel 1 goto failure +ihex2bin -l dd.i86 ..\..\..\bin\large\dd +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\df +@if errorlevel 1 goto failure +del df.r01 +as-z80 -l -o df.s01 +@if errorlevel 1 goto failure + +link-z80 -f df +@if errorlevel 1 goto failure +ihex2bin -l df.i86 ..\..\..\bin\large\df +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dhry +@if errorlevel 1 goto failure +del dhry.r01 +as-z80 -l -o dhry.s01 +@if errorlevel 1 goto failure + +link-z80 -f dhry +@if errorlevel 1 goto failure +ihex2bin -l dhry.i86 ..\..\..\bin\large\dhry +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\diff +@if errorlevel 1 goto failure +del diff.r01 +as-z80 -l -o diff.s01 +@if errorlevel 1 goto failure + +link-z80 -f diff +@if errorlevel 1 goto failure +ihex2bin -l diff.i86 ..\..\..\bin\large\diff +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dirname +@if errorlevel 1 goto failure +del dirname.r01 +as-z80 -l -o dirname.s01 +@if errorlevel 1 goto failure + +link-z80 -f dirname +@if errorlevel 1 goto failure +ihex2bin -l dirname.i86 ..\..\..\bin\large\dirname +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\diskusag +@if errorlevel 1 goto failure +del diskusag.r01 +as-z80 -l -o diskusag.s01 +@if errorlevel 1 goto failure + +link-z80 -f diskusag +@if errorlevel 1 goto failure +ihex2bin -l diskusag.i86 ..\..\..\bin\large\diskusag +@if errorlevel 1 goto failure + +rem dosread is not necessary for the hytech system (no floppy drive) +rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dosread +rem @if errorlevel 1 goto failure +rem del dosread.r01 +rem as-z80 -l -o dosread.s01 +rem @if errorlevel 1 goto failure + +rem link-z80 -f dosread +rem @if errorlevel 1 goto failure +rem ihex2bin -l dosread.i86 ..\..\..\bin\large\dosread +rem @if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\dtree +@if errorlevel 1 goto failure +del dtree.r01 +as-z80 -l -o dtree.s01 +@if errorlevel 1 goto failure + +link-z80 -f dtree +@if errorlevel 1 goto failure +ihex2bin -l dtree.i86 ..\..\..\bin\large\dtree +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\du +@if errorlevel 1 goto failure +del du.r01 +as-z80 -l -o du.s01 +@if errorlevel 1 goto failure + +link-z80 -f du +@if errorlevel 1 goto failure +ihex2bin -l du.i86 ..\..\..\bin\large\du +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\echo +@if errorlevel 1 goto failure +del echo.r01 +as-z80 -l -o echo.s01 +@if errorlevel 1 goto failure + +link-z80 -f echo +@if errorlevel 1 goto failure +ihex2bin -l echo.i86 ..\..\..\bin\large\echo +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ed +@if errorlevel 1 goto failure +del ed.r01 +as-z80 -l -o ed.s01 +@if errorlevel 1 goto failure + +link-z80 -f ed +@if errorlevel 1 goto failure +ihex2bin -l ed.i86 ..\..\..\bin\large\ed +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\expr +@if errorlevel 1 goto failure +del expr.r01 +as-z80 -l -o expr.s01 +@if errorlevel 1 goto failure + +link-z80 -f expr +@if errorlevel 1 goto failure +ihex2bin -l expr.i86 ..\..\..\bin\large\expr +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\false +@if errorlevel 1 goto failure +del false.r01 +as-z80 -l -o false.s01 +@if errorlevel 1 goto failure + +link-z80 -f false +@if errorlevel 1 goto failure +ihex2bin -l false.i86 ..\..\..\bin\large\false +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fgrep +@if errorlevel 1 goto failure +del fgrep.r01 +as-z80 -l -o fgrep.s01 +@if errorlevel 1 goto failure + +link-z80 -f fgrep +@if errorlevel 1 goto failure +ihex2bin -l fgrep.i86 ..\..\..\bin\large\fgrep +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\file +@if errorlevel 1 goto failure +del file.r01 +as-z80 -l -o file.s01 +@if errorlevel 1 goto failure + +link-z80 -f file +@if errorlevel 1 goto failure +ihex2bin -l file.i86 ..\..\..\bin\large\file +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\find +@if errorlevel 1 goto failure +del find.r01 +as-z80 -l -o find.s01 +@if errorlevel 1 goto failure + +link-z80 -f find +@if errorlevel 1 goto failure +ihex2bin -l find.i86 ..\..\..\bin\large\find +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fld +@if errorlevel 1 goto failure +del fld.r01 +as-z80 -l -o fld.s01 +@if errorlevel 1 goto failure + +link-z80 -f fld +@if errorlevel 1 goto failure +ihex2bin -l fld.i86 ..\..\..\bin\large\fld +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\fortune +@if errorlevel 1 goto failure +del fortune.r01 +as-z80 -l -o fortune.s01 +@if errorlevel 1 goto failure + +link-z80 -f fortune +@if errorlevel 1 goto failure +ihex2bin -l fortune.i86 ..\..\..\bin\large\fortune +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\grep +@if errorlevel 1 goto failure +del grep.r01 +as-z80 -l -o grep.s01 +@if errorlevel 1 goto failure + +link-z80 -f grep +@if errorlevel 1 goto failure +ihex2bin -l grep.i86 ..\..\..\bin\large\grep +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\gres +@if errorlevel 1 goto failure +del gres.r01 +as-z80 -l -o gres.s01 +@if errorlevel 1 goto failure + +link-z80 -f gres +@if errorlevel 1 goto failure +ihex2bin -l gres.i86 ..\..\..\bin\large\gres +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\head +@if errorlevel 1 goto failure +del head.r01 +as-z80 -l -o head.s01 +@if errorlevel 1 goto failure + +link-z80 -f head +@if errorlevel 1 goto failure +ihex2bin -l head.i86 ..\..\..\bin\large\head +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\id +@if errorlevel 1 goto failure +del id.r01 +as-z80 -l -o id.s01 +@if errorlevel 1 goto failure + +link-z80 -f id +@if errorlevel 1 goto failure +ihex2bin -l id.i86 ..\..\..\bin\large\id +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\inodes +@if errorlevel 1 goto failure +del inodes.r01 +as-z80 -l -o inodes.s01 +@if errorlevel 1 goto failure + +link-z80 -f inodes +@if errorlevel 1 goto failure +ihex2bin -l inodes.i86 ..\..\..\bin\large\inodes +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\kill +@if errorlevel 1 goto failure +del kill.r01 +as-z80 -l -o kill.s01 +@if errorlevel 1 goto failure + +link-z80 -f kill +@if errorlevel 1 goto failure +ihex2bin -l kill.i86 ..\..\..\bin\large\kill +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\lpd +@if errorlevel 1 goto failure +del lpd.r01 +as-z80 -l -o lpd.s01 +@if errorlevel 1 goto failure + +link-z80 -f lpd +@if errorlevel 1 goto failure +ihex2bin -l lpd.i86 ..\..\..\bin\large\lpd +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\lpr +@if errorlevel 1 goto failure +del lpr.r01 +as-z80 -l -o lpr.s01 +@if errorlevel 1 goto failure + +link-z80 -f lpr +@if errorlevel 1 goto failure +ihex2bin -l lpr.i86 ..\..\..\bin\large\lpr +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ls +@if errorlevel 1 goto failure +del ls.r01 +as-z80 -l -o ls.s01 +@if errorlevel 1 goto failure + +link-z80 -f ls +@if errorlevel 1 goto failure +ihex2bin -l ls.i86 ..\..\..\bin\large\ls +@if errorlevel 1 goto failure + +rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\man +rem @if errorlevel 1 goto failure +rem del man.r01 +rem as-z80 -l -o man.s01 +rem @if errorlevel 1 goto failure + +rem link-z80 -f man +rem @if errorlevel 1 goto failure +rem ihex2bin -l man.i86 ..\..\..\bin\large\man +rem @if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mkdir +@if errorlevel 1 goto failure +del mkdir.r01 +as-z80 -l -o mkdir.s01 +@if errorlevel 1 goto failure + +link-z80 -f mkdir +@if errorlevel 1 goto failure +ihex2bin -l mkdir.i86 ..\..\..\bin\large\mkdir +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mknod +@if errorlevel 1 goto failure +del mknod.r01 +as-z80 -l -o mknod.s01 +@if errorlevel 1 goto failure + +link-z80 -f mknod +@if errorlevel 1 goto failure +ihex2bin -l mknod.i86 ..\..\..\bin\large\mknod +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\more +@if errorlevel 1 goto failure +del more.r01 +as-z80 -l -o more.s01 +@if errorlevel 1 goto failure + +link-z80 -f more +@if errorlevel 1 goto failure +ihex2bin -l more.i86 ..\..\..\bin\large\more +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\mount +@if errorlevel 1 goto failure +del mount.r01 +as-z80 -l -o mount.s01 +@if errorlevel 1 goto failure + +link-z80 -f mount +@if errorlevel 1 goto failure +ihex2bin -l mount.i86 ..\..\..\bin\large\mount +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ncheck +@if errorlevel 1 goto failure +del ncheck.r01 +as-z80 -l -o ncheck.s01 +@if errorlevel 1 goto failure + +link-z80 -f ncheck +@if errorlevel 1 goto failure +ihex2bin -l ncheck.i86 ..\..\..\bin\large\ncheck +@if errorlevel 1 goto failure + +rem iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ncr +rem @if errorlevel 1 goto failure +rem del ncr.r01 +rem as-z80 -l -o ncr.s01 +rem @if errorlevel 1 goto failure + +rem link-z80 -f ncr +rem @if errorlevel 1 goto failure +rem ihex2bin -l ncr.i86 ..\..\..\bin\large\ncr +rem @if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\od +@if errorlevel 1 goto failure +del od.r01 +as-z80 -l -o od.s01 +@if errorlevel 1 goto failure + +link-z80 -f od +@if errorlevel 1 goto failure +ihex2bin -l od.i86 ..\..\..\bin\large\od +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\passwd +@if errorlevel 1 goto failure +del passwd.r01 +as-z80 -l -o passwd.s01 +@if errorlevel 1 goto failure + +link-z80 -f passwd +@if errorlevel 1 goto failure +ihex2bin -l passwd.i86 ..\..\..\bin\large\passwd +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pathchk +@if errorlevel 1 goto failure +del pathchk.r01 +as-z80 -l -o pathchk.s01 +@if errorlevel 1 goto failure + +link-z80 -f pathchk +@if errorlevel 1 goto failure +ihex2bin -l pathchk.i86 ..\..\..\bin\large\pathchk +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pr +@if errorlevel 1 goto failure +del pr.r01 +as-z80 -l -o pr.s01 +@if errorlevel 1 goto failure + +link-z80 -f pr +@if errorlevel 1 goto failure +ihex2bin -l pr.i86 ..\..\..\bin\large\pr +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\printenv +@if errorlevel 1 goto failure +del printenv.r01 +as-z80 -l -o printenv.s01 +@if errorlevel 1 goto failure + +link-z80 -f printenv +@if errorlevel 1 goto failure +ihex2bin -l printenv.i86 ..\..\..\bin\large\printenv +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ps +@if errorlevel 1 goto failure +del ps.r01 +as-z80 -l -o ps.s01 +@if errorlevel 1 goto failure + +link-z80 -f ps +@if errorlevel 1 goto failure +ihex2bin -l ps.i86 ..\..\..\bin\large\ps +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\pwd +@if errorlevel 1 goto failure +del pwd.r01 +as-z80 -l -o pwd.s01 +@if errorlevel 1 goto failure + +link-z80 -f pwd +@if errorlevel 1 goto failure +ihex2bin -l pwd.i86 ..\..\..\bin\large\pwd +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\readall +@if errorlevel 1 goto failure +del readall.r01 +as-z80 -l -o readall.s01 +@if errorlevel 1 goto failure + +link-z80 -f readall +@if errorlevel 1 goto failure +ihex2bin -l readall.i86 ..\..\..\bin\large\readall +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\reboot +@if errorlevel 1 goto failure +del reboot.r01 +as-z80 -l -o reboot.s01 +@if errorlevel 1 goto failure + +link-z80 -f reboot +@if errorlevel 1 goto failure +ihex2bin -l reboot.i86 ..\..\..\bin\large\reboot +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\renice +@if errorlevel 1 goto failure +del renice.r01 +as-z80 -l -o renice.s01 +@if errorlevel 1 goto failure + +link-z80 -f renice +@if errorlevel 1 goto failure +ihex2bin -l renice.i86 ..\..\..\bin\large\renice +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\rm +@if errorlevel 1 goto failure +del rm.r01 +as-z80 -l -o rm.s01 +@if errorlevel 1 goto failure + +link-z80 -f rm +@if errorlevel 1 goto failure +ihex2bin -l rm.i86 ..\..\..\bin\large\rm +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\rmdir +@if errorlevel 1 goto failure +del rmdir.r01 +as-z80 -l -o rmdir.s01 +@if errorlevel 1 goto failure + +link-z80 -f rmdir +@if errorlevel 1 goto failure +ihex2bin -l rmdir.i86 ..\..\..\bin\large\rmdir +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\roff +@if errorlevel 1 goto failure +del roff.r01 +as-z80 -l -o roff.s01 +@if errorlevel 1 goto failure + +link-z80 -f roff +@if errorlevel 1 goto failure +ihex2bin -l roff.i86 ..\..\..\bin\large\roff +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\setclock +@if errorlevel 1 goto failure +del setclock.r01 +as-z80 -l -o setclock.s01 +@if errorlevel 1 goto failure + +link-z80 -f setclock +@if errorlevel 1 goto failure +ihex2bin -l setclock.i86 ..\..\..\bin\large\setclock +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sort +@if errorlevel 1 goto failure +del sort.r01 +as-z80 -l -o sort.s01 +@if errorlevel 1 goto failure + +link-z80 -f sort +@if errorlevel 1 goto failure +ihex2bin -l sort.i86 ..\..\..\bin\large\sort +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\split +@if errorlevel 1 goto failure +del split.r01 +as-z80 -l -o split.s01 +@if errorlevel 1 goto failure + +link-z80 -f split +@if errorlevel 1 goto failure +ihex2bin -l split.i86 ..\..\..\bin\large\split +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\su +@if errorlevel 1 goto failure +del su.r01 +as-z80 -l -o su.s01 +@if errorlevel 1 goto failure + +link-z80 -f su +@if errorlevel 1 goto failure +ihex2bin -l su.i86 ..\..\..\bin\large\su +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sum +@if errorlevel 1 goto failure +del sum.r01 +as-z80 -l -o sum.s01 +@if errorlevel 1 goto failure + +link-z80 -f sum +@if errorlevel 1 goto failure +ihex2bin -l sum.i86 ..\..\..\bin\large\sum +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\sync +@if errorlevel 1 goto failure +del sync.r01 +as-z80 -l -o sync.s01 +@if errorlevel 1 goto failure + +link-z80 -f sync +@if errorlevel 1 goto failure +ihex2bin -l sync.i86 ..\..\..\bin\large\sync +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tail +@if errorlevel 1 goto failure +del tail.r01 +as-z80 -l -o tail.s01 +@if errorlevel 1 goto failure + +link-z80 -f tail +@if errorlevel 1 goto failure +ihex2bin -l tail.i86 ..\..\..\bin\large\tail +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tar +@if errorlevel 1 goto failure +del tar.r01 +as-z80 -l -o tar.s01 +@if errorlevel 1 goto failure + +link-z80 -f tar +@if errorlevel 1 goto failure +ihex2bin -l tar.i86 ..\..\..\bin\large\tar +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tee +@if errorlevel 1 goto failure +del tee.r01 +as-z80 -l -o tee.s01 +@if errorlevel 1 goto failure + +link-z80 -f tee +@if errorlevel 1 goto failure +ihex2bin -l tee.i86 ..\..\..\bin\large\tee +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ter +@if errorlevel 1 goto failure +del ter.r01 +as-z80 -l -o ter.s01 +@if errorlevel 1 goto failure + +link-z80 -f ter +@if errorlevel 1 goto failure +ihex2bin -l ter.i86 ..\..\..\bin\large\ter +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\termcap +@if errorlevel 1 goto failure +del termcap.r01 +as-z80 -l -o termcap.s01 +@if errorlevel 1 goto failure + +link-z80 -f termcap +@if errorlevel 1 goto failure +ihex2bin -l termcap.i86 ..\..\..\bin\large\termcap +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\test +@if errorlevel 1 goto failure +del test.r01 +as-z80 -l -o test.s01 +@if errorlevel 1 goto failure + +link-z80 -f test +@if errorlevel 1 goto failure +ihex2bin -l test.i86 ..\..\..\bin\large\test +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tget +@if errorlevel 1 goto failure +del tget.r01 +as-z80 -l -o tget.s01 +@if errorlevel 1 goto failure + +link-z80 -f tget +@if errorlevel 1 goto failure +ihex2bin -l tget.i86 ..\..\..\bin\large\tget +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\time +@if errorlevel 1 goto failure +del time.r01 +as-z80 -l -o time.s01 +@if errorlevel 1 goto failure + +link-z80 -f time +@if errorlevel 1 goto failure +ihex2bin -l time.i86 ..\..\..\bin\large\time +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\top +@if errorlevel 1 goto failure +del top.r01 +as-z80 -l -o top.s01 +@if errorlevel 1 goto failure + +link-z80 -f top +@if errorlevel 1 goto failure +ihex2bin -l top.i86 ..\..\..\bin\large\top +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\touch +@if errorlevel 1 goto failure +del touch.r01 +as-z80 -l -o touch.s01 +@if errorlevel 1 goto failure + +link-z80 -f touch +@if errorlevel 1 goto failure +ihex2bin -l touch.i86 ..\..\..\bin\large\touch +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\tr +@if errorlevel 1 goto failure +del tr.r01 +as-z80 -l -o tr.s01 +@if errorlevel 1 goto failure + +link-z80 -f tr +@if errorlevel 1 goto failure +ihex2bin -l tr.i86 ..\..\..\bin\large\tr +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\true +@if errorlevel 1 goto failure +del true.r01 +as-z80 -l -o true.s01 +@if errorlevel 1 goto failure + +link-z80 -f true +@if errorlevel 1 goto failure +ihex2bin -l true.i86 ..\..\..\bin\large\true +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\ualign +@if errorlevel 1 goto failure +del ualign.r01 +as-z80 -l -o ualign.s01 +@if errorlevel 1 goto failure + +link-z80 -f ualign +@if errorlevel 1 goto failure +ihex2bin -l ualign.i86 ..\..\..\bin\large\ualign +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\umount +@if errorlevel 1 goto failure +del umount.r01 +as-z80 -l -o umount.s01 +@if errorlevel 1 goto failure + +link-z80 -f umount +@if errorlevel 1 goto failure +ihex2bin -l umount.i86 ..\..\..\bin\large\umount +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uname +@if errorlevel 1 goto failure +del uname.r01 +as-z80 -l -o uname.s01 +@if errorlevel 1 goto failure + +link-z80 -f uname +@if errorlevel 1 goto failure +ihex2bin -l uname.i86 ..\..\..\bin\large\uname +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uniq +@if errorlevel 1 goto failure +del uniq.r01 +as-z80 -l -o uniq.s01 +@if errorlevel 1 goto failure + +link-z80 -f uniq +@if errorlevel 1 goto failure +ihex2bin -l uniq.i86 ..\..\..\bin\large\uniq +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uudecode +@if errorlevel 1 goto failure +del uudecode.r01 +as-z80 -l -o uudecode.s01 +@if errorlevel 1 goto failure + +link-z80 -f uudecode +@if errorlevel 1 goto failure +ihex2bin -l uudecode.i86 ..\..\..\bin\large\uudecode +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\uuencode +@if errorlevel 1 goto failure +del uuencode.r01 +as-z80 -l -o uuencode.s01 +@if errorlevel 1 goto failure + +link-z80 -f uuencode +@if errorlevel 1 goto failure +ihex2bin -l uuencode.i86 ..\..\..\bin\large\uuencode +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\wc +@if errorlevel 1 goto failure +del wc.r01 +as-z80 -l -o wc.s01 +@if errorlevel 1 goto failure + +link-z80 -f wc +@if errorlevel 1 goto failure +ihex2bin -l wc.i86 ..\..\..\bin\large\wc +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\which +@if errorlevel 1 goto failure +del which.r01 +as-z80 -l -o which.s01 +@if errorlevel 1 goto failure + +link-z80 -f which +@if errorlevel 1 goto failure +ihex2bin -l which.i86 ..\..\..\bin\large\which +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\whoami +@if errorlevel 1 goto failure +del whoami.r01 +as-z80 -l -o whoami.s01 +@if errorlevel 1 goto failure + +link-z80 -f whoami +@if errorlevel 1 goto failure +ihex2bin -l whoami.i86 ..\..\..\bin\large\whoami +@if errorlevel 1 goto failure + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\yes +@if errorlevel 1 goto failure +del yes.r01 +as-z80 -l -o yes.s01 +@if errorlevel 1 goto failure + +link-z80 -f yes +@if errorlevel 1 goto failure +ihex2bin -l yes.i86 ..\..\..\bin\large\yes +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/simple/cal.c b/src/simple/cal.c new file mode 100755 index 00000000..96af0b13 --- /dev/null +++ b/src/simple/cal.c @@ -0,0 +1,319 @@ +/* cal - print a calendar Author: Maritn Minow */ + +#include +#include +#include + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +#define do3months domonth +#define IO_SUCCESS 0 /* Unix definitions */ +#define IO_ERROR 1 +#define EOS 0 + +#define ENTRY_SIZE 3 /* 3 bytes per value */ +#define DAYS_PER_WEEK 7 /* Sunday, etc. */ +#define WEEKS_PER_MONTH 6 /* Max. weeks in a month */ +#define MONTHS_PER_LINE 3 /* Three months across */ +#define MONTH_SPACE 3 /* Between each month */ + +char *badarg = {"Bad argument\n"}; +char *how = {"usage: cal [month] year\n"}; + +/* Calendar() stuffs data into layout[], + * output() copies from layout[] to outline[], (then trims blanks). + */ +char layout[MONTHS_PER_LINE][WEEKS_PER_MONTH][DAYS_PER_WEEK][ENTRY_SIZE]; +char outline[(MONTHS_PER_LINE * DAYS_PER_WEEK * ENTRY_SIZE) + + (MONTHS_PER_LINE * MONTH_SPACE) + + 1]; + +char *weekday = " S M Tu W Th F S"; +char *monthname[] = { + "???", /* No month 0 */ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void doyear, (int year)); +_PROTOTYPE(void domonth, (int year, int month)); +_PROTOTYPE(void output, (int nmonths)); +_PROTOTYPE(void calendar, (int year, int month, int indx)); +_PROTOTYPE(void usage, (char *s)); +_PROTOTYPE(int date, (int year, int month, int week, int wday)); +_PROTOTYPE(void setmonth, (int year, int month)); +_PROTOTYPE(int getdate, (int week, int wday)); +_PROTOTYPE(static int Jan1, (int year)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + register int year; + + register int arg1val; + int arg1len; + int arg2val; + + if (argc <= 1) { + usage(how); + } else { + arg1val = atoi(argv[1]); + arg1len = strlen(argv[1]); + if (argc == 2) { + /* Only one argument, if small, it's a month. If + * large, it's a year. Note: cal 0082 Year + * 0082 cal 82 Year 0082 */ + if (arg1len <= 2 && arg1val <= 12) + do3months(year, arg1val); + else + doyear(arg1val); + } else { + /* Two arguments, allow 1980 12 or 12 1980 */ + arg2val = atoi(argv[2]); + if (arg1len > 2) + do3months(arg1val, arg2val); + else + do3months(arg2val, arg1val); + } + } + return(IO_SUCCESS); +} + +void doyear(year) +int year; +/* Print the calendar for an entire year. */ +{ + register int month; + + if (year < 1 || year > 9999) usage(badarg); + if (year < 100) + printf("\n\n\n 00%2d\n\n", year); + else + printf("\n\n\n%35d\n\n", year); + for (month = 1; month <= 12; month += MONTHS_PER_LINE) { + printf("%12s%23s%23s\n", + monthname[month], + monthname[month + 1], + monthname[month + 2]); + printf("%s %s %s\n", weekday, weekday, weekday); + calendar(year, month + 0, 0); + calendar(year, month + 1, 1); + calendar(year, month + 2, 2); + output(3); +#if MONTHS_PER_LINE != 3 +#error "the above will not work" +#endif + } + printf("\n\n\n"); +} + +void domonth(year, month) +int year; +int month; +/* Do one specific month -- note: no longer used */ +{ + if (year < 1 || year > 9999) usage(badarg); + if (month <= 0 || month > 12) usage(badarg); + printf("%9s%5d\n\n%s\n", monthname[month], year, weekday); + calendar(year, month, 0); + output(1); + printf("\n\n"); +} + +void output(nmonths) +int nmonths; /* Number of months to do */ +/* Clean up and output the text. */ +{ + register int week; + register int month; + register char *outp; + int i; + char tmpbuf[21], *p; + + for (week = 0; week < WEEKS_PER_MONTH; week++) { + outp = outline; + for (month = 0; month < nmonths; month++) { + /* The -1 in the following removes the unwanted + * leading blank from the entry for Sunday. */ + p = &layout[month][week][0][1]; + for (i = 0; i < 20; i++) tmpbuf[i] = *p++; + tmpbuf[20] = 0; + sprintf(outp, "%s ", tmpbuf); + outp += (DAYS_PER_WEEK * ENTRY_SIZE) + MONTH_SPACE - 1; + } + while (outp > outline && outp[-1] == ' ') outp--; + *outp = EOS; + printf("%s\n", outline); + } +} + +void calendar(year, month, indx) +int year; +int month; +int indx; /* Which of the three months */ +/* Actually build the calendar for this month. */ +{ + register char *tp; + int week; + register int wday; + register int today; + + setmonth(year, month); + for (week = 0; week < WEEKS_PER_MONTH; week++) { + for (wday = 0; wday < DAYS_PER_WEEK; wday++) { + tp = &layout[indx][week][wday][0]; + *tp++ = ' '; + today = getdate(week, wday); + if (today <= 0) { + *tp++ = ' '; + *tp++ = ' '; + } else if (today < 10) { + *tp++ = ' '; + *tp = (today + '0'); + } else { + *tp++ = (today / 10) + '0'; + *tp = (today % 10) + '0'; + } + } + } +} + +void usage(s) +char *s; +{ +/* Fatal parameter error. */ + + fprintf(stderr, "%s", s); + exit(IO_ERROR); +} + +/* Calendar routines, intended for eventual porting to TeX + * + * date(year, month, week, wday) + * Returns the date on this week (0 is first, 5 last possible) + * and day of the week (Sunday == 0) + * Note: January is month 1. + * + * setmonth(year, month) + * Parameters are as above, sets getdate() for this month. + * + * int + * getdate(week, wday) + * Parameters are as above, uses the data set by setmonth() + */ + +/* This structure is used to pass data between setmonth() and getdate(). + * It needs considerable expansion if the Julian->Gregorian change is + * to be extended to other countries. + */ + +static struct { + int this_month; /* month number used in 1752 checking */ + int feb; /* Days in February for this month */ + int sept; /* Days in September for this month */ + int days_in_month; /* Number of days in this month */ + int dow_first; /* Day of week of the 1st day in month */ +} info; + +static int day_month[] = { /* 30 days hath September... */ + 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +int date(year, month, week, wday) +int year; /* Calendar date being computed */ +int month; /* January == 1 */ +int week; /* Week in the month 0..5 inclusive */ +int wday; /* Weekday, Sunday == 0 */ +/* Return the date of the month that fell on this week and weekday. + * Return zero if it's out of range. + */ +{ + setmonth(year, month); + return(getdate(week, wday)); +} + +void setmonth(year, month) +int year; /* Year to compute */ +int month; /* Month, January is month 1 */ +/* Setup the parameters needed to compute this month + * (stored in the info structure). + */ +{ + register int i; + + if (month < 1 || month > 12) {/* Verify caller's parameters */ + info.days_in_month = 0; /* Garbage flag */ + return; + } + info.this_month = month; /* used in 1752 checking */ + info.dow_first = Jan1(year); /* Day of January 1st for now */ + info.feb = 29; /* Assume leap year */ + info.sept = 30; /* Assume normal year */ + /* Determine whether it's an ordinary year, a leap year or the + * magical calendar switch year of 1752. */ + switch ((Jan1(year + 1) + 7 - info.dow_first) % 7) { + case 1: /* Not a leap year */ + info.feb = 28; + case 2: /* Ordinary leap year */ + break; + + default: /* The magical moment arrives */ + info.sept = 19; /* 19 days hath September */ + break; + } + info.days_in_month = + (month == 2) ? info.feb + : (month == 9) ? info.sept + : day_month[month]; + for (i = 1; i < month; i++) { + switch (i) { /* Special months? */ + case 2: /* February */ + info.dow_first += info.feb; + break; + + case 9: info.dow_first += info.sept; break; + + default: + info.dow_first += day_month[i]; + break; + } + } + info.dow_first %= 7; /* Now it's Sunday to Saturday */ +} + +int getdate(week, wday) +int week; +int wday; +{ + register int today; + + /* Get a first guess at today's date and make sure it's in range. */ + today = (week * 7) + wday - info.dow_first + 1; + if (today <= 0 || today > info.days_in_month) + return(0); + else if (info.sept == 19 && info.this_month == 9 + && today >= 3) /* The magical month? */ + return(today + 11); /* If so, some dates changed */ + else /* Otherwise, */ + return(today); /* Return the date */ +} + +static int Jan1(year) +int year; +/* Return day of the week for Jan 1 of the specified year. */ +{ + register int day; + + day = year + 4 + ((year + 3) / 4); /* Julian Calendar */ + if (year > 1800) { /* If it's recent, do */ + day -= ((year - 1701) / 100); /* Clavian correction */ + day += ((year - 1601) / 400); /* Gregorian correction */ + } + if (year > 1752) /* Adjust for Gregorian */ + day += 3; /* calendar */ + return(day % 7); +} diff --git a/src/simple/cat.c b/src/simple/cat.c new file mode 100755 index 00000000..2cf3b0d7 --- /dev/null +++ b/src/simple/cat.c @@ -0,0 +1,48 @@ +/* kitten (baby-cat) + * (C) 1997 Chad Page + * + * jun/99: Adriano Cunha + * added piped input capability + */ + +#include +#include +#include +#include +#include + +int main(argc, argv) + int argc; + char **argv; +{ + int fd, i = 1, bytes = 0, viastdin = 0; + unsigned char buf[BUFSIZ]; + char *p; + + if (argc < 2) { + if (isatty(STDIN_FILENO)) { + write(STDERR_FILENO, "usage: cat filename ...\n", 20); + return 0; + } else { + argc++; + viastdin = 1; + } + } + while (i < argc) { + i++; + if (!viastdin) { + p=argv[i-1]; + if ((fd = open(p, O_RDONLY)) <= 0) { + write(STDERR_FILENO, "cat: can't open file\n", 21); + continue; /* missing file */ + } + } else fd = STDIN_FILENO; + while ((bytes = read(fd, buf, sizeof(buf))) > 0) { + if (write(STDOUT_FILENO, buf, bytes) != bytes) + return 2; /* write error - no space */ + } + if (!viastdin) close(fd); + } + return 0; +} + \ No newline at end of file diff --git a/src/simple/cdiff.c b/src/simple/cdiff.c new file mode 100755 index 00000000..aa416515 --- /dev/null +++ b/src/simple/cdiff.c @@ -0,0 +1,376 @@ +/* cdiff - context diff Author: Larry Wall */ + +/* Cdiff - turns a regular diff into a new-style context diff + * + * Usage: cdiff -c# file1 file2 + */ + +#define PATCHLEVEL 2 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char buff[512]; + +FILE *inputfp, *oldfp, *newfp; + +int oldmin, oldmax, newmin, newmax; +int oldbeg, oldend, newbeg, newend; +int preoldmax, prenewmax; +int preoldbeg, preoldend, prenewbeg, prenewend; +int oldwanted, newwanted; + +char *oldhunk, *newhunk; +char *progname; +size_t oldsize, oldalloc, newsize, newalloc; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void dumphunk, (void)); +_PROTOTYPE(char *getold, (int targ)); +_PROTOTYPE(char *getnew, (int targ)); +_PROTOTYPE(void *xmalloc, (size_t size)); +_PROTOTYPE(void *xrealloc, (void *ptr, size_t size)); + +#ifndef NAME_MAX +#define NAME_MAX 32 +#define PATH_MAX 128 +#endif + +#define Nullfp (FILE*)0 +#define Nullch (char*)0 +#define ENOUGH (NAME_MAX + PATH_MAX + 1) +#define CRC_END 12 + +#define qtime(x) asctime(localtime(x)) + +int main(argc, argv) +int argc; +char **argv; +{ + FILE *crcfp; + char *old, *new; + int context = 3; + struct stat statbuf; + register char *s; + char op; + char *newmark, *oldmark; + char sysbuf1[ENOUGH], sysbuf2[ENOUGH]; + int len; + char *line; + int i; + int status; + + progname = argv[0]; + oldalloc = 512; + oldhunk = (char *) xmalloc(oldalloc); + newalloc = 512; + newhunk = (char *) xmalloc(newalloc); + + for (argc--, argv++; argc; argc--, argv++) { + if (argv[0][0] != '-') break; + + if (argv[0][1] == 'c') context = atoi(argv[0] + 2); + } + + if (argc != 2) { + fprintf(stderr, "usage: cdiff -c# old new\n"); + exit(2); + } + old = argv[0]; + new = argv[1]; + + oldfp = fopen(old, "r"); + if (!oldfp) { + fprintf(stderr, "Can't open %s\n", old); + exit(2); + } + newfp = fopen(new, "r"); + if (!newfp) { + fprintf(stderr, "Can't open %s\n", new); + exit(2); + } + + /* Compute crcs by popen()ing crc and reading the output. Do this before + * popen()ing diff to do the work. popen() attempts to support multiple + * clients, but the 1.3-1.6.24b versions don't succeed. + */ + sprintf(sysbuf1, "crc %s", old); + crcfp = popen(sysbuf1, "r"); + if (!crcfp) { + /* The only advantage of cdiff over diff is that it prints crcs, so + * give up easily if crc fails. + */ + fprintf(stderr, "Can't execute 'crc %s'.\nCheck if your system has the 'crc' program and if it's in the path.", old); + exit(2); + } + fgets(sysbuf1, sizeof(sysbuf1), crcfp); + sysbuf1[CRC_END] = '\0'; + status = pclose(crcfp); + if (status != 0) { + fprintf(stderr, "'crc %s' returned bad status %d\n", old, status); + exit(2); + } + sprintf(sysbuf2, "crc %s", new); + crcfp = popen(sysbuf2, "r"); + if (!crcfp) { + fprintf(stderr, "Can't execute 'crc %s'\n", new); + exit(2); + } + fgets(sysbuf2, sizeof(sysbuf2), crcfp); + sysbuf2[CRC_END] = '\0'; + status = pclose(crcfp); + if (status != 0) { + fprintf(stderr, "'crc %s' returned bad status %d\n", new, status); + exit(2); + } + + sprintf(buff, "diff %s %s", old, new); + inputfp = popen(buff, "r"); + if (!inputfp) { + fprintf(stderr, "Can't execute 'diff %s %s'.\nCheck if your system has the 'diff' program and if it's in the path.\n", old, new); + exit(2); + } + + fstat(fileno(oldfp), &statbuf); + printf("*** %s\tcrc=%s\t%s", old, sysbuf1, qtime(&statbuf.st_mtime)); + fstat(fileno(newfp), &statbuf); + printf("--- %s\tcrc=%s\t%s", new, sysbuf2, qtime(&statbuf.st_mtime)); + + preoldend = -1000; + + while (fgets(buff, sizeof buff, inputfp) != Nullch) { + if (isdigit(*buff)) { + oldmin = atoi(buff); + for (s = buff; isdigit(*s); s++); + if (*s == ',') { + s++; + oldmax = atoi(s); + for (; isdigit(*s); s++); + } else { + oldmax = oldmin; + } + if (*s != 'a' && *s != 'd' && *s != 'c') { + fprintf(stderr, "Unparseable input: %s\n", s); + exit(2); + } + op = *s; + s++; + newmin = atoi(s); + for (; isdigit(*s); s++); + if (*s == ',') { + s++; + newmax = atoi(s); + for (; isdigit(*s); s++); + } else { + newmax = newmin; + } + if (*s != '\n' && *s != ' ') { + fprintf(stderr, "Unparseable input: %s\n", s); + exit(2); + } + newmark = oldmark = "! "; + if (op == 'a') { + oldmin++; + newmark = "+ "; + } + if (op == 'd') { + newmin++; + oldmark = "- "; + } + oldbeg = oldmin - context; + oldend = oldmax + context; + if (oldbeg < 1) oldbeg = 1; + newbeg = newmin - context; + newend = newmax + context; + if (newbeg < 1) newbeg = 1; + + if (preoldend < oldbeg - 1) { + if (preoldend >= 0) { + dumphunk(); + } + preoldbeg = oldbeg; + prenewbeg = newbeg; + oldwanted = newwanted = 0; + oldsize = newsize = 0; + } else { /* we want to append to previous hunk */ + oldbeg = preoldmax + 1; + newbeg = prenewmax + 1; + } + + for (i = oldbeg; i <= oldmax; i++) { + line = getold(i); + if (!line) { + oldend = oldmax = i - 1; + break; + } + len = strlen(line) + 2; + if (oldsize + len + 1 >= oldalloc) { + oldalloc *= 2; + oldhunk = (char *) xrealloc(oldhunk, oldalloc); + } + if (i >= oldmin) { + strcpy(oldhunk + oldsize, oldmark); + oldwanted++; + } else { + strcpy(oldhunk + oldsize, " "); + } + strcpy(oldhunk + oldsize + 2, line); + oldsize += len; + } + preoldmax = oldmax; + preoldend = oldend; + + for (i = newbeg; i <= newmax; i++) { + line = getnew(i); + if (!line) { + newend = newmax = i - 1; + break; + } + len = strlen(line) + 2; + if (newsize + len + 1 >= newalloc) { + newalloc *= 2; + newhunk = (char *) xrealloc(newhunk, newalloc); + } + if (i >= newmin) { + strcpy(newhunk + newsize, newmark); + newwanted++; + } else { + strcpy(newhunk + newsize, " "); + } + strcpy(newhunk + newsize + 2, line); + newsize += len; + } + prenewmax = newmax; + prenewend = newend; + } + } + + if (preoldend >= 0) { + dumphunk(); + } + status = pclose(inputfp); + if (!WIFEXITED(status)) exit(2); + status = WEXITSTATUS(status); + return(status == 0 || status == 1 ? status : 2); +} + +void dumphunk() +{ + int i; + char *line; + int len; + + for (i = preoldmax + 1; i <= preoldend; i++) { + line = getold(i); + if (!line) { + preoldend = i - 1; + break; + } + len = strlen(line) + 2; + if (oldsize + len + 1 >= oldalloc) { + oldalloc *= 2; + oldhunk = (char *) xrealloc(oldhunk, oldalloc); + } + strcpy(oldhunk + oldsize, " "); + strcpy(oldhunk + oldsize + 2, line); + oldsize += len; + } + for (i = prenewmax + 1; i <= prenewend; i++) { + line = getnew(i); + if (!line) { + prenewend = i - 1; + break; + } + len = strlen(line) + 2; + if (newsize + len + 1 >= newalloc) { + newalloc *= 2; + newhunk = (char *) xrealloc(newhunk, newalloc); + } + strcpy(newhunk + newsize, " "); + strcpy(newhunk + newsize + 2, line); + newsize += len; + } + printf("***************\n"); + if (preoldbeg >= preoldend) { + printf("*** %d ****\n", preoldend); + } else { + printf("*** %d,%d ****\n", preoldbeg, preoldend); + } + if (oldwanted) { + printf("%s", oldhunk); + } + oldsize = 0; + *oldhunk = '\0'; + if (prenewbeg >= prenewend) { + printf("--- %d ----\n", prenewend); + } else { + printf("--- %d,%d ----\n", prenewbeg, prenewend); + } + if (newwanted) { + printf("%s", newhunk); + } + newsize = 0; + *newhunk = '\0'; +} + +char *getold(targ) +int targ; +{ + static int oldline = 0; + + while (fgets(buff, sizeof buff, oldfp) != Nullch) { + oldline++; + if (oldline == targ) return buff; + } + return Nullch; +} + +char *getnew(targ) +int targ; +{ + static int newline = 0; + + while (fgets(buff, sizeof buff, newfp) != Nullch) { + newline++; + if (newline == targ) return buff; + } + return Nullch; +} + +void *xmalloc(size) +size_t size; +{ + void *ptr; + + ptr = malloc(size); + if (ptr == NULL) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(2); + } + return(ptr); +} + +void *xrealloc(ptr, size) +void *ptr; +size_t size; +{ + ptr = realloc(ptr, size); + if (ptr == NULL) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(2); + } + return(ptr); +} diff --git a/src/simple/cgrep.c b/src/simple/cgrep.c new file mode 100755 index 00000000..abf4971e --- /dev/null +++ b/src/simple/cgrep.c @@ -0,0 +1,387 @@ +/* cgrep - grep and display context Author: Mark Mallet */ + +/* + Nov 19 1984 Mark Mallett (mem@zinn.MV.COM) + +mem 860224 Modified to do r/e (regular expression) parsing on unix +mem 860324 Added -f, -n; added code to number lines correctly on output. +mem 870325 Added support for regcmp()/regex() style regular expression + library; redid some conditionals to provide better mix'n'match. +mem 870326 Don't try to print the filename if reading from stdin. + Add -w option. Fix a small problem which occasionally allowed + the separator to come out between adjacent lines of the file. +mem 871119 Fix semantics of call to regcmp(): the NULL terminating the + argument list was missing. It worked, but probably only + due to some bizarre coincidence. +dro 890109 Minor mods to compile under Minix + +*/ + +#define OS_UNIX /* Define this for unix systems */ + /* #define REGEX *//* Define this for re_comp/re_exec library */ +#define REGCMP /* Define this to use regcmp/regex */ + /* #define OS_CPM *//* Define this for CP/M-80 */ + + +/* Don't touch these */ +#define NOREGEXP /* Set this for no regular expression */ +#ifdef REGEX +#undef NOREGEXP +#endif /* REGEX */ + +#ifdef REGCMP +#undef NOREGEXP +#endif /* REGCMP */ + + +#ifdef OS_CPM +#include "stdio.h" +#include "ctype.h" +#endif /* OS_CPM */ + +/* Nick (it's in ..\include\types.h) #define size_t unsigned */ + +#ifdef OS_UNIX +#include +#include /* Either here or in sys directory - dro */ +#include +#include /* should have this - dro */ +#include /* should have this - dro */ +#include +#include +#endif /* OS_UNIX */ + + +/* Local definitions */ + +#ifndef NULL +#define NULL ((char *)0) +#endif /* NULL */ + +#ifndef NUL +#define NUL '\000' +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + + +/* Internal data declared global */ + + +/* Internal routines */ + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void dosrch, (char *ifnm)); +_PROTOTYPE(void shwlin, (char *fnm, int linnum, char *line)); +_PROTOTYPE(int matlin, (char *line)); +_PROTOTYPE(void regerror, (char *s)); + +/* External data */ + +#define Shwline S_wlin + + +/* Local data */ + +static int Debug = {FALSE}; /* Debug enabled flag */ +static int Lcur = {0}; /* Current line (in Lines array) */ +static char **Lines = {NULL}; /* Lines pointer array */ +static int Linlen = {100}; /* Line length */ +static int Lone = {0}; /* Line one (in Lines array) */ +static int Nmr = {0}; /* Number of matched regions */ +static char *Pat = {NULL}; /* Pattern */ +static char Shwfile = {TRUE}; /* Show file name... */ +static char Shwline = {TRUE}; /* Show line number */ +static int Waft = {0}; /* Window after */ +static int Wbef = {0}; /* Window before */ +static int Wsiz = {0}; /* Window size */ + +regexp *Re; /* Result from reg compilation */ + +int main(argc, argv) +int argc; /* Argument count */ +char **argv; /* Argument values */ + +{ + int i; /* Scratch */ + int n; /* Scratch again */ + int c; /* A character */ + char *aptr; /* Argument pointer */ + int nf; /* number of files on command line */ + + nf = 0; /* No files on line */ + + for (i = 1; i < argc; i++) { /* Look at args */ + if (argv[i][0] != '-') {/* If option */ + if (Pat == NULL) { /* If no pattern yet given */ + Pat = argv[i]; /* point here */ +#ifdef REGEX + if ((Re = re_comp(Pat)) != NULL) { + fprintf(stderr, "cgrep: %s\n", re); + exit(1); + } +#endif /* REGEX */ + +#ifdef REGCMP + if ((Re = regcomp(Pat)) == NULL) { + fprintf(stderr, "cgrep: error in regular expression.\n"); + exit(1); + } +#endif /* REGCMP */ + + } else { /* This must be a file to search */ + nf++; /* Count it */ + dosrch(argv[i]); /* Search */ + } + } else { /* Option char */ + c = argv[i][1]; /* Get option char */ + if (isupper(c)) /* Trap idiot definition of tolower */ + c = tolower(c); /* Don't care about case */ + n = i; + aptr = NULL; /* Find arg, if any */ + if (argv[i][2] != NUL) { + aptr = &argv[i][2]; + n = i; /* Where to set i if we use this arg */ + } else if (i < argc - 1) { /* use next.. */ + n = i + 1; + aptr = argv[n]; + } + switch (c) { /* Process the option */ + case 'a': /* Lines after */ + Waft = atoi(aptr); + Lines = NULL; + i = n; + break; + + case 'b': /* Lines before */ + Wbef = atoi(aptr); + Lines = NULL; + i = n; + break; + +/* Disable debug output + case 'd': Debug = TRUE; break; +*/ + + case 'f': /* Suppress filename on output */ + Shwfile = FALSE; + break; + + case 'l': /* Line length */ + Linlen = atoi(aptr); + Lines = NULL; + i = n; + break; + + case 'n': /* Suppress line number on output */ + Shwline = FALSE; + break; + + case 'w': /* Window: lines before and after */ + Waft = Wbef = atoi(aptr); + Lines = NULL; + i = n; + break; + + default: + fprintf(stderr, "Invalid option %s\n", argv[i]); + exit(1); + } + } + } + + if (Pat == NULL) { /* If no pattern given */ + fprintf(stderr, + "usage: cgrep [-a n] [-b n] [-f] [-l n] [-n] [-w n] pattern [filename... ]\n"); + exit(1); + } + if (nf == 0) /* No files processed ? */ + dosrch((char *)NULL); /* Do standard input */ + return(0); +} + + /* Dosrch (ifnm) Perform the search + * Accepts : + * + * ifn Input file name + * + * + * Returns : + * + * + */ + +void dosrch(ifnm) +char *ifnm; /* Input filelname */ + +{ + FILE *ifp; /* Input fp */ + char *lptr; /* Line pointer */ + int i; /* Scratch */ + int prtaft; /* Print-after count */ + int linnum; /* Line number */ + int nlb; /* Number of lines buffered */ + + if (ifnm != NULL) { /* If file name given */ + ifp = fopen(ifnm, "r"); /* Open it for read access */ + if (ifp == NULL) { + fprintf(stderr, "Can not open file %s\n", ifnm); + return; + } + } else + ifp = stdin; + + if (Lines == NULL) { /* If no line table allocated.. */ + Wsiz = Wbef + 2; /* Determine total window size */ + Lines = (char **) calloc((size_t)Wsiz, sizeof(char *)); + /* Allocate pointer table */ + for (i = 0; i < Wsiz; i++) /* Allocate line buffers */ + Lines[i] = (char *) calloc((size_t)Linlen, sizeof(char)); + } + Lcur = Lone = 0; /* Setup line pointers */ + nlb = 0; /* No lines buffered */ + linnum = 0; /* Line number is zero */ + prtaft = -(Wbef + 1); /* Make sure separator given first time */ + + for (;;) { /* Loop through the file */ + lptr = Lines[Lcur]; /* Get pointer to current line */ + if (++Lcur == Wsiz) /* Bump curr pointer and wrap */ + Lcur = 0; /* if hit end */ + if (Lone == Lcur) /* If wrapped to beginning of window */ + if (++Lone == Wsiz) /* Bump beginning */ + Lone = 0; /* and wrap if hit end */ + + if (fgets(lptr, Linlen, ifp) != lptr) break; /* if end of file */ + + linnum++; /* Count line number */ + if (matlin(lptr)) { /* If matching line */ + if (prtaft < (-Wbef)) /* Check for separator needed */ + if ((Nmr++ > 0) && ((Wbef > 0) || (Waft > 0))) + printf("----------------------------------------------------------------------------\n"); + while (Lone != Lcur) { /* Until we close the window */ + shwlin(ifnm, linnum - nlb, Lines[Lone]); + /* Show the line */ + if (++Lone == Wsiz) Lone = 0; + nlb--; + } + nlb = 0; /* No lines buffered */ + prtaft = Waft; /* Print n lines after */ + } else { /* Didn't match */ + if (prtaft-- > 0) { /* If must print lines after */ + shwlin(ifnm, linnum, lptr); + /* Show the line */ + Lone = Lcur; /* Match pointers */ + } else if (nlb < Wbef) /* Count lines buffered */ + nlb++; + } + } + + if (ifnm != NULL) fclose(ifp); +} + + /* Shwlin (fnm, linnum, line) Show a matching line + * + * Accepts : + * + * fnm File name + * + * linnum Line number + * + * line Line to show + * + * + * Returns : + * + * + */ + +void shwlin(fnm, linnum, line) +char *fnm; /* File name */ +int linnum; /* Line number */ +char *line; /* Line (with newline at end) to print */ + +{ + if (Shwfile && (fnm != NULL)) printf("%s%s", fnm, Shwline ? " " : ":"); + if (Shwline) printf("@%05d:", linnum); + printf("%s", line); +} + + /* Matlin (line) Perform match against pattern and line + * + * Accepts : + * + * line Address of line to match + * + * + * Returns : + * + * TRUE if match FALSE if not + * + * + */ + + +int matlin(line) +char *line; /* Line to match */ + +{ + int rtncode; /* Return value from this routine */ + + +#ifdef NOREGEXP + char *pptr, *lptr, *tlptr; + int c1, c2; +#endif /* NOREGEXP */ + + if (Debug) printf("Matching %s against %s", Pat, line); + +#ifdef REGEX + rtncode = re_exec(line); /* Hand off to r/e evaluator */ +#endif /* REGEX */ + +#ifdef REGCMP + rtncode = (regexec(Re, line/*, TRUE*/) != 0); +#endif /* REGCMP */ + +#ifdef NOREGEX /* Have to do menial comparison.. */ + lptr = line; /* Init line pointer */ + + for (rtncode = -1; rtncode < 0;) { + tlptr = lptr++; /* Get temp ptr to line */ + pptr = Pat; /* Get ptr to pattern */ + while (TRUE) { + if ((c1 = *pptr++) == NUL) { + rtncode = 1; /* GOOD return value */ + break; + } + if ((c2 = *tlptr++) == NUL) { + rtncode = 0; /* BAD return value */ + break; + } + if (isupper(c1)) c1 = tolower(c1); + if (isupper(c2)) c2 = tolower(c2); + if (c1 != c2) break; + } + } +#endif /* NOREGEX */ + + + if (Debug) printf("matlin returned %s\n", rtncode ? "TRUE" : "FALSE"); + return(rtncode); +} + + + +void regerror(s) +char *s; +{ + printf("%s\n", s); + exit(1); +} diff --git a/src/simple/chgrp.c b/src/simple/chgrp.c new file mode 100755 index 00000000..be13fba8 --- /dev/null +++ b/src/simple/chgrp.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Most simple built-in commands are here. + */ + +#include +#include +#include +#include +#include +#include + +#define isdecimal(ch) (((ch) >= '0') && ((ch) <= '9')) + +int main(int argc, char *argv[]) { + char *cp; + int ret = 0, gid; + struct group *grp; + struct stat statbuf; + + if (--argc < 2) { + fprintf(stderr, "usage: chgrp gid filename ...\n"); + return 0; + } + ++argc; + cp = *argv++; + if (isdecimal(*cp)) { + for (gid = 0; isdecimal(*cp); ++cp) + gid = gid * 10 + (*cp - '0'); + if (*cp) { + fprintf(stderr, "Bad gid value %s\n", cp); + return 1; + } + } + else { + if (NULL == (grp = getgrnam(cp))) { + fprintf(stderr, "Unknown group name %s\n", cp); + return 2; + } + gid = grp->gr_gid; + } + for (; --argc >= 0; ++argv) { + if ((stat(*argv, &statbuf) < 0) || + (chown(*argv, statbuf.st_uid, gid) < 0)) { + perror(*argv); + ret = 3; + } + } + return ret; +} diff --git a/src/simple/chmod.c b/src/simple/chmod.c new file mode 100755 index 00000000..b4674f3b --- /dev/null +++ b/src/simple/chmod.c @@ -0,0 +1,110 @@ +/* C H M O D . C + * + * Usage: chmod asciimode|octalmode file(s) + * Where: + * asciimode: the mode to set, use [ugoa][-+][rwx] to: + * apply to (u)ser, (g)roup, (o)ther or (a)ll [default: u] + * remove(-) or set(+) bits [required], + * apply to the (r)ead, (w)rite, e(x)ec bits + * octalmode: mode as an octal number + * file(s): the files to process + */ +#include +#include +#include +#include +#include + +static int buildmask(register char *s, int *owner, int *setflag, + int *readmode, int *writemode, int *execmode) { + register int state = 0; + + *owner = *readmode = *writemode = *execmode = 0; + for (; *s; ++s) { + switch (state) { + case 0: /* expecting owner info */ + if (*s == 'u') *owner |= S_IRWXU; + else if (*s == 'g') *owner |= S_IRWXG; + else if (*s == 'o') *owner |= S_IRWXO; + else if (*s == 'a') *owner |= (S_IRWXU | S_IRWXG | S_IRWXO); + else if (*s == '-' || *s == '+') { + *owner |= S_IRWXU; + s--; + } + else return 0; + state = 1; + break; + + case 1: /* expecting set or remove info */ + if (*s == '-') *setflag = 0; + else if (*s == '+') *setflag = 1; + else return 0; + state = 2; + break; + + case 2: /* expecting modebits info */ + if (*s == 'r') *readmode = (S_IRUSR|S_IRGRP|S_IROTH); + else if (*s == 'w') *writemode = (S_IWUSR|S_IWGRP|S_IWOTH); + else if (*s == 'x') *execmode = (S_IXUSR|S_IXGRP|S_IXOTH); + else return 0; + break; + } + } + return 1; /* successful parsing */ +} + +int main(argc, argv) + int argc; + char **argv; +{ + int owner, setflag, readmode, writemode, execmode, newmode; + int octal = 0, ret = 0, mode; + char *cp = *++argv; + struct stat statbuf; + + if (--argc == 0) { + fprintf(stderr, "usage: chmod asciimode|octalmode filename ...\n"); + return 0; + } + if (*cp >= '0' && *cp <= '7') { + for (mode = 0; *cp >= '0' && *cp <= '7'; ++cp) { + mode <<= 3; + mode += *cp - '0'; + } + if (*cp) { + fprintf(stderr, "Bad octal mode\n"); + return 1; + } + octal = 1; + } + else if (!buildmask(cp, &owner, &setflag, &readmode, + &writemode, &execmode)) { + fprintf(stderr, "Bad ascii mode %s\n", cp); + return 1; + } + while (--argc >= 1) { + cp = *++argv; + if (stat(cp, &statbuf)) { + fprintf(stderr, "Can't stat "); + perror(cp); + ++ret; + continue; + } + if (octal) + newmode = mode; + else { + newmode = statbuf.st_mode; + if (setflag) + newmode |= (readmode | writemode | execmode) & owner; + else newmode &= ~((readmode | writemode | execmode) & owner); + } + if (chmod(cp, newmode)) { + ++ret; + fprintf(stderr, "Problems setting octal mode %o for ", + newmode); + perror(cp); + } + } + return ret; +} + \ No newline at end of file diff --git a/src/simple/chown.c b/src/simple/chown.c new file mode 100755 index 00000000..4f44a8e2 --- /dev/null +++ b/src/simple/chown.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Most simple built-in commands are here. + */ + +#include +#include +#include +#include +#include +#include + +#define isdecimal(ch) (((ch) >= '0') && ((ch) <= '9')) + +int main(int argc, char *argv[]) { + char *cp; + int ret = 0, uid; + struct passwd *pwd; + struct stat statbuf; + + if (--argc < 2) { + fprintf(stderr, "usage: chown uid filename ...\n"); + return 1; + } + ++argv; + cp = *argv++; + if (isdecimal(*cp)) { + for (uid = 0; isdecimal(*cp); ++cp) + uid = uid * 10 + (*cp - '0'); + if (*cp) { + fprintf(stderr, "Bad uid value %s\n", cp); + return 2; + } + } + else { + if (NULL == (pwd = getpwnam(cp))) { + fprintf(stderr, "Unknown user name %s\n", cp); + return; + } + uid = pwd->pw_uid; + } + for (; --argc >= 0; ++argv) { + if ((stat(*argv, &statbuf) < 0) || + (chown(*argv, uid, statbuf.st_gid) < 0)) { + perror(*argv); + ret = 3; + } + } + return ret; +} diff --git a/src/simple/cksum.c b/src/simple/cksum.c new file mode 100755 index 00000000..bfa64cbf --- /dev/null +++ b/src/simple/cksum.c @@ -0,0 +1,159 @@ +/* cksum.c - Display file checksums and block counts Author: V. Archer */ + +/* Copyright 1991 by Vincent Archer + * You may freely redistribute this software, in source or binary + * form, provided that you do not alter this copyright mention in any + * way. + */ + +#include +#include +#include +#include + +int error; + +/* Table from P1003.2 (4.9/Fig 4.1). In fact, this table was taken from zmodem + * and rewritten to look like the Draft 11 example. + */ +unsigned long crctab[] = { + 0x7fffffff, + 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, + 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, + 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, + 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, + 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, + 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, + 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, + 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, + 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, + 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, + 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, + 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, + 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, + 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, + 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, + 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, + 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, + 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, + 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, + 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, + 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, + 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, + 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, + 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, + 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, + 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, + 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, + 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, + 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, + 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, + 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, + 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, + 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, + 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void crc, (int fd, char *name)); +_PROTOTYPE(unsigned long strncrc, (unsigned char *b, int n, unsigned long s)); + +static int aux; + +/* Routine straight out of 4.9.10 */ +unsigned long strncrc(b, n, s) +register unsigned char *b; /* byte sequence to checksum */ +register int n; /* length of sequence */ +register unsigned long s; /* initial checksum value */ +{ + register int i; + + while (n-- > 0) { + /* Compute the index to the crc table */ + i = (s >> 24) ^ ((unsigned int) (*b++)); + + if (i == 0) { + /* Replace an intermediate zero with the next value + * from the sequence */ + i = aux++; + if (aux >= sizeof(crctab) / sizeof(crctab[0])) aux = 0; + } + + /* New checksum value */ + s = (s << 8) ^ crctab[i]; + } + return(s); +} + +/* Main module. No options switches allowed, none parsed. */ +int main(argc, argv) +int argc; +char *argv[]; +{ + argc--; + error = 0; + if (!argc) + crc(0, (char *) 0); + else + for (argv++; argc--; argv++) crc(open(*argv, O_RDONLY), *argv); + return(error); +} + +/* Compute crc and size of input file descriptor. */ +void crc(fd, name) +int fd; +char *name; +{ + off_t f_size; + unsigned long crc; + int nb; + unsigned char buffer[1024]; + + if (fd < 0) { + perror(name); + error = 1; + return; + } + crc = 0; + f_size = 0; + aux = 0; + for (;;) { + nb = read(fd, (char *) buffer, sizeof(buffer)); + if (nb < 0) { + close(fd); + perror(name ? name : "stdin"); + error = 1; + return; + } + if (!nb) break; + f_size += nb; + crc = strncrc(buffer, nb, crc); + } + close(fd); + printf("%lu %ld", crc, f_size); + if (name) + printf(" %s\n", name); + else + putchar('\n'); +} diff --git a/src/simple/cmp.c b/src/simple/cmp.c new file mode 100755 index 00000000..6d1fcca7 --- /dev/null +++ b/src/simple/cmp.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Most simple built-in commands are here. + */ +#include +#include +#include +#include +#include + +int main(argc, argv) + int argc; + char **argv; +{ + int fd1, fd2; + int cc1, cc2, sts = 0; + long pos; + char *srcname, *destname, *lastarg; + char *bp1, *bp2, buf1[512], buf2[512]; + struct stat statbuf1, statbuf2; + + if (argc < 3) { + /*fprintf(stderr, "usage: cmp [-cls] file1 [file2]\n");*/ + fprintf(stderr, "usage: cmp file1 file2\n"); + return 0; + } + if (stat(argv[1], &statbuf1) < 0) { + perror(argv[1]); + return 9; + } + if (stat(argv[2], &statbuf2) < 0) { + perror(argv[2]); + return 9; + } + if ((statbuf1.st_dev == statbuf2.st_dev) && + (statbuf1.st_ino == statbuf2.st_ino)) + { + printf("Files are links to each other\n"); + return 9; + } +#if 1 /* Nick */ + if (memcmp(&statbuf1.st_size, &statbuf2.st_size, sizeof(off_t))) { +#else + if (statbuf1.st_size != statbuf2.st_size) { +#endif + printf("Files are different sizes\n"); + return 9; + } + if ((fd1 = open(argv[1], 0)) < 0) { + perror(argv[1]); + return 9; + } + if (argc == 2) + fd2 = 1; + else if ((fd2 = open(argv[2], 0)) < 0) { + perror(argv[2]); + close(fd1); + return 9; + } + for (pos = 0; ; ) { + if ((cc1 = read(fd1, buf1, sizeof(buf1))) < 0) { + perror(argv[1]); + goto Eof; + } + if ((cc2 = read(fd2, buf2, sizeof(buf2))) < 0) { + perror(argv[2]); + goto Eof; + } + if ((cc1 == 0) && (cc2 == 0)) { + printf("Files are identical\n"); + goto Eof; + } + if (cc1 < cc2) { + sts = 2; + printf("First file is shorter than second\n"); + goto Eof; + } + if (cc1 > cc2) { + sts = 2; + printf("Second file is shorter than first\n"); + goto Eof; + } + if (memcmp(buf1, buf2, cc1) == 0) { + pos += cc1; + continue; + } + for (bp1 = buf1, bp2 = buf2; *bp1++ == *bp2++; ++pos) + ; + printf("Files differ at byte position %ld\n", pos); + sts = 1; + goto Eof; + } +Eof: close(fd1); + close(fd2); + return sts; +} + diff --git a/src/simple/cp.c b/src/simple/cp.c new file mode 100755 index 00000000..cc965a61 --- /dev/null +++ b/src/simple/cp.c @@ -0,0 +1,1336 @@ +/* cp 1.9 - copy files Author: Kees J. Bot + * mv - move files 20 Jul 1993 + * rm - remove files + * ln - make a link + * cpdir - copy a directory tree (cp -psmr) + * clone - make a link farm (ln -fmr) + */ +#define nil 0 +#define const /* Nick */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Nick to access open() etc */ +#include +#ifndef DEBUG +#define DEBUG 0 +#define NDEBUG 1 +#endif +#include + +#define ssize_t int + +/* Copy files in this size chunks: */ +#if __minix && !__minix_vmd +#define CHUNK (8192 * sizeof(char *)) +#else +#if defined(MSX_UZIX_TARGET) || defined(PC_UZIX_TARGET) +#define CHUNK 2048 +#else +#define CHUNK (1024 << (sizeof(int) + sizeof(char *))) +#endif +#endif + +#if defined(MSX_UZIX_TARGET) || defined(PC_UZIX_TARGET) +#define LINKSIZE 128+1 +#else +#define LINKSIZE 1024+1 +#endif + +#ifndef CONFORMING +#define CONFORMING 1 /* Precisely POSIX conforming. */ +#endif + +#define arraysize(a) (sizeof(a) / sizeof((a)[0])) +#define arraylimit(a) ((a) + arraysize(a)) + +#if defined(MSX_UZIX_TARGET) || defined(PC_UZIX_TARGET) +#define LONG(x) (long)(x.t_time+x.t_date*65536) +#define S_ISFIFO S_ISPIPE +#define getegid getgid +#define geteuid getuid +#define mkfifo(x,y) 0 +#else +#define LONG(x) x +#endif + +char *prog_name; /* Call name of this program. */ +int ex_code= 0; /* Final exit code. */ + +typedef enum identity { CP, MV, RM, LN, CPDIR, CLONE } identity_t; +typedef enum action { COPY, MOVE, REMOVE, LINK } action_t; + +identity_t identity; /* How did the user call me? */ +action_t action; /* Copying, moving, or linking. */ +int pflag= 0; /* -p/-s: Make orginal and copy the same. */ +int iflag= 0; /* -i: Interactive overwriting/deleting. */ +int fflag= 0; /* -f: Force. */ +int sflag= 0; /* -s: Make a symbolic link (ln/clone). */ +int capital_Sflag= 0; /* Nick /* -S: Make a symlink if across devices. */ +int mflag= 0; /* -m: Merge trees, no target dir trickery. */ +int rflag= 0; /* -r/-R: Recursively copy a tree. */ +int vflag= 0; /* -v: Verbose. */ +int xflag= 0; /* -x: Don't traverse past mount points. */ +int xdev= 0; /* Set when moving or linking cross-device. */ +int expand= 0; /* Expand symlinks, ignore links. */ +int conforming= CONFORMING; /* Sometimes standards are a pain. */ + +int fc_mask; /* File creation mask. */ +int uid, gid; /* Effective uid & gid. */ +int istty; /* Can have terminal input. */ + +#ifndef S_ISLNK +/* There were no symlinks in medieval times. */ +#define S_ISLNK(mode) (0) +#define lstat stat +#define symlink(path1, path2) (errno= ENOSYS, -1) +#define readlink(path, buf, len) (errno= ENOSYS, -1) +#endif + +void report(const char *label) +{ + if (action == REMOVE && fflag) return; + fprintf(stderr, "%s: %s: %s\n", prog_name, label, strerror(errno)); + ex_code= 1; +} + +void fatal(const char *label) +{ + report(label); + exit(1); +} + +void report2(const char *src, const char *dst) +{ + fprintf(stderr, "%s %s %s: %s\n", prog_name, src, dst, strerror(errno)); + ex_code= 1; +} + +#if DEBUG +size_t nchunks= 0; /* Number of allocated cells. */ +#endif + +void *allocate(void *mem, size_t size) +/* Like realloc, but with checking of the return value. */ +{ +#if DEBUG + if (mem == nil) nchunks++; +#endif + if ((mem= mem == nil ? malloc(size) : realloc(mem, size)) == nil) + fatal("malloc()"); + return mem; +} + +void deallocate(void *mem) +/* Release a chunk of memory. */ +{ + if (mem != nil) { +#if DEBUG + nchunks--; +#endif + free(mem); + } +} + +typedef struct pathname { + char *path; /* The actual pathname. */ + size_t idx; /* Index for the terminating null byte. */ + size_t lim; /* Actual length of the path array. */ +} pathname_t; + +void path_init(pathname_t *pp) +/* Initialize a pathname to the null string. */ +{ + pp->path= allocate(nil, pp->lim= 16); + pp->path[pp->idx= 0]= 0; +} + +void path_add(pathname_t *pp, const char *name) +/* Add a component to a pathname. */ +{ + size_t lim; + char *p; + + lim= pp->idx + strlen(name) + 2; + + if (lim > pp->lim) { + pp->lim= lim += lim/2; /* add an extra 50% growing space. */ + + pp->path= allocate(pp->path, lim); + } + + p= pp->path + pp->idx; + if (p > pp->path && p[-1] != '/') *p++ = '/'; + + while (*name != 0) { + if (*name != '/' || p == pp->path || p[-1] != '/') + *p++ = *name; + name++; + } + *p = 0; + pp->idx= p - pp->path; +} + +void path_trunc(pathname_t *pp, size_t didx) +/* Delete part of a pathname to a remembered length. */ +{ + pp->path[pp->idx= didx]= 0; +} + +#if DEBUG +const char *path_name(const pathname_t *pp) +/* Return the actual name as a C string. */ +{ + return pp->path; +} + +size_t path_length(const pathname_t *pp) +/* The length of the pathname. */ +{ + return pp->idx; +} + +void path_drop(pathname_t *pp) +/* Release the storage occupied by the pathname. */ +{ + deallocate(pp->path); +} + +#else /* !DEBUG */ +#define path_name(pp) ((const char *) (pp)->path) +#define path_length(pp) ((pp)->idx) +#define path_drop(pp) deallocate((void *) (pp)->path) +#endif /* !DEBUG */ + +char *basename(const char *path) +/* Return the last component of a pathname. (Note: declassifies a const + * char * just like strchr. + */ +{ + const char *p= path; + + for (;;) { + while (*p == '/') p++; /* Trailing slashes? */ + + if (*p == 0) break; + + path= p; + while (*p != 0 && *p != '/') p++; /* Skip component. */ + } + return (char *) path; +} + +int affirmative(void) +/* Get a yes/no answer from the suspecting user. */ +{ + int c; + int ok; + + fflush(stdout); + fflush(stderr); + + while ((c= getchar()) == ' ') {} + ok= (c == 'y' || c == 'Y'); + while (c != EOF && c != '\n') c= getchar(); + + return ok; +} + +int writable(const struct stat *stp) +/* True iff the file with the given attributes allows writing. (And we have + * a terminal to ask if ok to overwrite.) + */ +{ + if (!istty || uid == 0) return 1; + if (stp->st_uid == uid) return stp->st_mode & S_IWUSR; + if (stp->st_gid == gid) return stp->st_mode & S_IWGRP; + return stp->st_mode & S_IWOTH; +} + +int trylink(const char *src, const char *dst, struct stat *srcst, + struct stat *dstst) +/* Keep the link structure intact if src has been seen before. */ +{ + typedef struct oldlink { + struct oldlink *next; + char *olddst; + dev_t dev; + ino_t ino; + ino_t count; + } oldlink_t; + static oldlink_t *oldies[0x100]; + oldlink_t *op, **pop; + int found, linked; + +#if DEBUG + if (src == nil) { + /* Time to clean house (consistency freak on the loose). */ + for (pop= oldies; pop < arraylimit(oldies); pop++) { + while ((op= *pop) != nil) { + *pop= op->next; + deallocate(op->olddst); + deallocate(op); + } + } + return 0; + } +#endif + if (action == COPY && expand) return 0; + + pop= &oldies[(unsigned) srcst->st_ino % arraysize(oldies)]; + found= 0; + + while ((op= *pop) != nil && srcst->st_ino <= op->ino) { + if (srcst->st_ino == op->ino && srcst->st_dev == op->dev) { + found= 1; + break; + } + pop= &op->next; + } + + if (!found) { + if (srcst->st_nlink > 1) { + /* Remember this one for later. */ + op= allocate(nil, sizeof(*op)); + op->olddst= allocate(nil, + (strlen(dst) + 1) * sizeof(*op->olddst)); + strcpy(op->olddst, dst); + op->ino= srcst->st_ino; + op->dev= srcst->st_dev; + op->count= srcst->st_nlink; + op->next= *pop; + *pop= op; + } + return 0; + } + /* Try to link the file copied earlier to the new file. */ + if (dstst->st_ino != 0) (void) unlink(dst); + + if ((linked= (link(op->olddst, dst) == 0)) && vflag) + printf("ln %s %s\n", op->olddst, dst); + + if (--op->count == 1) { + /* All the links to the file have been seen. */ + *pop= op->next; + deallocate(op->olddst); + deallocate(op); + } + return linked; +} + +int copy(const char *src, const char *dst, struct stat *srcst, + struct stat *dstst) +/* Copy one file to another and copy (some of) the attributes. */ +{ + char buf[CHUNK]; + int srcfd, dstfd; + ssize_t n; + + assert(srcst->st_ino != 0); + + if (dstst->st_ino == 0) { + /* The file doesn't exist yet. */ + + if (!S_ISREG(srcst->st_mode)) { + /* Making a new mode 666 regular file. */ + srcst->st_mode= (S_IFREG | 0666) & fc_mask; + } else + if (!pflag && conforming) { + /* Making a new file copying mode with umask applied. */ + srcst->st_mode &= fc_mask; + } + } else { + /* File exists, ask if ok to overwrite if '-i'. */ + + if (iflag || (action == MOVE && !fflag && !writable(dstst))) { + fprintf(stderr, "Overwrite %s? (mode = %03o) ", + dst, dstst->st_mode & 07777); + if (!affirmative()) return 0; + } + + if (action == MOVE) { + /* Don't overwrite, remove first. */ + if (unlink(dst) < 0 && errno != ENOENT) { + report(dst); + return 0; + } + } else { + /* Overwrite. */ + if (!pflag) { + /* Keep the existing mode and ownership. */ + srcst->st_mode= dstst->st_mode; + srcst->st_uid= dstst->st_uid; + srcst->st_gid= dstst->st_gid; + } + } + } + + /* Keep the link structure if possible. */ + if (trylink(src, dst, srcst, dstst)) return 1; + + if ((srcfd= open(src, O_RDONLY)) < 0) { + report(src); + return 0; + } + + dstfd= open(dst, O_WRONLY|O_CREAT|O_TRUNC, srcst->st_mode & 0777); + if (dstfd < 0 && fflag && errno == EACCES) { + /* Retry adding a "w" bit. */ + (void) chmod(dst, dstst->st_mode | S_IWUSR); + dstfd= open(dst, O_WRONLY|O_CREAT|O_TRUNC, 0); + } + if (dstfd < 0 && fflag && errno == EACCES) { + /* Retry after trying to delete. */ + (void) unlink(dst); + dstfd= open(dst, O_WRONLY|O_CREAT|O_TRUNC, 0); + } + if (dstfd < 0) { + report(dst); + close(srcfd); + return 0; + } + + /* Get current parameters. */ + if (fstat(dstfd, dstst) < 0) { + report(dst); + close(srcfd); + close(dstfd); + return 0; + } + + /* Copy the little bytes themselves. */ + while ((n= read(srcfd, buf, sizeof(buf))) > 0) { + char *bp = buf; + ssize_t r; + + while (n > 0 && (r= write(dstfd, bp, n)) > 0) { + bp += r; + n -= r; + } + if (r <= 0) { + if (r == 0) { + fprintf(stderr, + "%s: Warning: EOF writing to %s\n", + prog_name, dst); + break; + } + fatal(dst); + } + } + + if (n < 0) { + report(src); + close(srcfd); + close(dstfd); + return 0; + } + + close(srcfd); + close(dstfd); + + /* Copy the ownership. */ + if ((pflag || !conforming) + && S_ISREG(dstst->st_mode) + && (dstst->st_uid != srcst->st_uid + || dstst->st_gid != srcst->st_gid) + ) { + if (chmod(dst, 0) == 0) dstst->st_mode&= ~07777; + if (chown(dst, srcst->st_uid, srcst->st_gid) < 0) { + if (errno != EPERM) { + report(dst); + return 0; + } + } else { + dstst->st_uid= srcst->st_uid; + dstst->st_gid= srcst->st_gid; + } + } + + if (conforming && S_ISREG(dstst->st_mode) + && (dstst->st_uid != srcst->st_uid + || dstst->st_gid != srcst->st_gid) + ) { + /* Suid bits must be cleared in the holy name of + * security (and the assumed user stupidity). + */ + srcst->st_mode&= ~06000; + } + + /* Copy the mode. */ + if (S_ISREG(dstst->st_mode) && dstst->st_mode != srcst->st_mode) { + if (chmod(dst, srcst->st_mode) < 0) { + if (errno != EPERM) { + report(dst); + return 0; + } + fprintf(stderr, "%s: Can't change the mode of %s\n", + prog_name, dst); + } + } + + /* Copy the file modification time. */ + if ((pflag || !conforming) && S_ISREG(dstst->st_mode)) { + struct utimbuf ut; + time_t _now; + + time(&_now); +#ifdef HI_TECH_C + if (action == MOVE) { + _now.t_time=srcst->st_atime.t_time; + _now.t_date=srcst->st_atime.t_date; + } + ut.actime.t_time=_now.t_time; + ut.actime.t_date=_now.t_date; + _now.t_time=srcst->st_mtime.t_time; + _now.t_date=srcst->st_mtime.t_date; + ut.modtime.t_time=_now.t_time; + ut.modtime.t_date=_now.t_date; +#else + ut.actime= action == MOVE ? srcst->st_atime : _now; + ut.modtime= srcst->st_mtime; +#endif + if (utime(dst, &ut) < 0) { + if (errno != EPERM) { + report(dst); + return 0; + } + if (pflag) { + fprintf(stderr, + "%s: Can't set the time of %s\n", + prog_name, dst); + } + } + } + if (vflag) { + printf(action == COPY ? "cp %s %s\n" : "mv %s %s\n", src, dst); + } + return 1; +} + +void copy1(const char *src, const char *dst, struct stat *srcst, + struct stat *dstst) +/* Inspect the source file and then copy it. Treatment of symlinks and + * special files is a bit complicated. The filetype and link-structure are + * ignored if (expand && !rflag), symlinks and link-structure are ignored + * if (expand && rflag), everything is copied precisely if !expand. + */ +{ + int r, linked; + + assert(srcst->st_ino != 0); + + if (srcst->st_ino == dstst->st_ino && srcst->st_dev == dstst->st_dev) { + fprintf(stderr, "%s: can't copy %s onto itself\n", + prog_name, src); + ex_code= 1; + return; + } + + /* You can forget it if the destination is a directory. */ + if (dstst->st_ino != 0 && S_ISDIR(dstst->st_mode)) { + errno= EISDIR; + report(dst); + return; + } + + if (S_ISREG(srcst->st_mode) || (expand && !rflag)) { + if (!copy(src, dst, srcst, dstst)) return; + + if (action == MOVE && unlink(src) < 0) { + report(src); + return; + } + return; + } + + if (dstst->st_ino != 0) { + if (iflag || (action == MOVE && !fflag && !writable(dstst))) { + fprintf(stderr, "Replace %s? (mode = %03o) ", + dst, dstst->st_mode & 07777); + if (!affirmative()) return; + } + if (unlink(dst) < 0) { + report(dst); + return; + } + dstst->st_ino= 0; + } + + /* Apply the file creation mask if so required. */ + if (!pflag && conforming) srcst->st_mode &= fc_mask; + + linked= 0; + + if (S_ISLNK(srcst->st_mode)) { + char buf[LINKSIZE]; + + if ((r= readlink(src, buf, sizeof(buf)-1)) < 0) { + report(src); + return; + } + buf[r]= 0; + r= symlink(buf, dst); + if (vflag && r == 0) + printf("ln -s %s %s\n", buf, dst); + } else + if (trylink(src, dst, srcst, dstst)) { + linked= 1; + r= 0; + } else + if (S_ISFIFO(srcst->st_mode)) { + r= mkfifo(dst, srcst->st_mode); + if (vflag && r == 0) + printf("mkfifo %s\n", dst); + } else + if (S_ISBLK(srcst->st_mode) || S_ISCHR(srcst->st_mode)) { + r= mknod(dst, srcst->st_mode, srcst->st_rdev); + if (vflag && r == 0) { + printf("mknod %s %c %d %d\n", + dst, + S_ISBLK(srcst->st_mode) ? 'b' : 'c', + (srcst->st_rdev >> 8) & 0xFF, + (srcst->st_rdev >> 0) & 0xFF); + } + } else { + fprintf(stderr, "%s: %s: odd filetype %5o (not copied)\n", + prog_name, src, srcst->st_mode); + ex_code= 1; + return; + } + + if (r < 0 || lstat(dst, dstst) < 0) { + report(dst); + return; + } + + if (action == MOVE && unlink(src) < 0) { + report(src); + (void) unlink(dst); /* Don't want it twice. */ + return; + } + + if (linked) return; + + if (S_ISLNK(srcst->st_mode)) return; + + /* Copy the ownership. */ + if ((pflag || !conforming) + && (dstst->st_uid != srcst->st_uid + || dstst->st_gid != srcst->st_gid) + ) { + if (chown(dst, srcst->st_uid, srcst->st_gid) < 0) { + if (errno != EPERM) { + report(dst); + return; + } + } + } + + /* Copy the file modification time. */ + if (pflag || !conforming) { + struct utimbuf ut; + time_t _now; + + time(&_now); + ut.actime= action == MOVE ? srcst->st_atime : _now; + ut.modtime= srcst->st_mtime; + if (utime(dst, &ut) < 0) { + if (errno != EPERM) { + report(dst); + return; + } + fprintf(stderr, "%s: Can't set the time of %s\n", + prog_name, dst); + } + } +} + +void remove1(const char *src, struct stat *srcst) +{ + if (iflag || (!fflag && !writable(srcst))) { + fprintf(stderr, "Remove %s? (mode = %03o) ", src, + srcst->st_mode & 07777); + if (!affirmative()) return; + } + if (unlink(src) < 0) { + report(src); + } else { + if (vflag) printf("rm %s\n", src); + } +} + +void link1(const char *src, const char *dst, struct stat *srcst, + struct stat *dstst) +{ + pathname_t sym; + const char *p; + + if (dstst->st_ino != 0 && (iflag || fflag)) { + if (srcst->st_ino == dstst->st_ino) { + if (fflag) return; + fprintf(stderr, "%s: Can't link %s onto itself\n", + prog_name, src); + ex_code= 1; + return; + } + if (iflag) { + fprintf(stderr, "Remove %s? ", dst); + if (!affirmative()) return; + } + errno= EISDIR; + if (S_ISDIR(dstst->st_mode) || unlink(dst) < 0) { + report(dst); + return; + } + } + + if (!sflag && !(rflag && S_ISLNK(srcst->st_mode)) && + !(capital_Sflag && xdev)) { /* Nick */ + /* A normal link. */ + if (link(src, dst) < 0) { + if (!capital_Sflag || errno != EXDEV) { /* Nick */ + report2(src, dst); + return; + } + /* Can't do a cross-device link, we have to symlink. */ + xdev= 1; + } else { + if (vflag) printf("ln %s %s\n", src, dst); + return; + } + } + + /* Do a symlink. */ + if (!rflag && !capital_Sflag) { /* Nick */ + /* We can get away with a "don't care if it works" symlink. */ + if (symlink(src, dst) < 0) { + report(dst); + return; + } + if (vflag) printf("ln -s %s %s\n", src, dst); + return; + } + + /* If the source is a symlink then it is simply copied. */ + if (S_ISLNK(srcst->st_mode)) { + int r; + char buf[LINKSIZE]; + + if ((r= readlink(src, buf, sizeof(buf)-1)) < 0) { + report(src); + return; + } + buf[r]= 0; + if (symlink(buf, dst) < 0) { + report(dst); + return; + } + if (vflag) printf("ln -s %s %s\n", buf, dst); + return; + } + + /* Make a symlink that has to work, i.e. we must be able to access the + * source now, and the link must work. + */ + if (dst[0] == '/' && src[0] != '/') { + /* ln -[rsS] relative/path /full/path. */ + fprintf(stderr, + "%s: Symlinking %s to %s can't be made to work, too difficult\n", + prog_name, src, dst); + exit(1); + } + + /* Count the number of subdirectories in the destination file and + * add one '..' for each. + */ + path_init(&sym); + if (src[0] != '/') { + p= dst; + while (*p != 0) { + while (*p != 0 && *p != '/') p++; + while (*p == '/') p++; + if (*p == 0) break; + path_add(&sym, ".."); + } + } + path_add(&sym, src); + + if (symlink(path_name(&sym), dst) < 0) { + report(dst); + } else { + if (vflag) printf("ln -s %s %s\n", path_name(&sym), dst); + } + path_drop(&sym); +} + +typedef struct entrylist { + struct entrylist *next; + char *name; +} entrylist_t; + +int eat_dir(const char *dir, entrylist_t **dlist) +/* Make a linked list of all the names in a directory. */ +{ + DIR *dp; + struct dirent *entry; + + if ((dp= opendir(dir)) == nil) return 0; + + while ((entry= readdir(dp)) != nil) { + if (strcmp(entry->d_name, ".") == 0) continue; + if (strcmp(entry->d_name, "..") == 0) continue; + + *dlist= allocate(nil, sizeof(**dlist)); + (*dlist)->name= allocate(nil, strlen(entry->d_name)+1); + strcpy((*dlist)->name, entry->d_name); + dlist= &(*dlist)->next; + } + closedir(dp); + *dlist= nil; + return 1; +} + +void chop_dlist(entrylist_t **dlist) +/* Chop an entry of a name list. */ +{ + entrylist_t *junk= *dlist; + + *dlist= junk->next; + deallocate(junk->name); + deallocate(junk); +} + +void drop_dlist(entrylist_t *dlist) +/* Get rid of a whole list. */ +{ + while (dlist != nil) chop_dlist(&dlist); +} + +void do1(pathname_t *src, pathname_t *dst, int depth) +/* Perform the appropriate action on a source and destination file. */ +{ + size_t slashsrc, slashdst; + struct stat srcst, dstst; + entrylist_t *dlist; + static ino_t topdst_ino; + static dev_t topdst_dev; + static dev_t topsrc_dev; + +#if DEBUG + if (vflag && depth == 0) { + char flags[100], *pf= flags; + + if (pflag) *pf++= 'p'; + if (iflag) *pf++= 'i'; + if (fflag) *pf++= 'f'; + if (sflag) *pf++= 's'; + if (capital_Sflag) *pf++= 'S'; /* Nick */ + if (mflag) *pf++= 'm'; + if (rflag) *pf++= 'r'; + if (vflag) *pf++= 'v'; + if (xflag) *pf++= 'x'; + if (expand) *pf++= 'L'; + if (conforming) *pf++= 'C'; + *pf= 0; + printf(": %s -%s %s %s\n", prog_name, flags, + path_name(src), path_name(dst)); + } +#endif + + /* st_ino == 0 if not stat()'ed yet, or nonexistent. */ + srcst.st_ino= 0; + dstst.st_ino= 0; + + if (action != LINK || !sflag || rflag) { + /* Source must exist unless symlinking. */ + if ((expand ? stat : lstat)(path_name(src), &srcst) < 0) { + report(path_name(src)); + return; + } + } + + if (depth == 0) { + /* First call: Not cross-device yet, first dst not seen yet, + * remember top device number. + */ + xdev= 0; + topdst_ino= 0; + topsrc_dev= srcst.st_dev; + } + + /* Inspect the intended destination unless removing. */ + if (action != REMOVE) { + if ((expand ? stat : lstat)(path_name(dst), &dstst) < 0) { + if (errno != ENOENT) { + report(path_name(dst)); + return; + } + } + } + + if (action == MOVE && !xdev) { + if (dstst.st_ino != 0 && srcst.st_dev != dstst.st_dev) { + /* It's a cross-device rename, i.e. copy and remove. */ + xdev= 1; + } else + if (!mflag || dstst.st_ino == 0 || !S_ISDIR(dstst.st_mode)) { + /* Try to simply rename the file (not merging trees). */ + + if (srcst.st_ino == dstst.st_ino) { + fprintf(stderr, + "%s: Can't move %s onto itself\n", + prog_name, path_name(src)); + ex_code= 1; + return; + } + + if (dstst.st_ino != 0) { + if (iflag || (!fflag && !writable(&dstst))) { + fprintf(stderr, + "Replace %s? (mode = %03o) ", + path_name(dst), + dstst.st_mode & 07777); + if (!affirmative()) return; + } + if (!S_ISDIR(dstst.st_mode)) + (void) unlink(path_name(dst)); + } + + if (rename(path_name(src), path_name(dst)) == 0) { + /* Success. */ + if (vflag) { + printf("mv %s %s\n", path_name(src), + path_name(dst)); + } + return; + } + if (errno == EXDEV) { + xdev= 1; + } else { + report2(path_name(src), path_name(dst)); + return; + } + } + } + + if (!S_ISDIR(srcst.st_mode)) { + /* Copy/move/remove/link a single file. */ + switch (action) { + case COPY: + case MOVE: + copy1(path_name(src), path_name(dst), &srcst, &dstst); + break; + case REMOVE: + remove1(path_name(src), &srcst); + break; + case LINK: + link1(path_name(src), path_name(dst), &srcst, &dstst); + break; + } + return; + } + + /* Recursively copy/move/remove/link a directory if -r or -R. */ + if (!rflag) { + errno= EISDIR; + report(path_name(src)); + return; + } + + /* Ok to remove contents of dir? */ + if (action == REMOVE) { + if (xflag && topsrc_dev != srcst.st_dev) { + /* Don't recurse past a mount point. */ + return; + } + if (iflag) { + fprintf(stderr, "Remove contents of %s? ", + path_name(src)); + if (!affirmative()) return; + } + } + + /* Gather the names in the source directory. */ + if (!eat_dir(path_name(src), &dlist)) { + report(path_name(src)); + return; + } + + /* Check/create the target directory. */ + if (action != REMOVE && dstst.st_ino != 0 && !S_ISDIR(dstst.st_mode)) { + if (action != MOVE && !fflag) { + errno= ENOTDIR; + report(path_name(dst)); + return; + } + if (iflag) { + fprintf(stderr, "Replace %s? ", path_name(dst)); + if (!affirmative()) { + drop_dlist(dlist); + return; + } + } + if (unlink(path_name(dst)) < 0) { + report(path_name(dst)); + drop_dlist(dlist); + return; + } + dstst.st_ino= 0; + } + + if (action != REMOVE) { + if (dstst.st_ino == 0) { + /* Create a new target directory. */ + if (!pflag && conforming) srcst.st_mode&= fc_mask; + + if (mkdir(path_name(dst), srcst.st_mode | S_IRWXU) < 0 + || stat(path_name(dst), &dstst) < 0) { + report(path_name(dst)); + drop_dlist(dlist); + return; + } + if (vflag) printf("mkdir %s\n", path_name(dst)); + } else { + /* Target directory already exists. */ + if (action == MOVE && !mflag) { + errno= EEXIST; + report(path_name(dst)); + drop_dlist(dlist); + return; + } + if (!pflag) { + /* Keep the existing attributes. */ + srcst.st_mode= dstst.st_mode; + srcst.st_uid= dstst.st_uid; + srcst.st_gid= dstst.st_gid; + srcst.st_mtime= dstst.st_mtime; + } + } + + if (topdst_ino == 0) { + /* Remember the top destination. */ + topdst_dev= dstst.st_dev; + topdst_ino= dstst.st_ino; + } + + if (srcst.st_ino == topdst_ino && srcst.st_dev == topdst_dev) { + /* E.g. cp -r /shallow /shallow/deep. */ + fprintf(stderr, + "%s%s %s/ %s/: infinite recursion avoided\n", + prog_name, action != MOVE ? " -r" : "", + path_name(src), path_name(dst)); + drop_dlist(dlist); + return; + } + + if (xflag && topsrc_dev != srcst.st_dev) { + /* Don't recurse past a mount point. */ + drop_dlist(dlist); + return; + } + } + + /* Go down. */ + slashsrc= path_length(src); + slashdst= path_length(dst); + + while (dlist != nil) { + path_add(src, dlist->name); + if (action != REMOVE) path_add(dst, dlist->name); + + do1(src, dst, depth+1); + + path_trunc(src, slashsrc); + path_trunc(dst, slashdst); + chop_dlist(&dlist); + } + + if (action == MOVE || action == REMOVE) { + /* The contents of the source directory should have + * been (re)moved above. Get rid of the empty dir. + */ + if (action == REMOVE && iflag) { + fprintf(stderr, "Remove directory %s? ", + path_name(src)); + if (!affirmative()) return; + } + if (rmdir(path_name(src)) < 0) { + if (errno != ENOTEMPTY) report(path_name(src)); + return; + } + if (vflag) printf("rmdir %s\n", path_name(src)); + } + + if (action != REMOVE) { + /* Set the attributes of a new directory. */ + struct utimbuf ut; + + /* Copy the ownership. */ + if ((pflag || !conforming) + && (dstst.st_uid != srcst.st_uid + || dstst.st_gid != srcst.st_gid) + ) { + if (chown(path_name(dst), srcst.st_uid, + srcst.st_gid) < 0) { + if (errno != EPERM) { + report(path_name(dst)); + return; + } + } + } + + /* Copy the mode. */ + if (dstst.st_mode != srcst.st_mode) { + if (chmod(path_name(dst), srcst.st_mode) < 0) { + report(path_name(dst)); + return; + } + } + + /* Copy the file modification time. */ + if (LONG(dstst.st_mtime) != LONG(srcst.st_mtime)) { + time_t _now; + + time(&_now); + ut.actime= action == MOVE ? srcst.st_atime : _now; + ut.modtime= srcst.st_mtime; + if (utime(path_name(dst), &ut) < 0) { + if (errno != EPERM) { + report(path_name(dst)); + return; + } + fprintf(stderr, + "%s: Can't set the time of %s\n", + prog_name, path_name(dst)); + } + } + } +} + +void usage(void) +{ + char *flags1, *flags2; + + switch (identity) { + case CP: + flags1= "pifsmrRvx"; + flags2= "pifsrRvx"; + break; + case MV: + flags1= "ifsmvx"; + flags2= "ifsvx"; + break; + case RM: + fprintf(stderr, "usage: rm [-ifrRvx] file ...\n"); + exit(1); + case LN: + flags1= "ifsSmrRvx"; + flags2= "ifsSrRvx"; + break; + case CPDIR: + flags1= "ifvx"; + flags2= nil; + break; + case CLONE: + flags1= "ifsSvx"; + flags2= nil; + break; + } + fprintf(stderr, "usage: %s [-%s] file1 file2\n", prog_name, flags1); + if (flags2 != nil) + fprintf(stderr, " %s [-%s] file ... dir\n", prog_name, flags2); + exit(1); +} + +void main(int argc, char **argv) +{ + int i; + char *flags; + struct stat st; + pathname_t src, dst; + size_t slash; + +#if DEBUG >= 3 + /* The first argument is the call name while debugging. */ + if (argc < 2) exit(-1); + argv++; + argc--; +#endif +#if DEBUG + vflag= isatty(1); +#endif + + /* Call name of this program. */ + prog_name= basename(argv[0]); + + /* Required action. */ + if (strcmp(prog_name, "cp") == 0) { + identity= CP; + action= COPY; + flags= "pifsmrRvx"; + expand= 1; + } else + if (strcmp(prog_name, "mv") == 0) { + identity= MV; + action= MOVE; + flags= "ifsmvx"; + rflag= pflag= 1; + } else + if (strcmp(prog_name, "rm") == 0) { + identity= RM; + action= REMOVE; + flags= "ifrRvx"; + } else + if (strcmp(prog_name, "ln") == 0) { + identity= LN; + action= LINK; + flags= "ifsSmrRvx"; + } else + if (strcmp(prog_name, "cpdir") == 0) { + identity= CPDIR; + action= COPY; + flags= "pifsmrRvx"; + rflag= mflag= pflag= 1; + conforming= 0; + } else + if (strcmp(prog_name, "clone") == 0) { + identity= CLONE; + action= LINK; + flags= "ifsSmrRvx"; + rflag= mflag= fflag= 1; + } else { + fprintf(stderr, + "%s: Identity crisis, not called cp, mv, rm, ln, cpdir, or clone\n", + prog_name); + exit(1); + } + + /* Who am I?, where am I?, how protective am I? */ + uid= geteuid(); + gid= getegid(); + istty= isatty(0); + fc_mask= ~umask(0); + + /* Gather flags. */ + i= 1; + while (i < argc && argv[i][0] == '-') { + char *opt= argv[i++] + 1; + + if (opt[0] == '-' && opt[1] == 0) break; /* -- */ + + while (*opt != 0) { + /* Flag supported? */ + if (strchr(flags, *opt) == nil) usage(); + + switch (*opt++) { + case 'p': + pflag= 1; + break; + case 'i': + iflag= 1; + if (action == MOVE) fflag= 0; + break; + case 'f': + fflag= 1; + if (action == MOVE) iflag= 0; + break; + case 's': + if (action == LINK) { + sflag= 1; + } else { + /* Forget about POSIX, do it right. */ + conforming= 0; + } + break; + case 'S': + capital_Sflag= 1; /* Nick */ + break; + case 'm': + mflag= 1; + break; + case 'r': + expand= 0; + /*FALL THROUGH*/ + case 'R': + rflag= 1; + break; + case 'v': + vflag= 1; + break; + case 'x': + xflag= 1; + break; + default: + assert(0); + } + } + } + + switch (action) { + case REMOVE: + if (i == argc) usage(); + break; + case LINK: + /* 'ln dir/file' is to be read as 'ln dir/file .'. */ + if ((argc - i) == 1 && action == LINK) argv[argc++]= "."; + /*FALL THROUGH*/ + default: + if ((argc - i) < 2) usage(); + } + + path_init(&src); + path_init(&dst); + + if (action != REMOVE && !mflag && stat(argv[argc-1], &st) >= 0 + && S_ISDIR(st.st_mode)) { + /* The last argument is a directory, this means we have to + * throw the whole lot into this directory. This is the + * Right Thing unless you use -r. + */ + path_add(&dst, argv[argc-1]); + slash= path_length(&dst); + + do { + path_add(&src, argv[i]); + path_add(&dst, basename(argv[i])); + + do1(&src, &dst, 0); + + path_trunc(&src, 0); + path_trunc(&dst, slash); + } while (++i < argc-1); + } else + if (action == REMOVE || (argc - i) == 2) { + /* Just two files (or many files for rm). */ + + do { + path_add(&src, argv[i]); + if (action != REMOVE) path_add(&dst, argv[i+1]); + + do1(&src, &dst, 0); + path_trunc(&src, 0); + } while (action == REMOVE && ++i < argc); + } else { + usage(); + } + path_drop(&src); + path_drop(&dst); + +#if DEBUG + (void) trylink(nil, nil, nil, nil); + if (nchunks != 0) { + fprintf(stderr, "(%ld chunks of memory not freed)\n", + (long) nchunks); + } +#endif + exit(ex_code); +} diff --git a/src/simple/cr$.c b/src/simple/cr$.c new file mode 100755 index 00000000..b53124bf --- /dev/null +++ b/src/simple/cr$.c @@ -0,0 +1,50 @@ +/* + * cr.c -- add cr's for cp/m editors + * + * syntax: + * cr file ... + */ + +#include +#include + +main(argc,argv) +int argc; +char **argv; +{ + register char c; + FILE *in,*out; + unsigned int j; + char *s; + + if (argc < 2) { + fprintf(stderr,"usage: %s file ...\n",argv[0]); + exit(1); + } + for (j = 1; j +#include + +int main(int argc, char **argv) + { + register char c; +#if 1 /* Nick */ + register char buf; +#endif + FILE *in, *out; + unsigned int j; + char *s; +#if 1 /* Nick */ + int remove; +#endif + + if (argc < 2) + { + fprintf(stderr, "usage: %s [-r] file ...\n", argv[0]); + exit(1); + } + +#if 1 /* Nick */ + remove = 0; + for (j = 1; j < argc; j++) + { + s = argv[j]; + if (*s == '-') + { + while (*++s) + { + switch (*s) + { + case 'r': + remove = 1; + break; + default: + fprintf(stderr, + "unknown switch: %s\n", s); + exit(1); + } + } + } + else + { + break; + } + } + + for (; j < argc; j++) +#else + for (j = 1; j < argc; j++) +#endif + { + in = fopen(argv[j], "rb"); + if (in == NULL) + { + perror(argv[j]); + exit(1); + } + s = tmpnam(NULL); + out = fopen(s, "wb"); + if (out == NULL) + { + perror("Can't create temporary file"); + exit(1); + } +#if 1 /* Nick */ + if (remove) + { + if ((buf = fgetc(in)) != EOF) + { + while ((c = fgetc(in)) != EOF) + { + if (buf != '\r' || c != '\n') + { + fputc(buf, out); + } + buf = c; + } + fputc(buf, out); + } + } + else + { + while ((c = fgetc(in)) != EOF) + { + if (c == '\n') + { + fputc('\r', out); + } + fputc(c, out); + } + } +#else + while ((c = fgetc(in)) != EOF) + { + if (c == '\n') + { + fputc('\r', out); + } + fputc(c, out); + } +#endif + fclose(in); + fclose(out); + + if (unlink(argv[j]) < 0) + { + perror(argv[j]); + exit(1); + } + if (rename(s, argv[j]) < 0) + { + perror(s); + exit(1); + } + } + } diff --git a/src/simple/crc.c b/src/simple/crc.c new file mode 100755 index 00000000..48dbfd3b --- /dev/null +++ b/src/simple/crc.c @@ -0,0 +1,177 @@ +/* Compute checksum Author: Johan W. Stevenson */ + +/* Copyright 1988 by Johan W. Stevenson */ + +#include +#include +#include +#include + +int errs; + +#if __STDC__ +int main(int argc, char **argv); +void crc(char *fname); +#else +void crc(); +#endif + +int main(argc, argv) +int argc; +char **argv; +{ + char line[256]; + + if (argc < 2) { + if (isatty(fileno(stdin))) { + printf("usage: crc file1 file2...\n"); + return(1); + } + crc((char *) 0); + } + else if (argc == 2 && strcmp(argv[1], "-") == 0) + while (fgets(line, sizeof line, stdin) != NULL) { + if (line[strlen(line) - 1] == '\n') + line[strlen(line) - 1] = '\0'; + crc(line); + } + else + do { + crc(argv[1]); + argv++; + argc--; + } while (argc > 1); + return(errs != 0); +} + +/* Crctab calculated by Mark G. Mendel, Network Systems Corporation */ +static unsigned short crctab[256] = +#if 1 /* Nick, Hytech algorithm for compatibility with existing EPROMs */ + { 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, + 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, + 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, + 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, + 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, + 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, + 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, + 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, + 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, + 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, + 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, + 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, + 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, + 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, + 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, + 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, + 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, + 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, + 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, + 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, + 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, + 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, + 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, + 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, + 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, + 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, + 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, + 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, + 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, + 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, + 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, + 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 }; +#else +{ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; +#endif + +/* Updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. + * NOTE: First argument must be in range 0 to 255. + * Second argument is referenced twice. + * + * Programmers may incorporate any or all code into their programs, + * giving proper credit within the source. Publication of the + * source routines is permitted so long as proper credit is given + * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, + * Omen Technology. + */ + +#if 1 /* Nick, Hytech algorithm for compatibility with existing EPROMs */ +#define updcrc(cp, crc) ((crc >> 8) ^ crctab[(crc ^ cp) & 0xff]); +#else +#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp) +#endif + +void crc(fname) +char *fname; +{ + register int c; + register long len = 0; +#if 1 /* Nick, Hytech algorithm for compatibility with existing EPROMs */ + register unsigned short crc = 0xffff; +#else + register unsigned short crc = 0; +#endif + register FILE *fp; + + if (fname == NULL) + fp = stdin; +#if 1 /* Nick */ + else if ((fp = fopen(fname, "rb")) == NULL) { +#else + else if ((fp = fopen(fname, "r")) == NULL) { +#endif + fprintf(stderr, "crc: cannot open %s\n", fname); + errs++; + return; + } + while ((c = getc(fp)) != EOF) { + len++; + crc = updcrc(c, crc); + } +#if 1 /* Nick */ + printf("crc=0x%04x len=%6ld"); +#else + printf("%05u %6ld", crc, len); +#endif + if (fname) { +#if 1 /* Nick */ + printf(" file=%s\n", fname); +#else + printf(" %s", fname); +#endif + fclose(fp); + } + printf("\n"); +} diff --git a/src/simple/cron.c b/src/simple/cron.c new file mode 100755 index 00000000..4fcc2db4 --- /dev/null +++ b/src/simple/cron.c @@ -0,0 +1,370 @@ +/* Cron - clock daemon. Author: S.R. Sampson */ + +/* + * cron clock daemon. + * Cron is the clock daemon. It is typically started up from + * the system initialization file (/etc/rc or /etc/inittab) by + * the INIT program. + * + * If started by hand it must be done by the superuser. + * + * Since it is a true daemon, cron automatically puts itself in + * the background, to release its control terminal. If cron is + * used, it runs all day, spending most of its time asleep. + * Once a minute it wakes up and forks off a child which then + * examines /usr/lib/crontab to see if there are any commands to + * be executed. The format of this table is the same as in UNIX, + * except that % is not allowed to indicate 'new line'. + * + * Usage: /usr/bin/cron + * + * Datafile: /usr/lib/crontab + * Each crontab entry has six fields: + * + * minute hour day-of-month month day-of-week command + * + * Each entry is checked in turn, and any entry matching the + * current time is executed. The entry * matches anything. + * + * Version: 1.9 03/02/91 + * + * Authors: Steven R. Sampson, Fred van Kempen, Simmule Turner, + * Peter de Vrijer + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if 1 /* Nick */ +#include +#endif + +#define CRONTAB "/usr/lib/crontab" +#define LOGFILE "/usr/adm/cronlog" + +#define SEPARATOR " \t" +#define CRONSIZE 2048 + +typedef struct cron_entry { + struct cron_entry *next; + char *mn; + char *hr; + char *day; + char *mon; + char *wkd; + char *cmd; +} CRON; + + +static char *Version = "@(#) cron 1.9 (03/02/91)"; + + +static char crontab[CRONSIZE]; /* memory for the entries */ +static CRON *head, *entry_ptr; /* crontab entry pointers */ +static time_t prv_time; /* timekeeper: previous wakeup */ +static int started = 0; +static FILE *log, *logf; /* FILE pointer to logfile */ + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void log_error, (char *error, ...)); +_PROTOTYPE(void assign, (CRON *entry, char *line)); +_PROTOTYPE(void load_crontab, (void)); +_PROTOTYPE(int match, (char *left, int right)); +_PROTOTYPE(void wakeup, (void)); + +/* Write a record to the log file. */ +#ifdef __STDC__ +void log_error(char *error, ...) +{ + va_list args; + + va_start (args, error); + if ((logf = fopen(LOGFILE, "a")) != NULL) { + vfprintf(logf, error, args); + fclose(logf); + } + va_end(args); +} +#else +/* the K&R lib does not have vfprintf */ +void log_error(error) +char *error; +{ + if ((logf = fopen(LOGFILE, "a")) != NULL) { + fprintf(logf, error); + fclose(logf); + } +} +#endif + + +/* Assign the field values to the current crontab entry in core. */ +void assign(entry, line) +CRON *entry; +char *line; +{ + entry->mn = strtok(line, SEPARATOR); + entry->hr = strtok( (char *)NULL, SEPARATOR); + entry->day = strtok( (char *)NULL, SEPARATOR); + entry->mon = strtok( (char *)NULL, SEPARATOR); + entry->wkd = strtok( (char *)NULL, SEPARATOR); + entry->cmd = strchr(entry->wkd, '\0') + 1; +} + + +/* Read the on-disk crontab file into core. */ +void load_crontab() +{ + int len, pos; + FILE *cfp; + struct stat buf; + + if (stat(CRONTAB, &buf)) { + if (!started) fprintf(log, "Can't stat crontab\n"); + started = 0; + return; + } + + if ((convtime(&buf.st_mtime) - convtime(&prv_time)) <= 0) return; + + if ((cfp = fopen(CRONTAB, "r")) == NULL) { + if (!started) fprintf(log, "Can't open crontab\n"); + started = 0; + return; + } + prv_time = buf.st_mtime; + started = 1; + len = pos = 0; + entry_ptr = head; + + while (fgets(&crontab[pos], CRONSIZE - pos, cfp) != NULL) { + if (crontab[pos] == '#' || crontab[pos] == '\n') continue; + len = strlen(&crontab[pos]); + if (crontab[pos + len - 1] == '\n') { + len--; + crontab[pos + len] = '\0'; + } + + assign(entry_ptr, &crontab[pos]); + + if (entry_ptr->next == NULL) { + entry_ptr->next = (CRON *)malloc(sizeof(CRON)); + entry_ptr->next->next = NULL; + } + entry_ptr = entry_ptr->next; + pos += ++len; + if (pos >= CRONSIZE) break; + } + (void) fclose(cfp); + + while (entry_ptr) { + entry_ptr->mn = NULL; + entry_ptr = entry_ptr->next; + } +} + + +/* + * This routine will match the left string with the right number. + * + * The string can contain the following syntax * + * * This will return 1 for any number + * x,y [,z, ...] This will return 1 for any number given. + * x-y This will return 1 for any number within + * the range of x thru y. + */ +int match(left, right) +register char *left; +register int right; +{ + register int n; + register char c; + + n = 0; + if (!strcmp(left, "*")) return(1); + + while ((c = *left++) && (c >= '0') && (c <= '9')) n = (n * 10) + c - '0'; + + switch (c) { + case '\0': + return(right == n); + /*NOTREACHED*/ + break; + case ',': + if (right == n) return(1); + do { + n = 0; + while ((c = *left++) && (c >= '0') && (c <= '9')) + n = (n * 10) + c - '0'; + + if (right == n) return(1); + } while (c == ','); + return(0); + /*NOTREACHED*/ + break; + case '-': + if (right < n) return(0); + n = 0; + while ((c = *left++) && (c >= '0') && (c <= '9')) + n = (n * 10) + c - '0'; + return(right <= n); + /*NOTREACHED*/ + break; + default: + break; + } + return(0); +} + + +/* Wakeup from the sleep(), and check for any work. */ +void wakeup() +{ + register struct tm *tm; + time_t cur_time; + CRON *this_entry; + int st, pid; + + this_entry = head; + load_crontab(); + + time(&cur_time); + tm = localtime(&cur_time); + + while (this_entry->next && this_entry->mn) { + if (match(this_entry->mn, tm->tm_min) && + match(this_entry->hr, tm->tm_hour) && + match(this_entry->day, tm->tm_mday) && + match(this_entry->mon, tm->tm_mon + 1) && + match(this_entry->wkd, tm->tm_wday)) { + fprintf(log, "%02d/%02d-%02d:%02d %s\n", + tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, + this_entry->cmd); + if ((pid = fork()) == 0) { + st = execl("/bin/sh", "/bin/sh", "-c", + this_entry->cmd, (char *)NULL); + log_error("EXEC failed with status = %d\n", st); + } else { + if (pid < 0) + log_error("cron grandchild: Fork failed!\n\n"); + } + } + this_entry = this_entry->next; + } +} + + +int main(argc, argv) +int argc; +char *argv[]; +{ + register struct tm *tm; + int status, i, pid; + time_t clk; + + (void) chdir("/usr/adm"); + + if ((status = fork()) < 0) { + fprintf(stderr, "cron: cannot fork!\n"); + exit(1); + } else if (status > 0) exit(0); + + /* We are now the child. Ignore ALL signals. */ + for (i = 1; i <= NSIGS; i++) signal(i, SIG_IGN); + + /* Attempt to free all open file descriptors (we mostly don't have any + * files open, and reopen CRONTAB and LOGFILE as necessary). + */ + for (i = 0; i < 255; i++) close(i); + + /* Create a logfile, appending to the previous one. */ + if ((log = fopen(LOGFILE, "a")) != NULL) { + time(&clk); + tm = localtime(&clk); + fprintf(log, "cron started at: %02d/%02d-%02d:%02d\n", + tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min); + fclose(log); + } + + entry_ptr = (CRON *)malloc(sizeof(CRON)); + entry_ptr->next = NULL; + head = entry_ptr; + + /* The endless loop. */ + while (1) { + /* Sleep till the next full minute */ + time(&clk); + sleep(60); + + /* + * Now fork twice. The grandchild will run wakeup() . + * In that way cron will never have to wait longer than + * a few seconds + */ + if ((pid = fork()) == 0) { + /* + * This is the child, lets set the process group and + * fork again. This is the way it should be done in + * a true daemon. + */ + /* setpgrp();*/ /* make this line a comment if not available */ + + if ((pid = fork()) == 0) { + /* + * This is the grandchild, it has to do all the + * work. Set up standard file descriptors. No + * files are open at this point, so their numbers + * will be 0, 1 and 2 as required. Open the logfile + * if present, otherwise create it. + */ +#if 1 /* Nick */ + (void) open(_PATH_DEVNULL, O_RDWR); +#else + (void) open("/dev/null", O_RDWR); +#endif + if ((log = fopen(LOGFILE, "a")) != NULL) { + setbuf(log, (char *)NULL); + (void) dup(fileno(log)); + } else { + (void) dup(0); + (void) dup(0); + } + + wakeup(); + + /* The grandchild has to do an exit() also. */ + exit(0); + } else { + /* + * Here we are still the child, check if everything + * is ok. In any case we do an exit. + */ + if (pid < 0) { + log_error("cron: fork of grandchild failed\n"); + } + exit(0); + } + } else { + /* This is the parent. */ + if (pid < 0) { + log_error("cron: fork of child failed.\n"); + } else { + /* Wait for the child to change process group. */ + while (wait( (int *)NULL ) != pid); + } + } + } +} diff --git a/src/simple/date.c b/src/simple/date.c new file mode 100755 index 00000000..13198ae5 --- /dev/null +++ b/src/simple/date.c @@ -0,0 +1,13 @@ +/* + */ +#include +#include + +int main() { + time_t now; + + time(&now); + fputs(ctime(&now), stdout); + return 0; +} + \ No newline at end of file diff --git a/src/simple/dd.c b/src/simple/dd.c new file mode 100755 index 00000000..ba237d2d --- /dev/null +++ b/src/simple/dd.c @@ -0,0 +1,665 @@ +/* the 'dd' utility */ + +static char *sccsid = "@(#)dd.c 4.3 (Berkeley) 4/29/83"; +#include +#include +#include + +#define BIG 65535 /* 2147483647 */ +#define LCASE 01 +#define UCASE 02 +#define SWAB 04 +#define NERR 010 +#define SYNC 020 +int cflag; +int fflag; +int skip; +int seekn; +int count; +int files = 1; +char *string; +char *ifile; +char *ofile; +char *ibuf; +char *obuf; +int ibs = 512; +int obs = 512; +int bs; +int cbs; +int ibc; +int obc; +int cbc; +int nifr; +int nipr; +int nofr; +int nopr; +int ntrunc; +int ibf; +int obf; +char *op; +int nspace; +int etoa[] = { + 0000,0001,0002,0003,0234,0011,0206,0177, + 0227,0215,0216,0013,0014,0015,0016,0017, + 0020,0021,0022,0023,0235,0205,0010,0207, + 0030,0031,0222,0217,0034,0035,0036,0037, + 0200,0201,0202,0203,0204,0012,0027,0033, + 0210,0211,0212,0213,0214,0005,0006,0007, + 0220,0221,0026,0223,0224,0225,0226,0004, + 0230,0231,0232,0233,0024,0025,0236,0032, + 0040,0240,0241,0242,0243,0244,0245,0246, + 0247,0250,0133,0056,0074,0050,0053,0041, + 0046,0251,0252,0253,0254,0255,0256,0257, + 0260,0261,0135,0044,0052,0051,0073,0136, + 0055,0057,0262,0263,0264,0265,0266,0267, + 0270,0271,0174,0054,0045,0137,0076,0077, + 0272,0273,0274,0275,0276,0277,0300,0301, + 0302,0140,0072,0043,0100,0047,0075,0042, + 0303,0141,0142,0143,0144,0145,0146,0147, + 0150,0151,0304,0305,0306,0307,0310,0311, + 0312,0152,0153,0154,0155,0156,0157,0160, + 0161,0162,0313,0314,0315,0316,0317,0320, + 0321,0176,0163,0164,0165,0166,0167,0170, + 0171,0172,0322,0323,0324,0325,0326,0327, + 0330,0331,0332,0333,0334,0335,0336,0337, + 0340,0341,0342,0343,0344,0345,0346,0347, + 0173,0101,0102,0103,0104,0105,0106,0107, + 0110,0111,0350,0351,0352,0353,0354,0355, + 0175,0112,0113,0114,0115,0116,0117,0120, + 0121,0122,0356,0357,0360,0361,0362,0363, + 0134,0237,0123,0124,0125,0126,0127,0130, + 0131,0132,0364,0365,0366,0367,0370,0371, + 0060,0061,0062,0063,0064,0065,0066,0067, + 0070,0071,0372,0373,0374,0375,0376,0377 +}; +int atoe[] = { + 0000,0001,0002,0003,0067,0055,0056,0057, + 0026,0005,0045,0013,0014,0015,0016,0017, + 0020,0021,0022,0023,0074,0075,0062,0046, + 0030,0031,0077,0047,0034,0035,0036,0037, + 0100,0117,0177,0173,0133,0154,0120,0175, + 0115,0135,0134,0116,0153,0140,0113,0141, + 0360,0361,0362,0363,0364,0365,0366,0367, + 0370,0371,0172,0136,0114,0176,0156,0157, + 0174,0301,0302,0303,0304,0305,0306,0307, + 0310,0311,0321,0322,0323,0324,0325,0326, + 0327,0330,0331,0342,0343,0344,0345,0346, + 0347,0350,0351,0112,0340,0132,0137,0155, + 0171,0201,0202,0203,0204,0205,0206,0207, + 0210,0211,0221,0222,0223,0224,0225,0226, + 0227,0230,0231,0242,0243,0244,0245,0246, + 0247,0250,0251,0300,0152,0320,0241,0007, + 0040,0041,0042,0043,0044,0025,0006,0027, + 0050,0051,0052,0053,0054,0011,0012,0033, + 0060,0061,0032,0063,0064,0065,0066,0010, + 0070,0071,0072,0073,0004,0024,0076,0341, + 0101,0102,0103,0104,0105,0106,0107,0110, + 0111,0121,0122,0123,0124,0125,0126,0127, + 0130,0131,0142,0143,0144,0145,0146,0147, + 0150,0151,0160,0161,0162,0163,0164,0165, + 0166,0167,0170,0200,0212,0213,0214,0215, + 0216,0217,0220,0232,0233,0234,0235,0236, + 0237,0240,0252,0253,0254,0255,0256,0257, + 0260,0261,0262,0263,0264,0265,0266,0267, + 0270,0271,0272,0273,0274,0275,0276,0277, + 0312,0313,0314,0315,0316,0317,0332,0333, + 0334,0335,0336,0337,0352,0353,0354,0355, + 0356,0357,0372,0373,0374,0375,0376,0377 +}; +int atoibm[] = +{ + 0000,0001,0002,0003,0067,0055,0056,0057, + 0026,0005,0045,0013,0014,0015,0016,0017, + 0020,0021,0022,0023,0074,0075,0062,0046, + 0030,0031,0077,0047,0034,0035,0036,0037, + 0100,0132,0177,0173,0133,0154,0120,0175, + 0115,0135,0134,0116,0153,0140,0113,0141, + 0360,0361,0362,0363,0364,0365,0366,0367, + 0370,0371,0172,0136,0114,0176,0156,0157, + 0174,0301,0302,0303,0304,0305,0306,0307, + 0310,0311,0321,0322,0323,0324,0325,0326, + 0327,0330,0331,0342,0343,0344,0345,0346, + 0347,0350,0351,0255,0340,0275,0137,0155, + 0171,0201,0202,0203,0204,0205,0206,0207, + 0210,0211,0221,0222,0223,0224,0225,0226, + 0227,0230,0231,0242,0243,0244,0245,0246, + 0247,0250,0251,0300,0117,0320,0241,0007, + 0040,0041,0042,0043,0044,0025,0006,0027, + 0050,0051,0052,0053,0054,0011,0012,0033, + 0060,0061,0032,0063,0064,0065,0066,0010, + 0070,0071,0072,0073,0004,0024,0076,0341, + 0101,0102,0103,0104,0105,0106,0107,0110, + 0111,0121,0122,0123,0124,0125,0126,0127, + 0130,0131,0142,0143,0144,0145,0146,0147, + 0150,0151,0160,0161,0162,0163,0164,0165, + 0166,0167,0170,0200,0212,0213,0214,0215, + 0216,0217,0220,0232,0233,0234,0235,0236, + 0237,0240,0252,0253,0254,0255,0256,0257, + 0260,0261,0262,0263,0264,0265,0266,0267, + 0270,0271,0272,0273,0274,0275,0276,0277, + 0312,0313,0314,0315,0316,0317,0332,0333, + 0334,0335,0336,0337,0352,0353,0354,0355, + 0356,0357,0372,0373,0374,0375,0376,0377 +}; + +void usage(); +void flsh(); +void term(); +void stats(); +int match(char *s); +int number(unsigned int big); +void null(char c); +void cnull(int c); +void ebcdic(int cc); +void ibm(int cc); +void block(int cc); +void ascii(int cc); +void unblock(int cc); + +#ifdef HI_TECH_C +void doconv(int (*conv)(), int c) { + if (conv == cnull) cnull(c); else + if (conv == ebcdic) ebcdic(c); else + if (conv == ibm) ibm(c); else + if (conv == ascii) ascii(c); else + if (conv == block) block(c); else + if (conv == unblock) unblock(c); else { + fprintf(stderr, "PANIC: uknown conversion\n"); + exit(1); + } +} +#endif + +void main(argc, argv) +int argc; +char **argv; +{ + int (*conv)(); + register char *ip; + register int c; + int a; + + if (argc < 2) + usage(); + + + conv = NULL; + for(c=1; cibuf;) + *--ip = 0; + ibc = read(ibf, ibuf, ibs); + } + if(ibc == -1) { + perror("read"); + if((cflag&NERR) == 0) { + flsh(); + term(); + } + ibc = 0; + for(c=0; c> 1; + if(cflag&SWAB && c) + do { + a = *ip++; + ip[-1] = *ip; + *ip++ = a; + } while(--c); + ip = ibuf; + if (fflag) { + obc = ibc; + flsh(); + ibc = 0; + } + goto loop; + } + c = 0; + c |= *ip++; + c &= 0377; +#ifndef HI_TECH_C + (*conv)(c); +#else + doconv(conv, c); +#endif + goto loop; +} + +void usage() +{ +/* printf("convert and copy a file\n\n");*/ + printf("usage: dd [option=value]\n"); + printf(" if = input file\n"); + printf(" of = output file\n"); + printf(" ibs = input block size: default 512\n"); + printf(" obs = output block size: default 512\n"); + printf(" bs = blocksize\n"); + printf(" cbs = conversion block size\n"); + printf(" files = copy n files\n"); + printf(" skip = skip n input records\n"); + printf(" seek = skip n output records\n"); + printf(" count = copy only n input records\n"); + printf(" conv = ascii,ebcdic,ibm,lcase,ucase,swab,sync,noerror\n"); + exit(0); +} + + +void flsh() +{ + register int c; + + if(obc) { + if(obc == obs) + nofr++; else + nopr++; + c = write(obf, obuf, obc); + if(c != obc) { + perror("write"); + term(); + } + obc = 0; + } +} + +int match(s) +char *s; +{ + register char *cs; + + cs = string; + while(*cs++ == *s) + if(*s++ == '\0') + goto true; + if(*s != '\0') + return(0); + +true: + cs--; + string = cs; + return(1); +} + +int number(unsigned int big) +{ + register char *cs; + unsigned int n; + + cs = string; + n = 0; + while(*cs >= '0' && *cs <= '9') + n = n*10 + *cs++ - '0'; + for(;;) + switch(*cs++) { + + case 'k': + n *= 1024; + continue; + + case 'w': + n *= sizeof(int); + continue; + + case 'b': + n *= 512; + continue; + + case '*': + case 'x': + string = cs; + n *= number(BIG); + + case '\0': + if (n>=big /*|| n<0*/) { + fprintf(stderr, "dd: argument %D out of range\n", n); + exit(1); + } + return(n); + } + /* never gets here */ +} + +void cnull(cc) +int cc; +{ + register int c; + + c = cc; + if(cflag&UCASE && c>='a' && c<='z') + c += 'A'-'a'; + if(cflag&LCASE && c>='A' && c<='Z') + c += 'a'-'A'; + null(c); +} + +void null(char c) +{ + + *op = c; + op++; + if(++obc >= obs) { + flsh(); + op = obuf; + } +} + +void ascii(int cc) +{ + register int c; + + c = etoa[cc] & 0377; + if(cbs == 0) { + cnull(c); + return; + } + if(c == ' ') { + nspace++; + goto out; + } + while(nspace > 0) { + null(' '); + nspace--; + } + cnull(c); + +out: + if(++cbc >= cbs) { + null('\n'); + cbc = 0; + nspace = 0; + } +} + +void unblock(int cc) +{ + register int c; + + c = cc & 0377; + if(cbs == 0) { + cnull(c); + return; + } + if(c == ' ') { + nspace++; + goto out; + } + while(nspace > 0) { + null(' '); + nspace--; + } + cnull(c); + +out: + if(++cbc >= cbs) { + null('\n'); + cbc = 0; + nspace = 0; + } +} + +void ebcdic(int cc) +{ + register int c; + + c = cc; + if(cflag&UCASE && c>='a' && c<='z') + c += 'A'-'a'; + if(cflag&LCASE && c>='A' && c<='Z') + c += 'a'-'A'; + c = atoe[c] & 0377; + if(cbs == 0) { + null(c); + return; + } + if(cc == '\n') { + while(cbc < cbs) { + null(atoe[' ']); + cbc++; + } + cbc = 0; + return; + } + if(cbc == cbs) + ntrunc++; + cbc++; + if(cbc <= cbs) + null(c); +} + +void ibm(int cc) +{ + register int c; + + c = cc; + if(cflag&UCASE && c>='a' && c<='z') + c += 'A'-'a'; + if(cflag&LCASE && c>='A' && c<='Z') + c += 'a'-'A'; + c = atoibm[c] & 0377; + if(cbs == 0) { + null(c); + return; + } + if(cc == '\n') { + while(cbc < cbs) { + null(atoibm[' ']); + cbc++; + } + cbc = 0; + return; + } + if(cbc == cbs) + ntrunc++; + cbc++; + if(cbc <= cbs) + null(c); +} + +void block(int cc) +{ + register int c; + + c = cc; + if(cflag&UCASE && c>='a' && c<='z') + c += 'A'-'a'; + if(cflag&LCASE && c>='A' && c<='Z') + c += 'a'-'A'; + c &= 0377; + if(cbs == 0) { + null(c); + return; + } + if(cc == '\n') { + while(cbc < cbs) { + null(' '); + cbc++; + } + cbc = 0; + return; + } + if(cbc == cbs) + ntrunc++; + cbc++; + if(cbc <= cbs) + null(c); +} + +void term() +{ + + stats(); + exit(0); +} + +void stats() +{ + + fprintf(stderr,"%u+%u records in\n", nifr, nipr); + fprintf(stderr,"%u+%u records out\n", nofr, nopr); + if(ntrunc) + fprintf(stderr,"%u truncated records\n", ntrunc); +} diff --git a/src/simple/df.c b/src/simple/df.c new file mode 100755 index 00000000..0998a98a --- /dev/null +++ b/src/simple/df.c @@ -0,0 +1,170 @@ +/* df.c + * descripton: summarize filesystems space + * author: Archi Schekochikhin + * modified: Adriano Cunha + * added /etc/mtab query for getting fs name and mounting point + * license: GNU Public License version 2 + */ + +#include +#include +#include +#include +#include +#include + +typedef unsigned char BOOL; + +void findmntp(dev_t dev, inoptr ino, char *mpoint, char *fsysdev) { + int i; + FILE *fd; + struct stat statbuf; + char buf[256], *p, *p1; + + (void)ino; + strcpy(mpoint,"?"); + if ((fd = fopen("/etc/mtab", "r")) == NULL) + return; + while (!feof(fd)) { + fgets(buf, sizeof(buf)-1, fd); + if (NULL == (p = strchr(buf, '\t'))) + continue; + p1 = p + 1; + *p = '\0'; + stat(buf, &statbuf); + if (statbuf.st_rdev == dev) { + strcpy(fsysdev, buf); + if (NULL == (p = strchr(p1, '\t'))) + continue; + *p = '\0'; + strcpy(mpoint, p1); + fclose(fd); + return; + } + } + fclose(fd); + return; +} + +int main(argc, argv) + int argc; + char *argv[]; + { + BOOL iflag = 0, kflag = 0, nflag = 0; +#if 1 /* Nick, new getfsys() convention */ + filesys_t fsys; +#else + info_t info; + fsptr fsys; +#endif + int i, j; + char *p, mpoint[128], fsysdev[128]; + + for (i = 1; i < argc; ++i) + { + p = argv[i]; + if (p[0] == '-') + { + for (++p; *p; ++p) + { + switch (*p) + { + case 'i': iflag = 1; break; + case 'k': kflag = 1; break; + case 'n': nflag = 1; break; + default: + printf("usage: %s [-ikn]\n", argv[0]); + return 0; + } + } + } + else + break; + } + if (iflag) + printf("Filesystem\tInodes\tIUsed\tIFree\t%%IFree\tMounted on\n"); + else if (kflag) + printf("Filesystem\tSize(Kb) Used\t Free\t %%Free\tMounted on\n"); + else + printf("Filesystem\tBlocks\t Used\t Free\t %%Free\tMounted on\n"); +#if 1 /* Nick, new getfsys() convention */ + for (j = 0; j < 8; ++j) + { + if (getfsys(j, &fsys) == 0 && fsys.s_mounted == SMOUNTED) + { + int t = iflag ? 8 * fsys.s_isize : + fsys.s_fsize - fsys.s_reserv; + int u = iflag ? (t - fsys.s_tinode) : + (t - fsys.s_isize) - fsys.s_tfree; + int f = iflag ? fsys.s_tinode : fsys.s_tfree; + int prc; + + if (!iflag && kflag) + { + t /= 2; + u /= 2; + f /= 2; + } + if ((prc = t/100) != 0) + prc = f/prc; + strcpy(mpoint, "?"); + sprintf(fsysdev, "%d", j); + if (!nflag) + { + findmntp(fsys.s_dev, + fsys.s_mntpt, + mpoint, fsysdev); + } + printf("%-16s %6u\t%5u\t%5u\t%3u%%\t%s\n", + fsysdev, t, u, f, prc, + fsys.s_mntpt ? mpoint : "/"); + } + } +#else + if (i < argc) + { + for (; i < argc; ++i) + { + p = argv[i]; + } + } + else + { + for (j = 0; j < 8; ++j) + { + if (0 == getfsys(j, &info) && + (fsys = (fsptr)info.ptr) != NULL && + fsys->s_mounted) + { + int t = iflag ? 8 * fsys->s_isize : fsys->s_fsize - fsys->s_reserv; + int u = iflag ? (t - fsys->s_tinode) : + (t - fsys->s_isize) - fsys->s_tfree; + int f = iflag ? fsys->s_tinode : fsys->s_tfree; + int prc; + + if (!iflag && kflag) + { + t /= 2; + u /= 2; + f /= 2; + } + if ((prc = t/100) != 0) + prc = f/prc; + strcpy(mpoint, "?"); + sprintf(fsysdev, "%d", j); + if (!nflag) + { + findmntp(fsys->s_dev, + fsys->s_mntpt, + mpoint, fsysdev); + } + printf("%-16s %6u\t%5u\t%5u\t%3u%%\t%s\n", + fsysdev, t, u, f, prc, + fsys->s_mntpt ? mpoint : "/"); + } + } + } +#endif + return 0; + } + diff --git a/src/simple/dhry.c b/src/simple/dhry.c new file mode 100755 index 00000000..a1b1d488 --- /dev/null +++ b/src/simple/dhry.c @@ -0,0 +1,559 @@ +/* + * + * "DHRYSTONE" Benchmark Program + * + * Version: C/1.1, 12/01/84 + * + * Date: PROGRAM updated 01/06/86, COMMENTS changed 01/31/87 + * + * Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg.1013 + * Translated from ADA by Rick Richardson + * Every method to preserve ADA-likeness has been used, + * at the expense of C-ness. + * + * Compile: cc -O dry.c -o drynr : No registers + * cc -O -DREG=register dry.c -o dryr : Registers + * + * Defines: Defines are provided for old C compiler's + * which don't have enums, and can't assign structures. + * The time(2) function is library dependant; Most + * return the time in seconds, but beware of some, like + * Aztec C, which return other units. + * The LOOPS define is initially set for 50000 loops. + * If you have a machine with large integers and is + * very fast, please change this number to 500000 to + * get better accuracy. Please select the way to + * measure the execution time using the TIME define. + * For single user machines, time(2) is adequate. For + * multi-user machines where you cannot get single-user + * access, use the times(2) function. Be careful to + * adjust the HZ parameter below for the units which + * are returned by your times(2) function. You can + * sometimes find this in . If you have + * neither time(2) nor times(2), use a stopwatch in + * the dead of the night. + * Use a "printf" at the point marked "start timer" + * to begin your timings. DO NOT use the UNIX "time(1)" + * command, as this will measure the total time to + * run this program, which will (erroneously) include + * the time to malloc(3) storage and to compute the + * time it takes to do nothing. + * + * Run: drynr; dryr + * + * Results: If you get any new machine/OS results, please send to: + * + * ihnp4!castor!pcrat!rick + * + * and thanks to all that do. + * + * Note: I order the list in increasing performance of the + * "with registers" benchmark. If the compiler doesn't + * provide register variables, then the benchmark + * is the same for both REG and NOREG. + * + * PLEASE: Send complete information about the machine type, + * clock speed, OS and C manufacturer/version. If + * the machine is modified, tell me what was done. + * On UNIX, execute uname -a and cc -V to get this info. + * + * 80x8x NOTE: 80x8x benchers: please try to do all memory models + * for a particular compiler. + * + * + * The following program contains statements of a high-level programming + * language (C) in a distribution considered representative: + * + * assignments 53% + * control statements 32% + * procedure, function calls 15% + * + * 100 statements are dynamically executed. The program is balanced with + * respect to the three aspects: + * - statement type + * - operand type (for simple data types) + * - operand access + * operand global, local, parameter, or constant. + * + * The combination of these three aspects is balanced only approximately. + * + * The program does not compute anything meaningfull, but it is + * syntactically and semantically correct. + * + */ + + +#include +#include +#include +#include +#include +#include +#include + +#define REGISTER + +/* Accuracy of timings and human fatigue controlled by next two lines */ +/*#define LOOPS 50000 */ /* Use this for slow or 16 bit machines */ +/*#define LOOPS 500000 */ /* Use this for faster machines */ +#define LOOPS (sizeof(int) == 2 ? 50000 : 1000000)*/ + +/* Seconds to run */ +#define SECONDS 15 + +/* Compiler dependent options */ +/* #define NOENUM */ /* Define if compiler has no enum's */ +/* #define NOSTRUCTASSIGN */ /* Define if compiler can't assign structures*/ + +/* Define only one of the next two defines */ +#define TIMES /* Use times(2) time function */ +/*#define TIME */ /* Use time(2) time function */ + +#ifdef TIME +/* Ganularity of time(2) is of course 1 second */ +#define HZ 1 +#endif + +#ifdef TIMES +/* Define the granularity of your times(2) function */ +/*#define HZ 50 */ /* times(2) returns 1/50 second (europe?) */ +/*#define HZ 60 */ /* times(2) returns 1/60 second (most) */ +/*#define HZ 100 */ /* times(2) returns 1/100 second (WECo) */ +#define HZ CLOCKS_PER_SEC +#endif + +/* For compatibility with goofed up version */ +/*#undef GOOF */ /* Define if you want the goofed up version */ + +#ifdef GOOF +char Version[] = "1.0"; +#else +char Version[] = "1.1"; +#endif + +#ifdef NOSTRUCTASSIGN +#define structassign(d, s) memcpy(&(d), &(s), sizeof(d)) +#else +#define structassign(d, s) d = s +#endif + +#ifdef NOENUM +#define Ident1 1 +#define Ident2 2 +#define Ident3 3 +#define Ident4 4 +#define Ident5 5 +typedef int Enumeration; +#else +typedef enum { + Ident1, Ident2, Ident3, Ident4, Ident5 +} Enumeration; +#endif + +typedef int OneToThirty; +typedef int OneToFifty; +typedef char CapitalLetter; +typedef char String30[31]; +typedef int Array1Dim[51]; +typedef int Array2Dim[51][51]; + +struct Record { + struct Record *PtrComp; + Enumeration Discr; + Enumeration EnumComp; + OneToFifty IntComp; + String30 StringComp; +}; + +typedef struct Record RecordType; +typedef RecordType *RecordPtr; +typedef int boolean; + +#ifdef NULL +#undef NULL +#endif + +#define NULL 0 +#define TRUE 1 +#define FALSE 0 + +#ifndef REG +#define REG +#endif + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (void)); +_PROTOTYPE(void prep_timer, (void)); +_PROTOTYPE(static void timeout, (int sig)); +_PROTOTYPE(void Proc0, (void)); +_PROTOTYPE(void Proc1, (RecordPtr PtrParIn)); +_PROTOTYPE(void Proc2, (OneToFifty *IntParIO)); +_PROTOTYPE(void Proc3, (RecordPtr *PtrParOut)); +_PROTOTYPE(void Proc4, (void)); +_PROTOTYPE(void Proc5, (void)); +_PROTOTYPE(void Proc6, (Enumeration EnumParIn, Enumeration *EnumParOut)); +_PROTOTYPE(void Proc7, (OneToFifty IntParI1, OneToFifty IntParI2, OneToFifty *IntParOut)); +_PROTOTYPE(void Proc8, (Array1Dim Array1Par, Array2Dim Array2Par, OneToFifty IntParI1, OneToFifty IntParI2)); +_PROTOTYPE(Enumeration Func1, (CapitalLetter CharPar1, CapitalLetter CharPar2)); +_PROTOTYPE(boolean Func2, (String30 StrParI1, String30 StrParI2)); +_PROTOTYPE(boolean Func3, (Enumeration EnumParIn)); + +int main() +{ + printf("\"DHRYSTONE\" Benchmark Program vr. %s\n\n", Version); + printf("Please wait for %d seconds while benchmarking your system...\n", SECONDS); + Proc0(); + return(0); +} + +#if __STDC__ +volatile int done; +#else +int done; +#endif + +void prep_timer() +{ + signal(SIGALRM, (sig_t) timeout); /* Nick */ + done = 0; +} + +static void timeout(sig) +int sig; +{ + done = 1; +} + +/* Package 1 */ +int IntGlob; +boolean BoolGlob; +char Char1Glob; +char Char2Glob; +Array1Dim Array1Glob; +Array2Dim Array2Glob; +RecordPtr PtrGlb; +RecordPtr PtrGlbNext; + + +void Proc0() +{ + OneToFifty IntLoc1; + REG OneToFifty IntLoc2; + OneToFifty IntLoc3; + REG char CharIndex; + Enumeration EnumLoc; + String30 String1Loc; + String30 String2Loc; + register unsigned long i; + unsigned long starttime; + unsigned long benchtime; + unsigned long nulltime; + unsigned long nullloops; + unsigned long benchloops; + + i = 0; + prep_timer(); + +#ifdef TIME + starttime = time((long *) 0); +#endif + +#ifdef TIMES + starttime = clock(); +#endif + + alarm(1); + while (!done) i++; + +#ifdef TIME + nulltime = time((long *) 0) - starttime; /* Computes o'head of loop */ +#endif + +#ifdef TIMES + nulltime = clock() - starttime; /* Computes overhead of looping */ +#endif + + nullloops = i; + + PtrGlbNext = (RecordPtr) malloc(sizeof(RecordType)); + PtrGlb = (RecordPtr) malloc(sizeof(RecordType)); + PtrGlb->PtrComp = PtrGlbNext; + PtrGlb->Discr = Ident1; + PtrGlb->EnumComp = Ident3; + PtrGlb->IntComp = 40; + strcpy(PtrGlb->StringComp, "DHRYSTONE PROGRAM, SOME STRING"); +#ifndef GOOF + strcpy(String1Loc, "DHRYSTONE PROGRAM, 1'ST STRING"); /* GOOF */ +#endif + + Array2Glob[8][7] = 10; /* Was missing in published program */ + + +/***************** +-- Start Timer -- +*****************/ + i = 0; + prep_timer(); + +#ifdef TIME + starttime = time((long *) 0); +#endif + +#ifdef TIMES + starttime = clock(); +#endif + + alarm(SECONDS); + while (!done) { + i++; + Proc5(); + Proc4(); + IntLoc1 = 2; + IntLoc2 = 3; + strcpy(String2Loc, "DHRYSTONE PROGRAM, 2'ND STRING"); + EnumLoc = Ident2; + BoolGlob = !Func2(String1Loc, String2Loc); + while (IntLoc1 < IntLoc2) { + IntLoc3 = 5 * IntLoc1 - IntLoc2; + Proc7(IntLoc1, IntLoc2, &IntLoc3); + ++IntLoc1; + } + Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3); + Proc1(PtrGlb); + for (CharIndex = 'A'; CharIndex <= Char2Glob; ++CharIndex) + if (EnumLoc == Func1(CharIndex, 'C')) + Proc6(Ident1, &EnumLoc); + IntLoc3 = IntLoc2 * IntLoc1; + IntLoc2 = IntLoc3 / IntLoc1; + IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1; + Proc2(&IntLoc1); + } + + +/***************** +-- Stop Timer -- +*****************/ + + +#ifdef TIME + benchtime = time((long *) 0) - starttime; +#endif + +#ifdef TIMES + benchtime = clock() - starttime; +#endif + benchloops = i; + + /* Approximately correct benchtime to the nulltime. */ + benchtime -= nulltime / (nullloops / benchloops); + + printf("Dhrystone(%s) time for %lu passes = %lu.%02lu\n", + Version, + benchloops, benchtime / HZ, benchtime % HZ * 100 / HZ); + printf("This machine benchmarks at %lu dhrystones/second\n", + benchloops * HZ / benchtime); +} + + +void Proc1(PtrParIn) +REG RecordPtr PtrParIn; +{ +#define NextRecord (*(PtrParIn->PtrComp)) + + + structassign(NextRecord, *PtrGlb); + PtrParIn->IntComp = 5; + NextRecord.IntComp = PtrParIn->IntComp; + NextRecord.PtrComp = PtrParIn->PtrComp; + Proc3((RecordPtr *)NextRecord.PtrComp); + if (NextRecord.Discr == Ident1) { + NextRecord.IntComp = 6; + Proc6(PtrParIn->EnumComp, &NextRecord.EnumComp); + NextRecord.PtrComp = PtrGlb->PtrComp; + Proc7(NextRecord.IntComp, 10, &NextRecord.IntComp); + } else + structassign(*PtrParIn, NextRecord); + + +#undef NextRecord +} + + +void Proc2(IntParIO) +OneToFifty *IntParIO; +{ + REG OneToFifty IntLoc; + REG Enumeration EnumLoc; + + + IntLoc = *IntParIO + 10; + for (;;) { + if (Char1Glob == 'A') { + --IntLoc; + *IntParIO = IntLoc - IntGlob; + EnumLoc = Ident1; + } + if (EnumLoc == Ident1) break; + } +} + + +void Proc3(PtrParOut) +RecordPtr *PtrParOut; +{ + if (PtrGlb != NULL) + *PtrParOut = PtrGlb->PtrComp; + else + IntGlob = 100; + Proc7(10, IntGlob, &PtrGlb->IntComp); +} + + +void Proc4() +{ + REG boolean BoolLoc; + + + BoolLoc = Char1Glob == 'A'; + BoolLoc |= BoolGlob; + Char2Glob = 'B'; +} + + +void Proc5() +{ + Char1Glob = 'A'; + BoolGlob = FALSE; +} + + +void Proc6(EnumParIn, EnumParOut) +REG Enumeration EnumParIn; +REG Enumeration *EnumParOut; +{ + *EnumParOut = EnumParIn; + if (!Func3(EnumParIn)) *EnumParOut = Ident4; + switch (EnumParIn) { + case Ident1: *EnumParOut = Ident1; break; + case Ident2: + if (IntGlob > 100) + *EnumParOut = Ident1; + else + *EnumParOut = Ident4; + break; + case Ident3: *EnumParOut = Ident2; break; + case Ident4: + break; + case Ident5: *EnumParOut = Ident3; +} +} + + +void Proc7(IntParI1, IntParI2, IntParOut) +OneToFifty IntParI1; +OneToFifty IntParI2; +OneToFifty *IntParOut; +{ + REG OneToFifty IntLoc; + + + IntLoc = IntParI1 + 2; + *IntParOut = IntParI2 + IntLoc; +} + + +void Proc8(Array1Par, Array2Par, IntParI1, IntParI2) +Array1Dim Array1Par; +Array2Dim Array2Par; +OneToFifty IntParI1; +OneToFifty IntParI2; +{ + REG OneToFifty IntLoc; + REG OneToFifty IntIndex; + + + IntLoc = IntParI1 + 5; + Array1Par[IntLoc] = IntParI2; + Array1Par[IntLoc + 1] = Array1Par[IntLoc]; + Array1Par[IntLoc + 30] = IntLoc; + for (IntIndex = IntLoc; IntIndex <= (IntLoc + 1); ++IntIndex) + Array2Par[IntLoc][IntIndex] = IntLoc; + ++Array2Par[IntLoc][IntLoc - 1]; + Array2Par[IntLoc + 20][IntLoc] = Array1Par[IntLoc]; + IntGlob = 5; +} + + +Enumeration Func1(CharPar1, CharPar2) +CapitalLetter CharPar1; +CapitalLetter CharPar2; +{ + REG CapitalLetter CharLoc1; + REG CapitalLetter CharLoc2; + + + CharLoc1 = CharPar2; + CharLoc2 = CharLoc1; + /* note: the original code was CharLoc1=CharPar1;if(CharLoc2!=CharPar1). + but HTC generate wrong code for it, and dhry.com hangs. That's + why the swap of variables. + */ + if (CharLoc2 != CharPar1) + return(Ident1); + else + return(Ident2); +} + + +boolean Func2(StrParI1, StrParI2) +String30 StrParI1; +String30 StrParI2; +{ + REG OneToThirty IntLoc; + REG CapitalLetter CharLoc; + + + IntLoc = 1; + while (IntLoc <= 1) + if (Func1(StrParI1[IntLoc], StrParI2[IntLoc + 1]) == Ident1) { + CharLoc = 'A'; + ++IntLoc; + } + if (CharLoc >= 'W' && CharLoc <= 'Z') IntLoc = 7; + if (CharLoc == 'X') + return(TRUE); + else { + if (strcmp(StrParI1, StrParI2) > 0) { + IntLoc += 7; + return(TRUE); + } else + return(FALSE); + } +} + + +boolean Func3(EnumParIn) +REG Enumeration EnumParIn; +{ + REG Enumeration EnumLoc; + + + EnumLoc = EnumParIn; + if (EnumLoc == Ident3) return(TRUE); + return(FALSE); +} + + +#ifdef NOSTRUCTASSIGN +memcpy(d, s, l) +register char *d; +register char *s; +register int l; +{ + while (l--) *d++ = *s++; +} + +#endif diff --git a/src/simple/diff.c b/src/simple/diff.c new file mode 100755 index 00000000..027fc592 --- /dev/null +++ b/src/simple/diff.c @@ -0,0 +1,1268 @@ +/* diff - print differences between 2 files Author: Erik Baalbergen */ + +/* Poor man's implementation of diff(1) - no options available +* - may give more output than other diffs, +* due to the straight-forward algorithm +* - runs out of memory if the differing chunks become too large +* - input line length should not exceed LINELEN; longer lines are +* truncated, while only the first LINELEN characters are compared +* +* - Bug fixes by Rick Thomas Sept. 1989 +* +* Please report bugs and suggestions to erikb@cs.vu.nl +*------------------------------------------------------------------------------ +* Changed diff to conform to POSIX 1003.2 ( Draft 11) by Thomas Brupbacher +* ( tobr@mw.lpc.ethz.ch). +* +* To incorporate the context diff option -c in the program, the source code +* for the program cdiff has been copied to the end of this program. Only +* slight modifications for the cdiff code to work within the program diff +* were made( e.g. main() -> context_diff()). +* +* New options: +* -c, -C n where n=0,1,...: +* produces a context diff as the program cdiff. The default is to +* print 3 lines of context, this value can be changed with -C +* ( e.g. -C 5 prints five lines of context.) +* -e : Prints an ed script, so you can convert to with +* the command ed < `diff -e `. +* -b : Causes trailing blanks to be ignored and spaces of multiple blanks +* to be reduced to one blank before comparison. +*----------------------------------------------------------------------------- +*/ + +#include +#include /* NAME_MAX for maximal filename length */ +#include /* string manipulation */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* These definitions are needed only to suppress warning messages. */ +#define Nullfp ((FILE*)0) +#define Nullch ((char*)0) +#define NullStructLine ((struct line *)0) + +#define LINELEN 128 /* max line length included in diff */ + + +#define NOT_SET 0 /* Defines to characterise if a flag */ +#define SET 1 /* is set */ + + /* Indexes of the warning-message array */ +#define EXCLUSIVE_OPTIONS 0 +#define CANNOT_OPEN_FILE 1 + + /* Used to define the mode */ +typedef enum { + undefined, context, ed_mode +} MODE; + +#ifndef PATH_MAX +#define PATH_MAX 128 +#endif + +#if defined(MSX_UZIX_TARGET) || defined (PC_UZIX_TARGET) +#define NAME_MAX MAXNAMLEN +#define S_IFIFO S_IFPIPE +#endif + + /* Global variables for the 'normal' diff part */ +char *progname; /* program name (on command line) */ +int diffs = 0; /* number of differences */ +MODE mode; /* which mode is used */ +int severe_error; /* nonzero after severe, non-fatal error */ + +/* The following global variables are used with the -r option: + * for every pair of files that are different, a "command line" of the + * form "diff " is printed before the real + * output starts. */ +int firstoutput = 1; /* flag to print one time */ +char options_string[10]; /* string to hold command line options */ +char oldfile[PATH_MAX]; /* first file */ +char newfile[PATH_MAX]; /* second file */ + + + /* Global variables for the command-line options */ +int trim_blanks = NOT_SET; /* SET if -b specified */ +int recursive_dir = NOT_SET; /* SET if -r specified */ +int context_lines = 3; /* numbers of lines in a context */ +static int offset; /* offset of the actual line number for -e */ + + /* Function prototypes for the functions in this file */ +struct f; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv )); +_PROTOTYPE(void process_command_line, (int argc, char **argv )); +_PROTOTYPE(void analyse_input_files, (char *arg1, char *arg2, char *input1, + char *input2 )); +_PROTOTYPE(void diff, (char *filename1, char *filename2 )); +_PROTOTYPE(FILE *check_file, (char *name )); +_PROTOTYPE(void build_option_string, (void )); +_PROTOTYPE(void fatal_error, (char *fmt, char *s )); +_PROTOTYPE(void warn, (int number, char *string )); +_PROTOTYPE(void trimming_blanks, (char *l_text )); +_PROTOTYPE(char *filename, (char *path_string)); +_PROTOTYPE(struct line *new_line, (int size )); +_PROTOTYPE(void free_line, (struct line *l )); +_PROTOTYPE(int equal_line, (struct line *l1, struct line *l2 )); +_PROTOTYPE(int equal_3, (struct line *l1, struct line *l2 )); +_PROTOTYPE(struct line *read_line, (FILE *fp )); +_PROTOTYPE(void advance, (struct f *f )); +_PROTOTYPE(void aside, (struct f *f, struct line *l )); +_PROTOTYPE(struct line *next, (struct f *f )); +_PROTOTYPE(void init_f, (struct f *f, FILE *fp )); +_PROTOTYPE(void update, (struct f *f, char *s )); +_PROTOTYPE(void __diff, (FILE *fp1, FILE *fp2 )); +_PROTOTYPE(void differ, (struct f *f1, struct f *f2 )); +_PROTOTYPE(int wlen, (struct f *f )); +_PROTOTYPE(void range, (int a, int b )); +_PROTOTYPE(void cdiff, (char *old, char *new, FILE *file1, FILE *file2 )); +_PROTOTYPE(void dumphunk, (void )); +_PROTOTYPE(char *getold, (int targ )); +_PROTOTYPE(char *getnew, (int targ )); +_PROTOTYPE(int isdir, (char *path )); +_PROTOTYPE(void diff_recursive, (char *dir1, char *dir2 )); +_PROTOTYPE(void file_type_error, (char *filename1, char *filename2, + struct stat *statbuf1, struct stat *statbuf2 )); +_PROTOTYPE(void *xmalloc, (size_t size)); +_PROTOTYPE(void *xrealloc, (void *ptr, size_t size)); + +int main(argc, argv) +int argc; +char **argv; +{ + char file1[PATH_MAX], file2[PATH_MAX]; + extern int optind; /* index of the current string in argv */ + + progname = argv[0]; + process_command_line(argc, argv); + + analyse_input_files(argv[optind], argv[optind + 1], file1, file2); + optind++; + + if (recursive_dir == SET) { + build_option_string(); + diff_recursive(file1, file2); + } else { + diff(file1, file2); + } + + return(severe_error ? 2 : diffs > 0 ? 1 : 0); +} + +/* Process the command line and set the flags for the different + * options. the processing of the command line is done with the + * getopt() library function. a minimal error processing is done + * for the number of command line arguments. */ +void process_command_line(argc, argv) +int argc; /* number of arguments on command line */ +char **argv; /* ** to arguments on command line */ +{ + int c; + extern char *optarg; /* points to string with options */ + extern int optind; /* index of the current string in argv */ + + /* Are there enough arguments? */ + if (argc < 3) { + fprintf(stderr, "usage: %s [-c|-e|-C n][-br] file1 file2\n", progname); + exit(2); + } + + /* Process all options using getopt() */ + while ((c = getopt(argc, argv, "ceC:br")) != -1) { + switch (c) { + case 'c': + if (mode != undefined) warn(EXCLUSIVE_OPTIONS, "c"); + mode = context; + context_lines = 3; + break; + case 'e': + if (mode != undefined) warn(EXCLUSIVE_OPTIONS, "e"); + mode = ed_mode; + break; + case 'C': + if (mode != undefined) warn(EXCLUSIVE_OPTIONS, "C"); + mode = context; + context_lines = atoi(optarg); + break; + case 'b': trim_blanks = SET; break; + case 'r': recursive_dir = SET; break; + case '?': + exit(2); + } + } + + /* We should have two arguments left */ + if ((argc - optind) != 2) + fatal_error("Need exactly two input file-names!\n", ""); +} + +/* Analyse_input_files takes the two input files on the command line + * and decides what to do. returns the (corrected) filenames that + * can be used to call diff(). + * if two directories are given, then a recursive diff is done. + * one directory and one filename compares the file with + * in the directory with . + * if two filenames are specified, no special action takes place. + */ +void analyse_input_files(arg1, arg2, input1, input2) +char *arg1, *arg2; /* filenames on the command line */ +char *input1, *input2; /* filenames to be used with diff() */ +{ + int stat1 = 0, stat2 = 0; + + if (strcmp(arg1, "-") != 0) + stat1 = isdir(arg1); /* != 0 <-> arg1 is directory */ + if (strcmp(arg2, "-") != 0) stat2 = isdir(arg2); +#ifdef DEBUG + fprintf(stderr, "%s, stat = %d\n", arg1, stat1); + fprintf(stderr, "%s, stat = %d\n", arg2, stat2); +#endif + if (stat1 && stat2) { /* both arg1 and arg2 are directories */ + recursive_dir = SET; + strcpy(input1, arg1); + strcpy(input2, arg2); + return; + } + if (stat1 != 0) { /* arg1 is a dir, arg2 not */ + if (strcmp(arg2, "-") != 0) { /* arg2 != stdin */ + strcpy(input1, arg1); + strcat(input1, "/"); + strcat(input1, arg2); + strcpy(input2, arg2); + return; + } else { + fatal_error("cannot compare stdin (-) with a directory!", ""); + } + } + if (stat2 != 0) { /* arg2 is a dir, arg1 not */ + if (strcmp(arg1, "-") != 0) { /* arg1 != stdin */ + strcpy(input1, arg1); + strcpy(input2, arg2); + strcat(input2, "/"); + strcat(input2, arg1); + return; + } else { /* arg1 == stdin */ + fatal_error("cannot compare stdin (-) with a directory!", ""); + } + } + + /* Both arg1 and arg2 are normal files */ + strcpy(input1, arg1); + strcpy(input2, arg2); +} + +/* Diff() is the front end for all modes of the program diff, execpt + * the recursive_dir option. + * diff() expects the filenames of the two files to be compared as + * arguments. the mode is determined from the global variable mode. + */ +void diff(filename1, filename2) +char *filename1, *filename2; +{ + FILE *file1 = check_file(filename1); + FILE *file2 = check_file(filename2); + struct stat statbuf1, statbuf2; + + if ((file1 != Nullfp) && (file2 != Nullfp)) { + /* If we do a recursive diff, then we don't compare block + * special, character special or FIFO special files to any + * file. */ + fstat(fileno(file1), &statbuf1); + fstat(fileno(file2), &statbuf2); + if ((((statbuf1.st_mode & S_IFREG) != S_IFREG) || + ((statbuf2.st_mode & S_IFREG) != S_IFREG)) && + (recursive_dir == SET)) { + file_type_error(filename1, filename2, &statbuf1, &statbuf2); + } else { + switch (mode) { + case context: + cdiff(filename1, filename2, file1, file2); + break; + case ed_mode: + case undefined: + __diff(file1, file2); + if (mode == ed_mode) printf("w\n"); + break; + } + } + } else + severe_error = 1; + if (file1 != Nullfp) fclose(file1); + if (file2 != Nullfp) fclose(file2); +} + +/* Check_file() opens the fileptr with name . if + * equals "-" stdin is associated with the return value. + */ +FILE *check_file(name) +char *name; +{ + FILE *temp; + + if (strcmp(name, "-") == 0) { + return(stdin); + } else { + temp = fopen(name, "r"); + if (temp == Nullfp) warn(CANNOT_OPEN_FILE, name); + return(temp); + } +} + +/* Build_option_string() is called before recursive_dir() is called + * from the main() function. its purpose is to build the string that + * is used on the command line to get the current operation mode. + * e.g. "-C 6 -b". + */ +void build_option_string() +{ + switch (mode) { + case ed_mode:sprintf(options_string, "-e"); + break; + case context: + if (context_lines == 3) + sprintf(options_string, "-c"); + else + sprintf(options_string, "-C %d", context_lines); + break; + } + +} + + +/* The fatal error handler. + * Expects a format string and a string as arguments. The arguments + * are printed to stderr and the program exits with an error code 2. + */ +void fatal_error(fmt, s) +char *fmt; /* the format sttring to be printed */ +char *s; /* string to be inserted into the format + * string */ +{ + fprintf(stderr, "%s: ", progname); + fprintf(stderr, fmt, s); + fprintf(stderr, "\n"); + exit(2); +} + +/* This function prints non fatal error messages to stderr. + * Expects the index of the message to be printed and a pointer + * to the (optional) string to be printed. + * Returns no value. + */ +void warn(number, string) +int number; /* index of the warning */ +char *string; /* string to be inserted to the warning */ +{ + static char *warning[] = { + "%s: The options -c, -e, -C n are mutually exclusive! Assuming -%c\n", + "%s: cannot open file %s for reading\n", + }; + fprintf(stderr, warning[number], progname, string); +} + +/* Function used with the optione -b, trims the blanks in a input line: + * - blanks between words are reduced to one + * - trailing blanks are eliminated. + */ +void trimming_blanks(l_text) +char *l_text; /* begin of the char array */ +{ + char *line = l_text; + char *copy_to, *copy_from; + + do { + if (*line == ' ') { + copy_from = line; + copy_to = line; + while (*(++copy_from) == ' '); + if (*copy_from != '\n') copy_to++; + while (*copy_from != '\0') *(copy_to++) = *(copy_from++); + *copy_to = '\0'; + } + } while (*(++line) != '\0'); +} + + +/* Filename separates the filename and the relative path in path_string. + * Returns the filename with a leading / + */ +char *filename(path_string) +char *path_string; +{ + char name[NAME_MAX + 2]; /* filename plus / */ + char *ptr; + + name[0] = '/'; + ptr = strrchr(path_string, '/'); + + if (ptr == 0) { /* no / in path_string, only a filename */ + strcat(name, path_string); + } else { + strcat(name, ptr); + } + + return(name); +} + +/* The line module: one member in a linked list of lines. */ +struct line { + struct line *l_next; /* pointer to the next line */ + char l_eof; /* == 0 if last line in file */ + char *l_text; /* array with the text */ +}; + +struct line *freelist = 0; +#define stepup(ll) ( ((ll) && ((ll)->l_eof==0)) ? (ll)->l_next : (ll) ) + +/* Function to allocate space for a new line containing SIZE chars */ +struct line *new_line(size) +int size; +{ + register struct line *l; + + if ((l = freelist) != NullStructLine) + freelist = freelist->l_next; + else { + l = (struct line *) xmalloc(3 * sizeof(void *)); + l->l_text = (char *) xmalloc((size + 2) * sizeof(char)); + if ((l == 0) || (l->l_text == 0)) fatal_error("Out of memory", ""); + } + return l; +} + + +/* Free_line() releases storage allocated for . */ +void free_line(l) +register struct line *l; +{ + l->l_next = freelist; + freelist = l; +} + +/* Equal_line() compares two lines, and . + * the returned value is the result of the strcmp() function. + */ +int equal_line(l1, l2) +struct line *l1, *l2; +{ + if (l1 == 0 || l2 == 0) + return(0); + else if (l1->l_eof || l2->l_eof) + return(l1->l_eof == l2->l_eof); + else + return(strcmp(l1->l_text, l2->l_text) == 0); +} + +int equal_3(l1, l2) +struct line *l1, *l2; +{ + register int i, ansr; + + ansr = 1; +#ifdef DEBUG + if (l1 == 0) + fprintf(stderr, "\t(null)\n"); + else if (l1->l_eof) + fprintf(stderr, "\t(eof)\n"); + else + fprintf(stderr, "\t%s", l1->l_text); + if (l2 == 0) + fprintf(stderr, "\t(null)\n"); + else if (l2->l_eof) + fprintf(stderr, "\t(eof)\n"); + else + fprintf(stderr, "\t%s", l2->l_text); +#endif + for (i = 0; i < 3; ++i) { + if (!equal_line(l1, l2)) { + ansr = 0; + break; + } + l1 = stepup(l1); + l2 = stepup(l2); + } +#ifdef DEBUG + fprintf(stderr, "\t%d\n", ansr); +#endif + return(ansr); +} + +struct line * + read_line(fp) +FILE *fp; +{ + register struct line *l = new_line(LINELEN); + register char *p; + register int c; + + (p = &(l->l_text[LINELEN]))[1] = '\377'; + l->l_eof = 0; + if (fgets(l->l_text, LINELEN + 2, fp) == 0) { + l->l_eof = 1; + l->l_text[0] = 0; + } else if ((p[1] & 0377) != 0377 && *p != '\n') { + while ((c = fgetc(fp)) != '\n' && c != EOF) { + } + *p++ = '\n'; + *p = '\0'; + } + l->l_next = 0; + if (trim_blanks == SET) { +#ifdef DEBUG + printf("xxx %s xxx\n", l->l_text); +#endif + trimming_blanks(l->l_text); +#ifdef DEBUG + printf("xxx %s xxx\n", l->l_text); +#endif + } + return l; +} + +/* File window handler */ +struct f { + struct line *f_bwin, *f_ewin; + struct line *f_aside; + int f_linecnt; /* line number in file of last advanced line */ + FILE *f_fp; +}; + +void advance(f) +register struct f *f; +{ + register struct line *l; + + if ((l = f->f_bwin) != NullStructLine) { + if (f->f_ewin == l) + f->f_bwin = f->f_ewin = 0; + else + f->f_bwin = l->l_next; + free_line(l); + (f->f_linecnt)++; + } +} + +void aside(f, l) +struct f *f; +struct line *l; +{ + register struct line *ll; + + if (l == 0) return; + if ((ll = l->l_next) != NullStructLine) { + while (ll->l_next) ll = ll->l_next; + ll->l_next = f->f_aside; + f->f_aside = l->l_next; + l->l_next = 0; + f->f_ewin = l; + } +} + + +struct line *next(f) +register struct f *f; +{ + register struct line *l; + + if ((l = f->f_aside) != NullStructLine) { + f->f_aside = l->l_next; + l->l_next = 0; + } else + l = read_line(f->f_fp); + if (l) { + if (f->f_bwin == 0) + f->f_bwin = f->f_ewin = l; + else { + if (f->f_ewin->l_eof && l->l_eof) { + free_line(l); + return(f->f_ewin); + } + f->f_ewin->l_next = l; + f->f_ewin = l; + } + } + return l; +} + + +/* Init_f() initialises a window structure (struct f). is the + * file associated with . + */ +void init_f(f, fp) +register struct f *f; +FILE *fp; +{ + f->f_bwin = f->f_ewin = f->f_aside = 0; + f->f_linecnt = 0; + f->f_fp = fp; +} + + +/* Update() prints a window. is a pointer to the window, is the + * string containing the "prefix" to the printout( either "<" or ">"). + * after completion of update(), the window is empty. + */ +void update(f, s) +register struct f *f; +char *s; +{ + char *help; + int only_dot = 0; + + if (firstoutput && (recursive_dir == SET)) { + printf("diff %s %s %s\n", options_string, oldfile, newfile); + firstoutput = 0; + } + while (f->f_bwin && f->f_bwin != f->f_ewin) { + if (mode != ed_mode) { + printf("%s%s", s, f->f_bwin->l_text); + } else { +#ifdef DEBUG + printf("ed_mode: test for only dot"); + printf("%s", f->f_bwin->l_text); +#endif + help = f->f_bwin->l_text; + while ((*help == ' ') || + (*help == '.') || + (*help == '\t')) { + if (*(help++) == '.') only_dot++; + if (only_dot > 1) break; + } + + /* If only_dot is equal 1, there is only one dot on + * the line, so we have to take special actions. + * f the line with only one dot is found, we output + * two dots (".."), terminate the append modus and + * substitute "." for "..". Afterwards we restart + * with the append command. */ + if (*help == '\n' && only_dot == 1) { + help = f->f_bwin->l_text; + while (*help != '\0') { + if (*help == '.') printf("."); + putchar((int) *(help++)); + } + printf(".\n"); + printf(".s/\\.\\././\n"); + printf("a\n"); + } else { + printf("%s%s", s, f->f_bwin->l_text); + } + } + advance(f); + } +} + +/* __Diff(), performs the "core operation" of the program. + * Expects two file-pointers as arguments. This functions does + * *not* check if the file-pointers are valid. + */ + +void __diff(fp1, fp2) +FILE *fp1, *fp2; +{ + struct f f1, f2; + struct line *l1, *s1, *b1, *l2, *s2, *b2; + register struct line *ll; + + init_f(&f1, fp1); + init_f(&f2, fp2); + l1 = next(&f1); + l2 = next(&f2); + while ((l1->l_eof == 0) || (l2->l_eof == 0)) { + if (equal_line(l1, l2)) { + equal: + advance(&f1); + advance(&f2); + l1 = next(&f1); + l2 = next(&f2); + continue; + } + s1 = b1 = l1; + s2 = b2 = l2; + /* Read several more lines */ + next(&f1); + next(&f1); + next(&f2); + next(&f2); + /* Start searching */ +search: + next(&f2); + ll = s1; + do { + if (equal_3(ll, b2)) { + l1 = ll; + l2 = b2; + aside(&f1, ll); + aside(&f2, b2); + differ(&f1, &f2); + goto equal; + } + if (ll->l_eof) break; + ll = stepup(ll); + } while (ll); + b2 = stepup(b2); + + next(&f1); + ll = s2; + do { + if (equal_3(b1, ll)) { + l1 = b1; + l2 = ll; + aside(&f2, ll); + aside(&f1, b1); + differ(&f1, &f2); + goto equal; + } + if (ll->l_eof != 0) break; + ll = stepup(ll); + } while (ll); + b1 = stepup(b1); + + goto search; + } + + /* Both of the files reached EOF */ +} + +/* Differ() prints the differences between files. the arguments and + * are pointers to the two windows, where the differences are. + */ +void differ(f1, f2) +register struct f *f1, *f2; +{ + int cnt1 = f1->f_linecnt, len1 = wlen(f1); + int cnt2 = f2->f_linecnt, len2 = wlen(f2); + if ((len1 != 0) || (len2 != 0)) { + if (len1 == 0) { + if (mode == ed_mode) { + cnt1 += offset; + printf("%d a\n", cnt1); + update(f2, ""); + printf(".\n"); + offset += len2; + } else { + printf("%da", cnt1); + range(cnt2 + 1, cnt2 + len2); + } + } else if (len2 == 0) { + if (mode == ed_mode) { + cnt1 += offset; + range(cnt1 + 1, cnt1 + len1); + printf("d\n"); + offset -= len1; + while (f1->f_bwin && f1->f_bwin != f1->f_ewin) + advance(f1); + } else { + range(cnt1 + 1, cnt1 + len1); + printf("d%d", cnt2); + } + } else { + if (mode != ed_mode) { + range(cnt1 + 1, cnt1 + len1); + putchar('c'); + range(cnt2 + 1, cnt2 + len2); + } else { + cnt1 += offset; + if (len1 == len2) { + range(cnt1 + 1, cnt1 + len1); + printf("c\n"); + update(f2, ""); + printf(".\n"); + } else { + range(cnt1 + 1, cnt1 + len1); + printf("d\n"); + printf("%d a\n", cnt1); + update(f2, ""); + printf(".\n"); + offset -= len1 - len2; + } + while (f1->f_bwin && f1->f_bwin != f1->f_ewin) + advance(f1); + } + } + if (mode != ed_mode) { + putchar('\n'); + if (len1 != 0) update(f1, "< "); + if ((len1 != 0) && (len2 != 0)) printf("---\n"); + if (len2 != 0) update(f2, "> "); + } + diffs++; + } +} + + +/* Function wlen() calculates the number of lines in a window. */ +int wlen(f) +struct f *f; +{ + register cnt = 0; + register struct line *l = f->f_bwin, *e = f->f_ewin; + + while (l && l != e) { + cnt++; + l = l->l_next; + } + return cnt; +} + + +/* Range() prints the line numbers of a range. the arguments and + * are the beginning and the ending line number of the range. if + * == , only one line number is printed. otherwise and are + * separated by a ",". + */ +void range(a, b) +int a, b; +{ + printf(((a == b) ? "%d" : "%d,%d"), a, b); +} + +/* Here follows the code for option -c. + * This code is from the cdiff program by Larry Wall. I changed it only + * slightly to reflect the POSIX standard and to call the main routine + * as function context_diff(). + */ + +/* Cdiff - context diff Author: Larry Wall */ + +/* These global variables are still here from the original cdiff program... + * I was to lazy just to sort them out... + */ +char buff[512]; +FILE *oldfp, *newfp; + +int oldmin, oldmax, newmin, newmax; +int oldbeg, oldend, newbeg, newend; +int preoldmax, prenewmax; +int preoldbeg, preoldend, prenewbeg, prenewend; +int oldwanted, newwanted; + +char *oldhunk, *newhunk; +size_t oldsize, oldalloc, newsize, newalloc; + +void cdiff(old, new, file1, file2) +char *old, *new; /* The names of the two files to be compared */ +FILE *file1, *file2; /* The corresponding file-pointers */ +{ + FILE *inputfp; + struct stat statbuf; + register char *s; + char op; + char *newmark, *oldmark; + int len; + char *line; + int i, status; + + oldfp = file1; + newfp = file2; + + oldalloc = 512; + oldhunk = (char *) xmalloc(oldalloc); + newalloc = 512; + newhunk = (char *) xmalloc(newalloc); + + +/* The context diff spawns a new process that executes a normal diff + * and parses the output. + */ + if (trim_blanks == SET) + sprintf(buff, "diff -b %s %s", old, new); + else + sprintf(buff, "diff %s %s", old, new); + + inputfp = popen(buff, "r"); + if (!inputfp) { + fprintf(stderr, "Can't execute diff %s %s\n", old, new); + exit(2); + } + preoldend = -1000; + firstoutput = 1; + while (fgets(buff, sizeof buff, inputfp) != Nullch) { + if (firstoutput) { + if (recursive_dir == SET) { + printf("diff %s %s %s\n", options_string, + oldfile, newfile); + } + fstat(fileno(oldfp), &statbuf); + printf("*** %s %s", old, ctime(&statbuf.st_mtime)); + fstat(fileno(newfp), &statbuf); + printf("--- %s %s", new, ctime(&statbuf.st_mtime)); + firstoutput = 0; + } + if (isdigit(*buff)) { + oldmin = atoi(buff); + for (s = buff; isdigit(*s); s++); + if (*s == ',') { + s++; + oldmax = atoi(s); + for (; isdigit(*s); s++); + } else { + oldmax = oldmin; + } + if (*s != 'a' && *s != 'd' && *s != 'c') { + fprintf(stderr, "Unparseable input: %s", s); + exit(2); + } + op = *s; + s++; + newmin = atoi(s); + for (; isdigit(*s); s++); + if (*s == ',') { + s++; + newmax = atoi(s); + for (; isdigit(*s); s++); + } else { + newmax = newmin; + } + if (*s != '\n' && *s != ' ') { + fprintf(stderr, "Unparseable input: %s", s); + exit(2); + } + newmark = oldmark = "! "; + if (op == 'a') { + oldmin++; + newmark = "+ "; + } + if (op == 'd') { + newmin++; + oldmark = "- "; + } + oldbeg = oldmin - context_lines; + oldend = oldmax + context_lines; + if (oldbeg < 1) oldbeg = 1; + newbeg = newmin - context_lines; + newend = newmax + context_lines; + if (newbeg < 1) newbeg = 1; + + if (preoldend < oldbeg - 1) { + if (preoldend >= 0) { + dumphunk(); + } + preoldbeg = oldbeg; + prenewbeg = newbeg; + oldwanted = newwanted = 0; + oldsize = newsize = 0; + } else { /* we want to append to previous hunk */ + oldbeg = preoldmax + 1; + newbeg = prenewmax + 1; + } + + for (i = oldbeg; i <= oldmax; i++) { + line = getold(i); + if (!line) { + oldend = oldmax = i - 1; + break; + } + len = strlen(line) + 2; + if (oldsize + len + 1 >= oldalloc) { + oldalloc *= 2; + oldhunk = (char *) xrealloc(oldhunk, oldalloc); + } + if (i >= oldmin) { + strcpy(oldhunk + oldsize, oldmark); + oldwanted++; + } else { + strcpy(oldhunk + oldsize, " "); + } + strcpy(oldhunk + oldsize + 2, line); + oldsize += len; + } + preoldmax = oldmax; + preoldend = oldend; + + for (i = newbeg; i <= newmax; i++) { + line = getnew(i); + if (!line) { + newend = newmax = i - 1; + break; + } + len = strlen(line) + 2; + if (newsize + len + 1 >= newalloc) { + newalloc *= 2; + newhunk = (char *) xrealloc(newhunk, newalloc); + } + if (i >= newmin) { + strcpy(newhunk + newsize, newmark); + newwanted++; + } else { + strcpy(newhunk + newsize, " "); + } + strcpy(newhunk + newsize + 2, line); + newsize += len; + } + prenewmax = newmax; + prenewend = newend; + } + } + status = pclose(inputfp); + if (status != 0) diffs++; + if (!WIFEXITED(status) || WEXITSTATUS(status) > 1) severe_error = 1; + + if (preoldend >= 0) { + dumphunk(); + } +} + +void dumphunk() +{ + int i; + char *line; + int len; + + for (i = preoldmax + 1; i <= preoldend; i++) { + line = getold(i); + if (!line) { + preoldend = i - 1; + break; + } + len = strlen(line) + 2; + if (oldsize + len + 1 >= oldalloc) { + oldalloc *= 2; + oldhunk = (char *) xrealloc(oldhunk, oldalloc); + } + strcpy(oldhunk + oldsize, " "); + strcpy(oldhunk + oldsize + 2, line); + oldsize += len; + } + for (i = prenewmax + 1; i <= prenewend; i++) { + line = getnew(i); + if (!line) { + prenewend = i - 1; + break; + } + len = strlen(line) + 2; + if (newsize + len + 1 >= newalloc) { + newalloc *= 2; + newhunk = (char *) xrealloc(newhunk, newalloc); + } + strcpy(newhunk + newsize, " "); + strcpy(newhunk + newsize + 2, line); + newsize += len; + } + fputs("***************\n", stdout); + if (preoldbeg >= preoldend) { + printf("*** %d ****\n", preoldend); + } else { + printf("*** %d,%d ****\n", preoldbeg, preoldend); + } + if (oldwanted) { + fputs(oldhunk, stdout); + } + oldsize = 0; + *oldhunk = '\0'; + if (prenewbeg >= prenewend) { + printf("--- %d ----\n", prenewend); + } else { + printf("--- %d,%d ----\n", prenewbeg, prenewend); + } + if (newwanted) { + fputs(newhunk, stdout); + } + newsize = 0; + *newhunk = '\0'; +} + +char *getold(targ) +int targ; +{ + static int oldline = 0; + + while (fgets(buff, sizeof buff, oldfp) != Nullch) { + oldline++; + if (oldline == targ) return buff; + } + return Nullch; +} + +char *getnew(targ) +int targ; +{ + static int newline = 0; + + while (fgets(buff, sizeof buff, newfp) != Nullch) { + newline++; + if (newline == targ) return buff; + } + return Nullch; +} + + +/* Isdir() checks, if is the name of a directory. a return value + * is 0, is a normal file. otherwise the is a directory. + */ +int isdir(path) +char *path; +{ + struct stat buf; + stat(path, &buf); + if (buf.st_mode & S_IFDIR) { /* path is a directory */ + return(~0); + } else { + return(0); + } +} + + + +/* This is the "main" function if a diff of two directories has to be + * done. diff_recursive() expects the names of the two directories to + * be compared. */ +void diff_recursive(dir1, dir2) +char *dir1, *dir2; +{ + FILE *ls1, *ls2; + char file1[PATH_MAX], file2[PATH_MAX]; + char jointfile1[PATH_MAX], jointfile2[PATH_MAX]; + char command[PATH_MAX]; + int difference, eof1, eof2; + + sprintf(command, "ls %s", dir1); + ls1 = popen(command, "r"); + sprintf(command, "ls %s", dir2); + ls2 = popen(command, "r"); + + if ((ls1 == NULL) || (ls2 == NULL)) + fatal_error("cannot execute ls!", ""); + + file1[0] = '\0'; + eof1 = fscanf(ls1, "%s\n", file1); + file2[0] = '\0'; + eof2 = fscanf(ls2, "%s\n", file2); + + while ((file1[0] != '\0') && (file2[0] != '\0')) { + difference = strcmp(file1, file2); + while (difference != 0) { + if (difference < 0) { + printf("Only in %s: %s\n", dir1, file1); + file1[0] = '\0'; + eof1 = fscanf(ls1, "%s\n", file1); + if (file1[0] == '\0') break; + } else { + printf("Only in %s: %s\n", dir2, file2); + file2[0] = '\0'; + eof2 = fscanf(ls2, "%s\n", file2); + if (file2[0] == '\0') break; + } + difference = strcmp(file1, file2); + } + if (eof1 != EOF && eof2 != EOF) { + strcpy(jointfile1, dir1); + strcat(jointfile1, "/"); + strcat(jointfile1, file1); + strcpy(jointfile2, dir2); + strcat(jointfile2, "/"); + strcat(jointfile2, file2); + + if ((isdir(jointfile1) != 0) && (isdir(jointfile2) != 0)) { + printf("Common subdirectories: %s and %s\n", + jointfile1, jointfile2); + diff_recursive(jointfile1, jointfile2); + } else { + firstoutput = 1; + strcpy(oldfile, jointfile1); + strcpy(newfile, jointfile2); + diff(jointfile1, jointfile2); + } + file1[0] = '\0'; + eof1 = fscanf(ls1, "%s\n", file1); + file2[0] = '\0'; + eof2 = fscanf(ls2, "%s\n", file2); + } + } + + if (file1[0] != '\0') { /* first arg still has files */ + do { + printf("Only in %s: %s\n", dir1, file1); + eof1 = fscanf(ls1, " %s\n", file1); + } while (eof1 != EOF); + } + if (file2[0] != '\0') { + do { + printf("Only in %s: %s\n", dir2, file2); + eof2 = fscanf(ls2, " %s\n", file2); + } while (eof2 != EOF); + } + if (pclose(ls1) != 0) severe_error = 1; + if (pclose(ls2) != 0) severe_error = 1; +} + + +/* File_type_error is called, if in a recursive diff ( -r) one of the two + * files a block special, a character special or a FIFO special file is. + * The corresponding error message is printed here. */ +void file_type_error(filename1, filename2, statbuf1, statbuf2) +char *filename1, *filename2; +struct stat *statbuf1, *statbuf2; +{ + char type1[25], type2[25]; + + switch (statbuf1->st_mode & S_IFMT) { /* select only file mode */ + case S_IFREG: + sprintf(type1, "regular file "); + break; + case S_IFBLK: + sprintf(type1, "block special file "); + break; + case S_IFDIR: sprintf(type1, "directory "); break; + case S_IFCHR: + sprintf(type1, "character special file "); + break; + case S_IFIFO: + sprintf(type1, "FIFO special file "); + break; + } + + switch (statbuf2->st_mode & S_IFMT) { /* select only file mode */ + case S_IFREG: + sprintf(type2, "regular file "); + break; + case S_IFBLK: + sprintf(type2, "block special file "); + break; + case S_IFDIR: sprintf(type2, "directory "); break; + case S_IFCHR: + sprintf(type2, "character special file "); + break; + case S_IFIFO: + sprintf(type2, "FIFO special file "); + break; + } + printf("File %s is a %s while file %s is a %s\n", + filename1, type1, filename2, type2); +} + +void *xmalloc(size) +size_t size; +{ + void *ptr; + + ptr = malloc(size); + if (ptr == NULL) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(2); + } + return(ptr); +} + +void *xrealloc(ptr, size) +void *ptr; +size_t size; +{ + ptr = realloc(ptr, size); + if (ptr == NULL) { + fprintf(stderr, "%s: out of memory\n", progname); + exit(2); + } + return(ptr); +} diff --git a/src/simple/dirname.c b/src/simple/dirname.c new file mode 100755 index 00000000..558f1adc --- /dev/null +++ b/src/simple/dirname.c @@ -0,0 +1,41 @@ +/* dirname.c + */ +#include +#include + +void strip_trailing_slashes(path) + char *path; +{ + char *last = path + strlen(path) - 1; + + while (last > path && *last == '/') + *last-- = '\0'; +} + +int main (argc, argv) + int argc; + char **argv; +{ + char *line, *p; + + if (argc == 2) { + strip_trailing_slashes(p = argv[1]); + line = rindex(p, '/'); + if (line == NULL) { + p[0] = '.'; + p[1] = 0; + } + else { + while (line > p && *line == '/') + --line; + line[1] = 0; + } + write(STDOUT_FILENO, p, strlen(p)); + write(STDOUT_FILENO,"\n", 1); + return 0; + } else { + write(STDOUT_FILENO, "usage: dirname filename\n",24); + return 1; + } +} + diff --git a/src/simple/diskusag.c b/src/simple/diskusag.c new file mode 100755 index 00000000..714cf40a --- /dev/null +++ b/src/simple/diskusag.c @@ -0,0 +1,496 @@ +/* Diskusg - determines usage disk Author: Don Chapman */ + +/* + * + * Diskusg - Patterned after System V Administrative command + * but written for MINIX V1.5 or V1.6 from scratch. + * Does not access disk structures directly. Should + * be fairly portable to C with dirent. This version + * will count files that are linked to other names for + * each name. + * + * Output: Output is a listing, on stdout, by uid of the blocks + * in use on a special device (block structured, ie. disk) + * sorted by uid. Shows total blocks in use on the + * device for each uid. Form: uid username longint. + * + * Usage: diskusg [-p fil] [-u fil] [-s] [-v] [-i flst] spec.file ... + * + * Flags: -p fil Use "fil" to obtain a list of the usernames and + * uids rather than /etc/passwd. The file must be + * similar in form to /etc/passwd at least beyond + * the uid. eg: ast:Oky||V|yoZ7vO:8: or ast::8: + * + * -u fil Make an ascii list in "fil" of files that seem to + * belong to nobody. The form of the list is: + * special-file-name i-node-number user-ID. + * + * -s The input files are files of diskusg outputs and + * the new output should be the cumulative sum of the + * usages. The files were probably made using the + * command diskusg /specdev > file. This one deletes + * any duplicate usernames and charges all to the + * first username it sees. + * + * -v Verbose makes a listing on stderr of the files or + * directorys found with unknown owners. + * + * -i flst Ignore the data on the file systems whose name is + * in flst. Flst is a list of names separated by + * commas or enclosed within quotes. Diskusg compares + * each name with the names on the spec. file relative + * to the root (/) of the spec. file. + * ie: dskusg -i /tmp/ignoreme,/joe,/lib /dev/fd1 + * + * specfil The name of a special file (block structured) to be + * searched for disk usage. + * eg.: /dev/hd2 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(MSX_UZIX_TARGET) || defined(PC_UZIX_TARGET) +typedef uint uid_t; +#define NAME_MAX MAXNAMLEN +#define geteuid getuid +#define mktemp tmpnam +#endif + +/* Un-comment or compile -DREMOVE_DUPES if you wish */ + /* #define REMOVE_DUPES *//* option to always remove duplicate usernames */ +#define FALSE 0 +#define TRUE ~FALSE +#define PWLEN 100 +#define PLENGTH 40 + +#define USEREC struct userecord +USEREC { + char *name; + uid_t uid; + long blocks; + USEREC *next; +}; + +#define IGNREC struct ignrecord +IGNREC { + char *structname; + IGNREC *next; +}; + +static char *Version = "@(#) DISKUSG 1.00 D.E.C. (04/10/91)"; + +/* Globals */ +char *progname; +char *passwd = "/etc/passwd"; +char *ufile = NULL; +int uflag = FALSE; +FILE *ufd; +USEREC *list_head = NULL; +int verbose = FALSE; +int sflag = FALSE; +char *spec_name = "\0"; +struct stat this_stat; +dev_t real_dev; +char *ilist = NULL; +int iflag = FALSE; +IGNREC *ign_head = NULL; +int didmount = FALSE; +int mountlength; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int exists, (USEREC * head, uid_t uid)); +_PROTOTYPE(void insert, (USEREC ** head, USEREC * rec)); +_PROTOTYPE(void make_userlist, (void)); +_PROTOTYPE(void showlist, (void)); +_PROTOTYPE(int update_list, (uid_t uid, off_t bytes)); +_PROTOTYPE(void search_all, (char *cur_dir)); +_PROTOTYPE(int ilist_search, (char *path)); +_PROTOTYPE(void usage, (void)); +_PROTOTYPE(int main, (int argc, char *argv[])); +_PROTOTYPE(void malloc_chk, (void *p)); + + +/* For -s flag that builds the list as it goes */ +int exists(head, uid) /* See if uid already exists. */ +USEREC *head; /* In -s list disallow dupes. */ +uid_t uid; +{ + USEREC *curs; + for (curs = head; curs != NULL; curs = curs->next) + if (curs->uid == uid) return(TRUE); + return(FALSE); +} + +void insert(head, rec) /* Sorted by uid (keep duplicates) */ +USEREC **head; /* Normally there should be none but */ +USEREC *rec; /* I wanted option to see them... */ +{ + if (*head == NULL) { + rec->next = *head; + *head = rec; +#ifdef REMOVE_DUPES + } else if ((*head)->uid == rec->uid) { + return; +#endif + } else if ((*head)->uid > rec->uid) { + rec->next = *head; + *head = rec; + } else + insert(&((*head)->next), rec); +} + +void make_userlist() +{ /* Make list of known users. */ + FILE *fp1; /* do not remove duplicates */ + USEREC *temp_rec; /* however the blocks will */ + char line[PWLEN]; /* counted against first name */ + char *p1; + size_t name_length; + + fp1 = fopen(passwd, "r"); + while (!feof(fp1)) { + if (fgets(line, PWLEN, fp1)) { + temp_rec = (USEREC *) malloc(sizeof(USEREC)); + malloc_chk(temp_rec); + p1 = line; + name_length = 0; + while (*p1 && *p1 != ':') { + p1++; + name_length++; + } + *p1++ = '\0'; + temp_rec->name = (char *) malloc(name_length + 1); + malloc_chk(temp_rec); + strcpy(temp_rec->name, line); + while (*p1 && *p1 != ':') p1++; /* skip passwd */ + temp_rec->uid = atoi(++p1); + temp_rec->blocks = 0L; + insert(&list_head, temp_rec); + } + } + fclose(fp1); +} + +void showlist() +{ + USEREC *curs; + for (curs = list_head; curs != NULL; curs = curs->next) + printf("%d\t%-14s\t%ld\n", curs->uid, curs->name, curs->blocks); +} + +int update_list(uid, bytes) /* Increment uid's total. */ +uid_t uid; /* If uid has duplicates */ +off_t bytes; /* will be charged to first. */ +{ + USEREC *curs; + int found = 0; + for (curs = list_head; curs != NULL; curs = curs->next) { + if (curs->uid == uid) { + found++; + curs->blocks += (bytes + 1024 - 1) / 1024; /* ceiling */ + break; + } + } + return(found); /* -u and -v option need to know */ +} + +/* Traverse recursively: all directories on volume. */ +void search_all(cur_dir) /* If another volume is mounted on this vol */ +char *cur_dir; /* only the files really on this volume are */ +{ /* to be counted in the accumulated total. */ + struct dirent *this_file; + DIR *dp1; /* Activation record 4 pointers 1 int so */ + char *next_entry; /* should be able to recurse very deep. */ + int dir_length; /* Uses malloc and free for temporary space */ + int s; + + dir_length = strlen(cur_dir); + next_entry = (char *) malloc(strlen(cur_dir) + NAME_MAX + 2); + malloc_chk(next_entry); + strcpy(next_entry, cur_dir); + if (next_entry[dir_length - 1] != '/') { + strcat(next_entry, "/"); + dir_length++; + } + dp1 = opendir(cur_dir); + if (dp1 == NULL) { + fprintf(stderr, "Opendir returned NULL. (%s).\n", strerror(errno)); + exit(EXIT_FAILURE); + } + while ((this_file = readdir(dp1)) != NULL) { + /* Iterate through this directory */ + if (strcmp(this_file->d_name, ".") && + strcmp(this_file->d_name, "..")) { + strcpy(&next_entry[dir_length], this_file->d_name); + stat(next_entry, &this_stat); + if (real_dev != this_stat.st_dev) continue; + if (iflag) { + if (ilist_search(next_entry)) continue; + } + if (S_ISDIR(this_stat.st_mode)) { + /* Is a directory need to recurse */ + s = update_list((uid_t) this_stat.st_uid, +#if 0 /* Nick */ + 512L*this_stat.st_size.o_blkno + this_stat.st_size.o_offset); +#else + this_stat.st_size); +#endif + if (!s) { + if (verbose) fprintf(stderr, + "%s: Directory, No Owner, %s\n", + progname, next_entry); + if (uflag) fprintf(ufd, "%s %d %d\n", + spec_name, + this_stat.st_ino, + this_stat.st_uid); + } + search_all(next_entry); /* recursive call */ + } else { + /* Is regular file or spec. file */ + if (S_ISREG(this_stat.st_mode)) { + s = update_list((uid_t) this_stat.st_uid, +#if 0 /* Nick */ + 512L*this_stat.st_size.o_blkno + this_stat.st_size.o_offset); +#else + this_stat.st_size); +#endif + if (!s) { + if (verbose) fprintf(stderr, + "%s: File, No Owner, %s\n", + progname, next_entry); + if (uflag) fprintf(ufd, "%s %d %d\n", + spec_name, this_stat.st_ino, + this_stat.st_uid); + } /* endif !update */ + } /* end S_ISREG */ + /* Ignores any Specials: b, c, pipe, etc. */ + } /* endelse */ + } /* endif "." */ + } /* endwhile */ + closedir(dp1); + free(next_entry); +} + +int ilist_search(path) +char *path; +{ + IGNREC *ptr; + for (ptr = ign_head; ptr != NULL; ptr = ptr->next) { + if (!strcmp(&path[mountlength], ptr->structname)) return(TRUE); + } + return(FALSE); +} + +void usage() +{ + fprintf(stderr, + "usage: %s [-p file] [-s] [-u file] [-v] [-i file] [spec file]\n", progname); + exit(EXIT_FAILURE); +} + +/* Later be sure have counted the directory file sizes too ! */ +int main(argc, argv) +int argc; +char *argv[]; +{ + FILE *mtb; + FILE *dskusg; + USEREC *m_rec; + IGNREC *i_temp; + char line[PLENGTH]; + char mountedon[PLENGTH]; + char mf1[PLENGTH], mf2[PLENGTH], mf3[PLENGTH], mf4[PLENGTH], mf5[PLENGTH]; + char *p1, *p2, *p3; + int r; + size_t siz; + uid_t m_uid; + long m_blocks; + unsigned scan_uid; + progname = argv[0]; + argc--; + argv++; + while (argv[0] != NULL && argv[0][0] == '-') { + switch (argv[0][1]) { + case 'p': + if (argc > 1) passwd = argv[1]; + argc--; + argv++; + break; + case 'v': verbose++; break; + case 'u': + if (argc > 1) { + ufile = argv[1]; + uflag++; + argc--; + argv++; + break; + } else + usage(); + case 'i': + if (argc > 1) { + ilist = argv[1]; + iflag++; + argc--; + argv++; + break; + } else + usage(); + case 's': sflag++; break; + default: usage(); + } + /* Else spec file ? */ + + argc--; + argv++; + } /* end while '-' */ + if (!argc) usage(); + if (!sflag) make_userlist(); + if (iflag) { /* parse the ignore string and make list */ + p1 = p2 = ilist; + if (!*p1) { + fprintf(stderr, "%s: Bad -i list\n", progname); + exit(EXIT_FAILURE); + } + while (*p1) { + while (*p1 && !isspace(*p1) && *p1 != ',') p1++; + if (*p1) { + *p1 = '\0'; + p1++; + while (isspace(*p1)) p1++; + } + i_temp = (IGNREC *) malloc(sizeof(IGNREC)); + malloc_chk(i_temp); + siz = strlen(p2) + 1; + p3 = (char *) malloc(siz); + malloc_chk(p3); + i_temp->structname = p3; + strcpy(i_temp->structname, p2); + p2 = p1; + i_temp->next = ign_head; /* just stack'em */ + ign_head = i_temp; + } /* end while */ + } /* if iflag */ + if (uflag && !sflag) ufd = fopen(ufile, "w"); + +/* While there are more "files" to this command */ + while (argc > 0) { /* more to do */ + spec_name = argv[0]; + argc--; + argv++; + + /* Option -s sum values from previous diskusg output */ + if (sflag) { + /* Read output of previous diskusg output and total it */ + if ((dskusg = fopen(spec_name, "r")) == NULL) { + fprintf(stderr, "%s: -s open failed on %s\n", progname, spec_name); + exit(EXIT_FAILURE); + } + while (fgets(line, PLENGTH, dskusg)) { + sscanf(line, "%u%s%ld", &scan_uid, mf1, &m_blocks); + m_uid = scan_uid; + if (!exists(list_head, m_uid)) { + m_rec = (USEREC *) malloc(sizeof(USEREC)); + malloc_chk(m_rec); + m_rec->name = (char *) malloc(strlen(mf1) + 1); + malloc_chk(m_rec->name); + strcpy(m_rec->name, mf1); + m_rec->uid = m_uid; + m_rec->blocks = 0L; + insert(&list_head, m_rec); + } /* if !exist */ + update_list((uid_t) m_uid, + (off_t) 1024 * m_blocks); + } /* while fgets */ + fclose(dskusg); + continue; /* go on to next "while" file */ + } /* if sflag */ + /* Search all the files on the special device (not option -s) */ + stat(spec_name, &this_stat); /* will ignore "mounted on + * spec.dev" */ + real_dev = this_stat.st_rdev; /* using only files really on + * device */ + /* See if is block special */ + if (!S_ISBLK(this_stat.st_mode)) usage(); + + /* See if device is mounted already by searching mtab (old or new) */ + if ((mtb = fopen("/etc/mtab", "r")) == NULL) { + fprintf(stderr, "%s: No /etc/mtab found.\n", progname); + exit(EXIT_FAILURE); + } + mountedon[0] = '\0'; + while (!feof(mtb)) { /* see if mounted already */ + if (fgets(line, PLENGTH, mtb)) { + mf1[0] = mf2[0] = mf3[0] = mf4[0] = mf5[0] = '\0'; + r = sscanf(line, "%s%s%s%s%s", mf1, mf2, mf3, mf4, mf5); + if (!strcmp(spec_name, mf1)) { + if (r > 4) + strcpy(mountedon, mf5); /* hmmm.. old mtab */ + else { + if (!strcmp(mf3, "root")) + strcpy(mountedon, "/"); /* old mtab */ + else + strcpy(mountedon, mf2); /* new mtab */ + } + break; + } + } + } + fclose(mtb); + if (!mountedon[0]) { /* not mounted so mount temporarily */ + strcpy(mountedon, "tmpXXXXXX"); + mktemp(mountedon); + if (mkdir(mountedon, 0700)) { + fprintf(stderr, "%s: Can not make a temporary directory in pwd\n", progname); + exit(EXIT_FAILURE); + } + if (mount(spec_name, mountedon, 1)) { /* read only */ + rmdir(mountedon); /* clean up before leaving */ + if (geteuid() != 0) { + fprintf(stderr, "%s: Must run as root in order to mount %s\n", progname, spec_name); + exit(EXIT_FAILURE); + } + fprintf(stderr, "%s: Could not mount %s\n", progname, spec_name); + exit(EXIT_FAILURE); + } + didmount = TRUE; + } + mountlength = strlen(mountedon); /* Note: means -i names + * begin with / */ + search_all(mountedon); /* call the "traverse and accumulate" + * routine */ + if (didmount) { + umount(spec_name); + rmdir(mountedon); + didmount = FALSE; + } + spec_name[0] = '\0'; + mountedon[0] = '\0'; + } /* while argc > 0 .. spec_name */ + if (uflag && !sflag) fclose(ufd); + showlist(); /* list results to stdout */ + return(EXIT_SUCCESS); +} + +void malloc_chk(ptr) +void *ptr; +{ + if (ptr == NULL) { + fprintf(stderr, + "Malloc returned NULL. Use chmem to allocate more stack\n"); + exit(EXIT_FAILURE); + } +} diff --git a/src/simple/dosread.c b/src/simple/dosread.c new file mode 100755 index 00000000..a89a630b --- /dev/null +++ b/src/simple/dosread.c @@ -0,0 +1,1307 @@ +/* dos{dir|read|write|del} - {list|read|write|del} MS-DOS disks Author: M. Huisjes */ + +/* dosdir - list MS-DOS directories to stdout + * doswrite - write stdin/file to DOS-file + * dosread - read DOS-file to stdout/file + * dosdel - delete DOS-file + * + * Author: Michiel Huisjes. + * + * Usage: dos... [-lra] drive [ms-dos file/dir] [file] + * l: Give long listing. + * r: List recursively. + * a: Set ASCII bit. + */ + +#ifdef MSX_UZIX_TARGET +/* no assertions for MSX UZIX - let's save memory! */ +#define NDEBUG +#undef CACHE_ROOT +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +#ifdef MSX_UZIX_TARGET +/* these are true numbers, but you can increase if you have memory */ +#define MAX_CLUSTER_SIZE 8192 +#define MAX_ROOT_ENTRIES 256 +#else +#ifdef PC_UZIX_TARGET +/* due to limitation of memory... */ +#define MAX_CLUSTER_SIZE 2048 +#define MAX_ROOT_ENTRIES 256 +#else +#define MAX_CLUSTER_SIZE 4096 +#define MAX_ROOT_ENTRIES 512 +#endif +#endif +#define FAT_START 512L /* After bootsector */ +#define ROOTADDR (FAT_START + 2L * fat_size) +#define clus_add(cl_no) ((long) (((long) cl_no - 2L) \ + * (long) cluster_size \ + + data_start \ + )) +struct dir_entry { + unsigned char d_name[8]; + unsigned char d_ext[3]; + unsigned char d_attribute; + unsigned char d_reserved[10]; + unsigned short d_time; + unsigned short d_date; + unsigned short d_cluster; + unsigned long d_size; +}; + +typedef struct dir_entry DIRECTORY; + +#define NOT_USED 0x00 +#define ERASED 0xE5 +#define DIR 0x2E +#define DIR_SIZE (sizeof (struct dir_entry)) +#define SUB_DIR 0x10 +#define NIL_DIR ((DIRECTORY *) 0) + +#define LAST_CLUSTER12 0xFFF +#define LAST_CLUSTER 0xFFFF +#define FREE 0x000 +#define BAD 0xFF0 +#define BAD16 0xFFF0 + +#define FCLOSE if (fdo != stdout) fclose(fdo) +#define FABORT(x) FCLOSE; exit(x) + +typedef int BOOL; + +#define TRUE 1 +#define FALSE 0 +#define NIL_PTR ((char *) 0) + +#define DOS_TIME 315532800L /* 1970 - 1980 */ + +#define READ 0 +#define WRITE 1 + +#define FIND 3 +#define LABEL 4 +#define ENTRY 5 +#define find_entry(d, e, p) directory(d, e, FIND, p) +#define list_dir(d, e, f) (void) directory(d, e, f, NIL_PTR) +#define label() directory(root, root_entries, LABEL, NIL_PTR) +#define new_entry(d, e) directory(d, e, ENTRY, NIL_PTR) + +#define is_dir(d) ((d)->d_attribute & SUB_DIR) + +#define STD_OUT 1 + +char *cmnd; + +static int disk; /* File descriptor for disk I/O */ + +#ifdef CACHE_ROOT +static DIRECTORY root[MAX_ROOT_ENTRIES]; +#else +static DIRECTORY *root = NULL; +#endif +static DIRECTORY save_entry; +static char drive[] = "/dev/dosX"; +static char drive2[] = "/dev/fdX"; +#define DRIVE_NR (sizeof (drive) - 2) +static char buffer[MAX_CLUSTER_SIZE], *device = drive, path[128]; +static long data_start; +static long mark; /* offset of directory entry to be written */ +static unsigned short total_clusters, cluster_size, root_entries, sub_entries; +static unsigned long fat_size; +static char *unixfile; +FILE *fdo; + +static BOOL Rflag, Lflag, Aflag, dos_read, dos_write, dos_dir, dos_del, fat_16 = 0; +static BOOL big_endian; + +/* maximum size of a cooked 12bit FAT. Also Size of 16bit FAT cache + * if not enough memory for whole FAT + */ +#ifdef MSX_UZIX_TARGET +#define COOKED_SIZE 512 +#else +#define COOKED_SIZE 8192 +#endif +/* raw FAT. Only used for 12bit FAT to make conversion easier + */ +static unsigned char *raw_fat; +/* Cooked FAT. May be only part of the FAT for 16 bit FATs + */ +static unsigned short *cooked_fat; +/* lowest and highest entry in fat cache + */ +static unsigned short fat_low = USHRT_MAX, + fat_high = 0; +static BOOL fat_dirty = FALSE; +static unsigned int cache_size; +static unsigned long rawfat_size; + + +/* Prototypes. */ +_PROTOTYPE(void usage, (char *prog_name) ); +_PROTOTYPE(unsigned c2u2, (unsigned char *ucarray) ); +_PROTOTYPE(unsigned long c4u4, (unsigned char *ucarray) ); +_PROTOTYPE(void determine, (void)); +_PROTOTYPE(int main, (int argc, char *argv [])); +_PROTOTYPE(DIRECTORY *directory, (DIRECTORY *dir, int entries, BOOL function, char *pathname) ); +_PROTOTYPE(void extract, (DIRECTORY *entry) ); +_PROTOTYPE(void delete, (DIRECTORY *entry) ); +_PROTOTYPE(void make_file, (DIRECTORY *dir_ptr, int entries, char *name) ); +_PROTOTYPE(void fill_date, (DIRECTORY *entry) ); +_PROTOTYPE(char *make_name, (register DIRECTORY *dir_ptr, short dir_fl) ); +_PROTOTYPE(int fill, (char *buff, size_t size) ); +_PROTOTYPE(void xmodes, (int mode) ); +_PROTOTYPE(void show, (DIRECTORY *dir_ptr, char *name) ); +_PROTOTYPE(void free_blocks, (void)); +_PROTOTYPE(DIRECTORY *read_cluster, (unsigned int cluster) ); +_PROTOTYPE(unsigned short free_cluster, (BOOL leave_fl) ); +_PROTOTYPE(void link_fat, (unsigned int cl_1, unsigned int cl_2) ); +_PROTOTYPE(unsigned short next_cluster, (unsigned int cl_no) ); +_PROTOTYPE(unsigned short clear_cluster, (unsigned int cl_no) ); +_PROTOTYPE(char *slash, (char *str) ); +_PROTOTYPE(void add_path, (char *file, BOOL slash_fl) ); +_PROTOTYPE(void disk_io, (BOOL op, unsigned long seek, void *address, unsigned bytes) ); +_PROTOTYPE(void flush_fat, (void)); +_PROTOTYPE(void read_fat, (unsigned int cl_no)); +_PROTOTYPE(BOOL free_range, (unsigned short *first, unsigned short *last)); +_PROTOTYPE(long lmin, (long a, long b)); + +void usage(prog_name) +register char *prog_name; +{ + fprintf (stderr, "usage: %s ", prog_name); + if (dos_dir) fprintf(stderr, "[-lr] drive [dir]\n"); + if (dos_read || dos_write) fprintf(stderr, "[-a] drive dosfile [file]\n"); + if (dos_del) fprintf(stderr, "drive dosfile\n"); + exit(1); +} + +unsigned c2u2(ucarray) +unsigned char *ucarray; +{ + return ucarray[0] + (ucarray[1] << 8); /* parens vital */ +} + +unsigned long c4u4(ucarray) +unsigned char *ucarray; +{ + return ucarray[0] + ((unsigned long) ucarray[1] << 8) + + ((unsigned long) ucarray[2] << 16) + + ((unsigned long) ucarray[3] << 24); +} + +void determine() +{ + struct dosboot { + unsigned char cjump[2]; /* unsigneds avoid bugs */ + unsigned char nop; + unsigned char name[8]; + unsigned char cbytepers[2]; /* don't use shorts, etc */ + unsigned char secpclus; /* to avoid struct member */ + unsigned char creservsec[2]; /* alignment and byte */ + unsigned char fats; /* order bugs */ + unsigned char cdirents[2]; + unsigned char ctotsec[2]; + unsigned char media; + unsigned char csecpfat[2]; + unsigned char csecptrack[2]; + unsigned char cheads[2]; + unsigned char chiddensec[2]; + unsigned char dos4hidd2[2]; + unsigned char dos4totsec[4]; + /* Char fill[476]; */ + } boot; + unsigned short boot_magic; /* last of boot block */ + unsigned bytepers, reservsec, dirents; + unsigned secpfat, secptrack, heads, hiddensec; + unsigned long totsec; + unsigned char fat_info, fat_check; + unsigned short endiantest = 1; + int errcount = 0; + + big_endian = !(*(unsigned char *)&endiantest); + + /* Read Bios-Parameterblock */ + disk_io(READ, 0L, &boot, sizeof boot); + disk_io(READ, 0x1FEL, &boot_magic, sizeof boot_magic); + + /* Convert some arrays */ + bytepers = c2u2(boot.cbytepers); + reservsec = c2u2(boot.creservsec); + dirents = c2u2(boot.cdirents); + totsec = c2u2(boot.ctotsec); + if (totsec == 0) totsec = c4u4(boot.dos4totsec); + secpfat = c2u2(boot.csecpfat); + secptrack = c2u2(boot.csecptrack); + heads = c2u2(boot.cheads); + + /* The `hidden sectors' are the sectors before the partition. + * The calculation here is probably wrong (I think the dos4hidd2 + * bytes are the msbs), but that doesn't matter, since the + * value isn't used anyway + */ + hiddensec = c2u2(boot.chiddensec); + if (hiddensec == 0) hiddensec = c2u2 (boot.dos4hidd2); + +#ifdef PC_UZIX_TARGET + /* Safety checking */ + if (boot_magic != 0xAA55) { + fprintf (stderr, "%s: magic != 0xAA55\n", cmnd); + ++errcount; + } +#endif + + /* Check sectors per track instead of inadequate media byte */ + if (secptrack < 15 && /* assume > 15 hard disk & wini OK */ +#ifdef SECT10 /* BIOS modified for 10 sec/track */ + secptrack != 10 && +#endif +#ifdef SECT8 /* BIOS modified for 8 sec/track */ + secptrack != 8 && +#endif + secptrack != 9) { + fprintf (stderr, "%s: %d sectors per track not supported\n", cmnd, secptrack); + ++errcount; + } + if (bytepers == 0) { + fprintf (stderr, "%s: bytes per sector == 0\n", cmnd); + ++errcount; + } + if (boot.secpclus == 0) { + fprintf (stderr, "%s: sectors per cluster == 0\n", cmnd); + ++errcount; + } + if (boot.fats != 2 && (dos_write || dos_del)) { + fprintf (stderr, "%s: fats != 2\n", cmnd); + ++errcount; + } + if (reservsec != 1) { + fprintf (stderr, "%s: reserved != 1\n", cmnd); + ++errcount; + } + if (errcount != 0) { + fprintf (stderr, "%s: Can't handle disk\n", cmnd); + exit(2); + } + + /* Calculate everything. */ + if (boot.secpclus == 0) boot.secpclus = 1; + total_clusters = + (totsec - boot.fats * secpfat - reservsec - + dirents * 32L / bytepers ) / boot.secpclus + 2; + /* first 2 entries in FAT aren't used */ + cluster_size = bytepers * boot.secpclus; + fat_size = (unsigned long) secpfat * (unsigned long) bytepers; + data_start = (long) bytepers + (long) boot.fats * fat_size + + (long) dirents *32L; + root_entries = dirents; + sub_entries = boot.secpclus * bytepers / 32; + if (total_clusters > 4096) fat_16 = 1; + + /* Further safety checking */ + if (cluster_size > MAX_CLUSTER_SIZE) { + fprintf (stderr, "%s: cluster size too big\n", cmnd); + ++errcount; + } +#ifndef CACHE_ROOT + if (dirents * DIR_SIZE > MAX_CLUSTER_SIZE) { + fprintf(stderr, "%s: root directory too big\n", cmnd); + ++errcount; + } +#endif + + disk_io(READ, FAT_START, &fat_info, 1); + disk_io(READ, FAT_START + fat_size, &fat_check, 1); + if (fat_check != fat_info) { + fprintf (stderr, "%s: Disk type in FAT copy differs from disk type in FAT original.\n", cmnd); + ++errcount; + } + if (errcount != 0) { + fprintf (stderr, "%s: Can't handle disk\n", cmnd); + exit(2); + } +} + +int main(argc, argv) +int argc; +register char *argv[]; +{ + register char *arg_ptr = slash(argv[0]); + DIRECTORY *entry; + short idx = 1; + char dev_nr = '0'; + + fdo = stdout; + cmnd = arg_ptr; /* needed for error messages */ + if (!strcmp(arg_ptr, "dosdir")) + dos_dir = TRUE; + else if (!strcmp(arg_ptr, "dosread")) + dos_read = TRUE; + else if (!strcmp(arg_ptr, "doswrite")) + dos_write = TRUE; + else if (!strcmp(arg_ptr, "dosdel")) + dos_del = TRUE; + else { + fprintf (stderr, "%s: Program should be named dosread, doswrite, dosdel or dosdir.\n", cmnd); + exit(1); + } + + if (argc == 1) usage(argv[0]); + + if (argv[1][0] == '-') { + for (arg_ptr = &argv[1][1]; *arg_ptr; arg_ptr++) { + if (*arg_ptr == 'l' && dos_dir) { + Lflag = TRUE; + } else if (*arg_ptr == 'r' && dos_dir) { + Rflag = TRUE; + } else if (*arg_ptr == 'a' && !dos_dir && !dos_del) { + assert ('\n' == 10); + assert ('\r' == 13); + Aflag = TRUE; + } else { + usage(argv[0]); + } + } + idx++; + } + if (idx == argc) usage(argv[0]); + + if (strlen(argv[idx]) > 1) { + if (*(argv[idx]+1) == ':') { + if ((dev_nr = toupper (*argv[idx])) < 'A' || dev_nr > 'Z') + usage(argv[0]); + dev_nr = dev_nr - 'A' + '0'; + device = drive2; + device[7] = dev_nr; + if (*(argv[idx]+2) == '\0') + idx++; + else + argv[idx] = (argv[idx] + 2); + } else { + device = argv[idx++]; + + /* If the device does not contain a / we assume that it + * is the name of a device in /dev. Instead of prepending + * /dev/ we try to chdir there. + */ + if (strchr(device, '/') == NULL && chdir("/dev") < 0) { + perror("/dev"); + exit(1); + } + dev_nr = device[strlen(device)-1]; + } + } else { + if ((dev_nr = toupper (*argv[idx++])) < 'A' || dev_nr > 'Z') + usage(argv[0]); + + device[DRIVE_NR] = dev_nr; + } + if ((disk = open(device, (dos_write || dos_del) ? O_RDWR : O_RDONLY)) < 0) { + fprintf (stderr, "%s: cannot open %s: %s\n", + cmnd, device, strerror (errno)); + exit(1); + } + determine(); + +#ifdef CACHE_ROOT + disk_io(READ, ROOTADDR, root, + root_entries > MAX_ROOT_ENTRIES ? + DIR_SIZE * MAX_ROOT_ENTRIES : + DIR_SIZE * root_entries); + if (root_entries > MAX_ROOT_ENTRIES) { + fprintf (stderr, "%s: root dir limited to %d files\n", cmnd, MAX_ROOT_ENTRIES); + } +#endif + + if (dos_read || dos_write) { + unixfile = argv[idx+1]; + if (unixfile == NIL_PTR) { + fdo = stdout; + if (dos_write) fdo = stdin; + } else { + if ((fdo = fopen(unixfile, dos_read ? "wb" : "rb")) == NULL) { + perror(argv[0]); + exit(1); + } + } + } + + if (dos_dir && Lflag) { + entry = label(); + fprintf (fdo, "Volume in drive %c ", dev_nr - '0' + 'A'); + if (entry == NIL_DIR) + fprintf(fdo, "has no label.\n\n"); + else + fprintf (fdo, "is %.11s\n\n", entry->d_name); + } + if (argv[idx] == NIL_PTR) { + if (!dos_dir) usage(argv[0]); + if (Lflag) fprintf (fdo, "Root directory:\n"); + list_dir(root, root_entries, FALSE); + if (Lflag) free_blocks(); + fflush (fdo); + FABORT(0); + } + for (arg_ptr = argv[idx]; *arg_ptr; arg_ptr++) + if (*arg_ptr == '\\') *arg_ptr = '/'; + else *arg_ptr = toupper (*arg_ptr); + if (*--arg_ptr == '/') *arg_ptr = '\0'; /* skip trailing '/' */ + + add_path(argv[idx], FALSE); + add_path("/", FALSE); + + if (dos_dir && Lflag) fprintf (fdo, "Directory %s:\n", path); + + entry = find_entry(root, root_entries, argv[idx]); + + if (dos_dir) { + list_dir(entry, sub_entries, FALSE); + if (Lflag) free_blocks(); + } else if (dos_read) + extract(entry); + else if (dos_del) + delete(entry); + else { + if (entry != NIL_DIR) { + fflush (fdo); + if (is_dir(entry)) + fprintf (stderr, "%s: %s is a directory.\n", cmnd, path); + else + fprintf (stderr, "%s: %s already exists.\n", cmnd, argv[idx]); + exit(1); + } + add_path(NIL_PTR, TRUE); + + if (*path) make_file(find_entry(root, root_entries, path), + sub_entries, slash(argv[idx])); + else + make_file(root, root_entries, argv[idx]); + } + + (void) close(disk); + fflush (fdo); + if (fdo != stdout) fclose(fdo); + return(0); +} + + +/* General directory search routine. + * + * dir: + * Points to one or more directory entries + * if dir == root, when ROOT_CACHE is defined, dir points to the + * entire root directory; if ROOT_CACHE is not defined, root dir + * will be read from disk when needed. If dir != root, it points + * to a single directory entry describing the directory to be + * searched. + * + * entries: + * number of entries + * + * function: + * FIND ... find pathname relative to directory dir. + * LABEL ... find first label entry in dir. + * ENTRY ... create a new empty entry. + * FALSE ... list directory + * + * pathname: + * name of the file to be found or directory to be listed. + * must be in upper case, pathname components must be + * separated by slashes, but can be longer than than + * 8+3 characters (The rest is ignored). + */ +DIRECTORY *directory(dir, entries, function, pathname) +DIRECTORY *dir; +int entries; +int function; +register char *pathname; +{ + register DIRECTORY *dir_ptr = dir; + DIRECTORY *mem = NIL_DIR; + unsigned short cl_no = dir->d_cluster; + unsigned short type, last = 0; + char file_name[14]; + char dir_bkp[DIR_SIZE]; + char *name; + int i = 0; + + if (dir != NULL) { + memcpy((char *)dir_bkp, (char *)dir, DIR_SIZE); + dir = dir_bkp; + } + if (function == FIND) { + while (*pathname == '/') *pathname++; + while (*pathname != '/' && *pathname != '.' && *pathname && + i < 8) { + file_name[i++] = *pathname++; + } + if (*pathname == '.') { + int j = 0; + file_name[i++] = *pathname++; + while (*pathname != '/' && *pathname != '.' && *pathname && + j++ < 3) { + file_name[i++] = *pathname++; + } + } + while (*pathname != '/' && *pathname) pathname++; + file_name[i] = '\0'; + } + do { + if (dir != root) { + mem = dir_ptr = read_cluster(cl_no); + last = cl_no; + cl_no = next_cluster(cl_no); + } +#ifndef CACHE_ROOT + else { + disk_io(READ, ROOTADDR, buffer, root_entries * DIR_SIZE); + dir_ptr = buffer; + cl_no = dir_ptr->d_cluster; + } +#endif + for (i = 0; i < entries; i++, dir_ptr++) { + type = dir_ptr->d_name[0] & 0x0FF; + if (!mem) + mark = ROOTADDR + (long) i *(long) DIR_SIZE; + else + mark = clus_add(last) + (long) i *(long) DIR_SIZE; + if (function == ENTRY) { + if (type == NOT_USED || type == ERASED) return dir_ptr; + continue; + } + if (type == NOT_USED) break; + if (dir_ptr->d_attribute & 0x08) { + if (function == LABEL) return dir_ptr; + continue; + } + if (type == DIR || type == ERASED || function == LABEL) + continue; + type = is_dir(dir_ptr); + name = make_name(dir_ptr, + (function == FIND) ? FALSE : type); + if (function == FIND) { + if (strcmp(file_name, name) != 0) continue; + if (!type) { + if (dos_dir || *pathname) { + fflush (stdout); + fprintf (stderr, "%s: Not a directory: %s\n", cmnd, file_name); + exit(1); + } + } else if (*pathname == '\0' && dos_read) { + fflush (stdout); + fprintf (stderr, "%s: %s is a directory.\n", cmnd, path); + exit(1); + } + if (*pathname) { + dir_ptr = find_entry(dir_ptr, + sub_entries, pathname + 1); + } + if (mem) { + if (dir_ptr) { + memcpy((char *)&save_entry, (char *)dir_ptr, DIR_SIZE); + dir_ptr = &save_entry; + } + } + return dir_ptr; + } else { + if (function == FALSE) { + show(dir_ptr, name); + } else if (type) { /* Recursive */ + printf ( "Directory %s%s:\n", path, name); + add_path(name, FALSE); + list_dir(dir_ptr, sub_entries, FALSE); + add_path(NIL_PTR, FALSE); +#ifndef CACHE_ROOT + /* Re-read directory from disk */ + mem = dir_ptr = read_cluster(cl_no); +#endif + } + } + } + } while (cl_no != LAST_CLUSTER && mem); + + switch (function) { + case FIND: + if (dos_write && *pathname == '\0') return NIL_DIR; + fflush (stdout); + fprintf (stderr, "%s: Cannot find `%s'.\n", cmnd, file_name); + exit(1); + case LABEL: + return NIL_DIR; + case ENTRY: + if (!mem) { + fflush (stdout); + fprintf (stderr, "%s: No entries left in root directory.\n", cmnd); + exit(1); + } + cl_no = free_cluster(TRUE); + link_fat(last, cl_no); + link_fat(cl_no, LAST_CLUSTER); + memset(buffer, 0, cluster_size); + disk_io(WRITE, clus_add(cl_no), buffer, cluster_size); + + return new_entry(dir, entries); + case FALSE: + if (Rflag) { + printf ("\n"); + list_dir(dir, entries, TRUE); + } + } + return NULL; +} + +void delete(entry) +register DIRECTORY *entry; +{ + register unsigned short cl_no = entry->d_cluster; + + entry->d_name[0] = 0xe5; + disk_io(WRITE, mark, entry, DIR_SIZE); + while (cl_no != LAST_CLUSTER) cl_no = clear_cluster(cl_no); + if (fat_dirty) flush_fat (); +} + +void extract(entry) +register DIRECTORY *entry; +{ + register unsigned short cl_no = entry->d_cluster; + int rest, i; + long size = entry->d_size; + + if (size == 0) /* Empty file */ + return; + + do { + disk_io(READ, clus_add(cl_no), buffer, cluster_size); + rest = (size > (long) cluster_size) ? cluster_size : (short)size; + + if (Aflag) { + for (i = 0; i < rest; i ++) { + if (buffer [i] != '\r') fputc (buffer [i], fdo); + } + if (ferror (stdout)) { + fprintf (stderr, "%s: cannot write file: %s\n", + cmnd, strerror (errno)); + FABORT(1); + } + } else { + if (fwrite (buffer, 1, rest, fdo) != rest) { + fprintf (stderr, "%s: cannot write file: %s\n", + cmnd, strerror (errno)); + FABORT(1); + } + } + size -= (long) rest; + cl_no = next_cluster(cl_no); + if (cl_no == BAD16) { + fflush (stdout); + fprintf (stderr, "%s: reserved cluster value %x encountered.\n", + cmnd, cl_no); + FABORT(1); + } + } while (size && cl_no != LAST_CLUSTER); + + if (cl_no != LAST_CLUSTER) + fprintf (stderr, "%s: Too many clusters allocated for file.\n", cmnd); + else if (size != 0) + fprintf (stderr, "%s: Premature EOF: %ld bytes left.\n", cmnd, + entry->d_size); +} + + +/* Minimum of two long values + */ +long lmin (a, b) +long a, b; +{ + if (a < b) return a; + else return b; +} + + +void make_file(dir_ptr, entries, name) +DIRECTORY *dir_ptr; +int entries; +char *name; +{ + register DIRECTORY *entry = new_entry(dir_ptr, entries); + register char *ptr; + unsigned short cl_no = 0; + int i, r; + long size = 0L; + unsigned short first_cluster, last_cluster; + long chunk; + char dir_bkp[DIR_SIZE]; + + memcpy((char *)dir_bkp, (char *)entry, DIR_SIZE); + entry = (DIRECTORY *)dir_bkp; + memset (&entry->d_name[0], ' ', 11); /* clear entry */ + for (i = 0, ptr = name; i < 8 && *ptr != '.' && *ptr; i++) + entry->d_name[i] = *ptr++; + while (*ptr != '.' && *ptr) ptr++; + if (*ptr == '.') ptr++; + for (i = 0; i < 3 && *ptr != '.' && *ptr; i++) entry->d_ext[i] = *ptr++; + + for (i = 0; i < 10; i++) entry->d_reserved[i] = '\0'; + entry->d_attribute = '\0'; + + entry->d_cluster = 0; + + while (free_range (&first_cluster, &last_cluster)) { + do { + unsigned short nr_clus; + + chunk = lmin ((long) (last_cluster - first_cluster + 1) * + cluster_size, + (long) MAX_CLUSTER_SIZE); + r = fill(buffer, chunk); + if (r == 0) goto done; + nr_clus = (r + cluster_size - 1) / cluster_size; + disk_io(WRITE, clus_add(first_cluster), buffer, r); + + for (i = 0; i < nr_clus; i ++) { + if (entry->d_cluster == 0) + cl_no = entry->d_cluster = first_cluster; + else { + link_fat(cl_no, first_cluster); + cl_no = first_cluster; + } + first_cluster ++; + } + + size += r; + } while (first_cluster <= last_cluster); + } + fprintf (stderr, "%s: disk full. File truncated\n", cmnd); +done: + if (entry->d_cluster != 0) link_fat(cl_no, LAST_CLUSTER); + entry->d_size = size; + fill_date(entry); + disk_io(WRITE, mark, entry, DIR_SIZE); + + if (fat_dirty) flush_fat (); +} + + +#define SEC_MIN 60L +#define SEC_HOUR (60L * SEC_MIN) +#define SEC_DAY (24L * SEC_HOUR) +#define SEC_YEAR (365L * SEC_DAY) +#define SEC_LYEAR (366L * SEC_DAY) + +unsigned short mon_len[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +void fill_date(entry) +DIRECTORY *entry; +{ + time_t atime; + unsigned long cur_time; + unsigned short year = 0, month = 1, day, hour, minutes, seconds; + int i; + long tmp; + + time(&atime); + cur_time = convtime(&atime) - DOS_TIME; + if (cur_time < 0) /* Date not set on booting ... */ + cur_time = 0; + for (;;) { + tmp = (year % 4 == 0) ? SEC_LYEAR : SEC_YEAR; + if (cur_time < tmp) break; + cur_time -= tmp; + year++; + } + day = (unsigned short) (cur_time / SEC_DAY); + cur_time -= (long) day *SEC_DAY; + + hour = (unsigned short) (cur_time / SEC_HOUR); + cur_time -= (long) hour *SEC_HOUR; + + minutes = (unsigned short) (cur_time / SEC_MIN); + cur_time -= (long) minutes *SEC_MIN; + + seconds = (unsigned short) cur_time; + + mon_len[1] = (year % 4 == 0) ? 29 : 28; + i = 0; + while (day >= mon_len[i]) { + month++; + day -= mon_len[i++]; + } + day++; + + entry->d_date = (year << 9) | (month << 5) | day; + entry->d_time = (hour << 11) | (minutes << 5) | seconds; +} + +char *make_name(dir_ptr, dir_fl) +register DIRECTORY *dir_ptr; +short dir_fl; +{ + static char name_buf[14]; + register char *ptr = name_buf; + short i; + + for (i = 0; i < 8; i++) *ptr++ = dir_ptr->d_name[i]; + + while (*--ptr == ' '); + assert (ptr >= name_buf); + + ptr++; + if (dir_ptr->d_ext[0] != ' ') { + *ptr++ = '.'; + for (i = 0; i < 3; i++) *ptr++ = dir_ptr->d_ext[i]; + while (*--ptr == ' '); + ptr++; + } + if (dir_fl) *ptr++ = '/'; + *ptr = '\0'; + + return name_buf; +} + + +int fill(buff, size) +register char *buff; +size_t size; +{ + static BOOL nl_mark = FALSE; + char *last = &buff[size]; + char *begin = buff; + register int c; + + while (buff < last) { + if (nl_mark) { + *buff ++ = '\n'; + nl_mark = FALSE; + } else { + c = fgetc(fdo); + if (c == EOF) break; + if (Aflag && c == '\n') { + *buff ++ = '\r'; + nl_mark = TRUE; + } else { + *buff++ = c; + } + } + } + + return (buff - begin); +} + +#define HOUR 0xF800 /* Upper 5 bits */ +#define MIN 0x07E0 /* Middle 6 bits */ +#define YEAR 0xFE00 /* Upper 7 bits */ +#define MONTH 0x01E0 /* Mid 4 bits */ +#define DAY 0x01F /* Lowest 5 bits */ + +char *month[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +void xmodes(mode) +int mode; +{ + printf ( "\t%c%c%c%c%c", (mode & SUB_DIR) ? 'd' : '-', + (mode & 02) ? 'h' : '-', (mode & 04) ? 's' : '-', + (mode & 01) ? '-' : 'w', (mode & 0x20) ? 'a' : '-'); +} + +void show(dir_ptr, name) +DIRECTORY *dir_ptr; +char *name; +{ + register unsigned short e_date = dir_ptr->d_date; + register unsigned short e_time = dir_ptr->d_time; + unsigned short next; + char bname[20]; + short i = 0; + + while (*name && *name != '/') bname[i++] = *name++; + bname[i] = '\0'; + if (!Lflag) { + fprintf (fdo, "%s\n", bname); + return; + } + xmodes( (int) dir_ptr->d_attribute); + fprintf (fdo, "\t%s%s", bname, strlen(bname) < 8 ? "\t\t" : "\t"); + i = 1; + if (is_dir(dir_ptr)) { + next = dir_ptr->d_cluster; + while ((next = next_cluster(next)) != LAST_CLUSTER) i++; + fprintf (fdo, "%8ld", (long) i * (long) cluster_size); + } else + fprintf (fdo, "%8ld", dir_ptr->d_size); + fprintf (fdo, " %02d:%02d %2d %s %d\n", ((e_time & HOUR) >> 11), + ((e_time & MIN) >> 5), (e_date & DAY), + month[((e_date & MONTH) >> 5) - 1], ((e_date & YEAR) >> 9) + 1980); +} + +void free_blocks() +{ + register unsigned short cl_no; + long nr_free = 0; + long nr_bad = 0; + + for (cl_no = 2; cl_no < total_clusters; cl_no++) { + switch (next_cluster(cl_no)) { + case FREE: nr_free++; break; + case BAD16: nr_bad++; break; + } + } + + fprintf (fdo, "Free space: %ld bytes.\n", nr_free * (long) cluster_size); + if (nr_bad != 0) + fprintf (fdo, "Bad sectors: %ld bytes.\n", nr_bad * (long) cluster_size); +} + + +DIRECTORY *read_cluster(cluster) +register unsigned int cluster; +{ + disk_io(READ, clus_add(cluster), buffer, cluster_size); + + return (DIRECTORY *)buffer; +} + +static unsigned short cl_index = 2; + +/* find a range of consecutive free clusters. Return TRUE if found + * and return the first and last cluster in the |*first| and |*last|. + * If no free clusters are left, return FALSE. + * + * Warning: Assumes that all of the range is used before the next call + * to free_range or free_cluster. + */ +BOOL free_range (first, last) +unsigned short *first, *last; +{ + while (cl_index < total_clusters && next_cluster(cl_index) != FREE) + cl_index++; + if (cl_index >= total_clusters) return FALSE; + *first = cl_index; + while (cl_index < total_clusters && next_cluster(cl_index) == FREE) + cl_index++; + *last = cl_index - 1; + return TRUE; +} + + +/* find a free cluster. + * Return the number of the free cluster or a number > |total_clusters| + * if none is found. + * If |leave_fl| is TRUE, the the program will be terminated if + * no free cluster can be found + * + * Warning: Assumes that the cluster is used before the next call + * to free_range or free_cluster. + */ +unsigned short free_cluster(leave_fl) +BOOL leave_fl; +{ + while (cl_index < total_clusters && next_cluster(cl_index) != FREE) + cl_index++; + + if (leave_fl && cl_index >= total_clusters) { + fprintf (stderr, "%s: Diskette full. File not added.\n", cmnd); + exit(1); + } + return cl_index++; +} + +/* read a portion of the fat containing |cl_no| into the cache + */ +void read_fat (cl_no) + unsigned int cl_no; +{ + + if (!cooked_fat) { + /* Read the fat for the first time. We have to allocate all the + * buffers + */ + if (fat_16) { + /* FAT consists of little endian shorts. Easy to convert + */ + if ((cooked_fat = malloc (fat_size)) == NULL) { + /* Oops, FAT doesn't fit into memory, just read + * a chunk + */ + if ((cooked_fat = malloc (COOKED_SIZE)) == NULL) { + fprintf (stderr, "%s: not enough memory for FAT cache.\n", + cmnd); + exit (1); + } + cache_size = COOKED_SIZE / 2; + } else { + cache_size = fat_size / 2; + } + } else { + /* 12 bit FAT. Difficult encoding, but small. Keep + * both raw FAT and cooked version in memory if possible. + */ + cooked_fat = malloc (total_clusters * sizeof (short)); + raw_fat = malloc (fat_size); + if (cooked_fat == NULL || raw_fat == NULL) { + if (cooked_fat != NULL) free(cooked_fat); + if (raw_fat != NULL) free(raw_fat); + /* Oops, FAT doesn't fit into memory, just read + * a chunk + */ + cooked_fat = malloc (COOKED_SIZE); + raw_fat = malloc (COOKED_SIZE/sizeof (short)/2*3); + if (cooked_fat == NULL || raw_fat == NULL) { + fprintf (stderr, "%s: not enough memory for FAT cache.\n", + cmnd); + exit (1); + } + cache_size = COOKED_SIZE / sizeof(short); + rawfat_size = COOKED_SIZE / sizeof(short)/2*3; + } else { + cache_size = total_clusters; + rawfat_size = fat_size; + } + } + } + fat_low = cl_no; /* / cache_size * cache_size; ??? */ + + /* for FAT 12, round fat_low to a multiple of 2, so, when reading FAT from + * disk, we start at this cluster or previous one */ + if (!fat_16) if (fat_low & 1 != 0) fat_low--; + + fat_high = fat_low + cache_size - 1; + + if (!fat_16) { + unsigned short *cp; + unsigned char *rp; + unsigned short i; + + disk_io (READ, FAT_START + fat_low * 3 / 2, raw_fat, rawfat_size); + for (rp = raw_fat, cp = cooked_fat, i = 0; + i < cache_size; + rp += 3, i += 2) { + *cp = *rp + ((*(rp + 1) & 0x0f) << 8); + if (*cp == BAD) *cp = BAD16; + else if (*cp == LAST_CLUSTER12) *cp = LAST_CLUSTER; + cp ++; + *cp = ((*(rp + 1) & 0xf0) >> 4) + (*(rp + 2) << 4); + if (*cp == BAD) *cp = BAD16; + else if (*cp == LAST_CLUSTER12) *cp = LAST_CLUSTER; + cp ++; + } + } else { + assert (sizeof (short) == 2); + assert (CHAR_BIT == 8); /* just in case */ + + disk_io (READ, FAT_START + fat_low * 2, (void *)cooked_fat, cache_size * 2); + if (big_endian) { + unsigned short *cp; + unsigned char *rp; + unsigned short i; + + for (i = 0, rp = (unsigned char *)cooked_fat /* sic */, cp = cooked_fat; + i < cache_size; + rp += 2, cp ++, i ++) { + *cp = c2u2 (rp); + } + } + } +} + +/* flush the fat cache out to disk + */ +void flush_fat () +{ + if (fat_16) { + if (big_endian) { + unsigned short *cp; + unsigned char *rp; + unsigned short i; + + for (i = 0, rp = (unsigned char *)cooked_fat /* sic */, cp = cooked_fat; + i < cache_size; + rp += 2, cp ++, i ++) { + *rp = *cp; + *(rp + 1) = *cp >> 8; + } + } + disk_io (WRITE, FAT_START + fat_low * 2, (void *)cooked_fat, cache_size * 2); + disk_io (WRITE, FAT_START + fat_size + fat_low * 2, (void *)cooked_fat, cache_size * 2); + } else { + unsigned short *cp; + unsigned char *rp; + unsigned short i; + + for (rp = raw_fat, cp = cooked_fat, i = 0; + i < cache_size; + rp += 3, cp += 2, i += 2) { + *rp = *cp; + *(rp + 1) = ((*cp & 0xf00) >> 8) | + ((*(cp + 1) & 0x00f) << 4); + *(rp + 2) = ((*(cp + 1) & 0xff0) >> 4); + } + disk_io (WRITE, FAT_START + fat_low * 3 / 2, raw_fat, rawfat_size); + disk_io (WRITE, FAT_START + fat_size + fat_low * 3 / 2, raw_fat, rawfat_size); + } +} + +/* make cl_2 the successor of cl_1 + */ +void link_fat(cl_1, cl_2) +unsigned int cl_1; +unsigned int cl_2; +{ + if (cl_1 < fat_low || cl_1 > fat_high) { + if (fat_dirty) flush_fat (); + read_fat (cl_1); + } + cooked_fat [cl_1 - fat_low] = cl_2; + fat_dirty = TRUE; +} + + +unsigned short next_cluster(cl_no) +register unsigned int cl_no; +{ + if (cl_no < fat_low || cl_no > fat_high) { + if (fat_dirty) flush_fat (); + read_fat (cl_no); + } + return cooked_fat [cl_no - fat_low]; +} + +/* free cluster cl_no in FAT and return its sucessor */ +unsigned short clear_cluster(cl_no) +register unsigned int cl_no; +{ + unsigned short old; + + if (cl_no < fat_low || cl_no > fat_high) { + if (fat_dirty) flush_fat (); + read_fat (cl_no); + } + old = cooked_fat[cl_no - fat_low]; + cooked_fat[cl_no - fat_low] = 0; + fat_dirty = TRUE; + return old; +} + +char *slash(str) +register char *str; +{ + register char *result = str; + + while (*str) + if (*str++ == '/') result = str; + + return result; +} + +void add_path(file, slash_fl) +char *file; +BOOL slash_fl; +{ + register char *ptr = path; + + while (*ptr) ptr++; + + if (file == NIL_PTR) { + if (ptr != path) ptr--; + if (ptr != path) do { + ptr--; + } while (*ptr != '/' && ptr != path); + if (ptr != path && !slash_fl) *ptr++ = '/'; + *ptr = '\0'; + } else + strcpy (ptr, file); +} + + +void disk_io(op, seek, address, bytes) +register BOOL op; +unsigned long seek; +void *address; +register unsigned bytes; +{ + unsigned int r; + + if (lseek(disk, seek, SEEK_SET) < 0L) { + fflush (stdout); + fprintf (stderr, "%s: Bad lseek: %s\n", cmnd, strerror (errno)); + exit(1); + } + if (op == READ) + r = read(disk, (char *) address, bytes); + else { + r = write(disk, (char *) address, bytes); + }; + + if (r != bytes) { + fprintf (stderr, "%s: %s error: %s\n", op == READ ? "read" : "write", cmnd, strerror (errno)); + exit (1); + } +} + +char dosread_c_rcs_id [] = + "$Id: dosread.c,v 2.0 2001/03/11 14:30:43 adrcunha Rel $"; + +/* $Log: dosread.c,v $ + * Revision 2.0 2001/03/11 14:30:43 adrcunha@dcc.unicamp.br + * Fixed some bugs, added FAT12 cache, decreased memory usage, changed + * drive number to letter on dir header, introduced some sanity check for + * memory, added compilation directive CACHE_ROOT (with this, root dir is + * loaded on memory at the beginning; without this, root dir is allways + * read from disk when needed - it's slow, but saves memory). + * + * Revision 1.9 1999/11/28 14:32:37 adrcunha@dcc.unicamp.br + * Dosread and doswrite can read/write to/from a file, not only stdin/stdout. + * Added one more personality to the schizophrenic dosread: dosdel + * Drives can be referenced as A:, B:, etc for /dev/fd0, /dev/fd1, etc + * Dosfiles can be referenced after drive if drive is 'X:' (e.g., A:FOO.BAR) + * + * Revision 1.8 1994/05/14 21:53:08 hjp + * filenames with more than 3 characters and extension work again. + * removed debugging stuff and b_copy. + * + * Revision 1.7 1994/04/09 03:09:01 hjp + * (posted to comp.os.minix) + * merged branch 1.5.387 with stem. + * changed treatment of drive parameter + * + * Revision 1.5.387.9 1994/04/09 02:07:51 hjp + * Disk full no longer produces lost clusters but a truncated file. + * Truncated file names to 8+3 before comparisons to avoid duplicate + * files and filenames containing dots in the extension. + * Replaced sbrk and brk by malloc and free (mixing brk and malloc causes + * heap corruption which sometimes lead to core dumps. It may also have + * been the cause of data corruption Kees reported). + * Made global variables static and removed some unused ones. + * Error messages now contain program name. + * + * Revision 1.5.387.8 1993/11/13 00:38:45 hjp + * Posted to comp.os.minix and included in Minix-386vm 1.6.25.1. + * Speed optimizations for 1.44 MB disks. + * Replaced lowlevel I/O by stdio. + * Simplified -a: Now only removes resp. adds CRs + * Cleaned up. + * + * Revision 1.5.387.1 1993/01/15 19:32:29 ast + * Released with 1.6.24b + */ diff --git a/src/simple/dtree.c b/src/simple/dtree.c new file mode 100755 index 00000000..7ed94b4d --- /dev/null +++ b/src/simple/dtree.c @@ -0,0 +1,652 @@ +/* + * DTREE - Print the tree structure of a directory + * 4/7/83 name was changed from TREE to DTREE + * 9/7/83 mods for 4.1c and 4.2 dirctory structure added + * + * Dave Borman, Digital Unix Engineering Group + * decvax!borman + * Originally written at St. Olaf College, Northfield MN. + * Copyright (c) 1983 by Dave Borman + * All rights reserved + * This program may not be sold, but may be distributed + * provided this header is included. + * + * Compile: PDP V7 w/split i&d cc -O dtree.c -i -n -o dtree + * VAX 4.1bsd cc -O dtree.c -n -o dtree + * VAX 4.2bsd cc -O -DNEWDIR -DLINK dtree.c -n -o dtree + * + * Usage: dtree -[adfglnpsvx] [-b filenamesize] [-c linelength] [top] + * Flags: -a) include non-directory entries in listing + * -d) sort tree with directories at the top + * -f) sort tree with files at the top + * -g) same as l, but use group name instead of user name + * -l) print stats with each listing + * if both g & l flags are given, both owner and + * group will be printed + * -n) do not sort the tree + * -p) include files starting with a '.' (except "." & "..") + * -s) use shorter stats. Implies -l if -g isn't given. + * -v) variable length columns off + * -x) do not cross mounted file systems. + * -b length) big directory names (define the max. name length) + * -c length) set max column length to "length" (if col. + * length > file name length, this implies -b also) + */ + + /* Modified by Ed Arnold CSU-CS (csu-cs!arnold) 3-5-84 + * + * Allows symbolic links to both directories and individual files. + * With a '-l' or '-al' option, links are denoted with a 'l' in front of + * file or directory permissions. In all other instances both links to + * directories and files are represented just as files are. Contents of + * linked directories are not printed due to the possibility of + * recursively linked directories. + * + * Big directory name option added by: + * Mike Vevea CSU-CS (csu-cs!vevea) 3-22-84 + * Toggle sense of -v (running 4.2), and eliminate some extraneous + * print info Mike Meyer Energy Analysts (mwm@ea) 4/17/84 + * Fix the exit status to correctly indicate what happened. + * Mike Meyer Energy Analysts (mwm@ea) 4/23/84 + * + * 12/07/92 adapted for UZI280 by Stefan Nitschke + * - sbrk() instead of malloc() + * 05/10/99 adapted for UZX by Adriano Cunha + * - malloc() check / downsizing / readdir + */ + + +#define STATS /* comment out to remove stats, giving more core space */ + /* and thus the ability to tree larger tree structures */ + /* on PDP 11/70s */ + +#define NEWDIR /* directory structure ala Berkeley 4.1c or 4.2 */ + + +#define LINK /* allows links to be processed in Berkeley 4.2 version + NEWDIR must be defined as well as LINK */ + +static char Sccsid[]="@(#)dtree.c 2.3 2/14/84"; + +#ifdef LINK +static char Rcsid[] ="$Header: /mnt/ntape/RCS/dtree.c,v 1.2 84/04/23 10:33:41 root Exp $"; +#endif /* LINK Nick */ + +#include +#include +#include +#include +#include +#include +#ifdef STATS +# include +# include +#endif /* STATS Nick */ +#ifdef NEWDIR +# include +#else +# include +#endif /* NEWDIR Nick */ + +#ifdef MSX_UZIX_TARGET +#define DEFDIRSIZ 64 +#else +#define DEFDIRSIZ 255 +#endif + +#define DEFCOLWID 14 + +#ifndef MAXNAMLEN +# define MAXNAMLEN DEFCOLWID +#endif + /* + * TWIDDLE is a fudge factor. It should be declared so that + * sizeof(struct Entry) is on a nice boundry. + */ +#define TWIDDLE 1 + +#define addr(b,o) ((struct Entry *)((unsigned int)(b)+(o)*(sizeof(struct Entry)+Length))) +#define SIZEOFentry (sizeof(struct Entry)+Length) + +#define DEPTH 10 /* maximum depth that dtree will go */ + +#ifdef MSX_UZIX_TARGET +#define MAX 40 +#else +#define MAX 160 /* initial # of elements for list of files */ +#endif + +#define PWD "/bin/pwd" /* program to get name of current dir */ +#define DATE "/bin/date" /* program to print current date */ + +#define FFIRST 2 /* sort files first */ +#define DFIRST 1 /* sort directories first */ +#define FAIL -1 /* failure return status of sys calls */ +#define GREATER 1 /* return value of strcmp if arg1 > arg2 */ +#define LESSTHAN -1 /* return value of strcmp if arg1 < arg2 */ +#define SAME 0 /* return value of strcmp if arg1 == arg2 */ + + int Index = 0; /* current element of list[] */ + int Length = DEFDIRSIZ; /* max length of a dir. name */ + int CLength = DEFDIRSIZ; /* max length of a column */ + int All = 0; /* all != 0; list non-directory entries */ + int File_dir = 0; /* flag for how to sort */ + int Sort = 1; /* flag to cause sorting of entries */ + int Point = 1; /* skip point files if set */ + int Maxes[DEPTH]; /* array keeps track of max length in columns */ + int Level = 0; /* counter for how deep we are */ + int Device; /* device that we are starting tree on */ + int Xdev = 1; /* set to allow crossing of devices */ + int Varspaces = 1; /* set to allow compaction of column width */ +#ifdef STATS + int Gflag = 0; /* set for group stats instead of owner */ + int Longflg = 0; /* set for long listing */ + int Compact = 0; /* set for shortened long listing */ +#endif /* STATS Nick */ + struct stat Status; +#ifdef LINK + struct stat Lstat; /* stat of link, if there is one */ +#endif /* LINK Nick */ + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(int stln, (char *st)); +_PROTOTYPE(void pt_tree, ()); +_PROTOTYPE(int t_search, (char *dir, struct Entry *addrs)); +_PROTOTYPE(int compar, (struct Entry *a, struct Entry *b)); + +struct Entry { + int next; /* index to next element in list */ + /* could be a ptr, but realloc() */ + /* might screw us then */ +#ifdef STATS + off_t e_size; /* size in blocks */ + short e_mode; /* file mode */ + short e_uid; /* uid of owner */ + short e_gid; /* gid of owner */ +#endif /* STATS Nick */ + short dir; /* Entry is a directory */ + short last; /* last Entry in the dir. */ + short dev; /* set if same device as top */ + short end; /* index of last subdir Entry*/ + char e_name[TWIDDLE]; /* name from directory Entry */ + /* it will actually be larger */ +} *List, *SaveList; + +unsigned int Size; /* how big of space we've malloced */ + +char *Spaces; /* used for output */ +char Buf1[BUFSIZ]; /* buffers for stdio stuff. We don't want */ +/*char Buf2[BUFSIZ]; /* anyone calling malloc, because then */ +/*char Buf3[BUFSIZ]; /* realloc() will have to move the whole list */ + +int dir = 1; /* Entry is a directory */ +int last = 1; /* last Entry in the dir. */ +int dev = 1; /* set if same device as top */ +int end = 13; /* index of last subdir Entry*/ + + +main(argc, argv) +char **argv; +int argc; +{ + register int i, j = 0; + int flag = 0; /* used to jump over 'c' argument */ + char top[128]; /* array for treetop name */ + char home[128]; /* starting dir for multiple trees */ + char *ptr; + + + setbuf(stdout, Buf1); + + for (j=1; j 1) j += flag-1; + flag = 0; + continue; + } + if (argv[j][0] == '-') { + for (i = 1; i < strlen(argv[j]); i++) { + switch (argv[j][i]) { + case 'a': + All = 1; + break; + case 'b': + Length = atoi(argv[j+1+flag]); + if (Length > MAXNAMLEN) + Length = MAXNAMLEN; + else if (Length < 1) + Length = DEFCOLWID; + flag += 1; + break; + case 'c': + CLength = atoi(argv[j+1+flag]); + if (CLength > MAXNAMLEN) + CLength = MAXNAMLEN; + else if (CLength < 1) + CLength = DEFCOLWID; + if (Length < CLength) Length = CLength; + flag += 1; + break; + case 'd': + File_dir = DFIRST; + break; + case 'f': + File_dir = FFIRST; + break; + case 'n': + Sort = 0; + break; + case 'p': + Point = 0; + break; + case 'v': + Varspaces = 0; + break; + case 'x': + Xdev = 0; + break; +#ifdef STATS + case 'g': + Gflag = 1; + break; + case 'l': + Longflg = 1; + break; + case 's': + Compact = 1; + break; +#endif /* STATS Nick */ + default: + fprintf(stderr, + "Bad flag: %c\n", argv[j][i]); + fprintf(stderr, +#ifdef STATS + "usage: dtree -[adfglnpsvx] [-b filenamesize] [-c linelength] [directory ... ]\n"); +#else /* STATS Nick */ + "usage: dtree -[adfnpvx] [-b filenamesize] [-c linelength] [directory ... ]\n"); +#endif /* STATS Nick */ + exit(FAIL); + } + } + } else + break; + } + + /* Establish where we are (our home base...) */ + getcwd(home,128); + + + if ((Spaces = malloc(Length+2)) == NULL) { + fprintf(stderr, "dtree: out of memory (%d bytes)\n", Length+2); + exit(1); + } + for(i = 0; i < Length + 1; i++) + Spaces[i] = ' '; + Spaces[i] = '\0'; + + /* Get initial Storage space */ + Size = SIZEOFentry * MAX; + + if ((SaveList = (struct Entry *)malloc(Size)) == NULL) { + fprintf(stderr, "dtree: out of memory (%u bytes)\n", Size); + exit(1); + } +/* + SaveList = (struct Entry *)sbrk(Size); +*/ + /* adjust for no specified directory */ + if (j == argc) + argv[--j] = ".\0"; + + /* walk down the rest of the args, treeing them one at at time */ + for (; j < argc; j++) { + if (chdir(home) == -1) { + fprintf(stderr, "Can't chdir back to %s\n", home); + exit(1); + } + sprintf(top, "%s", argv[j]); + + if (chdir(top) == FAIL) + { + fprintf(stderr, "Can't chdir to %s\n", top); + continue; + } + else + { + getcwd(top,128); + ptr = top; +/* while (*ptr && (*ptr != '\n')) + ptr++; + *ptr = '\0'; + pclose(istr); +*/ + } + + List = SaveList; Index = 0; + ptr = rindex(top, '/'); + + if (!ptr || *++ptr == '\0') + sprintf(addr(List,Index)->e_name, "%s", top); + else + sprintf(addr(List,Index)->e_name, "%s", ptr); + + if(stat(top, &Status) == FAIL) { + fprintf(stderr, "Can't stat %s\n", top); + continue; + } + Device = Status.st_dev; + addr(List,0)->dir = 1; + addr(List,0)->last = 1; + addr(List,0)->next = 1; + Index = 1; + for (i = 1; i < DEPTH; i++) + Maxes[i] = 0; + Maxes[0] = stln(addr(List,0)->e_name); + Level = 1; + + /* search the tree */ + addr(List,0)->end = t_search(top, addr(List,0)); + + if (Index == 1) /* empty tree */ + addr(List,0)->next = 0; + + if (All) + printf("\nDirectory structure and contents of %s\n", top); + else + printf("\nDirectory structure of %s\n", top); + if (Point) + printf("(excluding entries that begin with '.')\n"); + pt_tree(); /* print the tree */ + } + exit(0) ; +} + + +t_search(dir, addrs) +char *dir; +struct Entry *addrs; +{ + int bsort; /* index to begin sort */ + int stmp; /* save temporary index value */ + struct Entry *sstep; /* saved step in list */ + int nitems; /* # of items in this directory */ + DIR *dirp; + char sub[MAXNAMLEN+1]; /* used for subdirectory names */ + int i; + struct dirent direntry; + struct dirent *dp = &direntry; + int n_subs = 0; + int tmp = 0; + + dirp = opendir("."); + if (dirp == NULL) { + fprintf(stderr, "Cannot open %s\n", dir); + return(0); + } +/* setbuf(dirp, Buf3);*/ + + bsort = Index; + sstep = addr(List,bsort); /* initialize sstep for for loop later on */ + nitems = Index; + /* get the entries of the directory that we are interested in */ + while ((dp = readdir(dirp)) != NULL ) { + if (!dp->d_ino + || (strcmp(dp->d_name, ".") == SAME) + || (strcmp(dp->d_name, "..") == SAME) + || (Point && dp->d_name[0] == '.')) + continue; + + sprintf(sub, "%s", dp->d_name); + if ((tmp = stat(sub, &Status)) == FAIL) { + fprintf(stderr, "%s:stat can't find\n", sub); + continue; + } + else if ((Status.st_mode & S_IFMT) == S_IFDIR) + addr(List,Index)->dir = 1; + else if (All) + addr(List,Index)->dir = 0; + else + continue; + sprintf(addr(List,Index)->e_name, "%s", dp->d_name); + addr(List,Index)->last = 0; + addr(List,Index)->end = 0; + addr(List,Index)->dev = (Device == Status.st_dev); + if (stln(addr(List,Index)->e_name) > Maxes[Level]) + Maxes[Level] = stln(addr(List,Index)->e_name); + ++Index; + if (Index*SIZEOFentry >= Size) { + Size += 20*SIZEOFentry; + if (!(List = + (struct Entry *)realloc((char *)List, Size))) { + fprintf(stderr, "Out of space\n"); + break; + } + fprintf(stderr, "Out of space\n"); + break; + } + } + closedir(dirp); + nitems = Index - nitems; /* nitems now contains the # of */ + /* items in this dir, rather than */ + /* # total items before this dir */ + if (Sort) + qsort(addr(List, bsort), nitems, SIZEOFentry, + (cmp_func_t) compar); /* Nick */ + addr(List,Index-1)->last = 1; /* mark last item for this dir */ + n_subs = nitems; + stmp = Index; + /* now walk through, and recurse on directory entries */ + /* sstep was initialized above */ + for (i = 0; i < nitems; sstep = addr(List,stmp - nitems+(++i))) { + if (sstep->dir && (Xdev || sstep->dev)) { + sstep->next = Index; + sprintf(sub, "%s", sstep->e_name); + tmp = n_subs; + Level++; + if (chdir(sub) == FAIL) + fprintf(stderr, + "Can't chdir to %s/%s\n", dir, sub); + else { + n_subs += t_search(sub, sstep); + if (chdir("..") == FAIL) { + fprintf(stderr, + "No '..' in %s/%s!\n",dir, sub); + exit(1); + } + } + --Level; + if (n_subs - tmp <= 0) + sstep->next = 0; + else + --n_subs; + } + else + sstep->next = 0; + } + addrs->end = (unsigned)n_subs; + return(n_subs); +} + +/* + * comparison routine for qsort + */ + +int compar(a, b) +struct Entry *a, *b; +{ + if (!File_dir) /* straight alphabetical */ + return(strncmp(a->e_name, b->e_name, Length)); + + /* sort alphabetically if both dirs or both not dirs */ + + if ((a->dir && b->dir) || (!a->dir && !b->dir)) + return(strncmp(a->e_name, b->e_name, Length)); + + if (File_dir == FFIRST) { /* sort by files first */ + if (a->dir) + return(GREATER); + else + return(LESSTHAN); + } + + if (a->dir) /* sort by dir first */ + return(LESSTHAN); + else + return(GREATER); +} + + +void pt_tree() +{ + register int i,j; + struct Entry *l; + struct Entry *hdr[DEPTH]; + int posit[DEPTH]; /* array of positions to print dirs */ + int con[DEPTH]; /* flags for connecting up tree */ + char flag; /* flag to leave blank line after dir */ + struct Entry *stack[DEPTH]; /* save positions for changing levels */ + int top = 0; /* index to top of stack */ + int count = 1; /* count of line of output */ + int n; + Level = 0; /* initialize Level */ + + /* this loop appends each Entry with dashes or spaces, for */ + /* directories or files respectively */ + + for (i = 0; i < Index; i++) { + for (j = 0; j < Length; j++) { + if (!addr(List,i)->e_name[j]) + break; + } + if (addr(List,i)->dir) { + addr(List,i)->e_name[j] = '-'; + } else { + addr(List,i)->e_name[j] = ' '; + } + } + + /* adjust the Maxes array according to the flags */ + + for (i = 0; i < DEPTH; i++) { + if (Varspaces) { + if (Maxes[i] > CLength ) + Maxes[i] = CLength; + } else + Maxes[i] = CLength; + } + + /* clear the connective and position flags */ + + for (i = 0; i < DEPTH; i++) + con[i] = posit[i] = 0; + + /* this is the main loop to print the tree structure. */ + l = addr(List,0); + j = 0; + for (;;) { + /* directory Entry, save it for later printing */ + if (l->dir != 0 && l->next != 0) { + hdr[Level] = l; + posit[Level] = count + (l->end + 1)/2 - 1; + flag = 1; + stack[top++] = l; + l = addr(List,l->next); + ++Level; + continue; + } + + /* print columns up to our Entry */ + for (j = 0; j < (flag ? Level-1 : Level); j++) { + if (!flag && posit[j] && posit[j] <= count) { + /* time to print it */ + if (hdr[j]->e_name[CLength-1] != '-') + hdr[j]->e_name[CLength-1] = '*'; + printf("|-%s",hdr[j]->e_name); + if (strlen(hdr[j]->e_name)e_name));n++) + putchar('-'); + posit[j] = 0; + if (hdr[j]->last != 0) + con[j] = 0; + else + con[j] = 1; + } + else + { + if (con[j]) putchar('|'); + else putchar(' '); + putchar(' '); + for (n=0;ne_name[CLength-1] != '-' && + l->e_name[CLength-1] != ' ') + l->e_name[CLength-1] = '*'; + printf("|-%s",l->e_name); + if (l->last) { + con[j] = 0; + } else { + con[j] = 1; + } + } + putchar('\n'); + + if (l->last) { + /* walk back up */ + while (l->last) { + --Level; + if (--top <= 0) + return; + l = stack[top]; + } + } + l = addr(l,1); + ++count; + } +} + + +/* stln - sortof like strlen, returns length up to Length-1 */ +int stln(st) +register char *st; +{ + register int t; + + for (t=0; t +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(MSX_UZIX_TARGET) || defined(PC_UZIX_TARGET) +typedef int nlink_t; +#endif + +#define BLOCK_SIZE 1024 + +extern char *optarg; +extern int optind; + +#define LINELEN 256 +#define NR_ALREADY 512 + +#ifdef S_IFLNK +#define LSTAT lstat +#else +#define LSTAT stat +#endif + +typedef struct already { + struct already *al_next; + int al_dev; + ino_t al_inum; + nlink_t al_nlink; +} ALREADY; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(int makedname, (char *d, char *f, char *out, int outlen)); +_PROTOTYPE(int done, (int dev, ino_t inum, nlink_t nlink)); +_PROTOTYPE(long dodir, (char *d, int thislev)); + +char *prog; /* program name */ +char *optstr = "asl:"; /* -a and -s arguments */ +int silent = 0; /* silent mode */ +int all = 0; /* all directory entries mode */ +char *startdir = "."; /* starting from here */ +int levels = 20000; /* # of directory levels to print */ +ALREADY *already[NR_ALREADY]; +int alc; + + +/* + * makedname - make the pathname from the directory name, and the + * directory entry, placing it in out. If this would overflow, + * return 0, otherwise 1. + */ +int makedname(d, f, out, outlen) +char *d; +char *f; +char *out; +int outlen; +{ + char *cp; + int length; + + length = strlen(f); + if (strlen(d) + length + 2 > outlen) return(0); + for (cp = out; *d; *cp++ = *d++); + if (*(cp - 1) != '/') *cp++ = '/'; + while (length--) *cp++ = *f++; + *cp = '\0'; + return(1); +} + +/* + * done - have we encountered (dev, inum) before? Returns 1 for yes, + * 0 for no, and remembers (dev, inum, nlink). + */ +int done(dev, inum, nlink) +int dev; +ino_t inum; +nlink_t nlink; +{ + register ALREADY **pap, *ap; + + pap = &already[(unsigned) inum % NR_ALREADY]; + while ((ap = *pap) != NULL) { + if (ap->al_inum == inum && ap->al_dev == dev) { + if (--ap->al_nlink == 0) { + *pap = ap->al_next; + free(ap); + } + return(1); + } + pap = &ap->al_next; + } + if ((ap = malloc(sizeof(*ap))) == NULL) { + fprintf(stderr, "du: Out of memory\n"); + exit(1); + } + ap->al_next = NULL; + ap->al_inum = inum; + ap->al_dev = dev; + ap->al_nlink = nlink - 1; + *pap = ap; + return(0); +} + +/* + * dodir - process the directory d. Return the long size (in blocks) + * of d and its descendants. + */ +long dodir(d, thislev) +char *d; +int thislev; +{ + int maybe_print; + struct stat s; + long total; + char dent[LINELEN]; + DIR *dp; + struct dirent *entry; + + if (LSTAT(d, &s) < 0) { + fprintf(stderr, + "%s: %s: %s\n", prog, d, strerror(errno)); + return 0L; + } +#if 0 /* Nick */ + total = s.st_size.o_blkno + (s.st_size.o_offset > 0); +#else + total = (s.st_size + (BLOCK_SIZE - 1)) / BLOCK_SIZE; +#endif + switch (s.st_mode & S_IFMT) { + case S_IFDIR: + /* Directories should not be linked except to "." and "..", so this + * directory should not already have been done. + */ + maybe_print = !silent; + if ((dp = opendir(d)) == NULL) break; + while ((entry = readdir(dp)) != NULL) { + if (strcmp(entry->d_name, ".") == 0 || + strcmp(entry->d_name, "..") == 0) + continue; + if (!makedname(d, entry->d_name, dent, sizeof(dent))) continue; + total += dodir(dent, thislev - 1); + } + closedir(dp); + break; + case S_IFBLK: + case S_IFCHR: + /* st_size for special files is not related to blocks used. */ + total = 0; + /* Fall through. */ + default: + if (s.st_nlink > 1 && done(s.st_dev, s.st_ino, s.st_nlink)) return 0L; + maybe_print = all; + break; + } + if (thislev >= levels || (maybe_print && thislev >= 0)) + printf("%ld\t%s\n", total, d); + return(total); +} + +int main(argc, argv) +int argc; +char **argv; +{ + int c; + + prog = argv[0]; + while ((c = getopt(argc, argv, optstr)) != EOF) switch (c) { + case 'a': all = 1; break; + case 's': silent = 1; break; + case 'l': levels = atoi(optarg); break; + default: + fprintf(stderr, + "usage: %s [-a] [-s] [-l levels] [startdir]\n", prog); + exit(1); + } + do { + if (optind < argc) startdir = argv[optind++]; + alc = 0; + (void) dodir(startdir, levels); + } while (optind < argc); + return(0); +} diff --git a/src/simple/echo.c b/src/simple/echo.c new file mode 100755 index 00000000..225591be --- /dev/null +++ b/src/simple/echo.c @@ -0,0 +1,105 @@ +/* Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * 01/99: added -e option by Archi Schekochikhin. + */ +#include + +typedef unsigned char BOOL; + +static BOOL nonl; + +static void doesc __P((char *p)); + +static void doesc(p) + char *p; +{ + int i, n; + char ch; + + while ((ch = *p++) != 0) { + if (ch == '\\') { + switch (*p++) { + case 'c': nonl = 1; continue; + case 'a': ch = 7; break; + case 'b': ch = '\b'; break; + case 'f': ch = '\f'; break; + case 'n': ch = '\n'; break; + case 'r': ch = '\r'; break; + case 't': ch = '\t'; break; + case 'v': ch = '\v'; break; + case '\\': ch = '\\'; break; + case 'x': + n = 0; + for (i = 2; --i >= 0; ++p) { + ch = *p - '0'; + if (ch > 'a'-'0') + ch = *p - 'a' + 10; + else if (ch > 'A'-'0') + ch = *p - 'A' + 10; + if (ch < 0 || ch > 15) + break; + n <<= 4; + n += ch; + } + ch = n; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + n = 0; + for (i = 3, --p; --i >= 0; ++p) { + ch = *p - '0'; + if (ch < 0 || ch > 7) + break; + n <<= 3; + n += ch; + } + ch = n; + break; + default: ch = *p; break; + } + } + fputc(ch, stdout); + } +} + +int main(argc, argv) + int argc; + char *argv[]; +{ + BOOL first = 1, esc = 0; + char *p; + int i; + + if (argc < 2) { + fprintf(stderr,"usage: echo [-ne] string ...\n"); + return 0; + } + for (i = 1; i < argc; ++i) { + p = argv[i]; + if (p[0] == '-') { + for (++p; *p; ++p) { + switch (*p) { + case 'n': nonl = 1; break; + case 'e': esc = 1; break; + default: goto Print; + } + } + } + else break; + } +Print: for (; i < argc; ++i) { + p = argv[i]; + if (!first) + fputc(' ', stdout); + first = 0; + if (esc) + doesc(p); + else fputs(p, stdout); + } + if (!nonl) + fputc('\n', stdout); + return ferror(stdout); +} + diff --git a/src/simple/ed.c b/src/simple/ed.c new file mode 100755 index 00000000..14bac90c --- /dev/null +++ b/src/simple/ed.c @@ -0,0 +1,2196 @@ +/* Copyright 1987 Brian Beattie Rights Reserved. + * + * Permission to copy and/or distribute granted under the + * following conditions: + * + * 1). No charge may be made other than resonable charges + * for reproduction. + * + * 2). This notice must remain intact. + * + * 3). No further restrictions may be added. + * + */ + +/* This program used to be in many little pieces, with this makefile: +.SUFFIXES: .c .s + +CFLAGS = -F + +OBJS = append.s catsub.s ckglob.s deflt.s del.s docmd.s doglob.s\ + doprnt.s doread.s dowrite.s ed.s egets.s find.s getfn.s getlst.s\ + getnum.s getone.s getptr.s getrhs.s gettxt.s ins.s join.s maksub.s\ + move.s optpat.s set.s setbuf.s subst.s getpat.s matchs.s amatch.s\ + unmkpat.s omatch.s makepat.s bitmap.s dodash.s esc.s System.s + +ed: $(OBJS) + cc -T. -i -o ed $(OBJS) +*/ + +#include +#include +#include +#include +#include +#include +#include + +/****************************/ + +/* tools.h */ +/* + * #defines for non-printing ASCII characters + */ + +#define NUL 0x00 /* ^@ */ +#define EOS 0x00 /* end of string */ +#define SOH 0x01 /* ^A */ +#define STX 0x02 /* ^B */ +#define ETX 0x03 /* ^C */ +#define EOT 0x04 /* ^D */ +#define ENQ 0x05 /* ^E */ +#define ACK 0x06 /* ^F */ +#define BEL 0x07 /* ^G */ +#define BS 0x08 /* ^H */ +#define HT 0x09 /* ^I */ +#define LF 0x0a /* ^J */ +#define NL '\n' +#define VT 0x0b /* ^K */ +#define FF 0x0c /* ^L */ +#define CR 0x0d /* ^M */ +#define SO 0x0e /* ^N */ +#define SI 0x0f /* ^O */ +#define DLE 0x10 /* ^P */ +#define DC1 0x11 /* ^Q */ +#define DC2 0x12 /* ^R */ +#define DC3 0x13 /* ^S */ +#define DC4 0x14 /* ^T */ +#define NAK 0x15 /* ^U */ +#define SYN 0x16 /* ^V */ +#define ETB 0x17 /* ^W */ +#define CAN 0x18 /* ^X */ +#define EM 0x19 /* ^Y */ +#define SUB 0x1a /* ^Z */ +#define ESC 0x1b /* ^[ */ +#define FS 0x1c /* ^\ */ +#define GS 0x1d /* ^] */ +#define RS 0x1e /* ^^ */ +#define US 0x1f /* ^_ */ +#define SP 0x20 /* space */ +#define DEL 0x7f /* DEL */ + + +#define TRUE 1 +#define FALSE 0 +#define ERR -2 + + +/* Definitions of meta-characters used in pattern matching + * routines. LITCHAR & NCCL are only used as token identifiers; + * all the others are also both token identifier and actual symbol + * used in the regular expression. + */ + + +#define BOL '^' +#define EOL '$' +#define ANY '.' +#define LITCHAR 'L' +#define ESCAPE '\\' +#define CCL '[' /* Character class: [...] */ +#define CCLEND ']' +#define NEGATE '~' +#define NCCL '!' /* Negative character class [^...] */ +#define CLOSURE '*' +#define OR_SYM '|' +#define DITTO '&' +#define OPEN '(' +#define CLOSE ')' + +/* Largest permitted size for an expanded character class. (i.e. the class + * [a-z] will expand into 26 symbols; [a-z0-9] will expand into 36.) + */ +#define CLS_SIZE 128 + +/* + * Tokens are used to hold pattern templates. (see makepat()) + */ +typedef char BITMAP; + +typedef struct token { + char tok; + char lchar; + BITMAP *bitmap; + struct token *next; +} TOKEN; + +#define TOKSIZE sizeof (TOKEN) + +/* + * An absolute maximun for strings. + */ + +#define MAXSTR 132 /* Maximum numbers of characters in a line */ + + +/* Macros */ +#define max(a,b) ((a>b)?a:b) +#define min(a,b) ((a='a'&&c<='z'?c-32:c) + +/* ed.h */ +#define FATAL (ERR-1) +struct line { + int l_stat; /* empty, mark */ + struct line *l_prev; + struct line *l_next; + char l_buff[1]; +}; + +typedef struct line LINE; + +#define LINFREE 1 /* entry not in use */ +#define LGLOB 2 /* line marked global */ + + /* max number of chars per line */ +#define MAXLINE (sizeof(int) == 2 ? 256 : 8192) +#define MAXPAT 256 /* max number of chars per replacement + * pattern */ + /* max file name size */ +#define MAXFNAME (sizeof(int) == 2 ? 256 : 1024) + +extern LINE line0; +extern int curln, lastln, line1, line2, nlines; +extern int nflg; /* print line number flag */ +extern int lflg; /* print line in verbose mode */ +extern char *inptr; /* tty input buffer */ +extern char linbuf[], *linptr; /* current line */ +extern int truncflg; /* truncate long line flag */ +extern int eightbit; /* save eighth bit */ +extern int nonascii; /* count of non-ascii chars read */ +extern int nullchar; /* count of null chars read */ +extern int truncated; /* count of lines truncated */ +extern int fchanged; /* file changed */ + +#define nextln(l) ((l)+1 > lastln ? 0 : (l)+1) +#define prevln(l) ((l)-1 < 0 ? lastln : (l)-1) + +/* amatch.c */ +/* #include */ +/* #include "tools.h" */ + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(static char *match, (char *lin, TOKEN *pat, char *boln)); +_PROTOTYPE(char *amatch, (char *lin, TOKEN *pat, char *boln)); +_PROTOTYPE(int append, (int line, int glob)); +_PROTOTYPE(BITMAP *makebitmap, (unsigned size)); +_PROTOTYPE(int setbit, (unsigned c, char *map, unsigned val)); +_PROTOTYPE(int testbit, (unsigned c, char *map)); +_PROTOTYPE(char *catsub, (char *from, char *to, char *sub, char *new, char *newend)); +_PROTOTYPE(int ckglob, (void)); +_PROTOTYPE(int deflt, (int def1, int def2)); +_PROTOTYPE(int del, (int from, int to)); +_PROTOTYPE(int docmd, (int glob)); +_PROTOTYPE(int dolst, (int line1, int line2)); +_PROTOTYPE(char *dodash, (int delim, char *src, char *map)); +_PROTOTYPE(int doglob, (void)); +_PROTOTYPE(int doprnt, (int from, int to)); +_PROTOTYPE(void prntln, (char *str, int vflg, int lin)); +_PROTOTYPE(void putcntl, (char c, FILE *stream)); +_PROTOTYPE(int doread, (int lin, char *fname)); +_PROTOTYPE(int dowrite, (int from, int to, char *fname, int apflg)); +_PROTOTYPE(void intr, (int sig)); +_PROTOTYPE(int egets, (char *str, int size, FILE *stream)); +_PROTOTYPE(int esc, (char **s)); +_PROTOTYPE(int find, (TOKEN *pat, int dir)); +_PROTOTYPE(char *getfn, (void)); +_PROTOTYPE(int getlst, (void)); +_PROTOTYPE(int getnum, (int first)); +_PROTOTYPE(int getone, (void)); +_PROTOTYPE(TOKEN *getpat, (char *arg)); +_PROTOTYPE(LINE *getptr, (int num)); +_PROTOTYPE(int getrhs, (char *sub)); +_PROTOTYPE(char *gettxt, (int num)); +_PROTOTYPE(int ins, (char *str)); +_PROTOTYPE(int System, (char *c)); +_PROTOTYPE(int join, (int first, int last)); +_PROTOTYPE(TOKEN *makepat, (char *arg, int delim)); +_PROTOTYPE(char *maksub, (char *sub, int subsz)); +_PROTOTYPE(char *matchs, (char *line, TOKEN *pat, int ret_endp)); +_PROTOTYPE(int move, (int num)); +_PROTOTYPE(int transfer, (int num)); +_PROTOTYPE(int omatch, (char **linp, TOKEN *pat, char *boln)); +_PROTOTYPE(TOKEN *optpat, (void)); +_PROTOTYPE(int set, (void)); +_PROTOTYPE(int show, (void)); +_PROTOTYPE(void relink, (LINE *a, LINE *x, LINE *y, LINE *b)); +_PROTOTYPE(void clrbuf, (void)); +_PROTOTYPE(void set_buf, (void)); +_PROTOTYPE(int subst, (TOKEN *pat, char *sub, int gflg, int pflag)); +_PROTOTYPE(void unmakepat, (TOKEN *head)); + +/* Scans throught the pattern template looking for a match + * with lin. Each element of lin is compared with the template + * until either a mis-match is found or the end of the template + * is reached. In the former case a 0 is returned; in the latter, + * a pointer into lin (pointing to the character following the + * matched pattern) is returned. + * + * "lin" is a pointer to the line being searched. + * "pat" is a pointer to a template made by makepat(). + * "boln" is a pointer into "lin" which points at the + * character at the beginning of the line. + */ + +char *paropen[9], *parclose[9]; +int between, parnum; + +char *amatch(lin, pat, boln) +char *lin; +TOKEN *pat; +char *boln; +{ + between = 0; + parnum = 0; + + lin = match(lin, pat, boln); + + if (between) return 0; + + while (parnum < 9) { + paropen[parnum] = parclose[parnum] = ""; + parnum++; + } + return lin; +} + +static char *match(lin, pat, boln) +char *lin; +TOKEN *pat; +char *boln; +{ + register char *bocl, *rval, *strstart; + + if (pat == 0) return 0; + + strstart = lin; + + while (pat) { + if (pat->tok == CLOSURE && pat->next) { + /* Process a closure: first skip over the closure + * token to the object to be repeated. This object + * can be a character class. */ + + pat = pat->next; + + /* Now match as many occurrences of the closure + * pattern as possible. */ + bocl = lin; + + while (*lin && omatch(&lin, pat, boln)); + + /* 'Lin' now points to the character that made made + * us fail. Now go on to process the rest of the + * string. A problem here is a character following + * the closure which could have been in the closure. + * For example, in the pattern "[a-z]*t" (which + * matches any lower-case word ending in a t), the + * final 't' will be sucked up in the while loop. + * So, if the match fails, we back up a notch and try + * to match the rest of the string again, repeating + * this process recursively until we get back to the + * beginning of the closure. The recursion goes, at + * most two levels deep. */ + + if (pat = pat->next) { + int savbtwn = between; + int savprnm = parnum; + + while (bocl <= lin) { + if (rval = match(lin, pat, boln)) { + /* Success */ + return(rval); + } else { + --lin; + between = savbtwn; + parnum = savprnm; + } + } + return(0); /* match failed */ + } + } else if (pat->tok == OPEN) { + if (between || parnum >= 9) return 0; + paropen[parnum] = lin; + between = 1; + pat = pat->next; + } else if (pat->tok == CLOSE) { + if (!between) return 0; + parclose[parnum++] = lin; + between = 0; + pat = pat->next; + } else if (omatch(&lin, pat, boln)) { + pat = pat->next; + } else { + return(0); + } + } + + /* Note that omatch() advances lin to point at the next character to + * be matched. Consequently, when we reach the end of the template, + * lin will be pointing at the character following the last character + * matched. The exceptions are templates containing only a BOLN or + * EOLN token. In these cases omatch doesn't advance. + * + * A philosophical point should be mentioned here. Is $ a position or a + * character? (i.e. does $ mean the EOL character itself or does it + * mean the character at the end of the line.) I decided here to + * make it mean the former, in order to make the behavior of match() + * consistent. If you give match the pattern ^$ (match all lines + * consisting only of an end of line) then, since something has to be + * returned, a pointer to the end of line character itself is + * returned. */ + + return((char *) max(strstart, lin)); +} + +/* append.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int append(line, glob) +int line, glob; +{ + int stat; + char lin[MAXLINE]; + + if (glob) return(ERR); + curln = line; + while (1) { + if (nflg) printf("%6d. ", curln + 1); + + if (fgets(lin, MAXLINE, stdin) == NULL) return(EOF); + if (lin[0] == '.' && lin[1] == '\n') return (0); + stat = ins(lin); + if (stat < 0) return(ERR); + } +} + +/* bitmap.c */ +/* + * BITMAP.C - makebitmap, setbit, testbit + * bit-map manipulation routines. + * + * Copyright (c) Allen I. Holub, all rights reserved. This program may + * for copied for personal, non-profit use only. + * + */ + +#ifdef DEBUG +/* #include */ +#endif + +/* #include "tools.h" */ + + +BITMAP *makebitmap(size) +unsigned size; +{ + /* Make a bit map with "size" bits. The first entry in the map is an + * "unsigned int" representing the maximum bit. The map itself is + * concatenated to this integer. Return a pointer to a map on + * success, 0 if there's not enough memory. */ + + unsigned *map, numbytes; + + numbytes = (size >> 3) + ((size & 0x07) ? 1 : 0); + +#ifdef DEBUG + printf("Making a %d bit map (%d bytes required)\n", size, numbytes); +#endif + + if (map = (unsigned *) malloc(numbytes + sizeof(unsigned))) *map = size; + + return((BITMAP *) map); +} + +int setbit(c, map, val) +unsigned c, val; +char *map; +{ + /* Set bit c in the map to val. If c > map-size, 0 is returned, else + * 1 is returned. */ + + if (c >= *(unsigned *) map) /* if c >= map size */ + return 0; + + map += sizeof(unsigned); /* skip past size */ + + if (val) + map[c >> 3] |= 1 << (c & 0x07); + else + map[c >> 3] &= ~(1 << (c & 0x07)); + + return 1; +} + +int testbit(c, map) +unsigned c; +char *map; +{ + /* Return 1 if the bit corresponding to c in map is set. 0 if it is not. */ + + if (c >= *(unsigned *) map) return 0; + + map += sizeof(unsigned); + + return(map[c >> 3] & (1 << (c & 0x07))); +} + +/* catsub.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +extern char *paropen[9], *parclose[9]; + +char *catsub(from, to, sub, new, newend) +char *from, *to, *sub, *new, *newend; +{ + char *cp, *cp2; + + for (cp = new; *sub != EOS && cp < newend;) { + if (*sub == DITTO) for (cp2 = from; cp2 < to;) { + *cp++ = *cp2++; + if (cp >= newend) break; + } + else if (*sub == ESCAPE) { + sub++; + if ('1' <= *sub && *sub <= '9') { + char *parcl = parclose[*sub - '1']; + + for (cp2 = paropen[*sub - '1']; cp2 < parcl;) { + *cp++ = *cp2++; + if (cp >= newend) break; + } + } else + *cp++ = *sub; + } else + *cp++ = *sub; + + sub++; + } + + return(cp); +} + +/* ckglob.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int ckglob() +{ + TOKEN *glbpat; + char c, delim; + char lin[MAXLINE]; + int num; + LINE *ptr; + + c = *inptr; + + if (c != 'g' && c != 'v') return(0); + + if (deflt(1, lastln) < 0) return(ERR); + + delim = *++inptr; + if (delim <= ' ') return(ERR); + + glbpat = optpat(); + + if (*inptr == delim) inptr++; + + ptr = getptr(1); + for (num = 1; num <= lastln; num++) { + ptr->l_stat &= ~LGLOB; + if (line1 <= num && num <= line2) { + strcpy(lin, ptr->l_buff); + strcat(lin, "\n"); + if (matchs(lin, glbpat, 0)) { + if (c == 'g') ptr->l_stat |= LGLOB; + } else { + if (c == 'v') ptr->l_stat |= LGLOB; + } + } + ptr = ptr->l_next; + } + return(1); +} + +/* deflt.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int deflt(def1, def2) +int def1, def2; +{ + if (nlines == 0) { + line1 = def1; + line2 = def2; + } + if (line1 > line2 || line1 <= 0) return(ERR); + return(0); +} + +/* del.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int del(from, to) +int from, to; +{ + LINE *first, *last, *next, *tmp; + + if (from < 1) from = 1; + first = getptr(prevln(from)); + last = getptr(nextln(to)); + next = first->l_next; + while (next != last && next != &line0) { + tmp = next->l_next; + free((char *) next); + next = tmp; + } + relink(first, last, first, last); + lastln -= (to - from) + 1; + curln = prevln(from); + return(0); +} + +/* docmd.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +char fname[MAXFNAME]; +int fchanged; +extern int nofname; + +extern int mark[]; + +int docmd(glob) +int glob; +{ + static char rhs[MAXPAT]; + TOKEN *subpat; + int c, err, line3; + int apflg, pflag, gflag; + int nchng; + char *fptr; + + pflag = FALSE; + while (*inptr == SP && *inptr == HT) inptr++; + + c = *inptr++; + + switch (c) { + case NL: + if (nlines == 0) { + if ((line2 = nextln(curln)) == 0) return(ERR); + } + curln = line2; + return(1); + + case '=': printf("%d\n", line2); break; + + case 'a': + if (*inptr != NL || nlines > 1) return(ERR); + + if (append(line1, glob) < 0) return(ERR);; + fchanged = TRUE; + break; + + case 'c': + if (*inptr != NL) return(ERR); + + if (deflt(curln, curln) < 0) return(ERR); + + if (del(line1, line2) < 0) return(ERR); + if (append(curln, glob) < 0) return (ERR); + fchanged = TRUE; + break; + + case 'd': + if (*inptr != NL) return(ERR); + + if (deflt(curln, curln) < 0) return(ERR); + + if (del(line1, line2) < 0) return(ERR); + if (nextln(curln) != 0) curln = nextln(curln); + fchanged = TRUE; + break; + + case 'e': + if (nlines > 0) return(ERR); + if (fchanged) { + fchanged = FALSE; + return(ERR); + } + + /* FALL THROUGH */ + case 'E': + if (nlines > 0) return(ERR); + + if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR); + + if ((fptr = getfn()) == NULL) return(ERR); + + clrbuf(); + if ((err = doread(0, fptr)) < 0) return(err); + + strcpy(fname, fptr); + fchanged = FALSE; + break; + + case 'f': + if (nlines > 0) return(ERR); + + if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR); + + if ((fptr = getfn()) == NULL) return(ERR); + + if (nofname) + printf("%s\n", fname); + else + strcpy(fname, fptr); + break; + + case 'i': + if (*inptr != NL || nlines > 1) return(ERR); + + if (append(prevln(line1), glob) < 0) return(ERR); + fchanged = TRUE; + break; + + case 'j': + if (*inptr != NL || deflt(curln, curln + 1) < 0) return(ERR); + + if (join(line1, line2) < 0) return(ERR); + break; + + case 'k': + while (*inptr == ' ' || *inptr == HT) inptr++; + + if (*inptr < 'a' || *inptr > 'z') return ERR; + c = *inptr++; + + if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR); + + mark[c - 'a'] = line1; + break; + + case 'l': + if (*inptr != NL) return(ERR); + if (deflt(curln, curln) < 0) return (ERR); + if (dolst(line1, line2) < 0) return (ERR); + break; + + case 'm': + if ((line3 = getone()) < 0) return(ERR); + if (deflt(curln, curln) < 0) return (ERR); + if (move(line3) < 0) return (ERR); + fchanged = TRUE; + break; + + case 'P': + case 'p': + if (*inptr != NL) return(ERR); + if (deflt(curln, curln) < 0) return (ERR); + if (doprnt(line1, line2) < 0) return (ERR); + break; + + case 'q': + if (fchanged) { + printf("File modified. Use q or Q to confirm exit.\n"); + fchanged = FALSE; + return(0); + } + + /* FALL THROUGH */ + case 'Q': + if (*inptr == NL && nlines == 0 && !glob) + return(EOF); + else + return(ERR); + + case 'r': + if (nlines > 1) return(ERR); + + if (nlines == 0) line2 = lastln; + + if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR); + + if ((fptr = getfn()) == NULL) return(ERR); + + if ((err = doread(line2, fptr)) < 0) return(err); + fchanged = TRUE; + break; + + case 's': + if (*inptr == 'e') return(set()); + while (*inptr == SP || *inptr == HT) inptr++; + if ((subpat = optpat()) == NULL) return (ERR); + if ((gflag = getrhs(rhs)) < 0) return (ERR); + if (*inptr == 'p') pflag++; + if (deflt(curln, curln) < 0) return (ERR); + if ((nchng = subst(subpat, rhs, gflag, pflag)) < 0) return (ERR); + if (nchng) fchanged = TRUE; + break; + + case 't': + if ((line3 = getone()) < 0) return(ERR); + if (deflt(curln, curln) < 0) return (ERR); + if (transfer(line3) < 0) return (ERR); + fchanged = TRUE; + break; + + case 'W': + case 'w': + apflg = (c == 'W'); + + if (*inptr != ' ' && *inptr != HT && *inptr != NL) return(ERR); + + if ((fptr = getfn()) == NULL) return(ERR); + + if (deflt(1, lastln) < 0) return(ERR); + if (dowrite(line1, line2, fptr, apflg) < 0) return (ERR); + fchanged = FALSE; + break; + + case 'x': + if (*inptr == NL && nlines == 0 && !glob) { + if ((fptr = getfn()) == NULL) return(ERR); + if (dowrite(1, lastln, fptr, 0) >= 0) return (EOF); + } + return(ERR); + + case 'z': + if (deflt(curln, curln) < 0) return(ERR); + + switch (*inptr) { + case '-': + if (doprnt(line1 - 21, line1) < 0) return(ERR); + break; + + case '.': + if (doprnt(line1 - 11, line1 + 10) < 0) return(ERR); + break; + + case '+': + case '\n': + if (doprnt(line1, line1 + 21) < 0) return(ERR); + break; + } + break; + + default: return(ERR); +} + return(0); +} + +int dolst(line1, line2) +int line1, line2; +{ + int oldlflg = lflg, p; + + lflg = 1; + p = doprnt(line1, line2); + lflg = oldlflg; + + return p; +} + +/* dodash.c */ +/* #include */ +/* #include "tools.h" */ + +/* Expand the set pointed to by *src into dest. + * Stop at delim. Return 0 on error or size of + * character class on success. Update *src to + * point at delim. A set can have one element + * {x} or several elements ( {abcdefghijklmnopqrstuvwxyz} + * and {a-z} are equivalent ). Note that the dash + * notation is expanded as sequential numbers. + * This means (since we are using the ASCII character + * set) that a-Z will contain the entire alphabet + * plus the symbols: [\]^_`. The maximum number of + * characters in a character class is defined by maxccl. + */ +char *dodash(delim, src, map) +int delim; +char *src, *map; +{ + + register int first, last; + char *start; + + start = src; + + while (*src && *src != delim) { + if (*src != '-') setbit(esc(&src), map, 1); + + else if (src == start || *(src + 1) == delim) + setbit('-', map, 1); + else { + src++; + + if (*src < *(src - 2)) { + first = *src; + last = *(src - 2); + } else { + first = *(src - 2); + last = *src; + } + + while (++first <= last) setbit(first, map, 1); + + } + src++; + } + return(src); +} + +/* doglob.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int doglob() +{ + int lin, stat; + char *cmd; + LINE *ptr; + + cmd = inptr; + + while (1) { + ptr = getptr(1); + for (lin = 1; lin <= lastln; lin++) { + if (ptr->l_stat & LGLOB) break; + ptr = ptr->l_next; + } + if (lin > lastln) break; + + ptr->l_stat &= ~LGLOB; + curln = lin; + inptr = cmd; + if ((stat = getlst()) < 0) return(stat); + if ((stat = docmd(1)) < 0) return (stat); + } + return(curln); +} + +/* doprnt.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int doprnt(from, to) +int from, to; +{ + int i; + LINE *lptr; + + from = from < 1 ? 1 : from; + to = to > lastln ? lastln : to; + + if (to != 0) { + lptr = getptr(from); + for (i = from; i <= to; i++) { + prntln(lptr->l_buff, lflg, (nflg ? i : 0)); + lptr = lptr->l_next; + } + curln = to; + } + return(0); +} + +void prntln(str, vflg, lin) +char *str; +int vflg, lin; +{ + if (lin) printf("%7d ", lin); + while (*str && *str != NL) { + if (*str < ' ' || *str >= 0x7f) { + switch (*str) { + case '\t': + if (vflg) + putcntl(*str, stdout); + else + putc(*str, stdout); + break; + + case DEL: + putc('^', stdout); + putc('?', stdout); + break; + + default: + putcntl(*str, stdout); + break; + } + } else + putc(*str, stdout); + str++; + } + if (vflg) putc('$', stdout); + putc('\n', stdout); +} + +void putcntl(c, stream) +char c; +FILE *stream; +{ + putc('^', stream); + putc((c & 31) | '@', stream); +} + +/* doread.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +extern int diag; + +int doread(lin, fname) +int lin; +char *fname; +{ + FILE *fp; + int err; + long bytes; + int lines; + static char str[MAXLINE]; + + err = 0; + nonascii = nullchar = truncated = 0; + + if (diag) printf("\"%s\" ", fname); + if ((fp = fopen(fname, "r")) == NULL) { + printf("file open error\n"); + return(ERR); + } + curln = lin; + for (lines = 0, bytes = 0; (err = egets(str, MAXLINE, fp)) > 0;) { + bytes += strlen(str); + if (ins(str) < 0) { + printf("File insert error.\n"); + err++; + break; + } + lines++; + } + fclose(fp); + if (err < 0) return(err); + if (diag) { + printf("%d lines %ld bytes", lines, bytes); + if (nonascii) printf(" [%d non-ascii]", nonascii); + if (nullchar) printf(" [%d nul]", nullchar); + if (truncated) printf(" [%d lines truncated]", truncated); + printf("\n"); + } + return(err); +} + +/* dowrite.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int dowrite(from, to, fname, apflg) +int from, to; +char *fname; +int apflg; +{ + FILE *fp; + int lin, err; + int lines; + long bytes; + char *str; + LINE *lptr; + + err = 0; + + lines = bytes = 0; + if (diag) printf("\"%s\" ", fname); + if ((fp = fopen(fname, (apflg ? "a" : "w"))) == NULL) { + printf("File open error.\n"); + return(ERR); + } + lptr = getptr(from); + for (lin = from; lin <= to; lin++) { + str = lptr->l_buff; + lines++; + bytes += strlen(str) + 1; + if (fputs(str, fp) == EOF) { + printf("File write error.\n"); + err++; + break; + } + fputc('\n', fp); + lptr = lptr->l_next; + } + if (diag) printf("%d lines %ld bytes\n", lines, bytes); + fclose(fp); + return(err); +} + +/* ed.c */ +/* Copyright 1987 Brian Beattie Rights Reserved. + * + * Permission to copy and/or distribute granted under the + * following conditions: + * + * 1). No charge may be made other than resonable charges + * for reproduction. + * + * 2). This notice must remain intact. + * + * 3). No further restrictions may be added. + * + */ +/* #include */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ +#include +jmp_buf env; + +LINE line0; +int curln = 0; +int lastln = 0; +char *inptr; +static char inlin[MAXLINE]; +int nflg, lflg; +int line1, line2, nlines; +extern char fname[]; +int version = 1; +int diag = 1; + +void intr(sig) +int sig; +{ + printf("?\n"); + longjmp(env, 1); +} + +int main(argc, argv) +int argc; +char **argv; +{ + int stat, i, doflush; + + set_buf(); + doflush = isatty(1); + + if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 0) { + diag = 0; + argc--; + argv++; + } + if (argc > 1) { + for (i = 1; i < argc; i++) { + if (doread(0, argv[i]) == 0) { + curln = 1; + strcpy(fname, argv[i]); + break; + } + } + } + while (1) { + setjmp(env); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) + { + signal(SIGINT, (sig_t) intr); /* Nick */ + } + + if (doflush) { + putchar(':'); + fflush(stdout); + } + + if (fgets(inlin, sizeof(inlin), stdin) == NULL) { + break; + } + if (*inlin == '!') { + for (inptr = inlin; *inptr != NL; inptr++); + *inptr = EOS; + System(inlin + 1); + continue; + } + inptr = inlin; + if (getlst() >= 0) + if ((stat = ckglob()) != 0) { + if (stat >= 0 && (stat = doglob()) >= 0) { + curln = stat; + continue; + } + } else { + if ((stat = docmd(0)) >= 0) { + if (stat == 1) doprnt(curln, curln); + continue; + } + } + if (stat == EOF) { + exit(0); + } + if (stat == FATAL) { + fputs("FATAL ERROR\n", stderr); + exit(1); + } + printf("?\n"); + } + return(0); +} + +/* egets.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int eightbit = 1; /* save eight bit */ +int nonascii, nullchar, truncated; +int egets(str, size, stream) +char *str; +int size; +FILE *stream; +{ + int c, count; + char *cp; + + for (count = 0, cp = str; size > count;) { + c = getc(stream); + if (c == EOF) { + *cp++ = '\n'; + *cp = EOS; + if (count) { + printf("[Incomplete last line]\n"); + } + return(count); + } + if (c == NL) { + *cp++ = c; + *cp = EOS; + return(++count); + } + if (c > 127) { + if (!eightbit) /* if not saving eighth bit */ + c = c & 127; /* strip eigth bit */ + nonascii++; /* count it */ + } + if (c) { + *cp++ = c; /* not null, keep it */ + count++; + } else + nullchar++; /* count nulls */ + } + str[count - 1] = EOS; + if (c != NL) { + printf("Truncating line.\n"); + truncated++; + while ((c = getc(stream)) != EOF) + if (c == NL) break; + } + return(count); +} + +/* esc.c */ +/* #include */ +/* #include "tools.h" */ + +/* Map escape sequences into their equivalent symbols. Returns the + * correct ASCII character. If no escape prefix is present then s + * is untouched and *s is returned, otherwise **s is advanced to point + * at the escaped character and the translated character is returned. + */ +int esc(s) +char **s; +{ + register int rval; + + + if (**s != ESCAPE) { + rval = **s; + } else { + (*s)++; + + switch (toupper(**s)) { + case '\000': rval = ESCAPE; break; + case 'S': rval = ' '; break; + case 'N': rval = '\n'; break; + case 'T': rval = '\t'; break; + case 'B': rval = '\b'; break; + case 'R': rval = '\r'; break; + default: rval = **s; break; + } + } + + return(rval); +} + +/* find.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int find(pat, dir) +TOKEN *pat; +int dir; +{ + int i, num; + char lin[MAXLINE]; + LINE *ptr; + + num = curln; + ptr = getptr(curln); + num = (dir ? nextln(num) : prevln(num)); + ptr = (dir ? ptr->l_next : ptr->l_prev); + for (i = 0; i < lastln; i++) { + if (num == 0) { + num = (dir ? nextln(num) : prevln(num)); + ptr = (dir ? ptr->l_next : ptr->l_prev); + } + strcpy(lin, ptr->l_buff); + strcat(lin, "\n"); + if (matchs(lin, pat, 0)) { + return(num); + } + num = (dir ? nextln(num) : prevln(num)); + ptr = (dir ? ptr->l_next : ptr->l_prev); + } + return(ERR); +} + +/* getfn.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +extern char fname[MAXFNAME]; +int nofname; + +char *getfn() +{ + static char file[256]; + char *cp; + + if (*inptr == NL) { + nofname = TRUE; + strcpy(file, fname); + } else { + nofname = FALSE; + while (*inptr == SP || *inptr == HT) inptr++; + + cp = file; + while (*inptr && *inptr != NL && *inptr != SP && *inptr != HT) { + *cp++ = *inptr++; + } + *cp = '\0'; + + if (strlen(file) == 0) { + printf("Bad file name.\n"); + return(NULL); + } + } + + if (strlen(file) == 0) { + printf("No file name.\n"); + return(NULL); + } + return(file); +} + +/* getlst.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int getlst() +{ + int num; + + line2 = 0; + for (nlines = 0; (num = getone()) >= 0;) { + line1 = line2; + line2 = num; + nlines++; + if (*inptr != ',' && *inptr != ';') break; + if (*inptr == ';') curln = num; + inptr++; + } + nlines = min(nlines, 2); + if (nlines == 0) line2 = curln; + if (nlines <= 1) line1 = line2; + + if (num == ERR) + return(num); + else + return(nlines); +} + +/* getnum.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int mark['z' - 'a' + 1]; + +int getnum(first) +int first; +{ + TOKEN *srchpat; + int num; + char c; + + while (*inptr == SP || *inptr == HT) inptr++; + + if (*inptr >= '0' && *inptr <= '9') { /* line number */ + for (num = 0; *inptr >= '0' && *inptr <= '9';) { + num = (num * 10) + *inptr - '0'; + inptr++; + } + return num; + } + switch (c = *inptr) { + case '.': + inptr++; + return(curln); + + case '$': + inptr++; + return(lastln); + + case '/': + case '?': + srchpat = optpat(); + if (*inptr == c) inptr++; + return(find(srchpat, c == '/' ? 1 : 0)); + + case '-': + case '+': + return(first ? curln : 1); + + case '\'': + inptr++; + if (*inptr < 'a' || *inptr > 'z') return(EOF); + + return mark[*inptr++ - 'a']; + + default: + return(first ? EOF : 1);/* unknown address */ + } +} + +/* getone.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +#define FIRST 1 +#define NOTFIRST 0 + +int getone() +{ + int c, i, num; + + if ((num = getnum(FIRST)) >= 0) { + while (1) { + while (*inptr == SP || *inptr == HT) inptr++; + + if (*inptr != '+' && *inptr != '-') break; + c = *inptr++; + + if ((i = getnum(NOTFIRST)) < 0) return(i); + + if (c == '+') { + num += i; + } else { + num -= i; + } + } + } + return(num > lastln ? ERR : num); +} + +/* getpat.c */ +/* #include */ +/* #include "tools.h" */ + +/* Translate arg into a TOKEN string */ +TOKEN * + getpat(arg) +char *arg; +{ + + return(makepat(arg, '\000')); +} + +/* getptr.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +LINE * + getptr(num) +int num; +{ + LINE *ptr; + int j; + + if (2 * num > lastln && num <= lastln) { /* high line numbers */ + ptr = line0.l_prev; + for (j = lastln; j > num; j--) ptr = ptr->l_prev; + } else { /* low line numbers */ + ptr = &line0; + for (j = 0; j < num; j++) ptr = ptr->l_next; + } + return(ptr); +} + +/* getrhs.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int getrhs(sub) +char *sub; +{ + if (inptr[0] == NL || inptr[1] == NL) /* check for eol */ + return(ERR); + + if (maksub(sub, MAXPAT) == NULL) return(ERR); + + inptr++; /* skip over delimter */ + while (*inptr == SP || *inptr == HT) inptr++; + if (*inptr == 'g') { + inptr++; + return(1); + } + return(0); +} + +/* gettxt.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +char * + gettxt(num) +int num; +{ + LINE *lin; + static char txtbuf[MAXLINE]; + + lin = getptr(num); + strcpy(txtbuf, lin->l_buff); + strcat(txtbuf, "\n"); + return(txtbuf); +} + +/* ins.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int ins(str) +char *str; +{ + char buf[MAXLINE], *cp; + LINE *new, *cur, *nxt; + + cp = buf; + while (1) { + if ((*cp = *str++) == NL) *cp = EOS; + if (*cp) { + cp++; + continue; + } + if ((new = (LINE *) malloc(sizeof(LINE) + strlen(buf))) == NULL) + return(ERR); /* no memory */ + + new->l_stat = 0; + strcpy(new->l_buff, buf); /* build new line */ + cur = getptr(curln); /* get current line */ + nxt = cur->l_next; /* get next line */ + relink(cur, new, new, nxt); /* add to linked list */ + relink(new, nxt, cur, new); + lastln++; + curln++; + + if (*str == EOS) /* end of line ? */ + return(1); + + cp = buf; + } +} + +/* join.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +extern int fchanged; + +int join(first, last) +int first, last; +{ + char buf[MAXLINE]; + char *cp = buf, *str; + int num; + + if (first <= 0 || first > last || last > lastln) return(ERR); + if (first == last) { + curln = first; + return 0; + } + for (num = first; num <= last; num++) { + str = gettxt(num); + + while (*str != NL && cp < buf + MAXLINE - 1) *cp++ = *str++; + + if (cp == buf + MAXLINE - 1) { + printf("line too long\n"); + return(ERR); + } + } + *cp++ = NL; + *cp = EOS; + del(first, last); + curln = first - 1; + ins(buf); + fchanged = TRUE; + return 0; +} + +/* makepat.c */ +/* #include */ +/* #include "tools.h" */ + +/* Make a pattern template from the strinng pointed to by arg. Stop + * when delim or '\000' or '\n' is found in arg. Return a pointer to + * the pattern template. + * + * The pattern template used here are somewhat different than those + * used in the "Software Tools" book; each token is a structure of + * the form TOKEN (see tools.h). A token consists of an identifier, + * a pointer to a string, a literal character and a pointer to another + * token. This last is 0 if there is no subsequent token. + * + * The one strangeness here is caused (again) by CLOSURE which has + * to be put in front of the previous token. To make this insertion a + * little easier, the 'next' field of the last to point at the chain + * (the one pointed to by 'tail) is made to point at the previous node. + * When we are finished, tail->next is set to 0. + */ +TOKEN * + makepat(arg, delim) +char *arg; +int delim; +{ + TOKEN *head, *tail, *ntok; + int error; + + /* Check for characters that aren't legal at the beginning of a template. */ + + if (*arg == '\0' || *arg == delim || *arg == '\n' || *arg == CLOSURE) + return(0); + + error = 0; + tail = head = NULL; + + while (*arg && *arg != delim && *arg != '\n' && !error) { + ntok = (TOKEN *) malloc(TOKSIZE); + ntok->lchar = '\000'; + ntok->next = 0; + + switch (*arg) { + case ANY: ntok->tok = ANY; break; + + case BOL: + if (head == 0) /* then this is the first symbol */ + ntok->tok = BOL; + else + ntok->tok = LITCHAR; + ntok->lchar = BOL; + break; + + case EOL: + if (*(arg + 1) == delim || *(arg + 1) == '\000' || + *(arg + 1) == '\n') { + ntok->tok = EOL; + } else { + ntok->tok = LITCHAR; + ntok->lchar = EOL; + } + break; + + case CLOSURE: + if (head != 0) { + switch (tail->tok) { + case BOL: + case EOL: + case CLOSURE: + return(0); + + default: + ntok->tok = CLOSURE; + } + } + break; + + case CCL: + + if (*(arg + 1) == NEGATE) { + ntok->tok = NCCL; + arg += 2; + } else { + ntok->tok = CCL; + arg++; + } + + if (ntok->bitmap = makebitmap(CLS_SIZE)) + arg = dodash(CCLEND, arg, ntok->bitmap); + else { + fprintf(stderr, "Not enough memory for pat\n"); + error = 1; + } + break; + + default: + if (*arg == ESCAPE && *(arg + 1) == OPEN) { + ntok->tok = OPEN; + arg++; + } else if (*arg == ESCAPE && *(arg + 1) == CLOSE) { + ntok->tok = CLOSE; + arg++; + } else { + ntok->tok = LITCHAR; + ntok->lchar = esc(&arg); + } + } + + if (error || ntok == 0) { + unmakepat(head); + return(0); + } else if (head == 0) { + /* This is the first node in the chain. */ + + ntok->next = 0; + head = tail = ntok; + } else if (ntok->tok != CLOSURE) { + /* Insert at end of list (after tail) */ + + tail->next = ntok; + ntok->next = tail; + tail = ntok; + } else if (head != tail) { + /* More than one node in the chain. Insert the + * CLOSURE node immediately in front of tail. */ + + (tail->next)->next = ntok; + ntok->next = tail; + } else { + /* Only one node in the chain, Insert the CLOSURE + * node at the head of the linked list. */ + + ntok->next = head; + tail->next = ntok; + head = ntok; + } + arg++; + } + + tail->next = 0; + return(head); +} + +/* maksub.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +char * + maksub(sub, subsz) +char *sub; +int subsz; +{ + int size; + char delim, *cp; + + size = 0; + cp = sub; + + delim = *inptr++; + for (size = 0; *inptr != delim && *inptr != NL && size < subsz; size++) { + if (*inptr == '&') { + *cp++ = DITTO; + inptr++; + } else if ((*cp++ = *inptr++) == ESCAPE) { + if (size >= subsz) return(NULL); + + switch (toupper(*inptr)) { + case NL: + *cp++ = ESCAPE; + break; + case 'S': + *cp++ = SP; + inptr++; + break; + case 'N': + *cp++ = NL; + inptr++; + break; + case 'T': + *cp++ = HT; + inptr++; + break; + case 'B': + *cp++ = BS; + inptr++; + break; + case 'R': + *cp++ = CR; + inptr++; + break; + case '0':{ + int i = 3; + *cp = 0; + do { + if (*++inptr < '0' || *inptr > '7') + break; + + *cp = (*cp << 3) | (*inptr - '0'); + } while (--i != 0); + cp++; + } break; + default: *cp++ = *inptr++; break; + } + } + } + if (size >= subsz) return(NULL); + + *cp = EOS; + return(sub); +} + +/* matchs.c */ +/* #include */ +/* #include "tools.h" */ + +/* Compares line and pattern. Line is a character string while pat + * is a pattern template made by getpat(). + * Returns: + * 1. A zero if no match was found. + * + * 2. A pointer to the last character satisfing the match + * if ret_endp is non-zero. + * + * 3. A pointer to the beginning of the matched string if + * ret_endp is zero. + * + * e.g.: + * + * matchs ("1234567890", getpat("4[0-9]*7), 0); + * will return a pointer to the '4', while: + * + * matchs ("1234567890", getpat("4[0-9]*7), 1); + * will return a pointer to the '7'. + */ +char * + matchs(line, pat, ret_endp) +char *line; +TOKEN *pat; +int ret_endp; +{ + + char *rval, *bptr; + char *line2; + TOKEN *pat2; + char c; + short ok; + + bptr = line; + + while (*line) { + + if (pat && pat->tok == LITCHAR) { + while (*line) { + pat2 = pat; + line2 = line; + if (*line2 != pat2->lchar) { + c = pat2->lchar; + while (*line2 && *line2 != c) ++line2; + line = line2; + if (*line2 == '\0') break; + } + ok = 1; + ++line2; + pat2 = pat2->next; + while (pat2 && pat2->tok == LITCHAR) { + if (*line2 != pat2->lchar) { + ok = 0; + break; + } + ++line2; + pat2 = pat2->next; + } + if (!pat2) { + if (ret_endp) + return(--line2); + else + return(line); + } else if (ok) + break; + ++line; + } + if (*line == '\0') return(0); + } else { + line2 = line; + pat2 = pat; + } + if ((rval = amatch(line2, pat2, bptr)) == 0) { + if (pat && pat->tok == BOL) break; + line++; + } else { + if (rval > bptr && rval > line) + rval--; /* point to last char matched */ + rval = ret_endp ? rval : line; + break; + } + } + return(rval); +} + +/* move.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int move(num) +int num; +{ + LINE *k0, *k1, *k2, *k3; + + if (line1 <= 0 || line2 < line1 || (line1 <= num && num <= line2)) + return(ERR); + k0 = getptr(prevln(line1)); + k1 = getptr(line1); + k2 = getptr(line2); + k3 = getptr(nextln(line2)); + + relink(k0, k3, k0, k3); + lastln -= line2 - line1 + 1; + + if (num > line1) num -= line2 - line1 + 1; + + curln = num + (line2 - line1 + 1); + + k0 = getptr(num); + k3 = getptr(nextln(num)); + + relink(k0, k1, k2, k3); + relink(k2, k3, k0, k1); + lastln += line2 - line1 + 1; + + return(1); +} + +int transfer(num) +int num; +{ + int mid, lin, ntrans; + + if (line1 <= 0 || line1 > line2) return(ERR); + + mid = num < line2 ? num : line2; + + curln = num; + ntrans = 0; + + for (lin = line1; lin <= mid; lin++) { + ins(gettxt(lin)); + ntrans++; + } + lin += ntrans; + line2 += ntrans; + + for (; lin <= line2; lin += 2) { + ins(gettxt(lin)); + line2++; + } + return(1); +} + +/* omatch.c */ +/* #include */ +/* #include "tools.h" */ + +/* Match one pattern element, pointed at by pat, with the character at + * **linp. Return non-zero on match. Otherwise, return 0. *Linp is + * advanced to skip over the matched character; it is not advanced on + * failure. The amount of advance is 0 for patterns that match null + * strings, 1 otherwise. "boln" should point at the position that will + * match a BOL token. + */ +int omatch(linp, pat, boln) +char **linp; +TOKEN *pat; +char *boln; +{ + + register int advance; + + advance = -1; + + if (**linp) { + switch (pat->tok) { + case LITCHAR: + if (**linp == pat->lchar) advance = 1; + break; + + case BOL: + if (*linp == boln) advance = 0; + break; + + case ANY: + if (**linp != '\n') advance = 1; + break; + + case EOL: + if (**linp == '\n') advance = 0; + break; + + case CCL: + if (testbit(**linp, pat->bitmap)) advance = 1; + break; + + case NCCL: + if (!testbit(**linp, pat->bitmap)) advance = 1; + break; + } + } + if (advance >= 0) *linp += advance; + + return(++advance); +} + +/* optpat.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +TOKEN *oldpat; + +TOKEN * + optpat() +{ + char delim, str[MAXPAT], *cp; + + delim = *inptr++; + cp = str; + while (*inptr != delim && *inptr != NL) { + if (*inptr == ESCAPE && inptr[1] != NL) *cp++ = *inptr++; + *cp++ = *inptr++; + } + + *cp = EOS; + if (*str == EOS) return(oldpat); + if (oldpat) unmakepat(oldpat); + oldpat = getpat(str); + return(oldpat); +} + +/* set.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +struct tbl { + char *t_str; + int *t_ptr; + int t_val; +} *t, tbl[] = { + + "number", &nflg, TRUE, + "nonumber", &nflg, FALSE, + "list", &lflg, TRUE, + "nolist", &lflg, FALSE, + "eightbit", &eightbit, TRUE, + "noeightbit", &eightbit, FALSE, + 0 +}; + +int set() +{ + char word[16]; + int i; + + inptr++; + if (*inptr != 't') { + if (*inptr != SP && *inptr != HT && *inptr != NL) return(ERR); + } else + inptr++; + + if (*inptr == NL) return(show()); + /* Skip white space */ + while (*inptr == SP || *inptr == HT) inptr++; + + for (i = 0; *inptr != SP && *inptr != HT && *inptr != NL;) + word[i++] = *inptr++; + word[i] = EOS; + for (t = tbl; t->t_str; t++) { + if (strcmp(word, t->t_str) == 0) { + *t->t_ptr = t->t_val; + return(0); + } + } + return(0); +} + +int show() +{ + extern int version; + + printf("ed version %d.%d\n", version / 100, version % 100); + printf("number %s, list %s\n", nflg ? "ON" : "OFF", lflg ? "ON" : "OFF"); + return(0); +} + +/* setbuf.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +void relink(a, x, y, b) +LINE *a, *x, *y, *b; +{ + x->l_prev = a; + y->l_next = b; +} + +void clrbuf() +{ + del(1, lastln); +} + +void set_buf() +{ + relink(&line0, &line0, &line0, &line0); + curln = lastln = 0; +} + +/* subst.c */ +/* #include */ +/* #include "tools.h" */ +/* #include "ed.h" */ + +int subst(pat, sub, gflg, pflag) +TOKEN *pat; +char *sub; +int gflg, pflag; +{ + int lin, chngd, nchngd; + char *txtptr, *txt; + char *lastm, *m, *new, buf[MAXLINE]; + + if (line1 <= 0) return(ERR); + nchngd = 0; /* reset count of lines changed */ + for (lin = line1; lin <= line2; lin++) { + txt = txtptr = gettxt(lin); + new = buf; + chngd = 0; + lastm = NULL; + while (*txtptr) { + if (gflg || !chngd) + m = amatch(txtptr, pat, txt); + else + m = NULL; + if (m != NULL && lastm != m) { + chngd++; + new = catsub(txtptr, m, sub, new, + buf + MAXLINE); + lastm = m; + } + if (m == NULL || m == txtptr) { + *new++ = *txtptr++; + } else { + txtptr = m; + } + } + if (chngd) { + if (new >= buf + MAXLINE) return(ERR); + *new++ = EOS; + del(lin, lin); + ins(buf); + nchngd++; + if (pflag) doprnt(curln, curln); + } + } + if (nchngd == 0 && !gflg) { + return(ERR); + } + return(nchngd); +} + +/* System.c */ +#define SHELL "/bin/sh" +#define SHELL2 "/usr/bin/sh" + +int System(c) +char *c; +{ + int pid, status; + + switch (pid = fork()) { + case -1: + return -1; + case 0: + execl(SHELL, "sh", "-c", c, (char *) 0); + execl(SHELL2, "sh", "-c", c, (char *) 0); + exit(-1); + default: while (wait(&status) != pid); +} + return status; +} + +/* unmkpat.c */ +/* #include */ +/* #include "tools.h" */ + +/* Free up the memory usde for token string */ +void unmakepat(head) +TOKEN *head; +{ + + register TOKEN *old_head; + + while (head) { + switch (head->tok) { + case CCL: + case NCCL: + free(head->bitmap); + /* Fall through to default */ + + default: + old_head = head; + head = head->next; + free((char *) old_head); + break; + } + } +} diff --git a/src/simple/expr.c b/src/simple/expr.c new file mode 100755 index 00000000..961ca408 --- /dev/null +++ b/src/simple/expr.c @@ -0,0 +1,648 @@ +/* expr - expression evaluator for shell Author: Peter S. Housel */ + +#include +#include +#include +#include + +struct value { + long numval; /* numeric value */ + int nf_valid; /* "numeric value field valid" flag */ + char *strval; /* string value */ +}; + +#define numresult(valp,number) \ + (((valp)->nf_valid = 1), \ + ((valp)->strval = NULL), \ + ((valp)->numval = (number))) + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void expr1, (struct value *valp)); +_PROTOTYPE(void expr2, (struct value *valp)); +_PROTOTYPE(void expr3, (struct value *valp)); +_PROTOTYPE(void expr4, (struct value *valp)); +_PROTOTYPE(void expr5, (struct value *valp)); +_PROTOTYPE(void expr6, (struct value *valp)); +_PROTOTYPE(void expr7, (struct value *valp)); +_PROTOTYPE(int nullz, (struct value *valp)); +_PROTOTYPE(int numvalue, (struct value *valp)); +_PROTOTYPE(char *strvalue, (struct value *valp)); +_PROTOTYPE(char *strsave, (char *string)); +_PROTOTYPE(void invalid, (char *err)); +_PROTOTYPE(void docolon, (struct value *match, struct value *pattern)); +_PROTOTYPE(void rcomp, (char *regexp)); +_PROTOTYPE(void rmatch, (char *str)); +_PROTOTYPE(char *rtry, (char *str, unsigned char **pcp)); +_PROTOTYPE(char *tryone, (char *str, unsigned char **pcp)); + +char *progname; +char **argp; +char NUMARG[] = "numeric argument required"; + +int main(argc, argv) +int argc; +char *argv[]; +{ + struct value val0; + + progname = argv[0]; + argp = &argv[1]; + expr1(&val0); + if (*argp != NULL) invalid("syntax error"); + (void) puts(strvalue(&val0)); + return(nullz(&val0)); +} + +/* Yet Another recursive descent parser. */ +void expr1(valp) +struct value *valp; +{ + struct value val1; + + expr2(valp); + + while (*argp != NULL) { + if (strcmp(*argp, "|") == 0) { + ++argp; + expr2(&val1); + if (nullz(valp)) + *valp = val1; + else; /* return the first arg (already in *valp) */ + } else + break; + } +} + +void expr2(valp) +struct value *valp; +{ + struct value val1; + + expr3(valp); + + while (*argp != NULL) { + if (strcmp(*argp, "&") == 0) { + ++argp; + expr3(&val1); + if (nullz(valp) && nullz(&val1)) + numresult(valp, 0); + else; /* return the first arg (already in *valp) */ + } else + break; + } +} + +/* Save source code lines but not object code, unfortunately. */ + +#define RELOP0 \ + ++argp; \ + expr4(&val1) + +#define RELOP1(OP) \ + if(numvalue(valp) && numvalue(&val1)) \ + numresult(valp, valp->numval OP val1.numval) +#define RELOP2(OP) \ + else \ + numresult(valp, strcmp(strvalue(valp), strvalue(&val1)) OP 0) + +void expr3(valp) +struct value *valp; +{ + struct value val1; + + expr4(valp); + + while (*argp != NULL) { + if (strcmp(*argp, "<") == 0) { + RELOP0; + RELOP1(<); + RELOP2(<); + } else if (strcmp(*argp, "<=") == 0) { + RELOP0; + RELOP1(<=); + RELOP2(<=); + } else if (strcmp(*argp, "=") == 0) { + RELOP0; + RELOP1(==); + RELOP2(==); + } else if (strcmp(*argp, "!=") == 0) { + RELOP0; + RELOP1(!=); + RELOP2(!=); + } else if (strcmp(*argp, ">=") == 0) { + RELOP0; + RELOP1(>=); + RELOP2(>=); + } else if (strcmp(*argp, ">") == 0) { + RELOP0; + RELOP1(>); + RELOP2(>); + } else + break; + } +} + +#define BINOP(NEXT,OP) \ + ++argp; \ + NEXT(&val1); \ + if(!numvalue(valp) || !numvalue(&val1)) \ + invalid(NUMARG); \ + else \ + numresult(valp, valp->numval OP val1.numval); \ + +void expr4(valp) +struct value *valp; +{ + struct value val1; + + expr5(valp); + + while (*argp != NULL) { + if (strcmp(*argp, "+") == 0) { + BINOP(expr5, +) + } else if (strcmp(*argp, "-") == 0) { + BINOP(expr5, -) + } else + break; + } +} + +void expr5(valp) +struct value *valp; +{ + struct value val1; + + expr6(valp); + + while (*argp != NULL) { + if (strcmp(*argp, "*") == 0) { + BINOP(expr6, *) + } else if (strcmp(*argp, "/") == 0) { + ++argp; + expr6(&val1); + if (!numvalue(valp) || !numvalue(&val1)) + invalid(NUMARG); + else { + if (val1.numval == 0) invalid("division by zero"); + numresult(valp, valp->numval / val1.numval); + } + } else if (strcmp(*argp, "%") == 0) { + ++argp; + expr6(&val1); + if (!numvalue(valp) || !numvalue(&val1)) + invalid(NUMARG); + else { + if (val1.numval == 0) invalid("division by zero"); + numresult(valp, valp->numval % val1.numval); + } + } else + break; + } +} + +void expr6(valp) +struct value *valp; +{ + struct value val1; + + expr7(valp); + + while (*argp != NULL) { + if (strcmp(*argp, ":") == 0) { + ++argp; + expr7(&val1); +#ifndef NOCOLON + docolon(valp, &val1); +#else + valp->nf_valid = 0; + valp->strval = NULL; +#endif + } else + break; + } +} + +void expr7(valp) +struct value *valp; +{ + if (*argp == NULL) + invalid("missing argument(s)"); + else if (strcmp(*argp, "(") == 0) { + ++argp; + expr1(valp); + if (strcmp(*argp++, ")") != 0) invalid("unbalanced parentheses"); + } else { + valp->nf_valid = 0; + valp->strval = *argp++; + } +} + +/* Return 1 if the argument is zero (numeric) or null (string */ +int nullz(valp) +struct value *valp; +{ + if (numvalue(valp)) return(valp->numval == 0); + + return(strlen(strvalue(valp)) == 0); +} + +/* Return 1 if the argument is a valid number, insuring that the nf_valid + * and numval fields are set properly. Does the string-to-number + * conversion if nf_valid is false. + */ +int numvalue(valp) +struct value *valp; +{ + register char *p; + int sign = 0, digits = 0; + /*unsigned*/ long num = 0; + + if (valp->nf_valid) return 1; + + if ((p = valp->strval) == NULL) return 0; + + if (*p == '-') { + ++p; + sign = 1; + } + while (isdigit(*p)) { + num = num * 10 + (*p++ - '0'); + digits = 1; + } + + if (!digits || *p != '\0') return 0; + + valp->numval = sign ? -num : num; + valp->nf_valid = 1; + return 1; +} + +/* Return the string value of the given argument. If there is only a + * numeric value, convert it to a string + */ +char *strvalue(valp) +struct value *valp; +{ + char numbuf[30]; + register char *p; + /*unsigned*/ long num; + int sign = 0; + + if (!valp->nf_valid) return(valp->strval != NULL) ? valp->strval : ""; + + p = numbuf + sizeof numbuf; + *--p = '\0'; + + if (valp->numval < 0) { + num = -(valp->numval); + sign = 1; + } else + num = valp->numval; + + do { + *--p = '0' + (num % 10); + num /= 10; + } while (num); + + if (sign) *--p = '-'; + + return(valp->strval = strsave(p)); +} + +/* Save the given string in its own allocated memory and return a pointer + * to that memory. + */ +char *strsave(string) +char *string; +{ + char *p; + + if ((p = (char *)malloc(strlen(string) + 1)) == NULL) invalid("out of memory"); + + (void) strcpy(p, string); + + return p; +} + +/* Print error message and exit. */ +void invalid(err) +char *err; +{ + (void) fputs(progname, stderr); + (void) fputs(": ", stderr); + (void) fputs(err, stderr); + (void) putc('\n', stderr); + exit(2); +} + +#ifndef NOCOLON + +#include + +#define RMIN (UCHAR_MAX-8) /* >= reserved as opcodes */ +#define RESC (UCHAR_MAX-8) /* for escaping opcodes */ +#define RDOT (UCHAR_MAX-7) /* match any character */ +#define ROPEN (UCHAR_MAX-6) /* opening \( */ +#define RCLOSE (UCHAR_MAX-5) /* closing \) */ +#define RSTAR (UCHAR_MAX-4) /* Kleene closure */ +#define RCLASS (UCHAR_MAX-3) /* character class */ +#define RBACK (UCHAR_MAX-2) /* \digit reference */ +#define REND (UCHAR_MAX-1) /* end of program */ + +#define RABEGIN 0x01 /* match anchored at BOL (^) */ +#define RAEND 0x02 /* match anchored at EOL ($) */ +#define RSELECT 0x04 /* \(...\) selection op used */ + +#define PROGLENGTH 1024 /* bytes reserved for r-programs */ + +#define CLASS_BYTES ((CHAR_MAX - CHAR_MIN) / CHAR_BIT) + +unsigned char rprogram[PROGLENGTH]; /* regexp program storage */ +unsigned int rflags = RABEGIN; /* regexp program context */ + +char *rbegins[10]; /* pointers to \( beginnings */ +char *rends[10]; /* pointers to \) endings */ +int rlevel; /* \(...\) level */ + +/* Compile the regexp, match it against the string, and return the + * proper result (a string if \(...\) used, and the match length otherwise. + */ +void docolon(match, pattern) +struct value *match, *pattern; +{ + rcomp(strvalue(pattern)); + + rmatch(strvalue(match)); + + if (rflags & RSELECT) { + match->nf_valid = 0; + if (rends[0] == rbegins[0] || rends[1] == NULL) { + match->strval = NULL; + } else { + *(rends[1]) = '\0'; /* semi-nasty */ + match->strval = rbegins[1]; + } + } else { + numresult(match, rends[0] - rbegins[0]); + } +} + +/* Compile an ed(1)-syntax regular-expression into the rprogram[] array. */ +void rcomp(regexp) +register char *regexp; +{ + char c; /* current regexp character */ + char first, last; /* limits of character class */ + unsigned char *starable; /* last "starable" variable */ + unsigned char *rpc; /* pointer to next program storage byte */ + int negate; /* character class negated */ + int i; /* loop counter and such */ + int pstack[9]; /* \(...\) nesting stack */ + int pstackp = 0; /* stack pointer for nesting stack */ + int pclosed[10]; /* flags indicating \(...\) closed */ + + rpc = &rprogram[0]; + starable = NULL; + + for (i = 1; i < 10; ++i) pclosed[i] = 0; + + if (*regexp == '^') { + rflags |= RABEGIN; /* not needed, as it turns out */ + ++regexp; + } + while ((c = *regexp++)) { + if ((rpc - rprogram) >= PROGLENGTH - 2 - CLASS_BYTES) + invalid("regular expression program too long"); + + switch (c) { + case '.': + starable = rpc; + *rpc++ = RDOT; + break; + case '\\': + if (isdigit(*regexp)) { + if (!pclosed[*regexp - '0']) + invalid("reference to unclosed/nonexistent \\(...\\) pair"); + starable = NULL; + *rpc++ = RBACK; + *rpc++ = *regexp++ - '0'; + } else if (*regexp == '(') { + starable = NULL; + ++regexp; + rflags |= RSELECT; + if ((i = ++rlevel) > 9) + invalid("too many \\(...\\) levels"); + pstack[pstackp++] = i; + *rpc++ = ROPEN; + *rpc++ = i; + break; + } else if (*regexp == ')') { + starable = NULL; + ++regexp; + if (pstackp == 0) + invalid("\\(...\\) pairs don't balance"); + i = pstack[--pstackp]; + *rpc++ = RCLOSE; + *rpc++ = i; + pclosed[i] = 1; + break; + } else if ((unsigned char) *regexp >= RMIN) { + starable = rpc; + *rpc++ = RESC; + *rpc++ = *regexp++; + break; + } else { + starable = rpc; + *rpc++ = *regexp++; + break; + } + case '$': + if (*regexp == '\0') { + rflags |= RAEND; + break; + } else { + starable = rpc; + *rpc++ = '$'; + break; + } + case '*': + if (starable == NULL) { + starable = rpc; + *rpc++ = '*'; + break; + } else { + memmove(starable + 1, starable, (size_t)(rpc - starable)); + *starable = RSTAR; + starable = NULL; + ++rpc; + break; + } + case '[': + negate = 0; + starable = rpc; + *rpc++ = RCLASS; + if (*regexp == '^') { + ++regexp; + negate = 1; + } + for (i = 0; i < CLASS_BYTES; ++i) rpc[i] = 0; + do { + first = *regexp++; + if (*regexp == '-' && regexp[1] != ']' + && regexp[1] > first) { + ++regexp; + last = *regexp++; + for (i = first; i < last; ++i) { + rpc[(i - CHAR_MIN) / CHAR_BIT] |= + 1 << ((i - CHAR_MIN) % CHAR_BIT); + } + } else { + rpc[(first - CHAR_MIN) / CHAR_BIT] |= + 1 << ((first - CHAR_MIN) % CHAR_BIT); + } + } while (*regexp && *regexp != ']'); + if (*regexp != ']') invalid("unterminated character class"); + ++regexp; + if (negate) for (i = 0; i < CLASS_BYTES; ++i, ++rpc) + *rpc = ~*rpc; + else + rpc += CLASS_BYTES; + break; + default: + if ((unsigned char) c >= RMIN) { + starable = rpc; + *rpc++ = RESC; + *rpc++ = c; + break; + } else { + starable = rpc; + *rpc++ = c; + break; + } + } + } + if (pstackp != 0) invalid("\\(...\\) pairs don't balance"); + *rpc = REND; +} + +/* It turns out that expr regular expressions have an implicit + * '^' prepended, and therefore RABEGIN is always on. It seemed + * a waste to delete the code after discovering this, however. + */ +void rmatch(str) +char *str; +{ + char *end; + unsigned char *rpc; + + rends[0] = rbegins[0] = str; + + if (rflags & RABEGIN) { + rpc = &rprogram[0]; + if ((end = rtry(str, &rpc)) != NULL) rends[0] = end; + } else { + while (*str) { + rpc = &rprogram[0]; + end = rtry(str, &rpc); + if (end != NULL && (end - str) > (rends[0] - rbegins[0])) { + rbegins[0] = str; /* longest match wins */ + rends[0] = end; + } + ++str; + } + } + +} + +/* Try to match str to program from *pcp on */ +char *rtry(str, pcp) +char *str; +unsigned char **pcp; +{ + char *nstr; + + while (*str && **pcp != REND) { + if ((nstr = tryone(str, pcp)) == NULL) return NULL; + str = nstr; + } + + while (**pcp == RCLOSE) { + rends[*(*pcp + 1)] = str; + *pcp += 2; + } + + if (**pcp != REND) return NULL; + + if ((rflags & RAEND) && *str != '\0') return NULL; + + return str; +} + +/* Try to match one regular expression operator */ +char *tryone(str, pcp) +char *str; +unsigned char **pcp; +{ + char *ret = NULL; + unsigned char *npc; + char *p, *q; + +again: + switch (**pcp) { + case RESC: + if (*str == *(*pcp + 1)) ret = str + 1; + *pcp += 2; + break; + default: + if (*str == **pcp) ret = str + 1; + *pcp += 1; + break; + case RDOT: + if (*str != '\0') ret = str + 1; + *pcp += 1; + break; + case RCLASS: + if (*str != '\0' + && ((*pcp + 1)[(*str - CHAR_MIN) / CHAR_BIT] + & (1 << ((*str - CHAR_MIN) % CHAR_BIT)))) { + ret = str + 1; + } + *pcp += CLASS_BYTES + 1; + break; + case ROPEN: + rbegins[*(*pcp + 1)] = str; + *pcp += 2; + goto again; + case RCLOSE: + rends[*(*pcp + 1)] = str; + *pcp += 2; + goto again; + case RBACK: + p = rbegins[*(*pcp + 1)]; + q = rends[*(*pcp + 1)]; + *pcp += 2; + while (p < q) + if (*p++ != *str++) return NULL; + ret = str; + break; + case RSTAR: + *pcp += 1; + p = str; + while (npc = *pcp, tryone(p, &npc) != NULL) ++p; + *pcp = npc; + while (p >= str + && (npc = *pcp, (ret = rtry(p, &npc)) == NULL)) + --p; + *pcp = npc; + break; + case REND: ret = str; +} + + return ret; +} + +#endif /* !NOCOLON */ diff --git a/src/simple/false.c b/src/simple/false.c new file mode 100755 index 00000000..2f674048 --- /dev/null +++ b/src/simple/false.c @@ -0,0 +1,6 @@ +/* false.c + */ +int main() { + return 1; +} + \ No newline at end of file diff --git a/src/simple/fgrep.c b/src/simple/fgrep.c new file mode 100755 index 00000000..66c2b0c1 --- /dev/null +++ b/src/simple/fgrep.c @@ -0,0 +1,358 @@ +/* fgrep - fast grep Author: Bert Gijsbers */ + +/* Copyright (c) 1991 by Bert Gijsbers. All rights reserved. + * Permission to use and redistribute this software is hereby granted provided + * that this copyright notice remains intact and that any modifications are + * clearly marked as such. + * + * syntax: + * fgrep -chlnsv <[-e string] ... [-f file] ... | string> [file] ... + * options: + * -c : print the number of matching lines + * -h : don't print file name headers if more than one file + * -l : print only the file names of the files containing a match + * -n : print line numbers + * -s : don't print, return status only + * -v : reverse, lines not containing one of the strings match + * -e string : search for this string + * -f file : file contains strings to search for + * notes: + * Options are processed by getopt(3). + * Multiple strings per command line are supported, eg. + * fgrep -e str1 -e str2 *.c + * Instead of a filename - is allowed, meaning standard input. + */ + +#include +#include +#include +#include +#include +#include + +#define MAX_STR_LEN 256 /* maximum length of strings to search for */ +#define BYTE 0xFF /* convert from char to int */ +#define READ_SIZE 4096 /* read() request size */ +#define BUF_SIZE (2*READ_SIZE) /* size of buffer */ + +typedef struct test_str { + struct test_str *next; /* linked list */ + char *str; /* string to be found */ + char *str_end; /* points to last character */ + int len; /* string length */ + char *bufp; /* pointer into input buffer */ + unsigned char table[256]; /* table for Boyer-Moore algorithm */ +} test_str; + +test_str *strings; +char *prog_name; +int cflag, hflag, lflag, nflag, sflag, vflag; +unsigned line_num; /* line number in current file */ + +int fd_in, eof_seen; /* file descriptor for input and eof status */ +char input_buffer[BUF_SIZE + 2];/* buffer + sentinel margin */ +#define buffer (&input_buffer[2]) + +/* Pointers into the input buffer */ +char *input; /* points to current input char */ +char *max_input; /* points to first invalid char */ +char *buf_end; /* points to first char not read */ + +/* Error messages */ +char no_mem[] = "not enough memory"; +char no_arg[] = "argument missing"; + +extern char *optarg; +extern int optind; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(char *search_str, (test_str * ts)); +_PROTOTYPE(int fill_buffer, (void)); +_PROTOTYPE(void failure, (char *mesg)); +_PROTOTYPE(void file_open, (void)); +_PROTOTYPE(void usage, (void)); +_PROTOTYPE(char *get_line, (void)); +_PROTOTYPE(void string_file, (void)); +_PROTOTYPE(void add_string, (char *str)); +_PROTOTYPE(int getopt, (int argc, char **argv, char *optstring)); + +int main(argc, argv) +int argc; +char **argv; +{ + char *line; + int c; + unsigned count; /* number of matching lines in current file */ + unsigned found_one = 0; /* was there any match in any file at all ? */ + +#ifdef noperprintf + noperprintf(stdout); +#else + static char outbuf[BUFSIZ]; + + setvbuf(stdout, outbuf, _IOFBF, sizeof outbuf); +#endif + + prog_name = argv[0]; + if (argc == 1) usage(); + while ((c = getopt(argc, argv, "ce:f:hlnsv")) != EOF) { + switch (c) { + case 'c': cflag++; break; + case 'e': add_string(optarg); break; + case 'f': string_file(); break; + case 'h': hflag++; break; + case 'l': lflag++; break; + case 'n': nflag++; break; + case 's': sflag++; break; + case 'v': vflag++; break; + default: usage(); break; + } + } + + /* If no -e or -f option is used take a string from the command line. */ + if (strings == (test_str *) NULL) { + if (optind == argc) failure(no_arg); + add_string(argv[optind++]); + } + if (argc - optind < 2) + hflag++; /* don't print filenames if less than two + * files */ + + /* Handle every matching line according to the flags. */ + do { + optarg = argv[optind]; + file_open(); + count = 0; + while ((line = get_line()) != (char *) NULL) { + count++; + if (sflag) return 0; + if (lflag) { + printf("%s\n", optarg); + fflush(stdout); + break; + } + if (cflag) continue; + if (hflag == 0) printf("%s:", optarg); + if (nflag) printf("%u:", line_num); + do { + putchar(*line); + } while (++line < input); + fflush(stdout); + } + found_one |= count; + if (cflag) { + if (hflag == 0) printf("%s: ", optarg); + printf("%u\n", count); + fflush(stdout); + } + close(fd_in); + } while (++optind < argc); + + /* Exit nonzero if no match is found. */ + return found_one ? 0 : 1; +} + +void usage() +{ + fprintf(stderr, + "usage: %s -chlnsv <[-e string] ... [-f file] ... | string> [file] ...\n", + prog_name); + exit(2); +} + +void failure(mesg) +char *mesg; +{ + fprintf(stderr, "%s: %s\n", prog_name, mesg); + exit(1); +} + +/* Add a string to search for to the global linked list `strings'. */ +void add_string(str) +char *str; +{ + test_str *ts; + int len; + + if (str == (char *) NULL || (len = strlen(str)) == 0) return; + if (len > MAX_STR_LEN) failure("string too long"); + if ((ts = (test_str *) malloc(sizeof(*ts))) == (test_str *) NULL) + failure(no_mem); + + /* Initialize Boyer-Moore table. */ + memset(ts->table, len, sizeof(ts->table)); + ts->len = len; + ts->str = str; + ts->str_end = str + len - 1; + for (; --len >= 0; str++) ts->table[*str & BYTE] = len; + + /* Put it on the list */ + ts->next = strings; + strings = ts; +} + +/* Open a file for reading. Initialize input buffer pointers. */ +void file_open() +{ + /* Use stdin if no file arguments are given on the command line. */ + if (optarg == (char *) NULL || strcmp(optarg, "-") == 0) { + fd_in = 0; + optarg = "stdin"; + } else if ((fd_in = open(optarg, O_RDONLY)) == -1) { + fprintf(stderr, "%s: can't open %s\n", prog_name, optarg); + exit(1); + } + input = max_input = buf_end = buffer; + buffer[-1] = '\n'; /* sentinel */ + eof_seen = 0; + line_num = 0; +} + +/* Move any leftover characters to the head of the buffer. + * Read characters into the rest of the buffer. + * Round off the available input to whole lines. + * Return the number of valid input characters. + */ +int fill_buffer() +{ + char *bufp; + int size; + + if (eof_seen) return 0; + + size = buf_end - max_input; + memmove(buffer, max_input, size); + bufp = &buffer[size]; + + do { + if ((size = read(fd_in, bufp, READ_SIZE)) <= 0) { + if (size != 0) failure("read error"); + eof_seen++; + if (bufp == buffer) /* no input left */ + return 0; + /* Make sure the last char of a file is '\n'. */ + *bufp++ = '\n'; + break; + } + bufp += size; + } while (bufp - buffer < READ_SIZE && bufp[-1] != '\n'); + + buf_end = bufp; + while (*--bufp != '\n'); + if (++bufp == buffer) { + /* Line too long. */ + *buf_end++ = '\n'; + bufp = buf_end; + } + max_input = bufp; + input = buffer; + + return max_input - buffer; +} + +/* Read strings from a file. Give duplicates to add_string(). */ +void string_file() +{ + char *str, *p; + + file_open(); + while (input < max_input || fill_buffer() > 0) { + p = (char *) memchr(input, '\n', BUF_SIZE); + *p++ = '\0'; + if ((str = (char *) malloc(p - input)) == (char *) NULL) + failure(no_mem); + memcpy(str, input, p - input); + add_string(str); + input = p; + } + close(fd_in); +} + +/* Scan the rest of the available input for a string using Boyer-Moore. + * Return a pointer to the match or a pointer beyond end of input if no match. + * Record how far the input is scanned. + */ +char *search_str(ts) +test_str *ts; +{ + char *bufp, *prevbufp, *s; + + bufp = input + ts->len - 1; + while (bufp < max_input) { + prevbufp = bufp; + bufp += ts->table[*bufp & BYTE]; + if (bufp > prevbufp) continue; + s = ts->str_end; + do { + if (s == ts->str) { /* match found */ + ts->bufp = bufp; + return bufp; + } + } while (*--bufp == *--s); + bufp = prevbufp + 1; + } + ts->bufp = bufp; + + return bufp; +} + +/* Return the next line in which one of the strings occurs. + * Or, if the -v option is used, the next line without a match. + * Or NULL on EOF. + */ +char *get_line() +{ + test_str *ts; + char *match, *line; + + /* Loop until a line is found. */ + while (1) { + if (input >= max_input && fill_buffer() == 0) { /* EOF */ + line = (char *) NULL; + break; + } + + /* If match is still equal to max_input after the next loop + * then no match is found. */ + match = max_input; + ts = strings; + do { + if (input == buffer) { + if (search_str(ts) < match) match = ts->bufp; + } else if (ts->bufp < match) { + if (ts->bufp >= input || search_str(ts) < match) + match = ts->bufp; + } + } while ((ts = ts->next) != (test_str *) NULL); + + /* Determine if and in what line a match is found. Only do + * line number counting if it is necessary or very easy. */ + if (vflag) { + line_num++; + line = input; + input = 1 + (char *) memchr(line, '\n', BUF_SIZE); + if (input <= match) break; /* no match in current line */ + } else if (nflag) { + do { + line_num++; + line = input; + input = 1 + (char *) memchr(line, '\n', BUF_SIZE); + } while (input < match || + (input == match && match < max_input)); + if (match < max_input) break; /* match found */ + } else if (match < max_input) { + /* Match found. */ + for (line = match; *--line != '\n';); + line++; + input = 1 + (char *) memchr(match, '\n', BUF_SIZE); + break; + } else + input = max_input; + } + + return line; +} diff --git a/src/simple/file.c b/src/simple/file.c new file mode 100755 index 00000000..2982ecf8 --- /dev/null +++ b/src/simple/file.c @@ -0,0 +1,285 @@ +/* file - report on file type. Author: Andy Tanenbaum */ +/* Magic number detection changed to look-up table 08-Jan-91 - ajm */ + +#include +#include +#include +#include +#include +#include + +#define BLOCK_SIZE 1024 + +#define XBITS 00111 /* rwXrwXrwX (x bits in the mode) */ +#define ENGLISH 25 /* cutoff for determining if text is Eng. */ +unsigned char buf[BLOCK_SIZE]; + +struct info { + int execflag; /* 1 == ack executable, 2 == gnu executable, + * 3 == core */ + unsigned char magic[4]; /* First four bytes of the magic number */ + unsigned char mask[4]; /* Mask to apply when matching */ + char *description; /* What it means */ +} table[] = { + 0x00, 0xc3, 0x10, 0x01, 0x00, 0xff, 0xff, 0xff, 0x00, + "UZIX MSX executable file", + 0x00, 0xe9, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + "UZIX PC executable file", + 0x00, 0x1f, 0x9d, 0x8d, 0x00, 0xff, 0xff, 0xff, 0x00, + "13-bit compressed file", + 0x00, 0x1f, 0x9d, 0x90, 0x00, 0xff, 0xff, 0xff, 0x00, + "16-bit compressed file", + 0x00, 0x65, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + "MINIX-PC bcc archive", + 0x00, 0x2c, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + "ACK object archive", + 0x00, 0x65, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + "MINIX-PC ack archive", + 0x00, 0x47, 0x6e, 0x75, 0x20, 0xff, 0xff, 0xff, 0xff, + "MINIX-68k gnu archive", + 0x00, 0x21, 0x3c, 0x61, 0x72, 0xff, 0xff, 0xff, 0xff, + "MINIX-PC gnu archive", + 0x00, 0x01, 0x02, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + "ACK object file", + 0x00, 0xa3, 0x86, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + "MINIX-PC bcc object file", + 0x00, 0x00, 0x00, 0x01, 0x07, 0xff, 0xff, 0xff, 0xff, + "MINIX-68k gnu object file", + 0x00, 0x07, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + "MINIX-PC gnu object file", + 0x01, 0x01, 0x03, 0x00, 0x04, 0xff, 0xff, 0x00, 0xff, + "MINIX-PC 16-bit executable", + 0x01, 0x01, 0x03, 0x00, 0x10, 0xff, 0xff, 0x00, 0xff, + "MINIX-PC 32-bit executable", + 0x01, 0x04, 0x10, 0x03, 0x01, 0xff, 0xff, 0xff, 0xff, + "MINIX-68k old style executable", + 0x01, 0x01, 0x03, 0x10, 0x0b, 0xff, 0xff, 0xff, 0xff, + "MINIX-68k new style executable", + 0x02, 0x0b, 0x01, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + "MINIX-PC 32-bit gnu executable combined I & D space", + 0x02, 0x00, 0x00, 0x0b, 0x01, 0xff, 0xff, 0xff, 0xff, + "MINIX-68k gnu executable", + 0x03, 0x82, 0x12, 0xC4, 0xC0, 0xff, 0xff, 0xff, 0xff, + "core file", +}; + +int tabsize = sizeof(table) / sizeof(struct info); +int L_flag; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void file, (char *name)); +_PROTOTYPE(void do_strip, (int type)); +_PROTOTYPE(void usage, (void)); + +int main(argc, argv) +int argc; +char *argv[]; +{ +/* This program uses some heuristics to try to guess about a file type by + * looking at its contents. + */ + int c, i; + + L_flag= 0; + while ((c= getopt(argc, argv, "L?")) != -1) + { + switch(c) + { + case 'L': + L_flag= 1; + break; + case '?': + usage(); + default: + fprintf(stderr, "file: panic getopt failed\n"); + exit(1); + } + } + if (optind >= argc) usage(); + for (i = optind; i < argc; i++) file(argv[i]); + return(0); +} + +void file(name) +char *name; +{ + int i, fd, n, mode, nonascii, special, funnypct, etaoins; + int j; + long engpct; + int c; + struct stat st_buf; + + printf("%s: ", name); + +#ifdef S_IFLNK + if (!L_flag) + n = lstat(name, &st_buf); + else + n = stat(name, &st_buf); +#else + n = stat(name, &st_buf); +#endif + if (n < 0) { + printf("cannot stat\n"); + return; + } + mode = st_buf.st_mode; + + /* Check for directories and special files. */ + if (S_ISDIR(mode)) { + printf("directory\n"); + return; + } + if (S_ISCHR(mode)) { + printf("character special file\n"); + return; + } + if (S_ISBLK(mode)) { + printf("block special file\n"); + return; + } + if (S_ISPIPE(mode)) { + printf("named pipe\n"); + return; + } +#ifdef S_IFLNK + if (S_ISLNK(mode)) { + n= readlink(name, (char *)buf, BLOCK_SIZE); + if (n == -1) + printf("cannot readlink\n"); + else + printf("symbolic link to %.*s\n", n, buf); + return; + } +#endif + if (!S_ISREG(mode)) { + printf("strange file type %5o\n", mode); + return; + } + + /* Open the file, stat it, and read in 1 block. */ + fd = open(name, O_RDONLY); + if (fd < 0) { + printf("cannot open\n"); + return; + } + n = read(fd, (char *)buf, BLOCK_SIZE); + if (n < 0) { + printf("cannot read\n"); + close(fd); + return; + } + if (n == 0) { /* must check this, for loop will fail otherwise !! */ + printf("empty file\n"); + close(fd); + return; + } + + for (i = 0; i < tabsize; i++) { + for (j = 0; j < 4; j++) + if ((buf[j] & table[i].mask[j]) != table[i].magic[j]) + break; + if (j == 4) { + printf("%s", table[i].description); + do_strip(table[i].execflag); + close(fd); + return; + } + } + + /* Check to see if file is a shell script. */ + if (mode & XBITS) { + /* Not a binary, but executable. Probably a shell script. */ + printf("shell script\n"); + close(fd); + return; + } + + /* Check for ASCII data and certain punctuation. */ + nonascii = 0; + special = 0; + etaoins = 0; + for (i = 0; i < n; i++) { + c = buf[i]; + if (c & 0200) nonascii++; + if (c == ';' || c == '{' || c == '}' || c == '#') special++; + if (c == '*' || c == '<' || c == '>' || c == '/') special++; + if (c >= 'A' && c <= 'Z') c = c - 'A' + 'a'; + if (c == 'e' || c == 't' || c == 'a' || c == 'o') etaoins++; + if (c == 'i' || c == 'n' || c == 's') etaoins++; + } + + if (nonascii == 0) { + /* File only contains ASCII characters. Continue processing. */ + funnypct = 100 * special / n; + engpct = 100L * (long) etaoins / n; + if (funnypct > 1) { + printf("C program\n"); + } else { + if (engpct > (long) ENGLISH) + printf("English text\n"); + else + printf("ASCII text\n"); + } + close(fd); + return; + } + + /* Give up. Call it data. */ + printf("data\n"); + close(fd); + return; +} + +void do_strip(type) +int type; +{ + if (type == 1) { /* Non-GNU executable */ + if (buf[2] & 1) + printf(", UZP"); + if (buf[2] & 2) + printf(", PAL"); + if (buf[2] & 4) + printf(", NSYM"); + if (buf[2] & 0x20) + printf(", sep I&D"); + else + printf(", comm I&D"); + if (( buf[28] | buf[29] | buf[30] | buf[31]) != 0) + printf(" not stripped\n"); + else + printf(" stripped\n"); + return; + } + + if (type == 2) { /* GNU format executable */ + if ((buf[16] | buf[17] | buf[18] | buf[19]) != 0) + printf(" not stripped\n"); + else + printf(" stripped\n"); + return; + } + + if (type == 3) { /* Core file in format */ + switch(buf[36] & 0xff) + { + case 1: printf(" of i86 executable"); break; + case 2: printf(" of i386 executable"); break; + default:printf(" of unknown executable"); break; + } + printf(" '%.32s'\n", buf+4); + return; + } + + printf("\n"); /* Not an executable file */ + } + +void usage() +{ + printf("usage: file [-L] name ...\n"); + exit(1); +} diff --git a/src/simple/find.c b/src/simple/find.c new file mode 100755 index 00000000..1e097ca0 --- /dev/null +++ b/src/simple/find.c @@ -0,0 +1,938 @@ +/* find - look for files satisfying a predicate Author: E. Baalbergen */ + +/* Original author: Erik Baalbergen; POSIX compliant version: Bert Laverman */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*######################## DEFINITIONS ##############################*/ + +#ifdef S_IFLNK +#define LSTAT lstat +#else +#define LSTAT stat +#endif + +#ifndef PATH_MAX +#define PATH_MAX 256 +#endif + +#define SHELL _PATH_BSHELL +#define MAXARG 256 /* maximum length for an argv for -exec */ +#define BSIZE 512 /* POSIX wants 512 byte blocks */ +#define SECS_PER_DAY (24L*60L*60L) /* check your planet */ + +#define OP_NAME 1 /* match name */ +#define OP_PERM 2 /* check file permission bits */ +#define OP_TYPE 3 /* check file type bits */ +#define OP_LINKS 4 /* check link count */ +#define OP_USER 5 /* check owner */ +#define OP_GROUP 6 /* check group ownership */ +#define OP_SIZE 7 /* check size, blocks or bytes */ +#define OP_SIZEC 8 /* this is a fake for -size with 'c' */ +#define OP_INUM 9 /* compare inode number */ +#define OP_ATIME 10 /* check last access time */ +#define OP_CTIME 11 /* check creation time */ +#define OP_MTIME 12 /* check last modification time */ +#define OP_EXEC 13 /* execute command */ +#define OP_OK 14 /* execute with confirmation */ +#define OP_PRINT 15 /* print name */ +#define OP_PRINT0 16 /* print name null terminated */ +#define OP_NEWER 17 /* compare modification times */ +#define OP_AND 18 /* logical and (short circuit) */ +#define OP_OR 19 /* logical or (short circuit) */ +#define OP_XDEV 20 /* do not cross file-system boundaries */ +#define OP_DEPTH 21 /* descend directory before testing */ +#define OP_PRUNE 22 /* don't descend into current directory */ +#define OP_NOUSER 23 /* check validity of user id */ +#define OP_NOGROUP 24 /* check validity of group id */ +#define LPAR 25 /* left parenthesis */ +#define RPAR 26 /* right parenthesis */ +#define NOT 27 /* logical not */ + +/* Some return values: */ +#define EOI -1 /* end of expression */ +#define NONE 0 /* not a valid predicate */ + +/* For -perm with symbolic modes: */ +#define ISWHO(c) ((c == 'u') || (c == 'g') || (c == 'o') || (c == 'a')) +#define ISOPER(c) ((c == '-') || (c == '=') || (c == '+')) +#define ISMODE(c) ((c == 'r') || (c == 'w') || (c == 'x') || \ + (c == 's') || (c == 't')) +#define MUSER 1 +#define MGROUP 2 +#define MOTHERS 4 + + +struct exec { + int e_cnt; + char *e_vec[MAXARG]; +}; + +struct node { + int n_type; /* any OP_ or NOT */ + union { + char *n_str; + struct { + long n_val; + int n_sign; + } n_int; + struct exec *n_exec; + struct { + struct node *n_left, *n_right; + } n_opnd; + } n_info; +}; + +struct oper { + char *op_str; + int op_val; +} ops[] = { + + { + "name", OP_NAME + }, + { + "perm", OP_PERM + }, + { + "type", OP_TYPE + }, + { + "links", OP_LINKS + }, + { + "user", OP_USER + }, + { + "group", OP_GROUP + }, + { + "size", OP_SIZE + }, + { + "inum", OP_INUM + }, + { + "atime", OP_ATIME + }, + { + "ctime", OP_CTIME + }, + { + "mtime", OP_MTIME + }, + { + "exec", OP_EXEC + }, + { + "ok", OP_OK + }, + { + "print", OP_PRINT + }, + { + "print0", OP_PRINT0 + }, + { + "newer", OP_NEWER + }, + { + "a", OP_AND + }, + { + "o", OP_OR + }, + { + "xdev", OP_XDEV + }, + { + "depth", OP_DEPTH + }, + { + "prune", OP_PRUNE + }, + { + "nouser", OP_NOUSER + }, + { + "nogroup", OP_NOGROUP + }, + { + 0, 0 + } +}; + + +char **ipp; /* pointer to next argument during parsing */ +char *prog; /* program name (== argv [0]) */ +char *epath; /* value of PATH environment string */ +time_t current_time; /* for computing age */ +int tty; /* fd for /dev/tty when using -ok */ +int xdev_flag = 0; /* cross device boundaries? */ +int devnr; /* device nr of first inode */ +int depth_flag = 0; /* descend before check? */ +int prune_here; /* This is Baaaad! Don't ever do this again! */ +int um; /* current umask() */ +int needprint = 1; /* implicit -print needed? */ + + +/* The prototypes: */ +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(char *safe_malloc, (int n)); +_PROTOTYPE(char *Salloc, (char *s)); +_PROTOTYPE(void find, (char *path, struct node * pred, char *last)); +_PROTOTYPE(int check, (char *path, struct stat * st, struct node * n, char *last)); +_PROTOTYPE(int ichk, (long val, struct node * n)); +_PROTOTYPE(int lex, (char *str)); +_PROTOTYPE(struct node * newnode, (int t)); +_PROTOTYPE(int isnumber, (char *str, int base, int sign)); +_PROTOTYPE(void number, (char *str, int base, long *pl, int *ps)); +_PROTOTYPE(void fmode, (char *str, long *pl, int *ps)); +_PROTOTYPE(struct node * expr, (int t)); +_PROTOTYPE(struct node * primary, (int t)); +_PROTOTYPE(struct node * secondary, (int t)); +_PROTOTYPE(void checkarg, (char *arg)); +_PROTOTYPE(struct node * simple, (int t)); +_PROTOTYPE(void nonfatal, (char *s1, char *s2)); +_PROTOTYPE(void fatal, (char *s1, char *s2)); +_PROTOTYPE(int smatch, (char *s, char *t)); +_PROTOTYPE(char *find_bin, (char *s)); +_PROTOTYPE(int execute, (int op, struct exec * e, char *path)); +_PROTOTYPE(void domode, (int op, int *mode, int bits)); + + +/* safe_malloc: a certified malloc */ +char *safe_malloc(n) +int n; +{ + char *m; + + if ((m = (char *) malloc(n)) == (char *) NULL) fatal("out of memory", ""); + return m; +} + +/* Salloc: allocate space for a string */ +char *Salloc(s) +char *s; +{ + return strcpy(safe_malloc(strlen(s) + 1), s); +} + + +/* Main: the main body */ +int main(argc, argv) +int argc; +char *argv[]; +{ + char **pathlist, *path, *last; + int pathcnt = 0, i; + struct node *pred; + + prog = *argv++; /* set program name (for diagnostics) */ + if ((epath = getenv("PATH")) == (char *) NULL) + fatal("Can't get path from environment", ""); + (void) umask(um = umask(0)); /* non-destructive get-umask :-) */ + time(¤t_time); /* get current time */ + + pathlist= argv; + while (--argc > 0 && lex(*argv) == NONE) { /* find paths */ + pathcnt++; + argv++; + } + if (pathcnt == 0) { /* there must be at least one path */ + fprintf(stderr, "usage: find path-list [predicate-list]\n"); + exit(1); + } + + ipp = argv; /* prepare for parsing */ + if (argc != 0) { /* If there is anything to parse, */ + pred = expr(lex(*ipp)); /* then do so */ + if (lex(*++ipp) != EOI) /* Make sure there's nothing left */ + fatal("syntax error: garbage at end of predicate", ""); + } else /* No predicate list */ + pred = (struct node *) NULL; + + for (i = 0; i < pathcnt; i++) { + if (xdev_flag) xdev_flag = 2; + path = pathlist[i]; + if ((last = strrchr(path, '/')) == NULL) last = path; else last++; + find(path, pred, last); + } + return 0; +} + +void find(path, pred, last) +char *path, *last; +struct node *pred; +{ + char spath[PATH_MAX]; + register char *send = spath, *p; + struct stat st; + DIR *dp; + struct dirent *de; + + if (path[1] == '\0' && *path == '/') { + *send++ = '/'; + *send = '\0'; + } else + while (*send++ = *path++) { + } + + if (LSTAT(spath, &st) == -1) + nonfatal("can't get status of ", spath); + else { + switch (xdev_flag) { + case 0: + break; + case 1: + if (st.st_dev != devnr) return; + break; + case 2: /* set current device number */ + xdev_flag = 1; + devnr = st.st_dev; + break; + } + + prune_here = 0; + if (!depth_flag && check(spath, &st, pred, last) && needprint) + printf("%s\n", spath); + if (!prune_here && (st.st_mode & S_IFMT) == S_IFDIR) { + if ((dp = opendir(spath)) == NULL) { + nonfatal("can't read directory ", spath); + return; + } + send[-1] = '/'; + while ((de = readdir(dp)) != NULL) { + p = de->d_name; + if ((de->d_name[0] != '.') || ((de->d_name[1]) + && ((de->d_name[1] != '.') + || (de->d_name[2])))) { + strcpy(send, de->d_name); + find(spath, pred, send); + } + } + closedir(dp); + } + if (depth_flag) { + send[-1] = '\0'; + if (check(spath, &st, pred, last) && needprint) + printf("%s\n", spath); + } + } +} + +int check(path, st, n, last) +char *path, *last; +register struct stat *st; +register struct node *n; +{ + if (n == (struct node *) NULL) return 1; + switch (n->n_type) { + case OP_AND: + return check(path, st, n->n_info.n_opnd.n_left, last) && + check(path, st, n->n_info.n_opnd.n_right, last); + case OP_OR: + return check(path, st, n->n_info.n_opnd.n_left, last) || + check(path, st, n->n_info.n_opnd.n_right, last); + case NOT: + return !check(path, st, n->n_info.n_opnd.n_left, last); + case OP_NAME: + return smatch(last, n->n_info.n_str); + case OP_PERM: + if (n->n_info.n_int.n_sign < 0) + return(st->st_mode & (int) n->n_info.n_int.n_val) == + (int) n->n_info.n_int.n_val; + return(st->st_mode & 07777) == (int) n->n_info.n_int.n_val; + case OP_NEWER: + return ((convtime(&st->st_mtime) - n->n_info.n_int.n_val) > 0); + case OP_TYPE: + return(st->st_mode & S_IFMT) == (mode_t) n->n_info.n_int.n_val; + case OP_LINKS: + return ichk((long) (st->st_nlink), n); + case OP_USER: + return st->st_uid == n->n_info.n_int.n_val; + case OP_GROUP: + return st->st_gid == n->n_info.n_int.n_val; + case OP_SIZE: +#if 0 /* Nick */ + return ichk((long)(st->st_size.o_blkno + (st->st_size.o_offset > 0)), + n); +#else + return ichk((st->st_size == 0) ? 0L : + (long) ((st->st_size - 1) / BSIZE + 1), n); +#endif + case OP_SIZEC: +#if 0 /* Nick */ + return ichk(512L*st->st_size.o_blkno + st->st_size.o_offset, n); +#else + return ichk((long) st->st_size, n); +#endif + case OP_INUM: + return ichk((long) (st->st_ino), n); + case OP_ATIME: + return ichk(convtime(&st->st_atime), n); + case OP_CTIME: + return ichk(convtime(&st->st_ctime), n); + case OP_MTIME: + return ichk(convtime(&st->st_mtime), n); + case OP_EXEC: + case OP_OK: + return execute(n->n_type, n->n_info.n_exec, path); + case OP_PRINT: + printf("%s\n", path); + return 1; + case OP_PRINT0: + printf("%s", path); putchar(0); + return 1; + case OP_XDEV: + case OP_DEPTH: + return 1; + case OP_PRUNE: + prune_here = 1; + return 1; + case OP_NOUSER: + return(getpwuid(st->st_uid) == (struct passwd *) NULL); + case OP_NOGROUP: + return(getgrgid(st->st_gid) == (struct group *) NULL); + } + fatal("ILLEGAL NODE", ""); + return 0; /* Never reached */ +} + +int ichk(val, n) +long val; +struct node *n; +{ + switch (n->n_info.n_int.n_sign) { + case 0: + return val == n->n_info.n_int.n_val; + case 1: + return val > n->n_info.n_int.n_val; + case -1: return val < n->n_info.n_int.n_val; +} + fatal("internal: bad n_sign", ""); + return 0; /* Never reached */ +} + +int lex(str) +char *str; +{ + if (str == (char *) NULL) return EOI; + if (*str == '-') { + register struct oper *op; + + str++; + for (op = ops; op->op_str; op++) + if (strcmp(str, op->op_str) == 0) break; + return op->op_val; + } + if (str[1] == 0) { + switch (*str) { + case '(': + return LPAR; + case ')': + return RPAR; + case '!': return NOT; + } + } + return NONE; +} + +struct node * + newnode(t) +int t; +{ + struct node *n = (struct node *) safe_malloc(sizeof(struct node)); + + n->n_type = t; + return n; +} + +/*########################### PARSER ###################################*/ +/* Grammar: + * expr : primary | primary OR expr; + * primary : secondary | secondary AND primary | secondary primary; + * secondary : NOT secondary | LPAR expr RPAR | simple; + * simple : -OP args... + */ + +/* Isnumber checks correct number syntax. A sign is allowed, but the '+' + * only if the number is to be in decimal. + */ +int isnumber(str, base, sign) +register char *str; +int base; +int sign; +{ + if (sign && ((*str == '-') || ((base == 8) && (*str == '+')))) str++; + while ((*str >= '0') && (*str < ('0' + base))) str++; + return(*str == '\0' ? 1 : 0); +} + +/* Convert a string to an integer, storing sign info in *ps. */ +void number(str, base, pl, ps) +char *str; +int base; +long *pl; +int *ps; +{ + int up = '0' + base - 1; + long val = 0; + + *ps = ((*str == '-' || *str == '+') ? ((*str++ == '-') ? -1 : 1) : 0); + while (*str >= '0' && *str <= up) val = base * val + *str++ - '0'; + if (*str) fatal("syntax error: illegal numeric value", ""); + *pl = val; +} + + +void domode(op, mode, bits) +int op; +int *mode; +int bits; +{ + switch (op) { + case '-': + *mode &= ~bits; + break; /* clear bits */ + case '=': + *mode |= bits; + break; /* set bits */ + case '+': + *mode |= (bits & ~um); /* set, but take umask in account */ + } +} + +void fmode(str, pl, ps) +char *str; +long *pl; +int *ps; +{ + int m = 0, w, op; + char *p = str; + + if (*p == '-') { + *ps = -1; + p++; + } else + *ps = 0; + + while (*p) { + w = 0; + if (ISOPER(*p)) + w = MUSER | MGROUP | MOTHERS; + else if (!ISWHO(*p)) + fatal("u, g, o, or a expected: ", p); + else { + while (ISWHO(*p)) { + switch (*p) { + case 'u': + w |= MUSER; + break; + case 'g': + w |= MGROUP; + break; + case 'o': + w |= MOTHERS; + break; + case 'a': + w = MUSER | MGROUP | MOTHERS; + } + p++; + } + if (!ISOPER(*p)) fatal("-, + or = expected: ", p); + } + op = *p++; + while (ISMODE(*p)) { + switch (*p) { + case 'r': + if (w & MUSER) domode(op, &m, S_IRUSR); + if (w & MGROUP) domode(op, &m, S_IRGRP); + if (w & MOTHERS) domode(op, &m, S_IROTH); + break; + case 'w': + if (w & MUSER) domode(op, &m, S_IWUSR); + if (w & MGROUP) domode(op, &m, S_IWGRP); + if (w & MOTHERS) domode(op, &m, S_IWOTH); + break; + case 'x': + if (w & MUSER) domode(op, &m, S_IXUSR); + if (w & MGROUP) domode(op, &m, S_IXGRP); + if (w & MOTHERS) domode(op, &m, S_IXOTH); + break; + case 's': + if (w & MUSER) domode(op, &m, S_ISUID); + if (w & MGROUP) domode(op, &m, S_ISGID); + break; + case 't': + domode(op, &m, S_ISVTX); + } + p++; + } + if (*p) { + if (*p == ',') + p++; + else + fatal("garbage at end of mode string: ", p); + } + } + *pl = m; +} + +struct node * + expr(t) +int t; +{ + struct node *nd, *p, *nd2; + + nd = primary(t); + if ((t = lex(*++ipp)) == OP_OR) { + nd2 = expr(lex(*++ipp)); + p = newnode(OP_OR); + p->n_info.n_opnd.n_left = nd; + p->n_info.n_opnd.n_right = nd2; + return p; + } + ipp--; + return nd; +} + +struct node * + primary(t) +int t; +{ + struct node *nd, *p, *nd2; + + nd = secondary(t); + if ((t = lex(*++ipp)) != OP_AND) { + ipp--; + if (t == EOI || t == RPAR || t == OP_OR) return nd; + } + nd2 = primary(lex(*++ipp)); + p = newnode(OP_AND); + p->n_info.n_opnd.n_left = nd; + p->n_info.n_opnd.n_right = nd2; + return p; +} + +struct node * + secondary(t) +int t; +{ + struct node *n, *p; + + if (t == LPAR) { + n = expr(lex(*++ipp)); + if (lex(*++ipp) != RPAR) fatal("syntax error, ) expected", ""); + return n; + } + if (t == NOT) { + n = secondary(lex(*++ipp)); + p = newnode(NOT); + p->n_info.n_opnd.n_left = n; + return p; + } + return simple(t); +} + +void checkarg(arg) +char *arg; +{ + if (arg == 0) fatal("syntax error, argument expected", ""); +} + +struct node * + simple(t) +int t; +{ + struct node *p = newnode(t); + struct exec *e; + struct stat est; + struct passwd *pw; + struct group *gr; + long l; + int i; + + switch (t) { + case OP_TYPE: + checkarg(*++ipp); + switch (**ipp) { + case 'b': + p->n_info.n_int.n_val = S_IFBLK; + break; + case 'c': + p->n_info.n_int.n_val = S_IFCHR; + break; + case 'd': + p->n_info.n_int.n_val = S_IFDIR; + break; + case 'f': + p->n_info.n_int.n_val = S_IFREG; + break; + case 'l': +#ifdef S_IFLNK + p->n_info.n_int.n_val = S_IFLNK; +#else + p->n_info.n_int.n_val = ~0; /* Always unequal. */ +#endif + break; + default: + fatal("-type needs b, c, d, f or l", ""); + } + break; + case OP_USER: + checkarg(*++ipp); + if (((pw = getpwnam(*ipp)) == NULL) + && isnumber(*ipp, 10, 0)) + number(*ipp, 10, &(p->n_info.n_int.n_val), + &(p->n_info.n_int.n_sign)); + else { + if (pw == NULL) + fatal("unknown user: ", *ipp); + p->n_info.n_int.n_val = pw->pw_uid; + p->n_info.n_int.n_sign = 0; + } + break; + case OP_GROUP: + checkarg(*++ipp); + if (((gr = getgrnam(*ipp)) == NULL) + && isnumber(*ipp, 10, 0)) + number(*ipp, 10, &(p->n_info.n_int.n_val), + &(p->n_info.n_int.n_sign)); + else { + if (gr == NULL) + fatal("unknown group: ", *ipp); + p->n_info.n_int.n_val = gr->gr_gid; + p->n_info.n_int.n_sign = 0; + } + break; + case OP_SIZE: + checkarg(*++ipp); + i = strlen(*ipp) - 1; + if ((*ipp)[i] == 'c') { + p->n_type = OP_SIZEC; /* Count in bytes i.s.o. blocks */ + (*ipp)[i] = '\0'; + } + number(*ipp, 10, &(p->n_info.n_int.n_val), + &(p->n_info.n_int.n_sign)); + break; + case OP_LINKS: + case OP_INUM: + checkarg(*++ipp); + number(*ipp, 10, &(p->n_info.n_int.n_val), + &(p->n_info.n_int.n_sign)); + break; + case OP_PERM: + checkarg(*++ipp); + if (isnumber(*ipp, 8, 1)) number(*ipp, 8, &(p->n_info.n_int.n_val), + &(p->n_info.n_int.n_sign)); + else + fmode(*ipp, &(p->n_info.n_int.n_val), + &(p->n_info.n_int.n_sign)); + break; + case OP_ATIME: + case OP_CTIME: + case OP_MTIME: + checkarg(*++ipp); + number(*ipp, 10, &l, &(p->n_info.n_int.n_sign)); + p->n_info.n_int.n_val = convtime(¤t_time) - l * SECS_PER_DAY; + /* More than n days old means less than the absolute time */ + p->n_info.n_int.n_sign *= -1; + break; + case OP_EXEC: + case OP_OK: + checkarg(*++ipp); + e = (struct exec *) safe_malloc(sizeof(struct exec)); + e->e_cnt = 2; + e->e_vec[0] = SHELL; + p->n_info.n_exec = e; + while (*ipp) { + if (**ipp == ';' && (*ipp)[1] == '\0') { + e->e_vec[e->e_cnt] = 0; + break; + } + e->e_vec[(e->e_cnt)++] = + (**ipp == '{' && (*ipp)[1] == '}' + && (*ipp)[2] == '\0') ? (char *) (-1) : *ipp; + ipp++; + } + if (*ipp == 0) fatal("-exec/-ok: ; missing", ""); + if ((e->e_vec[1] = find_bin(e->e_vec[2])) == 0) + fatal("can't find program ", e->e_vec[2]); + if (t == OP_OK) +#if 1 /* Nick */ + if ((tty = open(_PATH_TTY, O_RDWR)) < 0) + fatal("can't open " _PATH_TTY, ""); +#else + if ((tty = open("/dev/tty", O_RDWR)) < 0) + fatal("can't open /dev/tty", ""); +#endif + break; + case OP_NEWER: + checkarg(*++ipp); + if (LSTAT(*ipp, &est) == -1) + fatal("-newer: can't get status of ", *ipp); + p->n_info.n_int.n_val = convtime(&est.st_mtime); + break; + case OP_NAME: + checkarg(*++ipp); + p->n_info.n_str = *ipp; + break; + case OP_XDEV: xdev_flag = 1; break; + case OP_DEPTH: depth_flag = 1; break; + case OP_PRUNE: + case OP_PRINT: + case OP_PRINT0: + case OP_NOUSER: case OP_NOGROUP: break; + default: + fatal("syntax error, operator expected", ""); + } + if ((t == OP_PRINT) || (t == OP_PRINT0) || (t == OP_EXEC) || (t == OP_OK)) + needprint = 0; + + return p; +} + +/*######################## DIAGNOSTICS ##############################*/ + +void nonfatal(s1, s2) +char *s1, *s2; +{ + fprintf(stderr, "%s: %s%s\n", prog, s1, s2); +} + +void fatal(s1, s2) +char *s1, *s2; +{ + nonfatal(s1, s2); + exit(1); +} + +/*################### SMATCH #########################*/ +/* Don't try to understand the following one... */ +int smatch(s, t) /* shell-like matching */ +char *s, *t; +{ + register int n; + + if (*t == '\0') return *s == '\0'; + if (*t == '*') { + ++t; + do + if (smatch(s, t)) return 1; + while (*s++ != '\0'); + return 0; + } + if (*s == '\0') return 0; + if (*t == '\\') return (*s == *++t) ? smatch(++s, ++t) : 0; + if (*t == '?') return smatch(++s, ++t); + if (*t == '[') { + while (*++t != ']') { + if (*t == '\\') ++t; + if (*(t + 1) != '-') + if (*t == *s) { + while (*++t != ']') + if (*t == '\\') ++t; + return smatch(++s, ++t); + } else + continue; + if (*(t + 2) == ']') return(*s == *t || *s == '-'); + n = (*(t + 2) == '\\') ? 3 : 2; + if (*s >= *t && *s <= *(t + n)) { + while (*++t != ']') + if (*t == '\\') ++t; + return smatch(++s, ++t); + } + t += n; + } + return 0; + } + return(*s == *t) ? smatch(++s, ++t) : 0; +} + +/*####################### EXECUTE ###########################*/ +/* Do -exec or -ok */ + +char * + find_bin(s) +char *s; +{ + char *f, *l, buf[PATH_MAX]; + + if (*s == '/') /* absolute path name */ + return(access(s, 1) == 0) ? s : 0; + l = f = epath; + for (;;) { + if (*l == ':' || *l == 0) { + if (l == f) { + if (access(s, 1) == 0) return Salloc(s); + f++; + } else { + register char *p = buf, *q = s; + + while (f != l) *p++ = *f++; + f++; + *p++ = '/'; + while (*p++ = *q++) { + } + if (access(buf, 1) == 0) return Salloc(buf); + } + if (*l == 0) break; + } + l++; + } + return 0; +} + +int execute(op, e, path) +int op; +struct exec *e; +char *path; +{ + int s, pid; + char *argv[MAXARG]; + register char **p, **q; + + for (p = e->e_vec, q = argv; *p;) /* replace the {}s */ + if ((*q++ = *p++) == (char *) -1) q[-1] = path; + *q = '\0'; + if (op == OP_OK) { + char answer[10]; + + for (p = &argv[2]; *p; p++) { + write(tty, *p, strlen(*p)); + write(tty, " ", 1); + } + write(tty, "? ", 2); + if (read(tty, answer, 10) < 2 || *answer != 'y') return 0; + } + if ((pid = fork()) == -1) fatal("can't fork", ""); + if (pid == 0) { + register int i = 3; + + while (close(i++) == 0) { + } /* wow!!! */ + execv(argv[1], &argv[2]); /* binary itself? */ + execv(argv[0], &argv[1]); /* shell command? */ + fatal("exec failure: ", argv[1]); /* none of them! */ + exit(127); + } + return wait(&s) == pid && s == 0; +} diff --git a/src/simple/fld.c b/src/simple/fld.c new file mode 100755 index 00000000..b037b08b --- /dev/null +++ b/src/simple/fld.c @@ -0,0 +1,410 @@ +/* F L D . C 05.08.90, BAS + * + * Read and concatenate fields from in file + * + ********* -p not implemented!!!! ********** + * + * FLD -u -p -z* -[b t s? i? fm1.n1,m2.n2] {infiles} >outfile + * + * -?/-h - Help + * -u - unpack tabs + * -p - pack tabs + * -z* - skip first * spaces + * -b - skip head field's spaces + * -t - remove trailing spaces + * -s? - output fields separator + * -i? - input fields separator + * -fm1.n1,m2.n2 - define field + * -f# - get field from tty + * + * Values after "-f" define starting and ending pos of fielld: + * + * m1.n1 field start (first char of field) + * m2.n2 field end (first char not in field) + * + * Value 'm' define num of fields, skipped from begin of line. + * (0 means - no skip). + * + * Value 'n' define num of chars, skipped in selected field + * + * If "m1.n1" omitted, field started from line begin + * If "m2.n2" omitted, field continues to line end + * Excluding omitted "m2.n2", omitting any of four values means + * "use 0 for this value". + * + * If defined -b, heading spaces will be skipped after 'm', but before + * 'n' is applyed. + * + * If defined -t, trailing spaces of filed will be deleted. + * + * If defined -i?, char '?' declare input fileds separator. + * + * If defined -s?, char '?' will be printed after the mentioned field. + */ +#include +#include +#include +#include + +#ifndef __P /* (x) Nick */ +#define __P(x) x +#endif + +typedef unsigned char BOOL; + +typedef struct { + char *fstr; + char lbl; + char tbl; + char term; + char sep; + int s_f, s_o; + int e_f, e_o; +} FIELD; + +#define MAXLIN 512 +#define MAXFLD 10 + +FIELD fld[MAXFLD]; +int fp = 0, + nufp = 0; +char *lin = NULL; /* ¡-¥ - ®ª¨ */ +BOOL uflag = 0; /* « £   ¯ ª®¢ª¨ - ¡-«ï-® ®¢ */ +int zval = 0; /* ç¨ «® ¯ ®¯- ª ¥¬ë ¯ ®¡¥«®¢ */ + +FILE *fin = stdin, + *fou = stdout; +char *nfin = "", + *nfou = ""; + +char *hlp[] = { + "usage: fld -u -z* -[bs?t?i?fm1.n1,m2.n2 {infiles} >outfile", + "\t-?/-h\t- help", + "\t-u\t- unpack tabs (enable absolute positions)", + "\t-z*\t- remove first * blanks", + "\t-b\t- Skip leading blanks of field", + "\t-t\t- Kill trailing blanks of field", + "\t-s?\t- Field separator for output", + "\t-i?\t- Field separator for input", + "\t-fm1.n1,m2.n2 - Setup field", + "\t\t# - Get field from user", + "\t\tm1.n1 - Start of the field (first printable char)", + "\t\tm2.n2 - End of the field (first nonprintable char)", + "\t\t\t'm' - number of fields to skip, from the", + "\t\t\tstart of the data line (0 means 'skip no fields').", + "\t\t\t'n' - number of bytes to skip in the field.", + 0 +}; + +void help __P((void)); +void error __P((char *s1, char *s2)); +char *aton __P((char *p, int *num)); +char *skp __P((BOOL l, int n, char *s)); +char *nxt __P((char *s, char t)); +char *fnd __P((int sf, int so, int ef, int eo, BOOL lbl, BOOL tbl, char term, char **eof)); +char *getstr __P((char *p)); +int gts __P((char **p)); +void getfld __P((char *cp)); +void slice __P((void)); +int lget __P((char *s)); + +void help() { + int i = 0; + + while (hlp[i]) + fprintf(stderr,"%s\n",hlp[i++]); +} + +void error(char *s1,char *s2) { + fprintf(stderr, "fld: %s %s\n", s1, s2 ? s2 : ""); + exit(1); +} + +/* unsigned ASCII to decimal + * end on non digit, return ptr to terminator + */ +char *aton(char *p, int *num) { + register int n = 0; + register char c; + + while (c = *p++, isdigit(c)) + n = 10*n + (c - '0'); + *num = n; + return p-1; +} + +char *skp(l,n,s) + BOOL l; + int n; + char *s; +{ + if (l) + while (isspace(*s)) + ++s; + while (n-- && *s++) + ; + return s; +} + +char *nxt(s,t) + char *s, t; +{ + if (t) { + while(*s && *s++ != t) + ; + } + else { + while (isspace(*s)) + ++s; + while (*s && !isspace(*s)) + ++s; + } + return s; +} + +/* return ptrs to field start/end */ +char *fnd(sf, so, ef, eo, lbl, tbl, term, eof) + int sf, so; /* start fields & chars to skip */ + int ef, eo; /* end fields & chars to skip */ + BOOL lbl; /* skip leading whitespace flag */ + BOOL tbl; /* kill trailing whitespace flag */ + char term; /* field terminator, if not 0 */ + char **eof; /* eof pointer */ +{ + register char *sp; /* start pointer */ + register char *ep; /* end pointer */ + register int i; + + /* skip over fields */ + for (sp = lin, i = sf; i-- > 0; ) + sp = nxt(sp, term); + i = ef - sf; + ep = sp; + sp = skp(lbl,so,sp); + if (ef >= 0) { + if (i < 0) { + i = ef; + ep = lin; + } + while (i-- > 0) + ep = nxt(ep, term); + ep = skp(lbl,eo,ep); + if (tbl) + while(ep > sp && isspace(ep[-1])) + --ep; + *eof = (ep < sp) ? sp : ep; + } + else *eof = lin + strlen(lin); + return (sp); +} + +/* Get field from tty */ +char *getstr(char *p) { + char *s, *q; + + if (*p == 0) { + printf("-fld>"); + fflush(stdout); + if (fgets(p = lin, 80, stdin) == NULL) + exit(0); + if ((s = strrchr(p, '\n')) != NULL) + *s = 0; + } + s = q = p; + while ((*q++ = gts(&s)) != 0) + ; + if ((q = malloc(strlen(p)+1)) != NULL) + strcpy(q,p); + else error("No memory for field",p); + return q; +} + +/* Process escape sequence */ +int gts(char **p) { + register char *s = *p; + register char c = *s++; + register int i; + + if (c == '\\') { + c = *s; + if (c & 0100) + c &= 0137; + if (c == 'T') c = '\t'; + else if (c == 'S') c = ' '; + else if (c == 'N') c = '\n'; + else if (c == 'F') c = '\f'; + else if (c == 'V') c = '\v'; + else if (c >= '0' && c <= '7') { + c = 0; + for (i = 3; --i >= 0 && (*s >= '0' && *s <= '7'); ++s) + c = (c<<3) + (*s-'0'); + goto Ret; + } + else c = *s; + if (*s) + ++s; + } +Ret: *p = s; + return c; +} + +/* get field definition */ +void getfld(char *cp) { + register FIELD *x = &fld[fp]; + + if (fp >= MAXFLD) + error("Too many fields at",cp); + + if (*cp == '#') { + x->fstr = getstr(++cp); + ++nufp; + return; + } + + x->s_f = x->s_o = x->e_f = x->e_o = 0; + + cp = aton(cp,&x->s_f); + if (*cp == '.') + cp = aton(++cp,&x->s_o); + if (*cp == ',') { + cp = aton(++cp,&x->e_f); + if (*cp == '.') + cp = aton(++cp,&x->e_o); + } + if (*cp) + error("Illegal field definition",cp-1); +/* x->e_f = -1; +*/ +} + +void slice() { + register int i; + register FIELD *x; + register char *b; + static char *e; + + while (lget(lin)) { + for (i = 0; i < fp; i++) { + x = &fld[i]; + if ((b = x->fstr) != NULL) { + fputs(b,fou); + continue; + } + b = fnd(x->s_f,x->s_o,x->e_f,x->e_o, + x->lbl,x->tbl,x->term,&e); + while (b < e) + fputc(*b++,fou); + if (i < fp-1) + fputc(x->sep ? x->sep : '\t',fou); + } + fputc('\n',fou); + if (ferror(fou)) + error("Error write output file",nfou); + } +} + +int lget(s) + char *s; +{ + register int c; + register int pos; + static char *p; + + for (pos = 0; (c = fgetc(fin)) != EOF && c != '\n'; ) { + if (uflag && c == '\t') + for (c = 8 - (pos&7); --c >= 0; ) + s[pos++] = ' '; + else s[pos++] = c; + } + if (ferror(fin)) + error("Error read input file",nfin); + s[pos] = '\0'; + for (pos = zval, p = s; --pos >= 0; ++p) + if (*p != ' ') + break; + if (s != p) + strcpy(s,p); + return c != EOF; +} + +int main(argc, argv) + register int argc; + register char *argv[]; +{ + static char *p; + register char c; + register int ac = argc, nf = 0; + + if ((lin = (char *)malloc(MAXLIN+1)) == NULL) + error("Not enough memory",0); + + for (ac = 1; ac < argc; ++ac) { + c = *(p = argv[ac]); + if (c == '-') { + argv[ac] = NULL; + ++p; + while(p != 0 && (c = *p++) != 0) { + switch (tolower(c)) { + case '?': + case 'h': + help(); + return 0; + + case 'u': + ++uflag; + break; + + case 'z': + p = aton(p,&zval); + break; + + case 'b': + ++fld[fp].lbl; + break; + + case 't': + ++fld[fp].tbl; + break; + + case 's': + fld[fp].sep = gts(&p); + break; + + case 'i': + fld[fp].term = gts(&p); + break; + + case 'f': + getfld(p); + ++fp; + p = NULL; + break; + + default: + error("Illegal switch",p-1); + break; + } + } + } + else ++nf; + } + if (fp == 0 || fp == nufp) { + fld[fp].e_f = -1; + fp++; +/* remark("Warning - default field\n",0); /**/ + } + if (nf > 0) { + for (ac = 1; ac < argc; ++ac) { + if ((nfin = argv[ac]) != NULL) { + if ((fin = fopen(nfin,"r")) == NULL) + error("Can't open input file",nfin); + slice(); + fclose(fin); + } + } + } + else slice(); + fclose(fou); + return 0; +} + diff --git a/src/simple/fortune.c b/src/simple/fortune.c new file mode 100755 index 00000000..2ec64411 --- /dev/null +++ b/src/simple/fortune.c @@ -0,0 +1,101 @@ +/* fortune - hand out Chinese fortune cookies Author: Bert Reuling */ + +#include +#include +#include +#include +#include +#include + +#define COOKIEJAR "/usr/lib/fortune.dat" + +static char *Copyright = "\0Copyright (c) 1990 Bert Reuling"; +static unsigned long seed; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(unsigned long magic, (unsigned long range)); + +#if defined(MSX_UZIX_TARGET) || defined (PC_UZIX_TARGET) +#define LONG(x) (long)(x.t_time+x.t_date*65536) +#else +#define LONG(x) (long)x +#endif + +int main(argc, argv) +int argc; +char *argv[]; +{ + int c1, c2, c3; + struct stat cookie_stat; + FILE *cookie; + time_t now; + + if ((cookie = fopen(COOKIEJAR, "r")) == NULL) { + printf("\nSome things better stay closed.\n - %s\n", argv[0]); + exit (-1); + } + + /* Create seed from : date, time, user-id and process-id. we can't get + * the position of the moon, unfortunately. + */ + time(&now); + seed = LONG(now) + (long) getuid() + (long) getpid(); + + if (stat(COOKIEJAR, &cookie_stat) != 0) { + printf("\nIt furthers one to see the super guru (%d).\n - %s\n", errno, argv[0]); + exit (-1); + } + +#if 0 /* Nick */ + fseek(cookie, magic((unsigned long) (512L*cookie_stat.st_size.o_blkno + + cookie_stat.st_size.o_offset)), 0); +#else + fseek(cookie, magic((unsigned long) cookie_stat.st_size), 0); /* move by magic... */ +#endif + + c2 = c3 = '\0'; + while (((c1 = getc(cookie)) != EOF) && ((c1 != '%') || (c2 != '%') || (c3 != '\n'))) { + c3 = c2; + c2 = c1; + } + + if (c1 == EOF) { + printf("\nSomething unexpected has happened.\n - %s", argv[0]); + exit (-1); + } + + c2 = c3 = '\0'; + c1 = getc(cookie); /* skip \n */ + while (((c1 = getc(cookie)) != '%') || (c2 != '%') || (c3 != '\n')) { + if (c1 == EOF) { + rewind(cookie); + continue; + } +#if 1 /* Nick */ + if (c2) + { + putc(c2, stdout); + } +#else + putc(c2, stdout); +#endif + c3 = c2; + c2 = c1; + } + /* putc('\n', stdout); */ + fclose(cookie); + return (0); +} + +/* magic - please study carefully: there is more than meets the eye */ +unsigned long magic(range) +unsigned long range; +{ + + seed = 9065531L * (seed % 9065533L) - 2 * (seed / 9065531L) + 1L; + return (seed % range); +} diff --git a/src/simple/grep.c b/src/simple/grep.c new file mode 100755 index 00000000..775f06e8 --- /dev/null +++ b/src/simple/grep.c @@ -0,0 +1,717 @@ +/* grep.c 24.05.94 by BAS + * + * Get Regular Expression and Print + * + * GREP -CNVFD -P®¡à §¥æ ” ©«ë + * + * Grep ¯à®á¬ âਢ ¥â 㪠§ ­­ë¥ ä ©«ë (¨«¨ stdin), ¨ ¨é¥â ᮢ¯ ¤ î騥 + * á ®¡à §æ®¬ áâப¨.  á¯®§­ îâáï á«¥¤ãî騥 ª«îç¨: + * + * ? ¥ç âì 奫¯  + * C ¥ç âì ⮫쪮 ç¨á«  ᮢ¯ ¢è¨å áâப + * N ¥ç â âì ¯¥à¥¤ ª ¦¤®© áâப®© ¥¥ ­®¬¥à + * V ¥ç â âì ­¥á®¢¯ ¢è¨¥ áâப¨ + * F ¥ç â âì ¨¬¥­  ä ©«®¢ + * D Žâ« ¤ª  + * + * P ‡ ¤ ­¨¥ ®¡à §æ  (¬®¦­® § ¤ âì ­¥áª®«ìª®) + * + * Ž¡à §¥æ § ¤ ¥âáï ॣã«ïà­ë¬ ¢ëà ¦¥­¨¥¬. + * ‚¥àå­¨© ¨ ­¨¦­¨© ॣ¨áâà à §«¨ç îâáï. + * ãáâë¥ áâப¨ ᮢ¯ ¤ îâ á ®¡à §æ®¬ "$" (á¬. ­¨¦¥). + * + * ¥£ã«ïà­®¥ ¢ëà ¦¥­¨¥ áâநâáï ¨§ á«¥¤ãîé¨å í«¥¬¥­â®¢: + * + * x Ž¡ëç­ë© ᨬ¢®« (­¥ ®¯¨á ­­ë© ¤ «¥¥), ᮢ¯ ¤ ¥â á ᮡ®©. + * \ ªà ­ «î¡®£® ᨬ¢®« . "\$" ᮢ¯ ¤ ¥â á ¤®«« à®¬. + * \nnn (n = 0..7) - ᨬ¢®« á ª®¤®¬ nnn. + * ^ ‚ ­ ç «¥ ¢ëà ¦¥­¨ï ᮢ¯ ¤ ¥â á ­ ç «®¬ áâப¨. + * $ ‚ ª®­æ¥ ¢ëà ¦¥­¨ï ᮢ¯ ¤ ¥â á ª®­æ®¬ áâப¨. + * . ‹î¡®© ᨬ¢®«, ªà®¬¥ LF. + * :r ‹î¡ ï àãááª ï ¡ãª¢  + * :p ‹î¡®© ¯ã­ªâã æ¨®­­ë© ᨬ¢®« + * :l Œ «¥­ìª ï  ­£«¨©áª ï ¡ãª¢ . + * :u ®«ìè ï  ­£«¨©áª ï ¡ãª¢ . + * :a ‹î¡ ï  ­£«¨©áª ï ¡ãª¢ . + * :d ‹î¡ ï æ¨äà . + * :n ‹î¡ ï ¡ãª¢  ¨/¨«¨ æ¨äà . + * :c ‹î¡®© ª®­â஫, ªà®¬¥ LF ¨ TAB. + * :s ஡¥«. + * :t ’ ¡ã«ïâ®à. + * :e  ç «® ¯®¤¢ëà ¦¥­¨ï. + * * ‚ëà ¦¥­¨¥, §  ª®â®àë¬ ¨¤¥â '*', ᮢ¯ ¤ ¥â á ­®«¥¬ ¨«¨ + * ¡®«¥¥ ¯®ï¢«¥­¨© í⮣® ¢ëà ¦¥­¨ï: "fo*" ᮢ¯ ¤ ¥â á "f", + * "fo", "foo"... + * + ‚ëà ¦¥­¨¥, §  ª®â®àë¬ ¨¤¥â '+', ᮢ¯ ¤ ¥â á ®¤­¨¬ ¨«¨ + * ¡®«¥¥ ¯®ï¢«¥­¨© í⮣® ¢ëà ¦¥­¨ï: "fo+" ᮢ¯ ¤ ¥â á "fo"... + * - ‚ëà ¦¥­¨ï ¯¥à¥¤ '-' ᮢ¯ ¤ ¥â á ­®«¥¬ ¨«¨ ®¤­¨¬ ¯®ï¢«¥­¨¥¬ + * ¢ëà ¦¥­¨ï. + * [] ‘âப  ¢ ᪮¡ª å ᮢ¯ ¤ ¥â ⮫쪮 á ᨬ¢®« ¬¨ ¨§ áâப¨, + * ¨ ­¥ á ª ª¨¬¨ ¤à㣨¬¨. …᫨ ¯¥à¢ë© ᨬ¢®« áâப¨ '^', + * ¢ëà ¦¥­¨¥ ¡ã¤¥â ᮢ¯ ¤ âì á «î¡ë¬¨ ᨬ¢®« ¬¨, ¨áª«îç ï '\n' + * ¨ ¢á¥ ᨬ¢®«ë, ¢å®¤ï騥 ¢ áâபã. + * + * „«ï ¯à¨¬¥à , "A[xyz]+B" ᮢ¯ ¤¥â á "AxxB" ¨ "AxyzzyB",   "A[^xyz]+B" + * ᮢ¯ ¤¥â á "AbcB" ­® ­¥ á "AxB". „¨ ¯ §®­ ᨬ¢®«®¢ ¬®¦¥â ¡ëâì 㪠§ ­ + * ª ª ¤¢  ᨬ¢®« , à §¤¥«¥­­ëå '-'. ‡ ¬¥âìâ¥, çâ® [a-z] ᮢ¯ ¤ãâ á + * ¬ «¥­ìª¨¬¨ ¡ãª¢ ¬¨,   [z-a] ­¥ ᮢ¯ ¤¥â ­¨ á 祬. + * + * Š®­ª â¥­ æ¨ï ॣã«ïà­ëå ¢ëà ¦¥­¨© - á­®¢  ॣã«ïà­®¥ ¢ëà ¦¥­¨¥. + * + * „¨ £­®á⨪ : + * + * Unknown switch + * + * No pattern + * + * Illegal occurrence op. ... + * - Ž¯¥à â®à ¢ ­¥¢¥à­®¬ ª®­â¥ªáâ¥.  ¯à¨¬¥à, ®¡à §¥æ "*foo" + * ­¥¤®¯ãá⨬, â ª ª ª '*' ¤®«¦­  ¬®¤¨ä¨æ¨à®¢ âì áâ®ï饥 ¯¥à¥¤ ­¨¬ + * ¢ëà ¦¥­¨¥. + * + * No type + * - „¢®¥â®ç¨¥ á ­¥¢¥à­ë¬ ¨¤¥­â¨ä¨ª â®à®¬. + * + * Class terminates badly + * - ‘¨¬¢®«ì­ë© ª« áá "[...]" § ¢¥à襭 ­¥ª®à४⭮. + *  ¯à¨¬¥à, "[A-]" - ­¥¢¥à­®. + * + * Unterminated class + * - ‘¨¬¢®«ì­ë© ª« áá ­¥ § ¢¥à襭 ']'. + * + * Class too large + * - ‚­ãâ७­¨© ¡ãä¥à ¯¥à¥¯®«­¥­. + * + * Empty class + * - ‘¨¬¢®«ì­ë© ª« áá ¤®«¦¥ ᮤ¥à¦ âì çâ® ­¨¡ã¤ì."[]" - ­¥¢¥à­®. + * + * Pattern too complex + * - ‚­ãâ७­¨© ¡ãä¥à ¯¥à¥¯®«­¥­. + */ + +#undef DEBUG +#define DEBUG 0 + +#include +#include +#include +#include +#include + +#define IDENT "GREP V01.03" + +#define LMAX 4096 +#define PMAX 4096 +#define NPATS 16 + +#define CHAR 1 +#define BOL 2 +#define EOL 3 +#define ANY 4 +#define CLASS 5 +#define NCLASS 6 +#define STAR 7 +#define PLUS 8 +#define MINUS 9 +#define LOWER 10 +#define UPPER 11 +#define ALPHA 12 +#define DIGIT 13 +#define NALPHA 14 +#define CNTRL 15 +#define RANGE 16 +#define ENDPAT 17 +#define RUSSL 18 +#define START 19 + +char *items[] = { + "NULL\n", "'", "^ ", "$ ", "? ", "[", "[^", "\n*( ", + "\n+( ", "\n-( ", "L ", "U ", "A ", "D ", + "AN ", "CTRL ", "", ")\n", "R ", "! ", +}; + +int cflag = 0; +int nflag = 0; +int vflag = 0; +int fflag = 0; +#if DEBUG +int debug = 0; /* >0 ¤«ï ®â« ¤ª¨ */ +#endif + +long t_count = 0; +long t_lno = 0; +int t_fil = 0; + +char *pp = 0; +char emp[] = {EOL,ENDPAT,0}; + +char *lbuf; +char *pbuf; +char *pats[NPATS]; +int npats = 0; + +static int nullp = 0; + +static char *h1[] = { + IDENT, + "grep -cnfv {-p} files", + "\t-c - print only a count of matched lines", + "\t-n - preceed each line by its line number", + "\t-f - print file names", + "\t-v - print non-matching lines", +#if DEBUG + "\t-d - debug (may be 1, 2 times)", +#endif + "\t-p - give pattern, may be repeated", + "", + "In the pattern yor may use following elements:", + "\tx\t- ordinary character\t\\\t- quotes any char", + "\t^\t- beginning of line\t$\t- end of line", + "\t.\t- any char\t\t\\nnn\t- numeric (C-style) value", + "\t:l\t- lower-case\t\t:u\t- upper-case", + "\t:a\t- alphabetic\t\t:d\t- digits", + "\t:n\t- alphanumeric\t\t:r\t- any russian letter", + "\t:s\t- space\t\t\t:t\t- tab", + "\t:c\t- any control, except LF & TAB", + "\t:e\t- start of subexpression", + "\t*\t- repeat zero or more\t+\t- repeat one or more", + "\t-\t- optionally matches the expr", + "\t[..]\t- any from this (may be ranges FROM-TO)", + "\t[^..]\t- any except this", + NULL +}; + +void help(register char *s[]) { + register int i; + + for (i = 0; s[i]; i++) + fprintf(stderr,"%s\n",s[i]); + exit(1); +} + +void error(char *s1,char *s2) { + fprintf(stderr, "grep: %s %s\n", s1, s2 ? s2 : ""); + exit(1); +} + +void store(int op) { + if (pp >= pbuf+PMAX) + error("Pattern too complex",0); + *pp++ = op; +} + +void badpat(char *message, char *source, char *stop) { + /* Error message */ + /* Pattern start */ + /* Pattern end */ + fprintf(stderr,"grep: %s, pattern is \"%s\"\n", message, source); + fprintf(stderr,"\tStopped at byte %d, '%c'\n",stop-source, stop[-1]); + error("Stop",0); +} + +char *skippat(char *p) { + int level = 1; + + while (*p != 0 && (*p != ENDPAT || --level > 0)) { + if (*p == START || *p == STAR || *p == PLUS || *p == MINUS) + ++level; + ++p; + } + return p; +} + +char *pmatch(char *line, char *pattern) { + /* (ç áâì) áâப  */ + /* (ç áâì) ®¡à §¥æ */ + register char *l; /* 㪠§ â¥«ì áâப¨ */ + register char *p; /* 㪠§ â¥«ì ®¡à §æ  */ + register char c; /* ⥪ã騩 ᨬ¢®« */ + char *e; /* ª®­¥æ ¤«ï STAR ¨ PLUS ¬ â祭ìï */ + int op; /* ®¯¥à æ¨ï ¨§ ®¡à §æ  */ + int n; /* áç¥â稪 ª« áá  */ + char *are; /* ­ ç «® STAR ¬ â祭ìï */ + + l = line; +#if DEBUG + if (debug > 2) + printf("pmatch(\"%s\")\n", line); +#endif + p = pattern; + while ((op = *p++) != ENDPAT) { +#if DEBUG + if (debug > 2) { + char *s = items[op]; + printf("byte[%d] = '%c' ~ %s", + l-line, *l, *s < ' ' ? s+1 : s); + if (op == CHAR) + printf("%c'",*p); + printf("\n"); + } +#endif + c = *l++; + switch(op) { + case START: + break; + case CHAR: + if (c != *p++) + return 0; + break; + case BOL: + if (--l != lbuf) + return 0; + break; + case EOL: + if (*(--l)) + return 0; + break; + case ANY: + if (!c) + return 0; + break; + case DIGIT: + if (!isdigit(c)) + return 0; + break; + case UPPER: + if (!isupper(c)) + return 0; + break; + case LOWER: + if (!islower(c)) + return 0; + break; + case ALPHA: + if (!isalpha(c)) + return 0; + break; + case NALPHA: + if (!isalnum(c)) + return 0; + break; + case RUSSL: + if ((c >= '€' && c <= 'Ÿ') || + (c >= ' ' && c <= 'ï')) + break; + return 0; + case CNTRL: + if (c == '\t' || c >= 040) + return 0; + break; + case CLASS: + case NCLASS: + n = *p++ & 0377; + do { + if (*p == RANGE) { + p += 3; + n -= 2; + if (c >= p[-2] && c <= p[-1]) + break; + } + else if (c == *p++) + break; + } while (--n > 1); + if ((op == CLASS) == (n <= 1)) + return 0; + if (op == CLASS) + p += n - 2; + break; + case MINUS: + e = pmatch(--l, p); /* ¯à®¢¥à¨¬ */ + p = skippat(p); /* ¯à®¯ãá⨬ ®¡à §¥æ */ + if (e) /* ¬ â稬? */ + l = e; /* ¤ , ᬥ­¨âì áâபã */ + break; /* ¢á¥£¤  ®ª */ + case PLUS: /* 1 ¨«¨ ¡®«¥¥ ... */ + if ((l = pmatch(--l, p)) == 0) + return 0; /* ®¡ï§ ­ë ¬ âç¨âì */ + case STAR: /* 0 ¨«¨ ¡®«¥¥ ... */ + are = --l; /* § ¯®¬­¨¬ ­ ç «® áâப¨ */ + while (*l && (e = pmatch(l, p)) != 0) + l = e; /* á ¬®¥ ¤«¨­­®¥ ¬ âç¥­ì¥ */ + p = skippat(p); /* ¯à®¯ãá⨬ ®¡à §¥æ */ + while (l >= are) { /* ¯ëâ ¥¬áï ¬ âç¨âì ®áâ â®ª */ + if ((e = pmatch(l, p)) != 0) + return e; + --l; /* ­¥ 㤠«®áì, ­ § ¤ */ + } + return 0; /* ­¨ç¥£® ­¥ ¯®«ã稫®áì */ + default: + fprintf(stderr,"grep: Bad op code %03o for line\n%s\n", + op,lbuf); + exit(0); + } + } + return l; +} + +/* ஢¥àª  áâப¨ ¨§ lbuf, ¢¥à­¥â 1, ¥á«¨ áâப  ¬ âç¨â */ +int match(void) { + register char *l = lbuf; /* 㪠§ â¥«ì áâப¨ */ + register char *p = pbuf; + + if (p[0] == BOL && p[1] == CHAR && l[0] != p[2] || + p[0] == CHAR && (l = strchr(l,p[1])) == NULL) { +#if DEBUG + if (debug > 1) + printf("Fast test failed for\n\"%s\"\n",l); +#endif + return 0; + } + if (l[0] == '\0' && strcmp(pbuf,emp) == 0) + return 1; + while (*l) { + if (pmatch(l++, pbuf)) + return 1; + } + return 0; +} + +void printpattern(void) { + unsigned char *lp; + int c, n; + + printf("\n("); + for (lp = pbuf; lp < pp-1;) { + c = *lp++; + printf("%s",items[c]); + if (c == CHAR) { + c = *lp++; + printf("%s%c' ", c<' '?"^":"", c<' '? c + '@': c); + } + else if (c == CLASS || c == NCLASS) { + for (n = *lp++; --n >= 0; ) { + c = *lp++; + printf("%s%c",c<' '?"^":"",c<' '? c+'@':c); + } + printf("] "); + } + else if (c == RANGE) { + c = *lp++; + printf("'%s%c'-", c<' '?"^":"", c<' '? c + '@': c); + c = *lp++; + printf("'%s%c' ", c<' '?"^":"", c<' '? c + '@': c); + } + } + printf("\n"); +} + +int digit(int c, int r) { + c = tolower(c); + if (r > 10 && (c >= 'a' && c <= 'f')) + return c-'a'+10; + if (c >= '0' && c <= '0'+r) + return c - '0'; + return -1; +} + +char *escaped(char *source, int *val) { + char *s = source; + int c, v; + + if ((c = *s++) == 0) /* ­¥®¡å®¤¨¬ ᨬ¢®« */ + badpat("Class terminates badly", source, s); + if ((v = digit(c,10)) >= 0) { + int rad = 10; + if (c == '0') { + rad = 8; + switch (*s) { + case 'x': + case 'X': + rad = 16; ++s; break; + case 'b': + case 'B': + rad = 2; ++s; break; + } + /* v = 0; */ + } + for (; (c = digit(*s,rad)) >= 0; v = v*rad+c) + ++s; + } + else if (c == 't') + v = '\t'; + else if (c == 'r') + v = '\r'; + else if (c == 'n') + v = '\n'; + else if (c == 'a') + v = '\a'; + else if (c == 'f') + v = '\f'; + else v = c; + if (val != NULL) + *val = v; + return s; +} + +char *ordinar(char *source, int *val) { + char *s = source; + int v = 0; + + if (*s == 0) + badpat("Non expected end of line",source,s); + if (*s == '\\') + s = escaped(++s,&v); + else v = *s++; + if (*val != NULL) + *val = v; + else { + store(CHAR); + store(v); + } + return s; +} + +char *aclass(char *source) { + char *s = source; + int c, c1; + char *cp; + + c = CLASS; + if (*s == '^') { + ++s; + c = NCLASS; + } + cp = pp; + store(0); /* áç¥â稪 ¡ ©â®¢ */ + while (*s != 0 && *s != ']') { + s = ordinar(s,&c); + if (*s == '-' && s[1] != 0 && s[1] != ']') { + s = ordinar(++s,&c1); + if (c1 < c) + badpat("Empty range",source,s); + store(RANGE); + store(c); + store(c1); + } + } + if (*s != ']') + badpat("Unterminated class", source, s); + if ((c = (int)(pp - cp)) >= 256) + badpat("Class too large", source, s); + if (c == 0) + badpat("Empty class", source, s); + *cp = c; + return s+1; +} + +char *special(char *source) { + char *s = source; + int c = *s++; + + switch(tolower(c)) { + case 'l': + store(LOWER); break; + case 'u': + store(UPPER); break; + case 'a': + store(ALPHA); break; + case 'd': + store(DIGIT); break; + case 'n': + store(NALPHA); break; + case 'r': + store(RUSSL); break; + case 'c': + store(CNTRL); break; + case 's': + store(CHAR); store(' '); break; + case 't': + store(CHAR); store('\t'); break; + case 0: + badpat("No type after ':'", source, s); + default: + badpat("Unknown type", source, s); + } + return s; +} + +char *factor(char *source) { + char *s = source; + char *term(char *); + char *lp = pp; + int c; + + if (*s == ')') + return s; + store(START); /* ¢¤à㣠¡ã¤¥â ¬®¤¨ä¨ª â®à */ + c = *s; + if (c == '(') { + s = term(++s); + if (*s != ')') + badpat("Unterminated subexpression",source,s); + ++s; + } + else if (c == '.') { + ++s; + store(ANY); + } + else if (c == '[') + s = aclass(++s); + else if (c == ':') + s = special(++s); + else s = ordinar(s, &nullp); + c = *s; + if (c == '+' || c == '-' || c == '*') { + ++s; + *lp = (c == '+' ? PLUS : (c == '-' ? MINUS : STAR)); + store(ENDPAT); + } + else { + memcpy(lp,lp+1,pp-lp); /* ã¡à âì «¨è­¨© START */ + --pp; + } + return s; +} + +char *term(char *s) { + while (*s != 0 && *s != '$' && *s != ')') + s = factor(s); + return s; +} + +/* Š®¬¯¨«ïæ¨ï ®¡à §æ  ¢ ¡ãä¥à pbuf */ +void compile(char *source) { /* ®¡à §¥æ */ + char *s = source; +#if DEBUG + if (debug) + printf("\nPattern = \"%s\"\n", s); +#endif + pp = pbuf; + if (*s == '^') { + store(BOL); + ++s; + } + s = term(s); + if (*s == '$') { + store(EOL); + ++s; + } + store(ENDPAT); + store(0); /* § ¢¥à訬 áâபã */ + if (*s != 0) + badpat("Unterminated syntax",source,s); +#if DEBUG + if (debug) + printpattern(); +#endif +} + +void compile1(char *s) { + char *p; + int n; + + if (npats >= NPATS-1) + error("Too many patterns",0); + compile(s); + n = strlen(pbuf)+1; + if ((p = malloc(n)) == NULL) + error("No room for pattern",s); + pats[npats] = memcpy(p,pbuf,n); + ++npats; +} + +/* ‘ª ­¨à®¢ ­¨¥ ä ©«  ¤«ï ¯®¨áª  ®¡à §æ  ¨§ pbuf */ +void grep(FILE *fd, char *fn) { + /* ¤¥áªà¨¯â®à ä ©«  */ + /* ¨¬ï ä ©«  */ + register int lno, count, m, i, wasfn; + + ++t_fil; + lno = count = wasfn = 0; + while (fgets(lbuf,LMAX,fd)) { + lbuf[strlen(lbuf)-1] = 0; /* ã¡à âì LF */ + ++lno; ++t_lno; + for (m = 0, i = 0; m == 0 && i < npats; ++i) { + pbuf = pats[i]; + m |= match(); + } + if ((m && !vflag) || (!m && vflag)) { + ++count; ++t_count; + if (!cflag) { + if (fflag && !wasfn && *fn) { + printf("\f%s\n",fn); + ++wasfn; + } + if (nflag) + printf("%5d\t", lno); + puts(lbuf); + } + } + } + if (ferror(fd)) + error("Read error file", *fn ? fn : ""); + if (cflag) + printf("%s %d lines matched, %d total\n", + *fn ? fn : "", count, lno); +} + +int main(int argc, char *argv[]) { + register int i, c; + register int fcnt = 0; /* ç¨á«® ä ©«®¢ */ + char *ap; + FILE *fd; + + if ((lbuf = malloc(LMAX)) == NULL || + (pbuf = malloc(PMAX)) == NULL) + error("No enought memory",0); + for (i = 1; i < argc; ++i) { + ap = argv[i]; + if (*ap == '-') { + argv[i] = NULL; + ++ap; + while ((c = *ap++) != 0) { + switch (tolower(c)) { + case '?': + help(h1); break; + case 'c': + ++cflag; break; +#if DEBUG + case 'd': + ++debug; break; +#endif + case 'n': + ++nflag; break; + case 'f': + ++fflag; break; + case 'v': + ++vflag; break; + case 'p': + if (*ap != 0) + strcpy(lbuf,ap); + else if (++i < argc) { + strcpy(lbuf,argv[i]); + argv[i] = NULL; + } + ap = ""; + compile1(lbuf); + break; + default: + error("Unknown switch",--ap); + } + } + } + else ++fcnt; /* ¨¬ï ä ©«  */ + } + if (npats == 0) + error("No pattern",0); + + if (fcnt == 0) + grep(stdin,0); + else { + for (i = 1; fcnt > 0 && i < argc; ++i) { + ap = argv[i]; + if (ap) { + --fcnt; + if ((fd = fopen(ap,"r")) == NULL) + error("Can't open",ap); + grep(fd,ap); + fclose(fd); + } + } + if (cflag) + printf("%ld lines matched, %ld total in %d file(s)\n", + t_count, t_lno, t_fil); + } + return 0; +} + diff --git a/src/simple/gres.c b/src/simple/gres.c new file mode 100755 index 00000000..0399884e --- /dev/null +++ b/src/simple/gres.c @@ -0,0 +1,189 @@ +/* gres - grep and substitute Author: Martin C. Atkins */ + +/* + * globally search, and replace + * + *<-xtx-*>cc -o gres gres.c -lregexp + */ + +/* + * This program was written by: + * Martin C. Atkins, + * University of York, + * Heslington, + * York. Y01 5DD + * England + * and is released into the public domain, on the condition + * that this comment is always included without alteration. + */ + +#include +#include +#include +#include +#include + +#define MAXLINE (1024) + +int status = 1; +char *usagemsg = "usage: gres [-g] search replace [file ...]\n"; +char *progname; +int gflag = 0; /* != 0 => only do first substitution on line */ + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +#define std_err(x) write(STDERR_FILENO, x, strlen(x)) + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void process, (FILE *inf, regexp *exp, char *repstr)); +_PROTOTYPE(void regerror, (char *s)); +_PROTOTYPE(char *getbuf, (regexp *exp, char *repstr)); +_PROTOTYPE(void pline, (regexp *exp, char ibuf [], char *repstr)); +_PROTOTYPE(void dosub, (regexp *exp, char ibuf [], char *repstr)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + regexp *exp; + char *repstr; + char **argp = &argv[1]; + + progname = argv[0]; + if (*argp != 0 && argp[0][0] == '-' && argp[0][1] == 'g') { + gflag = 1; + argp++, argc--; + } + if (argc < 3) { + std_err(usagemsg); + exit(2); + } + if (argp[0][0] == '\0') { + std_err("gres: null match string is silly\n"); + exit(2); + } + if ((exp = regcomp(*argp++)) == NULL) { + std_err("gres: regcomp failed\n"); + exit(2); + } + repstr = *argp++; + if (*argp == 0) + process(stdin, exp, repstr); + else + while (*argp) { + FILE *inf; + + if (strcmp(*argp, "-") == 0) + process(stdin, exp, repstr); + else { + if ((inf = fopen(*argp, "r")) == NULL) { + std_err("gres: Can't open "); + std_err(*argp); + std_err("\n"); + status = 2; + } else { + process(inf, exp, repstr); + fclose(inf); + } + } + argp++; + } + return(status); +} + +/* This routine does the processing. */ +void process(inf, exp, repstr) +FILE *inf; +regexp *exp; +char *repstr; +{ + char ibuf[MAXLINE]; + + while (fgets(ibuf, MAXLINE, inf) != NULL) { + char *cr = strchr(ibuf, '\n'); + if (cr == 0) + std_err("gres: Line broken\n"); + else + *cr = '\0'; + if (regexec(exp, ibuf/*, 1*/)) { + pline(exp, ibuf, repstr); + if (status != 2) status = 0; + } else + puts(ibuf); + } +} + +void regerror(s) +char *s; +{ + std_err("gres: "); + std_err(s); + std_err("\n"); + exit(2); +} + +char *getbuf(exp, repstr) +regexp *exp; +char *repstr; +{ + static int bufsize = 0; + static char *buf = 0; + size_t guess = 10; + int ch; + + while (*repstr) { + switch (*repstr) { + case '&': + guess += exp->endp[0] - exp->startp[0]; + break; + case '\\': + if ((ch = *++repstr) < '0' || ch > '9') + guess += 2; + else { + ch -= '0'; + guess += exp->endp[ch] - exp->startp[ch]; + } + break; + default: guess++; + } + repstr++; + } + if (bufsize < guess) { + if (buf != 0) free((char *) buf); + buf = (char *)malloc(guess); + } + return buf; +} + +void pline(exp, ibuf, repstr) +regexp *exp; +char ibuf[]; +char *repstr; +{ + do { + dosub(exp, ibuf, repstr); + ibuf = exp->endp[0]; + if (*ibuf == '\0') break; + if (ibuf == exp->startp[0]) putchar(*ibuf++); + } while (!gflag && regexec(exp, ibuf/*, 0*/)); + puts(ibuf); +} + +/* Print one subsitution. */ +void dosub(exp, ibuf, repstr) +regexp *exp; +char ibuf[]; +char *repstr; +{ + char *buf = getbuf(exp, repstr); + char *end = exp->startp[0]; + int ch = *end; + + *end = '\0'; + fputs(ibuf, stdout); /* output the initial part of line */ + *end = ch; + regsub(exp, repstr, buf); + fputs(buf, stdout); +} diff --git a/src/simple/head.c b/src/simple/head.c new file mode 100755 index 00000000..90efd717 --- /dev/null +++ b/src/simple/head.c @@ -0,0 +1,87 @@ +/* head - print the first few lines of a file Author: Andy Tanenbaum */ + +#include +#include +#include + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +#define DEFAULT 10 + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void do_file, (int n, FILE *f)); +_PROTOTYPE(void usage, (void)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + FILE *f; + int n, k, nfiles; + char *ptr; + + /* Check for flag. Only flag is -n, to say how many lines to print. */ + k = 1; + ptr = argv[1]; + n = DEFAULT; + if (argc > 1 && *ptr++ == '-') { + k++; + n = atoi(ptr); + if (n <= 0) { + usage(); + return(1); + } + } + nfiles = argc - k; + + if (nfiles == 0) { + /* Print standard input only. */ + if (isatty(fileno(stdin))) { + usage(); + return(1); + } + do_file(n, stdin); + return(0); + } + + /* One or more files have been listed explicitly. */ + while (k < argc) { + if (nfiles > 1) printf("==> %s <==\n", argv[k]); + if ((f = fopen(argv[k], "r")) == NULL) + printf("head: cannot open %s\n", argv[k]); + else { + do_file(n, f); + fclose(f); + } + k++; + if (k < argc) printf("\n"); + } + return(0); +} + + + +void do_file(n, f) +int n; +FILE *f; +{ + int c; + + /* Print the first 'n' lines of a file. */ + while (n) switch (c = getc(f)) { + case EOF: + return; + case '\n': + --n; + default: putc((char) c, stdout); + } +} + + +void usage() +{ + fprintf(stderr, "usage: head [-n] [file ...]\n"); + return; +} diff --git a/src/simple/id.c b/src/simple/id.c new file mode 100755 index 00000000..fcfe2cf7 --- /dev/null +++ b/src/simple/id.c @@ -0,0 +1,55 @@ +/* id - return uid and gid Author: John J. Marco */ + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/ +/* ----- id.c ----- */ +/* Id - get real and effective user id and group id */ +/* Author: John J. Marco */ +/* pa1343@sdcc15.ucsd.edu */ +/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ + +#include +#include +#include +#include +#include + +/* if the system doesn't have getegid and geteuid functions... */ +#define getegid getgid +#define geteuid getuid + +int main() +{ + struct passwd *pwd; + struct group *grp; + int uid, gid, euid, egid; + + uid = getuid(); + gid = getgid(); + euid = geteuid(); + egid = getegid(); + + if ((pwd = getpwuid(uid)) == NULL) + printf("%s%d%s", "uid=", uid, " "); + else + printf("%s%d%s%s%s", "uid=", uid, "(", pwd->pw_name, ") "); + + if ((grp = getgrgid(gid)) == NULL) + printf("%s%d%s", "gid=", gid, " "); + else + printf("%s%d%s%s%s", "gid=", gid, "(", grp->gr_name, ") "); + + if (uid != euid) + if ((pwd = getpwuid(euid)) != NULL) + printf("%s%d%s%s%s", "euid=", euid, "(", pwd->pw_name, ") "); + else + printf("%s%d%s", "euid=", euid, " "); + + if (gid != egid) + if ((grp = getgrgid(egid)) != NULL) + printf("%s%d%s%s%s", "egid=", egid, "(", grp->gr_name, ") "); + else + printf("%s%d%s", "egid=", egid, " "); + + printf("\n"); + return(0); +} diff --git a/src/simple/inodes.c b/src/simple/inodes.c new file mode 100755 index 00000000..7c339a69 --- /dev/null +++ b/src/simple/inodes.c @@ -0,0 +1,262 @@ +/* inodes - print inode characteristics Author: Johan W. Stevenson */ + +/* Copyright 1984 by Johan W. Stevenson. */ + +#include +#include +#include +#include +#include +#include +#include + +#define NAMSIZ 256 +#define major(dev) (((dev) >> 8) & 0xFF) +#define minor(dev) ((dev) & 0xFF) + +struct linkbuf { + struct linkbuf *l_nxt; + ino_t l_ino; + dev_t l_dev; + char l_nam[NAMSIZ]; +}; + +char line[NAMSIZ]; +struct stat statbuf; +struct linkbuf *lhead = NULL; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(void do_inodes, (char *line)); +_PROTOTYPE(void dir, (void)); +_PROTOTYPE(void dev, (int c)); +_PROTOTYPE(void reg, (void)); +_PROTOTYPE(void lnk, (void)); +_PROTOTYPE(void sock, (void)); +_PROTOTYPE(int crc, (void)); + +int main(argc, argv) + int argc; + char **argv; +{ + char *aline; + + if (argc < 2 && isatty(fileno(stdin))) { + fprintf(stderr, "usage: inodes files...\n"); + return(1); + } + if (argc < 2 && !isatty(fileno(stdin))) { + while (gets(line)) do_inodes(line); + return(0); + } + while ((aline = *(++argv)) != 0) { + strcpy(line, aline); + do_inodes(line); + } + return(0); +} + +void do_inodes(char *line) { +#ifdef S_IFLNK + if (lstat(line, &statbuf) < 0) { +#else + if (stat(line, &statbuf) < 0) { +#endif + fprintf(stderr, "cannot stat %s\n", line); + } + switch (statbuf.st_mode & S_IFMT) { + case S_IFDIR: dir(); break; + case S_IFCHR: dev('c'); break; + case S_IFBLK: dev('b'); break; + case S_IFREG: reg(); break; +#ifdef S_IFLNK + case S_IFLNK: lnk(); break; +#endif +#ifdef S_IFSOCK + case S_IFSOCK: sock(); break; +#endif + default: + fprintf(stderr, "%s: bad mode 0%o\n", line, statbuf.st_mode); + } +} + +void dir() +{ + register struct stat *p = &statbuf; + + printf( + "d m=%04o uid=%2d gid=%2d X size=%8ld %s\n", + p->st_mode & 07777, + p->st_uid, + p->st_gid, + p->st_size, + line + ); +} + +void dev(c) +int c; +{ + register struct stat *p = &statbuf; + + printf( + "%c m=%04o uid=%2d gid=%2d major,minor=%2d,%2d size=%8ld %s\n", + c, + p->st_mode & 07777, + p->st_uid, + p->st_gid, + major(p->st_rdev), + minor(p->st_rdev), + p->st_size, + line + ); +} + +void reg() +{ + register struct stat *p = &statbuf; + + if (p->st_nlink > 1) { + register struct linkbuf *lp; + + for (lp = lhead; lp != NULL; lp = lp->l_nxt) + if (lp->l_ino == p->st_ino && lp->l_dev == p->st_dev) { + printf( + "i m=XXXX uid=X gid=X X X X %s -> %s\n", + line, + lp->l_nam + ); + return; + } + lp = (struct linkbuf *) malloc(sizeof(*lp)); + if (lp == NULL) { + fprintf(stderr, "inodes: out of memory, link information lost\n"); + } else { + lp->l_nxt = lhead; + lhead = lp; + lp->l_ino = p->st_ino; + lp->l_dev = p->st_dev; + strcpy(lp->l_nam, line); + } + } + printf( + "f m=%04o uid=%2d gid=%2d crc=%05u size=%8ld %s\n", + p->st_mode & 07777, + p->st_uid, + p->st_gid, + crc(), + p->st_size, + line + ); +} + +#ifdef S_IFLNK +void lnk() +{ + register struct stat *p = &statbuf; + char buf[NAMSIZ]; + register i; + + i = readlink(line, buf, sizeof(buf)-1); + if (i < 0) { + fprintf(stderr, "cannot readlink %s\n", line); + return; + } + buf[i] = '\0'; + printf( + "l m=%04o uid=%2d gid=%2d %s -> %s\n", + p->st_mode & 07777, + p->st_uid, + p->st_gid, + line, + buf + ); +} + +#endif + +#ifdef S_IFSOCK +void sock() +{ + register struct stat *p = &statbuf; + + printf( + "s %04o %2d %2d X X %s\n", + p->st_mode & 07777, + p->st_uid, + p->st_gid, + line + ); +} + +#endif + +/* Crctab calculated by Mark G. Mendel, Network Systems Corporation */ +static unsigned short crctab[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 +}; + +/* Updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. + * NOTE: First argument must be in range 0 to 255. + * Second argument is referenced twice. + * + * Programmers may incorporate any or all code into their programs, + * giving proper credit within the source. Publication of the + * source routines is permitted so long as proper credit is given + * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, + * Omen Technology. + */ + +#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp) + +int crc() +{ + register unsigned short crc; + register c; + register FILE *f; + + if ((f = fopen(line, "r")) == NULL) { + fprintf(stderr, "can't open %s\n", line); + return(0); + } + crc = 0; + while ((c = getc(f)) != EOF) { + crc = updcrc(c, crc); + } + if (ferror(f)) fprintf(stderr, "read error on %s\n", line); + fclose(f); + return(crc); +} diff --git a/src/simple/kill.c b/src/simple/kill.c new file mode 100755 index 00000000..9ed5474f --- /dev/null +++ b/src/simple/kill.c @@ -0,0 +1,60 @@ +/* Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Most simple built-in commands are here. + */ +#include +#include +#include +#include +#include +#include + +int main(argc, argv) + int argc; + char **argv; +{ + char *cp; + int pid, sig = SIGTERM; + + if (argc < 2) { + fprintf(stderr, "usage: kill [-sig] pid ...\n"); + return 0; + } + if (argv[1][0] == '-') { + cp = &argv[1][1]; + if (!strnicmp(cp, "SIG", 3)) + cp += 3; + if (!strcmp(cp, "HUP")) sig = SIGHUP; + else if (!strcmp(cp, "INT")) sig = SIGINT; + else if (!strcmp(cp, "QUIT")) sig = SIGQUIT; + else if (strcmp(cp, "KILL")) sig = SIGKILL; + else if (strcmp(cp, "TERM")) sig = SIGTERM; + else { + sig = 0; + while (isdecimal(*cp)) + sig = sig * 10 + *cp++ - '0'; + if (*cp) { + fprintf(stderr, "Unknown signal\n"); + return 1; + } + } + argc--; + argv++; + } + while (argc-- > 1) { + cp = *++argv; + pid = 0; + while (isdecimal(*cp)) + pid = pid * 10 + *cp++ - '0'; + if (*cp) { + fprintf(stderr, "Non-numeric pid\n"); + continue; + } + if (kill(pid, sig) < 0) + perror(*argv); + } + return 0; +} + diff --git a/src/simple/lpd.c b/src/simple/lpd.c new file mode 100755 index 00000000..75a4e047 --- /dev/null +++ b/src/simple/lpd.c @@ -0,0 +1,435 @@ +/* lpd 1.5 - Printer daemon Author: Kees J. Bot + * 3 Dec 1989 + */ +#define nil 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if 1 /* Nick */ +#include +#endif + +#ifndef PATH_MAX +#define PATH_MAX 255 +#endif + +#if 1 /* Nick */ +char PRINTER[] = _PATH_PRINTER; +#else +char PRINTER[] = "/dev/lpr"; +#endif +#if 1 /* Nick */ +char HOME[] = "/usr/spool/lpd"; +#else +static /* Nick has made this static, so it doesn't conflict with spool() */ +char SPOOL[] = "/usr/spool/lpd"; +#endif +char LOG[] = "/etc/lpd_log"; + +int mtmpnum = 0; +char jobX[] = "jobXXXXXX"; +char tmpX[] = "tmpXXXXXX"; + +void report(char *mess) +{ + fprintf(stderr, "lpd: %s: %s\n", mess, strerror(errno)); +} + +void fatal(char *mess) +{ + report(mess); + exit(1); +} + +char *mtmpnam(s) + char *s; +{ + do { + mtmpnum += 13; + ultoa(mtmpnum, s + 4, 6); + } while (access(s, 0) != -1); + return s; +} + +void spoolerr(char *file) +{ + unlink(jobX); + unlink(tmpX); + fatal(file); +} + +void spool(char *path) +/* Place a file into the spool directory, either by copying it, or by leaving + * a reference. + */ +{ + char *file; + int j, u; + + mtmpnam(jobX); + file= mtmpnam(tmpX); + +/* if (path[0] == '/') { + int f; + + if ((f= open(path, O_RDONLY)) >= 0) { + close(f); + file= path; + } + } + if (file != path) {*/ + if (path != nil) { + int f; + + if ((f= open(path, O_RDONLY)) < 0) { + report(path); + return; + } + close(f); + file =path; + } else { + int c; + FILE *t; + + if ((t= fopen(tmpX, "w")) == nil) spoolerr(tmpX); + + while ((c= getchar()) != EOF && putc(c, t) != EOF) {} + + if (ferror(stdin)) spoolerr(path); + + if (ferror(t) || fclose(t) == EOF) spoolerr(tmpX); + + fclose(stdin); + } + + if ((j= open(jobX, O_WRONLY|O_CREAT|O_EXCL, 0000)) < 0) spoolerr(jobX); + + u= getuid(); + if (write(j, file, strlen(file)+1) < 0 + || write(j, &u, sizeof(u)) < 0 + || write(j, path, strlen(path)+1) < 0 + || close(j) < 0 + || chmod(jobX, 0600) < 0 + ) spoolerr(jobX); +} + +struct job { + struct job *next; + time_t age; + char name[sizeof(jobX)]; +} *jobs = nil; + +int job(void) +/* Look for print jobs in the spool directory. Make a list of them sorted + * by age. Return true if the list is nonempty. + */ +{ + DIR *spool; + struct dirent *entry; + struct job *newjob, **ajob; + struct stat st; + + if (jobs != nil) return 1; + + if ((spool= opendir(".")) == nil) +#if 1 /* Nick */ + fatal(HOME); +#else + fatal(SPOOL); +#endif + + while ((entry= readdir(spool)) != nil) { + if (strncmp(entry->d_name, "job", 3) != 0) continue; + + if (stat(entry->d_name, &st) < 0 + || (st.st_mode & 0777) == 0000) continue; + + if ((newjob= malloc(sizeof(*newjob))) == nil) fatal("malloc()"); + newjob->age = st.st_mtime; + strcpy(newjob->name, entry->d_name); + + ajob= &jobs; + while (*ajob != nil && convtime(&(*ajob)->age) < convtime(&newjob->age)) + ajob= &(*ajob)->next; + + newjob->next= *ajob; + *ajob= newjob; + } + closedir(spool); + + return jobs != nil; +} + +/* What to do with control-X: + * 0 ignore, + * 1 give up on controlling the printer, assume user knows how printer works, + * 2 print. + */ +char control[] = { + 0, 1, 1, 1, 1, 1, 1, 0, /* \0, ^G don't show. */ + 1, 2, 2, 1, 2, 2, 1, 1, /* \t, \n, \f, \r */ + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 +}; + +int lp; +char buf[BUFSIZ]; +int count, column, line, ncols = 80, nlines = 66; + +int flush(void) +/* Copy the characters in the output buffer to the printer, with retries if + * out of paper. + */ +{ + char *bp= buf; + + while (count > 0) { + int retry = 0, complain = 0; + int r; + + while ((r= write(lp, bp, count)) < 0) { + if (errno != EAGAIN) fatal(PRINTER); + if (retry == complain) { + fprintf(stderr, + "lpd: %s: printer out of paper\n", + PRINTER); + complain= retry + 60; + } + sleep(1); + retry++; + } + bp+= r; + count-= r; + } + count = 0; +} + +int put(int c) +/* Send characters to the output buffer to be printed and do so if the buffer + * is full. Track the position of the write-head in `column' and `line'. + */ +{ + buf[count++] = c; + + if (c == '\f') { + column = 0; + line = 0; + } else + if (c == '\r') { + column = 0; + } else + if (c == '\n') { + line++; + } else { + if (++column > ncols) { line++; column= 1; } + } + if (line == nlines) line= 0; + + if (count == BUFSIZ) { + flush(); + } +} + +void print(FILE *f) +/* Send the contents of an open file to the printer. Expand tabs and change + * linefeed to a carriage-return linefeed sequence. Print a formfeed at the + * end if needed to reach the top of the next page. If a control character + * is printed that we do not know about, then the user is assumed to know + * what they are doing, so output processing is disabled. + */ +{ + int c; + + count= column= line= 0; + + while ((c= getc(f)) != EOF) { + if (c < ' ') { + switch (control[c]) { + case 0: continue; /* Ignore this one. */ + case 1: + /* Can't handle this junk, assume smart user. */ + do { + buf[count++] = c; + if (count == BUFSIZ) flush(); + } while ((c= getc(f)) != EOF); + + flush(); + return; + } + } + if (c == '\n') { + put('\r'); + put('\n'); + } else + if (c == '\t') { + do { + put(' '); + } while (column & 07); + } else + put(c); + } + if (column > 0) { put('\r'); put('\n'); } + if (line > 0) put('\f'); + flush(); + return; +} + +void joberr(char *job) +{ + fprintf(stderr, "lpd: something is wrong with %s\n", job); + + if (unlink(job) < 0) fatal("can't remove it"); +} + +void work(void) +/* Print all the jobs in the job list. */ +{ + FILE *j, *f; + char file[PATH_MAX+1], *pf=file; + int c; + struct job *job; + + job= jobs; + jobs= jobs->next; + + if ((j= fopen(job->name, "r")) == nil) { + joberr(job->name); + return; + } + + do { + if (pf == file + sizeof(file) || (c= getc(j)) == EOF) { + fclose(j); + joberr(job->name); + return; + } + *pf++ = c; + } while (c != 0); + + fclose(j); + + if ((f= fopen(file, "r")) == nil) + fprintf(stderr, "lpd: can't read %s - %s\n", file, strerror(errno)); + else { + print(f); + fclose(f); + } + if (file[0] != '/' && unlink(file) < 0) report(file); + + if (unlink(job->name) < 0) fatal(job->name); + free(job); +} + +void getcap(void) +/* Find the line printer dimensions in the termcap database under "lp". */ +{ + char printcap[1024]; + int n; + + if (tgetent(printcap, "lp") == 1) { + if ((n= tgetnum("co")) > 0) ncols= n; + if ((n= tgetnum("li")) > 0) nlines= n; + } +} + +void haunt(void) +/* Become a daemon, print jobs while there are any, exit. */ +{ + int fd; + time_t timep; + +#if 1 /* Nick */ + if ((fd= open(_PATH_TTY, O_RDONLY)) != -1) { +#else + if ((fd= open("/dev/tty", O_RDONLY)) != -1) { +#endif + /* We have a controlling tty! Disconnect. */ + close(fd); + + switch(fork()) { + case -1: fatal("can't fork"); + case 0: break; + default: exit(0); + } + +#if 1 /* Nick */ + if ((fd= open(_PATH_DEVNULL, O_RDONLY)) < 0) + fatal(_PATH_DEVNULL); +#else + if ((fd= open("/dev/null", O_RDONLY)) < 0) + fatal("/dev/null"); +#endif + dup2(fd, 0); + close(fd); + if ((fd= open(LOG, O_WRONLY)) < 0) + if ((fd =creat(LOG, 0666)) < 0) fatal(LOG); + dup2(fd, 1); + dup2(fd, 2); + close(fd); + time(&timep); +#if 1 /* Nick added localtime(), because asctime takes struct tm, not time_t */ + fprintf(stderr, "--- lpd started %s ---", ctime(&timep)); +#else + fprintf(stderr, "--- lpd started %s ---", asctime(&timep)); +#endif +#ifdef MINIX + setsid(); +#endif + } + + getcap(); + + do { + if ((lp= open(PRINTER, O_WRONLY)) < 0) { + /* Another lpd? */ + if (errno == EBUSY) exit(0); + fatal(PRINTER); + } + + while (job()) work(); + + close(lp); + } while (job()); + exit(0); +} + +int main(int argc, char **argv) +{ + if (argc < 2 && isatty(fileno(stdin))) { + fprintf(stderr, "usage: %s [files | stdin < data]\n", argv[0]); + exit(1); + } + + umask(0077); + +#if 1 /* Nick */ + if (chdir(HOME) < 0) + fatal(HOME); +#else + if (chdir(SPOOL) < 0) + fatal(SPOOL); +#endif + + if (argc < 2 || !strcmp(argv[1],"-")) { + spool(nil); + argc--; + argv++; + } + while (argc > 1) { + if (argv[1][0] != '/') + fprintf(stderr, "lpd: %s: file path must be absolute\n", argv[1]); + else spool(argv[1]); + argc--; + argv++; + } + haunt(); +} diff --git a/src/simple/lpr.c b/src/simple/lpr.c new file mode 100755 index 00000000..c581bb43 --- /dev/null +++ b/src/simple/lpr.c @@ -0,0 +1,55 @@ +#include +#include +#include +#if 1 /* Nick */ +#include +#endif + +main(argc,argv) +int argc; +char *argv[]; +{ + int lpf; + int file; + int cnt; + char *buf; + + buf = (char *)sbrk(BUFSIZ); /* Nick added cast */ + + if (argc != 2) + { + fprintf(stderr,"usage: lpr file\n"); + exit(1); + } + file = open(argv[1],0); + if (file < 0) + { + perror(argv[1]); + exit(1); + } +#if 1 /* Nick */ + lpf = open(_PATH_PRINTER,1); +#else + lpf = open("/dev/lpr",1); +#endif + if (lpf < 0) + { +#if 1 /* Nick */ + perror("lpr: " _PATH_PRINTER); +#else + perror("lpr: /dev/lpr"); +#endif + exit(1); + } + + while ((cnt = read(file,buf,BUFSIZ)) > 0) + write(lpf,buf,cnt); + + if (cnt == -1) + { + perror("lpr: read failed"); + exit(1); + } + + exit(0); +} diff --git a/src/simple/ls.c b/src/simple/ls.c new file mode 100755 index 00000000..3ad0bd7e --- /dev/null +++ b/src/simple/ls.c @@ -0,0 +1,321 @@ +/* ls.c for uzi180, ripped from ucpsub.c and modified by Nick */ + +#include "stdio.h" +#include "types.h" +#include "pwd.h" /* Nick */ +#include "grp.h" /* Nick */ +#include "time.h" /* Nick */ +#include "sys/stat.h" /* Nick stat.h */ +#include "unix.h" /* Nick dir.h */ +#include "syscalls.h" /* Nick to access read() etc */ + +int devdir(int stat); +char *prot(int stat); +char *sizefield(struct stat *statptr); +char *timefield(struct stat *statptr, char *year); +char *inofield(ino_t ino, int inoflag); +void dols(int d, char *path, int wide, char *year, int inoflag); +int xls(char *path, int wide, char *year, int inoflag); +int main(int argc, char **argv); + +int devdir(int stat) + { + stat &= S_IFMT; + + switch (stat) + { + + case S_IFDIR: + return 'd'; + + case S_IFPIPE: + return 'p'; + + case S_IFBLK: + return 'b'; + + case S_IFCHR: + return 'c'; + + case S_IFLNK: + return 'l'; + + } + + return '-'; + } + +char *prot(int stat) + { + static char _prots[8][4] = + { + "---", "--x", "-w-", "-wx", + "r--", "r-x", "rw-", "rwx" + }; + + return _prots[stat & 7]; + } + +#if 1 /* Nick */ +char *sizefield(struct stat *statptr) + { + static char sizebuf[10]; + + if (S_ISDEV(statptr->st_mode)) + { + sprintf(sizebuf, "%4d,%-4d", + MAJOR(statptr->st_rdev), + MINOR(statptr->st_rdev)); + } + else + { + sprintf(sizebuf, "%9ld", statptr->st_size); + } + + return sizebuf; + } + +char *timefield(struct stat *statptr, char *year) + { + char *timeptr; + + timeptr = ctime(&statptr->st_mtime); + + if (strcmp(year, timeptr + 19)) + { + strcpy(timeptr + 11, timeptr + 19); /* replace seconds */ + } + timeptr[16] = 0; /* truncate after seconds or year */ + + return timeptr + 4; + } + +char *inofield(ino_t ino, int inoflag) + { + static char inobuf[7]; + + if (inoflag) + { + sprintf(inobuf, "@%-5d", ino); + return inobuf; + } + + return " "; + } +#endif + +void dols(int d, char *path, int wide, char *year, int inoflag) + { + int i, fd; + direct_t buf; + char dname[512]; + struct stat statbuf; + + while (read(d, (char *) &buf, sizeof(direct_t)) == sizeof(direct_t)) + { + if (buf.d_name[0] == '\0') + continue; + dname[0] = '\0'; + if (strcmp(path, ".")) + { + strcpy(dname, path); + strcat(dname, "/"); + } + strncat(dname, buf.d_name, DIRNAMELEN); + fd = open(dname, O_SYMLINK); + i = (fd >= 0) ? fstat(fd, &statbuf) : + stat(dname, &statbuf); + if (i) + { + printf("ls: can't stat %s\n", dname); + if (fd >= 0) + close(fd); + continue; + } + if ((statbuf.st_mode & S_IFMT) == S_IFDIR) + strcat(dname, "/"); + if (!wide) + { +#if 1 /* Nick */ + printf("%c%s%s%s%4d%s%-8s %-8s%s %s %s", + devdir(statbuf.st_mode), + prot(statbuf.st_mode >> 6), + prot(statbuf.st_mode >> 3), + prot(statbuf.st_mode >> 0), + statbuf.st_nlink, + inofield(statbuf.st_ino, inoflag), + getpwuid(statbuf.st_uid)->pw_name, + getgrgid(statbuf.st_gid)->gr_name, + sizefield(&statbuf), + timefield(&statbuf, year), + dname); +#else + if (S_ISDEV(statbuf.st_mode)) + printf("%3d,%-5d", + MAJOR(statbuf.st_rdev), + MINOR(statbuf.st_rdev)); + else printf("%-9ld", statbuf.st_size); + printf(" %c%s%s%s %2d @%-5u %s", + devdir(statbuf.st_mode), + prot(statbuf.st_mode >> 6), + prot(statbuf.st_mode >> 3), + prot(statbuf.st_mode >> 0), + statbuf.st_nlink, + statbuf.st_ino, + dname); +#endif + if ((statbuf.st_mode & S_IFMT) == S_IFLNK) + { + dname[0] = 0; + i = read(fd, dname, sizeof(dname)-1); + dname[i] = 0; + printf(" -> %s", dname); + close(fd); + } + } + else + { + printf("%s", dname); + i = strlen(dname) + 1; + if ((statbuf.st_mode & S_IFMT) == S_IFLNK) putchar('@'); + else if (((statbuf.st_mode & S_IFMT) != S_IFDIR) && + ((statbuf.st_mode & S_IEXEC) + + (statbuf.st_mode & S_IGEXEC) + + (statbuf.st_mode & S_IOEXEC) != 0)) putchar('*'); + else i--; + if (wide >= 2) + { + if (i < 16) putchar('\t'); + if (i < 8) putchar('\t'); + } + } + if (wide < 2) putchar('\n'); + } + if (wide >= 2) putchar('\n'); +#if 1 /* Nick */ + fflush(stdout); +#endif + } + +int xls(char *path, int wide, char *year, int inoflag) + { + int d; + struct stat statbuf; + + if (stat(path, &statbuf) != 0) + { + printf("ls: can't stat %s\n", path); + /*pse();*/ + } + else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) + { + printf("ls: %s is not a directory\n", path); + /*pse();*/ + } + else if ((d = open(path, 0)) < 0) + { + printf("ls: can't open %s\n", path); + /*pse();*/ + } + else + { + dols(d, path, wide, year, inoflag); + close(d); + } + return 0; +} + +int main(int argc, char **argv) +{ + int j, wide; +#if 1 /* Nick */ + char *p; + time_t now; + char year[7]; + int inoflag; +#endif + +#if 0 /* Nick */ + printf("argc = %d\n", argc); + for (j = 0; j < argc; j++) + { + printf("argv[%d] = \"%s\"\n", j, argv[j]); + } + fflush(stdout); +#endif + + j = 1; + wide = 2; +#if 1 /* Nick */ + inoflag = 0; + + while (j < argc && argv[j][0] == '-') + { + p = argv[j++]; + while (*++p) + { + switch (*p) + { + case 'i': + inoflag = 1; + /* fallthru */ + case 'l': + wide = 0; + break; + default: + printf("usage: ls [-i] [-l] [files...]\n"); + fflush(stdout); + return 1; + } + } + } +#else + if (j < argc) + { + if (strcmp(argv[j], "-l") == 0) + { + wide = 0; + j++; + } + else if (argv[j][0] == '-') + { + printf("usage: ls [-l] [-i] [files...]\n"); + exit(1); + } + } +#endif + + if (wide && isatty(fileno(stdout)) == 0) + { + wide = 1; /* says we should only output a single column */ + } + +#if 1 /* Nick */ + if (wide == 0) + { + time(&now); + strcpy(year, ctime(&now) + 19); + } +#endif + + if (j >= argc) + { + xls(".", wide, year, inoflag); + } + else + { + while (j < argc) + { + xls(argv[j++], wide, year, inoflag); + } + } + +#if 1 /* Nick */ +/* printf("exiting\n"); */ +/* fflush(stdout); */ + return 0; +#else + exit(0); +#endif + } + diff --git a/src/simple/m.bat b/src/simple/m.bat new file mode 100755 index 00000000..de973440 --- /dev/null +++ b/src/simple/m.bat @@ -0,0 +1,37 @@ +cd build-l +@if .%1==. goto failure +call mklink-l %1 ..\ + +iccz80 -S -w -ml -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\%1 +@if errorlevel 1 goto failure +del %1.r01 +as-z80 -l -o %1.s01 +@if errorlevel 1 goto failure + +link-z80 -f %1 +@if errorlevel 1 goto failure +ihex2bin -l %1.i86 ..\..\..\bin\large\%1 +@if errorlevel 1 goto failure + +cd ..\build-b +call mklink-b %1 ..\ + +iccz80 -S -w -mb -v1 -z -A -I..\..\..\include\ -I..\..\kernel\uzi\ -DPC_UZIX_TARGET -DNDEBUG ..\%1 +@if errorlevel 1 goto failure +del %1.r01 +as-z80 -l -o %1.s01 +@if errorlevel 1 goto failure + +link-z80 -f %1 +@if errorlevel 1 goto failure +ihex2bin -l %1.i86 ..\..\..\bin\banked\%1 +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + +cd .. + diff --git a/src/simple/man.c$ b/src/simple/man.c$ new file mode 100755 index 00000000..95840baa --- /dev/null +++ b/src/simple/man.c$ @@ -0,0 +1,1032 @@ +/* (C) Robert de Bath 1997 under the terms of the GPL. + * + * This is a manual pager program, it will search for and format manual + * pages which it then pipes to more. + * + * The program understands manual pages that have been compressed with + * either 'compress' or 'gzip' and will decompress them on the fly. + * + * The environment is checked for these variables: + * MANSECT=1:2:3:4:5:6:7:8:9 # Manual section search order. + * MANPATH=/usrlocal/man:/usr/man # Directorys to search for man tree. + * PAGER=more # pager progam to use. + * PATH=... # Search for gzip/uncompress + * + * The program will display documents that are either in it's own "nroff -man" + * like format or in "catman" format, it will not correctly display pages in + * the BSD '-mdoc' format. + * + * Neither nroff nor any similar program is needed as this program has it's + * own built in _man_ _page_ _formatter_. This is NOT an nroff clone and will + * not (for instance) understand macros or tbl constructs. + * + * Unlike groff this is small, fast and picky! + */ +#define DONT_SPLATTER /* Lots of messages out */ + +#include +#include +#include +#include +#include +#include + +FILE *ofd = stdout; +FILE *ifd = stdin; +int ifd_class = 0; /* Type of ifd, 0=stdin, 1=file, 2=pipe */ + +char whitespace[256]; +char word[80]; /* Current word */ +int no_nl = 1; /* Next NL in input file is ignored */ +int catmode = 1; /* Have we seen a '.XX' command ? */ + +int keep_nl = 0; /* How many nl to keep til eof */ +int optional_keep = 0; /* Is the next keep optional ? */ +int pending_nl = 0; /* Is there a pending newline on output? */ +int no_fill = 0; /* Disable 'filling' of lines */ +int right_adjust = 1; /* Adjust right margin */ + +int standard_tab = 5; /* Amount left margin stepped by */ +int left_indent = 0; /* Current step of left margin */ +int old_para_indent = 0; /* Indent to go back to after this paragraph */ +int next_line_indent = -1; /* Indent after next line_break */ +int page_no = 1; /* Page number */ +int input_tab = 8; /* Tab width in input file */ + +int right_margin = 65; /* Don't print past this column */ +int page_length = 66; /* Lines on page */ +int current_line = 0; /* Line number = ? */ +int gaps_on_line = 0; /* Gaps on line for adjustments */ + +int *line_ptr = 0; +int line[256]; /* Buffer for building output line */ +int cur_font = 0x100; /* Current font, 1 == Roman */ + +char line_header[256] = ""; /* Page header line */ +char line_footer[256] = ""; /* Page footer line */ +char little_header[256] = "";/* Mini header for tty mode */ + +char man_file[256] = ""; + +int flg_w = 0; +int verbose = 1; + +int find_page(char *name, char *sect); +void step(char **pcur, char **pnext); +int open_page(char *name); +void close_page(void); +void do_file(void); +int fetch_word(void); +int do_command(void); +void do_skipeol(void); +int do_fontwords(int this_font, int other_font, int early_exit); +int do_argvcmd(int cmd_id); +int do_noargs(int cmd_id); +void build_headers(void); +void print_word(char *pword); +void line_break(void); +void page_break(void); +void print_header(void); +void print_footer(void); + +int find_page(name, sect) + char *name; + char *sect; +{ +#ifdef __TURBOC__ + static char defpath[] = "w:/util/manpages"; + static char defsect[] = "1;2;3;4;5;6;7;8;9"; + static char defsuff[] = ";.gz;.Z"; + static char manorcat[] = "man;cat"; +#else + static char defpath[] = "/usr/man:/usr/local/man"; + static char defsect[] = "1:2:3:4:5:6:7:8:9"; + static char defsuff[] = ":.gz:.Z"; + static char manorcat[] = "man:cat"; +#endif + + char fbuf[256]; + char *manpath; + char *mansect = sect; + char *mansuff; + char *mc, *mp, *ms, *su, *nmc, *nmp, *nms, *nsu; + int rv = -1; + + manpath = getenv("MANPATH"); + if (!manpath) manpath = defpath; + if (!mansect) mansect = getenv("MANSECT"); + if (!mansect) mansect = defsect; + mansuff = defsuff; + + if (strchr(name, '/')) { + for (su = nsu = mansuff, step(&su, &nsu); su; step(&su, &nsu)) { + strcpy(fbuf, name); + strcat(fbuf, su); + if ((rv = open_page(fbuf)) >= 0) + break; + } + *man_file = 0; + return rv; + } + /* SEARCH!! */ + for (mc = nmc = manorcat, step(&mc, &nmc); mc; step(&mc, &nmc)) { + for (ms = nms = mansect, step(&ms, &nms); ms; step(&ms, &nms)) { + for (mp = nmp = manpath, step(&mp, &nmp); mp; step(&mp, &nmp)) { + for (su = nsu = mansuff, step(&su, &nsu); su; step(&su, &nsu)) { + sprintf(fbuf, "%s/%s%s/%s.%s%s", mp, mc, ms, name, ms, su); + /* Got it ? */ + if (access(fbuf, 0) < 0) + continue; + if (flg_w) { + printf("%s\n", fbuf); + rv = 0; + continue; + } + /* Try it ! */ + if ((rv = open_page(fbuf)) >= 0) { + char *p; + + strcpy(man_file, fbuf); + p = strrchr(man_file, '/'); + if (p) + *p = 0; + p = strrchr(man_file, '/'); + if (p) + p[1] = 0; + return 0; + } + } + } + } + } + return rv; +} + +void step(pcurr, pnext) + char **pcurr, **pnext; +{ + char *curr = *pcurr; + char *next = *pnext; +#ifdef __TURBOC__ + char sep = ';'; +#else + char sep = ':'; +#endif + + if (curr == 0) + return; + if (curr == next) { + next = strchr(curr, sep); + if (next) + *next++ = 0; + } + else { + curr = next; + if (curr) { + curr[-1] = sep; + next = strchr(curr, sep); + if (next) + *next++ = 0; + } + } + *pcurr = curr; + *pnext = next; +} + +int open_page(name) + char *name; +{ + char *p, *command = 0; + + if (access(name, 0) < 0) + return -1; + p = strrchr(name, '.'); + if (p) { + if (strcmp(p, ".gz") == 0) command = "gzip -dc "; + if (strcmp(p, ".Z") == 0) command = "uncompress -c "; + } +#ifndef __TURBOC__ + if (command) { + char buf[256]; + + strcpy(buf, command); + strcat(buf, name); + ifd = popen(buf, "r"); + if (ifd == 0) + return -1; + ifd_class = 2; + return 0; + } +#endif + ifd = fopen(name, "r"); + if (ifd == 0) + return -1; + ifd_class = 1; + return 0; +} + +void close_page() { + switch (ifd_class) { + case 1: fclose(ifd); break; +#ifndef __TURBOC__ + case 2: pclose(ifd); break; +#endif + } + ifd_class = 0; +} + +/**************************************************************************** + * Accepted nroff commands and executors. + */ +struct cmd_list_s { + char cmd[3]; + int class; + int id; +} cmd_list[] = { + { "\\\"", 0, 0 }, + { "nh", 0, 0 }, /* This program never inserts hyphens */ + { "hy", 0, 0 }, /* This program never inserts hyphens */ + { "PD", 0, 0 }, /* Inter-para distance is 1 line */ + { "DT", 0, 0 }, /* Default tabs, they can't be non-default! */ + { "IX", 0, 0 }, /* Indexing for some weird package */ + { "Id", 0, 0 }, /* Line for RCS tokens */ + { "BY", 0, 0 }, /* I wonder where this should go ? */ + { "nf", 0, 1 }, /* Line break, Turn line fill off */ + { "fi", 0, 2 }, /* Line break, Turn line fill on */ + { "sp", 0, 3 }, /* Line break, line space (arg for Nr lines) */ + { "br", 0, 4 }, /* Line break */ + { "bp", 0, 5 }, /* Page break */ + { "PP", 0, 6 }, + { "LP", 0, 6 }, + { "P", 0, 6 }, /* Paragraph */ + { "RS", 0, 7 }, /* New Para + Indent start */ + { "RE", 0, 8 }, /* New Para + Indent end */ + { "HP", 0, 9 }, /* Begin hanging indent (TP without arg?) */ + { "ad", 0, 10 }, /* Line up right margin */ + { "na", 0, 11 }, /* Leave right margin unaligned */ + { "ta", 0, 12 }, /* Changes _input_ tab spacing, right? */ + { "TH", 1, 1 }, /* Title and headers */ + { "SH", 1, 2 }, /* Section */ + { "SS", 1, 3 }, /* Subsection */ + { "IP", 1, 4 }, /* New para, indent except argument 1 */ + { "TP", 1, 5 }, /* New para, indent except line 1 */ + { "B", 2, 22 }, /* Various font fiddles */ + { "BI", 2, 23 }, + { "BR", 2, 21 }, + { "I", 2, 33 }, + { "IB", 2, 32 }, + { "IR", 2, 31 }, + { "RB", 2, 12 }, + { "RI", 2, 13 }, + { "SB", 2, 42 }, + { "SM", 2, 44 }, + { "C", 2, 22 }, /* PH-UX manual pages! */ + { "CI", 2, 23 }, + { "CR", 2, 21 }, + { "IC", 2, 32 }, + { "RC", 2, 12 }, + { "so", 3, 0 }, + { "\0\0", 0 } +}; + +/**************************************************************************** + * ifd is the manual page, ofd is the 'output' file or pipe, format it! + */ +void do_file() { + int nl; + + ungetc('\r', ifd); + fprintf(stderr, "Formatting page, please wait...\n"); + while ((nl = fetch_word()) >= 0) { +#ifdef SPLATTER + fprintf(ofd, ">WS='%s',", whitespace); + fprintf(ofd, "catmode=%d,", catmode); + fprintf(ofd, "nl=%d,", nl); + fprintf(ofd, "no_nl=%d,", no_nl); + fprintf(ofd, "no_fill=%d,", no_fill); + fprintf(ofd, "keep_nl=%d,", keep_nl); + fprintf(ofd, "opt_keep=%d,", optional_keep); + fprintf(ofd, "WD='%s',", word); + fprintf(ofd, "\n"); +#endif + if (catmode) { + if (strcmp(word, "'\\\"") == 0 || + strcmp(word, "'''") == 0) { + /* This is a marker sometimes used for opening + * subprocesses like tbl and equ; this program + * ignores it. + */ + do_skipeol(); + } + else if (*whitespace == '\r') + fprintf(ofd, "%s%s", whitespace + 1, word); + else fprintf(ofd, "%s%s", whitespace, word); + } + else { + if (keep_nl && nl && !no_nl) { + if (optional_keep) { + optional_keep = 0; + if (line_ptr == 0 || + next_line_indent < 0 || + left_indent + (line_ptr - line) + 1 > + next_line_indent) + line_break(); + else if (line_ptr != 0 && + next_line_indent > 0) { + while (left_indent + (line_ptr - line) + 1 <= + next_line_indent) + *line_ptr++ = cur_font + ' '; + } + } + else line_break(); + if (keep_nl > 0) + keep_nl--; + } + if (nl == 1 && + (word[0] == '.' || + (word[0] == '\'' && strcmp(word, "'\\\"") == 0) || + (word[0] == '\'' && strcmp(word, "'''") == 0))) { + no_nl = 1; + if (do_command() < 0) + break; + } + else { + if (nl == 1 && no_fill) + line_break(); + if (*whitespace) + print_word(whitespace); + print_word(word); + no_nl = 0; + } + } + } + page_break(); +} + +int fetch_word() { + static int col = 0; + char *p = whitespace; + int ch, nl = 0; + + *p = 0; + if (!catmode && !no_fill) + p++; + while ((ch = fgetc(ifd)) != EOF && isspace(ch)) { + if (nl && no_fill && ch != '.' && ch != '\n') + break; + if (nl && !catmode && ch == '\n') { + *whitespace = 0; + strcpy(word, ".sp"); + ungetc(ch, ifd); + return 1; + } + nl = (ch == '\n' || ch == '\r'); + if (nl) + col = 0; + else col++; + if (no_fill && nl && *whitespace) { + *word = 0; + ungetc(ch, ifd); + return 0; + } + if (p < whitespace + sizeof(whitespace) - 1 && (!nl || catmode)) + *p++ = ch; + if (ch == '\t' && !catmode) { + p[-1] = ' '; + while (col % input_tab) { + if (p < whitespace + sizeof(whitespace) - 1) + *p++ = ' '; + col++; + } + } + if (!catmode && !no_fill && nl) + *(p = whitespace) = 0; + } + *p = 0; + if (catmode && ch == '.' && nl) + catmode = 0; + + *(p = word) = 0; + if (ch == EOF || p > word + sizeof(word) / 2) { + if (p != word) { + ungetc(ch, ifd); + *p = 0; + return nl; + } + return -1; + } + ungetc(ch, ifd); + while ((ch = fgetc(ifd)) != EOF && !isspace(ch)) { + if (p < word + sizeof(word) - 1) + *p++ = ch; + col++; + if (ch == '\\') { + if ((ch = fgetc(ifd)) == EOF) + break; + /* + * if( ch == ' ' ) ch = ' ' + 0x80; /* XXX Is this + * line needed? + */ + if (p < word + sizeof(word) - 1) + *p++ = ch; + col++; + } + } + *p = 0; + ungetc(ch, ifd); + return (nl != 0); +} + +int do_command() { + char *cmd = word + 1; + char lbuf[10]; + int i; + + /* Comments don't need the space */ + if (strncmp(cmd, "\\\"", 2) == 0) + cmd = "\\\""; + for (i = 0; cmd_list[i].cmd[0]; i++) { + if (strcmp(cmd_list[i].cmd, cmd) == 0) + break; + } + if (cmd_list[i].cmd[0] == 0) { + if (verbose) { + strncpy(lbuf, cmd, 3); + lbuf[3] = 0; + line_break(); + i = left_indent; + left_indent = 0; + strcpy(word, "**** Unknown formatter command: ."); + strcat(word, lbuf); + print_word(word); + line_break(); + left_indent = i; + } + i = 0; /* Treat as comment */ + } + switch (cmd_list[i].class) { + case 1: /* Parametered commands */ + return do_argvcmd(cmd_list[i].id); + + case 2: /* Font changers */ + return do_fontwords(cmd_list[i].id / 10, cmd_list[i].id % 10, 0); + + case 3: /* .so */ + fetch_word(); + strcat(man_file, word); + close_page(); + if (find_page(man_file, (char *) 0) < 0) { + fprintf(stderr, "Cannot open .so file %s\n", word); + return -1; + } + ungetc('\r', ifd); + break; + + default: + do_skipeol(); + if (cmd_list[i].id) + return do_noargs(cmd_list[i].id); + } + return 0; +} + +void do_skipeol() { + int ch; + char *p = word; + + while ((ch = fgetc(ifd)) != EOF && ch != '\n') { + if (p < word + sizeof(word) - 1) + *p++ = ch; + } + *p = 0; + ungetc(ch, ifd); +} + +int do_fontwords(this_font, other_font, early_exit) + int this_font, other_font, early_exit; +{ + static char ftab[] = " RBIS"; + char *p = word; + int i, ch; + int in_quote = 0; + + no_nl = 0; /* Line is effectivly been reprocessed so NL is visable */ + for (;;) { + if (p == word) { + strcpy(p, "\\f"); + p[2] = ftab[this_font]; + p += 3; + } + if ((ch = fgetc(ifd)) == EOF || ch == '\n') + break; + if (ch == '"') { + in_quote = !in_quote; + continue; + } + if (in_quote || !isspace(ch)) { + if (isspace(ch) && p > word + 3) { + strcpy(p, "\\fR"); + p += 3; + *p = 0; + print_word(word); + p = word; + if (no_fill) + print_word(" "); + continue; + } + if (p < word + sizeof(word) - 4) + *p++ = ch; + if (ch == '\\') { + if ((ch = fgetc(ifd)) == EOF || ch == '\n') + break; + if (p < word + sizeof(word) - 4) + *p++ = ch; + } + continue; + } + if (p != word + 3) { + if (early_exit) + break; + if (this_font == other_font) { + strcpy(p, "\\fR"); + p += 3; + *p = 0; + print_word(word); + p = word; + } + i = this_font; + this_font = other_font; + other_font = i; + if (p < word + sizeof(word) - 4) { + strcpy(p, "\\f"); + p[2] = ftab[this_font]; + p += 3; + } + } + } + ungetc(ch, ifd); + if (p > word + 3) { + strcpy(p, "\\fR"); + p += 3; + *p = 0; + print_word(word); + } + return 0; +} + +int do_noargs(cmd_id) + int cmd_id; +{ + if (cmd_id < 10) + line_break(); + switch (cmd_id) { + case 1: + no_fill = 1; + break; + case 2: + no_fill = 0; + break; + case 3: + pending_nl = 1; + break; + case 4: + break; + case 5: + page_break(); + break; + case 6: + left_indent = old_para_indent; + pending_nl = 1; + break; + case 7: + pending_nl = 1; + left_indent += standard_tab; + old_para_indent += standard_tab; + break; + case 8: + pending_nl = 1; + left_indent -= standard_tab; + old_para_indent -= standard_tab; + break; + case 10: + right_adjust = 1; + break; + case 11: + right_adjust = 0; + break; + case 12: + input_tab = atoi(word); + if (input_tab <= 0) + input_tab = 8; + break; + } + return 0; +} + +int do_argvcmd(cmd_id) + int cmd_id; +{ + int ch; + + line_break(); + while ((ch = fgetc(ifd)) != EOF && (ch == ' ' || ch == '\t')) + ; + ungetc(ch, ifd); + switch (cmd_id + 10 * (ch == '\n')) { + case 1: /* Title and headers */ + page_break(); + left_indent = old_para_indent = standard_tab; + build_headers(); + break; + + case 2: /* Section */ + left_indent = 0; + next_line_indent = old_para_indent = standard_tab; + no_nl = 0; + keep_nl = 1; + pending_nl = 1; + + do_fontwords(1, 1, 0); + return 0; + + case 3: /* Subsection */ + left_indent = standard_tab / 2; + next_line_indent = old_para_indent = standard_tab; + no_nl = 0; + keep_nl = 1; + pending_nl = 1; + + do_fontwords(1, 1, 0); + break; + + case 15: + case 5: /* New para, indent except line 1 */ + do_skipeol(); + next_line_indent = old_para_indent + standard_tab; + left_indent = old_para_indent; + pending_nl = 1; + keep_nl = 1; + optional_keep = 1; + break; + + case 4: /* New para, indent except argument 1 */ + next_line_indent = old_para_indent + standard_tab; + left_indent = old_para_indent; + pending_nl = 1; + keep_nl = 1; + optional_keep = 1; + do_fontwords(1, 1, 1); + do_skipeol(); + break; + + case 14: + pending_nl = 1; + left_indent = old_para_indent + standard_tab; + break; + } + return 0; +} + +void build_headers() { + char buffer[5][80]; + int strno = 0, stroff = 0; + int last_ch = 0, ch, in_quote = 0; + + for (ch = 0; ch < 5; ch++) + buffer[ch][0] = 0; + for (;;) { + if ((ch = fgetc(ifd)) == EOF || ch == '\n') + break; + if (ch == '"') { + if (last_ch == '\\') { + stroff--; + break; + } + in_quote = !in_quote; + continue; + } + last_ch = ch; + if (in_quote || !isspace(ch)) { + /* Nb, this does nothing about backslashes, + * perhaps it should + */ + if (stroff < sizeof(buffer[strno]) - 1) + buffer[strno][stroff++] = ch; + continue; + } + buffer[strno][stroff] = 0; + if (buffer[strno][0]) { + strno++; + stroff = 0; + if (strno == 5) + break; + } + } + if (strno < 5) + buffer[strno][stroff] = 0; + ungetc(ch, ifd); + /* Ok we should have upto 5 arguments build the header and footer */ + memset(little_header, ' ', right_margin); + memset(line_header, ' ', right_margin); + strcpy(line_header, buffer[0]); + strcat(line_header, "("); + strcat(line_header, buffer[1]); + strcat(line_header, ")"); + ch = strlen(line_header); + strcpy(line_header + right_margin - ch, line_header); + line_header[ch] = ' '; + ch = strlen(buffer[4]); + if (ch > right_margin) + ch = right_margin - 12; + memcpy(line_header + right_margin / 2 - ch / 2, buffer[4], ch); + memcpy(little_header, line_header, right_margin / 2 + ch / 2 + 1); + strcpy(little_header + right_margin - strlen(buffer[2]), buffer[2]); + memset(line_footer, ' ', right_margin - 6); + line_footer[right_margin - 6] = 0; + memcpy(line_footer, buffer[3], strlen(buffer[3])); + ch = strlen(buffer[2]); + if (ch > right_margin) + ch = right_margin - 12; + memcpy(line_footer + right_margin / 2 - ch / 2, buffer[2], ch); + do_skipeol(); +} + +/* Eat \& \a .. \z and \A .. \Z + * \fX Switch to font X (R B I S etc) + * \(XX Special character XX + * \X Print as X + */ +void print_word(pword) + char *pword; +{ + char *s; + int *d, ch = 0; + int length = 0; + int wword[256]; + int sp_font = cur_font; + + /* Eat and translate characters. */ + for (s = pword, d = wword; *s; s++) { + ch = 0; + if (*s == '\n') + continue; + if (*s != '\\') { + *d++ = (ch = *s) + cur_font; + length++; + } + else { + if (s[1] == 0) + break; + s++; + if (*s == 'f') { + if (s[1]) { + static char fnt[] = " RBI"; + char *p = strchr(fnt, *++s); + if (p == 0) + cur_font = 0x100; + else cur_font = 0x100 * (p - fnt); + } + continue; + } + else if (*s == 's') { + /* Font size adjusts - strip */ + while (s[1] && strchr("+-0123456789", s[1])) + s++; + continue; + } + else if (isalpha(*s) || strchr("!&^[]|~", *s)) + continue; + else if (*s == '(' || *s == '*') { + /* XXX Humm character xlate */ + if (*s == '*' && s[1]) ++s; + if (s[1]) ++s; + if (s[1]) ++s; + *d++ = '*' + cur_font; + length++; + continue; + } + *d++ = *s + cur_font; + length++; + } + } + *d = 0; +#ifdef SPLATTER + { + int *x; + + fprintf(ofd, ">WORD:"); + for (x = wword; *x; x++) + fputc(*x, ofd); + fprintf(ofd, ":\n"); + } +#endif + if (*wword == 0) + return; + if (line_ptr) { + if (line_ptr + (line_ptr[-1] == '.') - line + length >= + right_margin - left_indent) { + right_adjust = -right_adjust; + line_break(); + } + } + if (line_ptr == 0) + line_ptr = line; + else if (!no_fill && (line_ptr[-1] & 0xFF) > ' ') { + if ((line_ptr[-1] & 0xFF) == '.') + *line_ptr++ = cur_font + ' '; + *line_ptr++ = sp_font; + gaps_on_line++; + } + memcpy(line_ptr, wword, length * sizeof(int)); + line_ptr += length; +} + +void line_break() { + int *d, ch; + int spg = 1, rspg = 1, spgs = 0, gap = 0; + + if (line_ptr == 0) + return; + if (current_line == 0) + print_header(); + if (page_length > 12 && + current_line + pending_nl > page_length - 6) { + print_footer(); + print_header(); + } + if (current_line) + current_line += 1 + pending_nl; + for (; pending_nl > 0; pending_nl--) + fprintf(ofd, "\n"); + if (right_adjust < 0) { + int over = right_margin - left_indent - (line_ptr - line); +#ifdef SPLATTER + fprintf(ofd, ">Gaps=%d, Over=%d, ", gaps_on_line, over); +#endif + if (gaps_on_line && over) { + spg = rspg = 1 + over / gaps_on_line; + over = over % gaps_on_line; + if (over) { + if (current_line % 2) { + spgs = over; + spg++; + } + else { + spgs = gaps_on_line - over; + rspg++; + } + } + } +#ifdef SPLATTER + fprintf(ofd, " (%d,%d) sw=%d\n", spg, rspg, spgs); +#endif + right_adjust = 1; + } + *line_ptr = 0; + if (*line) { + for (ch = left_indent; ch > 0; ch--) + fputc(' ', ofd); + } + for (d = line; *d; d++) { + ch = *d; + if ((ch & 0xFF) == 0) { + int i; + if (gap++ < spgs) i = spg; + else i = rspg; + for (; i > 0; i--) + fputc(' ', ofd); + } + else { + switch (ch >> 8) { + case 2: + fputc(ch & 0xFF, ofd); + fputc('\b', ofd); + fputc(ch & 0xFF, ofd); + break; + case 3: + fputc('_', ofd); + fputc('\b', ofd); + fputc(ch & 0xFF, ofd); + break; + default: + fputc(ch & 0xFF, ofd); + break; + } + } + } + fputc('\n', ofd); + line_ptr = 0; + if (next_line_indent > 0) + left_indent = next_line_indent; + next_line_indent = -1; + gaps_on_line = 0; +} + +void page_break() { + line_break(); + if (current_line) + print_footer(); +} + +void print_header() { + pending_nl = 0; + if (*line_header && page_length) { + current_line = 7; + fprintf(ofd, "\n\n\n%s\n\n\n", line_header); + } + else if (*little_header && !page_length) { + current_line = 1; + fprintf(ofd, "%s\n\n", little_header); + } +} + +void print_footer() { + if (!page_length) + return; + while (current_line <= page_length - 3) { + fputc('\n', ofd); + current_line++; + } + fprintf(ofd, "%s%6d\n\n\n", line_footer, page_no++); + current_line = 0; +} + +/**************************************************************************** + * Main routine, hunt down the manpage. + */ +int main(argc, argv) + int argc; + char **argv; +{ + int ar, do_pclose_ofd = 0; + char *mansect = 0; + char *manname = 0; + + for (ar = 1; ar < argc; ar++) { + if (argv[ar][0] == '-') { + char *p; + for (p = argv[ar] + 1; *p; p++) { + switch (*p) { + case 'w': + flg_w = 1; + break; + case 'v': + verbose = 1; + break; + case 'q': + verbose = 0; + break; + } + } + } + else if (isdigit(argv[ar][0])) + mansect = argv[ar]; + else if (manname == 0) + manname = argv[ar]; + else if (mansect == 0) { + mansect = manname; + manname = argv[ar]; + } + else { + fprintf(stderr, "Ignoring argument %s\n", argv[ar]); + break; + } + } + if (manname == 0) { + fprintf(stderr, "Which manpage?\n"); + return 1; + } + if (find_page(manname, mansect) < 0) { + if (mansect != 0) + fprintf(stderr, "No entry for %s in section %s of the manual.\n", + manname, mansect); + else fprintf(stderr, "No manual entry for %s\n", manname); + return 1; + } + if (flg_w) + return 0; + /* ifd is now the file - display it */ + if (isatty(1)) { /* If writing to a tty do it to a pager */ + ofd = 0; +#ifndef __TURBOC__ + if (getenv("PAGER") != 0) + ofd = popen(getenv("PAGER"), "w"); + if (ofd == 0) ofd = popen("more", "w"); +#endif + if (ofd == 0) ofd = stdout; + else { + do_pclose_ofd = 1; + page_length = 0; + right_margin = 78; + } + } + do_file(); + /* Close files */ +#ifndef __TURBOC__ + if (do_pclose_ofd) + pclose(ofd); +#endif + close_page(); + return 0; +} + \ No newline at end of file diff --git a/src/simple/mkdir.c b/src/simple/mkdir.c new file mode 100755 index 00000000..98388422 --- /dev/null +++ b/src/simple/mkdir.c @@ -0,0 +1,94 @@ +/* mkdir.c + */ +#include +#include +#include +#include + +static unsigned short newmode; + +static int make_dir __P((char *name, int f)); +static void wr2 __P((char *s)); + +static int make_dir(name,f) + char *name; + int f; +{ + char *line, iname[256]; + + strcpy(iname, name); + line = rindex(iname,'/'); + if ((line != NULL) && (line != iname) && f) { + while ((line > iname) && (*line == '/')) + --line; + line[1] = 0; + make_dir(iname,1); + } + return mkdir(name, newmode) && !f; +} + +static void wr2(s) + char *s; +{ + write(STDERR_FILENO, s, strlen(s)); +} + +int main (argc,argv) + int argc; + char **argv; +{ + char *p; + int i, n, parent = 0, er = 0; + + newmode = 0666 & ~umask(0); + + argc--; + argv++; + while ((argc > 0) && (**argv == '-')) { + argc--; + p = *argv++ ; + while (*++p) switch (*p) { + case 'm': + argc--; + p = *argv++ ; + if (*p >= '0' && *p <= '7') { + for (newmode = 0; *p >= '0' && *p <= '7'; ++p) { + newmode <<= 3; + newmode += *p - '0'; + } + if (*p) { + wr2("Bad octal mode\n"); + return 1; + } + } + p--; /* *p=0, exit while/switch loop */ + break; + case 'p': + ++parent; + break; + default: + wr2("Unknown option\n"); + return 0; + } + } + + if (argc < 1) { + wr2("usage: mkdir [-p] [-m mode] dirname ...\n"); + return 1; + } + + for (i = 0; i < argc; i++) { + p = argv[i]; + n = strlen(p)-1; + while (p[n] == '/') + p[n--] = '\0'; + if (make_dir(p,parent)) { + wr2("mkdir: cannot create directory "); + wr2(p); + wr2("\n"); + er = 1; + } + } + return er; +} + diff --git a/src/simple/mknod.c b/src/simple/mknod.c new file mode 100755 index 00000000..1eed707c --- /dev/null +++ b/src/simple/mknod.c @@ -0,0 +1,67 @@ +/* mknod.c + */ +#include +#include +#include +#include +#include + +#define makedev(maj, min) (((maj) << 8) | (min)) + +static void wr2 __P((char *s)); + +static void wr2(s) + char *s; +{ + write(STDERR_FILENO, s, strlen(s)); +} + +int main(argc,argv) + int argc; + char **argv; +{ + unsigned newmode, filetype, major = 0, minor = 0; + char *p; + + newmode = 0666 & ~umask(0); + + if (strcmp(argv[1],"-m") == 0) { + argc-=2; + argv+=2; + p = *argv; + if (*p >= '0' && *p <= '7') { + for (newmode = 0; *p >= '0' && *p <= '7'; ++p) { + newmode <<= 3; + newmode += *p - '0'; + } + if (*p) { + wr2("Bad octal mode\n"); + return 1; + } + } + } + if (argc == 2 || argc == 5) { + if (argc == 5) { + switch(argv[2][0]) { + case 'b': filetype = S_IFBLK; break; + case 'c': + case 'u': filetype = S_IFCHR; break; + default: goto Usage; + } + major = atoi(argv[3]); + minor = atoi(argv[4]); + } + else filetype = S_IFREG; + if (mknod(argv[1], newmode | filetype, (major << 8) | minor)) { + wr2("mknod: cannot make device "); + wr2(argv[1]); + wr2("\n"); + return 1; + } + } + else { +Usage: wr2("usage: mknod [-m mode] name [b|c|u major minor]\n"); + } + return 0; +} + diff --git a/src/simple/more.c b/src/simple/more.c new file mode 100755 index 00000000..e6ced718 --- /dev/null +++ b/src/simple/more.c @@ -0,0 +1,196 @@ +/* Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * jun/99: Adriano Cunha + * added piped input capability + * + * set/99: Adriano Cunha + * added next file indication and rewind command + */ +#include +#include +/* Nick #include */ +#include /* Nick */ +#include +#include + +void main(argc, argv) + int argc; + char **argv; +{ + FILE *fp; + int ch, line, col, viastdin = 0, tty = STDIN_FILENO; + char *name, buf[8]; +#if 1 /* Nick */ + struct sgttyb state; + int raw; +#endif + + if (argc < 2) { + if (isatty(STDIN_FILENO)) { + fprintf(stderr, "usage: more filename ...\n"); + return; + } else { + viastdin=1; + argc++; + tty = open(_PATH_CONSOLE, O_RDONLY); + } + } +#if 1 /* Nick */ + if (isatty(tty)) + { + gtty(tty, &state); + raw = state.sg_flags; +#if 1 /* turn off echo etc */ + state.sg_flags = RAW; +#else + state.sg_flags &= ~CBREAK; + state.sg_flags |= RAW; +#endif +/* printf("raw = 0x%x state = 0x%x\n", raw, state.sg_flags); */ + stty(tty, &state); + } +#else + ioctl(tty, TTY_RAW); +#endif + +#if 1 /* Nick */ + while (argc > 1 && argv[1][0] == '-') + { + --argc; + ++argv; + /* do something */ + } +#endif + + while (argc-- > 1) { +Again: if (!viastdin) { + name = *(++argv); + if ((fp = fopen(name, "r")) == NULL) { + perror(name); + continue; + } + printf("<< %s >>\n", name); + } else fp=stdin; + line = 1; + col = 0; + + while (fp && ((ch = fgetc(fp)) != EOF)) { + switch (ch) { + case '\n': +#if 1 /* Nick */ + putchar('\r'); +#endif + line++; + case '\r': + col = 0; + break; + case '\t': +#if 1 /* Nick */ + while ((col & 7) != 7) + { + col++; + putchar(' '); + } + col++; + ch = ' '; +#else + col = ((col + 1) | 0x07) + 1; +#endif + break; + case '\b': + if (col > 0) + col--; + break; + default: + col++; + } + putchar(ch); + if (col >= 80) { + col -= 80; + line++; + } + if (line < 24) + continue; + if (col > 0) + putchar('\n'); + printf("--More--"); + if (argc > 1) + printf(" (Next file: %s)", + *(argv+1) ? *(argv+1) : "none"); + fflush(stdout); + if (read(tty, buf, 1) < 0) { + if (fp) + fclose(fp); + break; + } + col = 0; + ch = buf[0]; + if (ch == ':') { + putchar(':'); + if (read(tty, buf, 1) < 0) { + if (fp) + fclose(fp); + break; + } + ch = buf[0]; + } +#if 1 /* Nick */ + putchar('\r'); +#endif + putchar('\n'); + switch (ch) { + case 'P': + case 'p': + argc += 2; + argv -= 2; + fclose(fp); + fp = NULL; + break; + case 'N': + case 'n': + fclose(fp); + fp = NULL; + break; + case 'Q': + case 'q': + fclose(fp); + goto End; + case '\'': + argc++; + argv--; + fclose(fp); + fp = NULL; + break; + case '\n': + case '\r': + --line; + continue; + } + line = 1; + } + if (col > 0) + { +#if 1 /* Nick */ + putchar('\r'); +#endif + putchar('\n'); + } + if (fp && !viastdin) + fclose(fp); + } +End: +#if 1 /* Nick */ + if (isatty(tty)) + { + state.sg_flags = raw; +/* printf("raw = 0x%x state = 0x%x\n", raw, state.sg_flags); */ + stty(tty, &state); + } +#else + ioctl(tty, TTY_COOKED); +#endif + if (viastdin) close(tty); +} + diff --git a/src/simple/mount.c b/src/simple/mount.c new file mode 100755 index 00000000..edd7078a --- /dev/null +++ b/src/simple/mount.c @@ -0,0 +1,51 @@ +/* Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * jun/99: Adriano Cunha + * added /etc/mtab update + */ +#include +#include +#include + +void main(argc, argv) + int argc; + char **argv; +{ + int ro = 0; + char *str, buf[256]; + FILE *fd; + + argc--; + argv++; + while ((argc > 0) && (**argv == '-')) { + argc--; + str = *argv++ ; + while (*++str) switch (*str) { + case 'r': + ++ro; + break; + default: + fprintf(stderr, "Unknown option\n"); + return; + } + } + if (argc != 2) { + fprintf(stderr, "usage: mount [-r] devname dirname\n"); + return; + } + if (mount(argv[0], argv[1], ro) < 0) { + perror("mount failed"); + return; + } + if (NULL == (fd = fopen("/etc/mtab", "a"))) { + perror("can't update /etc/mtab"); + return; + } + sprintf(buf,"%s\t%s\tr%c\n", argv[0], argv[1], ro ? 'o' : 'w'); + if (fputs(buf, fd) == EOF) + perror("can't update /etc/mtab"); + fclose(fd); +} + diff --git a/src/simple/n.bat b/src/simple/n.bat new file mode 100755 index 00000000..eaa62467 --- /dev/null +++ b/src/simple/n.bat @@ -0,0 +1,196 @@ +md build-l +cd build-l +call mklink-l adduser ..\ +call mklink-l align ..\ +call mklink-l banner ..\ +call mklink-l basename ..\ +call mklink-l cal ..\ +call mklink-l cat ..\ +call mklink-l cdiff ..\ +call mklink-l cgrep ..\ +call mklink-l chgrp ..\ +call mklink-l chmod ..\ +call mklink-l chown ..\ +call mklink-l cksum ..\ +call mklink-l cmp ..\ +call mklink-l cp ..\ +call mklink-l cr ..\ +call mklink-l crc ..\ +call mklink-l cron ..\ +call mklink-l date ..\ +call mklink-l dd ..\ +call mklink-l df ..\ +call mklink-l dhry ..\ +call mklink-l diff ..\ +call mklink-l dirname ..\ +call mklink-l diskusag ..\ +call mklink-l dtree ..\ +call mklink-l du ..\ +call mklink-l echo ..\ +call mklink-l ed ..\ +call mklink-l expr ..\ +call mklink-l false ..\ +call mklink-l fgrep ..\ +call mklink-l file ..\ +call mklink-l find ..\ +call mklink-l fld ..\ +call mklink-l fortune ..\ +call mklink-l grep ..\ +call mklink-l gres ..\ +call mklink-l head ..\ +call mklink-l id ..\ +call mklink-l inodes ..\ +call mklink-l kill ..\ +call mklink-l lpd ..\ +call mklink-l lpr ..\ +call mklink-l ls ..\ +rem call mklink-l man ..\ +call mklink-l mkdir ..\ +call mklink-l mknod ..\ +call mklink-l more ..\ +call mklink-l mount ..\ +call mklink-l ncheck ..\ +rem call mklink-l ncr ..\ +call mklink-l od ..\ +call mklink-l passwd ..\ +call mklink-l pathchk ..\ +call mklink-l pr ..\ +call mklink-l printenv ..\ +call mklink-l ps ..\ +call mklink-l pwd ..\ +call mklink-l readall ..\ +call mklink-l reboot ..\ +call mklink-l renice ..\ +call mklink-l rm ..\ +call mklink-l rmdir ..\ +call mklink-l roff ..\ +call mklink-l setclock ..\ +call mklink-l sort ..\ +call mklink-l split ..\ +call mklink-l su ..\ +call mklink-l sum ..\ +call mklink-l sync ..\ +call mklink-l tail ..\ +call mklink-l tar ..\ +call mklink-l tee ..\ +call mklink-l ter ..\ +call mklink-l termcap ..\ +call mklink-l test ..\ +call mklink-l tget ..\ +call mklink-l time ..\ +call mklink-l top ..\ +call mklink-l touch ..\ +call mklink-l tr ..\ +call mklink-l true ..\ +call mklink-l ualign ..\ +call mklink-l umount ..\ +call mklink-l uname ..\ +call mklink-l uniq ..\ +call mklink-l uudecode ..\ +call mklink-l uuencode ..\ +call mklink-l wc ..\ +call mklink-l which ..\ +call mklink-l whoami ..\ +call mklink-l yes ..\ +copy ..\build-l.ban n.bat +call n +cd .. + +md build-b +cd build-b +call mklink-b adduser ..\ +call mklink-b align ..\ +call mklink-b banner ..\ +call mklink-b basename ..\ +call mklink-b cal ..\ +call mklink-b cat ..\ +call mklink-b cdiff ..\ +call mklink-b cgrep ..\ +call mklink-b chgrp ..\ +call mklink-b chmod ..\ +call mklink-b chown ..\ +call mklink-b cksum ..\ +call mklink-b cmp ..\ +call mklink-b cp ..\ +call mklink-b cr ..\ +call mklink-b crc ..\ +call mklink-b cron ..\ +call mklink-b date ..\ +call mklink-b dd ..\ +call mklink-b df ..\ +call mklink-b dhry ..\ +call mklink-b diff ..\ +call mklink-b dirname ..\ +call mklink-b diskusag ..\ +call mklink-b dtree ..\ +call mklink-b du ..\ +call mklink-b echo ..\ +call mklink-b ed ..\ +call mklink-b expr ..\ +call mklink-b false ..\ +call mklink-b fgrep ..\ +call mklink-b file ..\ +call mklink-b find ..\ +call mklink-b fld ..\ +call mklink-b fortune ..\ +call mklink-b grep ..\ +call mklink-b gres ..\ +call mklink-b head ..\ +call mklink-b id ..\ +call mklink-b inodes ..\ +call mklink-b kill ..\ +call mklink-b lpd ..\ +call mklink-b lpr ..\ +call mklink-b ls ..\ +rem call mklink-b man ..\ +call mklink-b mkdir ..\ +call mklink-b mknod ..\ +call mklink-b more ..\ +call mklink-b mount ..\ +call mklink-b ncheck ..\ +rem call mklink-b ncr ..\ +call mklink-b od ..\ +call mklink-b passwd ..\ +call mklink-b pathchk ..\ +call mklink-b pr ..\ +call mklink-b printenv ..\ +call mklink-b ps ..\ +call mklink-b pwd ..\ +call mklink-b readall ..\ +call mklink-b reboot ..\ +call mklink-b renice ..\ +call mklink-b rm ..\ +call mklink-b rmdir ..\ +call mklink-b roff ..\ +call mklink-b setclock ..\ +call mklink-b sort ..\ +call mklink-b split ..\ +call mklink-b su ..\ +call mklink-b sum ..\ +call mklink-b sync ..\ +call mklink-b tail ..\ +call mklink-b tar ..\ +call mklink-b tee ..\ +call mklink-b ter ..\ +call mklink-b termcap ..\ +call mklink-b test ..\ +call mklink-b tget ..\ +call mklink-b time ..\ +call mklink-b top ..\ +call mklink-b touch ..\ +call mklink-b tr ..\ +call mklink-b true ..\ +call mklink-b ualign ..\ +call mklink-b umount ..\ +call mklink-b uname ..\ +call mklink-b uniq ..\ +call mklink-b uudecode ..\ +call mklink-b uuencode ..\ +call mklink-b wc ..\ +call mklink-b which ..\ +call mklink-b whoami ..\ +call mklink-b yes ..\ +copy ..\build-b.ban n.bat +call n +cd .. + diff --git a/src/simple/ncheck.c b/src/simple/ncheck.c new file mode 100755 index 00000000..c680e826 --- /dev/null +++ b/src/simple/ncheck.c @@ -0,0 +1,218 @@ +/* ncheck name check Author: Raymond Michiels */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef PATH_MAX +#define PATH_MAX 128 +#endif + +ino_t *ilist; +int iflag = 0, aflag = 0, sflag = 0, nr_inodes = 0, opt, skip_len; +char *progname; +char *filesystem = NULL; +char *mnt_point = NULL; +char path[PATH_MAX]; + +extern int optind; +extern char *optarg; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void usage, (void)); +_PROTOTYPE(void myexit, (int n)); +_PROTOTYPE(void readilist, (char *p)); +_PROTOTYPE(int inlist, (ino_t inode)); +_PROTOTYPE(int dotfile, (char *fullname)); +_PROTOTYPE(int toprint, (struct stat *statbuf, char *name)); +_PROTOTYPE(void traverse, (char *dirname)); + +void myexit(n) /* maybe I could use something like _cleanup() */ +int n; +{ + if (filesystem != NULL) + umount(filesystem); + if (mnt_point != NULL) + rmdir(mnt_point); + exit(n); +} + + +void usage() +{ + fprintf(stderr, "usage: %s [ -i numbers] [-s] [-a] file_system\n", progname); + myexit(1); +} + + +void readilist(p) +char *p; +{ + ilist = (ino_t *)malloc(strlen(p)/2+1); + if (ilist == NULL) { + fprintf(stderr, "couldn't malloc i-node list\n"); + myexit(1); + } + do { + if (*p == ',') p++; /* skip comma's */ + if (!isdigit(*p)) { + fprintf(stderr, "malformed i-node list\n"); + myexit(1); + } + ilist[nr_inodes++] = atoi(p); + } while ((p = strchr(p, ',')) != NULL); +} + + +int inlist(inode) +ino_t inode; +{ + int i; + + for (i = 0; i < nr_inodes; i++) { + if (ilist[i] == inode) + return(1); + } + return(0); +} + + +int dotfile(fullname) +char *fullname; +{ + char *name; + + name = strrchr(fullname, '/') + 1; + + return(!(strcmp(name, ".") && strcmp(name, ".."))); +} + + +int toprint(statbuf, name) +struct stat *statbuf; +char *name; +{ +#define S_SPECIAL(x) (x & (S_ISUID | S_ISGID) || S_ISCHR(x) || S_ISBLK(x)) + + return ((!iflag || inlist(statbuf->st_ino)) && + (aflag || !dotfile(name)) && + (!sflag || S_SPECIAL(statbuf->st_mode))); +} + + +void traverse(dirname) +char *dirname; +{ + struct dirent *dirent; + DIR *dir; + struct stat statbuf; + int len; + + len = strlen(dirname); + if (stat(dirname, &statbuf) < 0) { + fprintf(stderr, "could not stat %s: %s\n", dirname, strerror(errno)); + return; + } + if (toprint(&statbuf, dirname)) + printf("%5ld %s\n", (long) statbuf.st_ino, dirname+skip_len); + + if (!dotfile(dirname) && S_ISDIR(statbuf.st_mode)) { + if ((dir = opendir(dirname)) == NULL) { + fprintf(stderr, "could not open %s: %s\n", dirname, + strerror(errno)); + return; + } + dirname[len++] = '/'; + while ((dirent = readdir(dir)) != NULL) { + strcpy(dirname+len, dirent->d_name); + traverse(dirname); + } + closedir(dir); + } +} + + +int main(argc, argv) +int argc; +char *argv[]; +{ + FILE *mtb; + char line[128]; + char mf1[32], mf2[32], mf3[32], mf4[32], mf5[32]; + int r; + + progname = argv[0]; + + while ((opt = getopt(argc, argv, "i:as")) != EOF) { + switch (opt) { + case 'i': + if (nr_inodes > 0) + usage(); + iflag = 1; + readilist(optarg); + break; + case 'a': + aflag = 1; + break; + case 's': + sflag = 1; + break; + } + } + if (optind > argc-1) + usage(); + filesystem = argv[optind]; + + /* See if device is mounted already by searching mtab (old or new) */ + if ((mtb = fopen("/etc/mtab", "r")) == NULL) { + fprintf(stderr, "%s: No /etc/mtab found.\n", progname); + myexit(1); + } + path[0] = '\0'; + while (!feof(mtb)) { /* see if mounted already */ + if (fgets(line, 128, mtb)) { + mf1[0] = mf2[0] = mf3[0] = mf4[0] = mf5[0] = '\0'; + r = sscanf(line, "%s%s%s%s%s", mf1, mf2, mf3, mf4, mf5); + if (!strcmp(filesystem, mf1)) { + if (r > 4) + strcpy(path, mf5); /* hmmm.. old mtab */ + else { + if (!strcmp(mf3, "root")) + strcpy(path, "/"); /* old mtab */ + else + strcpy(path, mf2); /* new mtab */ + } + break; + } + } + } + fclose(mtb); + if (!path[0]) { /* not mounted so mount temporarily */ + mnt_point = tmpnam((char *)NULL); + mkdir(mnt_point, 0777); + if (mount(filesystem, mnt_point, 1) < 0) { + perror("mount"); + myexit(1); + } + strcpy(path, mnt_point); + } + skip_len = strlen(path); + + traverse(path); + myexit(0); + + /* NOTREACHED */ + return(0); +} diff --git a/src/simple/ncr$.c b/src/simple/ncr$.c new file mode 100755 index 00000000..eece0274 --- /dev/null +++ b/src/simple/ncr$.c @@ -0,0 +1,53 @@ +/* + * ncr.c -- remove cr's for cp/m editors + * + * syntax: + * ncr file ... + */ + +#include +#include + +main(argc,argv) +int argc; +char **argv; +{ + register char c,d; + FILE *in,*out; + unsigned fn,j; + char *s; + + if (argc < 2) { + fprintf(stderr,"usage: %s file ...\n",argv[0]); + exit(1); + } + for (j = 1; j +#include +#include +#include +#include + + +int bflag, cflag, dflag, oflag, xflag, hflag, vflag; +int linenr, width, state, ever; +int prevwds[8]; +long off; +char buf[512]; /*, buffer[BUFSIZ];*/ +int next; +int fd; +int bytespresent; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(long offset, (int argc, char *argv [], int k)); +_PROTOTYPE(void dumpfile, (void)); +_PROTOTYPE(void wdump, (short *words, int k, int radix)); +_PROTOTYPE(void bdump, (char bytes [16 ], int k, char c)); +_PROTOTYPE(void byte, (int val, char c)); +_PROTOTYPE(int getwords, (short **words)); +_PROTOTYPE(int same, (short *w1, int *w2)); +_PROTOTYPE(void outword, (int val, int radix)); +_PROTOTYPE(void outnum, (int num, int radix)); +_PROTOTYPE(void addrout, (long l)); +_PROTOTYPE(char hexit, (int k)); +_PROTOTYPE(void usage, (void)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + int k, flags; + char *p; + + /* Process flags */ + fd = fileno(stdin); + flags = 0; + p = argv[1]; + if (argc < 2 && isatty(fileno(stdin))) usage(); + if (argc > 1 && *p == '-') { + /* Flags present. */ + flags++; + p++; + while (*p) { + switch (*p) { + case 'b': bflag++; break; + case 'c': cflag++; break; + case 'd': dflag++; break; + case 'h': hflag++; break; + case 'o': oflag++; break; + case 'v': vflag++; break; + case 'x': xflag++; break; + default: usage(); + } + p++; + } + } else { + oflag = 1; + } + if ((bflag | cflag | dflag | oflag | xflag) == 0) oflag = 1; + k = (flags ? 2 : 1); + if (bflag | cflag) { + width = 8; + } else if (oflag) { + width = 7; + } else if (dflag) { + width = 6; + } else { + width = 5; + } + + /* Process file name, if any. */ + p = argv[k]; + if (k < argc && *p != '+') { + /* Explicit file name given. */ + if ((fd = open(argv[k], O_RDONLY)) <= 0) { + fprintf(stderr, "od: cannot open %s\n", argv[k]); + exit(1); + } + k++; + } + + /* Process offset, if any. */ + if (k < argc) { + /* Offset present. */ + off = offset(argc, argv, k); + off = (off / 16L) * 16L; + lseek(fd, off, SEEK_SET); + } + dumpfile(); + addrout(off); + printf("\n"); + close(fd); + return(0); +} + + +long offset(argc, argv, k) +int argc; +char *argv[]; +int k; +{ + int dot, radix; + char *p, c; + long val; + + /* See if the offset is decimal. */ + dot = 0; + p = argv[k]; + while (*p) + if (*p++ == '.') dot = 1; + + /* Convert offset to binary. */ + radix = (dot ? 10 : 8); + val = 0; + p = argv[k]; + if (*p == '+') p++; + while (*p != 0 && *p != '.') { + c = *p++; + if (c < '0' || c > '9') { + printf("Bad character in offset: %c\n", c); + close(fd); + exit(1); + } + val = radix * val + c - '0'; + } + + p = argv[k + 1]; + if (k + 1 == argc - 1 && *p == 'b') val = 512L * val; + return(val); +} + + +void dumpfile() +{ + int k; + short *words; + + while ((k = getwords(&words))) { /* 'k' is # bytes read */ + if (!vflag) { /* ensure 'lazy' evaluation */ + if (k == 16 && ever == 1 && same(words, prevwds)) { + if (state == 0) { + printf("*\n"); + state = 1; + off += 16; + continue; + } else if (state == 1) { + off += 16; + continue; + } + } + } + addrout(off); + off += k; + state = 0; + ever = 1; + linenr = 1; + if (oflag) wdump(words, k, 8); + if (dflag) wdump(words, k, 10); + if (xflag) wdump(words, k, 16); + if (cflag) bdump((char *)words, k, (int)'c'); + if (bflag) bdump((char *)words, k, (int)'b'); + for (k = 0; k < 8; k++) prevwds[k] = words[k]; + for (k = 0; k < 8; k++) words[k] = 0; + } +} + + +void wdump(words, k, radix) +short *words; +int k, radix; +{ + int i; + + if (linenr++ != 1) printf(" "); + for (i = 0; i < (k + 1) / 2; i++) outword(words[i], radix); + printf("\n"); +} + + +void bdump(bytes, k, c) +char bytes[16]; +int k; +char c; +{ + int i; + + if (linenr++ != 1) printf(" "); + for (i = 0; i < k; i++) byte(bytes[i] & 0377, c); + printf("\n"); +} + +void byte(val, c) +int val; +char c; +{ + if (c == 'b') { + printf(" "); + outnum(val, 7); + return; + } + if (val == 0) + printf(" \\0"); + else if (val == '\b') + printf(" \\b"); + else if (val == '\f') + printf(" \\f"); + else if (val == '\n') + printf(" \\n"); + else if (val == '\r') + printf(" \\r"); + else if (val == '\t') + printf(" \\t"); + else if (val >= ' ' && val < 0177) + printf(" %c", val); + else { + printf(" "); + outnum(val, 7); + } +} + + +int getwords(words) +short **words; +{ + int count; + + if (next >= bytespresent) { + bytespresent = read(fd, buf, 512); + next = 0; + } + if (next >= bytespresent) return(0); + *words = (short *) &buf[next]; + if (next + 16 <= bytespresent) + count = 16; + else + count = bytespresent - next; + + next += count; + return(count); +} + +int same(w1, w2) +short *w1; +int *w2; +{ + int i; + i = 8; + while (i--) + if (*w1++ != *w2++) return(0); + return(1); +} + +void outword(val, radix) +int val, radix; +{ +/* Output 'val' in 'radix' in a field of total size 'width'. */ + + int i; + + if (radix == 16) i = width - 4; + if (radix == 10) i = width - 5; + if (radix == 8) i = width - 6; + if (i == 1) + printf(" "); + else if (i == 2) + printf(" "); + else if (i == 3) + printf(" "); + else if (i == 4) + printf(" "); + outnum(val, radix); +} + + +void outnum(num, radix) +int num, radix; +{ +/* Output a number with all leading 0s present. Octal is 6 places, + * decimal is 5 places, hex is 4 places. + */ + int d, i; + unsigned val; + char s[8]; + + val = (unsigned) num; + if (radix == 8) + d = 6; + else if (radix == 10) + d = 5; + else if (radix == 16) + d = 4; + else if (radix == 7) { + d = 3; + radix = 8; + } + for (i = 0; i < d; i++) { + s[i] = val % radix; + val -= s[i]; + val = val / radix; + } + for (i = d - 1; i >= 0; i--) { + if (s[i] > 9) + printf("%c", 'a' + s[i] - 10); + else + printf("%c", s[i] + '0'); + } +} + + +void addrout(l) +long l; +{ + int i; + + if (hflag == 0) { + for (i = 0; i < 7; i++) + printf("%c", (int) ((l >> (18 - 3 * i)) & 07) + '0'); + } else { + for (i = 0; i < 7; i++) + printf("%c", hexit((int) ((l >> (24 - 4 * i)) & 0x0F))); + } +} + +char hexit(k) +int k; +{ + if (k <= 9) + return('0' + k); + else + return('A' + k - 10); +} + +void usage() +{ + fprintf(stderr, "usage: od [-bcdhovx] [file] [ [+] offset [.] [b] ]\n"); + exit(1); +} diff --git a/src/simple/passwd.c b/src/simple/passwd.c new file mode 100755 index 00000000..de42721f --- /dev/null +++ b/src/simple/passwd.c @@ -0,0 +1,142 @@ +/* passwd.c + * description: change user password + * author: Shane Kerr + * copyright: 1998 by Shane Kerr , under terms of GPL + */ + +/* todo: make executable setuid on execute */ +/* needs to check setuid bit in fs/exec.c of ELKS kernel */ +/* todo: add a set of rules to make sure trivial passwords are not used */ +/* todo: lock password file while updating */ +/* need file locking first */ +/* todo: use rename to do an atomic move of temporary file */ +/* need rename that overwrites first */ + +#include +#include +#include +#include +#include +#include +#include + +/* maximum errors */ +#define MAX_FAILURE 5 + +/* valid characters for a salt value */ +static char salt_char[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; + +int main(argc, argv) + int argc; + char **argv; +{ + char *s, *pbuf, *tmp_fname, *pwf = _PATH_PASSWD; + char salt[3], nbuf1[128], nbuf2[128]; + int n, ch, failure_cnt, uid, gid; + struct passwd *pwd; + FILE *passwd_fp; + time_t now; + + switch (argc) { + case 1: + if ((pwd = getpwuid(getuid())) == NULL) { + fprintf(stderr, "%s: Error reading password file\n", argv[0]); + return 1; + } + break; + case 2: + if ((pwd = getpwnam(argv[1])) == NULL) { + fprintf(stderr, "%s: Unknown user %s\n", argv[0], argv[1]); + return 1; + } + if ((getuid() != 0) && (getuid() != pwd->pw_uid)) { + fprintf(stderr, "You may not change the password for %s.\n", + argv[1]); + return 1; + } + break; + default: + fprintf(stderr, "usage: %s [name]\n", argv[0]); + return 1; + } + + printf("Changing password for %s\n", pwd->pw_name); + + if ((getuid() != 0) && (pwd->pw_passwd[0] != 0)) { + pbuf = getpass("Old password:"); + putchar('\n'); + salt[0] = pwd->pw_passwd[0]; + salt[1] = pwd->pw_passwd[1]; + salt[2] = 0; + if (strcmp(crypt(pbuf, salt), pwd->pw_passwd)) { + fprintf(stderr, "Incorrect password for %s.\n", pwd->pw_name); + return 1; + } + memset(pbuf, 0, strlen(pbuf)); + } + failure_cnt = 0; + for (;;) { + pbuf = getpass("New password:"); + putchar('\n'); + strcpy(nbuf1, pbuf); + pbuf = getpass("Re-enter new password:"); + putchar('\n'); + strcpy(nbuf2, pbuf); + if (strcmp(nbuf1, nbuf2) == 0) { + /* need to create a tmp file for the new password */ + if ((tmp_fname = tmpnam(NULL)) == NULL) { + perror("Error getting temporary file name"); + return 1; + } + if ((passwd_fp = fopen(tmp_fname, "w")) == NULL) { + perror(tmp_fname); + return 1; + } + /* save off our UID */ + uid = pwd->pw_uid; + gid = pwd->pw_gid; + time(&now); + salt[0] = salt_char[(now.t_time) & 0x3F]; + salt[1] = salt_char[(now.t_time >> 6) & 0x3F]; + salt[2] = 0; + s = crypt(nbuf1, salt); + /* save entries to the new file */ + setpwent(); + for (n = 0; (pwd = getpwent()) != NULL; ++n) { + if (pwd->pw_uid == uid && pwd->pw_gid == gid) + pwd->pw_passwd = s; + if (putpwent(pwd, passwd_fp) == -1) { + perror("Error writing password file"); + return 1; + } + } + endpwent(); + /* update the file and move it into position */ + fclose(passwd_fp); + if (n < 1) { + fprintf(stderr, "Can't rewrite %s\n", pwf); + } + strcpy(nbuf2, pwf); + strcat(nbuf2, "~"); + unlink(nbuf2); + if (rename(pwf, nbuf2) == -1) { + perror("Error renaming old password file"); + return 1; + } + if (rename(tmp_fname, pwf) == -1) { + perror("Error installing new password file"); + return 1; + } + /* celebrate our success */ + printf("Password changed.\n"); + return 0; + } + if (++failure_cnt >= MAX_FAILURE) { + fprintf(stderr, "The password for %s is unchanged.\n", pwd->pw_name); + return 1; + } + fprintf(stderr, "They don't match; try again.\n"); + } +} + \ No newline at end of file diff --git a/src/simple/pathchk.c b/src/simple/pathchk.c new file mode 100755 index 00000000..10555ce4 --- /dev/null +++ b/src/simple/pathchk.c @@ -0,0 +1,192 @@ +/* pathchk - check pathnames Author: V. Archer */ + +/* Copyright 1991 by Vincent Archer + * You may freely redistribute this software, in source or binary + * form, provided that you do not alter this copyright mention in any + * way. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef PATH_MAX +#define PATH_MAX 256 +#endif + +#ifndef _POSIX_NAME_MAX +#define _POSIX_NAME_MAX 14 +#define _POSIX_PATH_MAX 255 +#endif + +#ifndef _PC_NAME_MAX +#define _PC_NAME_MAX 14 +#endif + +#define std_err(x) write(STDERR_FILENO, x, strlen(x)) + +#ifndef uid_t +typedef uint uid_t; +#endif + +#ifndef gid_t +typedef uint gid_t; +#endif + +/* Global variables. */ +char directory[PATH_MAX + 1]; +char POSIX_CHAR_SET[] = "\ +.#-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_~"; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void perr, (char *name, char *msg)); +_PROTOTYPE(void usage, (void)); + +/* Perror-like function, but with a user supplied message rather than an + * error one. The standard limits-related messages are not very clear on + * what is wrong. :-) + */ +void perr(name, msg) +char *name, *msg; +{ + std_err(name); + std_err(":"); + std_err(msg); +} + + +/* Main module. Since only one option (-p) is allowed, do not include all + * the getopt() stuff. + */ +int main(argc, argv) +int argc; +char *argv[]; +{ + char *name, *arg; + int pflag, length, maxl; + int rtstat = 0; + uid_t uid; + gid_t gid; + mode_t mask; + struct stat perms; + int Maxname; + + argc--; + argv++; + if (argc && !strcmp(*argv, "-p")) { + argc--; + argv++; + pflag = 1; + } else + pflag = 0; + uid = getuid(); + gid = getgid(); + + if (!argc) usage(); + + while (argc--) { + arg = *argv++; +#if PATH_MAX != _POSIX_PATH_MAX + if (pflag) { + if (strlen(arg) > _POSIX_PATH_MAX) { + perr(arg, "pathname too long for Posix\n"); + rtstat = 1; + continue; + } + } else +#endif + if (strlen(arg) > PATH_MAX) { + perr(arg, "pathname too long\n"); + rtstat = 1; + continue; + } + length = 0; + maxl = 0; + directory[0] = '.'; + directory[1] = '\0'; + if (pflag) { + Maxname = _POSIX_NAME_MAX; + } else +#ifdef MINIX + Maxname = pathconf(directory, _PC_NAME_MAX); +#else + Maxname = _PC_NAME_MAX; +#endif + for (name = arg; *name; name++) { + if (*name == '/') { + if (length > Maxname) break; +/* I do not allow a//b (empty component). Too ugly. */ + if (length == 0 && maxl) { + perr(arg, "empty component\n"); + rtstat = 1; + break; + } + length = 0; + + if (!pflag && directory[0]) { + if (maxl == 0) { + directory[0] = '/'; + directory[1] = '\0'; + } else { + strncpy(directory, arg, (size_t) maxl); + directory[maxl] = '\0'; + } + + if (stat(directory, &perms) == 0) { +#ifdef MINIX + Maxname = pathconf(directory, _PC_NAME_MAX); +#else + Maxname = _PC_NAME_MAX; +#endif + if (uid) { + if (uid == perms.st_uid) + mask = S_IXUSR; + else if (gid == perms.st_gid) + mask = S_IXGRP; + else + mask = S_IXOTH; + if (!(mask & perms.st_mode)) { + perr(arg, "not searchable\n"); + rtstat = 1; + break; + } + } + } else + directory[0] = '\0'; + } + } else { + if (!strchr(POSIX_CHAR_SET, *name)) { + perr(arg, "illegal character\n"); + rtstat = 1; + name = ""; + length = 0; /* do not print 2 msgs */ + break; + } + length++; + } + maxl++; + } + if (length > Maxname) { + perr(arg, pflag ? "component name too long for Posix\n" + : "component name too long\n"); + rtstat = 1; + } + } + return(rtstat); +} + + +/* Posix command prototype. */ +void usage() +{ + std_err("usage: pathchk [-p] file...\n"); + exit(1); +} diff --git a/src/simple/pr.c b/src/simple/pr.c new file mode 100755 index 00000000..02c77372 --- /dev/null +++ b/src/simple/pr.c @@ -0,0 +1,508 @@ +/* Pr - print files + * + * Author: Michiel Huisjes. + * Modified: Jacob P. Bunschoten. (30 nov 87) + * When "columns" is not given and numbering is on: + * line numbers are correlated with input lines. + * (try pr [-1] -n file ) + * tabs are accounted for. + * When numbering is turned on, width know this. + * automatic line-folding. -f to get the original program. + * backspaces are accounted for. -b to disable this. + * multi-column mode changed. + * header can be given and used. + * format changed may occur between printing of several files: + * pr -l30 file1 -w75 file2 + * + * Modified: Rick Thomas. (Sept 12, 1988) + * added "-M" option to cover functionality of old "-n" option, + * and made "-n" option behavior compatible with system V. + * + * Usage: pr [+page] [-columns] [-h header] [-wwidth] [-llength] [-ntm] [files] + * -t : Do not print the 5 line header and trailer at the page. + * -n : Turn on line numbering. + * -M : Use "Minix" style line numbering -- Each page begins at + * a line number that is an even multiple of the page length. + * Like the listings in Appendix E of the book. + * +page : Start printing at page n. + * -columns : Print files in n-columns. + * -l length: Take the length of the page to be n instead of 66 + * -h header: Take next argument as page header. + * -w width : Take the width of the page to be n instead of default 79 + * -f : do not fold lines. + * + * Modified: Lars Fredriksen (Jan 19, 1990) + * fixed the program so that + * pr -n *.c + * would work. The clobal variable 'width' was decremented + * by NUM_WIDTH, for each file, resulting in width finally + * being so small that nothing was printed. Used the local + * variable 'w' for the width adjustment (in print()) + * + * Modified: Kenneth J. Hendrickson (10 April 1991) + * date in header should be last modification date for files, + * and the current time for stdin. + * + * Modified: Kees J. Bot (5 October 1992) + * Use localtime(3) to get the date, it knows TZ. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define DEF_LENGTH 66 +#define DEF_WIDTH 79 +#define NUM_WIDTH 8 +#define TAB_WIDTH 8 /* fixed tab_width */ + +/* Used to compute next (fixed) tabstop */ +#define TO_TAB(x) (( (x) + TAB_WIDTH ) & ~07 ) + +typedef char BOOL; + +#define FALSE 0 +#define TRUE 1 + +/* EAT: eat rest of input line */ +#define EAT(fp) while((c=getc(fp))!='\n' && c!=EOF) + +/* L_BUF: calculate address of pointer to char (string) used in format */ +#define L_BUF(i,j) * (char **) (line_buf + (i + j*length)*sizeof(char *)) + +char *header; +BOOL no_header; +BOOL number = FALSE; +BOOL minix_number = FALSE; +BOOL ext_header_set = FALSE; /* external header given */ +BOOL back_space = TRUE; /* back space correction in line width */ +BOOL dont_fold = FALSE; /* original. If the line does not fit eat it. */ +short columns; +short cwidth; +short start_page = 1; +short width = DEF_WIDTH; +short length = DEF_LENGTH; +short linenr; +char *line_buf; /* used in format for multi-column output */ + +char output[1024]; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(static char *myalloc, (size_t size)); +_PROTOTYPE(char skip_page, (int lines, int width, FILE * filep)); +_PROTOTYPE(void format, (FILE * filep)); +_PROTOTYPE(void print_page, (int pagenr, int maxcol)); +_PROTOTYPE(void print, (FILE * filep)); +_PROTOTYPE(void out_header, (int page)); +_PROTOTYPE(void print_time, (time_t t)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + FILE *file; + char *ptr; + int index = 1; /* index is one ahead of argc */ + int line, col; + + if (isatty(fileno(stdin)) && argc < 2) goto Usage; + setbuf(stdout, output); + do { + if (argc == index) /* No arguments (left) */ + goto pr_files; + + ptr = argv[index++]; + if (*ptr == '+') { + start_page = atoi(++ptr); + continue; + } + if (*ptr != '-') { /* no flags */ + index--; + goto pr_files; + } + if (*++ptr >= '0' && *ptr <= '9') { + columns = atoi(ptr); + if (columns <= 0) columns = 1; + continue; /* Fetch next flag */ + } + while (*ptr) switch (*ptr++) { + case 't': no_header = TRUE; break; + case 'n': + number = TRUE; + minix_number = FALSE; + break; + case 'M': + number = TRUE; + minix_number = TRUE; + break; + case 'h': + header = argv[index++]; + ext_header_set = TRUE; + break; + case 'w': + if ((width = atoi(ptr)) <= 0) width = DEF_WIDTH; + *ptr = '\0'; + break; + case 'l': + if ((length = atoi(ptr)) <= 0) length = DEF_LENGTH; + *ptr = '\0'; + break; + case 'b': /* back_space correction off */ + back_space = FALSE; + break; + case 'f': /* do not fold lines */ + dont_fold = TRUE; + break; + default: +Usage: + fprintf(stderr, "usage: %s [+page] [-columns] [-h header] [-w] [-l] [-nMt] [files]\n", argv[0]); + exit(1); + } + continue; /* Scan for next flags */ + + + /* ============== flags are read. Print the file(s) ========= */ + +pr_files: + + if (!no_header) length -= 10; + + if (columns) { + cwidth = width / columns + 1; + if (columns > width) { + fprintf(stderr, "Too many columns for page width.\n"); + exit(1); + } + + /* Allocate piece of mem to hold some pointers */ + line_buf = myalloc(length * columns * sizeof(char *)); + } + for (line = 0; line < length; line++) + for (col = 0; col < columns; col++) + L_BUF(line, col) = NULL; + + if (length <= 0) { + fprintf(stderr, "Minimal length should be %d\n", no_header ? + 1 : 11); + exit(1); + } + while (index <= argc) { /* print all files, including stdin */ + if (index < argc && (*argv[index] == '-' || *argv[index] == '+')) + break; /* Format change */ + + if (argc == index) { /* no file specified, so stdin */ + if (!ext_header_set) header = ""; + file = stdin; + } else { + if ((file = fopen(argv[index], "r")) == (FILE *) 0) { + fprintf(stderr, "Cannot open %s\n", argv[index++]); + continue; + } + if (!ext_header_set) header = argv[index]; + } + if (columns) + format(file); + else + print(file); + fclose(file); + if (++index >= argc) + break; /* all files (including stdin) done */ + } + if (index >= argc) break; + /* When control comes here. format changes are to be done. + * reinitialize some variables */ + if (!no_header) length += 10; + + start_page = 1; + ext_header_set = FALSE; + if (columns) free(line_buf); + } while (index <= argc); /* "pr -l60" should work too */ + + (void) fflush(stdout); + return(0); +} + +char skip_page(lines, width, filep) +int lines, width; +FILE *filep; +{ + short c; + int char_cnt; + int w; + + do { + w = width; + if (number) /* first lines are shorter */ + if (!columns || /* called from print(file) */ + !(lines % columns)) /* called from format(file) */ + w -= NUM_WIDTH; + + char_cnt = 0; + while ((c = getc(filep)) != '\n' && c != EOF && char_cnt < w) { + /* Calculate if this line is longer than "width (w)" + * characters */ + if (c == '\b' && back_space) { + if (--char_cnt < 0) char_cnt = 0; + } else if (c == '\t') + char_cnt = TO_TAB(char_cnt); + else + char_cnt++; + } + if (dont_fold && c != '\n' && c != EOF) EAT(filep); + lines--; + if (c == '\n') linenr++; + } while (lines > 0 && c != EOF); + + return c; /* last char read */ +} + +void format(filep) +FILE *filep; +{ + char buf[512]; + short c = '\0'; + short index, lines, i; + short page_number = 0; + short maxcol = columns; + short wdth; + short line, col; + + do { + /* Check printing of page */ + page_number++; + + if (page_number < start_page && c != EOF) { + c = (char) skip_page(columns * length, cwidth, filep); + continue; + } + if (c == EOF) return; + + lines = columns * length; + for (line = 0; line < length; line++) + for (col = 0; col < columns; col++) { + if (L_BUF(line, col) != NULL) + free(L_BUF(line, col)); + L_BUF(line, col) = (char *) NULL; + } + line = 0; + col = 0; + do { + index = 0; + wdth = cwidth - 1; + if (number && !col) /* need room for numbers */ + wdth -= NUM_WIDTH; + + /* Intermidiate colums are shortened by 1 char */ + /* Last column not */ + if (col + 1 == columns) wdth++; + for (i = 0; i < wdth - 1; i++) { + c = getc(filep); + if (c == '\n' || c == EOF) break; + + if (c == '\b' && back_space) { + buf[index++] = '\b'; + if (--i < 0) { /* just in case ... */ + i = 0; + index = 0; + } + } else if (c == '\t') { + int cnt, max; + + max = TO_TAB(i); + for (cnt = i; cnt < max; cnt++) + buf[index++] = ' '; + i = max - 1; + } else + buf[index++] = (char) c; + } + buf[index++] = '\0'; + /* Collected enough chars (or eoln, or EOF) */ + + /* First char is EOF */ + if (i == 0 && lines == columns * length && c == EOF) return; + + /* Alloc mem to hold this (sub) string */ + L_BUF(line, col) = myalloc(index * sizeof(char)); + strcpy(L_BUF(line, col), buf); + + line++; + line %= length; + if (line == 0) { + col++; + col %= columns; + } + if (dont_fold && c != '\n' && c != EOF) EAT(filep); + lines--; /* line ready for output */ + if (c == EOF) { + maxcol = columns - lines / length; + } + } while (c != EOF && lines); + print_page(page_number, maxcol); + } while (c != EOF); +} + +void print_page(pagenr, maxcol) +int pagenr, maxcol; +{ + short pad, i, j; + short width; + char *p; + + if (minix_number) + linenr = (pagenr - 1) * length + 1; + else + linenr = 1; + + if (!no_header) out_header(pagenr); + + for (i = 0; i < length; i++) { + for (j = 0; j < maxcol; j++) { + width = cwidth; + if (number && j == 0) { /* first columns */ + printf("%7.7d ", linenr++); /* 7 == NUM_WIDTH-1 */ + width -= NUM_WIDTH; + } + pad = 0; + if (p = (char *) L_BUF(i, j)) + for (; pad < width - 1 && *p; pad++) putchar(*p++); + if (j < maxcol - 1) while (pad++ < width - 1) + putchar(' '); + } + putchar('\n'); + } + if (!no_header) printf("\n\n\n\n\n"); +} + +void print(filep) +FILE *filep; +{ + short c = '\0'; + short page_number = 0; + short lines; + short cnt; + short w = width; + BOOL pr_number = TRUE; /* only real lines are numbered, not folded + * parts */ + + linenr = 1; + if (number) w -= NUM_WIDTH; + + do { + /* Check printing of page */ + page_number++; + + if (page_number < start_page && c != EOF) { + pr_number = FALSE; + c = skip_page(length, w, filep); + if (c == '\n') pr_number = TRUE; + continue; + } + if (c == EOF) return; + + if (minix_number) linenr = (page_number - 1) * length + 1; + + if (page_number == start_page) c = getc(filep); + + /* Print the page */ + lines = length; + while (lines && c != EOF) { + if (lines == length && !no_header) out_header(page_number); + if (number) + if (pr_number) + printf("%7.7d ", linenr++); /* 7 == NUM_WIDTH-1 */ + else + printf("%7c ", ' '); /* 7 == NUM_WIDTH-1 */ + pr_number = FALSE; + cnt = 0; + while (c != '\n' && c != EOF && cnt < w) { + if (c == '\t') { + int i, max; + max = TO_TAB(cnt); + for (i = cnt; i < max; i++) putchar(' '); + cnt = max - 1; + } else if (c == '\b' && back_space) { + putchar('\b'); + cnt--; + } else + putchar(c); + c = getc(filep); + cnt++; + } + putchar('\n'); + if (dont_fold && c != '\n' && c != EOF) EAT(filep); + lines--; + if (c == '\n') { + c = getc(filep); + pr_number = TRUE; + } + } + if (lines == length) /* We never printed anything on this + * page -- */ + return; /* even the header, so dont try to fill it up */ + if (!no_header) /* print the trailer -- 5 blank lines */ + printf("\n\n\n\n\n"); + } while (c != EOF); + + /* Fill last page */ + if (page_number >= start_page) { + while (lines--) putchar('\n'); + } +} + +static char *myalloc(size) +size_t size; /* How many bytes */ +{ + void *ptr; + + ptr = malloc(size); + if (ptr == NULL) { + fprintf(stderr, "malloc returned NULL\n"); + exit(1); + } + return(char *) ptr; +} + +void out_header(page) +int page; +{ + time_t t; + struct stat buf; + + if (strlen(header)) { + stat(header, &buf); /* use last modify time for file */ + t = buf.st_mtime; + } else + time(&t); /* use current time for stdin */ + print_time(t); + printf(" %s Page %d\n\n\n", header, page); +} + +char *moname[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +/* Print the date. */ +void print_time(t) +time_t t; +{ + struct tm *tm; + + tm = localtime(&t); + + printf("\n\n%s %2d %2d:%02d %d", + moname[tm->tm_mon], + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + 1900 + tm->tm_year + ); +} diff --git a/src/simple/printenv.c b/src/simple/printenv.c new file mode 100755 index 00000000..e0afeba0 --- /dev/null +++ b/src/simple/printenv.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * Most simple built-in commands are here. + */ + +#include +#include + +void +main(argc, argv) + char **argv; +{ + char **env; + extern char **environ; + int len; + + env = environ; + + if (argc == 1) { + while (*env) + printf("%s\n", *env++); + return; + } + + len = strlen(argv[1]); + while (*env) { + if ((strlen(*env) > len) && (env[0][len] == '=') && + (memcmp(argv[1], *env, len) == 0)) + { + printf("%s\n", &env[0][len+1]); + return; + } + env++; + } +} diff --git a/src/simple/ps.c b/src/simple/ps.c new file mode 100755 index 00000000..da6d5c4e --- /dev/null +++ b/src/simple/ps.c @@ -0,0 +1,240 @@ +/* ps.c + * descripton: show processes status + * author: Archi Schekochikhin + * modified by: Adriano Cunha + * added the many formats (Archi's version had only one) + * license: GNU Public License version 2 + */ + +/* obs: options X, w and c not implemented + * option n affects only username + */ + +#include +#include +#include +#include +#include +#include + +#define M_l 'l' /* long format */ +#define M_u 'u' /* user format */ +#define M_s 's' /* signals format */ +#define M_m 'm' /* memory info format */ +#define M_X 'X' /* eXecution format */ + +#define F_a 0x01 /* all users flag */ +#define F_c 0x02 /* command flag */ +#define F_w 0x04 /* wide output flag */ +#define F_h 0x08 /* no header flag */ +#define F_r 0x10 /* running only flag */ +#define F_n 0x20 /* numeric output flag */ + +int mode = 0; +int flags = 0; + +void do_ps __P((void)); +char *mapstat __P((pstate_t)); + +char *mapstat(s) + pstate_t s; +{ + switch (s) { + case P_ZOMBIE: return "Zombie"; + case P_FORKING: return "Forking"; + case P_RUNNING: return "Running"; + case P_READY: return "Ready"; + case P_SLEEP: return "Sleep"; + case P_PAUSE: return "Pause"; + case P_WAIT: return "Waitfor"; + } + return "Undef"; +} + +/* UZIX t_time is not just counting seconds... + * so, dirty conversion routines are here: + */ + +unsigned long ticks2seconds(time_t *t) { + return (t->t_time/CLOCKS_PER_SEC)+(t->t_date*60); +} + +time_t seconds2uzixtime(unsigned long t) { + int y=0,m=0,d=0,h=0,mm=0; + unsigned long t1=t; + time_t tt; + + if (t1>=31536000) { + y=t1/31536000L; + t1=t1-(y*31536000L); + y=y-10; + } + if (t1>=2592000) { + m=t1/2592000L; + t1=t1-(m*2592000L); + m++; + } + if (t1>=86400) { + d=t1/86400; + t1=t1-d*86400; + d++; + } + if (t1>=3600) { + h=t1/3600; + t1=t1-h*3600; + } + if (t1>=60) { + mm=t1/60; + t1=t1-m*60; + } + tt.t_time=(((int)h << 8) << 3) | ((int)mm << 5) | ((int)t1 >> 1); + tt.t_date=(((int)y << 8) << 1) | ((int)m << 5) | d; + return tt; +} + +void do_ps() { + info_t info; + ptptr p; + int i, j, uid; + struct s_pdata pdata; + struct s_kdata kdata; + char *str; + char stime[9], cputime[9], pmem, pcpu; + char nuser[5], username[9], pssize[5]; + int useridknown = 0, userid = 0; + struct passwd *pwd; + int totalram; + time_t temptime; + signal_t psignal; + unsigned long ptimes; + unsigned char pri; +#define psize 32 /* UZIX: all processes have 32k size */ +#define ptty 0 /* UZIX: only one tty now */ + + getfsys(GI_PTAB, &info); + getfsys(GI_KDAT, &kdata); + totalram = kdata.k_tmem; + stime[8] = '\0'; + cputime[8] = '\0'; + strcpy(nuser,"USER"); + if (flags & F_n) { + strcpy(nuser, "UID"); + useridknown = 1; + } + uid = getuid(); + if (!(flags & F_h)) { + if (mode == 0) printf(" PID\tTTY\tSTAT\tTIME COMMAND\n"); + if (mode == M_l) printf("%-8s PID PRI NI SIZE WCHAN STAT TTY\tTIME ALARM\tCOMMAND\n",nuser); + if (mode == M_u) printf("%-8s PID %CPU %MEM TTY\tSTAT\tSTART TIME COMMAND\n",nuser); + if (mode == M_s) printf("%-8s PID SIGNAL PENDING IGNORED STAT\tTTY\tTIME COMMAND\n",nuser); + if (mode == M_m) printf(" PID PPID TTY\tSIZE\tSTAT\tCOMMAND\n"); + } + for (p = (ptptr)info.ptr, i = 0; i < info.size; ++i, ++p) { + if (p->p_status == 0 || (!(flags & F_a) && (p->p_uid != uid))) + continue; + if ((flags & F_r) && + (p->p_status != P_RUNNING && p->p_status != P_READY)) + continue; + pdata.u_pid = p->p_pid; + /* dependent data from getfsys(pdata) */ + if (p->p_status != P_ZOMBIE) { + if (getfsys(GI_PDAT, &pdata) < 0) + continue; + psignal = pdata.u_cursig; + /* start time of process */ + str = ctime(&pdata.u_time); + strncpy(stime, &str[11], 8); + /* process CPU time */ + ptimes = ticks2seconds(&pdata.u_utime); + temptime = seconds2uzixtime(ptimes); + str = ctime(&temptime); + strncpy(cputime, &str[11],8); + /* %CPU */ + time(&temptime); + pcpu = (ptimes*100)/difftime(&temptime, &pdata.u_time); + } else { + psignal = 0; + strcpy(stime, "--:--:--"); + strcpy(cputime, "--:--:--"); + pcpu = 0; + strcpy(pdata.u_name, "?"); + } + pri = p->p_cprio; + /* user id */ + if (!useridknown || (p->p_uid != userid)) { + if ((pwd = getpwuid(p->p_uid)) != NULL) + strcpy(username, pwd->pw_name); + else sprintf(username, "%-5d", p->p_uid); + userid = p->p_uid; + useridknown = 1; + } + /* you must calculate psize here */ + /* %MEM */ + pmem = (psize*100)/totalram; + /* convert pmem to a string terminated by k or M */ + j = psize; /* process size in kbytes */ + if (j < 1000) { /* I know that 1Mb=1024kb, but who cares? */ + sprintf(pssize, "%3dk", j); + } + else { + j /= 1024; /* too dirty... do it better! */ + sprintf(pssize, "%3dM", j); + } + /* show info */ + if (mode == 0) printf("%5d\t%d\t%s\t%s %s\n", + p->p_pid, ptty, mapstat(p->p_status), cputime, + pdata.u_name); + if (mode == M_l) printf("%-8s %-5d %-3d %-3d %-4s %04X %-7s %-3d\t%s %-5d %s\n", + username, p->p_pid, pri, p->p_nice, pssize, p->p_wait, + mapstat(p->p_status), ptty, cputime, + p->p_alarm, pdata.u_name); + if (mode == M_u) printf("%-8s %-5d %2d%c %2d%c %d\t%s\t%s %s %s\n", + username, p->p_pid, pcpu, '%', pmem, '%', ptty, + mapstat(p->p_status), stime, cputime, pdata.u_name); + if (mode == M_s) printf("%-8s %-5d %-6d %-7d %-7d %s\t%d\t%s %s\n", + username, p->p_pid, psignal, p->p_pending, p->p_ignored, + mapstat(p->p_status), ptty, cputime, pdata.u_name); + if (mode == M_m) printf(" %-5d %-5d %d\t\t%s\t%s\t%s\n", + p->p_pid, p->p_pptr->p_pid, ptty, pssize, mapstat(p->p_status), + pdata.u_name); + } + fflush(stdout); +} + +int main(argc, argv) + int argc; + char **argv; +{ + int i; + + for (i = 1; i < argc; ++i) { + char *p = argv[i]; + + if (*p == '-') + ++p; + while (*p) switch (*p++) { + case 'l': + case 'u': + case 's': + case 'm': + /*case 'X':*/ + if (mode != 0) { + fprintf(stderr, "ps: l, u, s and m are mutually exclusive\n"); + return 0; + } + mode = p[-1]; + case 'a': flags |= F_a; break; + /*case 'c': flags |= F_c; break;*/ + /*case 'w': flags |= F_w; break;*/ + case 'h': flags |= F_h; break; + case 'r': flags |= F_r; break; + case 'n': flags |= F_n; break; + default: + fprintf(stderr, "usage: ps [-][lusmahrn]\n"); + return 0; + } + } + do_ps(); + return 0; +} + diff --git a/src/simple/pwd.c b/src/simple/pwd.c new file mode 100755 index 00000000..2c74adbb --- /dev/null +++ b/src/simple/pwd.c @@ -0,0 +1,13 @@ +/* pwd.c + */ +#include +#include + +void main() { + char wd[PATHLEN]; + + getcwd(wd,PATHLEN-1); + write(STDOUT_FILENO, wd, strlen(wd)); + write(STDOUT_FILENO, "\n", 1); +} + \ No newline at end of file diff --git a/src/simple/readall.c b/src/simple/readall.c new file mode 100755 index 00000000..0d1a283e --- /dev/null +++ b/src/simple/readall.c @@ -0,0 +1,154 @@ +/* readall - read a whole device fast Author: Andy Tanenbaum */ + +/* Readall reads all the blocks on a device as fast as it can. If it hits + * an error, it stops reading in large units and reads one block at a time. + * It reports on all errors it finds. + * + * If the -b flag is given, the output is a shell script that can be run + * to mark all the bad blocks. + * + * If the -t flag is given, only the total numbers of blocks is reported. + * + * Examples of usage: + * readall /dev/hd1 # read /dev/hd1 + * readall -b /dev/hd2 # prepare bad block list on stdout + * readall -t /dev/ram # report size of ram disk + */ + +#include +#include +#include +#include +#include + +#define CHUNK 25 /* max number of blocks read at once */ +#define BLOCK_SIZE 512 /* size of a block */ +#define RESUME 50 /* # good reads before going back to CHUNK */ +#define DIVISOR 50 /* how often to print statistics */ +#define STORE 288 /* save this many bad blocks for summary */ + +int chunk = CHUNK; /* current number of blocks being read */ +long goodies; /* incremented on good reads */ +long errors; /* number of errors so far */ +int normal = 1; /* set unless -b flag is given */ +int total = 0; /* unset unless -t flag is given */ +char *name; /* name of special file being read */ + +#if 1 /* Nick */ +char buf[CHUNK * BLOCK_SIZE]; /* read buffer */ +#else +char a[CHUNK * BLOCK_SIZE]; /* read buffer */ +#endif +long rotten[STORE]; /* list of bad blocks */ + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +static _PROTOTYPE(void output, (long blocks_read)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + int fd, s, i, badprinted; + long b = 0; + char *p; + + if (argc != 2 && argc != 3) { + fprintf(stderr, "usage: readall [-b | -t] file\n"); + exit(1); + } + i = 1; + + p = argv[1]; + if (*p == '-' && *(p + 1) == 'b' && *(p + 2) == '\0') { + normal = 0; + i++; + name = argv[i]; + } + if (*p == '-' && *(p + 1) == 't' && *(p + 2) == '\0') { + normal = 0; + total = 1; + i++; + name = argv[i]; + } + fd = open(argv[i], O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s is not readable\n", argv[i]); + exit(1); + } + + /* Read the entire file. Try it in large chunks, but if an error + * occurs, go to single reads for a while. */ + while (1) { + lseek(fd, BLOCK_SIZE * b, SEEK_SET); + printf("will read %d blocks from %d sector\n", chunk, b); +#if 1 /* Nick */ + s = read(fd, buf, BLOCK_SIZE * chunk); +#else + s = read(fd, a, BLOCK_SIZE * chunk); +#endif + if (s == BLOCK_SIZE * chunk) { + /* Normal read, no errors. */ + b += chunk; + goodies++; + if (chunk == 1) { + if (goodies >= RESUME && b % DIVISOR == 0) + chunk = CHUNK; + } + } else if (s < 0) { + /* I/O error. */ + if (chunk != 1) { + chunk = 1; /* regress to single block mode */ + continue; + } + if (errors == STORE) { + fprintf(stderr, + "\n%ld Bad blocks is too many. Exiting\n", + errors); + exit(1); + } + rotten[(int) errors] = b; /* log the error */ + b += chunk; + errors++; + } else { + /* End of file. */ +printf("read only %d blocks (%d bytes)\n", s, s / BLOCK_SIZE); + b += s / BLOCK_SIZE; +printf("last block read is %d\n", b); + if (normal) { + output(b); + fprintf(stderr, "\n"); + } + if (total) printf("%8ld\n", b); + if ((errors == 0) || total) exit(0); + badprinted = 0; + if (normal) printf("Summary of bad blocks\n"); + + /* Print summary of bad blocks, possibly as shell script. */ + for (i = 0; i < errors; i++) { + if (normal == 0 && badprinted == 0) { + printf("badblocks %s ", name); + badprinted = 1; + } + printf("%6ld ", rotten[i]); + if ((i + 1) % 7 == 0) { + printf("\n"); + badprinted = 0; + } + } + printf("\n"); + exit(0); + } + if (normal && b % DIVISOR == 0) output(b); + } +} + +static void output(blocks_read) +long blocks_read; +{ +/* fprintf(stderr, "%8ld blocks read, %5ld errors\r", blocks_read, errors);*/ + fflush(stderr); +} diff --git a/src/simple/reboot.c b/src/simple/reboot.c new file mode 100755 index 00000000..9bdc7e17 --- /dev/null +++ b/src/simple/reboot.c @@ -0,0 +1,29 @@ +/* reboot.c for UZI180 */ + +#include +#include +#include +#include + +int main(void) + { + char *s = "\n\aSystem is going to reboot NOW!\a\n"; + + write(fileno(stdin), s, strlen(s)); + sync(); +#if 1 /* Nick, it was rather silly anyway, but useful for a test - reinstate */ + reboot('m','e'); + perror("reboot"); + return errno; +#else + sleep(3); + sync(); + sync(); + if (reboot('m','e')) + { + perror("reboot"); + return (errno); + } +#endif + } + diff --git a/src/simple/renice.c b/src/simple/renice.c new file mode 100755 index 00000000..6ea265e6 --- /dev/null +++ b/src/simple/renice.c @@ -0,0 +1,102 @@ +/* renice.c vr. 1.0 + * descripton: change processes priority + * author: Adriano Cunha + * license: GNU Public License version 2 + */ + +#include +#include +#include +#include +#include +#include + +#define CHG_PID 1 +#define CHG_GRP 2 +#define CHG_USER 3 +#define NONE 0 + +int verifynice(char nice) { + if (nice < -20 || nice > 19) { + printf("renice: invalid priority value\n"); + exit(1); + } +} + +int main(argc, argv) + int argc; + char **argv; +{ + char *pp, *nicestr; + char oldnice, nice, useridknown, niced; + char mode = CHG_PID; + info_t info; + ptptr p; + int i, value, err = 0; + struct passwd *pwd; + struct s_pdata pdata; + + argc--; + argv++; + if (argc < 2) { + printf("usage: renice [+]prio [[-p] pid...] [-g pgrp...] [-u user...]\n"); + exit(1); + } + nicestr = *argv++; + verifynice(nice = atoi(nicestr)); + argc--; + getfsys(GI_PTAB, &info); + while (argc > 0) { + argc--; + pp = *argv++ ; + if (!strcmp("-p", pp)) { + mode = CHG_PID; + continue; + } + if (!strcmp("-g", pp)) { + mode = CHG_GRP; + continue; + } + if (!strcmp("-u", pp)) { + mode = CHG_USER; + continue; + } + value = atoi(pp); + if (mode == CHG_USER) { + if ((pwd = getpwnam(pp)) != NULL) value = pwd->pw_uid; + else { + printf("renice: unknown user %s\n", pp); + exit(1); + } + } + niced = 0; + for (p = (ptptr)info.ptr, i = 0; i < info.size; ++i, ++p) { + if (p->p_status < P_READY) continue; + if (mode == CHG_PID && p->p_pid != value) continue; + if (mode == CHG_USER && p->p_uid != value) continue; + if (mode == CHG_GRP) { + pdata.u_pid = p->p_pid; + if (getfsys(GI_PDAT, &pdata) < 0) continue; + if (pdata.u_gid != value) continue; + } + oldnice = p->p_nice; + nice = atoi(nicestr); + if (*nicestr == '+') nice = oldnice + atoi(++nicestr); + verifynice(nice); + if (setprio(p->p_pid, nice) < 0) { + printf("PID %d: %s\n", p->p_pid, strerror(errno)); + err = 1; + } + niced = 1; + } + if (!niced) { + printf("renice: no process found with"); + if (mode == CHG_PID) printf(" pid %d\n", value); + if (mode == CHG_GRP) printf(" group id %d\n", value); + if (mode == CHG_USER) printf(" owner %s\n", pp); + err = 1; + } + } + return (err); +} + diff --git a/src/simple/rm.c b/src/simple/rm.c new file mode 100755 index 00000000..31876eb9 --- /dev/null +++ b/src/simple/rm.c @@ -0,0 +1,265 @@ +/* +** rm [-firv] file ... +*/ + +#include +#include +#include /* Nick added sys/ prefix */ +#include /* Nick to call waitpid() for wait() */ +#include /* silly silly */ +#include /* silly silly */ +/* #include */ + +int errcode; + + + +main(argc, argv) +char *argv[]; +{ + register char *arg; + int fflg, iflg, rflg; +#if 1 /* Nick */ + int vflg; +#endif + + fflg = 0; + if (isatty(0) == 0) + fflg++; + iflg = 0; + rflg = 0; + while(argc>1 && argv[1][0]=='-') { + arg = *++argv; + argc--; + + /* + * all files following a null option are considered file names + */ + if (*(arg+1) == '\0') break; + + while(*++arg != '\0') + switch(*arg) { + case 'f': + fflg++; + break; + case 'i': + iflg++; + break; + case 'r': + rflg++; + break; +#if 1 /* Nick */ + case 'v': + vflg++; + break; +#endif + default: + printf("rm: unknown option %s\n", *argv); +#if 1 /* Nick */ + fflush(stdout); + return 1; +#else + exit(1); +#endif + } + } + while(--argc > 0) { + if(!strcmp(*++argv, "..")) { + fprintf(stderr, "rm: cannot remove `..'\n"); +#if 1 /* Nick */ + fflush(stderr); +#endif + continue; + } +#if 1 /* Nick */ + rm(*argv, fflg, rflg, iflg, vflg); +#else + rm(*argv, fflg, rflg, iflg); +#endif + } + +#if 1 /* Nick */ + return errcode; +#else + exit(errcode ? 2:0); +#endif +} + + +#if 1 /* Nick */ +rm(arg, fflg, rflg, iflg, vflg) +#else +rm(arg, fflg, rflg, iflg) +#endif +char arg[]; +{ + struct stat buf; + struct direct dir; /* Nick direct */ + char name[100]; + int d; + + if(stat(arg, &buf)) { + if (fflg==0) { + fprintf(stderr, "rm: %s non-existent\n", arg); +#if 1 /* Nick */ + fflush(stderr); +#endif + ++errcode; + } + return; + } + if ((buf.st_mode&S_IFMT) == S_IFDIR) { + if(rflg) { + if(iflg && !dotname(arg)) { + printf("directory %s: ? ", arg); + if(!yes()) + return; + } + if((d=open(arg, 0)) < 0) { + fprintf(stderr, "rm: cannot read %s\n", arg); +#if 1 /* Nick */ + fflush(stderr); +#endif + exit(2); + } + while(read(d, &dir, sizeof(dir)) == sizeof(dir)) { /* Nick direct */ + if(dir.d_ino != 0 && !dotname(dir.d_name)) { /* Nick direct */ + sprintf(name, "%s/%.14s", arg, dir.d_name); /* Nick direct */ +#if 1 /* Nick */ + rm(name, fflg, rflg, iflg, vflg); +#else + rm(name, fflg, rflg, iflg); +#endif + } + } + close(d); +#if 1 /* Nick */ + if (rmdir(arg, iflg)) + { + if (fflg == 0 || vflg || iflg) + { + fprintf(stderr, "rm: directory %s not removed. ", arg); + fflush(stderr); + perror(""); + ++errcode; + } + } + else + { + if (vflg || iflg) + { + printf("rmdir %s\n", arg); + fflush(stdout); + } + } +#else + errcode += rmdir(arg, iflg); +#endif + return; + } + fprintf(stderr, "rm: %s directory\n", arg); +#if 1 /* Nick */ + fflush(stderr); +#endif + ++errcode; + return; + } + + if(iflg) { + printf("%s: ? ", arg); + if(!yes()) + return; + } + else if(!fflg) { + if(access(arg, 02) < 0 && isatty(fileno(stdin))) { + printf("%s: %o mode ? ", arg, buf.st_mode&0777); + if(!yes()) + return; + } + } +#if 1 /* Nick */ + if (unlink(arg)) + { + if (fflg == 0 || vflg || iflg) + { + fprintf(stderr, "rm: %s not removed. ", arg); + fflush(stderr); + perror(""); + ++errcode; + } + } + else + { + if (vflg || iflg) + { + printf("rm %s\n", arg); + fflush(stdout); + } + } +#else + if(unlink(arg) && (fflg==0 || iflg)) { + fprintf(stderr, "rm: %s not removed. ", arg); + perror(""); + ++errcode; + } +#endif +} + +dotname(s) +char *s; +{ + if((s[0]&0177) == '.') + if((s[1]&0177) == '.') + if(s[2] == '\0' || (s[2]&0177) == '/') + return(1); + else + return(0); + else if(s[1] == '\0') + return(1); + return(0); +} + +rmdir(f, iflg) +char *f; +{ + extern char **environ; + static char *argv[] = { "rmdir", 0, 0}; + + int status, i; + + if(dotname(f)) + return(0); + if(iflg) { + printf("%s: ? ", f); + if(!yes()) + return(0); + } + while((i=fork()) == -1) + sleep(3); + if(i) { + wait(&status); + return(status); + } +/* execl("/bin/rmdir", "rmdir", f, 0); */ + argv[1] = f; + execve("/bin/rmdir", argv, environ); + printf("No rmdir\n"); + exit(2); +} + +yes() +{ + int i, b; + +#if 1 /* Nick */ + fflush(stdout); +#endif + i = b = getchar(); + while(b != '\n' && b > 0) + b = getchar(); +#if 1 /* Nick */ + return((i == 'y') || (i == 'Y')); +#else + return(i == 'y'); +#endif +} diff --git a/src/simple/rmdir.c b/src/simple/rmdir.c new file mode 100755 index 00000000..764abaa9 --- /dev/null +++ b/src/simple/rmdir.c @@ -0,0 +1,63 @@ +/* rmdir.c + */ +#include +#include +#include +#include + +unsigned short newmode; + +static void wr2 __P((char *s)); + +static void wr2(s) + char *s; +{ + write(STDERR_FILENO, s, strlen(s)); +} + +int remove_dir(name, f) + char *name; + int f; +{ + int er, era = 2; + char *line; + + while ((er = rmdir(name)) == 0 && + (line = rindex(name, '/')) != NULL && + f) { + while (line > name && *line == '/') + *line-- = 0; + era = 0; + } + return (er && era); +} + +int main(argc, argv) + int argc; + char **argv; +{ + char *p; + int i, n, parent = 0, er = 0; + + if (argv[1][0] == '-' && argv[1][1] == 'p') + parent = 1; + newmode = 0666 & ~umask(0); + for (i = parent + 1; i < argc; i++) { + p = argv[i]; + n = strlen(p)-1; + if (p[0] != '-') { + while (p[n] == '/') + p[n--] = '\0'; + if (remove_dir(p, parent)) { + perror(argv[0]); + er = 1; + } + } + else { + wr2("usage: rmdir [-p] directory...\n"); + return 1; + } + } + return er; +} + \ No newline at end of file diff --git a/src/simple/roff.c b/src/simple/roff.c new file mode 100755 index 00000000..a8f9360e --- /dev/null +++ b/src/simple/roff.c @@ -0,0 +1,1569 @@ +/* roff - text justifier Author: George L. Sicherman */ + +/* + * roff - C version. + * the Colonel. 19 May 1983. + * + * Copyright 1983 by G. L. Sicherman. + * You may use and alter this software freely for noncommercial ends + * so long as you leave this message alone. + * + * Fix by Tim Maroney, 31 Dec 1984. + * .hc implemented, 8 Feb 1985. + * Fix to hyphenating with underlining, 12 Feb 1985. + * Fixes to long-line hang and .bp by Dave Tutelman, 30 Mar 1985. + * Fix to centering valve with long input lines, 4 May 1987. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SUFTAB "/usr/lib/suftab" +#define TXTLEN (o_pl-o_m1-o_m2-o_m3-o_m4-2) +#define IDTLEN (o_ti>=0?o_ti:o_in) +#define MAXMAC 64 +#define MAXDEPTH 10 +#define MAXLENGTH 255 +#define UNDERL '\200' + +/* undefine this if your terminal can be controled by tcgetattr/tcsetattr */ +#define NO_TERM_CONTROL + +char cumbuf[BUFSIZ]; + +char spacechars[] = " \t\n"; +int sflag, hflag, startpage, stoppage; +char holdword[MAXLENGTH], *holdp; +char assyline[MAXLENGTH]; +int assylen; +char ehead[100], efoot[100], ohead[100], ofoot[100]; +struct macrotype { + char mname[3]; + long int moff; +} macro[MAXMAC]; +int n_macros; +int depth; +int adjtoggle; +int isrequest = 0; +char o_tr[40][2]; /* OUTPUT TRANSLATION TABLE */ +int o_cc = '.'; /* CONTROL CHARACTER */ +int o_hc = -1; /* HYPHENATION CHARACTER */ +int o_tc = ' '; /* TABULATION CHARACTER */ +int o_in = 0; /* INDENT SIZE */ +int o_ix = -1; /* NEXT INDENT SIZE */ +int o_ta[20] = { + 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, + 113, 121, 129, 137, 145, 153, 161}; +int n_ta = 20; /* #TAB STOPS */ +int o_ll = 65, o_ad = 1, o_po = 0, o_ls = 1, o_ig = 0, o_fi = 1; +int o_pl = 66, o_ro = 0, o_hx = 0, o_bl = 0, o_sp = 0, o_sk = 0; +int o_ce = 0, o_m1 = 2, o_m2 = 2, o_m3 = 1, o_m4 = 3, o_ul = 0; +int o_li = 0, o_n1 = 0, o_n2 = 0, o_bp = -1, o_hy = 1; +int o_ni = 1; /* LINE-NUMBER INDENT */ +int o_nn = 0; /* #LINES TO SUPPRESS NUMBERING */ +int o_ti = -1; /* TEMPORARY INDENT */ +int page_no = -1; +int line_no = 9999; +int n_outwords; +FILE *File, *Macread, *Macwrite; +FILE *Save; +long int teller[MAXDEPTH]; +char *request[] = { + "ad", "ar", "bl", "bp", "br", "cc", "ce", "de", + "ds", "ef", "eh", "fi", "fo", "hc", "he", "hx", "hy", "ig", + "in", "ix", "li", "ll", "ls", "m1", "m2", "m3", "m4", + "n1", "n2", "na", "ne", "nf", "ni", "nn", "nx", "of", "oh", + "pa", "pl", "po", "ro", "sk", "sp", "ss", "ta", "tc", "ti", + "tr", "ul", 0}; +char *mfilnam = "/tmp/rtmXXXXXX"; +#if 1 /* Nick */ +int ch; +#else +int c; /* LAST CHAR READ */ +#endif +#ifndef NO_TERM_CONTROL +struct termios tty; +#endif + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void mesg, (int f)); +_PROTOTYPE(void readfile, (void)); +_PROTOTYPE(int readline, (void)); +_PROTOTYPE(void bumpword, (void)); +_PROTOTYPE(void dehyph, (char *s)); +_PROTOTYPE(int reallen, (char *s)); +_PROTOTYPE(void tabulate, (void)); +_PROTOTYPE(int readreq, (void)); +_PROTOTYPE(void snset, (int *par)); +_PROTOTYPE(int tread, (char *s)); +_PROTOTYPE(void nread, (int *i)); +_PROTOTYPE(int snread, (int *i, int *s, int sdef)); +_PROTOTYPE(int cread, (int *k)); +_PROTOTYPE(void defmac, (void)); +_PROTOTYPE(void openmac, (void)); +_PROTOTYPE(int copyline, (void)); +_PROTOTYPE(void submac, (int r)); +_PROTOTYPE(void endmac, (void)); +_PROTOTYPE(void do_ta, (void)); +_PROTOTYPE(void do_tr, (void)); +_PROTOTYPE(void do_nx, (void)); +_PROTOTYPE(int skipsp, (void)); +_PROTOTYPE(void writebreak, (void)); +_PROTOTYPE(void blankline, (void)); +_PROTOTYPE(void writeline, (int adflag, int flushflag)); +_PROTOTYPE(void fillline, (void)); +_PROTOTYPE(void insrt, (int p)); +_PROTOTYPE(void newpage, (void)); +_PROTOTYPE(void beginpage, (void)); +_PROTOTYPE(void endpage, (void)); +_PROTOTYPE(void blankpage, (void)); +_PROTOTYPE(void waitawhile, (void)); +_PROTOTYPE(void nix, (int sig)); +_PROTOTYPE(void writetitle, (char *t)); +_PROTOTYPE(char *pgform, (void)); +_PROTOTYPE(int titlen, (char *t, char c, int k)); +_PROTOTYPE(void spits, (char *s)); +_PROTOTYPE(void spit, (char c)); +_PROTOTYPE(int suck, (void)); +_PROTOTYPE(char *strhas, (char *p, char c)); +_PROTOTYPE(char *strend, (char *p)); +_PROTOTYPE(int isspace, (int c)); +_PROTOTYPE(int isalnum, (int c)); +_PROTOTYPE(int isdigit, (int c)); +_PROTOTYPE(int islegal, (int c)); +_PROTOTYPE(void bomb, (void)); + +int main(argc, argv) +int argc; +char **argv; +{ + if (isatty(fileno(stdin)) && argc < 2) bomb(); + if (!isatty(1)) setbuf(stdout, cumbuf); + while (--argc) switch (**++argv) { + case '+': startpage = atoi(++*argv); break; + case '-': + ++*argv; + if (isdigit(**argv)) + stoppage = atoi(*argv); + else + switch (**argv) { + case 's': sflag++; break; + case 'h': hflag++; break; + default: bomb(); + } + break; + default: + argc++; + goto endargs; + } +endargs: +#ifndef NO_TERM_CONTROL + if (sflag) tcgetattr(0, &tty); +#endif + mesg(0); /* BLOCK OUT MESSAGES */ + assylen = 0; + assyline[0] = '\0'; + if (!argc) { + File = stdin; + readfile(); + } else + while (--argc) { + File = fopen(*argv, "r"); + if (NULL == File) { + fprintf(stderr, "roff: cannot read %s\n", *argv); + exit(1); + } + readfile(); + fclose(File); + argv++; + } + writebreak(); + endpage(); + for (; o_sk; o_sk--) blankpage(); + mesg(1); /* ALLOW MESSAGES */ + return(0); +} + +void mesg(f) +int f; +{ + static int mode; + struct stat cbuf; + + if (!isatty(1)) return; + if (!f) { + fstat(1,&cbuf); + mode = cbuf.st_mode; + chmod(ttyname(1),mode & ~022); + } + else chmod(ttyname(1),mode); +/* ------- end of mesg */ +} + +void readfile() +{ + while (readline()) { + if (isrequest) continue; + if (o_ce || !o_fi) { + if (assylen) + writeline(0, 1); + else + blankline(); + if (o_ce) o_ce--; + } + } +} + +int readline() +{ + int startline, doingword; + isrequest = 0; + startline = 1; + doingword = 0; + +#if 1 /* Nick */ + ch = suck(); + if (ch == '\n') { +#else + c = suck(); + if (c == '\n') { +#endif + o_sp = 1; + writebreak(); + goto out; +#if 1 /* Nick */ + } else if (isspace(ch)) +#else + } else if (isspace(c)) +#endif + writebreak(); + for (;;) { +#if 1 /* Nick */ + if (ch == EOF) { +#else + if (c == EOF) { +#endif + if (doingword) bumpword(); + break; + } +#if 1 /* Nick */ + if (ch != o_cc && o_ig) { + while (ch != '\n' && ch != EOF) ch = suck(); +#else + if (c != o_cc && o_ig) { + while (c != '\n' && c != EOF) c = suck(); +#endif + break; + } +#if 1 /* Nick */ + if (isspace(ch) && !doingword) { +#else + if (isspace(c) && !doingword) { +#endif + startline = 0; +#if 1 /* Nick */ + switch (ch) { +#else + switch (c) { +#endif + case ' ': + assyline[assylen++] = ' '; + break; + case '\t': tabulate(); break; + case '\n': goto out; + } +#if 1 /* Nick */ + ch = suck(); +#else + c = suck(); +#endif + continue; + } +#if 1 /* Nick */ + if (isspace(ch) && doingword) { +#else + if (isspace(c) && doingword) { +#endif + bumpword(); +#if 1 /* Nick */ + if (ch == '\t') +#else + if (c == '\t') +#endif + tabulate(); + else if (assylen) + assyline[assylen++] = ' '; + doingword = 0; +#if 1 /* Nick */ + if (ch == '\n') break; +#else + if (c == '\n') break; +#endif + } +#if 1 /* Nick */ + if (!isspace(ch)) { +#else + if (!isspace(c)) { +#endif + if (doingword) +#if 1 /* Nick */ + *holdp++ = o_ul ? ch | UNDERL : ch; + else if (startline && ch == o_cc && !o_li) { +#else + *holdp++ = o_ul ? c | UNDERL : c; + else if (startline && c == o_cc && !o_li) { +#endif + isrequest = 1; + return readreq(); + } else { + doingword = 1; + holdp = holdword; +#if 1 /* Nick */ + *holdp++ = o_ul ? ch | UNDERL : ch; +#else + *holdp++ = o_ul ? c | UNDERL : c; +#endif + } + } + startline = 0; +#if 1 /* Nick */ + ch = suck(); +#else + c = suck(); +#endif + } +out: + if (o_ul) o_ul--; + if (o_li) o_li--; +#if 1 /* Nick */ + return ch != EOF; +#else + return c != EOF; +#endif +} + +/* + * bumpword - add word to current line. + */ + +void bumpword() +{ + char *hc; + *holdp = '\0'; +/* + * Tutelman's fix #1, modified by the Colonel. + */ + if (!o_fi || o_ce) goto giveup; +/* + * We use a while-loop in case of ridiculously long words with + * multiple hyphenation indicators. + */ + if (assylen + reallen(holdword) > o_ll - IDTLEN) { + if (!o_hy) + writeline(o_ad, 0); + else + while (assylen + reallen(holdword) > o_ll - IDTLEN) { +/* + * Try hyphenating it. + */ + if (o_hc && strhas(holdword, o_hc)) { +/* + * There are hyphenation marks. Use them! + */ + for (hc = strend(holdword); hc >= holdword; hc--) { + if ((*hc & ~UNDERL) != o_hc) + continue; + *hc = '\0'; + if (assylen + reallen(holdword) + 1 > + o_ll - IDTLEN) { + *hc = o_hc; + continue; + } + +/* + * Yay - it fits! + */ + dehyph(holdword); + strcpy(&assyline[assylen], holdword); + strcat(assyline, "-"); + assylen += strlen(holdword) + 1; + strcpy(holdword, ++hc); + break; /* STOP LOOKING */ + } /* for */ +/* + * It won't fit, or we've succeeded in breaking the word. + */ + writeline(o_ad, 0); + if (hc < holdword) goto giveup; + } else { +/* + * If no hyphenation marks, give up. + * Let somebody else implement it. + */ + writeline(o_ad, 0); + goto giveup; + } + } /* while */ + } +giveup: +/* + * remove hyphenation marks, even if hyphenation is disabled. + */ + if (o_hc) dehyph(holdword); + strcpy(&assyline[assylen], holdword); + assylen += strlen(holdword); + holdp = holdword; +} + +/* + * dehyph - remove hyphenation marks. + */ + +void dehyph(s) +char *s; +{ + char *t; + for (t = s; *s; s++) + if ((*s & ~UNDERL) != o_hc) *t++ = *s; + *t = '\0'; +} + +/* + * reallen - length of a word, excluding hyphenation marks. + */ + +int reallen(s) +char *s; +{ + register int n; + n = 0; + while (*s) n += (o_hc != (~UNDERL & *s++)); + return n; +} + +void tabulate() +{ + int j; + for (j = 0; j < n_ta; j++) + if (o_ta[j] - 1 > assylen + IDTLEN) { + for (; assylen + IDTLEN < o_ta[j] - 1; assylen++) + assyline[assylen] = o_tc; + return; + } + + /* NO TAB STOPS REMAIN */ + assyline[assylen++] = o_tc; +} + +int readreq() +{ + char req[3]; + int r, s; + +#if 1 /* Nick */ + if (skipsp()) return ch != EOF; + ch = suck(); + if (ch == EOF || ch == '\n') return ch != EOF; + if (ch == '.') { +#else + if (skipsp()) return c != EOF; + c = suck(); + if (c == EOF || c == '\n') return c != EOF; + if (c == '.') { +#endif + o_ig = 0; + do +#if 1 /* Nick */ + (ch = suck()); + while (ch != EOF && ch != '\n'); +#else + (c = suck()); + while (c != EOF && c != '\n'); +#endif + if (depth) endmac(); +#if 1 /* Nick */ + return ch != EOF; +#else + return c != EOF; +#endif + } + if (o_ig) { +#if 1 /* Nick */ + while (ch != EOF && ch != '\n') + ch = suck(); + return ch != EOF; +#else + while (c != EOF && c != '\n') c = suck(); + return c != EOF; +#endif + } +#if 1 /* Nick */ + req[0] = ch; + ch = suck(); + if (ch == EOF || ch == '\n') +#else + req[0] = c; + c = suck(); + if (c == EOF || c == '\n') +#endif + req[1] = '\0'; + else +#if 1 /* Nick */ + req[1] = ch; +#else + req[1] = c; +#endif + req[2] = '\0'; + for (r = 0; r < n_macros; r++) + if (!strcmp(macro[r].mname, req)) { + submac(r); + goto reqflsh; + } + for (r = 0; request[r]; r++) + if (!strcmp(request[r], req)) break; + if (!request[r]) { + do +#if 1 /* Nick */ + (ch = suck()); + while (ch != EOF && ch != '\n'); + return ch != EOF; +#else + (c = suck()); + while (c != EOF && c != '\n'); + return c != EOF; +#endif + } + switch (r) { + case 0: /* ad */ + o_ad = 1; + writebreak(); + break; + case 1: /* ar */ o_ro = 0; break; + case 2: /* bl */ + nread(&o_bl); + writebreak(); + break; + case 3: /* bp */ + case 37: /* pa */ +#if 1 /* Nick */ + ch = snread(&r, &s, 1); +#else + c = snread(&r, &s, 1); +#endif +/* + * Tutelman's fix #2 - the signs were reversed! + */ + if (s > 0) + o_bp = page_no + r; + else if (s < 0) + o_bp = page_no - r; + else + o_bp = r; + writebreak(); + if (line_no) { + endpage(); + beginpage(); + } + break; + case 4: /* br */ writebreak(); break; + case 5: /* cc */ +#if 1 /* Nick */ + ch = cread(&o_cc); +#else + c = cread(&o_cc); +#endif + break; + case 6: /* ce */ +/* + * Fix to centering. Set counter _after_ breaking! --G.L.S. + */ + nread(&r); + writebreak(); + o_ce = r; + break; + case 7: /* de */ defmac(); break; + case 8: /* ds */ + o_ls = 2; + writebreak(); + break; + case 9: /* ef */ +#if 1 /* Nick */ + ch = tread(efoot); +#else + c = tread(efoot); +#endif + break; + case 10: /* eh */ +#if 1 /* Nick */ + ch = tread(ehead); +#else + c = tread(ehead); +#endif + break; + case 11: /* fi */ + o_fi = 1; + writebreak(); + break; + case 12: /* fo */ +#if 1 /* Nick */ + ch = tread(efoot); +#else + c = tread(efoot); +#endif + strcpy(ofoot, efoot); + break; + case 13: /* hc */ +#if 1 /* Nick */ + ch = cread(&o_hc); +#else + c = cread(&o_hc); +#endif + break; + case 14: /* he */ +#if 1 /* Nick */ + ch = tread(ehead); +#else + c = tread(ehead); +#endif + strcpy(ohead, ehead); + break; + case 15: /* hx */ o_hx = 1; break; + case 16: /* hy */ nread(&o_hy); break; + case 17: /* ig */ o_ig = 1; break; + case 18: /* in */ + writebreak(); + snset(&o_in); + o_ix = -1; + break; + case 19: /* ix */ + snset(&o_ix); + if (!n_outwords) o_in = o_ix; + break; + case 20: /* li */ nread(&o_li); break; + case 21: /* ll */ snset(&o_ll); break; + case 22: /* ls */ snset(&o_ls); break; + case 23: /* m1 */ nread(&o_m1); break; + case 24: /* m2 */ nread(&o_m2); break; + case 25: /* m3 */ nread(&o_m3); break; + case 26: /* m4 */ nread(&o_m4); break; + case 27: /* n1 */ o_n1 = 1; break; + case 28: /* n2 */ nread(&o_n2); break; + case 29: /* na */ + o_ad = 0; + writebreak(); + break; + case 30: /* ne */ + nread(&r); + if (line_no + (r - 1) * o_ls + 1 > TXTLEN) { + writebreak(); + endpage(); + beginpage(); + } + break; + case 31: /* nf */ + o_fi = 0; + writebreak(); + break; + case 32: /* ni */ snset(&o_ni); break; + case 33: /* nn */ snset(&o_nn); break; + case 34: /* nx */ + do_nx(); +#if 1 /* Nick */ + ch = '\n'; /* SO WE DON'T FLUSH THE FIRST LINE */ +#else + c = '\n'; /* SO WE DON'T FLUSH THE FIRST LINE */ +#endif + break; + case 35: /* of */ +#if 1 /* Nick */ + ch = tread(ofoot); +#else + c = tread(ofoot); +#endif + break; + case 36: /* oh */ +#if 1 /* Nick */ + ch = tread(ohead); +#else + c = tread(ohead); +#endif + break; + case 38: /* pl */ snset(&o_pl); break; + case 39: /* po */ snset(&o_po); break; + case 40: /* ro */ o_ro = 1; break; + case 41: /* sk */ nread(&o_sk); break; + case 42: /* sp */ + nread(&o_sp); + writebreak(); + break; + case 43: /* ss */ + writebreak(); + o_ls = 1; + break; + case 44: /* ta */ do_ta(); break; + case 45: /* tc */ +#if 1 /* Nick */ + ch = cread(&o_tc); +#else + c = cread(&o_tc); +#endif + break; + case 46: /* ti */ + writebreak(); +#if 1 /* Nick */ + ch = snread(&r, &s, 0); +#else + c = snread(&r, &s, 0); +#endif + if (s > 0) + o_ti = o_in + r; + else if (s < 0) + o_ti = o_in - r; + else + o_ti = r; + break; + case 47: /* tr */ do_tr(); break; + case 48: /* ul */ nread(&o_ul); break; + } +reqflsh: +#if 1 /* Nick */ + while (ch != EOF && ch != '\n') + ch = suck(); + return ch != EOF; +#else + while (c != EOF && c != '\n') c = suck(); + return c != EOF; +#endif +} + +void snset(par) +int *par; +{ + int r, s; +#if 1 /* Nick */ + ch = snread(&r, &s, 0); +#else + c = snread(&r, &s, 0); +#endif + if (s > 0) + *par += r; + else if (s < 0) + *par -= r; + else + *par = r; +} + +int tread(s) +char *s; +{ + int leadbl; + leadbl = 0; + for (;;) { +#if 1 /* Nick */ + ch = suck(); + if (ch == ' ' && !leadbl) continue; + if (ch == EOF || ch == '\n') { +#else + c = suck(); + if (c == ' ' && !leadbl) continue; + if (c == EOF || c == '\n') { +#endif + *s = '\0'; +#if 1 /* Nick */ + return ch; +#else + return c; +#endif + } +#if 1 /* Nick */ + *s++ = ch; +#else + *s++ = c; +#endif + leadbl++; + } +} + +void nread(i) +int *i; +{ + int f; + f = 0; + *i = 0; + if (!skipsp()) for (;;) { +#if 1 /* Nick */ + ch = suck(); + if (ch == EOF) + break; + if (isspace(ch)) + break; + if (isdigit(ch)) { +#else + c = suck(); + if (c == EOF) break; + if (isspace(c)) break; + if (isdigit(c)) { +#endif + f++; +#if 1 /* Nick */ + *i = *i * 10 + ch - '0'; +#else + *i = *i * 10 + c - '0'; +#endif + } else + break; + } + if (!f) *i = 1; +} + +int snread(i, s, sdef) +int *i, *s, sdef; +{ + int f; + + f = *i = *s = 0; + for (;;) { +#if 1 /* Nick */ + ch = suck(); + if (ch == EOF || ch == '\n') break; + if (isspace(ch)) { +#else + c = suck(); + if (c == EOF || c == '\n') break; + if (isspace(c)) { +#endif + if (f) + break; + else + continue; + } +#if 1 /* Nick */ + if (isdigit(ch)) { +#else + if (isdigit(c)) { +#endif + f++; +#if 1 /* Nick */ + *i = *i * 10 + ch - '0'; + } else if ((ch == '+' || ch == '-') && !f) { +#else + *i = *i * 10 + c - '0'; + } else if ((c == '+' || c == '-') && !f) { +#endif + f++; +#if 1 /* Nick */ + *s = ch == '+' ? 1 : -1; +#else + *s = c == '+' ? 1 : -1; +#endif + } else + break; + } +#if 1 /* Nick */ + while (ch != EOF && ch != '\n') + ch = suck(); +#else + while (c != EOF && c != '\n') c = suck(); +#endif + if (!f) { + *i = 1; + *s = sdef; + } +#if 1 /* Nick */ + return ch; +#else + return c; +#endif +} + +int cread(k) +int *k; +{ + int u; + *k = -1; + for (;;) { + u = suck(); + if (u == EOF || u == '\n') return u; + if (isspace(u)) continue; + if (*k < 0) *k = u; + } +} + +void defmac() +{ + int i; + char newmac[3], *nm; + + if (skipsp()) return; + nm = newmac; + if (!Macwrite) openmac(); + *nm++ = suck(); +#if 1 /* Nick */ + ch = suck(); + if (ch != EOF && ch != '\n' && ch != ' ' && ch != '\t') + *nm++ = ch; +#else + c = suck(); + if (c != EOF && c != '\n' && c != ' ' && c != '\t') *nm++ = c; +#endif + *nm = '\0'; + /* KILL OLD DEFINITION IF ANY */ + for (i = 0; i < n_macros; i++) + if (!strcmp(newmac, macro[i].mname)) { + macro[i].mname[0] = '\0'; + break; + } + macro[n_macros].moff = ftell(Macwrite); + strcpy(macro[n_macros++].mname, newmac); +#if 1 /* Nick */ + while (ch != EOF && ch != '\n') ch = suck(); /* FLUSH HEADER LINE */ +#else + while (c != EOF && c != '\n') c = suck(); /* FLUSH HEADER LINE */ +#endif + while (copyline()); + fflush(Macwrite); +} + +void openmac() +{ + if (NULL == (Macwrite = fopen(tmpnam(mfilnam), "w"))) { + fprintf(stderr, "roff: cannot open temp file\n"); + exit(1); + } + Macread = fopen(mfilnam, "r"); + unlink(mfilnam); +} + +int copyline() +{ + int n, first, second; + +#if 1 /* Nick */ + if (ch == EOF) { +#else + if (c == EOF) { +#endif + fprintf(Macwrite, "..\n"); + return 0; + } + n = 0; + first = 1; + second = 0; + for (;;) { +#if 1 /* Nick */ + ch = suck(); + if (ch == EOF) { +#else + c = suck(); + if (c == EOF) { +#endif + if (!first) putc('\n', Macwrite); + return 0; + } +#if 1 /* Nick */ + if (ch == '\n') { +#else + if (c == '\n') { +#endif + putc('\n', Macwrite); + return n != 2; + } +#if 1 /* Nick */ + if (first && ch == '.') +#else + if (first && c == '.') +#endif + n++; +#if 1 /* Nick */ + else if (second && n == 1 && ch == '.') +#else + else if (second && n == 1 && c == '.') +#endif + n++; +#if 1 /* Nick */ + putc(ch, Macwrite); +#else + putc(c, Macwrite); +#endif + second = first; + first = 0; + } +} + +void submac(r) +int r; +{ +#if 1 /* Nick */ + while (ch != EOF && ch != '\n') + ch = suck(); +#else + while (c != EOF && c != '\n') c = suck(); +#endif + if (depth) + teller[depth - 1] = ftell(Macread); + else { + Save = File; + File = Macread; + } + depth++; + fseek(Macread, macro[r].moff, 0); +} + +void endmac() +{ + depth--; + if (depth) + fseek(Macread, teller[depth - 1], 0); + else + File = Save; +#if 1 /* Nick */ + ch = '\n'; +#else + c = '\n'; +#endif +} + +void do_ta() +{ + int v; + n_ta = 0; + for (;;) { + nread(&v); + if (v == 1) + return; + else + o_ta[n_ta++] = v; +#if 1 /* Nick */ + if (ch == '\n' || ch == EOF) break; +#else + if (c == '\n' || c == EOF) break; +#endif + } +} + +void do_tr() +{ + char *t; + t = &o_tr[0][0]; + *t = '\0'; + if (skipsp()) return; + for (;;) { +#if 1 /* Nick */ + ch = suck(); + if (ch == EOF || ch == '\n') break; + *t++ = ch; +#else + c = suck(); + if (c == EOF || c == '\n') break; + *t++ = c; +#endif + } + *t = '\0'; +} + +void do_nx() +{ + char fname[100], *f; + f = fname; + if (skipsp()) return; +#if 1 /* Nick */ + for (;;) + switch (ch = suck()) { +#else + for (;;) switch (c = suck()) { +#endif + case EOF: + case '\n': + case ' ': + case '\t': + if (f == fname) return; + goto got_nx; +#if 1 /* Nick */ + default: *f++ = ch; +#else + default: *f++ = c; +#endif + } +got_nx: + fclose(File); + *f = '\0'; + if (!(File = fopen(fname, "r"))) { + fprintf(stderr, "roff: cannot read %s\n", fname); + exit(1); + } +} + +int skipsp() +{ +#if 1 /* Nick */ + for (;;) + switch (ch = suck()) { +#else + for (;;) switch (c = suck()) { +#endif + case EOF: + case '\n': + return 1; + case ' ': + case '\t': + continue; + default: +#if 1 /* Nick */ + ungetc(ch, File); +#else + ungetc(c, File); +#endif + return 0; + } +} + +void writebreak() +{ + int q; + if (assylen) writeline(0, 1); + q = TXTLEN; + if (o_bl) { + if (o_bl + line_no > q) { + endpage(); + beginpage(); + } + for (; o_bl; o_bl--) blankline(); + } else if (o_sp) { + if (o_sp + line_no > q) + newpage(); + else if (line_no) + for (; o_sp; o_sp--) blankline(); + } +} + +void blankline() +{ + if (line_no >= TXTLEN) newpage(); + if (o_n2) o_n2++; + spit('\n'); + line_no++; +} + +void writeline(adflag, flushflag) +int adflag, flushflag; +{ + int j, q; + char lnstring[7]; + for (j = assylen - 1; j; j--) { + if (assyline[j] == ' ') + assylen--; + else + break; + } + q = TXTLEN; + if (line_no >= q) newpage(); + for (j = 0; j < o_po; j++) spit(' '); + if (o_n1) { + if (o_nn) for (j = 0; j < o_ni + 4; j++) + spit(' '); + else { + for (j = 0; j < o_ni; j++) spit(' '); + sprintf(lnstring, "%3d ", line_no + 1); + spits(lnstring); + } + } + if (o_n2) { + if (o_nn) for (j = 0; j < o_ni + 4; j++) + spit(' '); + else { + for (j = 0; j < o_ni; j++) spit(' '); + sprintf(lnstring, "%3d ", o_n2++); + spits(lnstring); + } + } + if (o_nn) o_nn--; + if (o_ce) for (j = 0; j < (o_ll - assylen + 1) / 2; j++) + spit(' '); + else + for (j = 0; j < IDTLEN; j++) spit(' '); + if (adflag && !flushflag) fillline(); + for (j = 0; j < assylen; j++) spit(assyline[j]); + spit('\n'); + assylen = 0; + assyline[0] = '\0'; + line_no++; + for (j = 1; j < o_ls; j++) + if (line_no <= q) blankline(); + if (!flushflag) { + if (o_hc) dehyph(holdword); + strcpy(assyline, holdword); + assylen = strlen(holdword); + *holdword = '\0'; + holdp = holdword; + } + if (o_ix >= 0) o_in = o_ix; + o_ix = o_ti = -1; +} + +void fillline() +{ + int excess, j, s, inc, spaces; + adjtoggle ^= 1; + if (!(excess = o_ll - IDTLEN - assylen)) return; + if (excess < 0) { + fprintf(stderr, "roff: internal error #2 [%d]\n", excess); + exit(1); + } + for (j = 2;; j++) { + if (adjtoggle) { + s = 0; + inc = 1; + } else { + s = assylen - 1; + inc = -1; + } + spaces = 0; + while (s >= 0 && s < assylen) { + if (assyline[s] == ' ') + spaces++; + else { + if (0 < spaces && spaces < j) { + insrt(s - inc); + if (inc > 0) s++; + if (!--excess) return; + } + spaces = 0; + } + s += inc; + } + } +} + +void insrt(p) +int p; +{ + int i; + for (i = assylen; i > p; i--) assyline[i] = assyline[i - 1]; + assylen++; +} + +void newpage() +{ + if (page_no >= 0) + endpage(); + else + page_no = 1; + for (; o_sk; o_sk--) blankpage(); + beginpage(); +} + +void beginpage() +{ + int i; + if (sflag) waitawhile(); + for (i = 0; i < o_m1; i++) spit('\n'); + writetitle(page_no & 1 ? ohead : ehead); + for (i = 0; i < o_m2; i++) spit('\n'); + line_no = 0; +} + +void endpage() +{ + int i; + for (i = line_no; i < TXTLEN; i++) blankline(); + for (i = 0; i < o_m3; i++) spit('\n'); + writetitle(page_no & 1 ? ofoot : efoot); + for (i = 0; i < o_m4; i++) spit('\n'); + if (o_bp < 0) + page_no++; + else { + page_no = o_bp; + o_bp = -1; + } +} + +void blankpage() +{ + int i; + if (sflag) waitawhile(); + for (i = 0; i < o_m1; i++) spit('\n'); + writetitle(page_no & 1 ? ohead : ehead); + for (i = 0; i < o_m2; i++) spit('\n'); + for (i = 0; i < TXTLEN; i++) spit('\n'); + for (i = 0; i < o_m3; i++) spit('\n'); + writetitle(page_no & 1 ? ofoot : efoot); + page_no++; + for (i = 0; i < o_m4; i++) spit('\n'); + line_no = 0; +} + +void waitawhile() +{ +#ifndef NO_TERM_CONTROL + tcflag_t oldflags; + if (isatty(0)) { + oldflags = tty.c_lflag; + tty.c_lflag &= ~ECHO; /* DON'T ECHO THE RUBOUT */ + tcsetattr(0, TCSANOW, &tty); + } +#endif + signal(SIGINT, (sig_t) nix); /* Nick */ + pause(); +#ifndef NO_TERM_CONTROL + if (isatty(0)) { + tty.c_lflag = oldflags; + tcsetattr(0, TCSANOW, &tty); + } +#endif +} + +void nix(sig) +int sig; +{ +} + +void writetitle(t) +char *t; +{ + char d, *pst; + int j, l, m, n; + d = *t; + if (o_hx || !d) { + spit('\n'); + return; + } + pst = pgform(); + for (j = 0; j < o_po; j++) spit(' '); + l = titlen(++t, d, strlen(pst)); + while (*t && *t != d) { + if (*t == '%') + spits(pst); + else + spit(*t); + t++; + } + if (!*t) { + spit('\n'); + return; + } + m = titlen(++t, d, strlen(pst)); + for (j = l; j < (o_ll - m) / 2; j++) spit(' '); + while (*t && *t != d) { + if (*t == '%') + spits(pst); + else + spit(*t); + t++; + } + if (!*t) { + spit('\n'); + return; + } + if ((o_ll - m) / 2 > l) + m += (o_ll - m) / 2; + else + m += l; + n = titlen(++t, d, strlen(pst)); + for (j = m; j < o_ll - n; j++) spit(' '); + while (*t && *t != d) { + if (*t == '%') + spits(pst); + else + spit(*t); + t++; + } + spit('\n'); +} + +char * + pgform() +{ + static char pst[11]; + int i; + if (o_ro) { + *pst = '\0'; + i = page_no; + if (i >= 400) { + strcat(pst, "cd"); + i -= 400; + } + while (i >= 100) { + strcat(pst, "c"); + i -= 100; + } + if (i >= 90) { + strcat(pst, "xc"); + i -= 90; + } + if (i >= 50) { + strcat(pst, "l"); + i -= 50; + } + if (i >= 40) { + strcat(pst, "xl"); + i -= 40; + } + while (i >= 10) { + strcat(pst, "x"); + i -= 10; + } + if (i >= 9) { + strcat(pst, "ix"); + i -= 9; + } + if (i >= 5) { + strcat(pst, "v"); + i -= 5; + } + if (i >= 4) { + strcat(pst, "iv"); + i -= 4; + } + while (i--) strcat(pst, "i"); + } else + sprintf(pst, "%d", page_no); + return pst; +} + +int titlen(t, c, k) +char *t, c; +int k; +{ + int q; + q = 0; + while (*t && *t != c) q += *t++ == '%' ? k : 1; + return q; +} + +void spits(s) +char *s; +{ + while (*s) spit(*s++); +} + +void spit(c) +char c; +{ + static int col_no, n_blanks; + int ulflag; + char *t; + ulflag = c & UNDERL; + c &= ~UNDERL; + for (t = (char *) o_tr; *t; t++) + if (*t++ == c) { +/* + * fix - last char translates to space. + */ + c = *t ? *t : ' '; + break; + } + if (page_no < startpage || (stoppage && page_no > stoppage)) return; + if (c != ' ' && c != '\n' && n_blanks) { + if (hflag && n_blanks > 1) + while (col_no / 8 < (col_no + n_blanks) / 8) { + putc('\t', stdout); + n_blanks -= 8 - (col_no & 07); + col_no = (8 + col_no) & ~07; + } + for (; n_blanks; n_blanks--) { + putc(' ', stdout); + col_no++; + } + } + if (ulflag && isalnum(c)) fputs("_\b", stdout); + if (c == ' ') + n_blanks++; + else { + putc(c, stdout); + col_no++; + } + if (c == '\n') { + col_no = 0; + n_blanks = 0; + } +} + +int suck() +{ + for (;;) { +#if 1 /* Nick */ + ch = getc(File); + if (islegal(ch)) + return ch; +#else + c = getc(File); + if (islegal(c)) return c; +#endif + } +} + +/* + * strhas - does string have character? Allow UNDERL flag. + */ + +char * + strhas(p, c) +char *p, c; +{ + for (; *p; p++) + if ((*p & ~UNDERL) == c) return p; + return NULL; +} + +/* + * strend - find NULL at end of string. + */ + +char * + strend(p) +char *p; +{ + while (*p++); + return p; +} + +/* + * isspace, isalnum, isdigit, islegal - classify a character. + * We could just as well use if it didn't vary from + * one version of Unix to another. As it is, these routines + * must be modified for weird character sets, like EBCDIC and + * CDC Scientific. + */ + +int isspace(c) +int c; +{ + char *s; + for (s = spacechars; *s; s++) + if (*s == c) return 1; + return 0; +} + +int isalnum(c) +int c; +{ + return(c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'); +} + +int isdigit(c) +int c; +{ + return c >= '0' && c <= '9'; +} + +int islegal(c) +int c; +{ + return (c >= ' ' && c <= '~') || isspace(c) || c == '\n' || c == EOF; +} + +void bomb() +{ + fprintf(stderr, "usage: roff [+00] [-00] [-s] [-h] file ...\n"); + exit(1); +} diff --git a/src/simple/setclock.c b/src/simple/setclock.c new file mode 100755 index 00000000..cc639d06 --- /dev/null +++ b/src/simple/setclock.c @@ -0,0 +1,97 @@ +/* setclock.c + * descripton: set machine real-time clock + * author: Adriano Cunha + * license: GNU Public License version 2 + */ +#include +#include +#include +#ifdef __TURBOC__ +#define STDOUT_FILENO 1 +#endif + +/* get an integer value from *p and return the first char after in p1 */ +int getint(char *p, char **p1) { + int v = 0; + + while (*p >= '0' && *p <= '9') { + v *= 10; + v += *p - '0'; + ++p; + } + *p1 = p; + return v; +} + +/* convert a given time in t1 and date in t2 into struct tm */ +int conv_time(char *t1, char *t2, struct tm *tt) { + int h, m, s, d, mm, y; + char *t; + + /* hh:mm[:ss] */ + t = t1; + h = getint(t, &t); + if ((h < 0) || (h > 23) || (*t++ != ':')) return 0; + m = getint(t, &t); + if ((m < 0) || (m > 59)) return 0; + if (*t) { + if (*t++ != ':') return 0; + s = getint(t, &t); + if ((s < 0) || (s > 59) || (*t != 0)) return 0; + } + else s = 0; + + /* dd/mm/yy[yy] */ + t = t2; + d = getint(t, &t); + if ((d < 1) || (d > 31) || (*t++ != '/')) return 0; + mm = getint(t, &t); + if ((mm < 1) || (mm > 12) || (*t++ != '/')) return 0; + y = getint(t, &t); + if (y < 100) { + if (y < 80) + y += 100; + } + else y -= 1900; + if ((y < 0) || (*t != 0)) return 0; + tt->tm_hour = h; + tt->tm_min = m; + tt->tm_sec = s; + tt->tm_year = y; + tt->tm_mon = mm - 1; + tt->tm_mday = d; + return 1; +} + +void wr(char *s) { + write(STDOUT_FILENO, s, strlen(s)); +} + +int main(argc, argv) + int argc; + char **argv; +{ + struct tm tt; + time_t mytimet; + + if (argc < 2) { + wr("usage: setclock hh:mm[:ss] dd/mm/yyyy\n"); + return 0; + } + argv++; + if (!conv_time(*argv, *(argv + 1), &tt)) { + wr("Bad date/time format\n"); + return 1; + } +#ifdef __TURBOC__ + wr(asctime(&tt)); +#else + mytimet = mktime(&tt); + if (stime(&mytimet) < 0) { + wr("You have no permission to set clock\n"); + return 2; + } +#endif + return 0; +} + \ No newline at end of file diff --git a/src/simple/sort.c b/src/simple/sort.c new file mode 100755 index 00000000..73bf6230 --- /dev/null +++ b/src/simple/sort.c @@ -0,0 +1,1202 @@ +/* sort - sort a file of lines Author: Michiel Huisjes */ + +/* SYNOPSIS: + * sort [-funbirdcmt'x'] [+beg_pos[opts] [-end_pos]] [-o outfile] [file].. + * + * [opts] can be any of + * -f : Fold upper case to lower. + * -n : Sort to numeric value (optional decimal point) implies -b + * -b : Skip leading blanks + * -i : Ignore chars outside ASCII range (040 - 0176) + * -r : Reverse the sense of comparisons. + * -d : Sort to dictionary order. Only letters, digits, comma's and points + * are compared. + * If any of these flags are used in [opts], then they override all global + * ordering for this field. + * + * I/O control flags are: + * -u : Print uniq lines only once. + * -c : Check if files are sorted in order. + * -m : Merge already sorted files. + * -o outfile : Name of output file. (Can be one of the input files). + * Default is stdout. + * - : Take stdin as input. + * + * Fields: + * -t'x' : Field separating character is 'x' + * +a.b : Start comparing at field 'a' with offset 'b'. A missing 'b' is + * taken to be 0. + * -a.b : Stop comparing at field 'a' with offset 'b'. A missing 'b' is + * taken to be 0. + * A missing -a.b means the rest of the line. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OPEN_FILES (10) /* Nr of open files per process */ +#define MEMORY_SIZE (10 * 1024) /* Total mem_size */ +#define LINE_SIZE (1024 >> 1) /* Max length of a line */ +#define IO_SIZE (2 * 1024) /* Size of buffered output */ +#define STD_OUT 1 /* Fd of terminal */ + +/* Return status of functions */ +#define OK 0 +#define ERROR -1 +#define NIL_PTR ((char *) 0) + +/* Compare return values */ +#define LOWER -1 +#define SAME 0 +#define HIGHER 1 + +/* Table definitions. */ +#define DICT 0x001 /* Alpha, numeric, letters and . */ +#define ASCII 0x002 /* All between ' ' and '~' */ +#define BLANK 0x004 /* ' ' and '\t' */ +#define DIGIT 0x008 /* 0-9 */ +#define UPPER 0x010 /* A-Z */ + +typedef int BOOL; + +#define FALSE 0 +#define TRUE 1 + +typedef struct { + int fd; /* Fd of file */ + char *buffer; /* Buffer for reads */ + int read_chars; /* Nr of chars actually read in buffer */ + int cnt; /* Nr of chars taken out of buffer */ + char *line; /* Contains line currently used */ +} MERGE; + +#define NIL_MERGE ((MERGE *) 0) +MERGE merge_f[OPEN_FILES]; /* Merge structs */ +int buf_size; /* Size of core available for each struct */ + +#define FIELDS_LIMIT 10 /* 1 global + 9 user */ +#define GLOBAL 0 + +typedef struct { + int beg_field, beg_pos; /* Begin field + offset */ + int end_field, end_pos; /* End field + offset. ERROR == EOLN */ + BOOL reverse; /* TRUE if rev. flag set on this field */ + BOOL blanks; + BOOL dictionary; + BOOL fold_case; + BOOL ascii; + BOOL numeric; +} FIELD; + +/* Field declarations. A total of FILEDS_LIMIT is allowed */ +FIELD fields[FIELDS_LIMIT]; +int field_cnt; /* Nr of field actually assigned */ + +/* Various output control flags */ +BOOL check = FALSE; +BOOL only_merge = FALSE; +BOOL uniq = FALSE; + +char *mem_top; /* Mem_top points to lowest pos of memory. */ +char *cur_pos; /* First free position in mem */ +char **line_table; /* Pointer to the internal line table */ +BOOL in_core = TRUE; /* Set if input cannot all be sorted in core */ + + /* Place where temp_files should be made */ +char temp_files[] = "/tmp/sort.XXXXX.XX"; +char *output_file; /* Name of output file */ +int out_fd; /* Fd to output file (could be STD_OUT) */ +char out_buffer[IO_SIZE]; /* For buffered output */ + +char **argptr; /* Pointer to argv structure */ +int args_offset; /* Nr of args spilled on options */ +int args_limit; /* Nr of args given */ + +char separator; /* Char that separates fields */ +int nr_of_files = 0; /* Nr_of_files to be merged */ +int disabled; /* Nr of files done */ + +char USAGE[] = "usage: sort [-funbirdcmt'x'] [+beg_pos [-end_pos]] [-o outfile] [file] .."; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +/* Forward declarations */ +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void get_opts, (char *ptr, FIELD * field)); +_PROTOTYPE(void new_field, (FIELD * field, int *offset, BOOL beg_fl)); +_PROTOTYPE(void adjust_options, (FIELD * field)); +_PROTOTYPE(void error, (BOOL quit, char *message, char *arg)); +_PROTOTYPE(void open_outfile, (void)); +_PROTOTYPE(void get_file, (int fd, off_t size)); +_PROTOTYPE(int last_line, (void)); +_PROTOTYPE(void print_table, (int fd)); +_PROTOTYPE(char *file_name, (int nr)); +_PROTOTYPE(void mread, (int fd, char *address, int bytes)); +_PROTOTYPE(void mwrite, (int fd, char *address, int bytes)); +_PROTOTYPE(void sort, (void)); +_PROTOTYPE(void sort_table, (int nel)); +_PROTOTYPE(void incr, (int si, int ei)); +_PROTOTYPE(int cmp_fields, (char *el1, char *el2)); +_PROTOTYPE(void build_field, (char *dest, FIELD * field, char *src)); +_PROTOTYPE(char *skip_fields, (char *str, int nf)); +_PROTOTYPE(int compare, (char *el1, char *el2)); +_PROTOTYPE(int cmp, (unsigned char *el1, unsigned char *el2, FIELD * field)); +_PROTOTYPE(int digits, (char *str1, char *str2, BOOL check_sign)); +_PROTOTYPE(void files_merge, (int file_cnt)); +_PROTOTYPE(void merge, (int start_file, int limit_file)); +_PROTOTYPE(void put_line, (char *line)); +_PROTOTYPE(MERGE * print, (MERGE * merg, int file_cnt)); +_PROTOTYPE(int read_line, (MERGE * merg)); +_PROTOTYPE(MERGE * skip_lines, (MERGE * smallest, int file_cnt)); +_PROTOTYPE(void uniq_lines, (MERGE * merg)); +_PROTOTYPE(void check_file, (int fd, char *file)); +_PROTOTYPE(int length, (char *line)); +_PROTOTYPE(void copy, (char *dest, char *src)); +_PROTOTYPE(char *msbrk, (int size)); +_PROTOTYPE(void mbrk, (char *address)); +_PROTOTYPE(void catch, (int dummy)); + +/* Table of all chars. 0 means no special meaning. */ +char table[256] = { +/* '^@' to space */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, BLANK | DICT, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + +/* Space to '0' */ + BLANK | DICT | ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, + ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, + ASCII, ASCII, + +/* '0' until '9' */ + DIGIT | DICT | ASCII, DIGIT | DICT | ASCII, DIGIT | DICT | ASCII, + DIGIT | DICT | ASCII, DIGIT | DICT | ASCII, DIGIT | DICT | ASCII, + DIGIT | DICT | ASCII, DIGIT | DICT | ASCII, DIGIT | DICT | ASCII, + DIGIT | DICT | ASCII, + +/* ASCII from ':' to '@' */ + ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, + +/* Upper case letters 'A' to 'Z' */ + UPPER | DICT | ASCII, UPPER | DICT | ASCII, UPPER | DICT | ASCII, + UPPER | DICT | ASCII, UPPER | DICT | ASCII, UPPER | DICT | ASCII, + UPPER | DICT | ASCII, UPPER | DICT | ASCII, UPPER | DICT | ASCII, + UPPER | DICT | ASCII, UPPER | DICT | ASCII, UPPER | DICT | ASCII, + UPPER | DICT | ASCII, UPPER | DICT | ASCII, UPPER | DICT | ASCII, + UPPER | DICT | ASCII, UPPER | DICT | ASCII, UPPER | DICT | ASCII, + UPPER | DICT | ASCII, UPPER | DICT | ASCII, UPPER | DICT | ASCII, + UPPER | DICT | ASCII, UPPER | DICT | ASCII, UPPER | DICT | ASCII, + UPPER | DICT | ASCII, UPPER | DICT | ASCII, + +/* ASCII from '[' to '`' */ + ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, + +/* Lower case letters from 'a' to 'z' */ + DICT | ASCII, DICT | ASCII, DICT | ASCII, DICT | ASCII, + DICT | ASCII, DICT | ASCII, DICT | ASCII, DICT | ASCII, + DICT | ASCII, DICT | ASCII, DICT | ASCII, DICT | ASCII, + DICT | ASCII, DICT | ASCII, DICT | ASCII, DICT | ASCII, + DICT | ASCII, DICT | ASCII, DICT | ASCII, DICT | ASCII, + DICT | ASCII, DICT | ASCII, DICT | ASCII, DICT | ASCII, + DICT | ASCII, DICT | ASCII, + +/* ASCII from '{' to '~' */ + ASCII, ASCII, ASCII, ASCII, + +/* Stuff from -1 to -177 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 +}; + + +/* + * Get_opts () assigns the options into the field structure as described in ptr. + * This field structure could be the GLOBAL one. + */ +void get_opts(ptr, field) +register char *ptr; +register FIELD *field; +{ + switch (*ptr) { + case 'b': /* Skip leading blanks */ + field->blanks = TRUE; + break; + case 'd': /* Dictionary order */ + field->dictionary = TRUE; + break; + case 'f': /* Fold upper case to lower */ + field->fold_case = TRUE; + break; + case 'i': /* Skip chars outside ' ' '~' */ + field->ascii = TRUE; + break; + case 'n': /* Sort on numeric */ + field->numeric = TRUE; + field->blanks = TRUE; + break; + case 'r': /* Reverse comparisons */ + field->reverse = TRUE; + break; + default: /* Illegal options */ + error(TRUE, USAGE, NIL_PTR); + } +} + +/* New_field () assigns a new field as described by the arguments. + * A field description is of the form: +a.b[opts] -c.d, where b and d, as well + * as -c.d and [opts] are optional. Nr before digit is field nr. Nr after digit + * is offset from field. + */ +void new_field(field, offset, beg_fl) +register FIELD *field; /* Field to assign */ +int *offset; /* Offset in argv structure */ +BOOL beg_fl; /* Assign beg or end of field */ +{ + register char *ptr; + + ptr = argptr[*offset]; + *offset += 1; /* Incr offset to next arg */ + ptr++; + + if (beg_fl) + field->beg_field = atoi(ptr); /* Assign int of first field */ + else + field->end_field = atoi(ptr); + + while (table[*ptr] & DIGIT) /* Skip all digits */ + ptr++; + + if (*ptr == '.') { /* Check for offset */ + ptr++; + if (beg_fl) + field->beg_pos = atoi(ptr); + else + field->end_pos = atoi(ptr); + while (table[*ptr] & DIGIT) /* Skip digits */ + ptr++; + } + if (beg_fl) { + while (*ptr != '\0') /* Check options after field */ + get_opts(ptr++, field); + } + if (beg_fl) { /* Check for end pos */ + ptr = argptr[*offset]; + if (ptr && *ptr == '-' && table[*(ptr + 1)] & DIGIT) { + new_field(field, offset, FALSE); + if (field->beg_field > field->end_field) + error(TRUE, "End field is before start field!", NIL_PTR); + } else /* No end pos. */ + field->end_field = ERROR; + } +} + +int main(argc, argv) +int argc; +char *argv[]; +{ + int arg_count = 1; /* Offset in argv */ + struct stat st; + register char *ptr; /* Ptr to *argv in use */ + register int fd; + int pid, pow; + + argptr = argv; + cur_pos = mem_top = msbrk(MEMORY_SIZE); /* Find lowest mem. location */ + + if (argc < 2 && isatty(fileno(stdin))) { + write(fileno(stdout), USAGE, strlen(USAGE)); + write(fileno(stdout), "\n", 1); + exit(1); + } + while (arg_count < argc && ((ptr = argv[arg_count])[0] == '-' || *ptr == '+')) { + if (*ptr == '-' && *(ptr + 1) == '\0') /* "-" means stdin */ + break; + if (*ptr == '+') { /* Assign field. */ + if (++field_cnt == FIELDS_LIMIT) + error(TRUE, "Too many fields", NIL_PTR); + new_field(&fields[field_cnt], &arg_count, TRUE); + } else { /* Get output options */ + while (*++ptr) { + switch (*ptr) { + case 'c': /* Only check file */ + check = TRUE; + break; + case 'm': /* Merge (sorted) files */ + only_merge = TRUE; + break; + case 'u': /* Only give uniq lines */ + uniq = TRUE; + break; + case 'o': /* Name of output file */ + output_file = argv[++arg_count]; + break; + case 't': /* Field separator */ + ptr++; + separator = *ptr; + break; + default: /* Sort options */ + get_opts(ptr, &fields[GLOBAL]); + } + } + arg_count++; + } + } + + for (fd = 1; fd <= field_cnt; fd++) adjust_options(&fields[fd]); + +/* Create name of tem_files 'sort.pid.aa' */ + ptr = &temp_files[10]; + pid = getpid(); + pow = 10000; + while (pow != 0) { + *ptr++ = pid / pow + '0'; + pid %= pow; + pow /= 10; + } + + signal(SIGINT, (sig_t) catch); /* Nick */ + +/* Only merge files. Set up */ + if (only_merge) { + args_limit = args_offset = arg_count; + while (argv[args_limit] != NIL_PTR) + args_limit++; /* Find nr of args */ + files_merge(args_limit - arg_count); + exit(0); + } + if (arg_count == argc) { /* No args left. Use stdin */ + if (check) + check_file(0, NIL_PTR); + else + get_file(0, (off_t) 0); + } else + while (arg_count < argc) { /* Sort or check args */ + if (strcmp(argv[arg_count], "-") == 0) + fd = 0; + else if (stat(argv[arg_count], &st) < 0) { + error(FALSE, "Cannot find ", argv[arg_count++]); + continue; + } + + /* Open files */ + else if ((fd = open(argv[arg_count], O_RDONLY)) < 0) { + error(FALSE, "Cannot open ", argv[arg_count++]); + continue; + } + if (check) + check_file(fd, argv[arg_count]); + else /* Get_file reads whole file */ +#if 0 /* Nick */ + get_file(fd, 512L*st.st_size.o_blkno + + st.st_size.o_offset); +#else + get_file(fd, st.st_size); +#endif + arg_count++; + } + + if (check) exit(0); + + sort(); /* Sort whatever is left */ + + if (nr_of_files == 1) /* Only one file sorted -> don't merge */ + exit(0); + + files_merge(nr_of_files); + return(0); +} + +/* Adjust_options() assigns all global variables set also in the fields + * assigned. + */ +void adjust_options(field) +register FIELD *field; +{ + register FIELD *gfield = &fields[GLOBAL]; + + if (gfield->reverse) field->reverse = TRUE; + if (gfield->blanks) field->blanks = TRUE; + if (gfield->dictionary) field->dictionary = TRUE; + if (gfield->fold_case) field->fold_case = TRUE; + if (gfield->ascii) field->ascii = TRUE; + if (gfield->numeric) field->numeric = TRUE; +} + +/* Error () prints the error message on stderr and exits if quit == TRUE. */ +void error(quit, message, arg) +register BOOL quit; +register char *message, *arg; +{ + write(2, message, strlen(message)); + if (arg != NIL_PTR) write(2, arg, strlen(arg)); + perror(" "); + if (quit) exit(1); +} + +/* Open_outfile () assigns to out_fd the fd where the output must go when all + * the sorting is done. + */ +void open_outfile() +{ + if (output_file == NIL_PTR) + out_fd = STD_OUT; + else if ((out_fd = creat(output_file, 0644)) < 0) + error(TRUE, "Cannot creat ", output_file); +} + +/* Get_file reads the whole file of filedescriptor fd. If the file is too big + * to keep in core, a partial sort is done, and the output is stashed somewhere. + */ +void get_file(fd, size) +int fd; /* Fd of file to read */ +register off_t size; /* Size of file */ +{ + register int i; + int rest; /* Rest in memory */ + char save_ch; /* Used in stdin readings */ + + rest = MEMORY_SIZE - (cur_pos - mem_top); + if (fd == 0) { /* We're reding stdin */ + while ((i = read(0, cur_pos, rest)) > 0) { + if ((cur_pos - mem_top) + i == MEMORY_SIZE) { + in_core = FALSE; + i = last_line(); /* End of last line */ + save_ch = mem_top[i]; + mem_top[i] = '\0'; + sort(); /* Sort core */ + mem_top[i] = save_ch; /* Restore erased char */ + /* Restore last (half read) line */ + for (rest = 0; i + rest != MEMORY_SIZE; rest++) + mem_top[rest] = mem_top[i + rest]; + /* Assign current pos. in memory */ + cur_pos = &mem_top[rest]; + } else { /* Fits, just assign position in mem. */ + cur_pos = cur_pos + i; + *cur_pos = '\0'; + } + + /* Calculate rest of mem */ + rest = MEMORY_SIZE - (cur_pos - mem_top); + } + } + + /* Reading file. Check size */ + else if (size > rest) { /* Won't fit */ + mread(fd, cur_pos, rest); + in_core = FALSE; + i = last_line(); /* Get pos. of last line */ + mem_top[i] = '\0'; /* Truncate */ + (void) lseek(fd, (off_t) (i - MEMORY_SIZE), SEEK_CUR); /* Do this next time */ + size = size - rest - i + MEMORY_SIZE; /* Calculate rest */ + cur_pos = mem_top; /* Reset mem */ + sort(); /* Sort core */ + get_file(fd, size); /* Get rest of file */ + } else { /* Fits. Just read in */ + rest = size; + mread(fd, cur_pos, rest); + cur_pos = cur_pos + rest; /* Reassign cur_pos */ + *cur_pos = '\0'; + (void) close(fd); /* File completed */ + } +} + +/* Last_line () find the last line in core and retuns the offset from the top + * of the memory. + */ +int last_line() +{ + register int i; + + for (i = MEMORY_SIZE - 2; i > 0; i--) + if (mem_top[i] == '\n') break; + return i + 1; +} + +/* Print_table prints the line table in the given file_descriptor. If the fd + * equals ERROR, it opens a temp_file itself. + */ +void print_table(fd) +int fd; +{ + register char **line_ptr; /* Ptr in line_table */ + register char *ptr; /* Ptr to line */ + int index = 0; /* Index in output buffer */ + + if (fd == ERROR) { + if ((fd = creat(file_name(nr_of_files), 0644)) < 0) + error(TRUE, "Cannot creat ", file_name(nr_of_files)); + } + for (line_ptr = line_table; *line_ptr != NIL_PTR; line_ptr++) { + ptr = *line_ptr; + /* Skip all same lines if uniq is set */ + if (uniq && *(line_ptr + 1) != NIL_PTR) { + if (compare(ptr, *(line_ptr + 1)) == SAME) continue; + } + do { /* Print line in a buffered way */ + out_buffer[index++] = *ptr; + if (index == IO_SIZE) { + mwrite(fd, out_buffer, IO_SIZE); + index = 0; + } + } while (*ptr++ != '\n'); + } + mwrite(fd, out_buffer, index);/* Flush buffer */ + (void) close(fd); /* Close file */ + nr_of_files++; /* Increment nr_of_files to merge */ +} + +/* File_name () returns the nr argument from the argument list, or a uniq + * filename if the nr is too high, or the arguments were not merge files. + */ +char *file_name(nr) +register int nr; +{ + if (only_merge) { + if (args_offset + nr < args_limit) return argptr[args_offset + nr]; + } + temp_files[16] = nr / 26 + 'a'; + temp_files[17] = nr % 26 + 'a'; + + return temp_files; +} + +/* Mread () performs a normal read (), but checks the return value. */ +void mread(fd, address, bytes) +int fd; +char *address; +register int bytes; +{ + if (read(fd, address, bytes) < 0 && bytes != 0) + error(TRUE, "Read error", NIL_PTR); +} + +/* Mwrite () performs a normal write (), but checks the return value. */ +void mwrite(fd, address, bytes) +int fd; +char *address; +register int bytes; +{ + if (write(fd, address, bytes) != bytes && bytes != 0) + error(TRUE, "Write error", NIL_PTR); +} + +/* Sort () sorts the input in memory starting at mem_top. */ +void sort() +{ + register char *ptr = mem_top; + register int count = 0; + +/* Count number of lines in memory */ + while (*ptr) { + if (*ptr++ == '\n') count++; + } + +/* Set up the line table */ + line_table = (char **) msbrk(count * sizeof(char *) + sizeof(char *)); + + count = 1; + ptr = line_table[0] = mem_top; + while (*ptr) { + if (*ptr++ == '\n') line_table[count++] = ptr; + } + + line_table[count - 1] = NIL_PTR; + +/* Sort the line table */ + sort_table(count - 1); + +/* Stash output somewhere */ + if (in_core) { + open_outfile(); + print_table(out_fd); + } else + print_table(ERROR); + +/* Free line table */ + mbrk((char *) line_table); +} + +/* Sort_table () sorts the line table consisting of nel elements. */ +void sort_table(nel) +register int nel; +{ + char *tmp; + register int i; + + /* Make heap */ + for (i = (nel >> 1); i >= 1; i--) incr(i, nel); + + /* Sort from heap */ + for (i = nel; i > 1; i--) { + tmp = line_table[0]; + line_table[0] = line_table[i - 1]; + line_table[i - 1] = tmp; + incr(1, i - 1); + } +} + +/* Incr () increments the heap. */ +void incr(si, ei) +register int si, ei; +{ + char *tmp; + + while (si <= (ei >> 1)) { + si <<= 1; + if (si + 1 <= ei && compare(line_table[si - 1], line_table[si]) <= 0) + si++; + if (compare(line_table[(si >> 1) - 1], line_table[si - 1]) >= 0) + return; + tmp = line_table[(si >> 1) - 1]; + line_table[(si >> 1) - 1] = line_table[si - 1]; + line_table[si - 1] = tmp; + } +} + +/* Cmp_fields builds new lines out of the lines pointed to by el1 and el2 and + * puts it into the line1 and line2 arrays. It then calls the cmp () routine + * with the field describing the arguments. + */ +int cmp_fields(el1, el2) +register char *el1, *el2; +{ + int i, ret; + char line1[LINE_SIZE], line2[LINE_SIZE]; + + for (i = 0; i < field_cnt; i++) { /* Setup line parts */ + build_field(line1, &fields[i + 1], el1); + build_field(line2, &fields[i + 1], el2); + if ((ret = cmp((unsigned char *) line1, (unsigned char *) line2, + &fields[i + 1])) != SAME) + break; /* If equal, try next field */ + } + +/* Check for reverse flag */ + if (i != field_cnt && fields[i + 1].reverse) return -ret; + +/* Else return the last return value of cmp () */ + return ret; +} + +/* Build_field builds a new line from the src as described by the field. + * The result is put in dest. + */ +void build_field(dest, field, src) +char *dest; /* Holds result */ +register FIELD *field; /* Field description */ +register char *src; /* Source line */ +{ + char *begin = src; /* Remember start location */ + char *last; /* Pointer to end location */ + int i; + +/* Skip begin fields */ + src = skip_fields(src, field->beg_field); + +/* Skip begin positions */ + for (i = 0; i < field->beg_pos && *src != '\n'; i++) src++; + +/* Copy whatever is left */ + copy(dest, src); + +/* If end field is assigned truncate (perhaps) the part copied */ + if (field->end_field != ERROR) { /* Find last field */ + last = skip_fields(begin, field->end_field); +/* Skip positions as given by end fields description */ + for (i = 0; i < field->end_pos && *last != '\n'; i++) last++; + dest[last - src] = '\n';/* Truncate line */ + } +} + +/* Skip_fields () skips nf fields of the line pointed to by str. */ +char *skip_fields(str, nf) +register char *str; +int nf; +{ + while (nf-- > 0) { + if (separator == '\0') {/* Means ' ' or '\t' */ + while (table[*str] & BLANK) str++; + while (*str != ' ' && *str != '\t' && *str != '\n') str++; + } else { + while (*str == separator) str++; + while (*str != separator && *str != '\n') str++; + } + } + return str; /* Return pointer to indicated field */ +} + +/* Compare is called by all sorting routines. It checks if fields assignments + * has been made. if so, it calls cmp_fields (). If not, it calls cmp () and + * reversed the return value if the (global) reverse flag is set. + */ +int compare(el1, el2) +register char *el1, *el2; +{ + int ret; + + if (field_cnt > GLOBAL) return cmp_fields(el1, el2); + + ret = cmp((unsigned char *) el1, (unsigned char *) el2, &fields[GLOBAL]); + return(fields[GLOBAL].reverse) ? -ret : ret; +} + +/* Cmp () is the actual compare routine. It compares according to the + * description given in the field pointer. + */ +int cmp(el1, el2, field) +register unsigned char *el1, *el2; +FIELD *field; +{ + int c1, c2; + + if (field->blanks) { /* Skip leading blanks */ + while (table[*el1] & BLANK) el1++; + while (table[*el2] & BLANK) el2++; + } + if (field->numeric) /* Compare numeric */ + return digits((char *) el1, (char *) el2, TRUE); + + for (;;) { + while (*el1 == *el2) { + if (*el1++ == '\n') /* EOLN on both strings */ + return SAME; + el2++; + } + if (*el1 == '\n') /* EOLN on string one */ + return LOWER; + if (*el2 == '\n') return HIGHER; + if (field->ascii) { /* Skip chars outside 040 - 0177 */ + if ((table[*el1] & ASCII) == 0) { + do { + el1++; + } while ((table[*el1] & ASCII) == 0); + continue; + } + if ((table[*el2] & ASCII) == 0) { + do { + el2++; + } while ((table[*el2] & ASCII) == 0); + continue; + } + } + if (field->dictionary) {/* Skip non-dict chars */ + if ((table[*el1] & DICT) == 0) { + do { + el1++; + } while ((table[*el1] & DICT) == 0); + continue; + } + if ((table[*el2] & DICT) == 0) { + do { + el2++; + } while ((table[*el2] & DICT) == 0); + continue; + } + } + if (field->fold_case) { /* Fold upper case to lower */ + if (table[c1 = *el1++] & UPPER) c1 += 'a' - 'A'; + if (table[c2 = *el2++] & UPPER) c2 += 'a' - 'A'; + if (c1 == c2) continue; + return c1 - c2; + } + return *el1 - *el2; + } + + /* NOTREACHED */ +} + +/* + * Digits compares () the two strings that point to a number of digits followed + * by an optional decimal point. + */ +int digits(str1, str2, check_sign) +register char *str1, *str2; +BOOL check_sign; /* True if sign must be checked */ +{ + BOOL negative = FALSE; /* True if negative numbers */ + int diff, pow, ret; + +/* Check for optional minus or plus sign */ + if (check_sign) { + if (*str1 == '-') { + negative = TRUE; + str1++; + } else if (*str1 == '+') + str1++; + + if (*str2 == '-') { + if (negative == FALSE) return HIGHER; + str2++; + } else if (negative) + return LOWER; + else if (*str2 == '+') + str2++; + } + +/* Keep incrementing as long as digits are available and equal */ + while ((table[*str1] & DIGIT) && table[*str2] & DIGIT) { + if (*str1 != *str2) break; + str1++; + str2++; + } + +/* First check for the decimal point. */ + if (*str1 == '.' || *str2 == '.') { + if (*str1 == '.') { + if (*str2 == '.') /* Both. Check decimal part */ + ret = digits(str1 + 1, str2 + 1, FALSE); + else + ret = (table[*str2] & DIGIT) ? LOWER : HIGHER; + } else + ret = (table[*str1] & DIGIT) ? HIGHER : LOWER; + } + +/* Now either two digits differ, or unknown char is seen (e.g. end of string) */ + else if ((table[*str1] & DIGIT) && (table[*str2] & DIGIT)) { + diff = *str1 - *str2; /* Basic difference */ + pow = 0; /* Check power of numbers */ + while (table[*str1++] & DIGIT) pow++; + while (table[*str2++] & DIGIT) pow--; + ret = (pow == 0) ? diff : pow; + } + +/* Unknown char. Check on which string it occurred */ + else { + if ((table[*str1] & DIGIT) == 0) + ret = (table[*str2] & DIGIT) ? LOWER : SAME; + else + ret = HIGHER; + } + +/* Reverse sense of comparisons if negative is true. (-1000 < -1) */ + return(negative) ? -ret : ret; +} + +/* Files_merge () merges all files as indicated by nr_of_files. Merging goes + * in numbers of files that can be opened at the same time. (OPEN_FILES) + */ +void files_merge(file_cnt) +register int file_cnt; /* Nr_of_files to merge */ +{ + register int i; + int limit; + + for (i = 0; i < file_cnt; i += OPEN_FILES) { + /* Merge last files and store in output file */ + if ((limit = i + OPEN_FILES) >= file_cnt) { + open_outfile(); + limit = file_cnt; + } else { /* Merge OPEN_FILES files and store in temp + * file */ + temp_files[16] = file_cnt / 26 + 'a'; + temp_files[17] = file_cnt % 26 + 'a'; + if ((out_fd = creat(temp_files, 0644)) < 0) + error(TRUE, "Cannot creat ", temp_files); + file_cnt++; + } + merge(i, limit); + } + +/* Cleanup mess */ + i = (only_merge) ? args_limit - args_offset : 0; + while (i < file_cnt) (void) unlink(file_name(i++)); +} + +/* Merge () merges the files between start_file and limit_file. */ +void merge(start_file, limit_file) +int start_file, limit_file; +{ + register MERGE *smallest; /* Keeps track of smallest line */ + register int i; + int file_cnt = limit_file - start_file; /* Nr of files to merge */ + +/* Calculate size in core available for file_cnt merge structs */ + buf_size = MEMORY_SIZE / file_cnt - LINE_SIZE; + + mbrk(mem_top); /* First reset mem to lowest loc. */ + disabled = 0; /* All files not done yet */ + +/* Set up merge structures. */ + for (i = start_file; i < limit_file; i++) { + smallest = &merge_f[i - start_file]; + if (!strcmp(file_name(i), "-")) /* File is stdin */ + smallest->fd = 0; + else if ((smallest->fd = open(file_name(i), O_RDONLY)) < 0) { + smallest->fd = ERROR; + error(FALSE, "Cannot open ", file_name(i)); + disabled++; /* Done this file */ + continue; + } + smallest->buffer = msbrk(buf_size); + smallest->line = msbrk(LINE_SIZE); + smallest->cnt = smallest->read_chars = 0; + (void) read_line(smallest); /* Read first line */ + } + + if (disabled == file_cnt) { /* Couldn't open files */ + (void) close(out_fd); + return; + } + +/* Find a merg struct to assign smallest. */ + for (i = 0; i < file_cnt; i++) { + if (merge_f[i].fd != ERROR) { + smallest = &merge_f[i]; + break; + } + } + +/* Loop until all files minus one are done */ + while (disabled < file_cnt - 1) { + if (uniq) /* Skip all same lines */ + smallest = skip_lines(smallest, file_cnt); + else { /* Find smallest line */ + for (i = 0; i < file_cnt; i++) { + if (merge_f[i].fd == ERROR) + continue; /* We've had this one */ + if (compare(merge_f[i].line, smallest->line) < 0) + smallest = &merge_f[i]; + } + } /* Print line and read next */ + smallest = print(smallest, file_cnt); + } + + if (only_merge && uniq) + uniq_lines(smallest); /* Print only uniq lines */ + else /* Print rest of file */ + while (print(smallest, file_cnt) != NIL_MERGE); + + put_line(NIL_PTR); /* Flush output buffer */ +} + +/* Put_line () prints the line into the out_fd filedescriptor. If line equals + * NIL_PTR, the out_fd is flushed and closed. + */ +void put_line(line) +register char *line; +{ + static int index = 0; /* Index in out_buffer */ + + if (line == NIL_PTR) { /* Flush and close */ + mwrite(out_fd, out_buffer, index); + index = 0; + (void) close(out_fd); + return; + } + do { /* Fill out_buffer with line */ + out_buffer[index++] = *line; + if (index == IO_SIZE) { + mwrite(out_fd, out_buffer, IO_SIZE); + index = 0; + } + } while (*line++ != '\n'); +} + +/* + * Print () prints the line of the merg structure and tries to read another one. + * If this fails, it returns the next merg structure which file_descriptor is + * still open. If none could be found, a NIL structure is returned. + */ +MERGE *print(merg, file_cnt) +register MERGE *merg; +int file_cnt; /* Nr of files that are being merged */ +{ + register int i; + + put_line(merg->line); /* Print the line */ + + if (read_line(merg) == ERROR) { /* Read next line */ + for (i = 0; i < file_cnt; i++) { + if (merge_f[i].fd != ERROR) { + merg = &merge_f[i]; + break; + } + } + if (i == file_cnt) /* No more files left */ + return NIL_MERGE; + } + return merg; +} + +/* Read_line () reads a line from the fd from the merg struct. If the read + * failed, disabled is incremented and the file is closed. Readings are + * done in buf_size bytes. + * Lines longer than LINE_SIZE are silently truncated. + */ +int read_line(merg) +register MERGE *merg; +{ + register char *ptr = merg->line - 1; /* Ptr buf that will hold line */ + + do { + ptr++; + if (merg->cnt == merg->read_chars) { /* Read new buffer */ + if ((merg->read_chars = + read(merg->fd, merg->buffer, buf_size)) <= 0) { + (void) close(merg->fd); /* OOPS */ + merg->fd = ERROR; + disabled++; + return ERROR; + } + merg->cnt = 0; + } + *ptr = merg->buffer[merg->cnt++]; /* Assign next char of line */ + if (ptr - merg->line == LINE_SIZE - 1) + *ptr = '\n'; /* Truncate very long lines */ + } while (*ptr != '\n' && *ptr != '\0'); + + if (*ptr == '\0') /* Add '\n' to last line */ + *ptr = '\n'; + *++ptr = '\0'; /* Add '\0' */ + return OK; +} + +/* Skip_lines () skips all same lines in all the files currently being merged. + * It returns a pointer to the merge struct containing the smallest line. + */ +MERGE *skip_lines(smallest, file_cnt) +register MERGE *smallest; +int file_cnt; +{ + register int i; + int ret; + + if (disabled == file_cnt - 1) /* We've had all */ + return smallest; + + for (i = 0; i < file_cnt; i++) { + if (merge_f[i].fd == ERROR || smallest == &merge_f[i]) + continue; /* Don't check same file */ + while ((ret = compare(merge_f[i].line, smallest->line)) == 0) { + if (read_line(&merge_f[i]) == ERROR) break; /* EOF */ + } + if (ret < 0) /* Line wasn't smallest. Try again */ + return skip_lines(&merge_f[i], file_cnt); + } + return smallest; +} + +/* Uniq_lines () prints only the uniq lines out of the fd of the merg struct. */ +void uniq_lines(merg) +register MERGE *merg; +{ + char lastline[LINE_SIZE]; /* Buffer to hold last line */ + + for (;;) { + put_line(merg->line); /* Print this line */ + copy(lastline, merg->line); /* and save it */ + if (read_line(merg) == ERROR) /* Read the next */ + return; + /* Keep reading until lines duffer */ + while (compare(lastline, merg->line) == SAME) + if (read_line(merg) == ERROR) return; + } + + /* NOTREACHED */ +} + +/* + * Check_file () checks if a file is sorted in order according to the arguments + * given in main (). + */ +void check_file(fd, file) +int fd; +char *file; +{ + register MERGE *merg; /* 1 file only */ + char lastline[LINE_SIZE]; /* Save last line */ + register int ret; /* ret status of compare */ + + if (fd == 0) file = "stdin"; + merg = (MERGE *) mem_top; /* Assign MERGE structure */ + merg->buffer = mem_top + sizeof(MERGE); + merg->line = msbrk(LINE_SIZE); + merg->cnt = merg->read_chars = 0; + merg->fd = fd; + buf_size = MEMORY_SIZE - sizeof(MERGE); + + if (read_line(merg) == ERROR) /* Read first line */ + return; + copy(lastline, merg->line); /* and save it */ + + for (;;) { + if (read_line(merg) == ERROR) /* EOF reached */ + break; + if ((ret = compare(lastline, merg->line)) > 0) { + error(FALSE, "Disorder in file ", file); + write(2, merg->line, length(merg->line)); + break; + } else if (ret < 0) /* Copy if lines not equal */ + copy(lastline, merg->line); + else if (uniq) { + error(FALSE, "Non uniq line in file ", file); + write(2, merg->line, length(merg->line)); + break; + } + } + + mbrk(mem_top); /* Reset mem */ +} + +/* Length () returns the length of the argument line including the linefeed. */ +int length(line) +register char *line; +{ + register int i = 1; /* Add linefeed */ + + while (*line++ != '\n') i++; + return i; +} + +/* Copy () copies the src line into the dest line including linefeed. */ +void copy(dest, src) +register char *dest, *src; +{ + while ((*dest++ = *src++) != '\n'); +} + +/* Msbrk() does a sbrk() and checks the return value. */ +char *msbrk(size) +register int size; +{ + register char *address; + + if ((address = (char *)sbrk(size)) == (char *) -1) /* Nick added cast */ + error(TRUE, "Not enough memory. Use chmem to allocate more", NIL_PTR); + return address; +} + +/* Mbrk() does a brk() and checks the return value. */ +void mbrk(address) +char *address; +{ + if (brk(address) < 0) error(TRUE, "Cannot reset memory", NIL_PTR); +} + +void catch(dummy) +int dummy; /* to satisfy the prototype */ +{ + register int i; + + signal(SIGINT, SIG_IGN); + only_merge = FALSE; + for (i = 0; i < 26; i++) (void) unlink(file_name(i)); + exit(2); +} diff --git a/src/simple/split.c b/src/simple/split.c new file mode 100755 index 00000000..534f020c --- /dev/null +++ b/src/simple/split.c @@ -0,0 +1,133 @@ +/* split - split a file Author: Michiel Huisjes */ + +#include +#include +#include +#include +#include +#include + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +#ifndef std_err +#define std_err(x) write(STDOUT_FILENO, "split: ", 7); \ + write(STDOUT_FILENO, x, strlen(x)) +#endif + +#define CHUNK_SIZE 1024 + +int cut_line = 1000; +int infile; +char out_file[100]; +char *suffix; + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void split, (void)); +_PROTOTYPE(int newfile, (void)); +_PROTOTYPE(void usage, (void)); +_PROTOTYPE(void quit, (void)); + +int main(argc, argv) +int argc; +char **argv; +{ + unsigned short i; + + out_file[0] = 'x'; + infile = -1; + + if (argc < 1 && isatty(fileno(stdin))) usage(); + if (argc > 4) usage(); + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + if (argv[i][1] >= '0' && argv[i][1] <= '9' + && cut_line == 1000) + cut_line = atoi(argv[i]); + else if (argv[i][1] == '\0' && infile == -1) + infile = 0; + else + usage(); + } else if (infile == -1) { + if ((infile = open(argv[i], O_RDONLY)) < 0) { + std_err("Cannot open input file.\n"); + return(1); + } + } else + strcpy(out_file, argv[i]); + } + if (infile == -1) infile = 0; + if (infile == 0) { + if (isatty(0)) { + usage(); + return(1); + } + } + strcat(out_file, "aa"); + for (suffix = out_file; *suffix; suffix++); + suffix--; + +/* Appendix now points to last `a' of "aa". We have to decrement it by one */ + *suffix = 'a' - 1; + split(); + return(0); +} + +void split() +{ + char buf[CHUNK_SIZE]; + register char *index, *base; + register int n; + int fd; + long lines = 0L; + + fd = -1; + while ((n = read(infile, buf, CHUNK_SIZE)) > 0) { + base = index = buf; + while (--n >= 0) { + if (*index++ == '\n') + if (++lines % cut_line == 0) { + if (fd == -1) fd = newfile(); + if (write(fd, base, (int) (index - base)) != (int) (index - base)) + quit(); + base = index; + close(fd); + fd = -1; + } + } + if (index == base) continue; + if (fd == -1) fd = newfile(); + if (write(fd, base, (int) (index - base)) != (int) (index - base)) + quit(); + } +} + +int newfile() +{ + int fd; + + if (++*suffix > 'z') { /* Increment letter */ + *suffix = 'a'; /* Reset last letter */ + ++*(suffix - 1); /* Previous letter must be incremented */ + /* E.g. was `filename.az' */ + /* Now `filename.ba' */ + } + if ((fd = creat(out_file, 0644)) < 0) { + std_err("Cannot create new file.\n"); + return(2); + } + return fd; +} + +void usage() +{ + write(STDOUT_FILENO, "usage: split [-n] [file [name]]\n", 32); + return; +} + +void quit() +{ + std_err("split: write error\n"); + return; +} diff --git a/src/simple/su.c b/src/simple/su.c new file mode 100755 index 00000000..de14e0f0 --- /dev/null +++ b/src/simple/su.c @@ -0,0 +1,87 @@ +/* su - become super-user Author: Patrick van Kleef */ + +/* some changes for UZIX by Adriano Cunha */ + +#include +#include +#include +#include +#include + +/* True iff the invoker need not give a password. */ +#define privileged() (getgid() == 0) + +#define std_err(x) write(STDOUT_FILENO, x, strlen(x)) + +int main(argc, argv) +int argc; +char *argv[]; +{ + register char *name, *password; + char *shell; + char arg0[20]; + static char shell1[] = "/bin/sh"; + static char shell2[] = "/usr/bin/sh"; + int nr, login_shell = 0; + register struct passwd *pwd; + static char USER[20], LOGNAME[25], HOME[100], SHELL[100]; + + if (argc > 1 && strcmp(argv[1], "-") == 0) { + login_shell = 1; /* Read .profile */ + argv[1] = argv[0]; + argv++; + argc--; + } + if (argc > 1) { + name = argv[1]; + argv[1] = argv[0]; + argv++; + } else { + name = "root"; + } + + if ((pwd = getpwnam(name)) == 0) { + std_err("Unknown id: "); + std_err(name); + std_err("\n"); + exit(1); + } + if (!privileged() && (strcmp(pwd->pw_passwd, crypt("", pwd->pw_passwd)) != 0 || + strcmp(pwd->pw_passwd, "") != 0)) { + password = getpass("Password:"); + std_err("\n"); + if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd))) { + std_err("Sorry\n"); + exit(2); + } + } + if (login_shell) { + if ((shell = pwd->pw_shell)[0] == 0) shell = shell1; + } else { + if ((shell = getenv("SH")) == NULL) shell = shell1; + } + if (access(shell, 0) < 0) shell = shell2; + if ((argv[0] = strrchr(shell, '/')) == NULL) argv[0] = shell; else argv[0]++; + + if (login_shell) { + arg0[0] = '-'; + strncpy(arg0+1, argv[0], sizeof(arg0)-2); + arg0[sizeof(arg0)-1] = 0; + argv[0] = arg0; + strcpy(USER, "USER="); + strcpy(USER + 5, name); + putenv(USER); + strcpy(SHELL, "SH="); + strcpy(SHELL + 6, shell); + putenv(SHELL); + strcpy(HOME, "HOME="); + strcpy(HOME + 5, pwd->pw_dir); + putenv(HOME); + (void) chdir(pwd->pw_dir); + } + setgid(pwd->pw_gid); + setuid(pwd->pw_uid); + execv(shell, argv); + std_err("No shell\n"); + return(3); +} \ No newline at end of file diff --git a/src/simple/sum.c b/src/simple/sum.c new file mode 100755 index 00000000..7410a5ab --- /dev/null +++ b/src/simple/sum.c @@ -0,0 +1,120 @@ +/* sum - checksum a file Author: Martin C. Atkins */ + +/* + * This program was written by: + * Martin C. Atkins, + * University of York, + * Heslington, + * York. Y01 5DD + * England + * and is released into the public domain, on the condition + * that this comment is always included without alteration. + */ + +#include +#include +#include +#include +#include + +#define BUFFER_SIZE (512) + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +int rc = 0; + +#define error(x,y) fprintf(stderr, "sum: %s%s\n", x, y) + +char *defargv[] = {"-", 0}; + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void sum, (int fd, char *fname)); +_PROTOTYPE(void putd, (int number, int fw, int zeros)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + register int fd; + + if (*++argv == 0) { + if (isatty(fileno(stdin))) { + printf("usage: sum file1 file2 ...\n"); + return(1); + } + argv = defargv; + } + for (; *argv; argv++) { + if (argv[0][0] == '-' && argv[0][1] == '\0') + fd = 0; + else + fd = open(*argv, O_RDONLY); + + if (fd == -1) { + error("can't open ", *argv); + rc = 1; + continue; + } + sum(fd, (argc > 2) ? *argv : (char *) 0); + if (fd != 0) close(fd); + } + return(rc); +} + +void sum(fd, fname) +int fd; +char *fname; +{ + char buf[BUFFER_SIZE]; + register int i, n; + long size = 0; + unsigned crc = 0; + unsigned tmp, blks; + + while ((n = read(fd, buf, BUFFER_SIZE)) > 0) { + for (i = 0; i < n; i++) { + crc = (crc >> 1) + ((crc & 1) ? 0x8000 : 0); + tmp = buf[i] & 0377; + crc += tmp; + crc &= 0xffff; + size++; + } + } + + if (n < 0) { + if (fname) + error("read error on ", fname); + else + error("read error", (char *) 0); + rc = 1; + return; + } + putd(crc, 5, 1); + blks = (size + (long) BUFFER_SIZE - 1L) / (long) BUFFER_SIZE; + putd(blks, 6, 0); + if (fname) printf(" %s", fname); + printf("\n"); +} + +void putd(number, fw, zeros) +int number, fw, zeros; +{ +/* Put a decimal number, in a field width, to stdout. */ + + char buf[10]; + int n; + unsigned num; + + num = (unsigned) number; + for (n = 0; n < fw; n++) { + if (num || n == 0) { + buf[fw - n - 1] = '0' + num % 10; + num /= 10; + } else + buf[fw - n - 1] = zeros ? '0' : ' '; + } + buf[fw] = 0; + printf("%s", buf); +} diff --git a/src/simple/sync.c b/src/simple/sync.c new file mode 100755 index 00000000..3c144a25 --- /dev/null +++ b/src/simple/sync.c @@ -0,0 +1,8 @@ +/* sync.c + */ +#include + +int main(void) { + return sync(); +} + \ No newline at end of file diff --git a/src/simple/tail.c b/src/simple/tail.c new file mode 100755 index 00000000..f8d0de32 --- /dev/null +++ b/src/simple/tail.c @@ -0,0 +1,362 @@ +/* tail - copy the end of a file Author: Norbert Schlenker */ + +/* Syntax: tail [-f] [-c number | -n number] [file] + * tail -[number][c|l][f] [file] (obsolescent) + * tail +[number][c|l][f] [file] (obsolescent) + * Flags: + * -c number Measure starting point in bytes. If number begins + * with '+', the starting point is relative to the + * the file's beginning. If number begins with '-' + * or has no sign, the starting point is relative to + * the end of the file. + * -f Keep trying to read after EOF on files and FIFOs. + * -n number Measure starting point in lines. The number + * following the flag has significance similar to + * that described for the -c flag. + * + * If neither -c nor -n are specified, the default is tail -n 10. + * + * In the obsolescent syntax, an argument with a 'c' following the + * (optional) number is equivalent to "-c number" in the standard + * syntax, with number including the leading sign ('+' or '-') of the + * argument. An argument with 'l' following the number is equivalent + * to "-n number" in the standard syntax. If the number is not + * specified, 10 is used as the default. If neither 'c' nor 'l' are + * specified, 'l' is assumed. The character 'f' may be suffixed to + * the argument and is equivalent to specifying "-f" in the standard + * syntax. Look for lines marked "OBSOLESCENT". + * + * If no file is specified, standard input is assumed. + * + * P1003.2 does not specify tail's behavior when a count of 0 is given. + * It also does not specify clearly whether the first byte (line) of a + * file should be numbered 0 or 1. Historical behavior is that the + * first byte is actually number 1 (contrary to all Unix standards). + * Historically, a count of 0 (or -0) results in no output whatsoever, + * while a count of +0 results in the entire file being copied (just like + * +1). The implementor does not agree with these behaviors, but has + * copied them slavishly. Look for lines marked "HISTORICAL". + * + * Author: Norbert Schlenker + * Copyright: None. Released to the public domain. + * Reference: P1003.2 section 4.59 (draft 10) + * Notes: Under Minix, this program requires chmem =30000. + * Bugs: No internationalization support; all messages are in English. + */ + +/* Force visible Posix names */ +#ifndef _POSIX_SOURCE +#define _POSIX_SOURCE 1 +#endif + +/* External interfaces */ +#include +#include +#include +#include +#include +#include + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +/* External interfaces that should have been standardized into */ +#ifdef _MINIX +_PROTOTYPE(int getopt, (int argc, char **argv, char *options)); +#else +extern int getopt(); +#endif +extern char *optarg; +extern int optind; + +/* We expect this constant to be defined in in a Posix program, + * but we'll specify it here just in case it's been left out. + */ +#if defined(MSX_UZIX_TARGET) || defined(PC_UZIX_TARGET) +#define LINE_MAX 256 +#endif + +#ifndef LINE_MAX +#define LINE_MAX 2048 /* minimum acceptable lower bound */ +#endif + +/* Magic numbers suggested or required by Posix specification */ +#define SUCCESS 0 /* exit code in case of success */ +#define FAILURE 1 /* or failure */ +#define DEFAULT_COUNT 10 /* default number of lines or bytes */ +#define MIN_BUFSIZE (LINE_MAX * DEFAULT_COUNT) +#define SLEEP_INTERVAL 1 /* sleep for one second intervals with -f */ + +#define FALSE 0 +#define TRUE 1 + +/* Internal functions - prototyped under Minix */ +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(int tail, (int count, int bytes, int read_until_killed)); +_PROTOTYPE(int keep_reading, (void)); +_PROTOTYPE(void usage, (void)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + int cflag = FALSE; + int nflag = FALSE; + int fflag = FALSE; + int number = -DEFAULT_COUNT; + char *suffix; + int opt; + struct stat stat_buf; + +/* Determining whether this invocation is via the standard syntax or + * via an obsolescent one is a nasty kludge. Here it is, but there is + * no pretense at elegance. + */ + if (argc == 1) { + if (isatty(fileno(stdin))) usage(); + /* simple: default read of a pipe */ + exit(tail(-DEFAULT_COUNT, 0, fflag)); + } + if ((argv[1][0] == '+') || /* OBSOLESCENT */ + (argv[1][0] == '-' && ((isdigit(argv[1][1])) || + (argv[1][1] == 'l') || + (argv[1][1] == 'c' && argv[1][2] == 'f')))) { + --argc; ++argv; + if (isdigit(argv[0][1])) { + number = (int)strtol(argv[0], &suffix, 10); + if (number == 0) { /* HISTORICAL */ + if (argv[0][0] == '+') + number = 1; + else + exit(SUCCESS); + } + } else { + number = (argv[0][0] == '+') ? DEFAULT_COUNT : -DEFAULT_COUNT; + suffix = &(argv[0][1]); + } + if (*suffix != '\0') { + if (*suffix == 'c') { + cflag = TRUE; + ++suffix; + } + else + if (*suffix == 'l') { + nflag = TRUE; + ++suffix; + } + } + if (*suffix != '\0') { + if (*suffix == 'f') { + fflag = TRUE; + ++suffix; + } + } + if (*suffix != '\0') { /* bad form: assume to be a file name */ + number = -DEFAULT_COUNT; + cflag = nflag = FALSE; + fflag = FALSE; + } else { + --argc; ++argv; + } + } else { /* new standard syntax */ + while ((opt = getopt(argc, argv, "c:fn:")) != EOF) { + switch (opt) { + case 'c': + cflag = TRUE; + if (*optarg == '+' || *optarg == '-') + number = atoi(optarg); + else + if (isdigit(*optarg)) + number = -atoi(optarg); + else + usage(); + if (number == 0) { /* HISTORICAL */ + if (*optarg == '+') + number = 1; + else + exit(SUCCESS); + } + break; + case 'f': + fflag = TRUE; + break; + case 'n': + nflag = TRUE; + if (*optarg == '+' || *optarg == '-') + number = atoi(optarg); + else + if (isdigit(*optarg)) + number = -atoi(optarg); + else + usage(); + if (number == 0) { /* HISTORICAL */ + if (*optarg == '+') + number = 1; + else + exit(SUCCESS); + } + break; + default: + usage(); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + } + + if (argc > 1 || /* too many arguments */ + (cflag && nflag)) { /* both bytes and lines specified */ + usage(); + } + + if (argc > 0) { /* an actual file */ + if (freopen(argv[0], "r", stdin) != stdin) { + fputs("tail: could not open ", stderr); + fputs(argv[0], stderr); + fputs("\n", stderr); + exit(FAILURE); + } + /* There is an optimization possibility here. If a file is being + * read, we need not look at the front of it. If we seek backwards + * from the end, we can (potentially) avoid looking at most of the + * file. Some systems fail when asked to seek backwards to a point + * before the start of the file, so we avoid that possibility. + */ + if (number < 0 && fstat(fileno(stdin), &stat_buf) == 0) { + long offset = cflag ? (long)number : (long)number * LINE_MAX; + +#if 0 + if (-offset < (512L*stat_buf.st_size.o_blkno + + stat_buf.st_size.o_offset)) +#else + if (-offset < stat_buf.st_size) +#endif + fseek(stdin, offset, SEEK_END); + } + } else { + fflag = FALSE; /* force -f off when reading a pipe */ + } + exit(tail(number, cflag, fflag)); + /* NOTREACHED */ +} + +int tail(count, bytes, read_until_killed) +int count; /* lines or bytes desired */ +int bytes; /* TRUE if we want bytes */ +int read_until_killed; /* keep reading at EOF */ +{ + int c; + char *buf; /* pointer to input buffer */ + char *buf_end; /* and one past its end */ + char *start; /* pointer to first desired character in buf */ + char *finish; /* pointer past last desired character */ + int wrapped_once = FALSE; /* TRUE after buf has been filled once */ + +/* This is magic. If count is positive, it means start at the count'th + * line or byte, with the first line or byte considered number 1. Thus, + * we want to SKIP one less line or byte than the number specified. In + * the negative case, we look backward from the end of the file for the + * (count + 1)'th newline or byte, so we really want the count to be one + * LARGER than was specified (in absolute value). In either case, the + * right thing to do is: + */ + --count; + +/* Count is positive: skip the desired lines or bytes and then copy. */ + if (count >= 0) { + while (count > 0 && (c = getchar()) != EOF) { + if (bytes || c == '\n') + --count; + } + while ((c = getchar()) != EOF) { + if (putchar(c) == EOF) + return FAILURE; + } + if (read_until_killed) + return keep_reading(); + return ferror(stdin) ? FAILURE : SUCCESS; + } + +/* Count is negative: allocate a reasonably large buffer. */ + if ((buf = (char *)malloc(MIN_BUFSIZE + 1)) == (char *)NULL) { + fputs("tail: out of memory\n", stderr); + return FAILURE; + } + buf_end = buf + (MIN_BUFSIZE + 1); + +/* Read the entire file into the buffer. */ + finish = buf; + while ((c = getchar()) != EOF) { + *finish++ = c; + if (finish == buf_end) { + finish = buf; + wrapped_once = TRUE; + } + } + if (ferror(stdin)) + return FAILURE; + +/* Back up inside the buffer. The count has already been adjusted to + * back up exactly one character too far, so we will bump the buffer + * pointer once after we're done. + * + * BUG: For large line counts, the buffer may not be large enough to + * hold all the lines. The specification allows the program to + * fail in such a case - this program will simply dump the entire + * buffer's contents as its best attempt at the desired behavior. + */ + if (finish != buf || wrapped_once) { /* file was not empty */ + start = (finish == buf) ? buf_end - 1 : finish - 1; + while (start != finish) { + if ((bytes || *start == '\n') && ++count == 0) + break; + if (start == buf) { + start = buf_end - 1; + if (!wrapped_once) /* never wrapped: stop now */ + break; + } else { + --start; + } + } + if (++start == buf_end) { /* bump after going too far */ + start = buf; + } + if (finish > start) { + fwrite(start, 1, finish - start, stdout); + } else { + fwrite(start, 1, buf_end - start, stdout); + fwrite(buf, 1, finish - buf, stdout); + } + } + if (read_until_killed) + return keep_reading(); + return ferror(stdout) ? FAILURE : SUCCESS; +} + +/* Wake at intervals to reread standard input. Copy anything read to + * standard output and then go to sleep again. + */ +int keep_reading() +{ + int c; + + for (;;) { + sleep(SLEEP_INTERVAL); + clearerr(stdin); + while ((c = getchar()) != EOF) { + if (putchar(c) == EOF) + return FAILURE; + } + if (ferror(stdin)) + return FAILURE; + } +} + +/* Tell the user the standard syntax. */ +void usage() +{ + fputs("usage: tail [-f] [-c number | -n number] [file]\n", stderr); + exit(FAILURE); +} diff --git a/src/simple/tar.c b/src/simple/tar.c new file mode 100755 index 00000000..01c75b67 --- /dev/null +++ b/src/simple/tar.c @@ -0,0 +1,1200 @@ +/* tar - tape archiver Author: Michiel Huisjes */ + +/* Usage: tar [cxt][vo][F][f] tapefile [files] + * + * attempt to make tar to conform to POSIX 1003.1 + * disclaimer: based on an old (1986) POSIX draft. + * Klamer Schutte, 20/9/89 + * + * Changes: + * Changed to handle the original minix-tar format. KS 22/9/89 + * Changed to handle BSD4.3 tar format. KS 22/9/89 + * Conform to current umask if not super-user. KS 22/9/89 + * Update usage message to show f option KS 22/9/89 + * + * + * 1) tar will back itself up, should check archive inode num(&dev) and + then check the target inode number. In verbose mode, issue + warning, in all cases ignore target. + marks@mgse Mon Sep 25 10:38:58 CDT 1989 + added global varaibles, made changes to main() and add_file(); + maks@mgse Mon Sep 25 12:09:20 CDT 1989 + + 2) tar will not notice that a file has changed size while it was being + backed up. should issue warning. + marks@mgse Mon Sep 25 10:38:58 CDT 1989 + + 3) the 'f' option was not documented in usage[]. + marks@mgse Mon Sep 25 12:03:20 CDT 1989 + changed both usage[] defines. Why are there two (one is commented out)? + ( deleted by me (was done twice) -- KS, 2/10/89 ) + * + * changed stat on tar_fd to an fstat KS 2/10/89 + * deleted mkfifo() code -- belongs in libc.a KS 2/10/89 + * made ar_dev default to -1 : an illegal device KS 2/10/89 + * made impossible to chown if normal user KS 2/10/89 + * if names in owner fields not known use numirical values KS 2/10/89 + * creat with mask 666 -- use umask if to liberal KS 2/10/89 + * allow to make directories as ../directory KS 2/10/89 + * allow tmagic field to end with a space (instead of \0) KS 2/10/89 + * correct usage of tmagic field KS 3/10/89 + * made mkdir() to return a value if directory == "." KS 3/10/89 + * made lint complains less (On a BSD 4.3 system) KS 3/10/89 + * use of directory(3) routines KS 3/10/89 + * deleted use of d_namlen selector of struct dirent KS 18/10/89 + * support mknod4(2) EC 7/7/90 + * forget inodes when link count expires EC 6/4/91 + * don't remember directories *twice*! + * added 'p' flag to ignore umask for normal user KJB 6/10/92 + * mknod4(2) out KJB 30/10/94 + * added 'D' flag to not recurse into directories KJB 19/12/94 + * + * Bugs: + * verbose mode is not reporting consistent + * code needs cleanup + * prefix field is not used + * timestamp of a directory will not be correct if there are files to be + * unpacked in the directory + * (add you favorite bug here (or two (or three (or ...)))) +*/ + +#include +#include /* need NULL */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Nick to access mkfifo() */ +#include + +#if defined(MSX_UZIX_TARGET) || defined (PC_UZIX_TARGET) +#define nlink_t int +#define geteuid getuid +#endif + +#define TBLOCK 512 +#define NAMSIZ 100 +#define PFXSIZ 155 + +#define TMODLEN 8 +#define TUIDLEN 8 +#define TGIDLEN 8 +#define TSIZLEN 12 +#define TMTMLEN 12 +#define TCKSLEN 8 + +#define TMAGIC "ustar" +#define TMAGLEN 6 +#define TVERSION "00" +#define TVERSLEN 2 +#define TUNMLEN 32 +#define TGNMLEN 32 +#define TDEVLEN 8 + +#define REGTYPE '0' +#define AREGTYPE '\0' +#define LNKTYPE '1' +#define SYMTYPE '2' +#define CHRTYPE '3' +#define BLKTYPE '4' +#define DIRTYPE '5' +#define FIFOTYPE '6' +#define CONTTYPE '7' + +#define TSUID 04000 +#define TSGID 02000 +#define TSVTX 01000 + +#define TUREAD 00400 +#define TUWRITE 00200 +#define TUEXEC 00100 +#define TGREAD 00040 +#define TGWRITE 00020 +#define TGEXEC 00010 +#define TOREAD 00004 +#define TOWRITE 00002 +#define TOEXEC 00001 + +union hblock { + char dummy[TBLOCK]; + struct header { + char name[NAMSIZ]; + char mode[TMODLEN]; + char uid[TUIDLEN]; + char gid[TGIDLEN]; + char size[TSIZLEN]; + char mtime[TMTMLEN]; + char chksum[TCKSLEN]; + char typeflag; + char linkname[NAMSIZ]; + char magic[TMAGLEN]; + char version[TVERSLEN]; + char uname[TUNMLEN]; + char gname[TGNMLEN]; + char devmajor[TDEVLEN]; + char devminor[TDEVLEN]; + char prefix[PFXSIZ]; + } dbuf; +}; + +#define POSIX_COMP /* POSIX compatible */ +#define DIRECT_3 /* use directory(3) routines */ + +#ifdef DIRECT_3 +#ifndef BSD +/* To all minix users: i am sorry, developed this piece of code on a + * BSD system. KS 18/10/89 */ +#include +#define direct dirent /* stupid BSD non-POSIX compatible name! */ +#else /* BSD */ +#include +#include +#endif /* BSD */ +#endif /* DIRECT_3 */ + +#ifdef S_IFPIPE +#define HAVE_FIFO /* have incorporated Simon Pooles' changes */ +#endif +#ifdef S_IFLNK +#define HAVE_SYMLINK +#endif + +typedef char BOOL; +#define TRUE 1 +#define FALSE 0 + +#define STRING_SIZE 256 /* string buffer size */ +#define HEADER_SIZE TBLOCK +#define NAME_SIZE NAMSIZ +/* #define BLOCK_BOUNDARY 20 -- not in POSIX ! */ + +typedef union hblock HEADER; + +/* Make the MINIX member names overlap to the POSIX names */ +#define m_name name +#define m_mode mode +#define m_uid uid +#define m_gid gid +#define m_size size +#define m_time mtime +#define m_checksum chksum +#define m_linked typeflag +#define m_link linkname +#define hdr_block dummy +#define m header +#define member dbuf + +/* Structure used to note links */ +struct link { + ino_t ino; + dev_t dev; + nlink_t nlink; + struct link *next; + char name[1]; +} *link_top = NULL; + +HEADER header; + +#define INT_TYPE (sizeof(header.member.m_uid)) +#define LONG_TYPE (sizeof(header.member.m_size)) + +#define NIL_HEADER ((HEADER *) 0) +#define NIL_PTR ((char *) 0) +#define TBLOCK_SIZE TBLOCK + +#define flush() print(NIL_PTR) + +BOOL show_fl, creat_fl, ext_fl; + +int tar_fd; +char usage[] = "usage: tar [cxt][voFfpD] tarfile [files]"; +char io_buffer[TBLOCK_SIZE]; +char path[NAME_SIZE]; +char pathname[NAME_SIZE]; +int force_flag = 0; +#ifdef ORIGINAL_DEFAULTS +int chown_flag = 1; +int verbose_flag = 1; +#else +int chown_flag = 0; +int verbose_flag = 0; +#endif +int norec_flag = 0; + +/* Make sure we don't tar ourselves. marks@mgse Mon Sep 25 12:06:28 CDT 1989 */ +ino_t ar_inode; /* archive inode number */ +dev_t ar_dev; /* archive device number */ + +int total_blocks; +int u_mask; /* one's complement of current umask */ + +#define block_size() (int) ((convert(header.member.m_size, LONG_TYPE) \ + + (long) TBLOCK_SIZE - 1) / (long) TBLOCK_SIZE) + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void error, (char *s1, char *s2)); +_PROTOTYPE(BOOL get_header, (void)); +_PROTOTYPE(void tarfile, (void)); +_PROTOTYPE(void skip_entry, (void)); +_PROTOTYPE(void extract, (char *file)); +_PROTOTYPE(void delete, (char *file)); +_PROTOTYPE(void do_chown, (char *file)); +_PROTOTYPE(void timestamp, (char *file)); +_PROTOTYPE(void copy, (char *file, int from, int to, long bytes)); +_PROTOTYPE(long convert, (char str[], int type)); +_PROTOTYPE(int checksum, (void)); +_PROTOTYPE(int is_dir, (char *file)); +_PROTOTYPE(char *path_name, (char *file)); +_PROTOTYPE(void add_path, (char *name)); +_PROTOTYPE(void add_file, (char *file)); +_PROTOTYPE(void verb_print, (char *s1, char *s2)); +_PROTOTYPE(void add_close, (int fd)); +_PROTOTYPE(int add_open, (char *file, struct stat * st)); +_PROTOTYPE(void make_header, (char *file, struct stat * st)); +_PROTOTYPE(void is_added, (struct stat * st, char *file)); +_PROTOTYPE(void is_deleted, (struct stat * st)); +_PROTOTYPE(char *is_linked, (struct stat * st)); +_PROTOTYPE(void clear_header, (void)); +_PROTOTYPE(void adjust_boundary, (void)); +_PROTOTYPE(void mread, (int fd, char *address, int bytes)); +_PROTOTYPE(void mwrite, (int fd, char *address, int bytes)); +_PROTOTYPE(int bread, (int fd, char *address, int bytes)); +_PROTOTYPE(int bwrite, (int fd, char *address, int bytes)); +_PROTOTYPE(void print, (char *str)); +_PROTOTYPE(char *num_out, (long number)); +_PROTOTYPE(void string_print, (char *buffer, char *fmt,...)); + +void error(s1, s2) +char *s1, *s2; +{ + string_print(NIL_PTR, "%s %s\n", s1, s2 ? s2 : ""); + flush(); + exit(1); +} + +int main(argc, argv) +int argc; +register char *argv[]; +{ + register char *mem_name; + register char *ptr; + struct stat st; + int i; + + if (argc < 3) error(usage, NIL_PTR); + + for (ptr = argv[1]; *ptr; ptr++) { + switch (*ptr) { + case 'c': creat_fl = TRUE; break; + case 'x': ext_fl = TRUE; break; + case 't': show_fl = TRUE; break; + case 'v': /* verbose output -Dal */ + verbose_flag = !verbose_flag; + break; + case 'o': /* chown/chgrp files -Dal */ + chown_flag = TRUE; + break; + case 'F': /* IGNORE ERRORS -Dal */ + force_flag = TRUE; + break; + case 'f': /* standard U*IX usage -KS */ + break; + case 'p': /* restore file modes right, ignore umask. */ + (void) umask(0); + break; + case 'D': /* do not recursively add directories. */ + norec_flag = TRUE; + break; + default: error(usage, NIL_PTR); + } + } + + if (creat_fl + ext_fl + show_fl != 1) error(usage, NIL_PTR); + + if (strcmp(argv[2], "-") == 0)/* only - means stdin/stdout - KS */ + tar_fd = creat_fl ? 1 : 0; /* '-' means used + * stdin/stdout -Dal */ + else + tar_fd = creat_fl ? creat(argv[2], 0666) : open(argv[2], O_RDONLY); + + if (tar_fd < 0) error("Cannot open ", argv[2]); + + if (geteuid()) { /* check if super-user */ + int save_umask; + save_umask = umask(0); + u_mask = ~save_umask; + umask(save_umask); + chown_flag = TRUE; /* normal user can't chown */ + } else + u_mask = ~0; /* don't restrict if 'privileged utility' */ + + ar_dev = -1; /* impossible device nr */ + if (creat_fl) { + if (tar_fd > 1 && fstat(tar_fd, &st) < 0) + error("Can't stat ", argv[2]); /* will never be here, + * right? */ + else { /* get archive inode & device */ + ar_inode = st.st_ino; /* save files inode */ + ar_dev = st.st_dev; /* save files device */ + } /* marks@mgse Mon Sep 25 11:30:45 CDT 1989 */ + + for (i = 3; i < argc; i++) { + add_file(argv[i]); + path[0] = '\0'; + } + adjust_boundary(); + } else if (ext_fl) { + /* Extraction code moved here from tarfile() MSP */ + while (get_header()) { + mem_name = header.member.m_name; + if (is_dir(mem_name)) { + for (ptr = mem_name; *ptr; ptr++); + *(ptr - 1) = '\0'; + header.dbuf.typeflag = '5'; + } + for (i = 3; i < argc; i++) + if (!strncmp(argv[i], mem_name, strlen(argv[i]))) + break; + if (argc == 3 || (i < argc)) { + extract(mem_name); + } else if (header.dbuf.typeflag == '0' || + header.dbuf.typeflag == 0 || + header.dbuf.typeflag == ' ') + skip_entry(); + flush(); + } + } else + tarfile(); /* tarfile() justs prints info. now MSP */ + + flush(); + return(0); +} + +BOOL get_header() +{ + register int check; + + mread(tar_fd, (char *) &header, sizeof(header)); + if (header.member.m_name[0] == '\0') return FALSE; + + if (force_flag) /* skip checksum verification -Dal */ + return TRUE; + + check = (int) convert(header.member.m_checksum, INT_TYPE); + + if (check != checksum()) error("Tar: header checksum error.", NIL_PTR); + + return TRUE; +} + +/* Tarfile() just lists info about archive now; as of the t flag. */ +/* Extraction has been moved into main() as that needs access to argv[] */ + +void tarfile() +{ + register char *mem_name; + + while (get_header()) { + mem_name = header.member.m_name; + string_print(NIL_PTR, "%s%s", mem_name, + (verbose_flag ? " " : "\n")); + switch (header.dbuf.typeflag) { + case '1': + verb_print("linked to", header.dbuf.linkname); + break; + case '2': + verb_print("symbolic link to", header.dbuf.linkname); + break; + case '6': verb_print("", "fifo"); break; + case '3': + case '4': + if (verbose_flag) { + char sizebuf[TSIZLEN + 1]; + + strncpy(sizebuf, header.dbuf.size, (size_t) TSIZLEN); + sizebuf[TSIZLEN] = 0; + string_print(NIL_PTR, + "%s special file major %s minor %s\n", + (header.dbuf.typeflag == '3' ? + "character" : "block"), + header.dbuf.devmajor, + header.dbuf.devminor, + sizebuf); + } + break; + case '0': /* official POSIX */ + case 0: /* also mentioned in POSIX */ + case ' ': /* ofetn used */ + if (!is_dir(mem_name)) { + if (verbose_flag) + string_print(NIL_PTR, "%d tape blocks\n", + block_size()); + skip_entry(); + break; + } else /* FALL TROUGH */ + case '5': + verb_print("", "directory"); + break; + default: + string_print(NIL_PTR, "not recogised item %d\n", + header.dbuf.typeflag); + } + flush(); + } +} + +void skip_entry() +{ + register int blocks = block_size(); + + while (blocks--) (void) bread(tar_fd, io_buffer, TBLOCK_SIZE); +} + +void extract(file) +register char *file; +{ + register int fd; + char *pd1, *pd2; /* walk thru failed directory path */ + + switch (header.dbuf.typeflag) { + case '1': /* Link */ + delete(file); + if (link(header.member.m_link, file) < 0) + string_print(NIL_PTR, "Cannot link %s to %s: %s\n", + header.member.m_link, file, strerror(errno)); + else if (verbose_flag) + string_print(NIL_PTR, "Linked %s to %s\n", + header.member.m_link, file); + return; + case '5': /* directory */ + if (!(file[0] == '.' && file[1] == '\0')) delete(file); + if ((file[0] == '.' && file[1] == '\0') || mkdir(file, 0700) == 0) { + do_chown(file); + verb_print("created directory", file); + } else { + string_print(NIL_PTR, "Can't make directory %s: %s\n", + file, strerror(errno)); + } + return; + case '3': /* character special */ + case '4': /* block special */ + { + int dmajor, dminor, mode; + + dmajor = (int) convert(header.dbuf.devmajor, INT_TYPE); + dminor = (int) convert(header.dbuf.devminor, INT_TYPE); + mode = (header.dbuf.typeflag == '3' ? S_IFCHR : S_IFBLK); + delete(file); + if (mknod(file, mode, (dmajor << 8 | dminor)) == 0) { + if (verbose_flag) string_print(NIL_PTR, + "made %s special file major %s minor %s\n", + (header.dbuf.typeflag == '3' ? + "character" : "block"), + header.dbuf.devmajor, + header.dbuf.devminor); + do_chown(file); + } + else + { + string_print(NIL_PTR, + "cannot make %s special file major %s minor %s: %s\n", + (header.dbuf.typeflag == '3' ? + "character" : "block"), + header.dbuf.devmajor, + header.dbuf.devminor, + strerror(errno)); + } + return; + } + case '2': /* symbolic link */ +#ifdef HAVE_SYMLINK + delete(file); + if (symlink(header.member.m_link, file) < 0) + string_print(NIL_PTR, "Cannot make symbolic link %s to %s: %s\n", + header.member.m_link, file, strerror(errno)); + else if (verbose_flag) + string_print(NIL_PTR, "Symbolic link %s to %s\n", + header.member.m_link, file); + return; +#endif + case '7': /* contiguous file -- what is this (KS) */ + print("Not implemented file type\n"); + return; /* not implemented, but break out */ +#ifdef HAVE_FIFO + case '6': /* fifo */ + delete(file); + if (mkfifo(file, 0) == 0) { /* is chmod'ed in do_chown */ + do_chown(file); + verb_print("made fifo", file); + } else + string_print(NIL_PTR, "Can't make fifo %s: %s\n", + file, strerror(errno)); + return; +#endif + } + + /* Create regular file. If failure, try to make missing directories. */ + if ((fd = creat(file, 0600)) < 0) { + pd1 = file; + while ((pd2 = index(pd1, '/')) > (char *) 0) { + *pd2 = '\0'; + if (access(file, 1) < 0) + if (mkdir(file, 0777) < 0) { + string_print(NIL_PTR, "Cannot mkdir %s: %s\n", + file, strerror(errno)); + return; + } else + string_print(NIL_PTR, "Made directory %s\n", file); + *pd2 = '/'; + pd1 = ++pd2; + } + if ((fd = creat(file, 0600)) < 0) { + string_print(NIL_PTR, "Cannot create %s: %s\n", + file, strerror(errno)); + return; + } + } + copy(file, tar_fd, fd, convert(header.member.m_size, LONG_TYPE)); + (void) close(fd); + + do_chown(file); +} + +void delete(file) +char *file; +{ + /* remove a file or an empty directory */ + struct stat stbuf; + + if (stat(file, &stbuf) < 0) return; + + if (S_ISDIR(stbuf.st_mode)) (void) rmdir(file); else (void) unlink(file); + /* leave error reporting to the create following soon. */ +} + +void do_chown(file) +char *file; +{ + int uid = -1, gid = -1; /* these are illegal ??? -- KS */ + + if (!chown_flag) { /* set correct owner and group -Dal */ + if (header.dbuf.magic[TMAGLEN] == ' ') + header.dbuf.magic[TMAGLEN] = '\0'; /* some tars out there + * ... */ + if (strncmp(TMAGIC, header.dbuf.magic, (size_t) TMAGLEN)) { + struct passwd *pwd; + struct group *grp; + + pwd = getpwnam(header.dbuf.uname); + if (pwd != NULL) uid = pwd->pw_uid; + grp = getgrnam(header.dbuf.gname); + if (grp != NULL) gid = grp->gr_gid; + } + if (uid == -1) uid = (int) convert(header.member.m_uid, INT_TYPE); + if (gid == -1) gid = (int) convert(header.member.m_gid, INT_TYPE); + chown(file, uid, gid); + } + chmod(file, u_mask & (int) convert(header.member.m_mode, INT_TYPE)); + + /* Should there be a timestamp if the chown failes? -- KS */ + timestamp(file); + +} + +void timestamp(file) +char *file; +{ + struct utimbuf buf; + +#if defined(MSX_UZIX_TARGET) || defined(PC_UZIX_TARGET) + int y=0,mn=0,d=0,hh=0,mm=0; + unsigned long t1; + time_t tt; + + t1=convert(header.dbuf.mtime, LONG_TYPE); + if (t1>=31536000) { + y=t1/31536000L; + t1=t1-(y*31536000L); + y=y-10; + } + if (t1>=2592000) { + mn=t1/2592000L; + t1=t1-(mn*2592000L); + mn++; + } + if (t1>=86400) { + d=t1/86400; + t1=t1-d*86400; + d++; + } + if (t1>=3600) { + hh=t1/3600; + t1=t1-hh*3600; + } + if (t1>=60) { + mm=t1/60; + t1=t1-mm*60; + } + tt.t_time=(((int)hh << 8) << 3) | ((int)mm << 5) | ((int)t1 >> 1); + tt.t_date=(((int)y << 8) << 1) | ((int)mn << 5) | d; + buf.modtime = buf.actime = tt; +#else + buf.modtime = buf.actime = convert(header.dbuf.mtime, LONG_TYPE); +#endif + + utime(file, &buf); +} + +void copy(file, from, to, bytes) +char *file; +int from, to; +register long bytes; +{ + register int rest; + int blocks = (int) ((bytes + (long) TBLOCK_SIZE - 1) / (long) TBLOCK_SIZE); + + if (verbose_flag) + string_print(NIL_PTR, "%s, %d tape blocks\n", file, blocks); + + while (blocks--) { + (void) bread(from, io_buffer, TBLOCK_SIZE); + rest = (bytes > (long) TBLOCK_SIZE) ? TBLOCK_SIZE : (int) bytes; + mwrite(to, io_buffer, (to == tar_fd) ? TBLOCK_SIZE : rest); + bytes -= (long) rest; + } +} + +long convert(str, type) +char str[]; +int type; +{ + register long ac = 0L; + register int i; + + for (i = 0; i < type; i++) { + if (str[i] >= '0' && str[i] <= '7') { + ac <<= 3; + ac += (long) (str[i] - '0'); + } + } + + return ac; +} + +int checksum() +{ + register char *ptr = header.member.m_checksum; + register int ac = 0; + + while (ptr < &header.member.m_checksum[INT_TYPE]) *ptr++ = ' '; + + ptr = header.hdr_block; + while (ptr < &header.hdr_block[TBLOCK_SIZE]) ac += *ptr++; + + return ac; +} + +int is_dir(file) +register char *file; +{ + while (*file++ != '\0'); + + return(*(file - 2) == '/'); +} + + +char *path_name(file) +register char *file; +{ + + string_print(pathname, "%s%s", path, file); + return pathname; +} + +void add_path(name) +register char *name; +{ + register char *path_ptr = path; + + while (*path_ptr) path_ptr++; + + if (name == NIL_PTR) { + while (*path_ptr-- != '/'); + while (*path_ptr != '/' && path_ptr != path) path_ptr--; + if (*path_ptr == '/') path_ptr++; + *path_ptr = '\0'; + } else { + while (*name) { + if (path_ptr == &path[NAME_SIZE]) + error("Pathname too long", NIL_PTR); + *path_ptr++ = *name++; + } + *path_ptr++ = '/'; + *path_ptr = '\0'; + } +} + +/* + * add a file to the archive +*/ +void add_file(file) +register char *file; +{ + struct stat st; + char *linkname; + register int fd = -1; + char namebuf[16]; /* -Dal */ + char cwd[129]; /* -KS */ + +#ifdef HAVE_SYMLINK + if (lstat(file, &st) < 0) { +#else + if (stat(file, &st) < 0) { +#endif + string_print(NIL_PTR, "%s: %s\n", file, strerror(errno)); + return; + } + if (st.st_dev == ar_dev && st.st_ino == ar_inode) { + string_print(NIL_PTR, "Cannot tar current archive file (%s)\n", file); + return; + } /* marks@mgse Mon Sep 25 12:06:28 CDT 1989 */ + if ((fd = add_open(file, &st)) < 0) { + string_print(NIL_PTR, "Cannot open %s\n", file); + return; + } + make_header(path_name(file), &st); + if ((linkname = is_linked(&st)) != NULL) { + strncpy(header.dbuf.linkname, linkname, (size_t) NAMSIZ); + header.dbuf.typeflag = '1'; + if (verbose_flag) string_print(NIL_PTR, "linked %s to %s\n", + header.dbuf.linkname, file); + string_print(header.member.m_checksum, "%I ", checksum()); + mwrite(tar_fd, (char *) &header, sizeof(header)); + } else { + is_added(&st, file); + switch (st.st_mode & S_IFMT) { + case S_IFREG: + header.dbuf.typeflag = '0'; + string_print(header.member.m_checksum, "%I ", checksum()); + mwrite(tar_fd, (char *) &header, sizeof(header)); +#if 0 + copy(path_name(file), fd, tar_fd, + (long) (512L*st.st_size.o_blkno + st.st_size.o_offset)); +#else + copy(path_name(file), fd, tar_fd, (long) st.st_size); +#endif + break; + case S_IFDIR: + header.dbuf.typeflag = '5'; + string_print(header.member.m_checksum, "%I ", checksum()); + mwrite(tar_fd, (char *) &header, sizeof(header)); + verb_print("read directory", file); + if (norec_flag) break; + if (NULL == getcwd(cwd, (int) sizeof cwd)) + string_print(NIL_PTR, "Error: cannot getcwd()\n"); + else if (chdir(file) < 0) + string_print(NIL_PTR, "Cannot chdir to %s: %s\n", + file, strerror(errno)); + else { + add_path(file); +#ifdef DIRECT_3 + { + DIR *dirp; + struct direct *dp; + struct stat dst; + + add_close(fd); + fd= 0; + dirp = opendir("."); + while (NULL != (dp = readdir(dirp))) + if (strcmp(dp->d_name, ".") == 0) + is_linked(&st); + else if (strcmp(dp->d_name, "..") == 0) { + if (stat("..", &dst) == 0) + is_linked(&dst); + } else { + strcpy(namebuf, dp->d_name); + add_file(namebuf); + } + closedir(dirp); + } +#else + { + int i; + struct direct dir; + struct stat dst; + + for (i = 0; i < 2; i++) { /* . and .. */ + mread(fd, &dir, sizeof(dir)); + if (strcmp(dir.d_name, ".") == 0) + is_linked(&st); + else if (strcmp(dir.d_name, "..") == 0) { + if (stat("..", &dst) == 0) + is_linked(&dst); + } else + break; + } + while (bread(fd, &dir, sizeof(dir)) == sizeof(dir)) + if (dir.d_ino) { + strncpy(namebuf, dir.d_name, + (size_t) DIRSIZ); + namebuf[DIRSIZ] = '\0'; + add_file(namebuf); + } + } +#endif + chdir(cwd); + add_path(NIL_PTR); + *file = 0; + } + break; +#ifdef HAVE_SYMLINK + case S_IFLNK: + { + int i; + + header.dbuf.typeflag = '2'; + verb_print("read symlink", file); + i = readlink(file, + header.dbuf.linkname, + sizeof(header.dbuf.linkname) - 1); + if (i < 0) { + string_print(NIL_PTR, + "Cannot read symbolic link %s: %s\n", + file, strerror(errno)); + return; + } + header.dbuf.linkname[i] = 0; + string_print(header.member.m_checksum, "%I ", checksum()); + mwrite(tar_fd, (char *) &header, sizeof(header)); + break; + } +#endif +#ifdef HAVE_FIFO + case S_IFPIPE: + header.dbuf.typeflag = '6'; + verb_print("read fifo", file); + string_print(header.member.m_checksum, "%I ", checksum()); + mwrite(tar_fd, (char *) &header, sizeof(header)); + break; +#endif + case S_IFBLK: + header.dbuf.typeflag = '4'; + if (verbose_flag) { + char sizebuf[TSIZLEN + 1]; + + strncpy(sizebuf, header.dbuf.size, (size_t) TSIZLEN); + sizebuf[TSIZLEN] = 0; + string_print(NIL_PTR, + "read block device %s major %s minor %s\n", + file, header.dbuf.devmajor, header.dbuf.devminor, sizebuf); + } + string_print(header.member.m_checksum, "%I ", checksum()); + mwrite(tar_fd, (char *) &header, sizeof(header)); + break; + case S_IFCHR: + header.dbuf.typeflag = '3'; + if (verbose_flag) string_print(NIL_PTR, + "read character device %s major %s minor %s\n", + file, header.dbuf.devmajor, header.dbuf.devminor); + string_print(header.member.m_checksum, "%I ", checksum()); + mwrite(tar_fd, (char *) &header, sizeof(header)); + break; + default: + is_deleted(&st); + string_print(NIL_PTR, "Tar: %s unknown file type. Not added.\n", file); + *file = 0; + } + } + + flush(); + add_close(fd); +} + +void verb_print(s1, s2) +char *s1, *s2; +{ + if (verbose_flag) string_print(NIL_PTR, "%s: %s\n", s1, s2); +} + +void add_close(fd) +int fd; +{ + if (fd != 0) close(fd); +} + +/* + * open file 'file' to be added to archive, return file descriptor +*/ +int add_open(file, st) +char *file; +struct stat *st; +{ + int fd; + if (((st->st_mode & S_IFMT) != S_IFREG) && + ((st->st_mode & S_IFMT) != S_IFDIR)) + return 0; + fd = open(file, O_RDONLY); + if (fd == -1) + fprintf(stderr, "open failed: %s\n", strerror(errno)); + return fd; +} + +void make_header(file, st) +char *file; +register struct stat *st; +{ + register char *ptr = header.member.m_name; + struct passwd *pwd; + struct group *grp; + + clear_header(); + + while (*ptr++ = *file++); + + if ((st->st_mode & S_IFMT) == S_IFDIR) { /* fixed test -Dal */ + *(ptr - 1) = '/'; + } + string_print(header.member.m_mode, "%I ", st->st_mode & 07777); + string_print(header.member.m_uid, "%I ", st->st_uid); + string_print(header.member.m_gid, "%I ", st->st_gid); + if ((st->st_mode & S_IFMT) == S_IFREG) + string_print(header.member.m_size, "%L ", st->st_size); + else + strncpy(header.dbuf.size, "0", (size_t) TSIZLEN); + string_print(header.member.m_time, "%L ", st->st_mtime); + strncpy(header.dbuf.magic, TMAGIC, (size_t) TMAGLEN); + header.dbuf.version[0] = 0; + header.dbuf.version[1] = 0; + pwd = getpwuid(st->st_uid); + strncpy(header.dbuf.uname, + (pwd != NULL ? pwd->pw_name : "nobody"), TUNMLEN); + grp = getgrgid(st->st_gid); + strncpy(header.dbuf.gname, + (grp != NULL ? grp->gr_name : "nobody"), TGNMLEN); + if (st->st_mode & (S_IFBLK | S_IFCHR)) { + string_print(header.dbuf.devmajor, "%I ", (st->st_rdev >> 8)); + string_print(header.dbuf.devminor, "%I ", (st->st_rdev & 0xFF)); + } + header.dbuf.prefix[0] = 0; +} + +void is_added(st, file) +struct stat *st; +char *file; +{ + struct link *new; + char *name; + + if ((*file == 0) || (st->st_nlink == 1)) return; + name = path_name(file); + new = (struct link *) malloc(sizeof(struct link) + strlen(name)); + if (new == NULL) { + print("Out of memory\n"); + return; + } + new->next = link_top; + new->dev = st->st_dev; + new->ino = st->st_ino; + new->nlink = st->st_nlink - 1; + strcpy(new->name, name); + link_top = new; +} + +void is_deleted(st) +struct stat *st; +{ + struct link *old; + + if ((old = link_top) != NULL) { + link_top = old->next; + free(old); + } +} + +char *is_linked(st) +struct stat *st; +{ + struct link *cur = link_top; + struct link **pre = &link_top; + static char name[NAMSIZ]; + + while (cur != NULL) + if ((cur->dev != st->st_dev) || (cur->ino != st->st_ino)) { + pre = &cur->next; + cur = cur->next; + } else { + if (--cur->nlink == 0) { + *pre = cur->next; + strncpy(name, cur->name, NAMSIZ); + return name; + } + return cur->name; + } + return NULL; +} + +void clear_header() +{ + register char *ptr = header.hdr_block; + + while (ptr < &header.hdr_block[TBLOCK_SIZE]) *ptr++ = '\0'; +} + +void adjust_boundary() +{ + clear_header(); + mwrite(tar_fd, (char *) &header, sizeof(header)); +#ifndef POSIX_COMP + while (total_blocks++ < BLOCK_BOUNDARY) + mwrite(tar_fd, (char *) &header, sizeof(header)); +#else + mwrite(tar_fd, (char *) &header, sizeof(header)); +#endif + (void) close(tar_fd); +} + +void mread(fd, address, bytes) +int fd, bytes; +char *address; +{ + if (bread(fd, address, bytes) != bytes) error("Tar: read error.", NIL_PTR); +} + +void mwrite(fd, address, bytes) +int fd, bytes; +char *address; +{ + if (bwrite(fd, address, bytes) != bytes) error("Tar: write error.", NIL_PTR); + + total_blocks++; +} + +int bread(fd, address, bytes) +int fd, bytes; +char *address; +{ + int n = 0, r; + + while (n < bytes) { + if ((r = read(fd, address + n, bytes - n)) <= 0) { + if (r < 0) return r; + break; + } + n += r; + } + return n; +} + +int bwrite(fd, address, bytes) +int fd, bytes; +char *address; +{ + int n = 0, r; + + while (n < bytes) { + if ((r = write(fd, address + n, bytes - n)) <= 0) { + if (r < 0) return r; + break; + } + n += r; + } + return n; +} + +char output[TBLOCK_SIZE]; +void print(str) /* changed to use stderr rather than stdout + * -Dal */ +register char *str; +{ + static int indx = 0; + + if (str == NIL_PTR) { + write(2, output, indx); + indx = 0; + return; + } + while (*str) { + output[indx++] = *str++; + if (indx == TBLOCK_SIZE) { + write(2, output, TBLOCK_SIZE); + indx = 0; + } + } +} + +char *num_out(number) +register long number; +{ + static char num_buf[12]; + register int i; + + for (i = 11; i--;) { + num_buf[i] = (number & 07) + '0'; + number >>= 3; + } + + return num_buf; +} + +/*VARARGS2*/ +#if __STDC__ +void string_print(char *buffer, char *fmt,...) +#else +void string_print(buffer, fmt) +char *buffer; +char *fmt; +#endif +{ + va_list args; + register char *buf_ptr; + char *scan_ptr; + char buf[STRING_SIZE]; + BOOL pr_fl, i; + + if (pr_fl = (buffer == NIL_PTR)) buffer = buf; + + va_start(args, fmt); + buf_ptr = buffer; + while (*fmt) { + if (*fmt == '%') { + fmt++; + switch (*fmt++) { + case 's': + scan_ptr = (char *) (va_arg(args, char *)); + break; + case 'I': + scan_ptr = num_out((long) (va_arg(args, int))); + for (i = 0; i < 5; i++) scan_ptr++; + break; + case 'L': + scan_ptr = num_out((long) va_arg(args, long)); + break; + case 'd': + scan_ptr = num_out((long) va_arg(args, int)); + while (*scan_ptr == '0') scan_ptr++; + scan_ptr--; + break; + default: scan_ptr = ""; + } + while (*buf_ptr++ = *scan_ptr++); + buf_ptr--; + } else + *buf_ptr++ = *fmt++; + } + *buf_ptr = '\0'; + + if (pr_fl) print(buffer); + va_end(args); +} diff --git a/src/simple/tee.c b/src/simple/tee.c new file mode 100755 index 00000000..cb9e5f22 --- /dev/null +++ b/src/simple/tee.c @@ -0,0 +1,32 @@ +/* tee.c + */ +#include +#include +#include +#include +#include + +int main(argc, argv) + int argc; + char **argv; +{ + int fd, bytes = 0; + unsigned char buf[BUFSIZ]; + + if (argc != 2) { + write(STDERR_FILENO, "usage: tee filename\n", 20); + return 0; + } + if ((fd = creat(argv[1], 0666)) <= 0) { + write(STDERR_FILENO, "tee: can't create file\n", 23); + return 1; /* missing file */ + } + while ((bytes = read(STDIN_FILENO, buf, sizeof(buf))) > 0) { + if (write(fd, buf, bytes) != bytes || + write(STDOUT_FILENO, buf, bytes) != bytes) + return 2; /* write error - no space */ + } + close(fd); + return 0; +} + diff --git a/src/simple/ter.c b/src/simple/ter.c new file mode 100755 index 00000000..3712eb47 --- /dev/null +++ b/src/simple/ter.c @@ -0,0 +1,178 @@ +/* ter.c for uzi180 by Nick */ + +#include +#include +#include +#include + +/* ------------------------------------------------------------------------- */ +/* definitions */ + +#define BUFFER 0x80 + +/* ------------------------------------------------------------------------- */ +/* prototypes */ + +void process_esc(char *buf, int *count); +void exit_error(char *mess1, char *mess2); +void exit_restore(void); +void entry_setup(void); +int main(int argc, char **argv); + +/* ------------------------------------------------------------------------- */ +/* global variables */ + +int fd_in, fd_out, fd_ter; +int raw_in, raw_ter; + +/* ------------------------------------------------------------------------- */ + +void exit_error(char *mess1, char *mess2) + { + exit_restore(); + write(fileno(stderr), mess1, strlen(mess1)); + perror(mess2); + exit(1); + } + +void exit_restore(void) + { + struct sgttyb state; + + if (fd_in >= 0 && isatty(fd_in)) + { + gtty(fd_in, &state); + state.sg_flags = raw_in; + stty(fd_in, &state); + } + + if (fd_ter >= 0 && isatty(fd_ter)) + { + gtty(fd_ter, &state); + state.sg_flags = raw_ter; + stty(fd_ter, &state); + close(fd_ter); + } + } + +void entry_setup(void) + { + struct sgttyb state; + + fd_in = fileno(stdin); + fd_out = fileno(stdout); + + if (isatty(fd_in)) + { + gtty(fd_in, &state); + raw_in = state.sg_flags; + state.sg_flags = RAW | UNBUFF; + stty(fd_in, &state); + } + + if (isatty(fd_ter)) + { + gtty(fd_ter, &state); + raw_ter = state.sg_flags; + state.sg_flags = RAW | UNBUFF; + stty(fd_ter, &state); + } + } + +void process_esc(char *buf, int *count) + { + switch (buf[0]) + { + case 'x': + case 'X': + exit_restore(); + printf("\nter: exiting\n"); + exit(0); + + case 0x1b: + return; /* with count = 1, so as to write it */ + + default: + *count = 0; + return; + } + } + +int main(int argc, char **argv) + { + int escflag, count; + char buf[BUFFER]; + + if (argc < 2) + { + printf("usage: ter devicename\n"); + exit(1); + } + + fd_in = -1; + fd_out = -1; + + fd_ter = open(argv[1], O_RDWR); + if (fd_ter < 0) + { + exit_error("ter: can't open ", argv[1]); + } + + printf("ter: ready\n"); + fflush(stdout); + + entry_setup(); + + escflag = 0; + while (1) + { + count = read(fd_ter, buf, BUFFER); + if (count < 0) + { + exit_error("ter: can't read ", argv[1]); + } + + if (count) + { + if (write(fd_out, buf, count) != count) + { + exit_error("ter: can't write ", "stdout"); + } + } + + count = read(fd_in, buf, 1); + if (count < 0) + { + exit_error("ter: can't read ", "stdin"); + } + + if (count) + { + if (escflag) + { + escflag = 0; + process_esc(buf, &count); + } + else if (buf[0] == 0x1b) + { + escflag = 1; + count = 0; + } + } + + if (count) + { +#if 0 + printf("[%x]", buf[0]); + fflush(stdout); +#endif + if (write(fd_ter, buf, count) != count) + { + exit_error("ter: can't write ", argv[1]); + } + } + } + } + +/* ------------------------------------------------------------------------- */ + diff --git a/src/simple/termcap.c b/src/simple/termcap.c new file mode 100755 index 00000000..111439a7 --- /dev/null +++ b/src/simple/termcap.c @@ -0,0 +1,167 @@ +/* termcap - print termcap settings Author: Terrence Holm */ + +#include +#include +#include + +#define TC_BUFFER 1024 /* Size of termcap(3) buffer */ + +/****************************************************************/ +/* */ +/* termcap [ type ] */ +/* */ +/* Prints out all of the termcap capabilities as described */ +/* in termcap(4). If "type" is not supplied then $TERM is */ +/* used. */ +/* */ +/****************************************************************/ + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void Print, (char *comment, char *name)); +_PROTOTYPE(void Error, (char *message, char *arg)); + +int main(argc, argv) +int argc; +char *argv[]; + + { + char *term; + char buffer[ TC_BUFFER ]; + + + /* Check for an argument */ + + if ( argc > 2 ) + Error( "usage: %s [type]\n", argv[0] ); + + if ( argc == 2 ) + term = argv[1]; + else + term = getenv( "TERM" ); + + if ( term == NULL ) + Error( "termcap: TERM is not defined\n", "" ); + + + /* Read in the termcap entry */ + + if ( tgetent( buffer, term ) != 1 ) + Error( "termcap: No termcap entry for %s\n", term ); + + + /* Print out the entry's contents */ + + printf( "TERM = %s\n\n", term ); + + if ( tgetflag( "am" ) == 1 ) + printf( "End of line wraps to next line (am)\n" ); + + if ( tgetflag( "bs" ) == 1 ) + printf( "Ctrl/H performs a backspace (bs)\n" ); + + printf( "Number of columns (co) = %d\n", tgetnum( "co" ) ); + printf( "Number of lines (li) = %d\n", tgetnum( "li" ) ); + + Print( "Clear to end of line", "ce" ); + Print( "Clear to end of screen", "cd" ); + Print( "Clear the whole screen", "cl" ); + + Print( "Start \"stand out\" mode", "so" ); + Print( "End \"stand out\" mode", "se" ); + Print( "Start underscore mode", "us" ); + Print( "End underscore mode", "ue" ); + Print( "Start blinking mode", "mb" ); + Print( "Start bold mode", "md" ); + Print( "Start reverse mode", "mr" ); + Print( "Return to normal mode", "me" ); + + Print( "Scroll backwards", "sr" ); + Print( "Cursor motion", "cm" ); + + Print( "Up one line", "up" ); + Print( "Down one line", "do" ); + Print( "Left one space", "le" ); + Print( "Right one space", "nd" ); + Print( "Move to top left corner", "ho" ); + + Print( "Generated by \"UP\"", "ku" ); + Print( "Generated by \"DOWN\"", "kd" ); + Print( "Generated by \"LEFT\"", "kl" ); + Print( "Generated by \"RIGHT\"", "kr" ); + Print( "Generated by \"HOME\"", "kh" ); + Print( "Generated by \"END\"", "k0" ); + Print( "Generated by \"PGUP\"", "k1" ); + Print( "Generated by \"PGDN\"", "k2" ); + Print( "Generated by numeric \"+\"", "k3" ); + Print( "Generated by numeric \"-\"", "k4" ); + Print( "Generated by numeric \"5\"", "k5" ); + + return( 0 ); + } + + + + + + +/****************************************************************/ +/* */ +/* Print( comment, name ) */ +/* */ +/* If a termcap entry exists for "name", then */ +/* print out "comment" and the entry. Control */ +/* characters are printed as ^x. */ +/* */ +/****************************************************************/ + + +void Print( comment, name ) + char *comment; + char *name; + + { + char entry[ 50 ]; + char *p = entry; + + if ( tgetstr( name, &p ) == NULL ) + return; + + printf( "%-32s (%s) = ", comment, name ); + + for ( p = entry; *p != '\0'; ++p ) + if ( *p < ' ' ) + printf( "^%c", *p + '@' ); + else if ( *p == '\177' ) + printf( "^?" ); + else + putchar( *p ); + + putchar( '\n' ); + } + + + + + + +/****************************************************************/ +/* */ +/* Error( message, arg ) */ +/* */ +/* Printf the "message" and abort. */ +/* */ +/****************************************************************/ + + +void Error( message, arg ) + char *message; + char *arg; + + { + fprintf( stderr, message, arg ); + exit( 1 ); + } diff --git a/src/simple/test.c b/src/simple/test.c new file mode 100755 index 00000000..80944bfd --- /dev/null +++ b/src/simple/test.c @@ -0,0 +1,360 @@ +/* test - test conditions Author: Erik Baalbergen */ + +/* Test- version 7-like test(1). + * + * Grammar: expr ::= bexpr | bexpr "-o" expr ; + * bexpr ::= primary | primary "-a" bexpr ; + * primary ::= unary-operator operand + * | operand binary-operator operand + * | operand + * | "(" expr ")" + * | "!" expr + * ; + * unary-operator ::= "-r"|"-w"|"-f"|"-d"|"-s"|"-t"|"-z"|"-n"|"-x"; + * binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"; + * operand ::= + * + * Author: Erik Baalbergen erikb@cs.vu.nl + * + * History: Fix Bert Reuling #571 (03/09/89 FVK) bert@kyber.UUCP + * + * Add Jeroen van der Pluijm 09/25/89 jeroen@minixug.nluug.nl + * Enabled linking to /usr/bin/[ so you cn use structures + * like: + * if [ -f ./test.c ] + * and so on. Also added checking of argv[0] to see if it + * is '[' and the last argument if it is ']'. + * + * Mod Fred van Kempen 09/27/89 waltje@minixug.nluug.nl + * Adapted source to MINIX Style Sheet. + * + * Mod Bruce Evans 09/27/89 evans@ditsyda.oz.au + * Allow whitespace in numbers. + * Deleted bloat from single use of stdio (fprintf). + * + * Mod Paul Wood 10/10/91 paul@max.uk.mugnet.org + * Added support for -x option. + * + * Add Kees J. Bot 02/19/92 kjb@cs.vu.nl + * Binary operator 'f1 -newer f2'. + */ + +#include +#include +#include +#include +#include +#include + +#define EOI 0 +#define FILRD 1 +#define FILWR 2 +#define FILND 3 +#define FILID 4 +#define FILGZ 5 +#define FILTT 6 +#define STZER 7 +#define STNZE 8 +#define STEQL 9 +#define STNEQ 10 +#define INTEQ 11 +#define INTNE 12 +#define INTGE 13 +#define INTGT 14 +#define INTLE 15 +#define INTLT 16 +#define UNEGN 17 +#define BAND 18 +#define BOR 19 +#define LPAREN 20 +#define RPAREN 21 +#define OPERAND 22 +#define FILXQ 23 +#define FILNW 24 + +#define UNOP 1 +#define BINOP 2 +#define BUNOP 3 +#define BBINOP 4 +#define PAREN 5 + +struct op { + char *op_text; + short op_num, op_type; +} ops[] = { + + { + "-r", FILRD, UNOP + }, + { + "-w", FILWR, UNOP + }, + { + "-f", FILND, UNOP + }, + { + "-d", FILID, UNOP + }, + { + "-s", FILGZ, UNOP + }, + { + "-t", FILTT, UNOP + }, + { + "-z", STZER, UNOP + }, + { + "-n", STNZE, UNOP + }, + { + "=", STEQL, BINOP + }, + { + "!=", STNEQ, BINOP + }, + { + "-eq", INTEQ, BINOP + }, + { + "-ne", INTNE, BINOP + }, + { + "-ge", INTGE, BINOP + }, + { + "-gt", INTGT, BINOP + }, + { + "-le", INTLE, BINOP + }, + { + "-lt", INTLT, BINOP + }, + { + "!", UNEGN, BUNOP + }, + { + "-a", BAND, BBINOP + }, + { + "-o", BOR, BBINOP + }, + { + "(", LPAREN, PAREN + }, + { + ")", RPAREN, PAREN + }, + { + "-x", FILXQ, UNOP + }, + { + "-newer", FILNW, BINOP + }, + { + 0, 0, 0 + } +}; + + +char **ip; +char *prog; +struct op *ip_op; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void syntax, (void)); +_PROTOTYPE(long num, (char *s)); +_PROTOTYPE(int filstat, (char *nm, int mode)); +_PROTOTYPE(int newer, (char *fil1, char *fil2)); +_PROTOTYPE(int lex, (char *s)); +_PROTOTYPE(int primary, (int n)); +_PROTOTYPE(int bexpr, (int n)); +_PROTOTYPE(int expr, (int n)); + +void syntax() +{ + write(2, prog, strlen(prog)); + write(2, ": syntax error\n", 15); + exit(1); +} + + +long num(s) +register char *s; +{ + long l = 0; + long sign = 1; + + while (*s == ' ' || *s == '\t') ++s; + if (*s == '\0') syntax(); + if (*s == '-') { + sign = -1; + s++; + } + while (*s >= '0' && *s <= '9') l = l * 10 + *s++ - '0'; + while (*s == ' ' || *s == '\t') ++s; + if (*s != '\0') syntax(); + return(sign * l); +} + + +int filstat(nm, mode) +char *nm; +int mode; +{ + struct stat s; + + switch (mode) { + case FILRD: + return(access(nm, 4) == 0); + case FILWR: + return(access(nm, 2) == 0); + case FILND: + return(stat(nm, &s) == 0 && ((s.st_mode & S_IFMT) != S_IFDIR)); + case FILID: + return(stat(nm, &s) == 0 && ((s.st_mode & S_IFMT) == S_IFDIR)); + case FILGZ: +#if 0 + return(stat(nm, &s) == 0 && (s.st_size.o_blkno || s.st_size.o_offset)); +#else + return(stat(nm, &s) == 0 && (s.st_size > 0L)); +#endif + case FILTT: + return(isatty((int) num(nm))); + case FILXQ: + return(access(nm, 1) == 0); + } + return(0); +} + + +int newer(fil1, fil2) +char *fil1, *fil2; +/* True iff fil1 is not older (!) then fil2. */ +{ + struct stat s1, s2; + + if (stat(fil1, &s1) != 0) return 0; + if (stat(fil2, &s2) != 0) return 1; + return (difftime(&s1.st_mtime, &s2.st_mtime) >= 0); +} + + +int lex(s) +register char *s; +{ + register struct op *op = ops; + + if (s == 0) return EOI; + while (op->op_text) { + if (strcmp(s, op->op_text) == 0) { + ip_op = op; + return(op->op_num); + } + op++; + } + ip_op = (struct op *) 0; + return(OPERAND); +} + + +int primary(n) +int n; +{ + register char *opnd1, *opnd2; + int res; + + if (n == EOI) syntax(); + if (n == UNEGN) return (!expr(lex(*++ip))); + if (n == LPAREN) { + res = expr(lex(*++ip)); + if (lex(*++ip) != RPAREN) syntax(); + return(res); + } + if (n == OPERAND) { + opnd1 = *ip; + (void) lex(*++ip); + if (ip_op && ip_op->op_type == BINOP) { + struct op *op = ip_op; + + if ((opnd2 = *++ip) == (char *) 0) syntax(); + + switch (op->op_num) { + case STEQL: + return(strcmp(opnd1, opnd2) == 0); + case STNEQ: + return(strcmp(opnd1, opnd2) != 0); + case INTEQ: + return(num(opnd1) == num(opnd2)); + case INTNE: + return(num(opnd1) != num(opnd2)); + case INTGE: + return(num(opnd1) >= num(opnd2)); + case INTGT: + return(num(opnd1) > num(opnd2)); + case INTLE: + return(num(opnd1) <= num(opnd2)); + case INTLT: + return(num(opnd1) < num(opnd2)); + case FILNW: + return(newer(opnd1, opnd2)); + } + } + ip--; + return(strlen(opnd1) > 0); + } + + /* Unary expression */ + if (ip_op->op_type != UNOP || *++ip == 0) syntax(); + if (n == STZER) return (strlen(*ip) == 0); + if (n == STNZE) return (strlen(*ip) != 0); + return(filstat(*ip, n)); +} + + +int bexpr(n) +int n; +{ + int res; + + if (n == EOI) syntax(); + res = primary(n); + if (lex(*++ip) == BAND) return(bexpr(lex(*++ip)) && res); + ip--; + return(res); +} + + +int expr(n) +int n; +{ + int res; + + if (n == EOI) syntax(); + res = bexpr(n); + if (lex(*++ip) == BOR) return(expr(lex(*++ip)) || res); + ip--; + return(res); +} + + +int main(argc, argv) +int argc; +char **argv; +{ + if (argv[0][0] == '[' && argv[argc - 1][0] != ']') { + write(2, "test: ] missing\n", 16); + exit(1); + } + if (argv[0][0] == '[') argc--; + + if (argc == 1) exit(1); + prog = argv[0]; + ip = &argv[1]; + return(!expr(lex(*ip))); +} diff --git a/src/simple/tget.c b/src/simple/tget.c new file mode 100755 index 00000000..49ed9123 --- /dev/null +++ b/src/simple/tget.c @@ -0,0 +1,111 @@ +/* tget 1.0 - get termcap values Author: Kees J. Bot + * 6 Mar 1994 + */ +#define nil 0 +#include +#include +#include +#include + +#if 1 +int fputchar(int c) /* Nick, for tputs(), please see include/termcap.h */ +{ + putchar(c); + return 0; /* Nick, for tputs(), please see include/termcap.h */ +} +#else +void fputchar(int c) +{ + putchar(c); +} +#endif + +void usage(void) +{ + fprintf(stderr, +"usage: tget [-flag id] [-num id] [-str id] [-goto col line] [[-echo] string]\n" + ); + exit(-1); +} + +void main(int argc, char **argv) +{ + char termbuf[1024]; + char string[256], *pstr; + char *term; + int i; + int excode= 0; + + if (argc == 1) { + usage(); + exit(-1); + } + + if ((term= getenv("TERM")) == nil) { + fprintf(stderr, "tget: $TERM is not set\n"); + exit(-1); + } + + if (tgetent(termbuf, term) != 1) { + fprintf(stderr, "tget: no termcap entry for '%s'\n", term); + exit(-1); + } + + for (i= 1; i < argc; i++) { + char *option= argv[i]; + char *id; + + if (option[0] != '-') { + fputs(option, stdout); + continue; + } + + if (++i == argc) usage(); + id= argv[i]; + + if (strcmp(option, "-flag") == 0) { + excode= tgetflag(id) ? 0 : 1; + } else + if (strcmp(option, "-num") == 0) { + int num; + + if ((num= tgetnum(id)) == -1) { + excode= 1; + } else { + excode= 0; + printf("%d", num); + } + } else + if (strcmp(option, "-str") == 0) { + char *str; + + if ((str= tgetstr(id, (pstr= string, &pstr))) == nil) { + excode= 1; + } else { + excode= 0; + tputs(str, 0, fputchar); + } + } else + if (strcmp(option, "-goto") == 0) { + char *cm; + int col, line; + + col= atoi(id); + if (++i == argc) usage(); + line= atoi(argv[i]); + + if ((cm= tgetstr("cm", (pstr= string, &pstr))) == nil) { + excode= 1; + } else { + excode= 0; + tputs(tgoto(cm, col, line), 0, fputchar); + } + } else + if (strcmp(option, "-echo") == 0) { + fputs(id, stdout); + } else { + usage(); + } + } + exit(excode); +} diff --git a/src/simple/time.c b/src/simple/time.c new file mode 100755 index 00000000..ecc14364 --- /dev/null +++ b/src/simple/time.c @@ -0,0 +1,185 @@ +/* time - time a command Authors: Andy Tanenbaum & Michiel Huisjes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +#if defined(MSX_UZIX_TARGET) || defined (PC_UZIX_TARGET) +#define diffticks(x, y) x.t_time+x.t_date*CLOCKS_PER_SEC*60- \ + y.t_time+y.t_date*CLOCKS_PER_SEC*60 +#else +#define diffticks(x, y) x-y +#endif + +#ifndef std_err +#define std_err(x) write(STDOUT_FILENO, x, strlen(x)) +#endif + +char **args; +char *name; + +int digit_seen; +#if 1 /* Nick */ +char buf[] = "12:34:56.78"; +#else +char a[] = "12:34:56.78"; +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void print_time, (clock_t t)); +_PROTOTYPE(void twin, (int n, char *p)); +_PROTOTYPE(void execute, (void)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + + struct tms pre_buf, post_buf; + int status, pid; + time_t start_time, end_time; + + if (argc <= 1) { + std_err("usage: time program [program args]\n"); + exit(0); + } + + args = &argv[1]; + name = argv[1]; + + /* Get real time at start of run. */ + time(&start_time); + + /* Fork off child. */ + if ((pid = fork()) < 0) { + std_err("Cannot fork\n"); + exit(1); + } + if (pid == 0) execute(); + + /* Parent is the time program. Disable interrupts and wait. */ + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + + do { + times(&pre_buf); + } while (wait(&status) != pid); + time(&end_time); + + if ((status & 0x00ff) != 0) std_err("Command terminated abnormally.\n"); + times(&post_buf); + + /* Print results. -DNEW_TIME_FORMAT enables time on one line to 0.01 sec. */ +#ifndef NEW_TIME_FORMAT + std_err("real "); + print_time((clock_t) difftime(&end_time, &start_time) * CLOCKS_PER_SEC); + std_err("\nuser "); + print_time(diffticks(post_buf.tms_cutime, pre_buf.tms_cutime)); + std_err("\nsys "); + print_time(diffticks(post_buf.tms_cstime, pre_buf.tms_cstime)); + std_err("\n"); +#else + print_time((clock_t) difftime(&end_time, &start_time) * CLOCKS_PER_SEC); + std_err(" real"); + print_time(diffticks(post_buf.tms_cutime, pre_buf.tms_cutime)); + std_err(" user"); + print_time(diffticks(post_buf.tms_cstime, pre_buf.tms_cstime)); + std_err(" sys\n"); +#endif + return((status & 0x00ff) ? -1 : (status >> 8)); +} + +void print_time(t) +register clock_t t; +{ +/* Print the time 't' in hours: minutes: seconds. 't' is in ticks. */ + + int hours, minutes, seconds, hundredths, i; + + digit_seen = 0; +#if 1 /* Nick */ + for (i = 0; i < 8; i++) + buf[i] = ' '; +#else + for (i = 0; i < 8; i++) a[i] = ' '; +#endif + hours = (int) (t / ((clock_t) 3600 * CLOCKS_PER_SEC)); + t -= (clock_t) hours * 3600 * CLOCKS_PER_SEC; + minutes = (int) (t / ((clock_t) 60 * CLOCKS_PER_SEC)); + t -= (clock_t) minutes * 60 * CLOCKS_PER_SEC; + seconds = (int) (t / CLOCKS_PER_SEC); + t -= (clock_t) seconds * CLOCKS_PER_SEC; + hundredths = (int) (t * 100 / CLOCKS_PER_SEC); + + if (hours) { +#if 1 /* Nick */ + twin(hours, &buf[0]); + buf[2] = ':'; +#else + twin(hours, &a[0]); + a[2] = ':'; +#endif + } + if (minutes || digit_seen) { +#if 1 /* Nick */ + twin(minutes, &buf[3]); + buf[5] = ':'; +#else + twin(minutes, &a[3]); + a[5] = ':'; +#endif + } + if (seconds || digit_seen) +#if 1 /* Nick */ + twin(seconds, &buf[6]); +#else + twin(seconds, &a[6]); +#endif + else +#if 1 /* Nick */ + buf[7] = '0'; +#else + a[7] = '0'; +#endif +#if 1 /* Nick */ + buf[9] = hundredths / 10 + '0'; + buf[10] = hundredths % 10 + '0'; + std_err(buf); +#else + a[9] = hundredths / 10 + '0'; + a[10] = hundredths % 10 + '0'; + std_err(a); +#endif +} + +void twin(n, p) +int n; +char *p; +{ + char c1, c2; + c1 = (n / 10) + '0'; + c2 = (n % 10) + '0'; + if (digit_seen == 0 && c1 == '0') c1 = ' '; + *p++ = c1; + *p++ = c2; + if (n > 0) digit_seen = 1; +} + +void execute() +{ + execvp(name, args); + std_err("Cannot execute "); + std_err(name); + std_err("\n"); + exit(-1); +} diff --git a/src/simple/top.c b/src/simple/top.c new file mode 100755 index 00000000..6549004c --- /dev/null +++ b/src/simple/top.c @@ -0,0 +1,434 @@ +/* top.c vr. 1.1 + * descripton: show processes status interactively + * author: Adriano Cunha + * heavily based on UZIX ps.c + * license: GNU Public License version 2 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* Nick */ +#include /* Nick */ + +#define MAXDISP 18 /* maximum number of processes displayed */ + +int nprocs = 0, nrun = 0, nslep = 0, nzomb = 0, nstop = 0; +int noprocstat = 0, nomemstat = 0, delay = 5, runonly = 0, securemode = 0; + +char *mapstat(pstate_t s) { + switch (s) { + case P_ZOMBIE: nzomb++; return "Zombie"; + case P_FORKING: return "Forking"; + case P_RUNNING: nrun++; return "Running"; + case P_READY: return "Ready"; + case P_SLEEP: nslep++; return "Sleep"; + case P_PAUSE: return "Pause"; + case P_WAIT: nstop++; return "Waitfor"; + } + return "Undef"; +} + +void cls() { + putchar('\014'); +} + +void home() { + putchar('\013'); +} + +void clreol() { + printf("%78s\r"," "); +} + +void setcursor() { + home(); + putchar('\n'); + if (!noprocstat) putchar('\n'); + if (!nomemstat) putchar('\n'); +} + +int input(int deflt) { + char buf[10]; + + fflush(stdout); + fflush(stdin); + scanf("%s", buf); + if (*buf=='\0') return deflt; + return atoi(buf); +} + +/* UZIX t_time is not just counting seconds... + * so, dirty conversion routines are here: + */ + +unsigned long ticks2seconds(time_t *t) { + return (t->t_time/CLOCKS_PER_SEC)+(t->t_date*60); +} + +time_t seconds2uzixtime(unsigned long t) { + int y=0,m=0,d=0,h=0,mm=0; + unsigned long t1=t; + time_t tt; + + if (t1>=31536000) { + y=t1/31536000L; + t1=t1-(y*31536000L); + y=y-10; + } + if (t1>=2592000) { + m=t1/2592000L; + t1=t1-(m*2592000L); + m++; + } + if (t1>=86400) { + d=t1/86400; + t1=t1-d*86400; + d++; + } + if (t1>=3600) { + h=t1/3600; + t1=t1-h*3600; + } + if (t1>=60) { + mm=t1/60; + t1=t1-mm*60; + } + tt.t_time=(((int)h << 8) << 3) | ((int)mm << 5) | ((int)t1 >> 1); + tt.t_date=(((int)y << 8) << 1) | ((int)m << 5) | d; + return tt; +} + +int main(argc, argv) + int argc; + char **argv; { + char *pp; + + argc--; + argv++; + while ((argc > 0) && (**argv == '-')) { + argc--; + pp = *argv++ ; + while (*++pp) switch (*pp) { + case 'd': + argc--; + pp = *argv++ ; + for (delay = 0; *pp >= '0' && *pp <= '9'; ++pp) { + delay *= 10; + delay += *pp - '0'; + } + if (*pp) { + printf("Bad delay value\n"); + return 1; + } + pp--; /* *p=0, exit while/switch loop */ + break; + case 'q': + delay = 0; + break; + case 's': + securemode = 1; + break; + case 'i': + runonly = 1; + break; + default: + printf("Unknown option\n"); + return 1; + } + } + if (argc != 0) { + printf("usage: top [-d delay][-q][-s][-i]\n"); + return 1; + } + return do_top(); +} + +void help() { + char c; + + cls(); + printf("available interactive commands:\n\n"); + printf("space - Update display\n"); + printf("^L - Clear screen\n"); + printf("i - Toggle idle processes mode\n"); + printf("m - Toggle memory usage mode\n"); + printf("t - Toggle processes summary mode\n"); + if (!securemode) printf("k - Kill a process\n"); + if (!securemode) printf("r - Renice a task\n"); + if (!securemode) printf("u - Show only processes of a specific user\n"); + if (!securemode) printf("s - Change delay between snapshots\n"); + printf("h,? - Show this help\n"); + printf("q - Quit program\n"); + printf("n,# - Change maximum number of processes shown\n\n"); + printf("Press RETURN to go back..."); + fflush(stdout); + fflush(stdin); + c=getchar(); +} + +void killp() { + signal_t psignal; + int kpid; + + if (securemode) return; + printf("PID of process to kill: "); + kpid=input(0); + if (kpid < 1) return; + setcursor(); + clreol(); + printf("Signal to send (15): "); + (signal_t)psignal=input(15); + if (psignal < 1 || psignal > NSIGS) psignal = SIGINT; + kill(kpid, psignal); +} + +void renice() { + int kpid; + char nicev; + + if (securemode) return; + printf("PID to renice: "); + kpid=input(0); + if (kpid < 1) return; + setcursor(); + clreol(); + printf("Renice PID %d to value (10): ", kpid); + nicev=(char)input(10); + setprio(kpid, nicev); +} + +int do_top() { + info_t info; + ptptr p; + int i, j, delay = 5, pnprocs = 0, securemode = 0; + int totalram, usedram, kram, maxdisp = MAXDISP, procsdisp = -1; + int runonly = 0; + int useronly = 0; + int kuid = -1; + uchar nicev; + unsigned long secs; + struct s_pdata pdata; + struct s_kdata kdata; + char *str, c; + char cputime[9]; + uchar pmem, pcpu; + char username[9], pssize[5]; + int useridknown = 0, userid; + struct passwd *pwd; + time_t temptime, now; + unsigned long ptimes, diff; + signal_t psignal; +#if 1 /* Nick */ + struct sgttyb state; + int raw; +#endif +#define psize 32 + +#if 1 /* Nick */ + if (isatty(fileno(stdin))) + { + gtty(fileno(stdin), &state); + raw = state.sg_flags; + } +#endif + + getfsys(GI_KDAT, &kdata); + totalram=kdata.k_tmem; + kram=kdata.k_kmem; + cputime[8]='\0'; + c='\0'; + for (;;) { +again: home(); + if (procsdisp != pnprocs) cls(); + pnprocs = procsdisp; + getfsys(GI_PTAB, &info); + time(&now); + str = ctime(&now); + printf("%s %s.%s (%s) - %s", kdata.k_name, kdata.k_version, + kdata.k_release, kdata.k_machine, str); + if (!noprocstat) + printf("%d processes: %d running, %d sleeping, %d zombie, %d stopped.\n", + nprocs, nrun, nslep, nzomb, nstop); + usedram = nprocs*32; + if (!nomemstat) + printf("Mem: %dk average, %dk used, %dk free, %dk kernel.\n", + totalram, usedram, totalram-usedram, kram); + clreol(); + if (c != '\0') { +#if 1 /* Nick */ + if (isatty(fileno(stdin))) + { + state.sg_flags = raw; + stty(fileno(stdin), &state); + } +#else + ioctl(fileno(stdin), TTY_COOKED); +#endif + if (c==' ') { + c='\0'; + continue; + } + if (c=='\014') { + cls(); + c='\0'; + goto again; + } + if (c=='q' || c=='Q') { + cls(); + return 0; + } + if (c=='t' || c=='T') { + noprocstat = 1 - noprocstat; + pnprocs = -1; /* redraw screen */ + c='\0'; + goto again; + } + if (c=='i' || c=='I') { + runonly = 1 - runonly; + pnprocs = -1; /* redraw screen */ + c='\0'; + goto again; + } + if (c=='m' || c=='M') { + nomemstat = 1 - nomemstat; + pnprocs = -1; /* redraw screen */ + c='\0'; + goto again; + } + if (c=='k' || c=='K') { + c='\0'; + killp(); + continue; + } + if (c=='r' || c=='R') { + c='\0'; + renice(); + continue; + } + if (c=='u' || c=='U') { + c='\0'; + if (securemode) continue; + printf("Which user (UID, -1 for all): "); + kuid = input(-1); + useronly = (kuid >= 0); + continue; + } + if (c=='s' || c=='S') { + c='\0'; + if (securemode) continue; + delay = -1; + while (delay < 0) { + setcursor(); + printf("New delay (in seconds): "); + delay=input(0); + } + goto again; + } + if (c=='n' || c=='N' || c=='#') { + c='\0'; + printf("Maximum display of processes: "); + maxdisp=input(MAXDISP); + if (maxdisp < 0) maxdisp=1; + if (maxdisp > MAXDISP) maxdisp=MAXDISP; + pnprocs=-1; + goto again; + } + if (c=='h' || c=='H' || c=='?') { + help(); + pnprocs = -1; + c='\0'; + goto again; + } + printf("Unknown command `%c' -- hit `h' for help.\a\n", c); + } else putchar('\n'); + printf("PID PPID PRIO NICE USER STAT\tSIZE \%%CPU \%%MEM TIME COMMAND\n"); + nprocs = 0; + nrun = 0; + nslep = 0; + nzomb = 0; + nstop = 0; + procsdisp = 0; + for (p = (ptptr)info.ptr, i = 0; i < info.size; ++i, ++p) { + if (p->p_status == 0) + continue; + nprocs++; + pdata.u_pid=p->p_pid; + if (runonly && p->p_status != P_RUNNING && + p->p_status != P_READY) continue; + if (useronly && p->p_uid != kuid) continue; + if (p->p_status != P_ZOMBIE) { + if (getfsys(GI_PDAT, &pdata) < 0) + continue; + psignal = pdata.u_cursig; + /* process CPU time */ + ptimes = ticks2seconds(&pdata.u_utime); + temptime = seconds2uzixtime(ptimes); + str = ctime(&temptime); + strncpy(cputime, &str[11],8); + /* %CPU */ + diff = difftime(&now, &pdata.u_time); + pcpu = (uchar)(((unsigned long)(ptimes*(unsigned long)100))/((unsigned long)diff)); + } else { + psignal = 0; + strcpy(cputime, "--:--:--"); + pcpu = 0; + strcpy(pdata.u_name, "?"); + } + if (procsdisp >= maxdisp) continue; + procsdisp++; + /* user id */ + if (!useridknown || (p->p_uid != userid)) { + if ((pwd = getpwuid(p->p_uid)) != NULL) + strcpy(username, pwd->pw_name); + else sprintf(username, "%-5d", p->p_uid); + userid = p->p_uid; + useridknown = 1; + } + /* you must calculate psize here */ + /* %MEM */ + pmem=(psize*100)/totalram; + /* convert pmem to a string terminated by k or M */ + j=psize; /* process size in kbytes */ + if (j<1000) { /* I know that 1Mb=1024kb, but who cares? */ + sprintf(pssize, "%3dk", j); + } else { + j = j / 1024; /* too dirty... do it better! */ + sprintf(pssize, "%3dM", j); + } + /* show info */ + printf("%-5d %-5d %-4d %-4d %-8s %s\t%-4s %3d%c %3d%c %s %s\n", + p->p_pid, p->p_pptr->p_pid, p->p_cprio, p->p_nice, + username, mapstat(p->p_status), pssize, pcpu, + '%', pmem, '%', cputime, pdata.u_name); + } + setcursor(); + c = '\0'; +#if 1 /* Nick */ + if (isatty(fileno(stdin))) + { + state.sg_flags &= ~CBREAK; + state.sg_flags |= RAW | UNBUFF; + stty(fileno(stdin), &state); + } +#else + ioctl(fileno(stdin), TTY_RAW_UNBUFF); +#endif + if (delay > 0) { + time(&temptime); + secs = convtime(&temptime); + while (convtime(&temptime) - secs < delay) { + time(&temptime); + if (read(fileno(stdin), &c, 1) != 0) break; + } + } + else read(fileno(stdin), &c, 1); + } +} + diff --git a/src/simple/touch.c b/src/simple/touch.c new file mode 100755 index 00000000..c7b9f82a --- /dev/null +++ b/src/simple/touch.c @@ -0,0 +1,158 @@ +/* touch.c + * descripton: change files creation/modification date + * author: Archi Schekochikhin + * Adriano Cunha + * license: GNU Public License version 2 + */ + +#ifdef VAX /* Nick */ +#include +#include +#include +#include +#define STDERR_FILENO 2 +#else +#include +#include /* for O_RDWR */ +#include +#include +#endif +#include +#include +#include + +void wr(char *s) { + write(STDERR_FILENO, s, strlen(s)); +} + +int getint(p, p1) + char *p; + char **p1; +{ + int v = 0; + for (v = 0; *p >= '0' && *p <= '9'; ++p) { + v *= 10; + v += *p - '0'; + } + *p1=p; + return v; +} + +#ifndef VAX /* Nick */ +int xconvtime(t1, t2, timet) + char *t1; + char *t2; + time_t *timet; +{ + int h,m,s,d,mm,y; + char *t, *dd, *e; + struct tm tt; + + t=t1; + dd=t2; + h=getint(t, &e); + if ((h<0) || (h>23) || (*e!=':')) return 0; + m=getint(t=++e, &e); + if ((m<0) || (m>59) || (*e!=':')) return 0; + s=getint(t=++e, &e); + if ((s<0) || (s>59) || (*e!=0)) return 0; + d=getint(dd, &e); + if ((d<1) || (d>31) || (*e!='/')) return 0; + mm=getint(dd=++e, &e); + if ((mm<1) || (mm>12) || (*e!='/')) return 0; + dd++; + y=getint(dd=++e, &e); + if (y<100) {if (y<80) y+=100;} else y-=1900; + if ((y<0) || (*e!=0)) return 0; + tt.tm_hour=h; + tt.tm_min=m; + tt.tm_sec=s; + tt.tm_year=y; + tt.tm_mon=mm-1; + tt.tm_mday=d; + *timet=mktime(&tt); + return 1; +} +#endif + +int main(argc, argv) + int argc; + char **argv; +{ + int i, fd, er = 0, ncreate = 0, modif = 0, mytime = 0, tmptim; + struct utimbuf utim; + struct stat statbuf; + char *p; + time_t now, mytimet; + + if (argc < 2) { +#ifdef VAX /* Nick */ + wr("usage: touch [-c] [-m] filename ...\n"); +#else + wr("usage: touch [-c] [-m] [-d time] filename ...\n"); +#endif + return 0; + } + argc--; + argv++; + while ((argc > 0) && (**argv == '-')) { + argc--; + p = *argv++ ; + while (*++p) switch (*p) { +#ifndef VAX /* Nick */ + case 'd': + if (!xconvtime(*argv, *(argv+1), &mytimet)) { + wr("Bad date/time format\n"); + return 0; + } + argc -= 2; + argv += 2; + mytime = 1; + break; +#endif + case 'c': + ncreate = 1; + break; + case 'm': + modif = 1; + break; + default: + wr("Unknown option(s) "); + wr(p); + wr(".\n"); + return 0; + } + } + for (i = 0; i < argc; i++) { + p = argv[i]; + if ((fd = open(p, O_RDWR)) < 0) { + if (errno == ENOENT) { + if (!ncreate) { + er = creat(p, 0666); + if (er != -1) er = close(er); + } + } + } else { + close(fd); + time(&now); + stat(p, &statbuf); + utim.actime = now; + utim.modtime = now; +#ifndef VAX /* Nick */ + if (mytime) { + utim.actime = mytimet; + utim.modtime = mytimet; + } +#endif + if (modif) utim.actime = statbuf.st_atime; + er = utime(p, &utim); + } + if (er != 0) { + wr("Can't touch file "); + wr(p); + wr(".\n"); + } + } + return er; +} + diff --git a/src/simple/tr.c b/src/simple/tr.c new file mode 100755 index 00000000..b2cafec0 --- /dev/null +++ b/src/simple/tr.c @@ -0,0 +1,376 @@ +/* + * t r . c 23.06.94 + * + * ணࠬ¬  ¯à¥®¡à §®¢ ­¨ï ᨬ¢®«®¢ + * + * TR ª®¯¨àã¥â áâ ­¤ àâ­ë© ¢¢®¤ ­  áâ ­¤ àâ­ë© ¢ë¢®¤ á § ¬¥é¥­¨¥¬ ¨«¨ + * ã­¨ç⮦¥­¨¥¬ ¢ë¡à ­­ëå ᨬ¢®«®¢. + * + * FROM ¨ TO - áâப¨ ᨬ¢®«®¢. ä䥪â TR § ¢¨á¨â ®â ¤«¨­ë ®¡¥¨å áâப. + * + * …᫨ FROM ¨ TO ®¤¨­ ª®¢®© ¤«¨­ë, ᨬ¢®«ë ¨§ TO § ¬¥é îâ ᨬ¢®«ë + * ¨§ FROM. ’ ª + * + * TR abcd wxyz +start -end + * + * ¨§¬¥­¨â ¢á¥ a ¢ w, b ¢ x, ¨ â.¤. TR €‡‹ˆ—€…’ ¡ãª¢ë ¯® ॣ¨áâà ¬. + * + * …᫨ TO - ¯ãáâ ï áâப , ¢á¥ ᨬ¢®«ë ¨§ FROM ã­¨ç⮦ îâáï. + * + * …᫨ TO ­¥ ¯ãáâ®, ­® ª®à®ç¥, 祬 FROM, ¢á¥ ᨬ¢®«ë ¨§ FROM, ­¥ + * ¨¬¥î騥 ¯ àë ¢ TO, ¡ã¤ãâ § ¬¥­¥­ë ­  ¯®á«¥¤­¨© ᨬ¢®« ¨§ TO, + * Ž «î¡ ï ¯®á«¥¤®¢ â¥«ì­®áâì â࠭᫨à㥬ëå â ª¨¬ ®¡à §®¬ ᨬ¢®«®¢ + * ãᥪ ¥âáï ¤® ®¤­®£® १ã«ìâ¨àãî饣® ᨬ¢®« . ’ ª: + * + * TR abcde12345 ABCDE- + * + * ¨§¬¥­¨â "aAbB1234cCdD5678eEfF" ­  "AABB-CCDD-678EEfF". + * + * …᫨ ᨬ¢®« ¢áâà¥ç ¥âáï ¢ FROM ¡®«¥¥ ®¤­®£® à § , ¨á¯®«ì§ã¥âáï + * á ¬®¥ «¥¢®¥ ¯®ï¢«¥­¨¥. ’ ª, ¤«ï ¨§¬¥­¥­¨ï ¢á¥å áâப ¨§ '*' ¢ ®¤­ã + * §¢¥§¤®çªã, ¨á¯®«ì§ã©â¥ TR ** *. + * + * ‚ ¤®¡ ¢«¥­¨¥ ª ¯à®áâë¬ á¨¬¢®« ¬, FROM ¨ TO ¬®£ãâ ¢ª«îç âì: + * + * ᪥©¯ë + * \x ¥áâì á ¬ x, ­® \b - ¡ ªá¯¥©á, \f - ä®à¬ä¨¤, \n - « ©­ä¨¤, + * \r - à¥âãà­, \t - â ¡ã«ïâ®à, \s - ¯à®¡¥« ¨ \DDD - ᨬ¢®« á + * ¢®á쬥à¨ç­ë¬ ª®¤®¬ DDD (¨á¯®«ì§ã¥âáï ⮫쪮 8 ¡¨â, æ¨äà ¬®¦¥â ¡ëâì + * ¨ ®¤­ , ¨ ¤¢¥, ¨á¯®«ì§®¢ ­¨¥ \0 ¢ë§ë¢ ¥â ­¥¯à¥¤áª §ã¥¬ë© १ã«ìâ â). + * 㪢ë b, f ¨ â.¤. ¬®£ãâ ¡ëâì ¢ ¤¢ãå ॣ¨áâà å. + * + * „¨ ¯ §®­ë + * a-e íª¢¨¢ «¥­â­® abcde, ¨ â.¯. ‡ ¬¥âìâ¥, çâ® e-a ¤®¯ãá⨬ë©, + * ­® ¯ãá⮩ ¤¨ ¯ §®­. + * + * Š« ááë + * :z ¯ãá⮩ ¤¨ ¯ §®­ + * :a íª¢¨¢ «¥­â­® a-zA-Z + * :l íª¢¨¢ «¥­â­® a-z + * :u íª¢¨¢ «¥­â­® A-Z + * :m íª¢¨¢ «¥­â­®  -ï + * :b íª¢¨¢ «¥­â­® €-Ÿ + * :r íª¢¨¢ «¥­â­®  -ï€-Ÿ + * :d íª¢¨¢ «¥­â­® 0-9 + * :n íª¢¨¢ «¥­â­® a-zA-Z0-9 + * :s ¤¨ ¯ §®­ ®â CTRL/A ¤® ¯à®¡¥«  (001-040) + * :. ¢á¥ ASCII ᨬ¢®«ë, ªà®¬¥ 0 (001-0377) + * + * ’ ª: TR ":a:." "A-ZA-Z " + * â࠭᫨àã¥â ¢á¥ « â¨­áª¨¥ ¡ãª¢ë ¢ ¢¥àå­¨© ॣ¨áâà, ¨ ।ãæ¨àã¥â + * ¢á¥ á®á«¥¤®¢ â¥«ì­®á⨠­¥-¡ãª¢ ¢ ®¤¨­ ¯à®¡¥« + * + * ˆ¤¥­â¨ä¨ª â®àë ª« áá  ¬®£ãâ ¡ëâì ¢ «î¡®¬ ॣ¨áâà¥. + * + * Žâà¨æ ­¨ï + * …᫨ ¯¥à¢ë© ᨬ¢®« FROM ¥áâì '^', íâ® ®§­ ç ¥â ¢á¥ ᨬ¢®«ë ­¥ + * ¨§ FROM. ‚ í⮬ á«ãç ¥ TO ¤®«¦­® ¡ëâì ¯ãáâ® ¨«¨ ⮫쪮 ¨§ ®¤­®£® + * ᨬ¢®« . + * + * '\' and ':' â¥àïîâ ᢮¥ ᯥ槭 ç¥­¨¥, ¥á«¨ ®­¨ ¯®á«¥¤­¨© ᨬ¢®« FROM + * ¨«¨ TO; '-' - ¥á«¨ ®­ ¯¥à¢ë© ᨬ¢®«; '^' - ¥á«¨ ®­ ­¥ ¯¥à¢ë© ᨬ¢®« + * FROM; «î¡®© ᨬ¢®« â¥àï¥â ᯥ槭 ç¥­¨¥ ¯®á«¥ í᪥©¯  ('\'). + * + * This program is licensed under GNU GPL license. + * + */ + +#include +#include +#include +#include + +#define SSIZE 512 /* à §¬¥à ®¡à §æ  */ +#define ESCAPE '\\' /* ᨬ¢®« í᪥©¯  */ +#define NOT '^' /* ᨬ¢®« ®âà¨æ ­¨ï */ +#define PCLASS ':' /* ¯à¥ä¨ªá ª« áá  */ +#define RANGE '-' /* ᯥæ¨ä¨ª â®à ¤¨ ¯ §®­  */ + +char *hlp[] = { + "usage: tr FROM TO [+START] [-END] [filein [fileout]]", + "\tSTART - starting position for transliteration", + "\tEND - ending position for transliteration", + "\tlen(FROM) == len(TO):", + "\t\tchars in TO are substitutes for chars in FROM", + "\tlen(TO) == 0:", + "\t\tany chars in FROM are deleted", + "\tlen(TO) < len(FROM):", + "\t\tall chars in FROM beyond the last one to match", + "\t\tup with one in TO translate into the last char", + "\t\tin TO; BUT any stream of consecutive characters so", + "\t\ttranslated is reduced to just one occurence of the", + "\t\tresulting char.", + "\tEscapes: \\r \\n \\t \\f \\b \\s \\ddd", + "\tRanges: a-e is the same as abcde (e-a is empty range)", + "\tClasses:", + "\t\t:z empty range", + "\t\t:a is the same as a-zA-Z", + "\t\t:l is the same as a-z", + "\t\t:u is the same as A-Z", + "\t\t:m is the same as  -ï", + "\t\t:b is the same as €-Ÿ", + "\t\t:r is the same as  -ï€-Ÿ", + "\t\t:d is the same as 0-9", + "\t\t:n is the same as a-zA-Z0-9", + "\t\t:s is the range \\001-\\040", + "\t\t:. is the range including all ASCII other then \\0", + "\tNegation: if the first character of FROM is '^',", + "\t\tany characters not in FROM match. In this case, TO", + "\t\tmust be null or only a single char", + 0 +}; + +void help(void) { + register int i = 0; + while (hlp[i]) + fprintf(stderr,"%s\n",hlp[i++]); + exit(0); +} + +void error(char *s1,char *s2) { + fprintf(stderr, "tr: %s %s\n", s1, s2 ? s2 : ""); + exit(1); +} + +int xindex(unsigned char *array, unsigned char c, int allbut, int lastto) { + register unsigned char *index; + + for (index = array; *index; ++index) + if (*index == c) + break; + if (allbut == 0) + return(*index ? (index - array) : (-1)); + if (*index) + return(-1); + return(lastto+1); +} + +/* ‚áâ ¢ª  ᨬ¢®«®¢ á lo ¤® hi (¢ª«îç¨â¥«ì­®) ¢ ttb */ +char *insrange(int lo, int hi, char *ttb) { + for (lo &= 0377, hi &= 0377; lo <= hi; *ttb++ = lo++) + ; + return ttb; +} + +/* Ž¡à ¡®âª  í᪥©¯®¢ + * + * char esc(ppc) + * char **ppc; + * + * esc(ppc) à á¯®§­ ¥â ¨ ®¡à ¡ â뢠¥â escaped-ᨬ¢®«ë. + * …᫨ *ppc 㪠§ë¢ ¥â ­¥ ­  '\', esc() ¯à®áâ® ¢¥à­¥â ᨬ¢®«. + * ˆ­ ç¥, ¥á«¨ á«¥¤ãî騩 ᨬ¢®« ¨§ ¬­®¦¥á⢠ {b,f,n,r,t,s}, ¢®§¢à é ¥âáï + * ᮮ⢥âáâ¢ãî騩 ª®¤. …᫨ á«¥¤ãî騩 ᨬ¢®« - ¢®á쬥à¨ç­ ï æ¨äà , + * ®¡à ¡ â뢠¥âáï \ddd, ¢®§¢à é ¥âáï ¯®«ã祭­®¥ §­ ç¥­¨¥. + * + * …᫨ '\' - ¯®á«¥¤­¨© ᨬ¢®«, á ¬ '\' ¢®§¢à é ¥âáï. + * + * …᫨ '\' ¯à¥¤è¥áâ¢ã¥â «î¡®¬ã ­¥ã¯®¬ï­ã⮬ã x, x á ¬ ¢®§¢à é ¥âáï. + * + * ‚® ¢á¥å á«ãç ïå, *ppc 㪠§ë¢ ¥â ­  ¯®á«¥¤­¨© ᨬ¢®«, "¯à®£«®ç¥­­ë©" esc(), + * ­ ¯à¨¬¥à 't' ¥á«¨ ¢¥à­ã«¨ ¤«ï '\t'. + */ +char esc(char **ppc) { + char c, c1; + char *pc = *ppc; + + if ((c = *pc) != ESCAPE || pc[1] == 0) + return(c); + else { + c = *++pc; + c1 = tolower(c); + *ppc = pc; + if (c1 == 'b') + return('\b'); + if (c1 == 'f') + return('\f'); + if (c1 == 'n') + return('\n'); + if (c1 == 'r') + return('\r'); + if (c1 == 't') + return('\t'); + if (c1 == 's') + return('\040'); + if (c1 >= '0' && c1 <= '7') { + c -= '0'; + c1 = pc[1]; + if (c1 >= '0' && c1 <= '7') { + c = (c << 3) + (c1 - '0'); + pc++; + c1 = pc[1]; + if (c1 >= '0' && c1 <= '7') { + c = (c << 3) + (c1 - '0'); + pc++; + } + } + *ppc = pc; + return (c & 0377); + } + return (c); + } +} + +/*  áè¨à¥­¨¥ ¤¨ ¯ §®­  ®â ¯®á«¥¤­¥£® ᨬ¢®«  ttb ¤® á«¥¤ãî饣® + * ᨬ¢®«  ¢ *ps (¬®¦¥â ¡ëâì "escaped"). + */ +char *dorange(char **ps, char *ttb) { + (*ps)++; /* ¯à®¯ã᪠RANGE */ + return insrange(ttb[-1]+1,esc(ps),ttb); +} + +/* ®áâ஥­¨¥ ttb (â ¡«¨æë âà ­á«ï樨) ¨§ array. */ +char *makttb(char *a, char *ttb, char *xxx) { + int c; + char *t = ttb; + + for (; (c = *a) != 0; ++a) { + if ((ttb - t) >= SSIZE) + error("Expansion to long for",xxx); + if (c == ESCAPE) + *ttb++ = esc(&a); + else if (c == PCLASS && a[1]) { + switch (c = tolower(*++a)) { + case 'z': + break; + case 'n': + ttb = insrange('0','9',ttb); + case 'a': + ttb = insrange('A','Z',ttb); + case 'l': + ttb = insrange('a','z',ttb); + break; + case 'u': + ttb = insrange('A','Z',ttb); + break; + case 'r': + ttb = insrange('€','Ÿ',ttb); + case 'm': + ttb = insrange(' ','¯',ttb); + ttb = insrange('à','ï',ttb); + break; + case 'b': + ttb = insrange('€','Ÿ',ttb); + break; + case 'd': + ttb = insrange('0','9',ttb); + break; + case 's': + ttb = insrange(1,' ',ttb); + break; + case '.': + ttb = insrange(1,0377,ttb); + break; + default: + error("Unknown class type",a-1); + } + } + else if (*a == RANGE && ttb != t && a[1]) + ttb = dorange(&a,ttb); + else *ttb++ = *a; + } + *ttb = 0; + return t; +} + +char *froms, + *tos; +int allbut, + collapse, + expander, + lastto; +int bp = 0, + ep = 9999; +FILE *fin = stdin, + *fout = stdout; + +void process(void) { + int pos = 0; + int i, c; + + while ((c = getc(fin)) != EOF) { + pos = (c == '\t') ? (pos+8-(pos&7)) : pos+1; + if (pos-1 < bp || (ep > 0 && pos-1 > ep)) { + putc(c,fout); + goto Cont; + } + i = xindex(froms,c,allbut,lastto); + if (collapse && i >= lastto && lastto >= 0) { /* ª®«« ¯á */ + putc(tos[lastto],fout); + do { + i = xindex(froms,c = getc(fin),allbut,lastto); + pos = (c == '\t') ? (pos+8-(pos&7)) : pos+1; + } while (c != EOF && i >= lastto); + if (c == EOF) + break; + } + if (i >= 0) { + if (lastto >= 0) + putc(tos[i],fout); /* âà ­á«ïæ¨ï */ + } /* ¨­ ç¥ - 稪 ¥¬ */ + else putc(c,fout); /* ª®¯¨à㥬 */ + +Cont: if (c == '\n') + pos = 0; + } +} + +void main(int argc, char *argv[]) { + int i, c; + char *nfin = NULL, *nfout = NULL; + char *from, *to; + + if (argc < 3) + help(); + froms = argv[1]; + tos = argv[2]; + + for (i = 3; i < argc; i++) { + to = argv[i]; + c = *to++; + if (c == '+') + bp = atoi(to); + else if (c == '-') + ep = atoi(to); + else if (nfin == NULL) + nfin = argv[i]; + else if (nfout == NULL) + nfout = argv[i]; + else error("Bad option",argv[i]); + } + if (bp >= ep) + error("Illegal +START/-END parameters",0); + if (nfin != NULL && (fin = fopen(nfin,"rb")) == NULL) + error("Can't open file",nfin); + if (nfout != NULL && (fout = fopen(nfout,"wb")) == NULL) + error("Can't create file",nfout); + setvbuf(fin,NULL,_IOFBF,0x7000); + setvbuf(fout,NULL,_IOFBF,0x7000); + if ((allbut = (*froms == NOT)) != 0) + froms++; + from = malloc(SSIZE+1); + to = malloc(SSIZE+1); + if (!from || !to) + error("Not enough memory",0); + froms = makttb(froms, from, "FROM"); + if (!tos) + *to = 0; + else makttb(tos, to, "TO"); + tos = to; + lastto = strlen(tos) - 1; + collapse = (strlen(froms)-1 > lastto || allbut); + expander = (strlen(froms)-1 < lastto); + +#ifdef DEBUG + fprintf(stderr,"%s%s, allbut %d, lastto %d\n", + collapse?"Collapse":"", + expander?"Expander":"", + allbut,lastto); + fprintf(stderr,"to: %s\n",tos); + fprintf(stderr,"from: %s\n",froms); + fprintf(stderr,"bp = %d, ep = %d\n",bp,ep); +#endif + process(); + exit(0); +} + \ No newline at end of file diff --git a/src/simple/true.c b/src/simple/true.c new file mode 100755 index 00000000..465eb5a6 --- /dev/null +++ b/src/simple/true.c @@ -0,0 +1,6 @@ +/* true.c + */ +int main() { + return 0; +} + \ No newline at end of file diff --git a/src/simple/ualign.c b/src/simple/ualign.c new file mode 100755 index 00000000..5420725f --- /dev/null +++ b/src/simple/ualign.c @@ -0,0 +1,129 @@ +/* ualign.c + * descripton: change files position on disk + * author: Archi Schekochikhin + * Adriano Cunha + * license: GNU Public License version 2 + */ + +#include /* for stdout */ +#include +#include /* for O_RDONLY */ +#include /* for XIP_UALIGN */ +#include +#include +#include +#include + +#if 0 +void wr(char *s) { + write(STDERR_FILENO, s, strlen(s)); +} + +int getint(p, p1) + char *p; + char **p1; +{ + int v = 0; + for (v = 0; *p >= '0' && *p <= '9'; ++p) { + v *= 10; + v += *p - '0'; + } + *p1=p; + return v; +} +#endif + +int main(argc, argv) + int argc; + char **argv; + { + int i, fd, er = 0, ncreate = 0, nsymlink = 0, verbose = 0; + struct utimbuf utim; + struct stat statbuf; + char *p; + time_t now, mytimet; + int errs = 0; + + if (argc < 2) + { + printf("usage: ualign [-c] [-s] [-v] filename ...\n"); + fflush(stdout); + return 0; + } + argc--; + argv++; + while ((argc > 0) && (**argv == '-')) + { + argc--; + p = *argv++; + while (*++p) + switch (*p) + { + case 'c': + ncreate = 1; + break; + case 's': + nsymlink = 1; + break; + case 'v': + verbose = 1; + break; + default: + printf("unknown option %s\n", p); + fflush(stdout); + return 1; + } + } + + for (i = 0; i < argc; i++) + { + er = 0; + p = argv[i]; + if (nsymlink) + { + fd = open(p, O_SYMLINK); + if (fd >= 0) + { + close(fd); + if (verbose) + { + printf("skipping symlink %s\n", p); + fflush(stdout); + } + continue; + } + } + fd = open(p, O_RDONLY); + if (fd < 0) + { + if (errno == ENOENT && ncreate == 0) + { + fd = creat(p, 0666); + } + } + if (fd < 0) + { + er = -1; + } + else + { + er = falign(fd, XIP_UALIGN); + close(fd); + } + if (er) + { + fprintf(stderr, "can't unalign "); + fflush(stderr); + perror(p); + errs++; + } + else if (verbose) + { + printf("ualign %s\n", p); + fflush(stdout); + } + } + + return errs; +} + diff --git a/src/simple/umount.c b/src/simple/umount.c new file mode 100755 index 00000000..8db4c044 --- /dev/null +++ b/src/simple/umount.c @@ -0,0 +1,73 @@ +/* Copyright (c) 1993 by David I. Bell + * Permission is granted to use, distribute, or modify this source, + * provided that this copyright notice remains intact. + * + * jun/99: Adriano Cunha + * added /etc/mtab update + */ +#include +#include +#include +#include + +int main(argc, argv) + int argc; + char **argv; +{ + FILE *fdi, *fdo; + int i, fnd = 0; + char buf[256], *p, c; + + if (argc != 2) { + fprintf(stderr, "usage: umount mountpoint\n"); + return 0; + } + if (umount(argv[1]) < 0) { + perror(argv[1]); + return 1; + } + if ((fdi = fopen("/etc/mtab", "r")) == NULL) { + perror("can't open /etc/mtab"); + return 2; + } + if ((fdo = fopen("/etc/mtab.tmp", "w")) == NULL) { + perror("can't backup /etc/mtab"); + return 2; + } + for (i = 0; !feof(fdi); i++) { + fgets(buf, sizeof(buf)-1, fdi); + if (NULL == (p = strchr(buf, '\t'))) + continue; + c = *p; + *p = 0; + if (0 == strcmp(buf,argv[1])) { + ++fnd; + continue; + } + *p = c; + fputs(buf, fdo); + fflush(fdo); + } + fclose(fdi); + fclose(fdo); + if (i < 1) { + errno = EFAULT; + perror("can't backup /etc/mtab"); +Unl: unlink("/etc/mtab.tmp"); + return 2; + } + if (fnd == 0) { + perror("/etc/mtab not correctly updated"); + goto Unl; + } + if (unlink("/etc/mtab")) { + perror("can't replace /etc/mtab"); + goto Unl; + } + if (rename("/etc/mtab.tmp", "/etc/mtab")) { + perror("can't rename /etc/mtab.tmp to /etc/mtab"); + return 3; + } + return 0; +} + diff --git a/src/simple/uname.c b/src/simple/uname.c new file mode 100755 index 00000000..fe80f780 --- /dev/null +++ b/src/simple/uname.c @@ -0,0 +1,65 @@ +#include +#include +#include + +/* Values that are bitwise or'd into toprint'. */ +/* Operating system name. */ +#define PRINT_SYSNAME 1 +/* Node name on a communications network. */ +#define PRINT_NODENAME 2 +/* Operating system release. */ +#define PRINT_RELEASE 4 +/* Operating system version. */ +#define PRINT_VERSION 8 +/* Machine hardware name. */ +#define PRINT_MACHINE 16 + +/* Mask indicating which elements of the name to print. */ +static unsigned char toprint; + +static void print_element (mask, element) + unsigned char mask; + char *element; +{ + if (toprint & mask) { + toprint &= ~mask; + write(STDOUT_FILENO,element,strlen(element)); + write(STDOUT_FILENO,toprint ? " " : "\n",1); + } +} + +void main (argc, argv) + int argc; + char **argv; +{ + int i; + struct utsname name; + + toprint = 0; + for (i = 1; i < argc; i++) { + switch(argv[i][1]) { + case 's': toprint |= PRINT_SYSNAME; break; + case 'n': toprint |= PRINT_NODENAME; break; + case 'r': toprint |= PRINT_RELEASE; break; + case 'v': toprint |= PRINT_VERSION; break; + case 'm': toprint |= PRINT_MACHINE; break; + case 'a': + toprint = PRINT_SYSNAME | PRINT_NODENAME | + PRINT_RELEASE | PRINT_VERSION | PRINT_MACHINE; + break; + default: + write(STDOUT_FILENO,"usage: uname [-amvrns]\n",23); + return; + } + } + if (toprint == 0) + toprint = PRINT_SYSNAME; + if (uname(&name) != -1) { + print_element(PRINT_SYSNAME, name.sysname); + print_element(PRINT_NODENAME, name.nodename); + print_element(PRINT_RELEASE, name.release); + print_element(PRINT_VERSION, name.version); + print_element(PRINT_MACHINE, name.machine); + } + exit(0); +} diff --git a/src/simple/uniq.c b/src/simple/uniq.c new file mode 100755 index 00000000..88c9a0a4 --- /dev/null +++ b/src/simple/uniq.c @@ -0,0 +1,189 @@ +/* U N I Q . C + * + * Read a file, writing unique (or non-unique) lines. + * + * uniq [-options] [-fields] [+letters] [file] + * + * Uniq reads a sorted input file, writing each unique line. + * The following options are defined: + * -u Only print unique lines. + * -d Only print duplicate lines. + * -c Print the number of times each line occurred along with + * the line. + * -z As -c, but print outal numbers. + * -N.M Skip over the first N words before checking + * for uniqueness. + * Skip over the first M letters (in the indicated field). + * Note that fields are skipped before letters. + * +L Compare only L letters. + * + * A word is defined as "optional spaces or tabs" followed by text up to + * the first space, tab, or end of line. + * + * uniq read from stdin (or file) and write to the stdout. + * + * This program is licensed under GNU GPL license. + * + */ + +#include +#include +#include +#include +#include + +#define MAXLINE 3000 + +int skip_fields = 0; /* Number of fields to skip */ +int skip_letters = 0; /* Number of letters to skip */ +int check_letters = 0; /* Number of letters to test */ +int linecount = 0; /* How many repetitions */ +int countmode = 0; /* Counted output */ +int mode = 0; /* Mode byte, if any */ +char *line1 = NULL; /* Input buffer 1 */ +char *line2 = NULL; /* Input buffer 2 */ + +char *hlp[] = { + "usage: uniq [-udcz] -[WORDS].[LETTERS] [+LENGTH] [file]", + "\tu - print unique lines", + "\td - print duplicated lines", + "\tc - print the number of times each line occurred", + "\t along with the line.", + "\tz - as -c, but print octal numbers", + "\tWORDS - skip over the first WORDS words before checking", + "\tLETTERS - skip over the first LETTERS letters", + "\tLENGTH - compare only LENGTH letters", + "\tfile - input file name (stdin if omitted)", + 0 +}; + +void error(char *s1,char *s2) { + fprintf(stderr, "uniq: %s %s\n", s1, s2 ? s2 : ""); + exit(1); +} + +void help(void) { + register int i = 0; + + while (hlp[i]) + fprintf(stderr,"%s\n",hlp[i++]); + exit(1); +} + +/* + * Return zero if they don't match. If they do, return 1. + */ +int equals(char *old, char *new) { + if (check_letters > 0) + return (strncmp(old, new, check_letters) == 0); + return (strcmp(old, new) == 0); +} + +/* + * Output this line. + */ +void output(char *line) { + if ((mode == 'u' && linecount > 1) || (mode == 'd' && linecount <= 1)) + return; + if (countmode == 'c') + printf("%5d\t", linecount); + else if (countmode == 'z') + printf("%06o\t", linecount); + fputs(line,stdout); +} + +/* Read a line. return NULL on end of file. If not end of file, return + * a pointer to the first byte of the field to check. + */ +char *getline(char *line) { + register int count; + register char c, *lp = line; + + if (fgets(lp,MAXLINE,stdin) == NULL) + return NULL; + for (count = 0; count < skip_fields; ++count) { + for (; (c = *lp) == ' ' || c == '\t'; ++lp) + ; + for (; (c = *lp) != ' ' && c != '\t'; ++lp) + if (!c) + return lp; + } + for (count = 0; count++ < skip_letters && *lp; ++lp) + ; + return lp; +} + +/* + * Read lines as long as new == old. Return a pointer to the field to + * test in new. Exit the program on end of file. + */ +char *check(char *new, char *old, char *oldpos) { + register char *lp; /* Random line pointer */ + + for (linecount = 0;; ) { + ++linecount; + if ((lp = getline(new)) == NULL) { + output(old); + exit(1); + } + if (!equals(oldpos, lp)) + break; + } + output(old); + return lp; +} + +void main(int argc, char *argv[]) { + register char *argp;/* Argument pointer */ + register char c; /* Temp character */ + register char *lp; /* Line buffer pointer */ + + if ((line1 = (char *)malloc(MAXLINE+1)) == NULL || + (line2 = (char *)malloc(MAXLINE+1)) == NULL) + error("Not enough memory",0); + + while (--argc > 0) { + argp = *++argv; + switch (c = *argp++) { + case '?': + help(); + case '+': + check_letters = atoi(argp); + break; + case '-': + while ((c = *argp++) != 0) { + switch (c = tolower(c)) { + case 'c': + case 'z': + countmode = c; + break; + case 'u': + case 'd': + mode = c; + break; + default: + if (!isdigit(c)) + error("Bad switch",*argv); + for (lp = --argp; isdigit(*lp); ++lp) + ; + if (lp != argp) + skip_fields = atoi(argp); + if (*lp == '.') + skip_letters = atoi(++lp); + } + } + break; + default: + if (freopen(*argv,"rt",stdin) == NULL) + error("Can't open file",*argv); + } + } + /* Here we go */ + if ((lp = getline(line2)) == 0) /* Prime the pump */ + exit(1); + for (;;) { + lp = check(line1, line2, lp); + lp = check(line2, line1, lp); + } +} + \ No newline at end of file diff --git a/src/simple/uudecode.c b/src/simple/uudecode.c new file mode 100755 index 00000000..e58c2136 --- /dev/null +++ b/src/simple/uudecode.c @@ -0,0 +1,580 @@ +/* uud - bulletproof version of uudecode */ + +/* + * Uud -- decode a uuencoded file back to binary form. + * + * From the Berkeley original, modified by MSD, RDR, JPHD & WLS. + * The Atari GEMDOS version compiled with MWC 2.x. + * The MSDOS version with TurboC. + * The Unix version with cc. + * this version is made: 25 Nov 1988. + * Jan 2 1990: Change system definition and change MSDOS to open the output + * file for write binary do cr/lf replacement. + */ + +#define UNIX 1 /* define one of: UNIX (Minix too!), MSDOS, or GEMDOS */ + +#ifdef GEMDOS +#define SYSNAME "gemdos" +#define SMALL 1 +#endif +#ifdef MSDOS +#define SYSNAME "msdos" +#define SMALL 1 +#endif +#ifdef UNIX +#define SYSNAME "unix" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef GEMDOS +#include +#define Error(n) { Bconin(2); exit(n); } +#else +#define Error(n) exit(n) +#endif +#ifdef UNIX +#define WRITE "w" +#else +#define WRITE "wb" /* for both MSDOS and GEMDOS! */ +#endif + +#define loop while (1) + +#ifdef MSX_UZIX_TARGET +#define LINELEN 128 +#else +#define LINELEN 256 +#endif + +#define NCHARS 256 +#define FILELEN 64 +#define NORMLEN 60 /* allows for 80 encoded chars per line */ + +#define SEQMAX 'z' +#define SEQMIN 'a' +char seqc; +int first, secnd, check, numl; + +FILE *in, *out; +char *pos; +char ifname[FILELEN], ofname[FILELEN]; +char *source = NULL, *target = NULL; +char blank, part = '\0'; +int partn, lens; +int debug = 0, nochk = 0, onedone = 0; +int chtbl[NCHARS], cdlen[NORMLEN + 3]; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(char *getnword, (char *str, int n)); +_PROTOTYPE(void gettable, (void)); +_PROTOTYPE(void decode, (void)); +_PROTOTYPE(void getfile, (char *buf)); +_PROTOTYPE(void format, (char *fp, ...)); +_PROTOTYPE(void doprnt, (char *fp, char *ap)); +_PROTOTYPE(void puti, (unsigned int i, unsigned int r)); +_PROTOTYPE(void outc, (register char c)); +_PROTOTYPE(void usage, ()); + +int main(argc, argv) int argc; char *argv[]; +{ + int mode; + register int i, j; + char *curarg; + char dest[FILELEN], buf[LINELEN]; + + if (argc < 2) usage(); + while ((curarg = argv[1]) != NULL && curarg[0] == '-') { + if (((curarg[1] == 'd') || (curarg[1] == 'D')) && + (curarg[2] == '\0')) { + debug = 1; + } else if (((curarg[1] == 'n') || (curarg[1] == 'N')) && + (curarg[2] == '\0')) { + nochk = 1; + } else if (((curarg[1] == 't') || (curarg[1] == 'T')) && + (curarg[2] == '\0')) { + argv++; + argc--; + if (argc < 2) { + format("uudecode: Missing target directory.\n"); + Error(15); + } + target = argv[1]; + if (debug) + format("Target dir = %s\n",target); + } else if (((curarg[1] == 's') || (curarg[1] == 'S')) && + (curarg[2] == '\0')) { + argv++; + argc--; + if (argc < 2) { + format("uudecode: Missing source directory.\n"); + Error(15); + } + source = argv[1]; + if (debug) + format("Source dir = %s\n",source); + } else if (curarg[1] != '\0') { + usage(); + } else + break; + argv++; + argc--; + } + + if (curarg == NULL || ((curarg[0] == '-') && (curarg[1] == '\0'))) { + in = stdin; + strcpy(ifname, ""); + } else { + if (source != NULL) { + strcpy(ifname, source); + strcat(ifname, curarg); + } else + strcpy(ifname, curarg); + if ((in = fopen(ifname, "r")) == NULL) { + format("uudecode: Can't open %s\n", ifname); + Error(2); + } + numl = 0; + } + +/* + * Set up the default translation table. + */ + for (i = 0; i < ' '; i++) chtbl[i] = -1; + for (i = ' ', j = 0; i < ' ' + 64; i++, j++) chtbl[i] = j; + for (i = ' ' + 64; i < NCHARS; i++) chtbl[i] = -1; + chtbl['`'] = chtbl[' ']; /* common mutation */ + chtbl['~'] = chtbl['^']; /* an other common mutation */ + blank = ' '; +/* + * set up the line length table, to avoid computing lotsa * and / ... + */ + cdlen[0] = 1; + for (i = 1, j = 5; i <= NORMLEN; i += 3, j += 4) + cdlen[i] = (cdlen[i + 1] = (cdlen[i + 2] = j)); +/* + * search for header or translation table line. + */ + loop { /* master loop for multiple decodes in one file */ + partn = 'a'; + loop { + if (fgets(buf, sizeof buf, in) == NULL) { + if (onedone) { + if (debug) format("End of file.\n"); + exit(0); + } else { + format("uudecode: No begin line.\n"); + Error(3); + } + } + numl++; + if (strncmp(buf, "table", (size_t)5) == 0) { + gettable(); + continue; + } + if (strncmp(buf, "begin", (size_t)5) == 0) { + break; + } + } + lens = strlen(buf); + if (lens) buf[--lens] = '\0'; +#ifdef SMALL + if ((pos = getnword(buf, 3))) { + strcpy(dest, pos); + } else +#else + if(sscanf(buf,"begin%o%s", &mode, dest) != 2) +#endif + { + format("uudecode: Missing filename in begin line.\n"); + Error(10); + } + + if (target != NULL) { + strcpy(ofname, target); + strcat(ofname, dest); + } else + strcpy(ofname, dest); + + if((out = fopen(ofname, WRITE)) == NULL) { + format("uudecode: Cannot open output file: %s\n", ofname); + Error(4); + } + if (debug) format("Begin uudecoding: %s\n", ofname); + seqc = SEQMAX; + check = nochk ? 0 : 1; + first = 1; + secnd = 0; + decode(); + fclose(out); +#ifdef UNIX + chmod(ofname, mode); +#endif + onedone = 1; + if (debug) format("End uudecoding: %s\n", ofname); + } /* master loop for multiple decodes in one file */ +} + +/* + * Bring back a pointer to the start of the nth word. + */ +char *getnword(str, n) register char *str; register int n; +{ + while((*str == '\t') || (*str == ' ')) str++; + if (! *str) return NULL; + while(--n) { + while ((*str != '\t') && (*str != ' ') && (*str)) str++; + if (! *str) return NULL; + while((*str == '\t') || (*str == ' ')) str++; + if (! *str) return NULL; + } + return str; +} + +/* + * Install the table in memory for later use. + */ +void gettable() +{ + char buf[LINELEN]; + register int c, n = 0; + register char *cpt; + + for (c = 0; c < NCHARS; c++) chtbl[c] = -1; + +again: if (fgets(buf, sizeof buf, in) == NULL) { + format("uudecode: EOF while in translation table.\n"); + Error(5); + } + numl++; + if (strncmp(buf, "begin", (size_t)5) == 0) { + format("uudecode: Incomplete translation table.\n"); + Error(6); + } + cpt = buf + strlen(buf) - 1; + *cpt = ' '; + while (*(cpt) == ' ') { + *cpt = 0; + cpt--; + } + cpt = buf; + while (c = *cpt) { + if (chtbl[c] != -1) { + format("uudecode: Duplicate char in translation table.\n"); + Error(7); + } + if (n == 0) blank = c; + chtbl[c] = n++; + if (n >= 64) return; + cpt++; + } + goto again; +} + +/* + * copy from in to out, decoding as you go along. + */ + +void decode() +{ + char buf[LINELEN], outl[LINELEN]; + register char *bp, *ut, kk; + register int *trtbl = chtbl; + register int n, c, rlen; + register unsigned int len; + + loop { + if (fgets(buf, sizeof buf, in) == NULL) { + format("uudecode: EOF before end.\n"); + fclose(out); + Error(8); + } + numl++; + len = strlen(buf); + if (len) buf[--len] = '\0'; +/* + * Is it an unprotected empty line before the end line ? + */ + if (len == 0) continue; +/* + * Get the binary line length. + */ + n = trtbl[*buf]; + if (n >= 0) goto decod; +/* + * end of uuencoded file ? + */ + if (strncmp(buf, "end", (size_t)3) == 0) return; +/* + * end of current file ? : get next one. + */ + if (strncmp(buf, "include", (size_t)7) == 0) { + getfile(buf); + continue; + } + format("uudecode: Bad prefix line %d in file: %s\n",numl, ifname); + if (debug) format("Bad line =%s\n",buf); + Error(11); +/* + * Sequence checking ? + */ +decod: rlen = cdlen[n]; +/* + * Is it the empty line before the end line ? + */ + if (n == 0) continue; +/* + * Pad with blanks. + */ + for (bp = &buf[c = len]; + c < rlen; c++, bp++) *bp = blank; +/* + * Verify if asked for. + */ + if (debug) { + for (len = 0, bp = buf; len < rlen; len++) { + if (trtbl[*bp] < 0) { + format( + "Non uuencoded char <%c>, line %d in file: %s\n", *bp, numl, ifname); + format("Bad line =%s\n",buf); + Error(16); + } + bp++; + } + } +/* + * All this just to check for uuencodes that append a 'z' to each line.... + */ + if (secnd && check) { + secnd = 0; + if (buf[rlen] == SEQMAX) { + check = 0; + if (debug) format("Sequence check turned off (2).\n"); + } else + if (debug) format("Sequence check on (2).\n"); + } else if (first && check) { + first = 0; + secnd = 1; + if (buf[rlen] != SEQMAX) { + check = 0; + if (debug) format("No sequence check (1).\n"); + } else + if (debug) format("Sequence check on (1).\n"); + } +/* + * There we check. + */ + if (check) { + if (buf[rlen] != seqc) { + format("uudecode: Wrong sequence line %d in %s\n", + numl, ifname); + if (debug) + format( + "Sequence char is <%c> instead of <%c>.\n", buf[rlen], seqc); + Error(18); + } + seqc--; + if (seqc < SEQMIN) seqc = SEQMAX; + } +/* + * output a group of 3 bytes (4 input characters). + * the input chars are pointed to by p, they are to + * be output to file f.n is used to tell us not to + * output all of them at the end of the file. + */ + ut = outl; + len = n; + bp = &buf[1]; + while (n > 0) { + *(ut) = trtbl[*bp] << 2; + *(ut++) = *(ut) | (trtbl[bp[1]] >> 4); + n--; + if (n) { + *(ut) = trtbl[bp[1]] << 4; + *(ut++) = *(ut) | (trtbl[bp[2]] >> 2); + n--; + } + if (n) { + *(ut++) = trtbl[bp[2]] << 6 | trtbl[bp[3]]; + n--; + } + bp += 4; + } + if ((n = fwrite(outl, (size_t)1, (size_t)len, out)) <= 0) { + format("uudecode: Error on writing decoded file.\n"); + Error(18); + } + } +} + +/* + * Find the next needed file, if existing, otherwise try further + * on next file. + */ +void getfile(buf) register char *buf; +{ + if ((pos = getnword(buf, 2)) == NULL) { + format("uudecode: Missing include file name.\n"); + Error(17); + } else + if (source != NULL) { + strcpy(ifname, source); + strcat(ifname, pos); + } else + strcpy(ifname, pos); +#ifdef GEMDOS + if (Fattrib(ifname, 0, 0) < 0) +#else + if (access(ifname, 04)) +#endif + { + if (debug) { + format("Cant find: %s\n", ifname); + format("Continuing to read same file.\n"); + } + } + else { + if (freopen(ifname, "r", in) == in) { + numl = 0; + if (debug) + format("Reading next section from: %s\n", ifname); + } else { + format("uudecode: Freopen abort: %s\n", ifname); + Error(9); + } + } + loop { + if (fgets(buf, LINELEN, in) == NULL) { + format("uudecode: No begin line after include: %s\n", ifname); + Error(12); + } + numl++; + if (strncmp(buf, "table", (size_t)5) == 0) { + gettable(); + continue; + } + if (strncmp(buf, "begin", (size_t)5) == 0) break; + } + lens = strlen(buf); + if (lens) buf[--lens] = '\0'; +/* + * Check the part suffix. + */ + if ((pos = getnword(buf, 3)) == NULL ) { + format("uudecode: Missing part name, in included file: %s\n", ifname); + Error(13); + } else { + part = *pos; + partn++; + if (partn > 'z') partn = 'a'; + if (part != partn) { + format("uudecode: Part suffix mismatch: <%c> instead of <%c>.\n", + part, partn); + Error(14); + } + if (debug) format("Reading part %c\n", *pos); + } +} + +/* + * Printf style formatting. (Borrowed from MicroEmacs by Dave Conroy.) + * A lot smaller than the full fledged printf. + */ +#ifdef __STDC__ +void format(char *fp, ...) +{ + va_list args; + + va_start (args, fp); + doprnt(fp, (char *)&args); + va_end(args); +} +#else +/* VARARGS1 */ +void format(fp, args) char *fp; +{ + doprnt(fp, (char *)&args); +} +#endif + +void doprnt(fp, ap) +register char *fp; +register char *ap; +{ + register int c, k; + register char *s; + + while ((c = *fp++) != '\0') { + if (c != '%') + outc(c); + else { + c = *fp++; + switch (c) { + case 'd': + puti(*(int *)ap, 10); + ap += sizeof(int); + break; + + case 's': + s = *(char **)ap; + while ((k = *s++) != '\0') + outc(k); + ap += sizeof(char *); + break; + + case 'c': + outc(*(int *)ap); + ap += sizeof(int); + break; + + default: + outc(c); + } + } + } +} + +/* + * Put integer, in radix "r". + */ +void puti(i, r) +register unsigned int i; +register unsigned int r; +{ + register unsigned int q, s; + + if ((q = i / r) != 0) + puti(q, r); + s = i % r; + if (s <= 9) + outc(s + '0'); + else + outc(s - 10 + 'A'); +} +void outc(c) +register char c; +{ +#ifdef GEMDOS + if (c == '\n') Bconout(2, '\r'); + Bconout(2, c); +#else + putchar(c); +#endif +} + +void usage() +{ + format("usage: uudecode [-n] [-d] [-s dir] [-t dir] [input-file]\n"); + Error(1); +} diff --git a/src/simple/uuencode.c b/src/simple/uuencode.c new file mode 100755 index 00000000..f75a91d0 --- /dev/null +++ b/src/simple/uuencode.c @@ -0,0 +1,224 @@ +/* uue - bulletproof version of uuencode */ + +/* Uue -- encode a file so that it's printable ascii, short lines + * + * Slightly modified from a version posted to net.sources a while back, + * and suitable for compilation on the IBM PC + * + * modified for Lattice C on the ST - 11.05.85 by MSD + * modified for ALCYON on the ST - 10-24-86 by RDR + * modified a little more for MWC... 02/09/87 by JPHD + * (An optional first argument of the form: -nnumber (e.g. -500), will + * produce a serie of files that long, linked by the include statement, + * such files are automatically uudecoded by the companion program.) + * More mods, - ... 05/06/87 by jphd + * Mods for TOPS 20, and more. 08/06/87 by jphd + * (remove freopen and rindex...change filename generation...) + * (A lot more to do about I/O speed, avoiding completely the stdio.h...) + * May be called as uuencode. Oct 2 1993 by Kees J. Bot + * + */ + + +#include +#include +#include +#include + +#define USAGE +#define FILE_NAME 10 /* affects how long names are truncated */ + +/* ENC is the basic 1 character encoding function to make a char printing */ +#define ENC(c) (((c) & 077) + ' ') + +FILE *fp, *outp; +char ofname[80]; +int lenofname; +int stdo = 0; + +#ifdef ST +#define READ "rb" +#else +#define READ "r" +#endif + +int part = 'a', chap = 'a'; +#define SEQMAX 'z' +#define SEQMIN 'a' +char seqc = SEQMAX; + +int split = 0; +int fileln = 32000; + +#ifndef _PROTOTYPE +#define _PROTOTYPE(x,y) x y +#endif + +_PROTOTYPE(int main, (int argc, char **argv)); +_PROTOTYPE(void maketable, (void)); +_PROTOTYPE(void makename, (void)); +_PROTOTYPE(void encode, (void)); +_PROTOTYPE(void outdec, (char *p)); +_PROTOTYPE(int fr, (char *buf, int cnt)); + +int main(argc, argv) +int argc; +char *argv[]; +{ + char *prog_name; + char *fname; + int filter; + + prog_name = argv[0] + strlen(argv[0]); + while (prog_name > argv[0] && prog_name[-1] != '/') prog_name--; + filter = strcmp(prog_name, "uuencode") == 0; + + if (argc < 2) { + fprintf(stderr, "usage: %s [-n] inputfile [-]\n", prog_name); + exit(2); + } + if (argv[1][0] == '-') { + fileln = -atoi(argv[1]); + if (fileln <= 0) { + fprintf(stderr, "Wrong file length arg.\n"); + exit(3); + } + split = 1; + argv++; + argc--; + } +#ifdef OLD_UUENCODE + if (filter) { /* old uuencode reads from standard input */ + fp = stdin; + } else +#endif + { + if ((fp = fopen(argv[1], READ)) == NULL) { /* binary input !!! */ + fprintf(stderr, "Cannot open %s\n", argv[1]); + exit(1); + } + } + fname = argv[1] + strlen(argv[1]); + while (fname > argv[1] && fname[-1] != '/') fname--; + strcpy(ofname, fname); + fname = ofname; + do { + if (*fname == '.') *fname = '\0'; + } while (*fname++); + /* 10 char prefix + .uue -> 14 chars MAX */ + lenofname = strlen(ofname); + if (lenofname > FILE_NAME) ofname[FILE_NAME] = '\0'; + strcat(ofname, ".uue"); + lenofname = strlen(ofname); + if (!split && (filter || (argc > 2) && (argv[2][0] == '-'))) { + stdo = 1; + outp = stdout; + } else { + makename(); + if ((outp = fopen(ofname, "w")) == NULL) { + fprintf(stderr, "Cannot open %s\n", ofname); + exit(1); + } + } + maketable(); + fprintf(outp, "begin %o %s\n", 0644, argv[1]); + encode(); + fprintf(outp, "end\n"); + fclose(outp); + return(0); +} + +/* Create ASCII table so a mailer can screw it up and the decode + * program can restore the error. + */ +void maketable() +{ + register int i, j; + + fputs("table\n", outp); + for (i = ' ', j = 0; i < '`'; j++) { + if (j == 32) putc('\n', outp); + fputc(i++, outp); + } + putc('\n', outp); +} + +/* Generate the names needed for single and multiple part encoding. */ +void makename() +{ + if (split) { + ofname[lenofname - 1] = part; + ofname[lenofname - 2] = chap; + } +} + +/* Copy from in to out, encoding as you go along. */ +void encode() +{ + char buf[80]; + register int i, n; + register int lines; + lines = 6; + + for (;;) { + n = fr(buf, 45); + putc(ENC(n), outp); + for (i = 0; i < n; i += 3) outdec(&buf[i]); + putc(seqc, outp); + seqc--; + if (seqc < SEQMIN) seqc = SEQMAX; + putc('\n', outp); + ++lines; + if (split && (lines > fileln)) { + part++; + if (part > 'z') { + part = 'a'; + if (chap == 'z') + chap = 'a'; /* loop ... */ + else + chap++; + } + makename(); + fprintf(outp, "include %s\n", ofname); + fclose(outp); + if ((outp = fopen(ofname, "w")) == NULL) { + fprintf(stderr, "Cannot open %s\n", ofname); + exit(1); + } + maketable(); + fprintf(outp, "begin part %c %s\n", part, ofname); + lines = 6; + } + if (n <= 0) break; + } +} + +/* Output one group of 3 bytes, pointed at by p, on file f. */ +void outdec(p) +register char *p; +{ + register int c1, c2, c3, c4; + + c1 = *p >> 2; + c2 = ((*p << 4) & 060) | ((p[1] >> 4) & 017); + c3 = ((p[1] << 2) & 074) | ((p[2] >> 6) & 03); + c4 = p[2] & 077; + putc(ENC(c1), outp); + putc(ENC(c2), outp); + putc(ENC(c3), outp); + putc(ENC(c4), outp); +} + +/* Fr: like read but stdio */ +int fr(buf, cnt) +register char *buf; +register int cnt; +{ + register int c, i; + for (i = 0; i < cnt; i++) { + c = fgetc(fp); + if (feof(fp)) return(i); + buf[i] = c; + } + return(cnt); +} diff --git a/src/simple/wc.c b/src/simple/wc.c new file mode 100755 index 00000000..492de5f4 --- /dev/null +++ b/src/simple/wc.c @@ -0,0 +1,161 @@ +/* wc Count Words, Lines, and Bytes in Files 24.11.87 by BAS + * + * wc [-bwp] [file ...] + * + * Count the number of bytes, words, and lines in one or more files. + * wc accepts wild-card file name arguments. + * + * -b - open files as binary stream + * -w - find max line width + * -p - count pages (FF-s) + * + * This program is licensed under GNU GPL license. + * + */ + +#include +#include +#include +#include + +long twords, tlines, tbytes; +int twidest, tpages; +int bflag, wflag, pflag; + +void error(char *s1,char *s2) { + fprintf(stderr, "wc: %s %s\n", s1, s2 ? s2 : ""); + exit(1); +} + +void help(void) { + fprintf(stderr, "usage: wc [-bwph] [files]\n"); + exit(0); +} + +void plural(long value, char *what) { + printf("%8ld %s%c", value, what, (value == 1) ? ' ' : 's'); +} + +void output(long lines, long words, long bytes, + int widest, int pages, char *filename) { + if (bflag) { + plural(bytes, "byte"); + plural((bytes+511)>>9,"block"); + printf("%6ldK",(bytes+1024)>>10); + } + else if (pflag) { + plural(lines, "line"); + printf("%5d wide",widest); + printf("%4d page%c", pages, (pages == 1) ? ' ' : 's'); + } + else { + plural(lines, "line"); + plural(words, "word"); + plural(bytes, "byte"); + if (wflag) + printf("%5d wide",widest); + } + if (filename) + printf("\t%s", filename); + printf("\n"); +} + +void count(FILE *fp, char *filename) { + register int c, inword = 0, pos, widest, pages; + long lines = 0; + long words = 0; + long bytes = 0; + + widest = pos = 0; + pages = 1; + while((c = getc(fp)) != EOF) { + ++bytes; + if (bflag) + continue; + if (isspace(c)) { + inword = 0; + if (c == '\n') { + if (pos > widest) + widest = pos; + ++lines; + pos = 0; + } + else if (pflag && c == '\f') { + ++pages; + pos = 0; + } + else if (pflag && c == '\t') { + int i = 8 - ((pos + 8) & 7); + pos += i; + bytes += i-1; + } + else ++pos; + } + else if (!inword) { + ++inword; + ++words; + ++pos; + } + else ++pos; + } + if (lines == 0) { + lines = 1; + widest = (int)bytes; + } + twords += words; + tlines += lines; + tbytes += bytes; + tpages += pages; + if (twidest < widest) + twidest = widest; + output(lines, words, bytes, widest, pages, filename); +} + +void main(int argc, char *argv[]) { + FILE *fp; + char c, *p; + int i, nfiles; + + bflag = wflag = pflag = 0; + for (nfiles = 0, i = 1; i < argc; ++i) { + p = argv[i]; + if (*p == '-') { + argv[i] = NULL; + while ((c = *(++p)) != 0) { + switch(c) { + case '?': + case 'h': + help(); + case 'b': ++bflag; break; + case 'w': ++wflag; break; + case 'p': ++pflag; break; + default: + error("Bad switch",p-1); + } + } + } + else ++nfiles; + } + + twords = tlines = tbytes = 0; + tpages = 0; + if (nfiles == 0) + count(stdin, NULL); + else { + for (nfiles = 0, i = 1; i < argc; ++i) { + if ((p = argv[i]) == NULL) + continue; + if ((fp = fopen(p, bflag ? "rb" : "r")) == NULL) + perror(p); + else { + ++nfiles; + setvbuf(fp,NULL,_IOFBF,BUFSIZE*10); + count(fp, p); + fclose(fp); + } + } + } + if (nfiles > 1) + output(tlines, twords, tbytes, twidest, tpages, "=total="); +} + \ No newline at end of file diff --git a/src/simple/which.c b/src/simple/which.c new file mode 100755 index 00000000..a06e1a14 --- /dev/null +++ b/src/simple/which.c @@ -0,0 +1,79 @@ +/* which - search paths for executable */ + +#define DELIMITER ':' + +#include +#include +#include +#include +#include + +int main(ac, av) +int ac; +char **av; +{ + char *path, *cp; + char buf[400]; + char prog[400]; + char patbuf[512]; + int quit, none; + int excode = 0; + + if (ac < 2) { + fprintf(stderr, "usage: %s cmd [cmd ...]\n", *av); + exit(1); + } + av[ac] = 0; + for (av++; *av; av++) { + + quit = 0; + none = 1; + if ((path = getenv("PATH")) == NULL) { + fprintf(stderr, "Null path.\n"); + exit(0); + } + strcpy(patbuf, path); + path = patbuf; + cp = path; + + while (1) { + cp = strchr(path, DELIMITER); + if (cp == NULL) + quit++; + else + *cp = '\0'; + + if (strcmp(path, "") == 0 && quit == 0) { + sprintf(buf, "%s./%s", path, *av); + } else + sprintf(buf, "%s/%s", path, *av); + + /* Fprintf(stderr,"Trying %s, path %s\n",buf,path); */ + + path = ++cp; + + if (access(buf, 1) == 0) { + printf("%s\n", buf); + none = 0; + } + sprintf(prog, "%s.%s", buf, "a"); + if (access(prog, 1) == 0) { + printf("%s\n", prog); + none = 0; + } + sprintf(prog, "%s.%s", buf, "out"); + if (access(prog, 1) == 0) { + printf("%s\n", prog); + none = 0; + } + if (quit) { + if (none) { + fprintf(stderr, "No %s in %s\n", *av, getenv("PATH")); + excode = 1; + } + break; + } + } + } + return(excode); +} diff --git a/src/simple/whoami.c b/src/simple/whoami.c new file mode 100755 index 00000000..593cd9f3 --- /dev/null +++ b/src/simple/whoami.c @@ -0,0 +1,20 @@ +#include +#include +#include + +void +main (void) +{ + register struct passwd *pw; + register int uid; + + uid = getuid (); + pw = getpwuid (uid); + if (pw) + { + write(STDOUT_FILENO,pw->pw_name,strlen(pw->pw_name)); + write(STDOUT_FILENO,"\n",1); + exit (0); + } + exit (1); +} diff --git a/src/simple/yes.c b/src/simple/yes.c new file mode 100755 index 00000000..60c469be --- /dev/null +++ b/src/simple/yes.c @@ -0,0 +1,21 @@ +#include +#include + +void +main (argc, argv) + int argc; + char **argv; +{ + if (argc == 1) + while (1) + write(STDOUT_FILENO,"y\n",2); + + while (1) { + int i; + for (i = 1; i < argc; i++) { + write(STDOUT_FILENO,argv[i], strlen(argv[i])); + write(STDOUT_FILENO,i == argc - 1 ? "\n" : " ",1); + } + } + +} diff --git a/src/troff/README b/src/troff/README new file mode 100755 index 00000000..cadbf3f5 --- /dev/null +++ b/src/troff/README @@ -0,0 +1,18 @@ +The version of [nt]roff in this directory +is changed somewhat from the version you +may be used to. + +1. fonts are in /usr/lib/font/ftXX, +where XX is the name of the font (e.g., HI). +Source is in ./font/ftXX.c. + +2. macro files like -ms are searched for in +/usr/lib/tmac/tmac.xxx. +Your /usr/lib/tmac may have to be changed. +The .so request has been modified to make it a +fatal error to try .so non-existent-file; +this should head off people who are explcitly +including /usr/lib/tmac.s, etc. + +3. terminal driving tables for nroff are +in /usr/lib/term/tabxxx instead of /usr/lib/term/xxx. diff --git a/src/troff/d.h b/src/troff/d.h new file mode 100755 index 00000000..fa8530dc --- /dev/null +++ b/src/troff/d.h @@ -0,0 +1,2 @@ +struct s_di {filep op; int dnl,dimac,ditrap,ditf,alss,blss,nls,mkline, + maxl,hnl,curd;} di[NDI], *dip; /* Nick d */ diff --git a/src/troff/font/chars.c b/src/troff/font/chars.c new file mode 100755 index 00000000..60ebe023 --- /dev/null +++ b/src/troff/font/chars.c @@ -0,0 +1,22 @@ +extern char codetab[]; +extern int chtab[]; + +main(){ + register i,j,k; + + for(i=040; i<(256); i++){ + j = codetab[i-040] & 0377; + if(j & 0200)for(k=0; chtab[k] != 0; k =+ 2){ + if(chtab[k+1] == i){ + printf("%o \\(%c%c\n", + j, + chtab[k] & 0377, + chtab[k]>>8 & 0377); + break; + }else if(i < 0177){ + printf("%o %c\n",j,i & 0177); + break; + } + } + } +} diff --git a/src/troff/font/ftB.c b/src/troff/font/ftB.c new file mode 100755 index 00000000..66f951b5 --- /dev/null +++ b/src/troff/font/ftB.c @@ -0,0 +1,136 @@ +/*modified for Commercial II*/ +char Bw[256-32] { /*Times Bold widths*/ +12, /*space*/ +13, /*!*/ +0, /*"*/ +0, /*#*/ +18, /*$*/ +28, /*%*/ +27, /*&*/ +12, /*' close*/ +16, /*(*/ +16, /*)*/ +18, /***/ +36, /*+*/ +12, /*,*/ +14, /*- hyphen*/ +12, /*.*/ +18, /*/*/ +19+0200, /*0*/ +19+0200, /*1*/ +19+0200, /*2*/ +19+0200, /*3*/ +19+0200, /*4*/ +19+0200, /*5*/ +19+0200, /*6*/ +19+0200, /*7*/ +19+0200, /*8*/ +19+0200, /*9*/ +13, /*:*/ +13, /*;*/ +0, /*<*/ +36, /*=*/ +0, /*>*/ +22, /*?*/ +0, /*@*/ +28+0200, /*A*/ +26+0200, /*B*/ +26+0200, /*C*/ +29+0200, /*D*/ +25+0200, /*E*/ +23+0200, /*F*/ +28+0200, /*G*/ +32+0200, /*H*/ +16+0200, /*I*/ +21+0200, /*J*/ +28+0200, /*K*/ +25+0200, /*L*/ +36+0200, /*M*/ +30+0200, /*N*/ +29+0200, /*O*/ +25+0200, /*P*/ +29+0300, /*Q*/ +28+0200, /*R*/ +23+0200, /*S*/ +25+0200, /*T*/ +29+0200, /*U*/ +27+0200, /*V*/ +36+0200, /*W*/ +27+0200, /*X*/ +28+0200, /*Y*/ +27+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +12, /*` open*/ +19, /*a*/ +19+0200, /*b*/ +16, /*c*/ +19+0200, /*d*/ +17, /*e*/ +13+0200, /*f*/ +18+0100, /*g*/ +22+0200, /*h*/ +12+0200, /*i*/ +12+0300, /*j*/ +23+0200, /*k*/ +12+0200, /*l*/ +32, /*m*/ +22, /*n*/ +18, /*o*/ +20+0100, /*p*/ +19+0100, /*q*/ +15, /*r*/ +17, /*s*/ +13+0200, /*t*/ +21, /*u*/ +19, /*v*/ +27, /*w*/ +21, /*x*/ +19+0100, /*y*/ +17, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +14, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +28, /*1/4*/ +28, /*1/2*/ +28, /*3/4*/ +36, /*minus*/ +22, /*fi*/ +22, /*fl*/ +23, /*ff*/ +33, /*ffi*/ +33, /*ffl*/ +15, /*degree*/ +20, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +0, +19, /*cent*/ +}; diff --git a/src/troff/font/ftBC.c b/src/troff/font/ftBC.c new file mode 100755 index 00000000..8c2c97f0 --- /dev/null +++ b/src/troff/font/ftBC.c @@ -0,0 +1,137 @@ +char XXw[256-32] { /*XX*/ +12, /*space*/ +11, /*!*/ +0, /*"*/ +0, /*#*/ +15, /*$*/ +19, /*%*/ +19, /*&*/ +7, /*' close*/ +8, /*(*/ +8, /*)*/ +14, /***/ +27, /*+*/ +7, /*,*/ +11, /*- hyphen*/ +7, /*.*/ +14, /*/*/ +15+0200, /*0*/ +15+0200, /*1*/ +15+0200, /*2*/ +15+0200, /*3*/ +15+0200, /*4*/ +15+0200, /*5*/ +15+0200, /*6*/ +15+0200, /*7*/ +15+0200, /*8*/ +15+0200, /*9*/ +11, /*:*/ +11, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +17, /*?*/ +0, /*@*/ +16+0200, /*A*/ +16+0200, /*B*/ +16+0200, /*C*/ +17+0200, /*D*/ +13+0200, /*E*/ +13+0200, /*F*/ +17+0200, /*G*/ +17+0200, /*H*/ +8+0200, /*I*/ +13+0200, /*J*/ +15+0200, /*K*/ +13+0200, /*L*/ +24+0200, /*M*/ +18+0200, /*N*/ +17+0200, /*O*/ +15+0200, /*P*/ +17+0300, /*Q*/ +16+0200, /*R*/ +15+0200, /*S*/ +14+0200, /*T*/ +17+0200, /*U*/ +15+0200, /*V*/ +23+0200, /*W*/ +15+0200, /*X*/ +14+0200, /*Y*/ +13+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +7, /*` open*/ +13, /*a*/ +13+0200, /*b*/ +12, /*c*/ +13+0200, /*d*/ +13, /*e*/ +9+0200, /*f*/ +13+0100, /*g*/ +13+0200, /*h*/ +7+0200, /*i*/ +7+0300, /*j*/ +12+0200, /*k*/ +7+0200, /*l*/ +20, /*m*/ +13, /*n*/ +13, /*o*/ +13+0100, /*p*/ +13+0100, /*q*/ +8, /*r*/ +11, /*s*/ +8+0200, /*t*/ +13, /*u*/ +11, /*v*/ +19, /*w*/ +10, /*x*/ +12+0100, /*y*/ +9, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +11, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +19, /*1/4*/ +19, /*1/2*/ +19, /*3/4*/ +27, /*minus*/ +17, /*fi*/ +17, /*fl*/ +18, /*ff*/ +26, /*ffi*/ +26, /*ffl*/ +13, /*degree*/ +17, /*dagger*/ +0, /*section*/ +10, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0,3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +0, +15, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftC.c b/src/troff/font/ftC.c new file mode 100755 index 00000000..c3169780 --- /dev/null +++ b/src/troff/font/ftC.c @@ -0,0 +1,137 @@ +char Cw[256-32] { /*Comm I news Condensed made to look like II*/ +12, /*space*/ +8, /*!*/ +0, /*"*/ +0, /*#*/ +16, /*$*/ +24, /*%*/ +23, /*&*/ +8, /*' close*/ +11, /*(*/ +11, /*)*/ +14, /***/ +27, /*+*/ +8, /*,*/ +10, /*- hyphen*/ +8, /*.*/ +18, /*/*/ +16+0200, /*0*/ +16+0200, /*1*/ +16+0200, /*2*/ +16+0200, /*3*/ +16+0200, /*4*/ +16+0200, /*5*/ +16+0200, /*6*/ +16+0200, /*7*/ +16+0200, /*8*/ +16+0200, /*9*/ +8, /*:*/ +8, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +14, /*?*/ +0, /*@*/ +19+0200, /*A*/ +17+0200, /*B*/ +17+0200, /*C*/ +17+0200, /*D*/ +15+0200, /*E*/ +15+0200, /*F*/ +18+0200, /*G*/ +17+0200, /*H*/ +8+0200, /*I*/ +13+0200, /*J*/ +17+0200, /*K*/ +15+0200, /*L*/ +22+0200, /*M*/ +18+0200, /*N*/ +18+0200, /*O*/ +16+0200, /*P*/ +18+0300, /*Q*/ +17+0200, /*R*/ +17+0200, /*S*/ +17+0200, /*T*/ +17+0200, /*U*/ +17+0200, /*V*/ +24+0200, /*W*/ +16+0200, /*X*/ +17+0200, /*Y*/ +15+0200, /*Z*/ +10, /*[*/ +0, /*\*/ +10, /*]*/ +0, /*^*/ +0, /*_*/ +8, /*` open*/ +14, /*a*/ +15+0200, /*b*/ +14, /*c*/ +15+0200, /*d*/ +14, /*e*/ +11+0200, /*f*/ +14+0100, /*g*/ +14+0200, /*h*/ +8+0200, /*i*/ +8+0300, /*j*/ +14+0200, /*k*/ +8+0200, /*l*/ +22, /*m*/ +14, /*n*/ +15, /*o*/ +15+0100, /*p*/ +15+0100, /*q*/ +10, /*r*/ +14, /*s*/ +12+0200, /*t*/ +14, /*u*/ +14, /*v*/ +20, /*w*/ +13, /*x*/ +14+0100, /*y*/ +12, /*z*/ +0, /*{*/ +5, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +10, /*hyphen*/ +27, /*bullet*/ +36, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +24, /*1/4*/ +24, /*1/2*/ +24, /*3/4*/ +27, /*minus*/ +18, /*fi*/ +18, /*fl*/ +20, /*ff*/ +18, /*ffi*/ +19, /*ffl*/ +15, /*degree*/ +19, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0,3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +0, /*registered*/ +0, /*copywrite*/ +0, +0, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftCE.c b/src/troff/font/ftCE.c new file mode 100755 index 00000000..1f0bf1e3 --- /dev/null +++ b/src/troff/font/ftCE.c @@ -0,0 +1,136 @@ +/*modified for Commercial II*/ +char CEw[256-32] { /*Century Expanded widths*/ +12, /*space*/ +13, /*!*/ +0, /*"*/ +20, /*#*/ +18, /*$*/ +24, /*%*/ +27, /*&*/ +9, /*' close*/ +15, /*(*/ +15, /*)*/ +16, /***/ +27, /*+*/ +9, /*,*/ +14, /*- hyphen*/ +9, /*.*/ +12, /*/*/ +18+0200, /*0*/ +18+0200, /*1*/ +18+0200, /*2*/ +18+0200, /*3*/ +18+0200, /*4*/ +18+0200, /*5*/ +18+0200, /*6*/ +18+0200, /*7*/ +18+0200, /*8*/ +18+0200, /*9*/ +13, /*:*/ +13, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +19, /*?*/ +30, /*@*/ +28+0200, /*A*/ +25+0200, /*B*/ +25+0200, /*C*/ +27+0200, /*D*/ +26+0200, /*E*/ +25+0200, /*F*/ +26+0200, /*G*/ +29+0200, /*H*/ +15+0200, /*I*/ +20+0200, /*J*/ +28+0200, /*K*/ +25+0200, /*L*/ +32+0200, /*M*/ +29+0200, /*N*/ +25+0200, /*O*/ +24+0200, /*P*/ +26+0300, /*Q*/ +26+0200, /*R*/ +22+0200, /*S*/ +24+0200, /*T*/ +28+0200, /*U*/ +28+0200, /*V*/ +36+0200, /*W*/ +27+0200, /*X*/ +27+0200, /*Y*/ +24+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +9, /*` open*/ +18, /*a*/ +19+0200, /*b*/ +16, /*c*/ +19+0200, /*d*/ +17, /*e*/ +13+0200, /*f*/ +20+0100, /*g*/ +19+0200, /*h*/ +10+0200, /*i*/ +12+0300, /*j*/ +20+0200, /*k*/ +10+0200, /*l*/ +29, /*m*/ +19, /*n*/ +17, /*o*/ +19+0100, /*p*/ +19+0100, /*q*/ +16, /*r*/ +15, /*s*/ +14+0200, /*t*/ +19, /*u*/ +19, /*v*/ +27, /*w*/ +19, /*x*/ +20+0100, /*y*/ +17, /*z*/ +0, /*{*/ +5, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +14, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +24, /*1/4*/ +24, /*1/2*/ +24, /*3/4*/ +27, /*minus*/ +20, /*fi*/ +20, /*fl*/ +22, /*ff*/ +30, /*ffi*/ +30, /*ffl*/ +13, /*degree*/ +18, /*dagger*/ +0, /*section*/ +8, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +0, +18, /*cent*/ +}; diff --git a/src/troff/font/ftCI.c b/src/troff/font/ftCI.c new file mode 100755 index 00000000..8be978ce --- /dev/null +++ b/src/troff/font/ftCI.c @@ -0,0 +1,140 @@ +/* + * Century Schoolbook Italic-- Commercial II; name CI + */ +char XXw[256-32] { /*XX*/ +12, /*space*/ +14, /*!*/ +0, /*"*/ +0, /*#*/ +20, /*$*/ +22, /*%*/ +32, /*&*/ +9, /*' close*/ +14, /*(*/ +14, /*)*/ +18, /***/ +27, /*+*/ +9, /*,*/ +12, /*- hyphen*/ +9, /*.*/ +10, /*/*/ +20+0200, /*0*/ +20+0200, /*1*/ +20+0200, /*2*/ +20+0200, /*3*/ +20+0200, /*4*/ +20+0200, /*5*/ +20+0200, /*6*/ +20+0200, /*7*/ +20+0200, /*8*/ +20+0200, /*9*/ +12, /*:*/ +12, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +21, /*?*/ +0, /*@*/ +27+0200, /*A*/ +25+0200, /*B*/ +24+0200, /*C*/ +28+0200, /*D*/ +26+0200, /*E*/ +23+0200, /*F*/ +27+0200, /*G*/ +29+0200, /*H*/ +14+0200, /*I*/ +20+0200, /*J*/ +27+0200, /*K*/ +25+0200, /*L*/ +32+0200, /*M*/ +28+0200, /*N*/ +26+0200, /*O*/ +23+0200, /*P*/ +26+0300, /*Q*/ +27+0200, /*R*/ +21+0200, /*S*/ +24+0200, /*T*/ +28+0200, /*U*/ +27+0200, /*V*/ +34+0200, /*W*/ +26+0200, /*X*/ +27+0200, /*Y*/ +22+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +9, /*` open*/ +20, /*a*/ +20+0200, /*b*/ +16, /*c*/ +22+0200, /*d*/ +16, /*e*/ +12+0200, /*f*/ +18+0100, /*g*/ +21+0200, /*h*/ +11+0200, /*i*/ +11+0300, /*j*/ +20+0200, /*k*/ +12+0200, /*l*/ +31, /*m*/ +21, /*n*/ +18, /*o*/ +20+0100, /*p*/ +18+0100, /*q*/ +16, /*r*/ +15, /*s*/ +12+0200, /*t*/ +21, /*u*/ +18, /*v*/ +27, /*w*/ +18, /*x*/ +17+0100, /*y*/ +15, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +12, /*hyphen*/ +27, /*bullet*/ +36, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +30, /*1/4*/ +30, /*1/2*/ +30, /*3/4*/ +27, /*minus*/ +21, /*fi*/ +21, /*fl*/ +21, /*ff*/ +29, /*ffi*/ +29, /*ffl*/ +16, /*degree*/ +19, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0,3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +21, /*registered*/ +21, /*copywrite*/ +0, +20, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftCK.c b/src/troff/font/ftCK.c new file mode 100755 index 00000000..ffb0ffa2 --- /dev/null +++ b/src/troff/font/ftCK.c @@ -0,0 +1,136 @@ +/*modified for Commercial II*/ +char CKw[256-32] { /*Century Bold Italic widths (CK)*/ +12, /*space*/ +14, /*!*/ +0, /*"*/ +0, /*#*/ +19, /*$*/ +31, /*%*/ +30, /*&*/ +10, /*' close*/ +18, /*(*/ +18, /*)*/ +18, /***/ +27, /*+*/ +10, /*,*/ +14, /*- hyphen*/ +10, /*.*/ +11, /*/*/ +19+0200, /*0*/ +19+0200, /*1*/ +19+0200, /*2*/ +19+0200, /*3*/ +19+0200, /*4*/ +19+0200, /*5*/ +19+0200, /*6*/ +19+0200, /*7*/ +19+0200, /*8*/ +19+0200, /*9*/ +13, /*:*/ +13, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +21, /*?*/ +0, /*@*/ +27+0200, /*A*/ +27+0200, /*B*/ +25+0200, /*C*/ +28+0200, /*D*/ +26+0200, /*E*/ +24+0200, /*F*/ +27+0200, /*G*/ +29+0200, /*H*/ +15+0200, /*I*/ +20+0200, /*J*/ +29+0200, /*K*/ +25+0200, /*L*/ +31+0200, /*M*/ +27+0200, /*N*/ +27+0200, /*O*/ +26+0200, /*P*/ +28+0300, /*Q*/ +29+0200, /*R*/ +22+0200, /*S*/ +25+0200, /*T*/ +28+0200, /*U*/ +25+0200, /*V*/ +35+0200, /*W*/ +26+0200, /*X*/ +27+0200, /*Y*/ +24+0200, /*Z*/ +14, /*[*/ +0, /*\*/ +14, /*]*/ +0, /*^*/ +0, /*_*/ +10, /*` open*/ +21, /*a*/ +19+0200, /*b*/ +18, /*c*/ +20+0200, /*d*/ +18, /*e*/ +14+0200, /*f*/ +19+0100, /*g*/ +21+0200, /*h*/ +12+0200, /*i*/ +13+0300, /*j*/ +21+0200, /*k*/ +13+0200, /*l*/ +30, /*m*/ +21, /*n*/ +19, /*o*/ +20+0100, /*p*/ +20+0100, /*q*/ +15, /*r*/ +16, /*s*/ +14+0200, /*t*/ +21, /*u*/ +19, /*v*/ +27, /*w*/ +22, /*x*/ +20+0100, /*y*/ +17, /*z*/ +0, /*{*/ +5, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +14, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +31, /*1/4*/ +31, /*1/2*/ +31, /*3/4*/ +27, /*minus*/ +23, /*fi*/ +23, /*fl*/ +22, /*ff*/ +19, /*en*/ +33, /*paragraph*/ +15, /*degree*/ +19, /*dagger*/ +0, /*section*/ +8, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +23, /*registered*/ +23, /*copywrite*/ +0, +19, /*cent*/ +}; diff --git a/src/troff/font/ftCS.c b/src/troff/font/ftCS.c new file mode 100755 index 00000000..e297c6d5 --- /dev/null +++ b/src/troff/font/ftCS.c @@ -0,0 +1,140 @@ +/* + * Century schoolbook -- Commercial II layout; name CS + */ +char XXw[256-32] { /*XX*/ +12, /*space*/ +13, /*!*/ +0, /*"*/ +0, /*#*/ +20, /*$*/ +26, /*%*/ +31, /*&*/ +9, /*' close*/ +14, /*(*/ +14, /*)*/ +19, /***/ +27, /*+*/ +9, /*,*/ +12, /*- hyphen*/ +9, /*.*/ +13, /*/*/ +20+0200, /*0*/ +20+0200, /*1*/ +20+0200, /*2*/ +20+0200, /*3*/ +20+0200, /*4*/ +20+0200, /*5*/ +20+0200, /*6*/ +20+0200, /*7*/ +20+0200, /*8*/ +20+0200, /*9*/ +13, /*:*/ +13, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +22, /*?*/ +0, /*@*/ +28+0200, /*A*/ +26+0200, /*B*/ +24+0200, /*C*/ +28+0200, /*D*/ +26+0200, /*E*/ +24+0200, /*F*/ +28+0200, /*G*/ +30+0200, /*H*/ +15+0200, /*I*/ +21+0200, /*J*/ +29+0200, /*K*/ +24+0200, /*L*/ +34+0200, /*M*/ +30+0200, /*N*/ +27+0200, /*O*/ +25+0200, /*P*/ +27+0300, /*Q*/ +27+0200, /*R*/ +22+0200, /*S*/ +24+0200, /*T*/ +30+0200, /*U*/ +28+0200, /*V*/ +36+0200, /*W*/ +27+0200, /*X*/ +27+0200, /*Y*/ +22+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +9, /*` open*/ +20, /*a*/ +20+0200, /*b*/ +17, /*c*/ +20+0200, /*d*/ +18, /*e*/ +14+0200, /*f*/ +21+0100, /*g*/ +22+0200, /*h*/ +12+0200, /*i*/ +14+0300, /*j*/ +22+0200, /*k*/ +12+0200, /*l*/ +32, /*m*/ +22, /*n*/ +18, /*o*/ +20+0100, /*p*/ +20+0100, /*q*/ +16, /*r*/ +16, /*s*/ +15+0200, /*t*/ +22, /*u*/ +20, /*v*/ +28, /*w*/ +20, /*x*/ +20+0100, /*y*/ +17, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +12, /*hyphen*/ +27, /*bullet*/ +36, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +30, /*1/4*/ +30, /*1/2*/ +30, /*3/4*/ +27, /*minus*/ +22, /*fi*/ +22, /*fl*/ +24, /*ff*/ +32, /*ffi*/ +32, /*ffl*/ +16, /*degree*/ +19, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0,3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +0, +20, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftCW.c b/src/troff/font/ftCW.c new file mode 100755 index 00000000..9b0da351 --- /dev/null +++ b/src/troff/font/ftCW.c @@ -0,0 +1,137 @@ +char XXw[256-32] { /*XX*/ +25, /*space*/ +25, /*!*/ +0, /*"*/ +0, /*#*/ +25, /*$*/ +25, /*%*/ +25, /*&*/ +25, /*' close*/ +25, /*(*/ +25, /*)*/ +25, /***/ +25, /*+*/ +25, /*,*/ +25, /*- hyphen*/ +25, /*.*/ +25, /*/*/ +25+0200, /*0*/ +25+0200, /*1*/ +25+0200, /*2*/ +25+0200, /*3*/ +25+0200, /*4*/ +25+0200, /*5*/ +25+0200, /*6*/ +25+0200, /*7*/ +25+0200, /*8*/ +25+0200, /*9*/ +25, /*:*/ +25, /*;*/ +0, /*<*/ +25, /*=*/ +0, /*>*/ +25, /*?*/ +0, /*@*/ +25+0200, /*A*/ +25+0200, /*B*/ +25+0200, /*C*/ +25+0200, /*D*/ +25+0200, /*E*/ +25+0200, /*F*/ +25+0200, /*G*/ +25+0200, /*H*/ +25+0200, /*I*/ +25+0200, /*J*/ +25+0200, /*K*/ +25+0200, /*L*/ +25+0200, /*M*/ +25+0200, /*N*/ +25+0200, /*O*/ +25+0200, /*P*/ +25+0300, /*Q*/ +25+0200, /*R*/ +25+0200, /*S*/ +25+0200, /*T*/ +25+0200, /*U*/ +25+0200, /*V*/ +25+0200, /*W*/ +25+0200, /*X*/ +25+0200, /*Y*/ +25+0200, /*Z*/ +25, /*[*/ +0, /*\*/ +25, /*]*/ +0, /*^*/ +0, /*_*/ +25, /*` open*/ +25, /*a*/ +25+0200, /*b*/ +25, /*c*/ +25+0200, /*d*/ +25, /*e*/ +25+0200, /*f*/ +25+0100, /*g*/ +25+0200, /*h*/ +25+0200, /*i*/ +25+0300, /*j*/ +25+0200, /*k*/ +25+0200, /*l*/ +25, /*m*/ +25, /*n*/ +25, /*o*/ +25+0100, /*p*/ +25+0100, /*q*/ +25, /*r*/ +25, /*s*/ +25+0200, /*t*/ +25, /*u*/ +25, /*v*/ +25, /*w*/ +25, /*x*/ +25+0100, /*y*/ +25, /*z*/ +0, /*{*/ +25, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +25, /*hyphen*/ +25, /*bullet*/ +25, /*square*/ +25, /*3/4 em*/ +25, /*rule*/ +25, /*1/4*/ +25, /*1/2*/ +25, /*3/4*/ +25, /*minus*/ +25, /*fi*/ +25, /*fl*/ +25, /*ff*/ +25, /*ffi*/ +25, /*ffl*/ +25, /*degree*/ +25, /*dagger*/ +0, /*section*/ +25, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0,3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +25, /*registered*/ +25, /*copywrite*/ +0, +25, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftG.c b/src/troff/font/ftG.c new file mode 100755 index 00000000..b9153e5e --- /dev/null +++ b/src/troff/font/ftG.c @@ -0,0 +1,136 @@ +/*modified for Commercial II*/ +char Gw[256-32] { /*Geneva Regular widths*/ +12, /*space*/ +12, /*!*/ +0, /*"*/ +0, /*#*/ +23, /*$*/ +28, /*%*/ +25, /*&*/ +9, /*' close*/ +13, /*(*/ +13, /*)*/ +16, /***/ +36, /*+*/ +8, /*,*/ +15, /*- hyphen*/ +8, /*.*/ +15, /*/*/ +23+0200, /*0*/ +23+0200, /*1*/ +23+0200, /*2*/ +23+0200, /*3*/ +23+0200, /*4*/ +23+0200, /*5*/ +23+0200, /*6*/ +23+0200, /*7*/ +23+0200, /*8*/ +23+0200, /*9*/ +12, /*:*/ +12, /*;*/ +0, /*<*/ +36, /*=*/ +0, /*>*/ +25, /*?*/ +0, /*@*/ +25+0200, /*A*/ +26+0200, /*B*/ +27+0200, /*C*/ +26+0200, /*D*/ +24+0200, /*E*/ +22+0200, /*F*/ +29+0200, /*G*/ +27+0200, /*H*/ +11+0200, /*I*/ +20+0200, /*J*/ +26+0200, /*K*/ +22+0200, /*L*/ +32+0200, /*M*/ +27+0200, /*N*/ +29+0200, /*O*/ +24+0200, /*P*/ +29+0300, /*Q*/ +26+0200, /*R*/ +25+0200, /*S*/ +23+0200, /*T*/ +27+0200, /*U*/ +24+0200, /*V*/ +35+0200, /*W*/ +25+0200, /*X*/ +26+0200, /*Y*/ +23+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +9, /*` open*/ +21, /*a*/ +22+0200, /*b*/ +21, /*c*/ +22+0200, /*d*/ +21, /*e*/ +12+0200, /*f*/ +21+0100, /*g*/ +22+0200, /*h*/ +10+0200, /*i*/ +10+0300, /*j*/ +21+0200, /*k*/ +10+0200, /*l*/ +31, /*m*/ +22, /*n*/ +21, /*o*/ +22+0100, /*p*/ +22+0100, /*q*/ +14, /*r*/ +20, /*s*/ +12+0200, /*t*/ +22, /*u*/ +19, /*v*/ +28, /*w*/ +20, /*x*/ +20+0100, /*y*/ +18, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +15, /*hyphen*/ +27, /*bullet*/ +36, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +30, /*1/4*/ +30, /*1/2*/ +30, /*3/4*/ +36, /*minus*/ +22, /*fi*/ +22, /*fl*/ +24, /*ff*/ +34, /*ffi*/ +34, /*ffl*/ +14, /*degree*/ +20, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +21, /*registered*/ +21, /*copywrite*/ +0, +23, /*cent*/ +}; diff --git a/src/troff/font/ftGI.c b/src/troff/font/ftGI.c new file mode 100755 index 00000000..39d69d74 --- /dev/null +++ b/src/troff/font/ftGI.c @@ -0,0 +1,135 @@ +char W10[256-32] { /*Genevia Regular Italic (GI) widths #803-033B*/ +13, /*space*/ +13, /*!*/ +0, /*"*/ +0, /*#*/ +23, /*$*/ +30, /*%*/ +26, /*&*/ +9, /*' close*/ +13, /*(*/ +13, /*)*/ +15, /***/ +36, /*+*/ +8, /*,*/ +14, /*- hyphen*/ +8, /*.*/ +11, /*/*/ +23+0200, /*0*/ +23+0200, /*1*/ +23+0200, /*2*/ +23+0200, /*3*/ +23+0200, /*4*/ +23+0200, /*5*/ +23+0200, /*6*/ +23+0200, /*7*/ +23+0200, /*8*/ +23+0200, /*9*/ +12, /*:*/ +12, /*;*/ +0, /*<*/ +36, /*=*/ +0, /*>*/ +24, /*?*/ +0, /*@*/ +25+0200, /*A*/ +25+0200, /*B*/ +28+0200, /*C*/ +26+0200, /*D*/ +23+0200, /*E*/ +21+0200, /*F*/ +29+0200, /*G*/ +26+0200, /*H*/ +11+0200, /*I*/ +20+0200, /*J*/ +25+0200, /*K*/ +22+0200, /*L*/ +31+0200, /*M*/ +27+0200, /*N*/ +29+0200, /*O*/ +23+0200, /*P*/ +29+0300, /*Q*/ +26+0200, /*R*/ +25+0200, /*S*/ +22+0200, /*T*/ +26+0200, /*U*/ +24+0200, /*V*/ +33+0200, /*W*/ +25+0200, /*X*/ +24+0200, /*Y*/ +23+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +9, /*` open*/ +21, /*a*/ +22+0200, /*b*/ +21, /*c*/ +22+0200, /*d*/ +21, /*e*/ +12+0200, /*f*/ +22+0100, /*g*/ +22+0200, /*h*/ +10+0200, /*i*/ +10+0300, /*j*/ +20+0200, /*k*/ +10+0200, /*l*/ +32, /*m*/ +22, /*n*/ +22, /*o*/ +22+0100, /*p*/ +22+0100, /*q*/ +13, /*r*/ +20, /*s*/ +12+0200, /*t*/ +22, /*u*/ +19, /*v*/ +28, /*w*/ +20, /*x*/ +19+0100, /*y*/ +18, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +14, /*hyphen*/ +27, /*bullet*/ +36, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +30, /*1/4*/ +30, /*1/2*/ +30, /*3/4*/ +36, /*minus*/ +22, /*fi*/ +22, /*fl*/ +24, /*ff*/ +34, /*ffi*/ +34, /*ffl*/ +14, /*degree*/ +20, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +21, /*registered*/ +21, /*copywrite*/ +0, +23, /*cent*/ +}; diff --git a/src/troff/font/ftGM.c b/src/troff/font/ftGM.c new file mode 100755 index 00000000..2a518ee4 --- /dev/null +++ b/src/troff/font/ftGM.c @@ -0,0 +1,136 @@ +/*Geneva Medium (similar to Helvetica Medium)*/ +char W11[256-32] { /*Geneva Medium widths*/ +14, /*space*/ +14, /*!*/ +0, /*"*/ +0, /*#*/ +25, /*$*/ +29, /*%*/ +27, /*&*/ +10, /*' close*/ +15, /*(*/ +15, /*)*/ +17, /***/ +27, /*+*/ +10, /*,*/ +17, /*- hyphen*/ +10, /*.*/ +17, /*/*/ +25+0200, /*0*/ +25+0200, /*1*/ +25+0200, /*2*/ +25+0200, /*3*/ +25+0200, /*4*/ +25+0200, /*5*/ +25+0200, /*6*/ +25+0200, /*7*/ +25+0200, /*8*/ +25+0200, /*9*/ +14, /*:*/ +14, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +27, /*?*/ +0, /*@*/ +27+0200, /*A*/ +27+0200, /*B*/ +29+0200, /*C*/ +28+0200, /*D*/ +24+0200, /*E*/ +23+0200, /*F*/ +29+0200, /*G*/ +27+0200, /*H*/ +12+0200, /*I*/ +22+0200, /*J*/ +27+0200, /*K*/ +23+0200, /*L*/ +32+0200, /*M*/ +28+0200, /*N*/ +30+0200, /*O*/ +25+0200, /*P*/ +30+0300, /*Q*/ +26+0200, /*R*/ +26+0200, /*S*/ +24+0200, /*T*/ +27+0200, /*U*/ +26+0200, /*V*/ +35+0200, /*W*/ +26+0200, /*X*/ +25+0200, /*Y*/ +25+0200, /*Z*/ +16, /*[*/ +0, /*\*/ +16, /*]*/ +0, /*^*/ +0, /*_*/ +10, /*` open*/ +22, /*a*/ +23+0200, /*b*/ +22, /*c*/ +23+0200, /*d*/ +22, /*e*/ +14+0200, /*f*/ +23+0100, /*g*/ +22+0200, /*h*/ +11+0200, /*i*/ +11+0300, /*j*/ +22+0200, /*k*/ +11+0200, /*l*/ +32, /*m*/ +22, /*n*/ +23, /*o*/ +23+0100, /*p*/ +23+0100, /*q*/ +15, /*r*/ +21, /*s*/ +14+0200, /*t*/ +22, /*u*/ +20, /*v*/ +30, /*w*/ +21, /*x*/ +21+0100, /*y*/ +20, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +7, /*narrow space*/ +17, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +32, /*1/4*/ +32, /*1/2*/ +32, /*3/4*/ +27, /*minus*/ +24, /*fi*/ +24, /*fl*/ +28, /*ff*/ +38, /*ffi*/ +38, /*ffl*/ +14, /*degree*/ +23, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +21, /*registered*/ +21, /*copywrite*/ +0, +25, /*cent*/ +}; diff --git a/src/troff/font/ftGR.c b/src/troff/font/ftGR.c new file mode 100755 index 00000000..5c2656d0 --- /dev/null +++ b/src/troff/font/ftGR.c @@ -0,0 +1,137 @@ +char XXw[256-32] { /*XX*/ +12, /*space*/ +0, /*!*/ +0, /*"*/ +0, /*#*/ +20, /*$*/ +0, /*%*/ +20, /*&*/ +10, /*' close*/ +16, /*(*/ +16, /*)*/ +0, /***/ +0, /*+*/ +10, /*,*/ +15, /*- hyphen*/ +10, /*.*/ +0, /*/*/ +20+0200, /*0*/ +20+0200, /*1*/ +6+0200, /*2*/ +6+0200, /*3*/ +4+0200, /*4*/ +6+0200, /*5*/ +4+0200, /*6*/ +15+0200, /*7*/ +15+0200, /*8*/ +20+0200, /*9*/ +11, /*:*/ +14, /*;*/ +0, /*<*/ +20, /*=*/ +0, /*>*/ +20, /*?*/ +0, /*@*/ +23+0200, /*A*/ +26+0200, /*B*/ +28+0200, /*C*/ +28+0200, /*D*/ +27+0200, /*E*/ +30+0200, /*F*/ +24+0200, /*G*/ +23+0200, /*H*/ +16+0200, /*I*/ +20+0200, /*J*/ +29+0200, /*K*/ +28+0200, /*L*/ +33+0200, /*M*/ +30+0200, /*N*/ +26+0200, /*O*/ +25+0200, /*P*/ +30+0300, /*Q*/ +29+0200, /*R*/ +27+0200, /*S*/ +25+0200, /*T*/ +29+0200, /*U*/ +21+0200, /*V*/ +24+0200, /*W*/ +29+0200, /*X*/ +33+0200, /*Y*/ +25+0200, /*Z*/ +28, /*[*/ +0, /*\*/ +0, /*]*/ +0, /*^*/ +0, /*_*/ +10, /*` open*/ +23, /*a*/ +25+0200, /*b*/ +18, /*c*/ +19+0200, /*d*/ +17, /*e*/ +24+0200, /*f*/ +21+0100, /*g*/ +23+0200, /*h*/ +12+0200, /*i*/ +18+0300, /*j*/ +21+0200, /*k*/ +21+0200, /*l*/ +24, /*m*/ +20, /*n*/ +19, /*o*/ +21+0100, /*p*/ +21+0100, /*q*/ +24, /*r*/ +24, /*s*/ +17+0200, /*t*/ +19, /*u*/ +15, /*v*/ +24, /*w*/ +23, /*x*/ +24+0100, /*y*/ +17, /*z*/ +0, /*{*/ +0, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +15, /*hyphen*/ +0, /*bullet*/ +0, /*square*/ +0, /*3/4 em*/ +38, /*rule*/ +19, /*1/4*/ +16, /*1/2*/ +0, /*3/4*/ +17, /*minus*/ +30, /*fi*/ +29, /*fl*/ +34, /*ff*/ +20, /*ffi*/ +17, /*ffl*/ +0, /*degree*/ +20, /*dagger*/ +0, /*section*/ +10, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0,3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +0, /*registered*/ +0, /*copywrite*/ +0, +20, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftI.c b/src/troff/font/ftI.c new file mode 100755 index 00000000..5aff97b2 --- /dev/null +++ b/src/troff/font/ftI.c @@ -0,0 +1,136 @@ +/*modified for Commercial II*/ +char Iw[256-32] { /*Times Italic widths*/ +12, /*space*/ +13, /*!*/ +0, /*"*/ +0, /*#*/ +19, /*$*/ +27, /*%*/ +26, /*&*/ +11, /*' close*/ +15, /*(*/ +15, /*)*/ +16, /***/ +36, /*+*/ +11, /*,*/ +13, /*- hyphen*/ +11, /*.*/ +9, /*/*/ +19+0200, /*0*/ +19+0200, /*1*/ +19+0200, /*2*/ +19+0200, /*3*/ +19+0200, /*4*/ +19+0200, /*5*/ +19+0200, /*6*/ +19+0200, /*7*/ +19+0200, /*8*/ +19+0200, /*9*/ +11, /*:*/ +11, /*;*/ +0, /*<*/ +36, /*=*/ +0, /*>*/ +20, /*?*/ +0, /*@*/ +25+0200, /*A*/ +24+0200, /*B*/ +26+0200, /*C*/ +27+0200, /*D*/ +23+0200, /*E*/ +21+0200, /*F*/ +27+0200, /*G*/ +29+0200, /*H*/ +14+0200, /*I*/ +16+0200, /*J*/ +28+0200, /*K*/ +24+0200, /*L*/ +34+0200, /*M*/ +27+0200, /*N*/ +27+0200, /*O*/ +22+0200, /*P*/ +27+0300, /*Q*/ +27+0200, /*R*/ +20+0200, /*S*/ +23+0200, /*T*/ +28+0200, /*U*/ +25+0200, /*V*/ +36+0200, /*W*/ +24+0200, /*X*/ +24+0200, /*Y*/ +25+0200, /*Z*/ +13, /*[*/ +0, /*\*/ +13, /*]*/ +0, /*^*/ +0, /*_*/ +11, /*` open*/ +19, /*a*/ +18+0200, /*b*/ +15, /*c*/ +18+0200, /*d*/ +16, /*e*/ +11+0200, /*f*/ +17+0100, /*g*/ +19+0200, /*h*/ +9+0200, /*i*/ +9+0300, /*j*/ +19+0200, /*k*/ +9+0200, /*l*/ +28, /*m*/ +19, /*n*/ +18, /*o*/ +17+0100, /*p*/ +18+0100, /*q*/ +13, /*r*/ +14, /*s*/ +10+0200, /*t*/ +19, /*u*/ +16, /*v*/ +24, /*w*/ +18, /*x*/ +16+0100, /*y*/ +14, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +13, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +27, /*1/4*/ +27, /*1/2*/ +27, /*3/4*/ +36, /*minus*/ +21, /*fi*/ +21, /*fl*/ +21, /*ff*/ +31, /*ffi*/ +31, /*ffl*/ +15, /*degree*/ +19, /*dagger*/ +0, /*section*/ +7, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +0, +19, /*cent*/ +}; diff --git a/src/troff/font/ftL.c b/src/troff/font/ftL.c new file mode 100755 index 00000000..81b2b7ca --- /dev/null +++ b/src/troff/font/ftL.c @@ -0,0 +1,138 @@ +char Lw[256-32] { /*L Geneva Light*/ +12, /*space*/ +11, /*!*/ +0, /*"*/ +0, /*#*/ +21, /*$*/ +27, /*%*/ +25, /*&*/ +7, /*' close*/ +13, /*(*/ +13, /*)*/ +16, /***/ +27, /*+*/ +7, /*,*/ +13, /*- hyphen*/ +7, /*.*/ +10, /*/*/ +21+0200, /*0*/ +21+0200, /*1*/ +21+0200, /*2*/ +21+0200, /*3*/ +21+0200, /*4*/ +21+0200, /*5*/ +21+0200, /*6*/ +21+0200, /*7*/ +21+0200, /*8*/ +21+0200, /*9*/ +11, /*:*/ +11, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +22, /*?*/ +0, /*@*/ +23+0200, /*A*/ +24+0200, /*B*/ +26+0200, /*C*/ +26+0200, /*D*/ +22+0200, /*E*/ +20+0200, /*F*/ +27+0200, /*G*/ +26+0200, /*H*/ +10+0200, /*I*/ +18+0200, /*J*/ +24+0200, /*K*/ +20+0200, /*L*/ +30+0200, /*M*/ +26+0200, /*N*/ +28+0200, /*O*/ +22+0200, /*P*/ +28+0300, /*Q*/ +24+0200, /*R*/ +22+0200, /*S*/ +20+0200, /*T*/ +25+0200, /*U*/ +23+0200, /*V*/ +35+0200, /*W*/ +23+0200, /*X*/ +22+0200, /*Y*/ +22+0200, /*Z*/ +11, /*[*/ +0, /*\*/ +11, /*]*/ +0, /*^*/ +0, /*_*/ +7, /*` open*/ +20, /*a*/ +21+0200, /*b*/ +20, /*c*/ +21+0200, /*d*/ +20, /*e*/ +11+0200, /*f*/ +21+0100, /*g*/ +20+0200, /*h*/ +9+0200, /*i*/ +9+0300, /*j*/ +19+0200, /*k*/ +9+0200, /*l*/ +31, /*m*/ +20, /*n*/ +20, /*o*/ +21+0100, /*p*/ +21+0100, /*q*/ +12, /*r*/ +18, /*s*/ +11+0200, /*t*/ +20, /*u*/ +18, /*v*/ +27, /*w*/ +18, /*x*/ +18+0100, /*y*/ +17, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +13, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +30, /*1/4*/ +30, /*1/2*/ +30, /*3/4*/ +27, /*minus*/ +20, /*fi*/ +20, /*fl*/ +22, /*ff*/ +31, /*ffi*/ +31, /*ffl*/ +14, /*degree*/ +18, /*dagger*/ +0, /*section*/ +8, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +21, /*registered*/ +21, /*copywrite*/ +0, +21, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftLI.c b/src/troff/font/ftLI.c new file mode 100755 index 00000000..70f38e54 --- /dev/null +++ b/src/troff/font/ftLI.c @@ -0,0 +1,138 @@ +char LIw[256-32] { /*LI Geneva Light Italic*/ +12, /*space*/ +12, /*!*/ +0, /*"*/ +0, /*#*/ +21, /*$*/ +27, /*%*/ +26, /*&*/ +7, /*' close*/ +13, /*(*/ +13, /*)*/ +15, /***/ +36, /*+*/ +7, /*,*/ +13, /*- hyphen*/ +7, /*.*/ +7, /*/*/ +21+0200, /*0*/ +21+0200, /*1*/ +21+0200, /*2*/ +21+0200, /*3*/ +21+0200, /*4*/ +21+0200, /*5*/ +21+0200, /*6*/ +21+0200, /*7*/ +21+0200, /*8*/ +21+0200, /*9*/ +11, /*:*/ +11, /*;*/ +0, /*<*/ +36, /*=*/ +0, /*>*/ +24, /*?*/ +0, /*@*/ +24+0200, /*A*/ +25+0200, /*B*/ +27+0200, /*C*/ +26+0200, /*D*/ +22+0200, /*E*/ +20+0200, /*F*/ +28+0200, /*G*/ +26+0200, /*H*/ +10+0200, /*I*/ +19+0200, /*J*/ +25+0200, /*K*/ +21+0200, /*L*/ +30+0200, /*M*/ +26+0200, /*N*/ +28+0200, /*O*/ +23+0200, /*P*/ +28+0300, /*Q*/ +24+0200, /*R*/ +23+0200, /*S*/ +21+0200, /*T*/ +25+0200, /*U*/ +22+0200, /*V*/ +32+0200, /*W*/ +22+0200, /*X*/ +22+0200, /*Y*/ +22+0200, /*Z*/ +11, /*[*/ +0, /*\*/ +11, /*]*/ +0, /*^*/ +0, /*_*/ +7, /*` open*/ +21, /*a*/ +22+0200, /*b*/ +20, /*c*/ +22+0200, /*d*/ +20, /*e*/ +12+0200, /*f*/ +22+0100, /*g*/ +21+0200, /*h*/ +9+0200, /*i*/ +9+0300, /*j*/ +20+0200, /*k*/ +9+0200, /*l*/ +31, /*m*/ +21, /*n*/ +21, /*o*/ +22+0100, /*p*/ +22+0100, /*q*/ +13, /*r*/ +19, /*s*/ +12+0200, /*t*/ +21, /*u*/ +18, /*v*/ +27, /*w*/ +19, /*x*/ +18+0100, /*y*/ +18, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +13, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +27, /*1/4*/ +27, /*1/2*/ +27, /*3/4*/ +36, /*minus*/ +21, /*fi*/ +21, /*fl*/ +24, /*ff*/ +33, /*ffi*/ +33, /*ffl*/ +14, /*degree*/ +20, /*dagger*/ +0, /*section*/ +8, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +21, /*registered*/ +21, /*copywrite*/ +0, +21, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftPA.c b/src/troff/font/ftPA.c new file mode 100755 index 00000000..2984bb34 --- /dev/null +++ b/src/troff/font/ftPA.c @@ -0,0 +1,136 @@ +/*Commercial II*/ +char PAw[256-32] { /*character withs for Palatino 814-007A*/ +12, /*space*/ +12, /*!*/ +0, /*"*/ +0, /*sharp*/ +19, /*$*/ +27, /*%*/ +29, /*&*/ +10, /*' close*/ +14, /*(*/ +14, /*)*/ +16, /***/ +27, /*+*/ +9, /*,*/ +14, /*- hyphen*/ +9, /*.*/ +12, /*/*/ +19+0200, /*0*/ +19+0200, /*1*/ +19+0200, /*2*/ +19+0200, /*3*/ +19+0200, /*4*/ +19+0200, /*5*/ +19+0200, /*6*/ +19+0200, /*7*/ +19+0200, /*8*/ +19+0200, /*9*/ +12, /*:*/ +12, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +20, /*?*/ +0, /*@*/ +28+0200, /*A*/ +21+0200, /*B*/ +25+0200, /*C*/ +28+0200, /*D*/ +21+0200, /*E*/ +20+0200, /*F*/ +27+0200, /*G*/ +30+0200, /*H*/ +12+0200, /*I*/ +12+0200, /*J*/ +27+0200, /*K*/ +22+0200, /*L*/ +34+0200, /*M*/ +30+0200, /*N*/ +29+0200, /*O*/ +22+0200, /*P*/ +29+0300, /*Q*/ +25+0200, /*R*/ +19+0200, /*S*/ +22+0200, /*T*/ +28+0200, /*U*/ +27+0200, /*V*/ +36+0200, /*W*/ +24+0200, /*X*/ +24+0200, /*Y*/ +24+0200, /*Z*/ +13, /*[*/ +0, /*\*/ +13, /*]*/ +0, /*^*/ +0, /*_*/ +10, /*` open*/ +18, /*a*/ +20+0200, /*b*/ +16, /*c*/ +21+0200, /*d*/ +17, /*e*/ +12+0200, /*f*/ +19+0100, /*g*/ +22+0200, /*h*/ +11+0200, /*i*/ +11+0300, /*j*/ +20+0200, /*k*/ +11+0200, /*l*/ +32, /*m*/ +22, /*n*/ +20, /*o*/ +21+0100, /*p*/ +19+0100, /*q*/ +15, /*r*/ +15, /*s*/ +12+0200, /*t*/ +22, /*u*/ +20, /*v*/ +30, /*w*/ +19, /*x*/ +20+0100, /*y*/ +18, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +14, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +27, /*1/4*/ +27, /*1/2*/ +27, /*3/4*/ +27, /*minus*/ +22, /*fi*/ +22, /*fl*/ +23, /*ff*/ +33, /*ffi*/ +33, /*ffl*/ +13, /*degree*/ +22, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +0, +19, /*cent*/ +}; diff --git a/src/troff/font/ftPB.c b/src/troff/font/ftPB.c new file mode 100755 index 00000000..4d62ed50 --- /dev/null +++ b/src/troff/font/ftPB.c @@ -0,0 +1,136 @@ +/*Commercial II*/ +char W14[256-32] { /*character withs for Palatino Bold 814-009A*/ +12, /*space*/ +14, /*!*/ +00, /*"*/ +00, /*sharp*/ +18, /*$*/ +27, /*%*/ +30, /*&*/ +12, /*' close*/ +14, /*(*/ +14, /*)*/ +15, /***/ +27, /*+*/ +12, /*,*/ +15, /*- hyphen*/ +10, /*.*/ +13, /*/*/ +18+0200, /*0*/ +18+0200, /*1*/ +18+0200, /*2*/ +18+0200, /*3*/ +18+0200, /*4*/ +18+0200, /*5*/ +18+0200, /*6*/ +18+0200, /*7*/ +18+0200, /*8*/ +18+0200, /*9*/ +14, /*:*/ +15, /*;*/ +00, /*<*/ +27, /*=*/ +00, /*>*/ +21, /*?*/ +00, /*@*/ +28+0200, /*A*/ +22+0200, /*B*/ +25+0200, /*C*/ +29+0200, /*D*/ +21+0200, /*E*/ +20+0200, /*F*/ +28+0200, /*G*/ +30+0200, /*H*/ +14+0200, /*I*/ +14+0200, /*J*/ +28+0200, /*K*/ +22+0200, /*L*/ +36+0200, /*M*/ +30+0200, /*N*/ +29+0200, /*O*/ +22+0200, /*P*/ +29+0300, /*Q*/ +26+0200, /*R*/ +20+0200, /*S*/ +25+0200, /*T*/ +28+0200, /*U*/ +28+0200, /*V*/ +36+0200, /*W*/ +25+0200, /*X*/ +25+0200, /*Y*/ +23+0200, /*Z*/ +13, /*[*/ +00, /*\*/ +13, /*]*/ +00, /*^*/ +0, /*_*/ +12, /*` open*/ +18, /*a*/ +20+0200, /*b*/ +16, /*c*/ +22+0200, /*d*/ +18, /*e*/ +14+0200, /*f*/ +20+0100, /*g*/ +22+0200, /*h*/ +12+0200, /*i*/ +12+0300, /*j*/ +22+0200, /*k*/ +12+0200, /*l*/ +32, /*m*/ +22, /*n*/ +20, /*o*/ +22+0100, /*p*/ +20+0100, /*q*/ +15, /*r*/ +16, /*s*/ +13+0200, /*t*/ +22, /*u*/ +21, /*v*/ +31, /*w*/ +19, /*x*/ +21+0100, /*y*/ +18, /*z*/ +00, /*{*/ +2, /*|*/ +00, /*}*/ +00, /*~*/ +6, /*narrow space*/ +15, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +32, /*1/4*/ +32, /*1/2*/ +32, /*3/4*/ +27, /*minus*/ +23, /*fi*/ +23, /*fl*/ +25, /*ff*/ +34, /*ffi*/ +34, /*ffl*/ +15, /*degree*/ +21, /*dagger*/ +00, /*section*/ +9, /*foot mark*/ +00, /*'*/ +00, /*`*/ +00, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +00, +18, /*cent*/ +}; diff --git a/src/troff/font/ftPI.c b/src/troff/font/ftPI.c new file mode 100755 index 00000000..6f4cfbd0 --- /dev/null +++ b/src/troff/font/ftPI.c @@ -0,0 +1,136 @@ +/*Commercial II*/ +char PIw[256-32] { /*character withs for Palatino Italic 814-008A*/ +12, /*space*/ +9, /*!*/ +00, /*"*/ +00, /*sharp*/ +18, /*$*/ +28, /*%*/ +27, /*&*/ +9, /*' close*/ +13, /*(*/ +13, /*)*/ +19, /***/ +27, /*+*/ +9, /*,*/ +14, /*- hyphen*/ +9, /*.*/ +12, /*/*/ +18+0200, /*0*/ +18+0200, /*1*/ +18+0200, /*2*/ +18+0200, /*3*/ +18+0200, /*4*/ +18+0200, /*5*/ +18+0200, /*6*/ +18+0200, /*7*/ +18+0200, /*8*/ +18+0200, /*9*/ +9, /*:*/ +9, /*;*/ +00, /*<*/ +27, /*=*/ +00, /*>*/ +14, /*?*/ +00, /*@*/ +27+0200, /*A*/ +21+0200, /*B*/ +24+0200, /*C*/ +27+0200, /*D*/ +20+0200, /*E*/ +18+0200, /*F*/ +26+0200, /*G*/ +27+0200, /*H*/ +12+0200, /*I*/ +12+0200, /*J*/ +25+0200, /*K*/ +20+0200, /*L*/ +36+0200, /*M*/ +28+0200, /*N*/ +27+0200, /*O*/ +20+0200, /*P*/ +27+0300, /*Q*/ +25+0200, /*R*/ +17+0200, /*S*/ +22+0200, /*T*/ +28+0200, /*U*/ +27+0200, /*V*/ +35+0200, /*W*/ +26+0200, /*X*/ +25+0200, /*Y*/ +22+0200, /*Z*/ +14, /*[*/ +00, /*\*/ +14, /*]*/ +00, /*^*/ +0, /*_*/ +9, /*` open*/ +17, /*a*/ +16+0200, /*b*/ +15, /*c*/ +18+0200, /*d*/ +15, /*e*/ +12+0200, /*f*/ +16+0100, /*g*/ +18+0200, /*h*/ +12+0200, /*i*/ +12+0300, /*j*/ +16+0200, /*k*/ +11+0200, /*l*/ +28, /*m*/ +20, /*n*/ +16, /*o*/ +18+0100, /*p*/ +16+0100, /*q*/ +14, /*r*/ +14, /*s*/ +11+0200, /*t*/ +19, /*u*/ +18, /*v*/ +26, /*w*/ +18, /*x*/ +19+0100, /*y*/ +16, /*z*/ +00, /*{*/ +2, /*|*/ +00, /*}*/ +00, /*~*/ +6, /*narrow space*/ +14, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +28, /*1/4*/ +28, /*1/2*/ +28, /*3/4*/ +27, /*minus*/ +20, /*fi*/ +20, /*fl*/ +20, /*ff*/ +29, /*ffi*/ +29, /*ffl*/ +14, /*degree*/ +20, /*dagger*/ +00, /*section*/ +10, /*foot mark*/ +00, /*'*/ +00, /*`*/ +00, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +0, +18, /*cent*/ +}; diff --git a/src/troff/font/ftR.c b/src/troff/font/ftR.c new file mode 100755 index 00000000..696fde3b --- /dev/null +++ b/src/troff/font/ftR.c @@ -0,0 +1,136 @@ +/*modified for Commercial II*/ +char Rw[256-32] { /*Times Roman widths*/ +12, /*space*/ +12, /*!*/ +0, /*"*/ +0, /*#*/ +19, /*$*/ +29, /*%*/ +28, /*&*/ +12, /*' close*/ +16, /*(*/ +16, /*)*/ +16, /***/ +36, /*+*/ +12, /*,*/ +13, /*- hyphen*/ +10, /*.*/ +17, /*/*/ +19+0200, /*0*/ +19+0200, /*1*/ +19+0200, /*2*/ +19+0200, /*3*/ +19+0200, /*4*/ +19+0200, /*5*/ +19+0200, /*6*/ +19+0200, /*7*/ +19+0200, /*8*/ +19+0200, /*9*/ +10, /*:*/ +12, /*;*/ +0, /*<*/ +36, /*=*/ +0, /*>*/ +20, /*?*/ +0, /*@*/ +29+0200, /*A*/ +23+0200, /*B*/ +26+0200, /*C*/ +30+0200, /*D*/ +24+0200, /*E*/ +23+0200, /*F*/ +30+0200, /*G*/ +29+0200, /*H*/ +13+0200, /*I*/ +16+0200, /*J*/ +28+0200, /*K*/ +24+0200, /*L*/ +35+0200, /*M*/ +29+0200, /*N*/ +27+0200, /*O*/ +22+0200, /*P*/ +27+0300, /*Q*/ +27+0200, /*R*/ +20+0200, /*S*/ +24+0200, /*T*/ +29+0200, /*U*/ +27+0200, /*V*/ +36+0200, /*W*/ +28+0200, /*X*/ +27+0200, /*Y*/ +23+0200, /*Z*/ +14, /*[*/ +0, /*\*/ +14, /*]*/ +0, /*^*/ +0, /*_*/ +12, /*` open*/ +17, /*a*/ +20+0200, /*b*/ +16, /*c*/ +20+0200, /*d*/ +18, /*e*/ +13+0200, /*f*/ +18+0100, /*g*/ +21+0200, /*h*/ +10+0200, /*i*/ +9+0300, /*j*/ +20+0200, /*k*/ +10+0200, /*l*/ +32, /*m*/ +21, /*n*/ +20, /*o*/ +19+0100, /*p*/ +19+0100, /*q*/ +14, /*r*/ +15, /*s*/ +12+0200, /*t*/ +21, /*u*/ +20, /*v*/ +26, /*w*/ +20, /*x*/ +18+0100, /*y*/ +17, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +13, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +29, /*1/4*/ +29, /*1/2*/ +29, /*3/4*/ +36, /*minus*/ +21, /*fi*/ +21, /*fl*/ +24, /*ff*/ +32, /*ffi*/ +32, /*ffl*/ +15, /*degree*/ +20, /*dagger*/ +0, /*section*/ +8, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +0, +19, /*cent*/ +}; diff --git a/src/troff/font/ftS.c b/src/troff/font/ftS.c new file mode 100755 index 00000000..c17d2684 --- /dev/null +++ b/src/troff/font/ftS.c @@ -0,0 +1,135 @@ +/* +Modified for Commercial II +and with +, -, and = for equations +*/ +char Sw[256-32] { /*Special font widths*/ +0,0, /*.=Sw+042-40*/ +13, /*"*/ +29, /*#*/ +0,0,0,0, /*.=Sw+074-40*/ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0, +36, /*<*/ +0, /*.=Sw+076-40*/ +36, /*>*/ +0, /*.=Sw+100-40*/ +36, /*@*/ +0,0,0,0,0,0,0, /*.=Sw+134-40*/ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0, +15, /*\\*/ +0, /*.=Sw+136-40*/ +15, /*^*/ +18, /*_ underrule*/ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0, +14, /*{*/ +0, /*.=Sw+175-40*/ +14, /*}*/ +15, /*~*/ +0, /*.=Sw+220-40*/ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +17, /*section*/ +0, /*.=Sw+222-40*/ +10, /*acute accent*/ +10, /*grave accent*/ +18, /*underrule*/ +15, /*slash (longer)*/ +0, /**/ +0, /**/ +24, /*alpha*/ +23+0300, /*beta*/ +23+0100, /*gamma*/ +19+0200, /*delta*/ +18, /*epsilon*/ +18+0300, /*zeta*/ +23+0100, /*eta*/ +19+0200, /*theta*/ +13, /*iota*/ +21, /*kappa*/ +22+0200, /*lambda*/ +25+0100, /*mu*/ +20, /*nu*/ +20+0300, /*xi*/ +20, /*omicron*/ +27, /*pi*/ +21+0100, /*rho*/ +27, /*sigma*/ +20, /*tau*/ +21, /*upsilon*/ +25+0300, /*phi*/ +22+0100, /*chi*/ +24+0300, /*psi*/ +25, /*omega*/ +24+0200, /*Gamma*/ +26+0200, /*Delta*/ +28+0200, /*Theta*/ +28+0200, /*Lambda*/ +27+0200, /*Xi*/ +29+0200, /*Pi*/ +25+0200, /*Sigma*/ +0, /**/ +28+0200, /*Upsilon*/ +29+0200, /*Phi*/ +32+0200, /*Psi*/ +36+0200, /*Omega*/ +30, /*square root*/ +18+0100, /*terminal sigma*/ +18, /*root en*/ +36, /*>=*/ +36, /*<=*/ +36, /*identically equal*/ +27, /*minus*/ +36, /*approx =*/ +36, /*approximates*/ +36, /*not equal*/ +36, /*right arrow*/ +36, /*left arrow*/ +18, /*up arrow*/ +18, /*down arrow*/ +27, /*equal*/ +27, /*multiply*/ +27, /*divide*/ +36, /*plus-minus*/ +36, /*cup (union)*/ +36, /*cap (intersection)*/ +36, /*subset of*/ +36, /*superset of*/ +36, /*improper subset*/ +36, /*improper superset*/ +34, /*infinity*/ +21, /*partial derivative*/ +36+0200, /*gradient*/ +22, /*not*/ +24, /*integral sign*/ +27, /*proportional to*/ +28, /*empty set*/ +27, /*member of*/ +27, /*plus*/ +0, +0, +0, /*box vert rule (was 2.)*/ +0, +17, /*dbl dagger*/ +42, /*right hand*/ +42, /*left hand*/ +16, /*math * */ +41, /*bell system sign*/ +9, /*or*/ +27, /*circle*/ +9, /*left top (of big curly)*/ +9, /*left bottom*/ +9, /*right top*/ +9, /*right bot*/ +9, /*left center of big curly bracket*/ +9, /*right center of big curly bracket*/ +9, /*bold vertical*/ +9, /*left floor (left bot of big sq bract)*/ +9, /*right floor (rb of ")*/ +9, /*left ceiling (lt of ")*/ +9 }; /*right ceiling (rt of ")*/ diff --git a/src/troff/font/ftSB.c b/src/troff/font/ftSB.c new file mode 100755 index 00000000..826a54f5 --- /dev/null +++ b/src/troff/font/ftSB.c @@ -0,0 +1,138 @@ +char SBw[256-32] { /*SB Stymie Bold*/ +12, /*space*/ +13, /*!*/ +0, /*"*/ +0, /*#*/ +25, /*$*/ +32, /*%*/ +29, /*&*/ +9, /*' close*/ +15, /*(*/ +15, /*)*/ +13, /***/ +27, /*+*/ +9, /*,*/ +13, /*- hyphen*/ +9, /*.*/ +17, /*/*/ +25+0200, /*0*/ +25+0200, /*1*/ +25+0200, /*2*/ +25+0200, /*3*/ +25+0200, /*4*/ +25+0200, /*5*/ +25+0200, /*6*/ +25+0200, /*7*/ +25+0200, /*8*/ +25+0200, /*9*/ +13, /*:*/ +13, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +25, /*?*/ +0, /*@*/ +30+0200, /*A*/ +26+0200, /*B*/ +27+0200, /*C*/ +28+0200, /*D*/ +25+0200, /*E*/ +24+0200, /*F*/ +28+0200, /*G*/ +30+0200, /*H*/ +14+0200, /*I*/ +17+0200, /*J*/ +29+0200, /*K*/ +23+0200, /*L*/ +35+0200, /*M*/ +30+0200, /*N*/ +29+0200, /*O*/ +24+0200, /*P*/ +29+0300, /*Q*/ +27+0200, /*R*/ +24+0200, /*S*/ +26+0200, /*T*/ +30+0200, /*U*/ +29+0200, /*V*/ +40+0200, /*W*/ +30+0200, /*X*/ +29+0200, /*Y*/ +25+0200, /*Z*/ +13, /*[*/ +0, /*\*/ +13, /*]*/ +0, /*^*/ +0, /*_*/ +9, /*` open*/ +18, /*a*/ +21+0200, /*b*/ +18, /*c*/ +21+0200, /*d*/ +19, /*e*/ +13+0200, /*f*/ +21+0100, /*g*/ +22+0200, /*h*/ +11+0200, /*i*/ +10+0300, /*j*/ +21+0200, /*k*/ +11+0200, /*l*/ +30, /*m*/ +22, /*n*/ +19, /*o*/ +21+0100, /*p*/ +21+0100, /*q*/ +14, /*r*/ +16, /*s*/ +12+0200, /*t*/ +22, /*u*/ +22, /*v*/ +29, /*w*/ +22, /*x*/ +22+0100, /*y*/ +19, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +13, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +32, /*1/4*/ +32, /*1/2*/ +32, /*3/4*/ +27, /*minus*/ +24, /*fi*/ +24, /*fl*/ +26, /*ff*/ +37, /*ffi*/ +37, /*ffl*/ +14, /*degree*/ +20, /*dagger*/ +0, /*section*/ +10, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copywrite*/ +0, +25, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftSI.c b/src/troff/font/ftSI.c new file mode 100755 index 00000000..5d4d03a2 --- /dev/null +++ b/src/troff/font/ftSI.c @@ -0,0 +1,138 @@ +char SIw[256-32] { /*SI Stymie Medium Italic*/ +12, /*space*/ +11, /*!*/ +0, /*"*/ +0, /*#*/ +18, /*$*/ +30, /*%*/ +26, /*&*/ +8, /*' close*/ +12, /*(*/ +12, /*)*/ +17, /***/ +27, /*+*/ +8, /*,*/ +11, /*- hyphen*/ +7, /*.*/ +7, /*/*/ +18+0200, /*0*/ +18+0200, /*1*/ +18+0200, /*2*/ +18+0200, /*3*/ +18+0200, /*4*/ +18+0200, /*5*/ +18+0200, /*6*/ +18+0200, /*7*/ +18+0200, /*8*/ +18+0200, /*9*/ +11, /*:*/ +11, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +22, /*?*/ +0, /*@*/ +25+0200, /*A*/ +23+0200, /*B*/ +24+0200, /*C*/ +25+0200, /*D*/ +24+0200, /*E*/ +23+0200, /*F*/ +26+0200, /*G*/ +27+0200, /*H*/ +11+0200, /*I*/ +11+0200, /*J*/ +25+0200, /*K*/ +21+0200, /*L*/ +30+0200, /*M*/ +27+0200, /*N*/ +26+0200, /*O*/ +21+0200, /*P*/ +26+0300, /*Q*/ +24+0200, /*R*/ +21+0200, /*S*/ +22+0200, /*T*/ +25+0200, /*U*/ +25+0200, /*V*/ +33+0200, /*W*/ +25+0200, /*X*/ +25+0200, /*Y*/ +24+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +8, /*` open*/ +16, /*a*/ +19+0200, /*b*/ +17, /*c*/ +18+0200, /*d*/ +18, /*e*/ +11+0200, /*f*/ +19+0100, /*g*/ +19+0200, /*h*/ +10+0200, /*i*/ +10+0300, /*j*/ +18+0200, /*k*/ +10+0200, /*l*/ +28, /*m*/ +19, /*n*/ +18, /*o*/ +19+0100, /*p*/ +19+0100, /*q*/ +12, /*r*/ +14, /*s*/ +10+0200, /*t*/ +19, /*u*/ +18, /*v*/ +27, /*w*/ +18, /*x*/ +18+0100, /*y*/ +16, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +11, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +29, /*1/4*/ +29, /*1/2*/ +29, /*3/4*/ +27, /*minus*/ +19, /*fi*/ +19, /*fl*/ +20, /*ff*/ +28, /*ffi*/ +28, /*ffl*/ +17, /*degree*/ +19, /*dagger*/ +0, /*section*/ +8, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +19, /*registered*/ +19, /*copywrite*/ +0, +18, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftSM.c b/src/troff/font/ftSM.c new file mode 100755 index 00000000..054076ff --- /dev/null +++ b/src/troff/font/ftSM.c @@ -0,0 +1,138 @@ +char SMw[256-32] { /*SM Stymie Medium*/ +12, /*space*/ +11, /*!*/ +0, /*"*/ +0, /*#*/ +24, /*$*/ +22, /*%*/ +26, /*&*/ +9, /*' close*/ +13, /*(*/ +13, /*)*/ +13, /***/ +27, /*+*/ +9, /*,*/ +11, /*- hyphen*/ +9, /*.*/ +15, /*/*/ +24+0200, /*0*/ +24+0200, /*1*/ +24+0200, /*2*/ +24+0200, /*3*/ +24+0200, /*4*/ +24+0200, /*5*/ +24+0200, /*6*/ +24+0200, /*7*/ +24+0200, /*8*/ +24+0200, /*9*/ +11, /*:*/ +11, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +22, /*?*/ +0, /*@*/ +27+0200, /*A*/ +22+0200, /*B*/ +25+0200, /*C*/ +25+0200, /*D*/ +20+0200, /*E*/ +20+0200, /*F*/ +27+0200, /*G*/ +27+0200, /*H*/ +12+0200, /*I*/ +14+0200, /*J*/ +25+0200, /*K*/ +20+0200, /*L*/ +30+0200, /*M*/ +26+0200, /*N*/ +27+0200, /*O*/ +20+0200, /*P*/ +27+0300, /*Q*/ +23+0200, /*R*/ +18+0200, /*S*/ +21+0200, /*T*/ +26+0200, /*U*/ +25+0200, /*V*/ +32+0200, /*W*/ +26+0200, /*X*/ +25+0200, /*Y*/ +21+0200, /*Z*/ +14, /*[*/ +0, /*\*/ +14, /*]*/ +0, /*^*/ +0, /*_*/ +9, /*` open*/ +18, /*a*/ +21+0200, /*b*/ +18, /*c*/ +21+0200, /*d*/ +19, /*e*/ +11+0200, /*f*/ +21+0100, /*g*/ +21+0200, /*h*/ +10+0200, /*i*/ +10+0300, /*j*/ +20+0200, /*k*/ +10+0200, /*l*/ +30, /*m*/ +21, /*n*/ +19, /*o*/ +21+0100, /*p*/ +21+0100, /*q*/ +14, /*r*/ +15, /*s*/ +11+0200, /*t*/ +21, /*u*/ +20, /*v*/ +27, /*w*/ +21, /*x*/ +20+0100, /*y*/ +18, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +11, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +31, /*1/4*/ +31, /*1/2*/ +31, /*3/4*/ +27, /*minus*/ +21, /*fi*/ +21, /*fl*/ +22, /*ff*/ +32, /*ffi*/ +32, /*ffl*/ +15, /*degree*/ +19, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +22, /*registered*/ +22, /*copywrite*/ +0, +24, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/ftUD.c b/src/troff/font/ftUD.c new file mode 100755 index 00000000..a9866b91 --- /dev/null +++ b/src/troff/font/ftUD.c @@ -0,0 +1,136 @@ +/*modified for Commercial II*/ +char UDw[256-32] { /*Utica Demibold widths (Utica == Futura)*/ +12, /*space*/ +11, /*!*/ +0, /*"*/ +16, /*0*/ +21, /*$*/ +28, /*%*/ +25, /*&*/ +10, /*' close*/ +14, /*(*/ +14, /*)*/ +13, /***/ +27, /*+*/ +9, /*,*/ +14, /*- hyphen*/ +9, /*.*/ +15, /*/*/ +21+0200, /*0*/ +21+0200, /*1*/ +21+0200, /*2*/ +21+0200, /*3*/ +21+0200, /*4*/ +21+0200, /*5*/ +21+0200, /*6*/ +21+0200, /*7*/ +21+0200, /*8*/ +21+0200, /*9*/ +11, /*:*/ +11, /*;*/ +0, /*<*/ +27, /*=*/ +0, /*>*/ +20, /*?*/ +0, /*@*/ +24+0200, /*A*/ +19+0200, /*B*/ +22+0200, /*C*/ +21+0200, /*D*/ +19+0200, /*E*/ +16+0200, /*F*/ +26+0200, /*G*/ +24+0200, /*H*/ +12+0200, /*I*/ +17+0200, /*J*/ +21+0200, /*K*/ +14+0200, /*L*/ +29+0200, /*M*/ +26+0200, /*N*/ +26+0200, /*O*/ +19+0200, /*P*/ +27+0300, /*Q*/ +19+0200, /*R*/ +18+0200, /*S*/ +16+0200, /*T*/ +24+0200, /*U*/ +22+0200, /*V*/ +33+0200, /*W*/ +22+0200, /*X*/ +20+0200, /*Y*/ +22+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +10, /*` open*/ +20, /*a*/ +20+0200, /*b*/ +14, /*c*/ +20+0200, /*d*/ +18, /*e*/ +11+0200, /*f*/ +20+0100, /*g*/ +19+0200, /*h*/ +9+0200, /*i*/ +9+0300, /*j*/ +18+0200, /*k*/ +9+0200, /*l*/ +29, /*m*/ +19, /*n*/ +18, /*o*/ +20+0100, /*p*/ +20+0100, /*q*/ +12, /*r*/ +15, /*s*/ +10+0200, /*t*/ +19, /*u*/ +18, /*v*/ +28, /*w*/ +18, /*x*/ +18+0100, /*y*/ +16, /*z*/ +0, /*{*/ +5, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +14, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +28, /*1/4*/ +28, /*1/2*/ +28, /*3/4*/ +27, /*minus*/ +18, /*fi*/ +18, /*fl*/ +19, /*ff*/ +27, /*ffi*/ +27, /*ffl*/ +14, /*degree*/ +29, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +16, /*registered*/ +16, /*copywrite*/ +0, +21, /*cent*/ +}; diff --git a/src/troff/font/ftXM.c b/src/troff/font/ftXM.c new file mode 100755 index 00000000..33afad38 --- /dev/null +++ b/src/troff/font/ftXM.c @@ -0,0 +1,138 @@ +char SMw[256-32] { /*SM Stymie Medium*/ +12+2, /*space*/ +11+2, /*!*/ +0, /*"*/ +0, /*#*/ +24+2, /*$*/ +22+2, /*%*/ +26+2, /*&*/ +9+2, /*' close*/ +13+2, /*(*/ +13+2, /*)*/ +13+2, /***/ +27+2, /*+*/ +9+2, /*,*/ +11+2, /*- hyphen*/ +9+2, /*.*/ +15+2, /*/*/ +24+0200+2, /*0*/ +24+0200+2, /*1*/ +24+0200+2, /*2*/ +24+0200+2, /*3*/ +24+0200+2, /*4*/ +24+0200+2, /*5*/ +24+0200+2, /*6*/ +24+0200+2, /*7*/ +24+0200+2, /*8*/ +24+0200+2, /*9*/ +11+2, /*:*/ +11+2, /*;*/ +0, /*<*/ +27+2, /*=*/ +0, /*>*/ +22+2, /*?*/ +0, /*@*/ +27+0200+2, /*A*/ +22+0200+2, /*B*/ +25+0200+2, /*C*/ +25+0200+2, /*D*/ +20+0200+2, /*E*/ +20+0200+2, /*F*/ +27+0200+2, /*G*/ +27+0200+2, /*H*/ +12+0200+2, /*I*/ +14+0200+2, /*J*/ +25+0200+2, /*K*/ +20+0200+2, /*L*/ +30+0200+2, /*M*/ +26+0200+2, /*N*/ +27+0200+2, /*O*/ +20+0200+2, /*P*/ +27+0300+2, /*Q*/ +23+0200+2, /*R*/ +18+0200+2, /*S*/ +21+0200+2, /*T*/ +26+0200+2, /*U*/ +25+0200+2, /*V*/ +32+0200+2, /*W*/ +26+0200+2, /*X*/ +25+0200+2, /*Y*/ +21+0200+2, /*Z*/ +14+2, /*[*/ +0, /*\*/ +14+2, /*]*/ +0, /*^*/ +0, /*_*/ +9+2, /*` open*/ +18+2, /*a*/ +21+0200+2, /*b*/ +18+2, /*c*/ +21+0200+2, /*d*/ +19+2, /*e*/ +11+0200+2, /*f*/ +21+0100+2, /*g*/ +21+0200+2, /*h*/ +10+0200+2, /*i*/ +10+0300+2, /*j*/ +20+0200+2, /*k*/ +10+0200+2, /*l*/ +30+2, /*m*/ +21+2, /*n*/ +19+2, /*o*/ +21+0100+2, /*p*/ +21+0100+2, /*q*/ +14+2, /*r*/ +15+2, /*s*/ +11+0200+2, /*t*/ +21+2, /*u*/ +20+2, /*v*/ +27+2, /*w*/ +21+2, /*x*/ +20+0100+2, /*y*/ +18+2, /*z*/ +0, /*{*/ +2+2, /*|*/ +0, /*}*/ +0, /*~*/ +6+2, /*narrow space*/ +11+2, /*hyphen*/ +27+2, /*bullet*/ +27+2, /*square*/ +36+2, /*3/4 em*/ +18+2, /*rule*/ +31+2, /*1/4*/ +31+2, /*1/2*/ +31+2, /*3/4*/ +27+2, /*minus*/ +21+2, /*fi*/ +21+2, /*fl*/ +22+2, /*ff*/ +32+2, /*ffi*/ +32+2, /*ffl*/ +15+2, /*degree*/ +19+2, /*dagger*/ +0, /*section*/ +9+2, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3+2, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +22+2, /*registered*/ +22+2, /*copywrite*/ +0, +24+2, /*cent*/ +0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0}; diff --git a/src/troff/font/linkrc b/src/troff/font/linkrc new file mode 100755 index 00000000..633e64f6 --- /dev/null +++ b/src/troff/font/linkrc @@ -0,0 +1,7 @@ +cd /usr/lib/font +rm ftH ftHI ftHM ftFD ftCI +ln ftG ftH +ln ftGI ftHI +ln ftGM ftHM +ln ftUD ftFD +ln ftCK ftCI diff --git a/src/troff/font/makefile b/src/troff/font/makefile new file mode 100755 index 00000000..2799d3ad --- /dev/null +++ b/src/troff/font/makefile @@ -0,0 +1,16 @@ +cp: all + for i in *.o; do cp $$i /usr/lib/font/`basename $$i .o`; done + rm *.o + +cmp: all + for i in *.o; do cmp $$i /usr/lib/font/`basename $$i .o`; done + rm *.o + +.c.o: + cc -c $<; strip $@ + +all: ftB.o ftBC.o ftC.o ftCE.o ftCI.o ftCK.o ftCS.o ftCW.o ftG.o ftGI.o ftGM.o ftGR.o +all: ftI.o ftL.o ftLI.o ftPA.o ftPB.o ftPI.o ftR.o ftS.o ftSB.o ftSI.o ftSM.o ftUD.o ftXM.o + +mkfont:mkfont.c mkfont1.c -o mkfont + cc -n -s mkfont.c diff --git a/src/troff/font/mkfont.c b/src/troff/font/mkfont.c new file mode 100755 index 00000000..7a760667 --- /dev/null +++ b/src/troff/font/mkfont.c @@ -0,0 +1,103 @@ +#include "mkfont1.c" + +/* + this program takes 102 width values + (one per line) in the order provided bu Graphic + Systems and prepares a C-compileable width table. +*/ +char ibuf[512]; +int id; +int width[102]; +int ascii[102]; +int zero; +int emw, hyw; +int xxx; + +main(argc,argv) +int argc; +char **argv; +{ + register i, j; + register char *p; + + while((--argc > 0) && ((++argv)[0][0]=='-')){ + switch(argv[0][1]){ + default: + continue; + } + } + if(argc){ + if((id=open(argv[0],0)) < 0){ + printf("Cannot open: %s.\n",argv[0]); + exit(1); + } + } + j = read(id,ibuf,512); + p = ibuf; + for(i=0; i<102; i++){ + width[i] = atoi(p); + while(*p++ != '\n'); + } + for(i=0; i<102; i++){ + if(font[i].name < 0177){ + ascii[i] = font[i].name; + }else{ + for(j=0; chtab[j] != 0; j =+ 2){ + if(font[i].name == chtab[j])break; + } + ascii[i] = chtab[j+1] & 0377; + if(chtab[j] == 'hy')hyw = width[i]; + if(chtab[j] == 'em')emw = width[i]; + } + } + printf("char XXw[256-32] {\t/*XX*/\n"); + for(i=040; i<256; i++){ + if(i == 0377){ + printf("0};\n"); + break; + } + if(i == 0177){ + printf("6,\t %s\n",nametab[i-040]); + continue; + } + if(i == 0226){ + printf("3,\t %s\n",nametab[i-040]); + continue; + } + if(i == ' '){ + printf("12,\t %s\n",nametab[i-040]); + continue; + } + if(i == '-'){ + printf("%d,\t %s\n",hyw,nametab[i-040]); + continue; + } + for(j=0; j<102; j++){ + if(ascii[j] == i)break; + } + if(j == 102){ + printf("0,"); + zero++; + if(nametab[i-040]){ + printf("\t %s\n",nametab[i-040]); + zero = 0; + }else if(i < 0177){ + printf("\t /*%c*/\n",i); + zero = 0; + } + if(zero && !((i+1)%8)){ + printf("\n"); + zero = 0; + } + }else{ + if(zero){ + zero = 0; + printf("\n"); + } + printf("%d",width[j]); + if(font[j].ctval)printf("+0%d00, ",font[j].ctval); + else printf(",\t "); + printf("%s\n",nametab[i-040]); + } + } +} diff --git a/src/troff/font/mkfont1.c b/src/troff/font/mkfont1.c new file mode 100755 index 00000000..3e566079 --- /dev/null +++ b/src/troff/font/mkfont1.c @@ -0,0 +1,369 @@ + +struct { + int name; + int ctval; + } font[102] { +'h',2, +'t',2, +'n',0, +'m',0, +'l',2, +'i',2, +'z',0, +'s',0, +'d',2, +'b',2, +'x',0, +'f',2, +'j',3, +'u',0, +'k',2, +'p',1, +'em',0, +';',0, +'a',0, +'ru',0, +'c',0, +'`',0, +'e',0, +'\'',0, +'o',0, +'14',0, +'r',0, +'12',0, +'v',0, +'hy',0, +'w',0, +'q',1, +'/',0, +'.',0, +'g',1, +'34',0, +',',0, +'&',0, +'y',1, +'%',0, +'Q',3, +'T',2, +'O',2, +'H',2, +'N',2, +'M',2, +'L',2, +'R',2, +'G',2, +'I',2, +'P',2, +'C',2, +'V',2, +'E',2, +'Z',2, +'D',2, +'B',2, +'S',2, +'Y',2, +'F',2, +'X',2, +'A',2, +'W',2, +'J',2, +'U',2, +'K',2, +'0',2, +'1',2, +'2',2, +'3',2, +'4',2, +'5',2, +'6',2, +'7',2, +'8',2, +'9',2, +'*',0, +'--',0, +'fi',0, +'fl',0, +'ff',0, +'ct',0, +'Fl',0, +'Fi',0, +'(',0, +')',0, +'[',0, +']',0, +'de',0, +'dg',0, +'=',0, +'rg',0, +':',0, +'+',0, +'!',0, +'bu',0, +'?',0, +'fm',0, +'|',0, +'co',0, +'sq',0, +'$',0}; +char *nametab[256-32] { +"/*space*/", +"/*!*/", +"/*\"*/", +"/*#*/", +"/*$*/", +"/*%*/", +"/*&*/", +"/*' close*/", +"/*(*/", +"/*)*/", +"/***/", +"/*+*/", +"/*,*/", +"/*- hyphen*/", +"/*.*/", +"/*/*/", +"/*0*/", +"/*1*/", +"/*2*/", +"/*3*/", +"/*4*/", +"/*5*/", +"/*6*/", +"/*7*/", +"/*8*/", +"/*9*/", +"/*:*/", +"/*;*/", +"/*<*/", +"/*=*/", +"/*>*/", +"/*?*/", +"/*@*/", +"/*A*/", +"/*B*/", +"/*C*/", +"/*D*/", +"/*E*/", +"/*F*/", +"/*G*/", +"/*H*/", +"/*I*/", +"/*J*/", +"/*K*/", +"/*L*/", +"/*M*/", +"/*N*/", +"/*O*/", +"/*P*/", +"/*Q*/", +"/*R*/", +"/*S*/", +"/*T*/", +"/*U*/", +"/*V*/", +"/*W*/", +"/*X*/", +"/*Y*/", +"/*Z*/", +"/*[*/", +"/*\\*/", +"/*]*/", +"/*^*/", +"/*_*/", +"/*` open*/", +"/*a*/", +"/*b*/", +"/*c*/", +"/*d*/", +"/*e*/", +"/*f*/", +"/*g*/", +"/*h*/", +"/*i*/", +"/*j*/", +"/*k*/", +"/*l*/", +"/*m*/", +"/*n*/", +"/*o*/", +"/*p*/", +"/*q*/", +"/*r*/", +"/*s*/", +"/*t*/", +"/*u*/", +"/*v*/", +"/*w*/", +"/*x*/", +"/*y*/", +"/*z*/", +"/*{*/", +"/*|*/", +"/*}*/", +"/*~*/", +"/*narrow space*/", +"/*hyphen*/", +"/*bullet*/", +"/*square*/", +"/*3/4 em*/", +"/*rule*/", +"/*1/4*/", +"/*1/2*/", +"/*3/4*/", +"/*minus*/", +"/*fi*/", +"/*fl*/", +"/*ff*/", +"/*ffi*/", +"/*ffl*/", +"/*degree*/", +"/*dagger*/", +"/*section*/", +"/*foot mark*/", +"/*'*/", +"/*`*/", +"/*_*/", +0, +"/*half nar sp*/", +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +"/*registered*/", +"/*copywrite*/", +0, +"/*cent*/", +}; +int chtab [] { +'--', 0210, /*font minus*/ +'hy', 0200, /*hyphen*/ +'bu', 0201, /*bullet*/ +'sq', 0202, /*square*/ +'em', 0203, /*3/4em*/ +'ru', 0204, /*rule*/ +'14', 0205, /*1/4*/ +'12', 0206, /*1/2*/ +'34', 0207, /*3/4*/ +'mi', 0302, /*equation minus*/ +'fi', 0211, /*fi*/ +'fl', 0212, /*fl*/ +'ff', 0213, /*ff*/ +'Fi', 0214, /*ffi*/ +'Fl', 0215, /*ffl*/ +'de', 0216, /*degree*/ +'dg', 0217, /*dagger*/ +'sc', 0220, /*section*/ +'fm', 0221, /*foot mark*/ +'aa', 0222, /*acute accent*/ +'ga', 0223, /*grave accent*/ +'ul', 0224, /*underrule*/ +'sl', 0225, /*slash (longer)*/ +'*a', 0230, /*alpha*/ +'*b', 0231, /*beta*/ +'*g', 0232, /*gamma*/ +'*d', 0233, /*delta*/ +'*e', 0234, /*epsilon*/ +'*z', 0235, /*zeta*/ +'*y', 0236, /*eta*/ +'*h', 0237, /*theta*/ +'*i', 0240, /*iota*/ +'*k', 0241, /*kappa*/ +'*l', 0242, /*lambda*/ +'*m', 0243, /*mu*/ +'*n', 0244, /*nu*/ +'*c', 0245, /*xi*/ +'*o', 0246, /*omicron*/ +'*p', 0247, /*pi*/ +'*r', 0250, /*rho*/ +'*s', 0251, /*sigma*/ +'*t', 0252, /*tau*/ +'*u', 0253, /*upsilon*/ +'*f', 0254, /*phi*/ +'*x', 0255, /*chi*/ +'*q', 0256, /*psi*/ +'*w', 0257, /*omega*/ +'*A', 0101, /*Alpha*/ +'*B', 0102, /*Beta*/ +'*G', 0260, /*Gamma*/ +'*D', 0261, /*Delta*/ +'*E', 0105, /*Epsilon*/ +'*Z', 0132, /*Zeta*/ +'*Y', 0110, /*Eta*/ +'*H', 0262, /*Theta*/ +'*I', 0111, /*Iota*/ +'*K', 0113, /*Kappa*/ +'*L', 0263, /*Lambda*/ +'*M', 0115, /*Mu*/ +'*N', 0116, /*Nu*/ +'*C', 0264, /*Xi*/ +'*O', 0117, /*Omicron*/ +'*P', 0265, /*Pi*/ +'*R', 0120, /*Rho*/ +'*S', 0266, /*Sigma*/ +'*T', 0124, /*Tau*/ +'*U', 0270, /*Upsilon*/ +'*F', 0271, /*Phi*/ +'*X', 0130, /*Chi*/ +'*Q', 0272, /*Psi*/ +'*W', 0273, /*Omega*/ +'sr', 0274, /*square root*/ +'ts', 0275, /*terminal sigma*/ +'rn', 0276, /*root en*/ +'>=', 0277, /*>=*/ +'<=', 0300, /*<=*/ +'==', 0301, /*identically equal*/ +'~=', 0303, /*approx =*/ +'ap', 0304, /*approximates*/ +'!=', 0305, /*not equal*/ +'->', 0306, /*right arrow*/ +'<-', 0307, /*left arrow*/ +'ua', 0310, /*up arrow*/ +'da', 0311, /*down arrow*/ +'eq', 0312, /*equation equal*/ +'mu', 0313, /*multiply*/ +'di', 0314, /*divide*/ +'+-', 0315, /*plus-minus*/ +'cu', 0316, /*cup (union)*/ +'ca', 0317, /*cap (intersection)*/ +'sb', 0320, /*subset of*/ +'sp', 0321, /*superset of*/ +'ib', 0322, /*improper subset*/ +'ip', 0323, /* " superset*/ +'if', 0324, /*infinity*/ +'pd', 0325, /*partial derivative*/ +'gr', 0326, /*gradient*/ +'no', 0327, /*not*/ +'is', 0330, /*integral sign*/ +'pt', 0331, /*proportional to*/ +'es', 0332, /*empty set*/ +'mo', 0333, /*member of*/ +'pl', 0334, /*equation plus*/ +'rg', 0335, /*registered*/ +'co', 0336, /*copyright*/ +'br', 0337, /*box vert rule*/ +'ct', 0340, /*cent sign*/ +'dd', 0341, /*dbl dagger*/ +'rh', 0342, /*right hand*/ +'lh', 0343, /*left hand*/ +'**', 0344, /*math * */ +'bs', 0345, /*bell system sign*/ +'or', 0346, /*or*/ +'ci', 0347, /*circle*/ +'lt', 0350, /*left top (of big curly)*/ +'lb', 0351, /*left bottom*/ +'rt', 0352, /*right top*/ +'rb', 0353, /*right bot*/ +'lk', 0354, /*left center of big curly bracket*/ +'rk', 0355, /*right center of big curly bracket*/ +'bv', 0356, /*bold vertical*/ +'lf', 0357, /*left floor (left bot of big sq bract)*/ +'rf', 0360, /*right floor (rb of ")*/ +'lc', 0361, /*left ceiling (lt of ")*/ +'rc', 0362, /*right ceiling (rt of ")*/ +0,0}; diff --git a/src/troff/hytab.c b/src/troff/hytab.c new file mode 100755 index 00000000..f6cc31d3 --- /dev/null +++ b/src/troff/hytab.c @@ -0,0 +1,123 @@ +/* + * Hyphenation digram tables + */ + +char bxh[1][13] = { + 0060,0000,0040,0000,0040,0000,0000,0040,0000,0000,0040,0000,0040 +}; + +char hxx[26][13] = { + 0006,0042,0041,0123,0021,0024,0063,0042,0002,0043,0021,0001,0022, + 0140,0000,0200,0003,0260,0006,0000,0160,0007,0000,0140,0000,0320, + 0220,0000,0160,0005,0240,0010,0000,0100,0006,0000,0200,0000,0320, + 0240,0000,0120,0003,0140,0000,0000,0240,0010,0000,0220,0000,0160, + 0042,0023,0041,0040,0040,0022,0043,0041,0030,0064,0021,0000,0041, + 0100,0000,0140,0000,0220,0006,0000,0140,0003,0000,0200,0000,0000, + 0200,0000,0120,0002,0220,0010,0000,0160,0006,0000,0140,0000,0320, + 0020,0000,0020,0000,0020,0000,0000,0020,0000,0000,0020,0000,0000, + 0043,0163,0065,0044,0022,0043,0104,0042,0061,0146,0061,0000,0007, + 0100,0000,0140,0000,0040,0000,0000,0100,0000,0000,0120,0000,0000, + 0140,0000,0040,0011,0060,0004,0001,0120,0003,0000,0140,0000,0040, + 0200,0000,0100,0000,0140,0000,0000,0140,0000,0000,0140,0000,0240, + 0200,0000,0140,0000,0160,0000,0000,0220,0000,0000,0140,0000,0240, + 0200,0000,0140,0000,0160,0000,0000,0220,0000,0000,0060,0000,0240, + 0021,0043,0041,0121,0040,0023,0042,0003,0142,0042,0061,0001,0022, + 0120,0000,0140,0010,0140,0010,0000,0140,0002,0000,0120,0000,0120, + 0000,0000,0000,0000,0360,0000,0000,0000,0000,0000,0160,0000,0000, + 0100,0000,0040,0005,0120,0000,0000,0100,0000,0000,0060,0000,0140, + 0140,0040,0100,0001,0240,0041,0000,0242,0000,0002,0140,0000,0100, + 0240,0000,0120,0002,0200,0000,0000,0320,0007,0000,0240,0000,0340, + 0101,0021,0041,0020,0040,0005,0042,0121,0002,0021,0201,0000,0020, + 0160,0000,0100,0000,0140,0000,0000,0160,0006,0000,0220,0000,0140, + 0140,0000,0020,0001,0020,0000,0000,0100,0001,0000,0300,0000,0000, + 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, + 0106,0041,0040,0147,0040,0000,0063,0041,0001,0102,0160,0002,0002, + 0300,0000,0040,0017,0140,0017,0000,0240,0000,0000,0140,0000,0120, +}; + +char bxxh[26][13] = { + 0005,0150,0153,0062,0062,0246,0152,0127,0146,0203,0310,0017,0206, + 0100,0000,0120,0000,0140,0000,0000,0100,0000,0000,0120,0000,0060, + 0100,0000,0040,0000,0060,0000,0000,0060,0000,0000,0220,0000,0040, + 0100,0000,0120,0000,0200,0000,0000,0100,0000,0000,0140,0000,0060, + 0043,0142,0046,0140,0062,0147,0210,0131,0046,0106,0246,0017,0111, + 0060,0000,0020,0000,0060,0000,0000,0040,0000,0000,0100,0000,0000, + 0060,0000,0040,0000,0040,0000,0000,0040,0000,0000,0100,0000,0040, + 0100,0000,0100,0000,0100,0000,0000,0040,0000,0000,0100,0000,0140, + 0066,0045,0145,0140,0000,0070,0377,0030,0130,0103,0003,0017,0006, + 0040,0000,0040,0000,0020,0000,0000,0040,0000,0000,0100,0000,0000, + 0200,0000,0020,0000,0140,0000,0000,0120,0000,0000,0120,0000,0040, + 0120,0000,0040,0000,0060,0000,0000,0060,0000,0000,0160,0000,0040, + 0120,0000,0040,0000,0120,0000,0000,0040,0000,0000,0160,0000,0040, + 0120,0000,0020,0000,0140,0000,0000,0120,0000,0000,0140,0000,0040, + 0051,0126,0150,0140,0060,0210,0146,0006,0006,0165,0003,0017,0244, + 0120,0000,0040,0000,0160,0000,0000,0140,0000,0000,0060,0000,0140, + 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, + 0140,0000,0140,0000,0060,0000,0000,0100,0000,0000,0140,0000,0020, + 0120,0000,0020,0000,0060,0000,0000,0060,0000,0000,0060,0000,0040, + 0140,0000,0020,0000,0100,0000,0000,0140,0000,0000,0140,0000,0020, + 0070,0125,0051,0162,0120,0105,0126,0104,0006,0044,0000,0017,0052, + 0140,0000,0020,0000,0140,0000,0000,0060,0000,0000,0060,0000,0040, + 0020,0000,0000,0000,0020,0000,0000,0000,0000,0000,0000,0000,0060, + 0140,0000,0160,0000,0200,0000,0000,0140,0000,0000,0000,0000,0240, + 0065,0042,0060,0200,0000,0210,0222,0146,0006,0204,0220,0012,0003, + 0240,0000,0020,0000,0120,0000,0000,0200,0000,0000,0200,0000,0240, +}; + +char xhx[26][13] = { + 0032,0146,0042,0107,0076,0102,0042,0146,0202,0050,0006,0000,0051, + 0036,0377,0057,0013,0057,0366,0377,0057,0001,0377,0057,0000,0040, + 0037,0377,0020,0000,0100,0022,0377,0057,0362,0116,0100,0000,0017, + 0057,0377,0057,0031,0137,0363,0377,0037,0362,0270,0077,0000,0117, + 0074,0142,0012,0236,0076,0125,0063,0165,0341,0046,0047,0000,0024, + 0020,0017,0075,0377,0040,0001,0377,0017,0001,0204,0020,0000,0040, + 0057,0017,0057,0340,0140,0362,0314,0117,0003,0302,0100,0000,0057, + 0057,0357,0077,0017,0100,0366,0314,0057,0342,0346,0037,0000,0060, + 0252,0145,0072,0157,0377,0165,0063,0066,0164,0050,0363,0000,0362, + 0000,0000,0020,0000,0020,0000,0000,0017,0000,0000,0020,0000,0000, + 0117,0017,0237,0377,0200,0354,0125,0110,0004,0257,0000,0000,0300, + 0057,0367,0054,0357,0157,0216,0314,0114,0217,0353,0053,0000,0057, + 0077,0213,0077,0077,0177,0317,0377,0114,0377,0352,0077,0000,0076, + 0077,0213,0077,0077,0157,0177,0377,0054,0377,0352,0117,0000,0075, + 0125,0230,0065,0216,0057,0066,0063,0047,0345,0126,0011,0000,0033, + 0057,0377,0051,0360,0120,0361,0273,0056,0001,0256,0057,0000,0060, + 0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000,0000, + 0076,0310,0056,0310,0137,0174,0273,0055,0335,0266,0033,0000,0155, + 0077,0157,0057,0360,0057,0063,0042,0024,0077,0206,0020,0000,0040, + 0057,0037,0077,0360,0100,0365,0377,0037,0362,0176,0050,0000,0026, + 0167,0146,0042,0112,0077,0110,0062,0254,0366,0052,0377,0000,0163, + 0060,0000,0040,0000,0120,0000,0377,0060,0012,0000,0037,0000,0257, + 0037,0232,0157,0361,0040,0003,0125,0010,0001,0256,0000,0000,0340, + 0377,0377,0377,0377,0377,0377,0377,0377,0377,0377,0377,0017,0277, + 0253,0315,0257,0216,0377,0206,0146,0306,0371,0126,0232,0000,0004, + 0057,0012,0100,0360,0160,0360,0000,0040,0000,0017,0157,0000,0176, +}; + +char xxh[26][13] = { + 0045,0150,0154,0162,0042,0246,0210,0147,0152,0103,0230,0017,0206, + 0100,0000,0040,0000,0140,0000,0000,0100,0000,0021,0120,0017,0060, + 0100,0000,0040,0002,0140,0320,0000,0060,0000,0001,0220,0017,0040, + 0100,0001,0120,0001,0241,0000,0000,0100,0000,0020,0140,0017,0060, + 0023,0162,0046,0142,0022,0207,0210,0131,0052,0106,0250,0017,0110, + 0060,0000,0042,0000,0160,0000,0000,0040,0000,0212,0100,0017,0000, + 0140,0000,0040,0002,0140,0000,0000,0120,0000,0040,0120,0017,0040, + 0100,0000,0100,0000,0140,0001,0021,0140,0000,0046,0100,0017,0140, + 0066,0045,0025,0201,0020,0130,0146,0030,0130,0103,0025,0017,0006, + 0100,0000,0040,0000,0020,0000,0000,0040,0000,0000,0200,0017,0000, + 0200,0000,0020,0001,0140,0000,0000,0140,0000,0000,0120,0017,0040, + 0120,0026,0042,0020,0140,0161,0042,0143,0000,0022,0162,0017,0040, + 0121,0042,0060,0020,0140,0200,0000,0123,0000,0021,0220,0017,0041, + 0121,0042,0060,0120,0140,0200,0000,0123,0000,0021,0160,0017,0041, + 0051,0126,0150,0141,0060,0210,0146,0066,0026,0165,0026,0017,0247, + 0120,0000,0040,0003,0160,0000,0000,0140,0000,0021,0100,0017,0140, + 0000,0000,0000,0000,0200,0000,0000,0000,0000,0000,0000,0017,0000, + 0141,0023,0122,0040,0160,0143,0042,0142,0000,0047,0143,0017,0020, + 0120,0000,0040,0006,0140,0060,0000,0141,0000,0026,0100,0017,0040, + 0140,0000,0020,0007,0100,0000,0000,0140,0000,0001,0140,0017,0020, + 0110,0125,0051,0162,0120,0125,0127,0104,0006,0104,0000,0017,0052, + 0140,0000,0040,0000,0160,0000,0000,0140,0000,0000,0060,0017,0000, + 0040,0005,0020,0000,0040,0313,0231,0030,0000,0140,0000,0017,0056, + 0140,0000,0160,0000,0200,0000,0000,0140,0000,0000,0000,0017,0240, + 0065,0042,0060,0040,0000,0206,0231,0146,0006,0224,0220,0017,0004, + 0240,0000,0020,0000,0140,0000,0000,0220,0000,0000,0200,0017,0141, +}; diff --git a/src/troff/makefile b/src/troff/makefile new file mode 100755 index 00000000..018f970d --- /dev/null +++ b/src/troff/makefile @@ -0,0 +1,18 @@ +all: nroff troff + +nroff: + make -f nmake + rm *.o + +troff: + make -f tmake + rm *.o + +cp: all + cp nroff troff /bin + rm nroff troff + +cmp: all + cmp nroff /bin/nroff + cmp troff /bin/troff + rm nroff troff diff --git a/src/troff/n.bat b/src/troff/n.bat new file mode 100755 index 00000000..330db7a3 --- /dev/null +++ b/src/troff/n.bat @@ -0,0 +1,135 @@ +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n1.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n2.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n3.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n4.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n5.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n6.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n7.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n8.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n9.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c n10.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c ni.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c nii.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c ntab.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c hytab.c +@if errorlevel 1 goto failure +cl -Zi -I. -I..\kernel\uzi -DVAX -DNROFF -c suftab.c +@if errorlevel 1 goto failure +link @nroff.w32 +@if errorlevel 1 goto failure +copy nroff.exe ..\bin + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n1 +@if errorlevel 1 goto failure +del n1.r01 +as-z80 -l -o n1.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n2 +@if errorlevel 1 goto failure +del n2.r01 +as-z80 -l -o n2.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n3 +@if errorlevel 1 goto failure +del n3.r01 +as-z80 -l -o n3.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n4 +@if errorlevel 1 goto failure +del n4.r01 +as-z80 -l -o n4.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n5 +@if errorlevel 1 goto failure +del n5.r01 +as-z80 -l -o n5.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n6 +@if errorlevel 1 goto failure +del n6.r01 +as-z80 -l -o n6.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n7 +@if errorlevel 1 goto failure +del n7.r01 +as-z80 -l -o n7.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n8 +@if errorlevel 1 goto failure +del n8.r01 +as-z80 -l -o n8.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n9 +@if errorlevel 1 goto failure +del n9.r01 +as-z80 -l -o n9.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF n10 +@if errorlevel 1 goto failure +del n10.r01 +as-z80 -l -o n10.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF ni +@if errorlevel 1 goto failure +del ni.r01 +as-z80 -l -o ni.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF nii +@if errorlevel 1 goto failure +del nii.r01 +as-z80 -l -o nii.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF ntab +@if errorlevel 1 goto failure +del ntab.r01 +as-z80 -l -o ntab.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF hytab +@if errorlevel 1 goto failure +del hytab.r01 +as-z80 -l -o hytab.s01 +@if errorlevel 1 goto failure + +iccz80 -S -w -mb -v1 -z -A -I..\..\include\ -DNROFF suftab +@if errorlevel 1 goto failure +del suftab.r01 +as-z80 -l -o suftab.s01 +@if errorlevel 1 goto failure + +link-z80 -f nroff +@if errorlevel 1 goto failure +ihex2bin -l nroff.i86 ..\..\bin\banked\nroff +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/troff/n1.c b/src/troff/n1.c new file mode 100755 index 00000000..d2e10022 --- /dev/null +++ b/src/troff/n1.c @@ -0,0 +1,1059 @@ +#if 1 /* Nick */ +#include /* for tmpnam() prototype */ +#include /* for open() and related definitions */ +#endif +#ifdef VAX /* Nick */ +#include /* original v7 unix */ +#else +#include /* for uzi c library */ +#endif +#include +#include "tdef.h" +extern +#include "d.h" +extern +#include "v.h" +#ifdef NROFF +extern +#include "tw.h" +#endif +#include "s.h" +#include +jmp_buf sjbuf; +#ifndef VAX /* Nick */ +#include +#endif + +/* +troff1.c + +consume options, initialization, main loop, +input routines, escape function calling +*/ + +extern struct s *frame, *stk, *nxf; +extern struct s *ejl, *litlev; +extern filep ip; +extern filep offset; +extern filep nextb; + + +extern int stdi; +extern int waitf; +extern int nofeed; +extern int quiet; +extern int ptid; +extern int ascii; +extern int npn; +extern int xflg; +extern int stop; +extern char ibuf[IBUFSZ]; +extern char xbuf[IBUFSZ]; +extern char *ibufp; +extern char *xbufp; +extern char *eibuf; +extern char *xeibuf; +extern int cbuf[NC]; +extern int *cp; +extern int *vlist; +extern int nx; +extern int mflg; +extern int ch; +extern int pto; +extern int pfrom; +extern int cps; +extern int chbits; +extern int ibf; +extern int ttyod; +#ifndef VAX /* Nick */ +extern struct sgttyb ttys; +#endif +extern int iflg; +extern int init; +extern int rargc; +extern char **argp; +extern char trtab[256]; +extern int lgf; +extern int copyf; +extern int eschar; +extern int ch0; +extern int cwidth; +extern int nlflg; +extern int *ap; +extern int donef; +extern int nflush; +extern int nchar; +extern int rchar; +extern int nfo; +extern int ifile; +extern int fc; +extern int padc; +extern int tabc; +extern int dotc; +extern int raw; +extern int tabtab[NTAB]; +extern char nextf[]; +extern int nfi; +#ifdef NROFF +extern char termtab[]; +extern int tti; +#endif +extern int ifl[NSO]; +extern int ifi; +extern int pendt; +extern int flss; +extern int fi; +extern int lg; +extern char ptname[]; +extern int print; +extern int nonumb; +extern int pnlist[]; +extern int *pnp; +extern int nb; +extern int trap; +extern int tflg; +extern int ejf; +extern int lit; +extern int cc; +extern int c2; +extern int spread; +extern int gflag; +extern int oline[]; +extern int *olinep; +extern int dpn; +extern int noscale; +extern char *unlkp; +extern int pts; +extern int level; +extern int ttysave; +extern int tdelim; +extern int dotT; +extern int tabch, ldrch; +extern int eqflg; +extern no_out; +extern int hflg; +#ifndef NROFF +extern char codetab[]; +extern int spbits; +#endif +extern int xxx; +int stopmesg; +filep ipl[NSO]; +long offl[NSO]; +long ioff; +char *ttyp; +extern struct contab { + int rq; + union { + int (*f)(); + unsigned mx; + }x; +}contab[NM]; +int ms[] = {31,28,31,30,31,30,31,31,30,31,30,31}; +#ifndef NROFF +int acctf; +#endif + +main(argc,argv) +int argc; +char **argv; +{ + char *p, *q; + register i, j; + extern catch(), fpecatch(), kcatch(); + +#ifdef DEBUG + fprintf(stderr, "main()\n"); + fflush(stderr); +#endif + +#ifndef VAX /* Nick */ + signal(SIGHUP,catch); + if(signal(SIGINT,catch) == SIG_IGN){ + signal(SIGHUP,SIG_IGN); + signal(SIGINT,SIG_IGN); + signal(SIGQUIT,SIG_IGN); + } + signal(SIGFPE,fpecatch); + signal(SIGPIPE,catch); + signal(SIGTERM,kcatch); +#endif + init1(argv[0][0]); +options: +#ifdef DEBUG + fprintf(stderr, "options\n"); + fflush(stderr); +#endif + while(--argc > 0 && (++argv)[0][0]=='-') + switch(argv[0][1]){ + + case 0: + goto start; + case 'i': + stdi++; + continue; + case 'q': + quiet++; +#ifndef VAX /* Nick */ + if(gtty(0, &ttys) >= 0) + ttysave = ttys.sg_flags; +#endif + continue; + case 'n': + npn = cnum(&argv[0][2]); + continue; + case 'p': + xflg = 0; + cps = cnum(&argv[0][2]); + continue; + case 'S': + stopmesg++; + continue; + case 's': + if(!(stop = cnum(&argv[0][2])))stop++; + continue; + case 'r': + vlist[findr(argv[0][2])] = cnum(&argv[0][3]); + continue; + case 'm': + p = &nextf[nfi]; + q = &argv[0][2]; + while((*p++ = *q++) != 0); + mflg++; + continue; + case 'o': + getpn(&argv[0][2]); + continue; +#ifdef NROFF + case 'h': + hflg++; + continue; + case 'z': + no_out++; + continue; + case 'e': + eqflg++; + continue; + case 'T': + p = &termtab[tti]; + q = &argv[0][2]; + if(!((*q) & 0177))continue; + while((*p++ = *q++) != 0); + dotT++; + continue; +#endif +#ifndef NROFF + case 'z': + no_out++; + case 'a': + ascii = 1; + nofeed++; + case 't': + ptid = 1; + continue; + case 'w': + waitf = 1; + continue; + case 'f': + nofeed++; + continue; + case 'x': + xflg = 0; + continue; + case 'b': + if (open(ptname, O_BINARY | O_WRONLY) < 0) + prstr("Busy.\n"); + else prstr("Available.\n"); + done3(0); + case 'g': + stop = ptid = gflag = 1; + dpn = 0; + continue; +#endif + default: + pto = cnum(&argv[0][1]); + continue; + } + + if(argv[0][0] == '+'){ + pfrom = cnum(&argv[0][1]); + print = 0; + if(argc > 0)goto options; + } + +start: +#ifdef DEBUG + fprintf(stderr, "start\n"); + fflush(stderr); +#endif + argp = argv; + rargc = argc; + init2(); + setjmp(sjbuf); +#ifdef DEBUG + fprintf(stderr, "setjmp\n"); + fflush(stderr); +#endif +loop: +#ifdef DEBUG + fprintf(stderr, "loop\n"); + fflush(stderr); +#endif + copyf = lgf = nb = nflush = nlflg = 0; + if(ip && (rbf0(ip)==0) && ejf && (frame->pframe <= ejl)){ + nflush++; + trap = 0; + eject((struct s *)0); + goto loop; + } + i = getch(); + if(pendt)goto lt; + if(lit && (frame <= litlev)){ + lit--; + goto lt; + } + if((j = (i & CMASK)) == XPAR){ + copyf++; + tflg++; + for(;(i & CMASK) != '\n';)pchar(i = getch()); + tflg = 0; + copyf--; + goto loop; + } + if((j == cc) || (j == c2)){ + if(j == c2)nb++; + copyf++; + while(((j=((i=getch()) & CMASK)) == ' ') || + (j == '\t')); + ch = i; + copyf--; + control(getrq(),1); + flushi(); + goto loop; + } +lt: + ch = i; + text(); + goto loop; +} +catch(){ +/* + prstr("Interrupt\n"); +*/ + done3(01); +} +fpecatch(){ + prstrfl("Floating Exception.\n"); +#ifndef VAX /* Nick */ + signal(SIGFPE,fpecatch); +#endif +} +kcatch(){ +#ifndef VAX /* Nick */ + signal(SIGTERM,SIG_IGN); +#endif + done3(01); +} +#ifndef NROFF +acctg() { + static char *acct_file = "/usr/adm/tracct"; + acctf = open(acct_file, O_BINARY | O_WRONLY); + setuid(getuid()); +} +#endif +init1(a) +char a; +{ + register char *p; + char *mktemp(); + register i; + +#ifdef DEBUG + fprintf(stderr, "init1(%d) starting\n", (int)a); + fflush(stderr); +#endif + +#ifndef NROFF + acctg();/*open troff actg file while mode 4755*/ +#endif + p = tmpnam(NULL); /* Nick mktemp("/tmp/taXXXXX"); */ + if(a == 'a')p = &p[5]; + if((close(creat(p, 0600))) < 0){ + prstr("Cannot create temp file.\n"); + exit(-1); + } + ibf = open(p, O_BINARY | O_RDWR); + for(i=256; --i;)trtab[i]=i; + trtab[UNPAD] = ' '; + mchbits(); + if(a != 'a')unlkp = p; +#ifdef DEBUG + fprintf(stderr, "init1() returning\n"); + fflush(stderr); +#endif +} +init2() +{ + register i,j; + extern int block; + extern char *setbrk(); +#ifndef VAX /* Nick */ + extern char *ttyname(); +#endif + +#ifdef DEBUG + fprintf(stderr, "init2() starting\n"); + fflush(stderr); +#endif + + ttyod = 2; +#ifndef VAX /* Nick */ + if(((ttyp=ttyname(j=0)) != (char *)0) || + ((ttyp=ttyname(j=1)) != (char *)0) || + ((ttyp=ttyname(j=2)) != (char *)0)) + ; + else +#endif + ttyp = "notty"; + iflg = j; + if(ascii)mesg(0); + + if((!ptid) && (!waitf)){ + if ((ptid = open(ptname, O_BINARY | O_WRONLY)) < 0){ + prstr("Typesetter busy.\n"); + done3(-2); + } + } + ptinit(); + for(i=NEV; i--;)write(ibf, (char *)&block, EVS*sizeof(int)); + olinep = oline; + ibufp = eibuf = ibuf; + v.hp = init = 0; + ioff = 0; + v.nl = -1; + cvtime(); + frame = stk = (struct s *)setbrk(DELTA); + dip = &di[0]; /* Nick d */ + nxf = frame + 1; + nx = mflg; +#ifdef DEBUG + fprintf(stderr, "init2() returning\n"); + fflush(stderr); +#endif +} +cvtime(){ + + long tt; + register i; + + time(&tt); + tt -= 3600*ZONE; /*5hrs for EST*/ + v.dy = (tt/86400L) + 1; + v.dw = (v.dy + 3)%7 + 1; +#if 1 /* Nick */ + for(v.yr=1970;; v.yr++){ +#else + for(v.yr=70;; v.yr++){ +#endif + if((v.yr)%4)ms[1]=28;else ms[1]=29; + for(i=0;i<12;){ + if(v.dy<=ms[i]){ + v.mo = i+1; + return; + } + v.dy -= ms[i++]; + } + } +} +cnum(a) +char *a; +{ + register i; + + ibufp = a; + eibuf = MAXPTR; + i = atoix(); /* Nick atoi */ + ch = 0; + return(i); +} +mesg(f) +int f; +{ + static int mode; + + if(!f){ + stat(ttyp,cbuf); + mode = ((struct stat *)(cbuf))->st_mode; + chmod(ttyp,mode & ~022); + }else{ + chmod(ttyp,mode); + } +} +prstrfl(s) +char *s; +{ + flusho(); + prstr(s); +} +prstr(s) +char *s; +{ + register i; + register char *j; + + j = s; + for(i=0;*s;i++)s++; + write(ttyod,j,i); +} +control(a,b) +int a,b; +{ + register i,j; + extern filep boff(); + + i = a; + if((i == 0) || ((j = findmn(i)) == -1))return(0); + if(contab[j].rq & MMASK){ + nxf->nargs = 0; + if(b)collect(); + flushi(); + return(pushi(((filep)contab[j].x.mx)<= eibuf) && (ibufp != MAXPTR))){ + if(nfo)goto g1; + g0: + if(nextfile()){ + if(ip)goto again; + if(ibufp < eibuf)goto g2; + } + g1: + nx = 0; + if((j=read(ifile,ibuf,IBUFSZ)) <= 0)goto g0; + ibufp = ibuf; + eibuf = ibuf + j; + if(ip)goto again; + } + g2: + i = *ibufp++ & 0177; + ioff++; + if(i >= 040)goto g4; else i = ifilt[i]; + } + if(raw)return(i); + if((j = i & CMASK) == IMP)goto again; + if((i == 0) && !init)goto again; +g4: + if((copyf == 0) && ((i & ~BMASK) == 0) && ((i & CMASK) < 0370)) +#ifndef NROFF + if(spbits && (i>31) && ((codetab[i-32] & 0200))) i |= spbits; + else +#endif + i |= chbits; + if((i & CMASK) == eschar)i = (i & ~CMASK) | ESC; + return(i); +} +nextfile(){ + register char *p; + +#ifdef DEBUG + fprintf(stderr,"nextfile() starting\n"); + fflush(stderr); +#endif + +n0: + if(ifile)close(ifile); + if(nx){ + p = nextf; + if(*p != 0)goto n1; + } + if(ifi > 0){ + if(popf())goto n0; /*popf error*/ + return(1); /*popf ok*/ + } + if(rargc-- <= 0)goto n2; + p = (argp++)[0]; +n1: + if((p[0] == '-') && (p[1] == 0)){ + ifile = 0; + }else if ((ifile=open(p, /*O_BINARY |*/ O_RDONLY)) < 0){ + prstr("Cannot open "); + prstr(p); + prstr("\n"); + nfo -= mflg; + done(02); + } +#ifdef DEBUG + fprintf(stderr,"nextfile() opened %s\n", p); + fflush(stderr); +#endif + nfo++; + v.cd = 0; + ioff = 0; +#ifdef DEBUG + fprintf(stderr,"nextfile() returning x\n", p); + fflush(stderr); +#endif + return(0); +n2: +#ifdef DEBUG + fprintf(stderr,"nextfile() done all files\n", p); + fflush(stderr); +#endif + if((nfo -= mflg) && !stdi)done(0); + nfo++; + v.cd = ifile = stdi = mflg = 0; + ioff = 0; +#ifdef DEBUG + fprintf(stderr,"nextfile() returning y\n", p); + fflush(stderr); +#endif + return(0); +} +popf(){ + register i; + register char *p, *q; +#ifndef VAX /* Nick */ + extern char *ttyname(); +#endif + + ioff = offl[--ifi]; + ip = ipl[ifi]; + if((ifile = ifl[ifi]) == 0){ + p = xbuf; + q = ibuf; + ibufp = xbufp; + eibuf = xeibuf; + while(q < eibuf)*q++ = *p++; + return(0); + } + if((lseek(ifile,(long)(ioff & ~(IBUFSZ-1)),0) < 0) || + ((i = read(ifile,ibuf,IBUFSZ)) < 0))return(1); + eibuf = ibuf + i; + ibufp = ibuf; +#ifndef VAX /* Nick */ + if(ttyname(ifile) == (char *)0) +#endif + if((ibufp = ibuf + (int)(ioff & (IBUFSZ-1))) >= eibuf) + return(1); + return(0); +} +flushi(){ + if(nflush)return; + ch = 0; + if((ch0 & CMASK) == '\n')nlflg++; + ch0 = 0; + copyf++; + while(!nlflg){ + if(donef && (frame == stk))break; + getch(); + } + copyf--; + v.hp = 0; +} +getach(){ + register i; + + lgf++; + if(((i = getch()) & MOT) || + ((i&CMASK) == ' ') || + ((i&CMASK) == '\n')|| + (i & 0200)){ + ch = i; + i = 0; + } + lgf--; + return(i & 0177); +} +casenx(){ + lgf++; + skip(); + getname(); + nx++; + nextfile(); + nlflg++; + ip = 0; + ap = 0; + nchar = pendt = 0; + frame = stk; + nxf = frame + 1; +} +getname(){ + register int i, j, k; + + lgf++; + for(k=0; k < (NS-1); k++){ + if(((j=(i=getch()) & CMASK) <= ' ') || + (j > 0176))break; + nextf[k] = j; + } + nextf[k] = 0; + ch = i; + lgf--; + return(nextf[0]); +} +caseso(){ + register i; + register char *p, *q; + +#ifdef DEBUG + fprintf(stderr, "caseso() starting\n"); + fflush(stderr); +#endif + + lgf++; + nextf[0] = 0; + if (skip() || !getname() || + ((i=open(nextf, /*O_BINARY |*/ O_RDONLY)) <0) || + (ifi >= NSO)) { + prstr("can't open file "); + prstr(nextf); + prstr("\n"); + done(02); + } +#ifdef DEBUG + fprintf(stderr, "caseso() opened file %s\n", nextf); + fflush(stderr); +#endif + flushi(); + ifl[ifi] = ifile; + ifile = i; + offl[ifi] = ioff; + ioff = 0; + ipl[ifi] = ip; + ip = 0; + nx++; + nflush++; + if(!ifl[ifi++]){ + p = ibuf; + q = xbuf; + xbufp = ibufp; + xeibuf = eibuf; + while(p < eibuf)*q++ = *p++; + } +#ifdef DEBUG + fprintf(stderr, "caseso() returning\n", nextf); + fflush(stderr); +#endif +} + +casecf(){ /* copy file without change */ + int fd, i, n; + char buf[512]; + + flusho(); + lgf++; + nextf[0] = 0; + if(skip() || !getname() || + ((fd=open(nextf, /*O_BINARY |*/ O_RDONLY)) <0) || + (ifi >= NSO)) { + prstr("can't open file "); + prstr(nextf); + prstr("\n"); + done(02); + } + while ((n = read(fd, buf, 512)) > 0) + for (i = 0; i < n; i++) + oput(buf[i]); + flusho(); + close(fd); +} +getpn(a) +char *a; +{ + register i, neg; + long atoi1(); + + if((*a & 0177) == 0)return; + neg = 0; + ibufp = a; + eibuf = MAXPTR; + noscale++; + while((i = getch() & CMASK) != 0)switch(i){ + case '+': + case ',': + continue; + case '-': + neg = MOT; + goto d2; + default: + ch = i; + d2: + i = atoi1(); + if(nonumb)goto fini; + else{ + *pnp++ = i | neg; + neg = 0; + if(pnp >= &pnlist[NPN-2]){ + prstr("Too many page numbers\n"); + done3(-3); + } + } + } +fini: + if(neg)*pnp++ = -2; + *pnp = -1; + ch = noscale = print = 0; + pnp = pnlist; + if(*pnp != -1)chkpn(); +} +setrpt(){ + register i, j; + + copyf++;raw++; + i = getch0(); + copyf--;raw--; + if((i < 0) || + (((j = getch0()) & CMASK) == RPT))return; + rchar = j; + nchar = i & BMASK; +} diff --git a/src/troff/n10.c b/src/troff/n10.c new file mode 100755 index 00000000..d68005cb --- /dev/null +++ b/src/troff/n10.c @@ -0,0 +1,302 @@ +#include /* for diagnostics */ +#include /* for open() and related definitions */ +#ifndef VAX +#include /* Nick, for wait() to waitpid() translation macro */ +#endif +#include "tdef.h" +#ifndef VAX /* Nick */ +#include +#endif +extern +#include "d.h" +extern +#include "v.h" +extern +#include "tw.h" +/* +nroff10.c + +Device interfaces +*/ + +extern int lss; +extern char obuf[]; +extern char *obufp; +extern int xfont; +extern int esc; +extern int lead; +extern int oline[]; +extern int *olinep; +extern int ulfont; +extern int esct; +extern int sps; +extern int ics; +extern int ttysave; +#ifndef VAX /* Nick */ +extern struct sgttyb ttys; +#endif +extern char termtab[]; +extern int ptid; +extern int waitf; +extern int pipeflg; +extern int eqflg; +extern int hflg; +extern int tabtab[]; +extern int ascii; +extern int xxx; +int dtab; +int bdmode; +int plotmode; + +ptinit(){ + register i, j; + register char **p; + char *q; +#ifdef VAX /* Nick */ + short x[8]; + int items, *to; + short *from; +#else + int x[8]; +#endif + extern char *setbrk(); + +#ifdef DEBUG + fprintf(stderr,"ptinit() starting\n"); + fflush(stderr); +#endif + + if ((i = open(termtab, O_BINARY | O_RDONLY)) < 0){ + prstr("Cannot open "); + prstr(termtab); + prstr("\n"); + exit(-1); + } +#ifdef VAX /* Nick */ + read(i,(char *)x,8*sizeof(short)); + items = (short *)&ts.zzz - &ts.bset; + read(i,(char *)&ts.bset,j = sizeof(short)*items); + from = &ts.bset; + to=&t.bset; + while (from < (short *)&ts.zzz) + { + *to++ = *from++; /* sign extend */ + } +#else + read(i,(char *)x,8*sizeof(int)); + read(i,(char *)&t.bset,j = sizeof(int)*((int *)&t.zzz - &t.bset)); +#endif + x[2] -= j; + q = setbrk(x[2]); +#ifdef VAX /* Nick */ + lseek(i,(long)t.twinit+8*sizeof(short),0); +#else + lseek(i,(long)t.twinit+8*sizeof(int),0); +#endif + i = read(i,q,x[2]); + j = q - t.twinit; + for(p = &t.twinit; p < &t.zzz; p++){ + if(*p)*p += j;else *p = ""; + } + sps = EM; + ics = EM*2; + dtab = 8 * t.Em; + for(i=0; i<16; i++)tabtab[i] = dtab * (i+1); + if(eqflg)t.Adj = t.Hor; +#ifdef DEBUG + fprintf(stderr,"ptinit() returning\n"); + fflush(stderr); +#endif +} +twdone(){ + obufp = obuf; + oputs(t.twrest); + flusho(); + if(pipeflg){ + close(ptid); +#ifndef VAX /* Nick */ + wait(&waitf); +#endif + } +#ifndef VAX /* Nick */ + if(ttysave != -1) { + ttys.sg_flags = ttysave; + stty(1, &ttys); + } +#endif +} +ptout(i) +int i; +{ + *olinep++ = i; + if(olinep >= &oline[LNSIZE])olinep--; + if((i&CMASK) != '\n')return; + olinep--; + lead += dip->blss + lss - t.Newline; + dip->blss = 0; + esct = esc = 0; + if(olinep>oline){ + move(); + ptout1(); + oputs(t.twnl); + }else{ + lead += t.Newline; + move(); + } + lead += dip->alss; + dip->alss = 0; + olinep = oline; +} +ptout1() +{ + register i, k; + register char *codep; + extern char *plot(); + int *q, w, j, phyw; + + for(q=oline; q>9) & 03; + if(*t.bdon & 0377){ + if(!bdmode && (xfont == 2)){ + oputs(t.bdon); + bdmode++; + } + if(bdmode && (xfont != 2)){ + oputs(t.bdoff); + bdmode = 0; + } + } + if(xfont == ulfont){ + for(k=w/t.Char;k>0;k--)oput('_'); + for(k=w/t.Char;k>0;k--)oput('\b'); + } + while(*codep != 0){ + if(*codep & 0200){ + codep = plot(codep); + oputs(t.plotoff); + oput(' '); + }else{ + if(plotmode)oputs(t.plotoff); + *obufp++ = *codep++; + if(obufp == (obuf + OBUFSZ + ascii - 1))flusho(); +/* oput(*codep++);*/ + } + } + if(!w)for(k=phyw/t.Char;k>0;k--)oput('\b'); + } +} +char *plot(x) +char *x; +{ + register int i; + register char *j, *k; + + if(!plotmode)oputs(t.ploton); + k = x; + if((*k & 0377) == 0200)k++; + for(; *k; k++){ + if(*k & 0200){ + if(*k & 0100){ + if(*k & 040)j = t.up; else j = t.down; + }else{ + if(*k & 040)j = t.left; else j = t.right; + } + if(!(i = *k & 037))return(++k); + while(i--)oputs(j); + }else oput(*k); + } + return(k); +} +move(){ + register k; + register char *i, *j; + char *p, *q; + int iesct, dt; + + iesct = esct; + if(esct += esc)i = "\0"; else i = "\n\0"; + j = t.hlf; + p = t.right; + q = t.down; + if(lead){ + if(lead < 0){ + lead = -lead; + i = t.flr; + /* if(!esct)i = t.flr; else i = "\0";*/ + j = t.hlr; + q = t.up; + } + if(*i & 0377){ + k = lead/t.Newline; + lead = lead%t.Newline; + while(k--)oputs(i); + } + if(*j & 0377){ + k = lead/t.Halfline; + lead = lead%t.Halfline; + while(k--)oputs(j); + } + else { /* no half-line forward, not at line begining */ + k = lead/t.Newline; + lead = lead%t.Newline; + if (k>0) esc=esct; + i = "\n"; + while (k--) oputs(i); + } + } + if(esc){ + if(esc < 0){ + esc = -esc; + j = "\b"; + p = t.left; + }else{ + j = " "; + if(hflg)while((dt = dtab - (iesct%dtab)) <= esc){ + if(dt%t.Em)break; + oput(TAB); + esc -= dt; + iesct += dt; + } + } + k = esc/t.Em; + esc = esc%t.Em; + while(k--)oputs(j); + } + if((*t.ploton & 0377) && (esc || lead)){ + if(!plotmode)oputs(t.ploton); + esc /= t.Hor; + lead /= t.Vert; + while(esc--)oputs(p); + while(lead--)oputs(q); + oputs(t.plotoff); + } + esc = lead = 0; +} +ptlead(){move();} +dostop(){ + char junk; + + flusho(); + read(2,&junk,1); +} diff --git a/src/troff/n2.c b/src/troff/n2.c new file mode 100755 index 00000000..9a33fb06 --- /dev/null +++ b/src/troff/n2.c @@ -0,0 +1,366 @@ +#include /* for diagnostics */ +#include /* for open() and related definitions */ +#include "tdef.h" +#ifndef VAX /* Nick */ +#include +#endif +extern +#include "d.h" +extern +#include "v.h" +#ifdef NROFF +extern +#include "tw.h" +#endif +#include "s.h" +#include +extern jmp_buf sjbuf; /* defined in n1.c */ + +/* +troff2.c + +output, cleanup +*/ + +extern struct s *frame, *stk, *nxf; +extern filep ip; +extern filep offset; +extern char *enda; + + +extern char obuf[OBUFSZ]; +extern char *obufp; +extern int dilev; +extern int eschar; +extern int tlss; +extern int tflg; +extern int ascii; +extern int print; +extern char trtab[]; +extern int waitf; +extern char ptname[]; +extern int ptid; +extern int em; +extern int ds; +extern int mflg; +extern filep woff; +extern int nflush; +extern int lgf; +extern int app; +extern int nfo; +extern int donef; +extern int *pendw; +extern int nofeed; +extern int trap; +#ifndef VAX /* Nick */ +extern struct sgttyb ttys; +#endif +extern int ttysave; +extern int quiet; +extern int pendnf; +extern int ndone; +extern int lead; +extern int ralss; +extern int paper; +extern int gflag; +extern char *unlkp; +extern char nextf[]; +extern int pipeflg; +extern int ejf; +extern int no_out; +extern int level; +extern int stopmesg; +extern int xxx; +int toolate; +int error; +#ifndef NROFF +extern int acctf; +#endif + +pchar(c) +int c; +{ + register i, j; + + if((i=c) & MOT){pchar1(i); return;} + switch(j = i & CMASK){ + case 0: + case IMP: + case RIGHT: + case LEFT: + return; + case HX: + j = (tlss>>9) | ((i&~0777)>>3); + if(i & 040000){ + j &= ~(040000>>3); + if(j > dip->blss)dip->blss = j; + }else{ + if(j > dip->alss)dip->alss = j; + ralss = dip->alss; + } + tlss = 0; + return; + case LX: + tlss = i; + return; + case PRESC: + if(dip == &di[0])j = eschar; /* Nick d */ + default: + i = (trtab[j] & BMASK) | (i & ~CMASK); + } + pchar1(i); +} +pchar1(c) +int c; +{ + register i, j, *k; + extern int chtab[]; + + j = (i = c) & CMASK; + if(dip != &di[0]){ /* Nick d */ + wbf(i); + dip->op = offset; + return; + } + if(!tflg && !print){ + if(j == '\n')dip->alss = dip->blss = 0; + return; + } + if(no_out || (j == FILLER))return; +#ifndef NROFF + if(ascii){ + if(i & MOT){ + oput(' '); + return; + } + if(j < 0177){ + oput(i); + return; + } + switch(j){ + case 0200: + case 0210: + oput('-'); + break; + case 0211: + oputs("fi"); + break; + case 0212: + oputs("fl"); + break; + case 0213: + oputs("ff"); + break; + case 0214: + oputs("ffi"); + break; + case 0215: + oputs("ffl"); + break; + default: + for(k=chtab; *++k != j; k++) + if(*k == 0)return; + oput('\\'); + oput('('); + oput(*--k & BMASK); + oput(*k >> BYTE); + } + }else +#endif + ptout(i); +} +oput(i) +char i; +{ + *obufp++ = i; + if(obufp == (obuf + OBUFSZ + ascii - 1))flusho(); +} +oputs(i) +char *i; +{ + while(*i != 0)oput(*i++); +} +flusho(){ + if(!ascii)*obufp++ = 0; + if(!ptid){ + while ((ptid=open(ptname, O_BINARY | O_WRONLY)) < 0){ + if(++waitf <=2)prstr("Waiting for Typesetter.\n"); +#ifndef VAX /* Nick */ + sleep(15); +#endif + } + } + if(no_out == 0){ + if (!toolate) { + toolate++; +#ifdef NROFF +#ifndef VAX /* Nick */ + if(t.bset || t.breset){ + if(ttysave == -1) { + gtty(1, &ttys); + ttysave = ttys.sg_flags; + } + ttys.sg_flags &= ~t.breset; + ttys.sg_flags |= t.bset; + stty(1, &ttys); + } +#endif + { + char *p = t.twinit; + while (*p++) + ; + write(ptid, t.twinit, p-t.twinit-1); + } +#endif + } + toolate += write(ptid, obuf, obufp-obuf); + } + obufp = obuf; +} +done(x) int x;{ + register i; + + error |= x; + level = 0; + app = ds = lgf = 0; + if(i=em){ + donef = -1; + em = 0; + if(control(i,0)) + { +#ifdef DEBUG + fprintf(stderr, "longjmp 1\n"); + fflush(stderr); +#endif + longjmp(sjbuf,1); + } + } + if(!nfo)done3(0); + mflg = 0; + dip = &di[0]; /* Nick d */ + if(woff)wbt(0); + if(pendw)getword(1); + pendnf = 0; + if(donef == 1)done1(0); + donef = 1; + ip = 0; + frame = stk; + nxf = frame + 1; + if(!ejf)tbreak(); + nflush++; + eject((struct s *)0); +#ifdef DEBUG + fprintf(stderr, "longjmp 2\n"); + fflush(stderr); +#endif + longjmp(sjbuf,1); +} +done1(x) int x; { + error |= x; + if(v.nl){ + trap = 0; + eject((struct s *)0); +#ifdef DEBUG + fprintf(stderr, "longjmp 3\n"); + fflush(stderr); +#endif + longjmp(sjbuf,1); + } + if(nofeed){ + ptlead(); + flusho(); + done3(0); + }else{ + if(!gflag)lead += TRAILER; + done2(0); + } +} +done2(x) int x; { + register i; + + ptlead(); +#ifndef NROFF + if(!ascii){ + oput(T_INIT); + oput(T_STOP); + if(!gflag)for(i=8; i>0; i--)oput(T_PAD); + if(stopmesg)prstr("Troff finished.\n"); + } +#endif + flusho(); + done3(x); +} +done3(x) int x;{ + error |= x; +#ifndef VAX /* Nick */ + signal(SIGINT, SIG_IGN); + signal(SIGTERM, SIG_IGN); +#endif +#if 1 /* Nick */ + if (unlkp) +#endif + unlink(unlkp); +#ifdef NROFF + twdone(); +#endif +#ifndef VAX /* Nick */ + if(quiet){ + ttys.sg_flags |= ECHO; + stty(0, &ttys); + } +#endif + if(ascii)mesg(1); +#ifndef NROFF + report(); +#endif + exit(error); +} +edone(x) int x;{ + frame = stk; + nxf = frame + 1; + ip = 0; + done(x); +} +#ifndef NROFF +report(){ + struct {int use; int uid;} a; + + if((ptid != 1) && paper ){ + lseek(acctf,0L,2); + a.use = paper; + a.uid = getuid(); + write(acctf,(char *)&a,sizeof(a)); + } +} +#endif +#ifdef NROFF +casepi(){ + register i; + int id[2]; + + if(toolate || skip() || !getname() +#ifndef VAX /* Nick */ + || (pipe(id) == -1) || ((i=fork()) == -1) +#endif + ) + { + prstr("Pipe not created.\n"); + return; + } + ptid = id[1]; + if(i>0){ + close(id[0]); + toolate++; + pipeflg++; + return; + } + close(0); + dup(id[0]); + close(id[1]); + execl(nextf,nextf,0); + prstr("Cannot exec: "); + prstr(nextf); + prstr("\n"); + exit(-4); +} +#endif diff --git a/src/troff/n3.c b/src/troff/n3.c new file mode 100755 index 00000000..2f0417df --- /dev/null +++ b/src/troff/n3.c @@ -0,0 +1,709 @@ +#ifdef VAX /* Nick */ +#include +#define NULL 0 +#endif +#include "tdef.h" +extern +#include "d.h" +extern +#include "v.h" +#ifdef NROFF +extern +#include "tw.h" +#endif +#include "s.h" + +/* +troff3.c + +macro and string routines, storage allocation +*/ + +unsigned blist[NBLIST]; +extern struct s *frame, *stk, *nxf; +extern filep ip; +extern filep offset; +extern filep nextb; +extern char *enda; + +extern int ch; +extern int ibf; +extern int lgf; +extern int copyf; +extern int ch0; +extern int app; +extern int ds; +extern int nlflg; +extern int *argtop; +extern int *ap; +extern int nchar; +extern int pendt; +extern int rchar; +extern int dilev; +extern int nonumb; +extern int lt; +extern int nrbits; +extern int nform; +extern int fmt[]; +extern int oldmn; +extern int newmn; +extern int macerr; +extern filep apptr; +extern int diflg; +extern filep woff; +extern filep roff; +extern int wbfi; +extern int po; +extern int *cp; +extern int xxx; +int pagech = '%'; +int strflg; +extern struct contab { + int rq; + union { + int (*f)(); + unsigned mx; + }x; +}contab[NM]; +#ifdef VAX /* Nick */ +short wbuf[BLK]; +short rbuf[BLK]; +#else +int wbuf[BLK]; +int rbuf[BLK]; +#endif + +caseig(){ + register i; + + offset = 0; + if((i = copyb()) != '.')control(i,1); +} +casern(){ + register i,j; + + lgf++; + skip(); + if(((i=getrq())==0) || ((oldmn=findmn(i)) < 0))return; + skip(); + clrmn(findmn(j=getrq())); + if(j)contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j; +} +caserm(){ + lgf++; + while(!skip()){ + clrmn(findmn(getrq())); + } +} +caseas(){ + app++; + caseds(); +} +caseds(){ + ds++; + casede(); +} +caseam(){ + app++; + casede(); +} +casede(){ + register i, req; + register filep savoff; + extern filep finds(); + + if(dip != di)wbfl(); /* Nick d */ + req = '.'; + lgf++; + skip(); + if((i=getrq())==0)goto de1; + if((offset=finds(i)) == 0)goto de1; + if(ds)copys(); + else req = copyb(); + wbfl(); + clrmn(oldmn); + if(newmn)contab[newmn].rq = i | MMASK; + if(apptr){ + savoff = offset; + offset = apptr; + wbt(IMP); + offset = savoff; + } + offset = dip->op; + if(req != '.')control(req,1); +de1: + ds = app = 0; + return; +} +findmn(i) +int i; +{ + register j; + + for(j=0;j= 0){ + if(contab[i].rq & MMASK)ffree(((filep)contab[i].x.mx)<= 0) && (contab[oldmn].rq & MMASK)){ + savip = ip; + ip = (((filep)contab[oldmn].x.mx)< 1)done2(02); + prstr("Too many string/macro names.\n"); + edone(04); + return(offset = 0); + } + contab[i].x.mx = (unsigned)(nextb>>BLKBITS); + if(!diflg){ + newmn = i; + if(oldmn == -1)contab[i].rq = -1; + }else{ + contab[i].rq = mn | MMASK; + } + } + + app = 0; + return(offset = nextb); +} +skip(){ + register i; + + while(((i=getch()) & CMASK) == ' '); + ch=i; + return(nlflg); +} +copyb() +{ + register i, j, k; + int ii, req, state; + filep savoff; + + if(skip() || !(j=getrq()))j = '.'; + req = j; + k = j>>BYTE; + j &= BMASK; + copyf++; + flushi(); + nlflg = 0; + state = 1; + while(1){ + i = (ii = getch()) & CMASK; + if(state == 3){ + if(i == k)break; + if(!k){ + ch = ii; + i = getach(); + ch = ii; + if(!i)break; + } + state = 0; + goto c0; + } + if(i == '\n'){ + state = 1; + nlflg = 0; + goto c0; + } + if((state == 1) && (i == '.')){ + state++; + savoff = offset; + goto c0; + } + if((state == 2) && (i == j)){ + state++; + goto c0; + } + state = 0; +c0: + if(offset)wbf(ii); + } + if(offset){ + wbfl(); + offset = savoff; + wbt(0); + } + copyf--; + return(req); +} +copys() +{ + register i; + + copyf++; + if(skip())goto c0; + if(((i=getch()) & CMASK) != '"')wbf(i); + while(((i=getch()) & CMASK) != '\n')wbf(i); +c0: + wbt(0); + copyf--; +} +filep alloc() +{ + register i; + extern filep boff(); + filep j; + + for(i=0;i>BLKBITS); + } + offset = ((filep)blist[j])<= BLK)wbfl(); +} +wbfl(){ + if(woff == 0)return; +#ifdef VAX /* Nick */ + lseek(ibf, ((long)woff) * sizeof(short), 0); + write(ibf, (char *)wbuf, wbfi * sizeof(short)); +#else + lseek(ibf, ((long)woff) * sizeof(int), 0); + write(ibf, (char *)wbuf, wbfi * sizeof(int)); +#endif + if((woff & (~(BLK-1))) == (roff & (~(BLK-1))))roff = -1; + woff = 0; +} +blisti(i) +filep i; +{ + return((i-NEV*EVS)/(BLK)); +} +rbf(){ + register i; + extern filep incoff(); + + if((i=rbf0(ip)) == 0){ + if(!app)i = popi(); + }else{ + ip = incoff(ip); + } + return(i); +} +rbf0(p) +filep p; +{ + register filep i; + + if((i = (p & (~(BLK-1)))) != roff){ + roff = i; +#ifdef VAX /* Nick */ + lseek(ibf, ((long)roff) * sizeof(short), 0); + if (read(ibf, (char *)rbuf, BLK * sizeof(short)) == 0) +#else + lseek(ibf, ((long)roff) * sizeof(int), 0); + if (read(ibf, (char *)rbuf, BLK * sizeof(int)) == 0) +#endif + return(0); + } +#ifdef VAX /* Nick */ + return (int)(rbuf[p & (BLK-1)]) & 0xffff; +#else + return(rbuf[p & (BLK-1)]); +#endif +} +filep incoff(p) +filep p; +{ + register i; + register filep j; + if(!((j = (++p)) & (BLK-1))){ + if((i = blist[blisti(--p)]) == -1){ + prstr("Bad storage allocation.\n"); + done2(-5); + } + j = ((filep)i)<nargs = 0; + frame = p->pframe; + ip = p->pip; + nchar = p->pnchar; + rchar = p->prchar; + pendt = p->ppendt; + ap = p->pap; + cp = p->pcp; + ch0 = p->pch0; + return(p->pch); +} +pushi(newip) +filep newip; +{ + register struct s *p; + extern char *setbrk(); + + if((enda - sizeof(struct s)) < (char *)nxf)setbrk(DELTA); + p = nxf; + p->pframe = frame; + p->pip = ip; + p->pnchar = nchar; + p->prchar = rchar; + p->ppendt = pendt; + p->pap = ap; + p->pcp = cp; + p->pch0 = ch0; + p->pch = ch; + cp = ap = 0; + nchar = rchar = pendt = ch0 = ch = 0; + frame = nxf; + if(nxf->nargs == 0) nxf += 1; + else nxf = (struct s *)argtop; + return(ip = newip); +} +char *setbrk(x) +int x; +{ + register char *i; +#ifdef VAX /* Nick */ + static int pbrk = 0; + static char *pool = NULL; +#else + char *sbrk(); +#endif + +#ifdef VAX /* Nick */ + if (pool == NULL) + { + pool = (char *)malloc(0x10000); /* 64 kbytes */ + if (pool == NULL) + { + prstrfl("Can't allocate pool.\n"); + edone(0100); + } + } + i = &pool[pbrk]; + pbrk += x; + if (pbrk > 0x10000) { +#else + if((i = sbrk(x)) == MAXPTR){ +#endif + prstrfl("Core limit reached.\n"); + edone(0100); + }else{ + enda = i + x; + } + return(i); +} +getsn(){ + register i; + + if((i=getach()) == 0)return(0); + if(i == '(')return(getrq()); + else return(i); +} +setstr(){ + register i; + + lgf++; + if(((i=getsn()) == 0) || + ((i=findmn(i)) == -1) || + !(contab[i].rq & MMASK)){ + lgf--; + return(0); + }else{ + if((enda-2) < (char *)nxf)setbrk(DELTA); + nxf->nargs = 0; + strflg++; + lgf--; + return(pushi(((filep)contab[i].x.mx)<nargs = 0; + savnxf = nxf; + if(skip())goto rtn; + lim = (int *)(nxf = savnxf + sizeof(struct s)/sizeof(savnxf)); + strflg = 0; + if((argppend = + (argpp = (int **)savnxf+(sizeof(struct s)/sizeof(int **))) + (sizeof(struct s)-1)) + > (int **)enda)setbrk(DELTA); + strp = (int *)argppend; + for(i=8; i>=0; i--)argpp[i] = 0; + while((argpp != argppend) && (!skip())){ + *argpp++ = strp; + quote = 0; + if(((i = getch()) & CMASK) == '"')quote++; + else ch = i; + while(1){ + i = getch(); + if( nlflg || + ((!quote) && ((i & CMASK) == ' ')))break; + if(quote && ((i & CMASK) == '"') && + (((i=getch()) & CMASK) != '"')){ + ch = i; + break; + } + *strp++ = i; + if(strflg && (strp >= lim)){ + prstrfl("Macro argument too long.\n"); + copyf--; + edone(004); + } + if((enda-4) <= (char *)strp)setbrk(DELTA); + } + *strp++ = 0; + } + nxf = savnxf; + nxf->nargs = argpp -(int **)(nxf + 1); + argtop = strp; +rtn: + copyf--; +} +seta() +{ + register i; + + if(((i = (getch() & CMASK) - '0') > 0) && + (i <= 9) && (i <= frame->nargs))ap = *((int **)frame + i-1 + (sizeof(struct s)/sizeof(int **))); +} +caseda(){ + app++; + casedi(); +} +casedi(){ + register i, j; + register *k; + + lgf++; + if(skip() || ((i=getrq()) == 0)){ + if(dip != di)wbt(0); /* Nick d */ + if(dilev > 0){ + v.dn = dip->dnl; + v.dl = dip->maxl; + dip = &di[--dilev]; /* Nick d */ + offset = dip->op; + } + goto rtn; + } + if(++dilev == NDI){ + --dilev; + prstr("Cannot divert.\n"); + edone(02); + } + if(dip != di)wbt(0); /* Nick d */ + diflg++; + dip = &di[dilev]; /* Nick d */ + dip->op = finds(i); + dip->curd = i; + clrmn(oldmn); + k = (int *)&dip->dnl; + for(j=0; j<10; j++)k[j] = 0; /*not op and curd*/ +rtn: + app = 0; + diflg = 0; +} +casedt(){ + lgf++; + dip->dimac = dip->ditrap = dip->ditf = 0; + skip(); + dip->ditrap = vnumb((int *)0); + if(nonumb)return; + skip(); + dip->dimac = getrq(); +} +casetl(){ + register i, j; + int w1, w2, w3, delim; + filep begin; + extern width(), pchar(); + + dip->nls = 0; + skip(); + if(dip != di)wbfl(); /* Nick d */ + if((offset = begin = alloc()) == 0)return; + if((delim = getch()) & MOT){ + ch = delim; + delim = '\''; + }else delim &= CMASK; + if(!nlflg) + while(((i = getch()) & CMASK) != '\n'){ + if((i & CMASK) == delim)i = IMP; + wbf(i); + } + wbf(IMP);wbf(IMP);wbt(0); + + w1 = hseg(width,begin); + w2 = hseg(width,(filep)0); + w3 = hseg(width,(filep)0); + offset = dip->op; +#ifdef NROFF + if(!offset)horiz(po); +#endif + hseg(pchar,begin); + if(w2 || w3)horiz(j=quant((lt - w2)/2-w1,HOR)); + hseg(pchar,(filep)0); + if(w3){ + horiz(lt-w1-w2-w3-j); + hseg(pchar,(filep)0); + } + newline(0); + if(dip != di){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;} /* Nick d */ + else{if(v.nl > dip->hnl)dip->hnl = v.nl;} + ffree(begin); +} +casepc(){ + pagech = chget(IMP); +} +hseg(f,p) +int (*f)(); +filep p; +{ + register acc, i; + static filep q; + + acc = 0; + if(p)q = p; + while(1){ + i = rbf0(q); + q = incoff(q); + if(!i || (i == IMP))return(acc); + if((i & CMASK) == pagech){ + nrbits = i & ~CMASK; + nform = fmt[findr('%')]; + acc += fnumb(v.pn,f); + }else acc += (*f)(i); + } +} +casepm(){ + register i, k; + register char *p; + int xx, cnt, kk, tot; + filep j; + char *kvt(); + char pmline[10]; + + kk = cnt = 0; + tot = !skip(); + for(i = 0; i> BYTE) & 0177))*(p-1) = ' '; + *p++ = ' '; + kvt(k,p); + prstr(pmline); + } + } + if(tot || (cnt > 1)){ + kvt(kk,pmline); + prstr(pmline); + } +} +char *kvt(k,p) +int k; +char *p; +{ + if(k>=100)*p++ = k/100 + '0'; + if(k>=10)*p++ = (k%100)/10 + '0'; + *p++ = k%10 + '0'; + *p++ = '\n'; + *p = 0; + return(p); +} +dummy(){} diff --git a/src/troff/n4.c b/src/troff/n4.c new file mode 100755 index 00000000..38f87ae8 --- /dev/null +++ b/src/troff/n4.c @@ -0,0 +1,526 @@ +#include "tdef.h" +extern +#include "d.h" +extern +#include "v.h" +#ifdef NROFF +extern +#include "tw.h" +#endif +#include "s.h" +/* +troff4.c + +number registers, conversion, arithmetic +*/ + +extern struct s *frame; + +extern int ascii; +extern int cbuf[NC]; +extern int *cp; +extern int rx[NN]; /* Nick r */ +extern int *vlist; +extern int inc[NN]; +extern int fmt[NN]; +extern int ch; +extern int lgf; +extern int pl; +extern int lastl; +extern int ralss; +extern int totout; +extern int nrbits; +extern int nonumb; +extern int vflag; +extern int noscale; +extern int dfact; +extern int dfactd; +extern int po; +extern int nform; +extern int ll; +extern int in; +extern int font; +extern int bdtab[]; +extern int lss; +extern int pts; +extern int fi; +extern int res; +extern int cwidth; +extern int dotT; +extern int ev; +extern int ne; +extern int ad, admod; +extern int print; +extern int ls; +extern int nel, un; +extern int xxx; +int regcnt = NNAMES; + +setn() +{ + register i,j; + int f; + + f = nform = 0; + if((i=getch() & CMASK) == '+')f = 1; + else if(i == '-')f = -1; + else ch = i; + if((i=getsn()) == 0)return; + if((i & 0177) == '.')switch(i>>BYTE){ + case 's': i = pts & 077; break; + case 'v': i = lss; break; + case 'f': i = font + 1; break; + case 'p': i = pl; break; + case 't': i = findt1(); break; + case 'o': i = po; break; + case 'l': i = ll; break; + case 'i': i = in; break; + case '$': i = frame->nargs; break; + case 'A': i = ascii; break; + case 'c': i = v.cd; break; + case 'n': i = lastl; break; + case 'a': i = ralss; break; + case 'h': i = dip->hnl; break; + case 'd': + if(dip != di)i = dip->dnl; else i = v.nl; /* Nick d */ + break; + case 'u': i = fi; break; + case 'j': i = ad + 2*admod; break; + case 'w': i = cwidth; break; + case 'x': i = nel; break; + case 'y': i = un; break; + case 'T': i = dotT; break; /*-Tterm used in nroff*/ + case 'V': i = VERT; break; + case 'H': i = HOR; break; + case 'k': i = ne; break; + case 'P': i = print; break; + case 'L': i = ls; break; + case 'R': i = NN - regcnt; break; + case 'z': i = dip->curd; + cbuf[0] = i & BMASK; + cbuf[1] = (i >> BYTE) & BMASK; + cbuf[2] = 0; + cp = cbuf; + return; +#ifndef NROFF + case 'b': i = bdtab[font]; break; +#endif + + default: + goto s0; + } + else{ +s0: + if((j=findr(i)) == -1)i = 0; + else{ + i = (vlist[j] = (vlist[j] + inc[j]*f)); + nform = fmt[j]; + } + } + setn1(i); + cp = cbuf; +} +setn1(i) +int i; +{ + extern int wrc(); + + cp = cbuf; + nrbits = 0; + fnumb(i,wrc); + *cp = 0; + cp = cbuf; +} +findr(i) +int i; +{ + register j; + static int numerr; + + if(i == 0)return(-1); + for(j=0;j 1)done2(04); else edone(04); + } + return(j); +} +fnumb(i,f) +int i, (*f)(); +{ + register j; + + j = 0; + if(i < 0){ + j = (*f)('-' | nrbits); + i = -i; + } + switch(nform){ + default: + case '1': + case 0: return(decml(i,f) + j); + case 'i': + case 'I': return(roman(i,f) + j); + case 'a': + case 'A': return(abc(i,f) + j); + } +} +decml(i,f) +int i, (*f)(); +{ + register j,k; + + k = 0; + nform--; + if((j=i/10) || (nform > 0))k = decml(j,f); + return(k + (*f)((i%10 + '0') | nrbits)); +} +roman(i,f) +int i, (*f)(); +{ + + if(!i)return((*f)('0' | nrbits)); + if(nform == 'i')return(roman0(i,f,"ixcmz","vldw")); + else return(roman0(i,f,"IXCMZ","VLDW")); +} +roman0(i,f,onesp,fivesp) +int i, (*f)(); +char *onesp, *fivesp; +{ + register q, rem, k; + + k = 0; + if(!i)return(0); + k = roman0(i/10,f,onesp+1,fivesp+1); + q = (i=i%10)/5; + rem = i%5; + if(rem == 4){ + k += (*f)(*onesp | nrbits); + if(q)i = *(onesp+1); + else i = *fivesp; + return(k += (*f)(i | nrbits)); + } + if(q)k += (*f)(*fivesp | nrbits); + while(--rem >= 0) + k += (*f)(*onesp | nrbits); + return(k); +} +abc(i,f) +int i, (*f)(); +{ + if(!i)return((*f)('0' | nrbits)); + else return(abc0(i-1,f)); +} +abc0(i,f) +int i, (*f)(); +{ + register j, k; + + k = 0; + if(j=i/26)k = abc0(j-1,f); + return(k + (*f)((i%26 + nform) | nrbits)); +} +wrc(i) +int i; +{ + if(cp >= &cbuf[NC])return(0); + *cp++ = i; + return(1); +} +atoix(){ /* Nick atoi */ + extern long atoi0(); + + return((int)atoi0()); +} +long atoi0() +{ + register ii, k, cnt; + long i, acc; + extern long ckph(); + + i = 0; acc = 0; + nonumb = 0; + cnt = -1; +a0: + cnt++; + switch((ii=getch()) & CMASK){ + default: + ch = ii; + if(cnt)break; + case '+': + i = ckph(); + if(nonumb)break; + acc += i; + goto a0; + case '-': + i = ckph(); + if(nonumb)break; + acc -= i; + goto a0; + case '*': + i = ckph(); + if(nonumb)break; + acc *= i; + goto a0; + case '/': + i = ckph(); + if(nonumb)break; + if(i == 0){ + prstrfl("Divide by zero.\n"); + acc = 0; + }else acc /= i; + goto a0; + case '%': + i = ckph(); + if(nonumb)break; + acc %= i; + goto a0; + case '&': /*and*/ + i = ckph(); + if(nonumb)break; + if((acc > 0) && (i > 0))acc = 1; else acc = 0; + goto a0; + case ':': /*or*/ + i = ckph(); + if(nonumb)break; + if((acc > 0) || (i > 0))acc = 1; else acc = 0; + goto a0; + case '=': + if(((ii=getch()) & CMASK) != '=')ch = ii; + i = ckph(); + if(nonumb){acc = 0; break;} + if(i == acc)acc = 1; + else acc = 0; + goto a0; + case '>': + k = 0; + if(((ii=getch()) & CMASK) == '=')k++; else ch =ii; + i = ckph(); + if(nonumb){acc = 0; break;} + if(acc > (i - k))acc = 1; else acc = 0; + goto a0; + case '<': + k = 0; + if(((ii=getch()) & CMASK) == '=')k++; else ch =ii; + i = ckph(); + if(nonumb){acc = 0; break;} + if(acc < (i + k))acc = 1; else acc = 0; + goto a0; + case ')': break; + case '(': + acc = atoi0(); + goto a0; + } + return(acc); +} +long ckph(){ + register i; + long j; + extern long atoi0(); + extern long atoi1(); + + if(((i = getch()) & CMASK) == '(')j = atoi0(); + else{ + ch = i; + j = atoi1(); + } + return(j); +} +long atoi1() +{ + register i, j, digits; + long acc; + int neg, abs, field; + + neg = abs = field = digits = 0; + acc = 0; +a0: + switch((i = getch()) & CMASK){ + default: + ch = i; + break; + case '+': + goto a0; + case '-': + neg = 1; + goto a0; + case '|': + abs = 1 + neg; + neg = 0; + goto a0; + } +a1: + while(((j = ((i = getch()) & CMASK) - '0') >= 0) && (j <= 9)){ + field++; + digits++; + acc = 10*acc + j; + } + if((i & CMASK) == '.'){ + field++; + digits = 0; + goto a1; + } + ch = i; + if(!field)goto a2; + switch((i = getch()) & CMASK){ + case 'u': + i = j = 1; + break; + case 'v': /*VSs - vert spacing*/ + j = lss; + i = 1; + break; + case 'm': /*Ems*/ + j = EM; + i = 1; + break; + case 'n': /*Ens*/ + j = EM; +#ifndef NROFF + i = 2; +#endif +#ifdef NROFF + i = 1; /*Same as Ems in NROFF*/ +#endif + break; + case 'p': /*Points*/ + j = INCH; + i = 72; + break; + case 'i': /*Inches*/ + j = INCH; + i = 1; + break; + case 'c': /*Centimeters*/ + j = INCH*50; + i = 127; + break; + case 'P': /*Picas*/ + j = INCH; + i = 6; + break; + default: + j = dfact; + ch = i; + i = dfactd; + } + if(neg) acc = -acc; + if(!noscale){ + acc = (acc*j)/i; + } + if((field != digits) && (digits > 0))while(digits--)acc /= 10; + if(abs){ + if(dip != di)j = dip->dnl; else j = v.nl; /* Nick d */ + if(!vflag)j = v.hp; + if(abs == 2)j = -j; + acc -= j; + } +a2: + nonumb = !field; + return(acc); +} +caserr(){ + register i,j; + + lgf++; + while(!skip() && (i=getrq()) ){ + for(j=NNAMES; j= '0') && + (j <= '9'))k++; + } + if(!k)k=j; + fmt[findr(i)] = k & BMASK; +} +vnumb(i) +int *i; +{ + vflag++; + dfact = lss; + res = VERT; + return(inumb(i)); +} +hnumb(i) +int *i; +{ + dfact = EM; + res = HOR; + return(inumb(i)); +} +inumb(n) +int *n; +{ + register i, j, f; + + f = 0; + if(n){ + if((j = (i = getch()) & CMASK) == '+')f = 1; + else if(j == '-')f = -1; + else ch = i; + } + i = atoix(); /* Nick atoi */ + if(n && f)i = *n + f*i; + i = quant(i,res); + vflag = 0; + res = dfactd = dfact = 1; + if(nonumb)i = 0; + return(i); +} +quant(n,m) +int n, m; +{ + register i, neg; + + neg = 0; + if(n<0){ + neg++; + n = -n; + } + i = n/m; + if((n - m*i) > (m/2))i += 1; + i *= m; + if(neg)i = -i; + return(i); +} diff --git a/src/troff/n5.c b/src/troff/n5.c new file mode 100755 index 00000000..4c822a38 --- /dev/null +++ b/src/troff/n5.c @@ -0,0 +1,823 @@ +#include "tdef.h" +#ifndef VAX /* Nick */ +#include +#endif +extern +#include "d.h" +extern +#include "v.h" +#include "s.h" + +/* +troff5.c + +misc processing requests +*/ + +extern struct s *frame; +extern struct s *litlev; +extern filep ip; +extern filep offset; + +extern int ascii; +extern int nonumb; +extern int admod; +extern int ad; +extern int fi; +extern int cc; +extern int c2; +extern int ohc; +extern int tabc; +extern int dotc; +extern int pendnf; +extern int hyf; +extern int ce; +extern int po; +extern int po1; +extern int nc; +extern int in; +extern int un; +extern int un1; +extern int in1; +extern int ll; +extern int ll1; +extern int lt; +extern int lt1; +extern int nlist[NTRAP]; +extern int mlist[NTRAP]; +extern int lgf; +extern int pl; +extern int npn; +extern int npnflg; +extern int copyf; +extern char nextf[]; +extern int trap; +extern int lss; +extern int em; +extern int evlist[EVLSZ]; +extern int evi; +extern int ibf; +extern int ev; +extern int ch; +extern int nflush; +extern int tty; +#ifndef VAX /* Nick */ +extern struct sgttyb ttys; +#endif +extern int quiet; +extern int iflg; +extern int eschar; +extern int lit; +extern int ls; +extern int ls1; +extern int tabtab[]; +extern char trtab[]; +extern int ul; +extern int cu; +extern int sfont; +extern int font; +extern int fontlab[]; +extern int it; +extern int itmac; +extern int noscale; +extern int ic; +extern int icf; +extern int ics; +extern int *vlist; +extern int sv; +extern int esc; +extern int nn; +extern int nms; +extern int ndf; +extern int lnmod; +extern int ni; +extern int lnsize; +extern int nb; +extern int nlflg; +extern int apts, apts1, pts, pts1, font, font1; +extern int ulfont; +extern int ulbit; +extern int error; +extern int nmbits; +extern int chbits; +extern int tdelim; +extern int xxx; +int iflist[NIF]; +int ifx; + +casead(){ + register i; + + ad = 1; + /*leave admod alone*/ + if(skip())return; + switch(i = getch() & CMASK){ + case 'r': /*right adj, left ragged*/ + admod = 2; + break; + case 'l': /*left adj, right ragged*/ + admod = ad = 0; /*same as casena*/ + break; + case 'c': /*centered adj*/ + admod = 1; + break; + case 'b': case 'n': + admod = 0; + break; + case '0': case '2': case '4': + ad = 0; + case '1': case '3': case '5': + admod = (i - '0')/2; + } +} +casena(){ + ad = 0; +} +casefi(){ + tbreak(); + fi++; + pendnf = 0; + lnsize = LNSIZE; +} +casenf(){ + tbreak(); + fi = 0; +/* can't do while oline is only LNSIZE + lnsize = LNSIZE + WDSIZE; +*/ +} +casers(){ + dip->nls = 0; +} +casens(){ + dip->nls++; +} +chget(c) +int c; +{ + register i; + + if(skip() || + ((i = getch()) & MOT) || + ((i&CMASK) == ' ') || + ((i&CMASK) == '\n')){ + ch = i; + return(c); + }else return(i & BMASK); +} +casecc(){ + cc = chget('.'); +} +casec2(){ + c2 = chget('\''); +} +casehc(){ + ohc = chget(OHC); +} +casetc(){ + tabc = chget(0); +} +caselc(){ + dotc = chget(0); +} +casehy(){ + register i; + + hyf = 1; + if(skip())return; + noscale++; + i = atoix(); /* Nick atoi */ + noscale = 0; + if(nonumb)return; + hyf = max(i,0); +} +casenh(){ + hyf = 0; +} +max(aa,bb) +int aa,bb; +{ + if(aa>bb)return(aa); + else return(bb); +} +casece(){ + register i; + + noscale++; + skip(); + i = max(atoix(),0); /* Nick atoi */ + if(nonumb)i = 1; + tbreak(); + ce = i; + noscale = 0; +} +casein(){ + register i; + + if(skip())i = in1; + else i = max(hnumb(&in),0); + tbreak(); + in1 = in; + in = i; + if(!nc){ + un = in; + setnel(); + } +} +casell(){ + register i; + + if(skip())i = ll1; + else i = max(hnumb(&ll),INCH/10); + ll1 = ll; + ll = i; + setnel(); +} +caselt(){ + register i; + + if(skip())i = lt1; + else i = max(hnumb(<),0); + lt1 = lt; + lt = i; +} +caseti(){ + register i; + + if(skip())return; + i = max(hnumb(&in),0); + tbreak(); + un1 = i; + setnel(); +} +casels(){ + register i; + + noscale++; + if(skip())i = ls1; + else i = max(inumb(&ls),1); + ls1 = ls; + ls = i; + noscale = 0; +} +casepo(){ + register i; + + if(skip())i = po1; + else i = max(hnumb(&po),0); + po1 = po; + po = i; +#ifndef NROFF + if(!ascii)esc += po - po1; +#endif +} +casepl(){ + register i; + + skip(); + if((i = vnumb(&pl)) == 0)pl = 11 * INCH; /*11in*/ + else pl = i; + if(v.nl > pl)v.nl = pl; +} +casewh(){ + register i, j, k; + + lgf++; + skip(); + i = vnumb((int *)0); + if(nonumb)return; + skip(); + j = getrq(); + if((k=findn(i)) != NTRAP){ + mlist[k] = j; + return; + } + for(k=0; knls)return; + eject(savframe); +} +casetm(x) int x;{ + register i; + char tmbuf[NTM]; + + lgf++; + copyf++; + if(skip() && x)prstrfl("User Abort."); + for(i=0; inls || trap)return; + i = findt1(); + if(!a){ + skip(); + j = vnumb((int *)0); + if(nonumb)j = lss; + }else j = a; + if(j == 0)return; + if(i < j)j = i; + savlss = lss; + if(dip != di)i = dip->dnl; else i = v.nl; /* Nick d */ + if((i + j) < 0)j = -i; + lss = j; + newline(0); + lss = savlss; +} +casert(){ + register a, *p; + + skip(); + if(dip != di)p = &dip->dnl; else p = &v.nl; /* Nick d */ + a = vnumb(p); + if(nonumb)a = dip->mkline; + if((a < 0) || (a >= *p))return; + nb++; + casesp(a - *p); +} +caseem(){ + lgf++; + skip(); + em = getrq(); +} +casefl(){ + tbreak(); + flusho(); +} +caseev(){ + register nxev; + extern int block; + + if(skip()){ +e0: + if(evi == 0)return; + nxev = evlist[--evi]; + goto e1; + } + noscale++; + nxev = atoix(); /* Nick atoi */ + noscale = 0; + if(nonumb)goto e0; + flushi(); + if((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ)){ + prstrfl("Cannot do ev.\n"); + if(error)done2(040);else edone(040); + return; + } + evlist[evi++] = ev; +e1: + if(ev == nxev)return; + lseek(ibf, (long)(ev*EVS*sizeof(int)), 0); + write(ibf,(char *)&block, EVS*sizeof(int)); + lseek(ibf, (long)(nxev*EVS*sizeof(int)), 0); + read(ibf,(char *)&block, EVS*sizeof(int)); + ev = nxev; +} +caseel(){ + if(--ifx < 0){ + ifx = 0; + iflist[0] = 0; + } + caseif(2); +} +caseie(){ + if(ifx >= NIF){ + prstr("if-else overflow.\n"); + ifx = 0; + edone(040); + } + caseif(1); + ifx++; +} +caseif(x) +int x; +{ + register i, notflag, true; + + if(x == 2){ + notflag = 0; + true = iflist[ifx]; + goto i1; + } + true = 0; + skip(); + if(((i = getch()) & CMASK) == '!'){ + notflag = 1; + }else{ + notflag = 0; + ch = i; + } + i = atoix(); /* Nick atoi */ + if(!nonumb){ + if(i > 0)true++; + goto i1; + } + switch((i = getch()) & CMASK){ + case 'e': + if(!(v.pn & 01))true++; + break; + case 'o': + if(v.pn & 01)true++; + break; +#ifdef NROFF + case 'n': + true++; + case 't': +#endif +#ifndef NROFF + case 't': + true++; + case 'n': +#endif + case ' ': + break; + default: + true = cmpstr(i); + } +i1: + true ^= notflag; + if(x == 1)iflist[ifx] = !true; + if(true){ + i2: + do{ + v.hp = 0; + } + while(((i = getch()) & CMASK) == ' '); + if((i & CMASK) == LEFT)goto i2; + ch = i; + nflush++; + }else{ + copyf++; + if(eat(LEFT) == LEFT){ + while(eatblk(RIGHT,LEFT) != RIGHT)nlflg = 0; + } + copyf--; + } +} +eatblk(right,left) +int right,left; +{ + register i; + +e0: + while(((i = getch() & CMASK) != right) && + (i != left) && + (i != '\n')); + if(i == left){ + while((i=eatblk(right,left)) != right)nlflg = 0; + goto e0; + } + return(i); +} +cmpstr(delim) +int delim; +{ + register i, j; + register filep p; + extern filep alloc(); + extern filep incoff(); + filep begin; + int cnt, k; + int savapts, savapts1, savfont, savfont1, + savpts, savpts1; + + if(delim & MOT)return(0); + delim &= CMASK; + if(dip != di)wbfl(); /* Nick d */ + if((offset = begin = alloc()) == (filep)0)return(0); + cnt = 0; + v.hp = 0; + savapts = apts; + savapts1 = apts1; + savfont = font; + savfont1 = font1; + savpts = pts; + savpts1 = pts1; + while(((j = (i=getch()) & CMASK) != delim) && (j != '\n')){ + wbf(i); + cnt++; + } + wbt(0); + k = !cnt; + if(nlflg)goto rtn; + p = begin; + apts = savapts; + apts1 = savapts1; + font = savfont; + font1 = savfont1; + pts = savpts; + pts1 = savpts1; + mchbits(); + v.hp = 0; + while(((j = (i=getch()) & CMASK) != delim) && (j != '\n')){ + if(rbf0(p) != i){ + eat(delim); + k = 0; + break; + } + p = incoff(p); + k = !(--cnt); + } +rtn: + apts = savapts; + apts1 = savapts1; + font = savfont; + font1 = savfont1; + pts = savpts; + pts1 = savpts1; + mchbits(); + offset = dip->op; + ffree(begin); + return(k); +} +caserd(){ + + lgf++; + skip(); + getname(); + if(!iflg){ + if(quiet){ +#ifndef VAX /* Nick */ + ttys.sg_flags &= ~ECHO; + stty(0, &ttys); +#endif + prstrfl(""); /*bell*/ + }else{ + if(nextf[0]){ + prstr(nextf); + prstr(":"); + }else{ + prstr(""); /*bell*/ + } + } + } + collect(); + tty++; + pushi((filep)-1); +} +rdtty(){ + char onechar; + + onechar = 0; + if(read(0, &onechar, 1) == 1){ + if(onechar == '\n')tty++; + else tty = 1; + if(tty != 3)return(onechar); + } + popi(); + tty = 0; +#ifndef VAX /* Nick */ + if(quiet){ + ttys.sg_flags |= ECHO; + stty(0, &ttys); + } +#endif + return(0); +} +caseec(){ + eschar = chget('\\'); +} +caseeo(){ + eschar = 0; +} +caseli(){ + + skip(); + lit = max(inumb((int *)0),1); + litlev = frame; + if((dip == di) && (v.nl == -1))newline(1); /* Nick d */ +} +caseta(){ + register i; + + tabtab[0] = nonumb = 0; + for(i=0; ((i < (NTAB-1)) && !nonumb); i++){ + if(skip())break; + tabtab[i] = max(hnumb(&tabtab[max(i-1,0)]),0) & TMASK; + if(!nonumb) switch(ch & CMASK){ + case 'C': + tabtab[i] |= CTAB; + break; + case 'R': + tabtab[i] |= RTAB; + break; + default: /*includes L*/ + break; + } + nonumb = ch = 0; + } + tabtab[i] = 0; +} +casene(){ + register i, j; + + skip(); + i = vnumb((int *)0); + if(nonumb)i = lss; + if(i > (j = findt1())){ + i = lss; + lss = j; + dip->nls = 0; + newline(0); + lss = i; + } +} +casetr(){ + register i, j; + + lgf++; + skip(); + while((i = getch() & CMASK) != '\n'){ + if((i & MOT) || ((j = getch()) & MOT))return; + if((j &= CMASK) == '\n')j = ' '; + trtab[i] = j; + } +} +casecu(){ + cu++; + caseul(); +} +caseul(){ + register i; + + noscale++; + if(skip())i = 1; + else i = atoix(); /* Nick atoi */ + if(ul && (i == 0)){ + font = sfont; + ul = cu = 0; + } + if(i){ + if(!ul){ + sfont = font; + font = ulfont; + } + ul = i; + } + noscale = 0; + mchbits(); +} +caseuf(){ + register i, j; + + if(skip() || !(i = getrq()) || (i == 'S') || + ((j = find(i,fontlab)) == -1)) + ulfont = 1; /*default position 2*/ + else ulfont = j; +#ifdef NROFF + if(ulfont == 0)ulfont = 1; +#endif + ulbit = ulfont<<9; +} +caseit(){ + register i; + + lgf++; + it = itmac = 0; + noscale++; + skip(); + i = atoix(); /* Nick atoi */ + skip(); + if(!nonumb && (itmac = getrq()))it = i; + noscale = 0; +} +casemc(){ + register i; + + if(icf > 1)ic = 0; + icf = 0; + if(skip())return; + ic = getch(); + icf = 1; + skip(); + i = max(hnumb((int *)0),0); + if(!nonumb)ics = i; +} +casemk(){ + register i, j; + + if(dip != di)j = dip->dnl; else j = v.nl; /* Nick d */ + if(skip()){ + dip->mkline = j; + return; + } + if((i = getrq()) == 0)return; + vlist[findr(i)] = j; +} +casesv(){ + register i; + + skip(); + if((i = vnumb((int *)0)) < 0)return; + if(nonumb)i = 1; + sv += i; + caseos(); +} +caseos(){ + register savlss; + + if(sv <= findt1()){ + savlss = lss; + lss = sv; + newline(0); + lss = savlss; + sv = 0; + } +} +casenm(){ + register i; + + lnmod = nn = 0; + if(skip())return; + lnmod++; + noscale++; + i = inumb(&v.ln); + if(!nonumb)v.ln = max(i,0); + getnm(&ndf,1); + getnm(&nms,0); + getnm(&ni,0); + noscale = 0; + nmbits = chbits; +} +getnm(p,min) +int *p, min; +{ + register i; + + eat(' '); + if(skip())return; + i = atoix(); /* Nick atoi */ + if(nonumb)return; + *p = max(i,min); +} +casenn(){ + noscale++; + skip(); + nn = max(atoix(),1); /* Nick atoi */ + noscale = 0; +} +caseab(){ + dummy(); + casetm(1); + done2(0); +} diff --git a/src/troff/n6.c b/src/troff/n6.c new file mode 100755 index 00000000..86011d47 --- /dev/null +++ b/src/troff/n6.c @@ -0,0 +1,281 @@ +#if 1 /* Nick */ +#define NULL 0 +#endif +#include "tdef.h" +extern +#include "d.h" +extern +#include "v.h" +#ifdef NROFF +extern +#include "tw.h" +#endif + +/* +troff6.c + +width functions, sizes and fonts +*/ + +extern int eschar; +extern int widthp; +extern int ohc; +extern int xfont; +extern int smnt; +extern int setwdf; +extern char trtab[]; +extern int chbits; +extern int nonumb; +extern int noscale; +extern int font; +extern int font1; +extern int pts; +extern int sps; +extern int nlflg; +extern int nform; +extern int dfact; +extern int dfactd; +extern int lss; +extern int lss1; +extern int vflag; +extern int ch0; +extern int level; +extern int ch; +extern int res; +extern int xxx; +int fontlab[] = {'R','I','B','S',0}; + +width(c) +int c; +{ + register i,j,k; +#if 1 /* Nick */ + char *p; +#endif + + j = c; + k = 0; + if(j & MOT){ + if(j & VMOT)goto rtn; + k = j & ~MOTV; + if(j & NMOT)k = -k; + goto rtn; + } + if((i = (j & CMASK)) == 010){ + k = -widthp; + goto rtn; + } + if(i == PRESC)i = eschar; + if((i == ohc) || + (i >= 0370))goto rtn; + if(j & ZBIT)goto rtn; + i = trtab[i] & BMASK; + if(i < 040)goto rtn; +#if 1 /* Nick */ + p = t.codetab[i-32]; + if (p == NULL) + { + k = 0; + } + else + { + k = (*p & 0177) * t.Char; + } +#else + k = (*(t.codetab[i-32]) & 0177) * t.Char; +#endif + widthp = k; +rtn: + return(k); +} +setch(){ + register i,*j,k; + extern int chtab[]; + + if((i = getrq()) == 0)return(0); + for(j=chtab;*j != i;j++)if(*(j++) == 0)return(0); + k = *(++j) | chbits; + return(k); +} +find(i,j) +int i,j[]; +{ + register k; + + if(((k = i-'0') >= 1) && (k <= 4) && (k != smnt))return(--k); + for(k=0; j[k] != i; k++)if(j[k] == 0)return(-1); + return(k); +} +mchbits(){ + chbits = (((pts)<<2) | font) << (BYTE + 1); + sps = width(' ' | chbits); +} +setps(){ + register i,j; + + if((((i=getch() & CMASK) == '+') || (i == '-')) && + (((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9))){ + ch = 0; + return; + } + if((i -= '0') == 0){ + return; + } + if((i > 0) && (i <= 9)){ + if((i <= 3) && + ((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9)){ + i = 10*i +j; + ch = 0; + } + } +} +caseft(){ + skip(); + setfont(1); +} +setfont(a) +int a; +{ + register i,j; + + if(a)i = getrq(); + else i = getsn(); + if(!i || (i == 'P')){ + j = font1; + goto s0; + } + if(i == 'S')return; + if((j = find(i,fontlab)) == -1)return; +s0: + font1 = font; + font = j; + mchbits(); +} +setwd(){ + register i, base, wid; + int delim, em, k; + int savlevel, savhp, savfont, savfont1; + + base = v.st = v.sb = wid = v.ct = 0; + if((delim = getch() & CMASK) & MOT)return; + savhp = v.hp; + savlevel = level; + v.hp = level = 0; + savfont = font; + savfont1 = font1; + setwdf++; + while((((i = getch()) & CMASK) != delim) && !nlflg){ + wid += width(i); + if(!(i & MOT)){ + em = 2*t.Halfline; + }else if(i & VMOT){ + k = i & ~MOTV; + if(i & NMOT)k = -k; + base -= k; + em = 0; + }else continue; + if(base < v.sb)v.sb = base; + if((k=base + em) > v.st)v.st = k; + } + nform = 0; + setn1(wid); + v.hp = savhp; + level = savlevel; + font = savfont; + font1 = savfont1; + mchbits(); + setwdf = 0; +} +vmot(){ + dfact = lss; + vflag++; + return(mot()); +} +hmot(){ + dfact = EM; + return(mot()); +} +mot(){ + register i, j; + + j = HOR; + getch(); /*eat delim*/ + if(i = atoix()){ /* Nick atoi */ + if(vflag)j = VERT; + i = makem(quant(i,j)); + } + getch(); + vflag = 0; + dfact = 1; + return(i); +} +sethl(k) +int k; +{ + register i; + + i = t.Halfline; + if(k == 'u')i = -i; + else if(k == 'r')i = -2*i; + vflag++; + i = makem(i); + vflag = 0; + return(i); +} +makem(i) +int i; +{ + register j; + + if((j = i) < 0)j = -j; + j = (j & ~MOTV) | MOT; + if(i < 0)j |= NMOT; + if(vflag)j |= VMOT; + return(j); +} +casefp(){ + register i, j; + + skip(); + if(((i = (getch() & CMASK) - '0' -1) < 0) || (i >3))return; + if(skip() || !(j = getrq()))return; + fontlab[i] = j; +} +casevs(){ + register i; + + skip(); + vflag++; + dfact = INCH; /*default scaling is points!*/ + dfactd = 72; + res = VERT; + i = inumb(&lss); + if(nonumb)i = lss1; + if(i < VERT)i = VERT; + lss1 = lss; + lss = i; +} +xlss(){ + register i, j; + + getch(); + dfact = lss; + i = quant(atoix(),VERT); /* Nick atoi */ + dfact = 1; + getch(); + if((j = i) < 0)j = -j; + ch0 = ((j & 03700)<<3) | HX; + if(i < 0)ch0 |= 040000; + return(((j & 077)<<9) | LX); +} +casefz(){} +caseps(){} +caselg(){} +casecs(){} +casebd(){} +casess(){} +getlg(i) +int i; +{ + return(i); +} diff --git a/src/troff/n7.c b/src/troff/n7.c new file mode 100755 index 00000000..cc6db183 --- /dev/null +++ b/src/troff/n7.c @@ -0,0 +1,755 @@ +#include "tdef.h" +extern +#include "d.h" +extern +#include "v.h" +#ifdef NROFF +extern +#include "tw.h" +#endif +#include "s.h" +#ifdef NROFF +#define GETCH gettch +#endif +#ifndef NROFF +#define GETCH getch +#endif + +/* +troff7.c + +text +*/ + +extern struct s *frame, *stk; +extern struct s *ejl; + +extern int pl; +extern int trap; +extern int flss; +extern int npnflg; +extern int npn; +extern int stop; +extern int nflush; +extern int ejf; +extern int ascii; +extern int donef; +extern int nc; +extern int wch; +extern int dpn; +extern int ndone; +extern int lss; +extern int pto; +extern int pfrom; +extern int print; +extern int nlist[NTRAP]; +extern int mlist[NTRAP]; +extern int *pnp; +extern int nb; +extern int ic; +extern int icf; +extern int ics; +extern int ne; +extern int ll; +extern int un; +extern int un1; +extern int in; +extern int ls; +extern int spread; +extern int totout; +extern int nwd; +extern int *pendw; +extern int *linep; +extern int line[]; +extern int lastl; +extern int ch; +extern int ce; +extern int fi; +extern int nlflg; +extern int pendt; +extern int sps; +extern int adsp; +extern int pendnf; +extern int over; +extern int adrem; +extern int nel; +extern int ad; +extern int ohc; +extern int hyoff; +extern int nhyp; +extern int spflg; +extern int word[]; +extern int *wordp; +extern int wne; +extern int chbits; +extern int cwidth; +extern int widthp; +extern int hyf; +extern int xbitf; +extern int vflag; +extern int ul; +extern int cu; +extern int font; +extern int sfont; +extern int it; +extern int itmac; +extern int *hyptr[NHYP]; +extern int **hyp; +extern int *wdstart, *wdend; +extern int lnmod; +extern int admod; +extern int nn; +extern int nms; +extern int ndf; +extern int ni; +extern int nform; +extern int lnsize; +extern int po; +extern int ulbit; +extern int *vlist; +extern int nrbits; +extern int nmbits; +extern char trtab[]; +extern int xxx; +int brflg; + +tbreak(){ + register *i, j, pad; + int res; + + trap = 0; + if(nb)return; + if((dip == di) && (v.nl == -1)){ /* Nick d */ + newline(1); + return; + } + if(!nc){ + setnel(); + if(!wch)return; + if(pendw)getword(1); + movword(); + }else if(pendw && !brflg){ + getword(1); + movword(); + } + *linep = dip->nls = 0; +#ifdef NROFF + if(dip == di)horiz(po); /* Nick d */ +#endif + if(lnmod)donum(); + lastl = ne; + if(brflg != 1){ + totout = 0; + }else if(ad){ + if((lastl = (ll - un)) < ne)lastl = ne; + } + if(admod && ad && (brflg != 2)){ + lastl = ne; + adsp = adrem = 0; +#ifdef NROFF + if(admod == 1)un += quant(nel/2,t.Adj); +#endif +#ifndef NROFF + if(admod == 1)un += nel/2; +#endif + else if(admod ==2)un += nel; + } + totout++; + brflg = 0; + if((lastl+un) > dip->maxl)dip->maxl = (lastl+un); + horiz(un); +#ifdef NROFF + if(adrem%t.Adj)res = t.Hor; else res = t.Adj; +#endif + for(i = line;nc > 0;){ + if(((j = *i++) & CMASK) == ' '){ + pad = 0; + do{ + pad += width(j); + nc--; + }while(((j = *i++) & CMASK) == ' '); + i--; + pad += adsp; + --nwd; + if(adrem){ + if(adrem < 0){ +#ifdef NROFF + pad -= res; + adrem += res; + }else if((totout&01) || + ((adrem/res)>=(nwd))){ + pad += res; + adrem -= res; +#endif +#ifndef NROFF + pad--; + adrem++; + }else{ + pad++; + adrem--; +#endif + } + } + horiz(pad); + }else{ + pchar(j); + nc--; + } + } + if(ic){ + if((j = ll - un - lastl + ics) > 0)horiz(j); + pchar(ic); + } + if(icf)icf++; + else ic = 0; + ne = nwd = 0; + un = in; + setnel(); + newline(0); + if(dip != di){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;} /* Nick d */ + else{if(v.nl > dip->hnl)dip->hnl = v.nl;} + for(j=ls-1; (j >0) && !trap; j--)newline(0); + spread = 0; +} +donum(){ + register i, nw; + extern pchar(); + + nrbits = nmbits; + nw = width('1' | nrbits); + if(nn){ + nn--; + goto d1; + } + if(v.ln%ndf){ + v.ln++; + d1: + un += nw*(3+nms+ni); + return; + } + i = 0; + if(v.ln<100)i++; + if(v.ln<10)i++; + horiz(nw*(ni+i)); + nform = 0; + fnumb(v.ln,pchar); + un += nw*nms; + v.ln++; +} +text(){ + register i; + static int spcnt; + + nflush++; + if((dip == di) && (v.nl == -1)){newline(1); return;} /* Nick d */ + setnel(); + if(ce || !fi){ + nofill(); + return; + } + if(pendw)goto t4; + if(pendt)if(spcnt)goto t2; else goto t3; + pendt++; + if(spcnt)goto t2; + while(((i = GETCH()) & CMASK) == ' ')spcnt++; + if(nlflg){ + t1: + nflush = pendt = ch = spcnt = 0; + callsp(); + return; + } + ch = i; + if(spcnt){ + t2: + tbreak(); + if(nc || wch)goto rtn; + un += spcnt*sps; + spcnt = 0; + setnel(); + if(trap)goto rtn; + if(nlflg)goto t1; + } +t3: + if(spread)goto t5; + if(pendw || !wch) + t4: + if(getword(0))goto t6; + if(!movword())goto t3; +t5: + if(nlflg)pendt = 0; + adsp = adrem = 0; + if(ad){ +/* jfr */ if (nwd==1) adsp=nel; else adsp=nel/(nwd-1); +#ifdef NROFF + adsp = (adsp/t.Adj)*t.Adj; +#endif + adrem = nel - adsp*(nwd-1); + } + brflg = 1; + tbreak(); + spread = 0; + if(!trap)goto t3; + if(!nlflg)goto rtn; +t6: + pendt = 0; + ckul(); +rtn: + nflush = 0; +} +nofill(){ + register i, j; + + if(!pendnf){ + over = 0; + tbreak(); + if(trap)goto rtn; + if(nlflg){ + ch = nflush = 0; + callsp(); + return; + } + adsp = adrem = 0; + nwd = 10000; + } + while((j = ((i = GETCH()) & CMASK)) != '\n'){ + if(j == ohc)continue; + if(j == CONT){ + pendnf++; + nflush = 0; + flushi(); + ckul(); + return; + } + storeline(i,-1); + } + if(ce){ + ce--; + if((i=quant(nel/2,HOR)) > 0)un += i; + } + if(!nc)storeline(FILLER,0); + brflg = 2; + tbreak(); + ckul(); +rtn: + pendnf = nflush = 0; +} +callsp(){ + register i; + + if(flss)i = flss; else i = lss; + flss = 0; + casesp(i); +} +ckul(){ + if(ul && (--ul == 0)){ + cu = 0; + font = sfont; + mchbits(); + } + if(it && (--it == 0) && itmac)control(itmac,0); +} +storeline(c,w){ + register i; + + if((c & CMASK) == JREG){ + if((i=findr(c>>BYTE)) != -1)vlist[i] = ne; + return; + } + if(linep >= (line + lnsize - 1)){ + if(!over){ + prstrfl("Line overflow.\n"); + over++; + c = 0343; + w = -1; + goto s1; + } + return; + } +s1: + if(w == -1)w = width(c); + ne += w; + nel -= w; +/* + * if( cu && !(c & MOT) && (trtab[(c & CMASK)] == ' ')) + * c = ((c & ~ulbit) & ~CMASK) | '_'; + */ + *linep++ = c; + nc++; +} +newline(a) +int a; +{ + register i, j, nlss; + int opn; + + if(a)goto nl1; + if(dip != di){ /* Nick d */ + j = lss; + pchar1(FLSS); + if(flss)lss = flss; + i = lss + dip->blss; + dip->dnl += i; + pchar1(i); + pchar1('\n'); + lss = j; + dip->blss = flss = 0; + if(dip->alss){ + pchar1(FLSS); + pchar1(dip->alss); + pchar1('\n'); + dip->dnl += dip->alss; + dip->alss = 0; + } + if(dip->ditrap && !dip->ditf && + (dip->dnl >= dip->ditrap) && dip->dimac) + if(control(dip->dimac,0)){trap++; dip->ditf++;} + return; + } + j = lss; + if(flss)lss = flss; + nlss = dip->alss + dip->blss + lss; + v.nl += nlss; +#ifndef NROFF + if(ascii){dip->alss = dip->blss = 0;} +#endif + pchar1('\n'); + flss = 0; + lss = j; + if(v.nl < pl)goto nl2; +nl1: + ejf = dip->hnl = v.nl = 0; + ejl = frame; + if(donef){ + if((!nc && !wch) || ndone)done1(0); + ndone++; + donef = 0; + if(frame == stk)nflush++; + } + opn = v.pn; + v.pn++; + if(npnflg){ + v.pn = npn; + npn = npnflg = 0; + } +nlpn: + if(v.pn == pfrom){ + print++; + pfrom = -1; + }else if(opn == pto){ + print = 0; + opn = -1; + chkpn(); + goto nlpn; + } + if(stop && print){ + dpn++; + if(dpn >= stop){ + dpn = 0; + dostop(); + } + } +nl2: + trap = 0; + if(v.nl == 0){ + if((j = findn(0)) != NTRAP) + trap = control(mlist[j],0); + } else if((i = findt(v.nl-nlss)) <= nlss){ + if((j = findn1(v.nl-nlss+i)) == NTRAP){ + prstrfl("Trap botch.\n"); + done2(-5); + } + trap = control(mlist[j],0); + } +} +findn1(a) +int a; +{ + register i, j; + + for(i=0; idimac && ((i = dip->ditrap -a) > 0))k = i; + return(k); + } + for(i=0; i i)k = i; + return(k); +} +findt1(){ + register i; + + if(dip != di)i = dip->dnl; /* Nick d */ + else i = v.nl; + return(findt(i)); +} +eject(a) +struct s *a; +{ + register savlss; + + if(dip != di)return; /* Nick d */ + ejf++; + if(a)ejl = a; + else ejl = frame; + if(trap)return; +e1: + savlss = lss; + lss = findt(v.nl); + newline(0); + lss = savlss; + if(v.nl && !trap)goto e1; +} +movword(){ + register i, w, *wp; + int savwch, hys; + + over = 0; + wp = wordp; + if(!nwd){ + while(((i = *wp++) & CMASK) == ' '){ + wch--; + wne -= width(i); + } + wp--; + } + if((wne > nel) && + !hyoff && hyf && + (!nwd || (nel > 3*sps)) && + (!(hyf & 02) || (findt1() > lss)) + )hyphen(wp); + savwch = wch; + hyp = hyptr; + nhyp = 0; + while(*hyp && (*hyp <= wp))hyp++; + while(wch){ + if((hyoff != 1) && (*hyp == wp)){ + hyp++; + if(!wdstart || + ((wp > (wdstart+1)) && + (wp < wdend) && + (!(hyf & 04) || (wp < (wdend-1))) && + (!(hyf & 010) || (wp > (wdstart+2))) + ) + ){ + nhyp++; + storeline(IMP,0); + } + } + i = *wp++; + w = width(i); + wne -= w; + wch--; + storeline(i,w); + } + if(nel >= 0){ + nwd++; + return(0); + } + xbitf = 1; + hys = width(0200); /*hyphen*/ +m1: + if(!nhyp){ + if(!nwd)goto m3; + if(wch == savwch)goto m4; + } + if(*--linep != IMP)goto m5; + if(!(--nhyp)) + if(!nwd)goto m2; + if(nel < hys){ + nc--; + goto m1; + } +m2: + if(((i = *(linep-1) & CMASK) != '-') && + (i != 0203) + ){ + *linep = (*(linep-1) & ~CMASK) | 0200; + w = width(*linep); + nel -= w; + ne += w; + linep++; +/* + hsend(); +*/ + } +m3: + nwd++; +m4: + wordp = wp; + return(1); +m5: + nc--; + w = width(*linep); + ne -= w; + nel += w; + wne += w; + wch++; + wp--; + goto m1; +} +horiz(i) +int i; +{ + vflag = 0; + if(i)pchar(makem(i)); +} +setnel(){ + if(!nc){ + linep = line; + if(un1 >= 0){ + un = un1; + un1 = -1; + } + nel = ll - un; + ne = adsp = adrem = 0; + } +} +getword(x) +int x; +{ + register i, j, swp; + int noword; + + noword = 0; + if(x)if(pendw){ + *pendw = 0; + goto rtn; + } + if(wordp = pendw)goto g1; + hyp = hyptr; + wordp = word; + over = wne = wch = 0; + hyoff = 0; + while(1){ + j = (i = GETCH()) & CMASK; + if(j == '\n'){ + wne = wch = 0; + noword = 1; + goto rtn; + } + if(j == ohc){ + hyoff = 1; + continue; + } + if(j == ' '){ + storeword(i,cwidth); + continue; + } + break; + } + swp = widthp; + storeword(' ' | chbits, -1); + if(spflg){ + storeword(' ' | chbits, -1); + spflg = 0; + } + widthp = swp; +g0: + if(j == CONT){ + pendw = wordp; + nflush = 0; + flushi(); + return(1); + } + if(hyoff != 1){ + if(j == ohc){ + hyoff = 2; + *hyp++ = wordp; + if(hyp > (hyptr+NHYP-1))hyp = hyptr+NHYP-1; + goto g1; + } + if((j == '-') || + (j == 0203) /*3/4 Em dash*/ + )if(wordp > word+1){ + hyoff = 2; + *hyp++ = wordp + 1; + if(hyp > (hyptr+NHYP-1))hyp = hyptr+NHYP-1; + } + } + storeword(i,cwidth); +g1: + j = (i = GETCH()) & CMASK; + if(j != ' '){ + if(j != '\n')goto g0; + j = *(wordp-1) & CMASK; + if((j == '.') || + (j == '!') || + (j == '?'))spflg++; + } + *wordp = 0; +rtn: + wdstart = 0; + wordp = word; + pendw = 0; + *hyp++ = 0; + setnel(); + return(noword); +} +storeword(c,w) +int c, w; +{ + + if(wordp >= &word[WDSIZE - 1]){ + if(!over){ + prstrfl("Word overflow.\n"); + over++; + c = 0343; + w = -1; + goto s1; + } + return; + } +s1: + if(w == -1)w = width(c); + wne += w; + *wordp++ = c; + wch++; +} +#ifdef NROFF +extern char trtab[]; +gettch(){ + register int i, j; + + if(!((i = getch()) & MOT) && (i & ulbit)){ + j = i&CMASK; + if(cu && (trtab[j] == ' ')) + i = ((i & ~ulbit)& ~CMASK) | '_'; + if(!cu && (j>32) && (j<0370) && !(*t.codetab[j-32] & 0200)) + i &= ~ulbit; + } + return(i); +} +#endif diff --git a/src/troff/n8.c b/src/troff/n8.c new file mode 100755 index 00000000..cb414297 --- /dev/null +++ b/src/troff/n8.c @@ -0,0 +1,276 @@ +#include "tdef.h" + +/* +troff8.c + +hyphenation +*/ + +char hbuf[NHEX]; +char *nexth = hbuf; +int *hyend; +extern int *wdstart, *wdend; +extern int *hyptr[]; +extern int **hyp; +extern int hyoff; +extern int noscale; +extern int xxx; +#define THRESH 160 /*digram goodness threshold*/ +int thresh = THRESH; + +hyphen(wp) +int *wp; +{ + register *i, j; + + i = wp; + while(punct(*i++)) + ; + if (!alph(*--i)) + return; + wdstart = i++; + while(alph(*i++)) + ; + hyend = wdend = --i-1; + while(punct(*i++)) + ; + if (*--i) + return; + if ((wdend-wdstart-4) < 0) + return; + hyp = hyptr; + *hyp = 0; + hyoff = 2; + if (!exword() && !suffix()) + digram(); + *hyp++ = 0; + if (*hyptr) for(j = 1; j;) { + j = 0; + for(hyp = hyptr+1; *hyp != 0; hyp++) { + if (*(hyp-1) > *hyp) { + j++; + i = *hyp; + *hyp = *(hyp-1); + *(hyp-1) = i; + } + } + } +} + +punct(i) +int i; +{ + if (!i || alph(i)) + return(0); + else + return(1); +} + +alph(i) +int i; +{ + register j; + + j = i & CMASK; + if (((j >= 'A') && (j <= 'Z')) || ((j >= 'a') && (j <= 'z'))) + return(1); + else + return(0); +} + +caseht() +{ + thresh = THRESH; + if (skip()) + return; + noscale++; + thresh = atoix(); /* Nick atoi */ + noscale = 0; +} + +casehw() +{ + register i, k; + register char *j; + + k = 0; + while(!skip()) { + if ((j = nexth) >= (hbuf + NHEX - 2)) + goto full; + for (;;) { + if ((i = getch()) & MOT) + continue; + if (((i &= CMASK) == ' ') || (i == '\n')) { + *j++ = 0; + nexth = j; + *j = 0; + if (i == ' ') + break; + else + return; + } + if (i == '-') { + k = 0200; + continue; + } + *j++ = maplow(i) | k; + k = 0; + if (j >= (hbuf + NHEX - 2)) + goto full; + } + } + return; +full: + prstr("Exception word list full.\n"); + *nexth = 0; +} + +exword() +{ + register int *w; + register char *e; + char *save; + + e = hbuf; + while(1) { + save = e; + if (*e == 0)return(0); + w = wdstart; + while((*e && (w <= hyend)) && + ((*e & 0177) == maplow(*w & CMASK))) {e++; w++;}; + if (!*e) { + if (((w-1) == hyend) || + ((w == wdend) && (maplow(*w & CMASK) == 's'))) { + w = wdstart; + for(e = save; *e; e++) { + if (*e & 0200)*hyp++ = w; + if (hyp > (hyptr+NHYP-1)) + hyp = hyptr+NHYP-1; + w++; + } + return(1); + }else{e++; continue;} + }else while(*e++); + } +} + +suffix() +{ + register int *w; + register char *s, *s0; + int i; + extern char *suftab[]; + extern int *chkvow(); + +again: + if (!alph(i = *hyend & CMASK)) + return(0); + if (i < 'a') + i -= 'A'-'a'; + if ((s0 = suftab[i-'a']) == 0) + return(0); + for (;;) { + if ((i = *s0 & 017) == 0) + return(0); + s = s0 + i - 1; + w = hyend - 1; + while(((s > s0) && (w >= wdstart)) && + ((*s & 0177) == maplow(*w))) { + s--; + w--; + } + if (s == s0) + break; + s0 += i; + } + s = s0 + i - 1; + w = hyend; + if (*s0 & 0200) goto mark; + while(s > s0) { + w--; + if (*s-- & 0200) { + mark: + hyend = w - 1; + if (*s0 & 0100) + continue; + if (!chkvow(w)) + return(0); + *hyp++ = w; + } + } + if (*s0 & 040) + return(0); + if (exword()) + return(1); + goto again; +} + +maplow(i) +int i; +{ + if ((i &= CMASK) < 'a')i += 'a' - 'A'; + return(i); +} + +vowel(i) +int i; +{ + switch(maplow(i)) { + case 'a': + case 'e': + case 'i': + case 'o': + case 'u': + case 'y': + return(1); + default: + return(0); + } +} + +int *chkvow(w) +int *w; +{ + while(--w >= wdstart)if(vowel(*w & CMASK))return(w); + return(0); +} + +digram() { + register *w, val; + int *nhyend, *maxw, maxval; + extern char bxh[26][13], bxxh[26][13], xxh[26][13], xhx[26][13], hxx[26][13]; + +again: + if (!(w=chkvow(hyend+1)))return; + hyend = w; + if (!(w=chkvow(hyend)))return; + nhyend = w; + maxval = 0; + w--; + while((++w < hyend) && (w < (wdend-1))) { + val = 1; + if (w == wdstart)val *= dilook('a',*w,bxh); + else if(w == wdstart+1)val *= dilook(*(w-1),*w,bxxh); + else val *= dilook(*(w-1),*w,xxh); + val *= dilook(*w, *(w+1), xhx); + val *= dilook(*(w+1), *(w+2), hxx); + if (val > maxval) { + maxval = val; + maxw = w + 1; + } + } + hyend = nhyend; + if (maxval > thresh)*hyp++ = maxw; + goto again; +} + +dilook(a,b,t) +int a, b; +char t[26][13]; +{ + register i, j; + + i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2]; + if (!(j & 01))i >>= 4; + return(i & 017); +} diff --git a/src/troff/n9.c b/src/troff/n9.c new file mode 100755 index 00000000..f6244839 --- /dev/null +++ b/src/troff/n9.c @@ -0,0 +1,328 @@ +#include "tdef.h" +extern +#include "d.h" +extern +#include "v.h" +#ifdef NROFF +extern +#include "tw.h" +#endif +/* +troff9.c + +misc functions +*/ + +extern int cbuf[]; +extern int *cp; +extern int ch; +extern int chbits; +extern int dfact; +extern int vflag; +extern int pts; +extern int fc; +extern int padc; +extern int tabtab[]; +extern int nlflg; +extern int lss; +extern int tabch, ldrch; +extern int tabc, dotc; +extern int nchar, rchar; +extern int xxx; + +setz(){ + register i; + + if(!((i = getch()) & MOT))i |= ZBIT; + return(i); +} +setline(){ + register *i, length, c; + int w, cnt, delim, rem, temp; + + if((delim = getch()) & MOT)return; + else delim &= CMASK; + vflag = 0; + dfact = EM; + length = quant(atoix(),HOR); /* Nick atoi */ + dfact = 1; + if(!length){ + eat(delim); + return; + } +s0: + if(((c = getch()) & CMASK) == delim){ + ch = c; + c = 0204 | chbits; + }else if((c & CMASK) == FILLER)goto s0; + w = width(c); + i = cbuf; + if(length < 0){ + *i++ = makem(length); + length = -length; + } + if(!(cnt = length/w)){ + *i++ = makem(-(temp = ((w-length)/2))); + *i++ = c; + *i++ = makem(-(w - length - temp)); + goto s1; + } + if(rem = length%w){ + switch(c & CMASK){ + case 0204: /*rule*/ + case 0224: /*underrule*/ + case 0276: /*root en*/ + *i++ = c | ZBIT; + default: + *i++ = makem(rem); + } + } + if(cnt){ + *i++ = RPT; + *i++ = cnt; + *i++ = c; + } +s1: + *i++ = 0; + eat(delim); + cp = cbuf; +} +eat(c) +int c; +{ + register i; + + while(((i = getch() & CMASK) != c) && + (i != '\n')); + return(i); +} +setov(){ + register i, j, k; + int *p, delim, o[NOV], w[NOV]; + + if((delim = getch()) & MOT)return; + else delim &= CMASK; + for(k=0; (k 0 )break; + } + type = tabtab[j] & (~TMASK); + fp = fbuf; + pp = padptr; + if(x == savfc){while(1){ + if(((j = (i = getch()) & CMASK)) == padc){ + npad++; + *pp++ = fp; + if(pp > (padptr + NPP - 1))break; + goto s1; + }else if(j == savfc) break; + else if(j == '\n'){ + temp = j; + nlflg = 0; + break; + } + ws += width(i); + s1: + *fp++ = i; + if(fp > (fbuf + FBUFSZ -3))break; + } + if(!npad){ + npad++; + *pp++ = fp; + *fp++ = 0; + } + *fp++ = temp; + *fp++ = 0; + temp = i = (j = length-ws)/npad; + i = (i/HOR)*HOR; + if((j -= i*npad) <0)j = -j; + i = makem(i); + if(temp <0)i |= NMOT; + for(;npad > 0; npad--){ + *(*--pp) = i; + if(j){ + j -= HOR; + (*(*pp)) += HOR; + } + } + cp = fbuf; + j = 0; + }else if(type == 0){ + /*plain tab or leader*/ + if((j = width(rchar)) == 0)nchar = 0; + else{ + nchar = length /j; + length %= j; + } + if(length)j = length | MOT; + else j = getch0(); + }else{ + /*center tab*/ + /*right tab*/ + while(((j = (i = getch()) & CMASK) != savtc) && + (j != '\n') && (j != savlc)){ + ws += width(i); + *fp++ = i; + if(fp > (fbuf +FBUFSZ - 3)) break; + } + *fp++ = i; + *fp++ = 0; + if(type == RTAB)length -= ws; + else length -= ws/2; /*CTAB*/ + if(((j = width(rchar)) == 0) || (length <= 0))nchar = 0; + else{ + nchar = length/j; + length %= j; + } + length = (length/HOR)*HOR; + j = makem(length); + cp = fbuf; + nlflg = 0; + } +rtn: + fc = savfc; tabch = savtc; ldrch = savlc; + return(j); +} diff --git a/src/troff/ni.c b/src/troff/ni.c new file mode 100755 index 00000000..0e7c1631 --- /dev/null +++ b/src/troff/ni.c @@ -0,0 +1,265 @@ +#include "tdef.h" +char obuf[OBUFSZ]; +char *obufp = obuf; +int rx[NN] = { /* Nick r */ + PAIR('%',0), + PAIR('n','l'), + PAIR('y','r'), + PAIR('h','p'), + PAIR('c','t'), + PAIR('d','n'), + PAIR('m','o'), + PAIR('d','y'), + PAIR('d','w'), + PAIR('l','n'), + PAIR('d','l'), + PAIR('s','t'), + PAIR('s','b'), + PAIR('c','.')}; +int pto = 10000; +int pfrom = 1; +int print = 1; +#ifdef VAX /* Nick */ +char nextf[NS] = "tmac\\tmac.xxxxx"; +int nfi = 10; +#else +char nextf[NS] = "/usr/lib/tmac/tmac.xxxxx"; +int nfi = 19; +#endif +#ifdef NROFF +#ifdef VAX /* Nick */ +char termtab[NS] = "term\\tab37"; +int tti = 8; +#else +char termtab[NS] = "/usr/lib/term/tab37"; +int tti = 17; +#endif +#endif +#ifndef NROFF +int oldbits = -1; +#endif +int init = 1; +int fc = IMP; +int eschar = '\\'; +int pl = 11*INCH; +int po = PO; +int dfact = 1; +int dfactd = 1; +int res = 1; +int smnt = 4; +int ascii = ASCII; +int ptid = PTID; +char ptname[] = "/dev/cat"; +int lg = LG; +int pnlist[NPN] = {-1}; +int *pnp = pnlist; +int npn = 1; +int npnflg = 1; +int xflg = 1; +int dpn = -1; +int totout = 1; +int ulfont = 1; +int ulbit = 1<<9; +int tabch = TAB; +int ldrch = LEADER; +int xxx; +extern caseds(), caseas(), casesp(), caseft(), caseps(), casevs(), +casenr(), caseif(), casepo(), casetl(), casetm(), casebp(), casech(), +casepn(), tbreak(), caseti(), casene(), casenf(), casece(), casefi(), +casein(), caseli(), casell(), casens(), casemk(), casert(), caseam(), +casede(), casedi(), caseda(), casewh(), casedt(), caseit(), caserm(), +casern(), casead(), casers(), casena(), casepl(), caseta(), casetr(), +caseul(), caselt(), casenx(), caseso(), caseig(), casetc(), casefc(), +caseec(), caseeo(), caselc(), caseev(), caserd(), caseab(), casefl(), +done(), casess(), casefp(), casecs(), casebd(), caselg(), casehc(), +casehy(), casenh(), casenm(), casenn(), casesv(), caseos(), casels(), +casecc(), casec2(), caseem(), caseaf(), casehw(), casemc(), casepm(), +casecu(), casepi(), caserr(), caseuf(), caseie(), caseel(), casepc(), +caseht(); +#ifndef NROFF +extern casefz(); +#endif +extern casecf(); +struct contab { + int rq; +/* + union { + */ + int (*f)(); +/* + unsigned mx; + }x; + */ +}contab[NM]= { + PAIR('d','s'),caseds, + PAIR('a','s'),caseas, + PAIR('s','p'),casesp, + PAIR('f','t'),caseft, + PAIR('p','s'),caseps, + PAIR('v','s'),casevs, + PAIR('n','r'),casenr, + PAIR('i','f'),caseif, + PAIR('i','e'),caseie, + PAIR('e','l'),caseel, + PAIR('p','o'),casepo, + PAIR('t','l'),casetl, + PAIR('t','m'),casetm, + PAIR('b','p'),casebp, + PAIR('c','h'),casech, + PAIR('p','n'),casepn, + PAIR('b','r'),tbreak, + PAIR('t','i'),caseti, + PAIR('n','e'),casene, + PAIR('n','f'),casenf, + PAIR('c','e'),casece, + PAIR('f','i'),casefi, + PAIR('i','n'),casein, + PAIR('l','i'),caseli, + PAIR('l','l'),casell, + PAIR('n','s'),casens, + PAIR('m','k'),casemk, + PAIR('r','t'),casert, + PAIR('a','m'),caseam, + PAIR('d','e'),casede, + PAIR('d','i'),casedi, + PAIR('d','a'),caseda, + PAIR('w','h'),casewh, + PAIR('d','t'),casedt, + PAIR('i','t'),caseit, + PAIR('r','m'),caserm, + PAIR('r','r'),caserr, + PAIR('r','n'),casern, + PAIR('a','d'),casead, + PAIR('r','s'),casers, + PAIR('n','a'),casena, + PAIR('p','l'),casepl, + PAIR('t','a'),caseta, + PAIR('t','r'),casetr, + PAIR('u','l'),caseul, + PAIR('c','u'),casecu, + PAIR('l','t'),caselt, + PAIR('n','x'),casenx, + PAIR('s','o'),caseso, + PAIR('i','g'),caseig, + PAIR('t','c'),casetc, + PAIR('f','c'),casefc, + PAIR('e','c'),caseec, + PAIR('e','o'),caseeo, + PAIR('l','c'),caselc, + PAIR('e','v'),caseev, + PAIR('r','d'),caserd, + PAIR('a','b'),caseab, + PAIR('f','l'),casefl, + PAIR('e','x'),done, + PAIR('s','s'),casess, + PAIR('f','p'),casefp, + PAIR('c','s'),casecs, + PAIR('b','d'),casebd, + PAIR('l','g'),caselg, + PAIR('h','c'),casehc, + PAIR('h','y'),casehy, + PAIR('n','h'),casenh, + PAIR('n','m'),casenm, + PAIR('n','n'),casenn, + PAIR('s','v'),casesv, + PAIR('o','s'),caseos, + PAIR('l','s'),casels, + PAIR('c','c'),casecc, + PAIR('c','2'),casec2, + PAIR('e','m'),caseem, + PAIR('a','f'),caseaf, + PAIR('h','w'),casehw, + PAIR('m','c'),casemc, + PAIR('p','m'),casepm, +#ifdef NROFF + PAIR('p','i'),casepi, +#endif + PAIR('u','f'),caseuf, + PAIR('p','c'),casepc, + PAIR('h','t'),caseht, +#ifndef NROFF + PAIR('f','z'),casefz, +#endif + PAIR('c', 'f'),casecf, +}; + +/* +troff environment block +*/ + +int block = 0; +int ics = ICS; +int ic = 0; +int icf = 0; +int chbits = 0; +int spbits = 0; +int nmbits = 0; +int apts = PS; +int apts1 = PS; +int pts = PS; +int pts1 = PS; +int font = FT; +int font1 = FT; +int sps = SPS; +int spacesz = SS; +int lss = VS; +int lss1 = VS; +int ls = 1; +int ls1 = 1; +int ll = LL; +int ll1 = LL; +int lt = LL; +int lt1 = LL; +int ad = 1; +int nms = 1; +int ndf = 1; +int fi = 1; +int cc = '.'; +int c2 = '\''; +int ohc = OHC; +int tdelim = IMP; +int hyf = 1; +int hyoff = 0; +int un1 = -1; +int tabc = 0; +int dotc = '.'; +int adsp = 0; +int adrem = 0; +int lastl = 0; +int nel = 0; +int admod = 0; +int *wordp = 0; +int spflg = 0; +int *linep = 0; +int *wdend = 0; +int *wdstart = 0; +int wne = 0; +int ne = 0; +int nc = 0; +int nb = 0; +int lnmod = 0; +int nwd = 0; +int nn = 0; +int ni = 0; +int ul = 0; +int cu = 0; +int ce = 0; +int in = 0; +int in1 = 0; +int un = 0; +int wch = 0; +int pendt = 0; +int *pendw = 0; +int pendnf = 0; +int spread = 0; +int it = 0; +int itmac = 0; +int lnsize = LNSIZE; +int *hyptr[NHYP] = {0}; +int tabtab[NTAB] = {DTAB,DTAB*2,DTAB*3,DTAB*4,DTAB*5,DTAB*6,DTAB*7,DTAB*8, + DTAB*9,DTAB*10,DTAB*11,DTAB*12,DTAB*13,DTAB*14,DTAB*15,0}; +int line[LNSIZE] = {0}; +int word[WDSIZE] = {0}; +int blockxxx[EVS-68-NHYP-NTAB-WDSIZE-LNSIZE] = {0}; +/*spare 5 words*/ +int oline[LNSIZE+1]; diff --git a/src/troff/nii.c b/src/troff/nii.c new file mode 100755 index 00000000..31b1f754 --- /dev/null +++ b/src/troff/nii.c @@ -0,0 +1,140 @@ +#include "tdef.h" +#ifdef NROFF +#include "tw.h" +#endif +#include "s.h" +#include "d.h" +#include "v.h" +#ifndef VAX /* Nick */ +#include +#endif + +int *vlist = (int *)&v; +struct s *frame, *stk, *ejl; +struct s *nxf, *litlev; + +#ifdef NROFF +int pipeflg; +int hflg; +int eqflg; +#endif + +#ifndef NROFF +int xpts; +int verm; +int *pslp; +int psflg; +int ppts; +int pfont; +int paper; +int mpts; +int mfont; +int mcase; +int escm; +int cs; +int code; +int ccs; +int bd; +int back; +#endif + +int level; +int stdi; +int waitf; +int nofeed; +int quiet; +int stop; +char ibuf[IBUFSZ]; +char xbuf[IBUFSZ]; +char *ibufp; +char *xbufp; +char *eibuf; +char *xeibuf; +int cbuf[NC]; +int *cp; +int nx; +int mflg; +int ch = 0; +int cps; +int ibf; +int ttyod; +#ifndef VAX /* Nick */ +struct sgttyb ttys; +#endif +int iflg; +char *enda; +int rargc; +char **argp; +char trtab[256]; +int lgf; +int copyf; +int ch0; +int cwidth; +filep ip; +int nlflg; +int *ap; +int donef; +int nflush; +int nchar; +int rchar; +int nfo; +int ifile; +int padc; +int raw; +int ifl[NSO]; +int ifi; +int flss; +int nonumb; +int trap; +int tflg; +int ejf; +int lit; +int gflag; +int dilev; +int tlss; +filep offset; +int em; +int ds; +filep woff; +int app; +int ndone; +int lead; +int ralss; +filep nextb; +int *argtop; +int nrbits; +int nform; +int oldmn; +int newmn; +int macerr; +filep apptr; +int diflg; +filep roff; +int wbfi; +int inc[NN]; +int fmt[NN]; +int evi; +int vflag; +int noscale; +int po1; +int nlist[NTRAP]; +int mlist[NTRAP]; +int evlist[EVLSZ]; +int ev; +int tty; +int sfont; +int sv; +int esc; +int widthp; +int xfont; +int setwdf; +int xbitf; +int over; +int nhyp; +int **hyp; +int *olinep; +int esct; +int ttysave = -1; +int dotT; +char *unlkp; +int no_out; diff --git a/src/troff/nmake b/src/troff/nmake new file mode 100755 index 00000000..1c084af5 --- /dev/null +++ b/src/troff/nmake @@ -0,0 +1,32 @@ +CFLAGS=-n -s -O -DNROFF +NFILES=n1.o n2.o n3.o n4.o n5.o n6.o n7.o n8.o n9.o n10.o ni.o nii.o ntab.o hytab.o suftab.o + +nroff: $(NFILES) + cc -o nroff $(CFLAGS) $(NFILES) + +n1.o: tdef.h d.h v.h tw.h s.h +n2.o: tdef.h d.h v.h tw.h s.h +n3.o: tdef.h d.h v.h tw.h s.h +n4.o: tdef.h d.h v.h tw.h s.h +n5.o: tdef.h d.h v.h tw.h s.h +n6.o: tdef.h d.h v.h tw.h s.h +t6.o: tdef.h d.h v.h tw.h s.h +n7.o: tdef.h d.h v.h tw.h s.h +n8.o: tdef.h d.h v.h tw.h s.h +n9.o: tdef.h d.h v.h tw.h s.h +n10.o: tdef.h d.h v.h tw.h s.h +t10.o: tdef.h d.h v.h tw.h s.h +ni.o: tdef.h d.h v.h tw.h s.h +nii.o: tdef.h d.h v.h tw.h s.h + +hytab.o: hytab.c + cc -S hytab.c + ed hytab.s L<4HAVv9P)pHiGbYLk#S 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∈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Μt+(E_KCnKw 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 TVju7)C5`lvvR!K8Sn59jVOtVX literal 0 HcmV?d00001 diff --git a/src/troff/nroff.lnk b/src/troff/nroff.lnk new file mode 100755 index 00000000..4170c383 --- /dev/null +++ b/src/troff/nroff.lnk @@ -0,0 +1,27 @@ +-k ..\..\lib +-l libcb.lib +-l libsysb.lib +-l libiar.lib +-m +-u +-i +-o nroff +-bl RCODE=0x8100 +-bl CODE=0x4000,0x10000 +-bc CODE=0x4000 +..\..\lib\c0b.rel +n1 +n2 +n3 +n4 +n5 +n6 +n7 +n8 +n9 +n10 +ni +nii +ntab +hytab +suftab diff --git a/src/troff/nroff.w32 b/src/troff/nroff.w32 new file mode 100755 index 00000000..145d404d --- /dev/null +++ b/src/troff/nroff.w32 @@ -0,0 +1,20 @@ +/debug +/subsystem:console +"/libpath:c:\Program Files\Microsoft Visual Studio\VC98\lib" +/map:nroff.map +/out:nroff.exe +n1.obj +n2.obj +n3.obj +n4.obj +n5.obj +n6.obj +n7.obj +n8.obj +n9.obj +n10.obj +ni.obj +nii.obj +ntab.obj +hytab.obj +suftab.obj diff --git a/src/troff/ntab.c b/src/troff/ntab.c new file mode 100755 index 00000000..db17a50f --- /dev/null +++ b/src/troff/ntab.c @@ -0,0 +1,135 @@ +#define BYTE 8 +#define PAIR(A,B) (A|(B<','='), 0277, /*>=*/ +PAIR('<','='), 0300, /*<=*/ +PAIR('=','='), 0301, /*identically equal*/ +PAIR('~','='), 0303, /*approx =*/ +PAIR('a','p'), 0304, /*approximates*/ +PAIR('!','='), 0305, /*not equal*/ +PAIR('-','>'), 0306, /*right arrow*/ +PAIR('<','-'), 0307, /*left arrow*/ +PAIR('u','a'), 0310, /*up arrow*/ +PAIR('d','a'), 0311, /*down arrow*/ +PAIR('e','q'), 0312, /*equation equal*/ +PAIR('m','u'), 0313, /*multiply*/ +PAIR('d','i'), 0314, /*divide*/ +PAIR('+','-'), 0315, /*plus-minus*/ +PAIR('c','u'), 0316, /*cup (union)*/ +PAIR('c','a'), 0317, /*cap (intersection)*/ +PAIR('s','b'), 0320, /*subset of*/ +PAIR('s','p'), 0321, /*superset of*/ +PAIR('i','b'), 0322, /*improper subset*/ +PAIR('i','p'), 0323, /* " superset*/ +PAIR('i','f'), 0324, /*infinity*/ +PAIR('p','d'), 0325, /*partial derivative*/ +PAIR('g','r'), 0326, /*gradient*/ +PAIR('n','o'), 0327, /*not*/ +PAIR('i','s'), 0330, /*integral sign*/ +PAIR('p','t'), 0331, /*proportional to*/ +PAIR('e','s'), 0332, /*empty set*/ +PAIR('m','o'), 0333, /*member of*/ +PAIR('p','l'), 0334, /*equation plus*/ +PAIR('r','g'), 0335, /*registered*/ +PAIR('c','o'), 0336, /*copyright*/ +PAIR('b','r'), 0337, /*box vert rule*/ +PAIR('c','t'), 0340, /*cent sign*/ +PAIR('d','d'), 0341, /*dbl dagger*/ +PAIR('r','h'), 0342, /*right hand*/ +PAIR('l','h'), 0343, /*left hand*/ +PAIR('*','*'), 0344, /*math * */ +PAIR('b','s'), 0345, /*bell system sign*/ +PAIR('o','r'), 0346, /*or*/ +PAIR('c','i'), 0347, /*circle*/ +PAIR('l','t'), 0350, /*left top (of big curly)*/ +PAIR('l','b'), 0351, /*left bottom*/ +PAIR('r','t'), 0352, /*right top*/ +PAIR('r','b'), 0353, /*right bot*/ +PAIR('l','k'), 0354, /*left center of big curly bracket*/ +PAIR('r','k'), 0355, /*right center of big curly bracket*/ +PAIR('b','v'), 0356, /*bold vertical*/ +PAIR('l','f'), 0357, /*left floor (left bot of big sq bract)*/ +PAIR('r','f'), 0360, /*right floor (rb of ")*/ +PAIR('l','c'), 0361, /*left ceiling (lt of ")*/ +PAIR('r','c'), 0362, /*right ceiling (rt of ")*/ +0,0}; diff --git a/src/troff/s.h b/src/troff/s.h new file mode 100755 index 00000000..86018cf4 --- /dev/null +++ b/src/troff/s.h @@ -0,0 +1,12 @@ +struct s { + int nargs; + struct s *pframe; + filep pip; + int pnchar; + int prchar; + int ppendt; + int *pap; + int *pcp; + int pch0; + int pch; + }; diff --git a/src/troff/sh.1 b/src/troff/sh.1 new file mode 100755 index 00000000..1cb61240 --- /dev/null +++ b/src/troff/sh.1 @@ -0,0 +1,261 @@ +.TH SH 1 +.SH NAME +sh, ., break, case, cd, continue, eval, exec, exit, export, for, if, read, readonly, set, shift, trap, umask, wait, while \- shell +.SH SYNOPSIS +\fBsh\fR [\fB\-eiknqstvxu\fR] [\fB\-c \fIstr\fR] \fB[\fIfile\fR]\fR +.br +.de FL +.TP +\\fB\\$1\\fR +\\$2 +.. +.de EX +.TP 20 +\\fB\\$1\\fR +# \\$2 +.. +.SH OPTIONS +.FL "\-c" "Execute the commands in \fIstr\fR" +.FL "\-e" "Quit on error" +.FL "\-i" "Interactive mode; ignore QUIT, TERMINATE, INTERRUPT" +.FL "\-k" "Look for name=value everywhere on command line" +.FL "\-n" "Do not execute commands" +.FL "\-q" "Change qflag from sig_ign to sig_del" +.FL "\-s" "Read commands from standard input" +.FL "\-t" "Exit after reading and executing one command" +.FL "\-v" "Echo input lines as they are read" +.FL "\-x" "Trace" +.FL "\-u" "Unset variables" +.SH EXAMPLES +.EX "sh script" "Run a shell script" +.SH DESCRIPTION +.PP +.I Sh +is the shell, which forms the user's main interface with the system. +On startup, the shell reads /etc/profile and $HOME/.profile, if they exist, +and executes any commands they contain. The Minix shell has most of the +features of the V7 (Bourne) shell, including redirection of input and output, +pipes, magic characters, background processes, and shell scripts. A brief +summary follows, but whole books have been written on shell programming alone. +.LP +Some of the more common notations are: +.PP +.in +2.45i +.ta 2i 2.2i +.ti -2.2i +date # Regular command +.ti -2.2i +sort file2 # Redirect \fIstdin\fR and \fIstdout\fR +.ti -2.2i +cc file.c 2>error # Redirect \fIstderr\fR +.ti -2.2i +a.out >f 2>&1 # Combine standard output and standard error +.ti -2.2i +sort >file2 # Append output to \fIfile2\fR +.ti -2.2i +sort file2 & # Background job +.ti -2.2i +(ls \-l; a.out) & # Run two background commands sequentially +.ti -2.2i +sort with no command name, modify shell I/O +.ti -2i +exit [n] exit a shell program, with exit value n +.ti -2i +export [var] export var to shell's children; list exported variables +.ti -2i +pwd print the name of the current working directory +.ti -2i +read var read a line from stdin and assign to var +.ti -2i +readonly [var] make var readonly; list readonly variables +.ti -2i +set -f set shell flag (+f unsets flag) +.ti -2i +set str set positional parameter to str +.ti -2i +set show the current shell variables +.ti -2i +shift reassign positional parameters (except ${0}) one left +.ti -2i +times print accumulated user and system times for processes +.ti -2i +trap arg sigs trap signals sigs and run arg on receipt +.ti -2i +trap list trapped signals +.ti -2i +umask [n] set the user file creation mask; show the current umask +.ti -2i +wait [n] wait for process pid n; wait for all processes +.in -2.25i +.LP +The shell also contains a programming language, which has the following +operators and flow control statements: +.PP +.in +3.50i +.ta 2i 3.25i +.ti -3.25i +# Comment The rest of the line is ignored +.ti -3.25i += Assignment Set a shell variable +.ti -3.25i +&& Logical AND Execute second command only if first succeeds +.ti -3.25i +|| Logical OR Execute second command only if first fails +.ti -3.25i +(...) Group Execute enclosed commands before continuing +.in -3.50i +.PP +.in +2.25i +.ta 2i +.ti -2i +for For loop (for ... in ... do ... done) +.ti -2i +case Case statement ((case ... ) ... ;; ... esac) +.ti -2i +esac Case statement end +.ti -2i +while While loop (while ... do ... done) +.ti -2i +do Do/For/While loop start (do ... until ...) +.ti -2i +done For/While loop end +.ti -2i +if Conditional statement (if ... else ... elif ... fi) +.ti -2i +in For loop selection +.ti -2i +then Conditional statement start +.ti -2i +else Conditional statement alternative +.ti -2i +elif Conditional statement end +.ti -2i +until Do loop end +.ti -2i +fi Conditional statement end +.in -2.25i +.SH "SEE ALSO" +.BR echo (1), +.BR expr (1), +.BR pwd (1), +.BR true (1). diff --git a/src/troff/suftab.c b/src/troff/suftab.c new file mode 100755 index 00000000..011a3225 --- /dev/null +++ b/src/troff/suftab.c @@ -0,0 +1,606 @@ +/* + * Suffix table + */ + +static char sufa[] = { + 02,0200+'t', /* -TA */ + 02,0200+'s', /* -SA */ + 03,0200+'t','r', /* -TRA */ + 03,0200+'d','r', /* -DRA */ + 03,0200+'b','r', /* -BRA */ + 02,0200+'p', /* -PA */ + 02,0200+'n', /* -NA */ + 02,0200+'m', /* -MA */ + 03,0200+'p','l', /* -PLA */ + 02,0200+'l', /* -LA */ + 02,0200+'k', /* -KA */ + 03,0200+'t','h', /* -THA */ + 03,0200+'s','h', /* -SHA */ + 02,0200+'g', /* -GA */ + 02,0200+'d', /* -DA */ + 02,0200+'c', /* -CA */ + 02,0200+'b', /* -BA */ + 00 +}; + +static char sufc[] = { + 04,'e','t',0200+'i', /* ET-IC */ + 07,'a','l',0200+'i','s',0200+'t','i', /* AL-IS-TIC */ + 04,'s',0200+'t','i', /* S-TIC */ + 04,'p',0200+'t','i', /* P-TIC */ + 05,0200+'l','y','t',0200+'i', /* -LYT-IC */ + 04,'o','t',0200+'i', /* OT-IC */ + 05,'a','n',0200+'t','i', /* AN-TIC */ + 04,'n',0200+'t','i', /* N-TIC */ + 04,'c',0200+'t','i', /* C-TIC */ + 04,'a','t',0200+'i', /* AT-IC */ + 04,'h',0200+'n','i', /* H-NIC */ + 03,'n',0200+'i', /* N-IC */ + 03,'m',0200+'i', /* M-IC */ + 04,'l',0200+'l','i', /* L-LIC */ + 04,'b',0200+'l','i', /* B-LIC */ + 04,0200+'c','l','i', /* -CLIC */ + 03,'l',0200+'i', /* L-IC */ + 03,'h',0200+'i', /* H-IC */ + 03,'f',0200+'i', /* F-IC */ + 03,'d',0200+'i', /* D-IC */ + 03,0200+'b','i', /* -BIC */ + 03,'a',0200+'i', /* A-IC */ + 03,0200+'m','a', /* -MAC */ + 03,'i',0200+'a', /* I-AC */ + 00 +}; + +static char sufd[] = { + 04,0200+'w','o','r', /* -WORD */ + 04,0200+'l','o','r', /* -LORD */ + 04,0200+'f','o','r', /* -FORD */ + 04,0200+'y','a','r', /* -YARD */ + 04,0200+'w','a','r', /* -WARD */ + 05,0200+'g','u','a','r', /* -GUARD */ + 04,0200+'t','a','r', /* -TARD */ + 05,0200+'b','o','a','r', /* -BOARD */ + 04,0200+'n','a','r', /* -NARD */ + 05,0200+'l','i','a','r', /* -LIARD */ + 04,0200+'i','a','r', /* -IARD */ + 04,0200+'g','a','r', /* -GARD */ + 04,0200+'b','a','r', /* -BARD */ + 03,0200+'r','o', /* -ROD */ + 04,0200+'w','o','o', /* -WOOD */ + 04,0200+'h','o','o', /* -HOOD */ + 04,0200+'m','o','n', /* -MOND */ + 04,0200+'t','e','n', /* -TEND */ + 05,0200+'s','t','a','n', /* -STAND */ + 04,0200+'l','a','n', /* -LAND */ + 04,0200+'h','a','n', /* -HAND */ + 04,0200+'h','o','l', /* -HOLD */ + 04,0200+'f','o','l', /* -FOLD */ + 05,0200+'f','i','e','l', /* -FIELD */ + 03,0200+'v','i', /* -VID */ + 03,0200+'c','i', /* -CID */ + 04,0200+'s','a','i', /* -SAID */ + 04,0200+'m','a','i', /* -MAID */ + 04,'t',0200+'t','e', /* T-TED */ + 03,'t',0200+'e', /* T-ED */ + 04,0200+'d','r','e', /* -DRED */ + 04,0200+'c','r','e', /* -CRED */ + 04,0200+'b','r','e', /* -BRED */ + 05,'v',0200+'e','l','e', /* V-ELED */ + 0100+04,'a','l',0200+'e', /* AL/ED */ + 0140+03,0200+'e','e', /* /EED */ + 040+05,'e','d',0200+'d','e', /* ED-DED */ + 04,'d',0200+'d','e', /* D-DED */ + 040+04,'e','d',0200+'e', /* ED-ED */ + 03,'d',0200+'e', /* D-ED */ + 05,0200+'d','u','c','e', /* -DUCED */ + 0300+02,'e', /* E/D */ + 05,0200+'s','t','e','a', /* -STEAD */ + 04,0200+'h','e','a', /* -HEAD */ + 00 +}; + +static char sufe[] = { + 05,'a','r',0200+'i','z', /* AR-IZE */ + 05,'a','n',0200+'i','z', /* AN-IZE */ + 05,'a','l',0200+'i','z', /* AL-IZE */ + 06,0200+'a','r','d',0200+'i','z', /* -ARD-IZE */ + 05,0200+'s','e','l','v', /* -SELVE */ + 05,0200+'k','n','i','v', /* -KNIVE */ + 05,0200+'l','i','e','v', /* -LIEVE */ + 0100+03,0200+'q','u', /* /QUE */ + 07,'o','n',0200+'t','i','n',0200+'u', /* ON-TIN-UE */ + 03,0200+'n','u', /* -NUE */ + 03,0200+'d','u', /* -DUE */ + 0300+02,'u', /* U/E */ + 0300+05,'q','u','a','t', /* QUAT/E */ + 04,'u',0200+'a','t', /* U-ATE */ + 05,0200+'s','t','a','t', /* -STATE */ + 04,0200+'t','a','t', /* -TATE */ + 06,0200+'t','o','r',0200+'a','t', /* -TOR-ATE */ + 05,'e','n',0200+'a','t', /* EN-ATE */ + 04,0200+'m','a','t', /* -MATE */ + 05,0200+'h','o','u','s', /* -HOUSE */ + 05,0200+'c','l','o','s', /* -CLOSE */ + 04,'i',0200+'o','s', /* I-OSE */ + 04,0200+'w','i','s', /* -WISE */ + 05,'a','s',0200+'u','r', /* AS-URE */ + 040+04,0200+'s','u','r', /* -SURE */ + 06,0200+'f','i','g',0200+'u','r', /* -FIG-URE */ + 040+03,0200+'t','r', /* -TRE */ + 05,0200+'s','t','o','r', /* -STORE */ + 04,0200+'f','o','r', /* -FORE */ + 05,0200+'w','h','e','r', /* -WHERE */ + 06,0200+'s','p','h','e','r', /* -SPHERE */ + 03,0200+'d','r', /* -DRE */ + 03,0200+'c','r', /* -CRE */ + 03,0200+'b','r', /* -BRE */ + 05,0200+'s','c','o','p', /* -SCOPE */ + 04,'y',0200+'o','n', /* Y-ONE */ + 05,0200+'s','t','o','n', /* -STONE */ + 05,0200+'p','h','o','n', /* -PHONE */ + 04,0200+'g','o','n', /* -GONE */ + 04,'e',0200+'o','n', /* E-ONE */ + 040+04,0200+'e','n','n', /* -ENNE */ + 040+05,'a',0200+'r','i','n', /* A-RINE */ + 05,0200+'c','l','i','n', /* -CLINE */ + 04,0200+'l','i','n', /* -LINE */ + 007,00200+'r','o','u',00200+'t','i','n', /*-ROU-TINE */ + 04,0200+'s','o','m', /* -SOME */ + 04,0200+'c','o','m', /* -COME */ + 04,0200+'t','i','m', /* -TIME */ + 03,0200+'z','l', /* -ZLE */ + 03,0200+'t','l', /* -TLE */ + 03,0200+'s','l', /* -SLE */ + 03,0200+'p','l', /* -PLE */ + 05,0200+'v','i','l','l', /* -VILLE */ + 04,'c','k',0200+'l', /* CK-LE */ + 03,0200+'k','l', /* -KLE */ + 03,0200+'g','l', /* -GLE */ + 03,0200+'f','l', /* -FLE */ + 03,0200+'d','l', /* -DLE */ + 03,0200+'c','l', /* -CLE */ + 05,0200+'p','a',0200+'b','l', /* -PA-BLE */ + 05,'f','a',0200+'b','l', /* FA-BLE */ + 05,0200+'c','a',0200+'b','l', /* -CA-BLE */ + 06,0200+'s','t','a','b','l', /* -STABLE */ + 04,0200+'a','b','l', /* -ABLE */ + 03,0200+'b','l', /* -BLE */ + 04,0200+'d','a','l', /* -DALE */ + 04,0200+'m','a','l', /* -MALE */ + 04,0200+'s','a','l', /* -SALE */ + 04,0200+'l','i','k', /* -LIKE */ + 0340+05,'g',0200+'u','a','g', /* -G/UAGE */ + 05,0200+'r','i','a','g', /* -RIAGE */ + 05,'e','r',0200+'a','g', /* ER-AGE */ + 04,'m',0200+'a','g', /* M-AGE */ + 04,'k',0200+'a','g', /* K-AGE */ + 04,'d',0200+'a','g', /* D-AGE */ + 04,0200+'w','i','f', /* -WIFE */ + 05,0200+'k','n','i','f', /* -KNYFE */ + 03,0200+'s','e', /* -SEE */ + 04,0200+'f','r','e', /* -FREE */ + 0340+02,'e', /* EE */ + 04,0200+'w','i','d', /* -WIDE */ + 04,0200+'t','i','d', /* -TIDE */ + 04,0200+'s','i','d', /* -SIDE */ + 06,0200+'q','u','e','n','c', /* -QUENCE */ + 07,0200+'f','l','u',0200+'e','n','c', /* -FLU-ENCE */ + 040+06,'e','s',0200+'e','n','c', /* ES-ENCE */ + 06,'e','r',0200+'e','n','c', /* ER-ENCE */ + 05,'i',0200+'e','n','c', /* I-ENCE */ + 040+05,0200+'s','a','n','c', /* -SANCE */ + 06,'e','r',0200+'a','n','c', /* ER-ANCE */ + 06,'a','r',0200+'a','n','c', /* AR-ANCE */ + 05,0200+'n','a','n','c', /* -NANCE */ + 07,0200+'b','a','l',0200+'a','n','c', /* -BAL-ANCE */ + 05,'i',0200+'a','n','c', /* I-ANCE */ + 07,0200+'j','u','s',0200+'t','i','c', /* -JUS-TICE */ + 05,0200+'s','t','i','c', /* -STICE */ + 05,0200+'p','i','e','c', /* -PIECE */ + 05,0200+'p','l','a','c', /* -PLACE */ + 0340+01, /* /E */ + 00 +}; + +static char suff[] = { + 03,0200+'o','f', /* -OFF */ + 05,0200+'p','r','o','o', /* -PROOF */ + 04,0200+'s','e','l', /* -SELF */ + 03,0200+'r','i', /* -RIF */ + 040+04,0200+'l','i','e', /* -LIEF */ + 00 +}; + +static char sufg[] = { + 03,0200+'l','o', /* -LOG */ + 04,0200+'l','o','n', /* -LONG */ + 05,'t',0200+'t','i','n', /* T-TING */ + 06,0200+'s','t','r','i','n', /* -STRING */ + 05,'r',0200+'r','i','n', /* R-RING */ + 05,'p',0200+'p','i','n', /* P-PING */ + 05,'n',0200+'n','i','n', /* N-NING */ + 05,'m',0200+'m','i','n', /* M-MING */ + 05,'l',0200+'l','i','n', /* L-LING */ + 05,0200+'z','l','i','n', /* -ZLING */ + 05,0200+'t','l','i','n', /* -TLING */ + 040+05,'s',0200+'l','i','n', /* S-LING */ + 05,'r',0200+'l','i','n', /* R-LING */ + 05,0200+'p','l','i','n', /* -PLING */ + 06,'n',0200+'k','l','i','n', /* N-KLING */ + 05,'k',0200+'l','i','n', /* K-LING */ + 05,0200+'g','l','i','n', /* -GLING */ + 05,0200+'f','l','i','n', /* -FLING */ + 05,0200+'d','l','i','n', /* -DLING */ + 05,0200+'c','l','i','n', /* -CLING */ + 05,0200+'b','l','i','n', /* -BLING */ + 06,'y',0200+'t','h','i','n', /* Y-THING */ + 07,'e','e','t','h',0200+'i','n', /* EETH-ING */ + 06,'e',0200+'t','h','i','n', /* E-THING */ + 05,'g',0200+'g','i','n', /* G-GING */ + 05,'d',0200+'d','i','n', /* D-DING */ + 05,'b',0200+'b','i','n', /* B-BING */ + 03,0200+'i','n', /* -ING */ + 00 +}; + +static char sufh[] = { + 05,0200+'m','o','u','t', /* -MOUTH */ + 05,0200+'w','o','r','t', /* -WORTH */ + 04,0200+'w','i','t', /* -WITH */ + 05,'t',0200+'t','i','s', /* T-TISH */ + 05,'e',0200+'t','i','s', /* E-TISH */ + 05,'p',0200+'p','i','s', /* P-PISH */ + 05,'r',0200+'n','i','s', /* R-NISH */ + 05,'n',0200+'n','i','s', /* N-NISH */ + 05,0200+'p','l','i','s', /* -PLISH */ + 05,0200+'g','u','i','s', /* -GUISH */ + 05,0200+'g','l','i','s', /* -GLISH */ + 05,'b',0200+'l','i','s', /* B-LISH */ + 05,'g',0200+'g','i','s', /* G-GISH */ + 05,'d',0200+'d','i','s', /* D-DISH */ + 03,0200+'i','s', /* -ISH */ + 05,0200+'g','r','a','p', /* -GRAPH */ + 07,0200+'b','o','r',0200+'o','u','g', /* -BOR-OUGH */ + 05,0200+'b','u','r','g', /* -BURGH */ + 04,0200+'v','i','c', /* -VICH */ + 03,0200+'n','a', /* -NAH */ + 03,0200+'l','a', /* -LAH */ + 04,0200+'m','i',0200+'a', /* -MI-AH */ + 00 +}; + +static char sufi[] = { + 03,0200+'t','r', /* -TRI */ + 03,0200+'c','h', /* -CHI */ + 0200+03,'i','f', /* IF-I */ + 0200+03,'e','d', /* ED-I */ + 05,0200+'a','s','c','i', /* -ASCII */ + 04,0200+'s','e','m', /* -SEMI */ + 00 +}; + +static char sufk[] = { + 04,0200+'w','o','r', /* -WORK */ + 04,0200+'m','a','r', /* -MARK */ + 04,0200+'b','o','o', /* -BOOK */ + 04,0200+'w','a','l', /* -WALK */ + 05,0200+'c','r','a','c', /* -CRACK */ + 04,0200+'b','a','c', /* -BACK */ + 00 +}; + +static char sufl[] = { + 03,0200+'f','u', /* -FUL */ + 05,'s',0200+'w','e','l', /* S-WELL */ + 04,0200+'t','e','l', /* -TELL */ + 05,0200+'s','h','e','l', /* -SHELL */ + 05,0200+'s','t','a','l', /* -STALL */ + 04,0200+'s','t','a', /* -STAL */ + 04,0200+'b','a','l', /* -BALL */ + 04,0200+'c','a','l', /* -CALL */ + 03,'v',0200+'e', /* V-EL */ + 03,'u',0200+'e', /* U-EL */ + 03,'k',0200+'e', /* K-EL */ + 04,'t','h',0200+'e', /* TH-EL */ + 05,'t','c','h',0200+'e', /* TCH-EL */ + 03,'a',0200+'e', /* A-EL */ + 0140+04,0200+'q','u','a', /* /QUAL */ + 040+03,'u',0200+'a', /* U-AL */ + 03,0200+'t','a', /* -TAL */ + 04,'u','r',0200+'a', /* UR-AL */ + 040+05,'g',0200+'o',0200+'n','a', /* G-O-NAL */ + 04,'o','n',0200+'a', /* ON-AL */ + 03,0200+'n','a', /* -NAL */ + 04,0200+'t','i','a', /* -TIAL */ + 04,0200+'s','i','a', /* -SIAL */ + 040+05,0200+'t','r','i',0200+'a', /* -TRI-AL */ + 04,'r','i',0200+'a', /* RI-AL */ + 04,0200+'n','i',0200+'a', /* -NI-AL */ + 04,0200+'d','i',0200+'a', /* -DI-AL */ + 04,0200+'c','i','a', /* -CIAL */ + 03,0200+'g','a', /* -GAL */ + 04,0200+'m','e','a', /* -MEAL */ +/* 040+04,0200+'r','e',0200+'a', /* -RE-AL */ + 040+04,0200+'r','e','a', /* -REAL */ + 06,'c',0200+'t','i',0200+'c','a', /* C-TI-CAL */ + 05,0200+'s','i',0200+'c','a', /* -SI-CAL */ + 04,0200+'i',0200+'c','a', /* -I-CAL */ + 03,0200+'c','a', /* -CAL */ + 03,0200+'b','a', /* -BAL */ + 06,0200+'n','o',0200+'m','i',0200+'a', /* -NO-MI-AL */ + 00 +}; + +static char sufm[] = { + 03,0200+'n','u', /* -NUM */ + 05,'o',0200+'r','i',0200+'u', /* O-RI-UM */ + 040+03,'i',0200+'u', /* I-UM */ + 040+03,'e',0200+'u', /* E-UM */ + 05,'i','v',0200+'i','s', /* IV-ISM */ + 04,0200+'t','i','s', /* -TISM */ + 05,'i',0200+'m','i','s', /* I-MISM */ + 05,'a','l',0200+'i','s', /* AL-ISM */ + 040+04,'e',0200+'i','s', /* E-ISM */ + 040+04,'a',0200+'i','s', /* A-ISM */ + 04,0200+'r','o','o', /* -ROOM */ + 03,0200+'d','o', /* -DOM */ + 03,0200+'h','a', /* -HAM */ + 06,0200+'a',0200+'r','i','t','h', /* -A-RITHM */ + 05,0200+'r','i','t','h', /* -RITHM */ + 00 +}; + +static char sufn[] = { + 04,0200+'t','o','w', /* -TOWN */ + 04,0200+'d','o','w', /* -DOWN */ + 04,0200+'t','u','r', /* -TURN */ + 05,0200+'s','p','o','o', /* -SPOON */ + 04,0200+'n','o','o', /* -NOON */ + 04,0200+'m','o','o', /* -MOON */ + 011,'a','l',0200+'i',0200+'z','a',0200+'t','i','o', /* AL-I-ZA-TION */ + 07,0200+'i',0200+'z','a',0200+'t','i','o', /* -I-ZA-TION */ + 07,'l',0200+'i',0200+'a',0200+'t','i','o', /* L-I-A-TION */ + 04,0200+'t','i','o', /* -TION */ + 040+05,'s',0200+'s','i','o', /* S-SION */ + 04,0200+'s','i','o', /* -SION */ + 04,'n',0200+'i','o', /* N-ION */ + 04,0200+'g','i','o', /* -GION */ + 04,0200+'c','i','o', /* -CION */ + 03,0200+'c','o', /* -CON */ + 05,0200+'c','o','l','o', /* -COLON */ + 03,0200+'t','o', /* -TON */ + 04,'i','s',0200+'o', /* IS-ON */ + 03,0200+'s','o', /* -SON */ + 03,0200+'r','i', /* -RIN */ + 03,0200+'p','i', /* -PIN */ + 03,0200+'n','i', /* -NIN */ + 03,0200+'m','i', /* -MIN */ + 03,0200+'l','i', /* -LIN */ + 03,0200+'k','i', /* -KIN */ + 05,0200+'s','t','e','i', /* -STEIN */ + 04,0200+'t','a','i', /* -TAIN */ + 05,'g','h','t',0200+'e', /* GHT-EN */ + 05,0200+'w','o','m',0200+'e', /* -WOM-EN */ + 03,0200+'m','e', /* -MEN */ + 04,'o',0200+'k','e', /* O-KEN */ + 03,'k',0200+'e', /* K-EN */ + 04,0200+'t','e','e', /* -TEEN */ + 04,0200+'s','e','e', /* -SEEN */ + 040+03,0200+'s','a', /* -SAN */ + 05,0200+'w','o','m',0200+'a', /* -WOM-AN */ + 03,0200+'m','a', /* -MAN */ + 04,0200+'t','i','a', /* -TIAN */ + 04,0200+'s','i','a', /* -SIAN */ + 040+04,'e',0200+'i','a', /* E-IAN */ + 04,0200+'c','i','a', /* -CIAN */ + 0300+03,'i','a', /* IA/N */ + 05,0200+'c','l','e','a', /* -CLEAN */ + 04,0200+'m','e','a', /* -MEAN */ + 040+03,'e',0200+'a', /* E-AN */ + 00 +}; + +static char sufo[] = { + 05,0200+'m','a','c',0200+'r', /* -MAC-RO */ + 00 +}; + +static char sufp[] = { + 05,0200+'g','r','o','u', /* -GROUP */ + 02,0200+'u', /* -UP */ + 04,0200+'s','h','i', /* -SHIP */ + 04,0200+'k','e','e', /* -KEEP */ + 00 +}; + +static char sufr[] = { + 04,0200+'z','a','r', /* -ZARR */ + 0300+02,'r', /* R/R */ + 03,0200+'t','o', /* -TOR */ + 040+03,0200+'s','o', /* -SOR */ + 040+04,0200+'r','i',0200+'o', /* -RI-OR */ + 04,'i','z',0200+'e', /* IZ-ER */ + 05,0200+'c','o','v',0200+'e', /* -COV-ER */ +/* 04,'o',0200+'v','e', /* O-VER */ + 04,0200+'o','v','e', /* -OVER */ + 04,0200+'e','v',0200+'e', /* -EV-ER */ + 8,0200+'c','o','m',0200+'p','u','t',0200+'e', /* -COM-PUT-ER */ + 040+05,'u','s',0200+'t','e', /* US-TER */ + 05,'o','s','t',0200+'e', /* OST-ER */ + 040+05,0200+'a','c',0200+'t','e', /* -AC-TER */ + 06,0200+'w','r','i','t',0200+'e', /* -WRIT-ER */ + 040+05,'i','s',0200+'t','e', /* IS-TER */ + 040+05,'e','s',0200+'t','e', /* ES-TER */ + 040+05,'a','s',0200+'t','e', /* AS-TER */ + 04,0200+'s','t','e', /* -STER */ + 05,'a','r',0200+'t','e', /* AR-TER */ + 04,'r','t',0200+'e', /* RT-ER */ + 040+05,'m',0200+'e',0200+'t','e', /* M-E-TER */ + 05,0200+'w','a',0200+'t','e', /* -WA-TER */ + 03,'r',0200+'e', /* R-ER */ + 04,'o','p',0200+'e', /* OP-ER */ + 05,0200+'p','a',0200+'p','e', /* -PA-PER */ + 04,'w','n',0200+'e', /* WN-ER */ + 040+04,'s',0200+'n','e', /* S-NER */ + 04,'o','n',0200+'e', /* ON-ER */ + 04,'r','m',0200+'e', /* RM-ER */ + 03,0200+'m','e', /* -MER */ + 04,'l','l',0200+'e', /* LL-ER */ + 05,'d',0200+'d','l','e', /* D-DLER */ + 04,0200+'b','l','e', /* -BLER */ + 03,'k',0200+'e', /* K-ER */ + 05,'n',0200+'t','h','e', /* N-THER */ + 06,0200+'f','a',0200+'t','h','e', /* -FA-THER */ + 06,'e','i',0200+'t','h','e', /* EI-THER */ + 04,'t','h',0200+'e', /* TH-ER */ + 04,'s','h',0200+'e', /* SH-ER */ + 04,0200+'p','h','e', /* -PHER */ + 04,'c','h',0200+'e', /* CH-ER */ + 04,'d','g',0200+'e', /* DG-ER */ + 04,'r','d',0200+'e', /* RD-ER */ + 06,'o','u','n','d',0200+'e', /* OUND-ER */ + 04,'l','d',0200+'e', /* LD-ER */ + 04,'i','d',0200+'e', /* ID-ER */ + 05,0200+'d','u','c',0200+'e', /* -DUC-ER */ + 04,'n','c',0200+'e', /* NC-ER */ + 0100+02, 0200+'e', /* /ER */ + 03,0200+'s','a', /* -SAR */ + 040+06,'a','c',0200+'u',0200+'l','a', /* AC-U-LAR */ + 040+06,'e','c',0200+'u',0200+'l','a', /* EC-U-LAR */ + 040+06,'i','c',0200+'u',0200+'l','a', /* IC-U-LAR */ + 040+06,'e','g',0200+'u',0200+'l','a', /* EG-U-LAR */ + 00 +}; + +static char sufs[] = { + 040+04,'u',0200+'o','u', /* U-OUS */ + 05,0200+'t','i','o','u', /* -TIOUS */ + 05,0200+'g','i','o','u', /* -GIOUS */ + 05,0200+'c','i','o','u', /* -CIOUS */ + 040+04,'i',0200+'o','u', /* I-OUS */ + 05,0200+'g','e','o','u', /* -GEOUS */ + 05,0200+'c','e','o','u', /* -CEOUS */ + 04,'e',0200+'o','u', /* E-OUS */ + 0140+02,0200+'u', /* /US */ + 04,0200+'n','e','s', /* -NESS */ + 04,0200+'l','e','s', /* -LESS */ + 0140+02,0200+'s', /* /SS */ + 040+05,'p',0200+'o',0200+'l','i', /* P-O-LIS */ + 0140+02,0200+'i', /* /IS */ + 0100+03,0200+'x','e', /* X/ES */ + 0100+03,0200+'s','e', /* S/ES */ + 0100+04,'s','h',0200+'e', /* SH/ES */ + 0100+04,'c','h',0200+'e', /* CH/ES */ + 0300+01, /* /S */ + 00 +}; + +static char suft[] = { + 06,'i','o','n',0200+'i','s', /* ION-IST */ + 05,'i','n',0200+'i','s', /* IN-IST */ + 05,'a','l',0200+'i','s', /* AL-IST */ + 06,'l',0200+'o',0200+'g','i','s', /* L-O-GIST */ + 05,'h','t',0200+'e','s', /* HT-EST */ + 04,'i',0200+'e','s', /* I-EST */ + 05,'g',0200+'g','e','s', /* G-GEST */ + 04,'g',0200+'e','s', /* G-EST */ + 05,'d',0200+'d','e','s', /* D-DEST */ + 04,'d',0200+'e','s', /* D-EST */ + 04,0200+'c','a','s', /* -CAST */ + 05,0200+'h','e','a','r', /* -HEART */ + 04,0200+'f','o','o', /* -FOOT */ + 03,'i',0200+'o', /* I-OT */ + 05,0200+'f','r','o','n', /* -FRONT */ + 05,0200+'p','r','i','n', /* -PRINT */ + 04,0200+'m','e','n', /* -MENT */ + 05,0200+'c','i','e','n', /* -CIENT */ + 04,'i',0200+'a','n', /* I-ANT */ + 06,0200+'w','r','i','g','h', /* -WRIGHT */ + 06,0200+'b','r','i','g','h', /* -BRIGHT */ + 06,0200+'f','l','i','g','h', /* -FLIGHT */ + 06,0200+'w','e','i','g','h', /* -WEIGHT */ + 05,0200+'s','h','i','f', /* -SHIFT */ + 05,0200+'c','r','a','f', /* -CRAFT */ + 040+04,'d','g',0200+'e', /* DG-ET */ + 04,0200+'g','o','a', /* -GOAT */ + 04,0200+'c','o','a', /* -COAT */ + 04,0200+'b','o','a', /* -BOAT */ + 04,0200+'w','h','a', /* -WHAT */ + 04,0200+'c','u','i', /* -CUIT */ + 00 +}; + +static char sufy[] = { + 040+04,'e','s',0200+'t', /* ES-TY */ + 040+05,'q','u','i',0200+'t', /* QUI-TY */ + 04,0200+'t','i',0200+'t', /* -TI-TY */ + 040+05,'o','s',0200+'i',0200+'t', /* OS-I-TY */ + 04,0200+'s','i',0200+'t', /* -SI-TY */ + 05,'i','n',0200+'i',0200+'t', /* IN-I-TY */ + 04,'n','i',0200+'t', /* NI-TY */ + 040+010,'f','a',0200+'b','i','l',0200+'i',0200+'t', /* FA-BIL-I-TY */ + 010,0200+'c','a',0200+'b','i','l',0200+'i',0200+'t', /* -CA-BIL-I-TY */ + 010,0200+'p','a',0200+'b','i','l',0200+'i',0200+'t', /* -PA-BIL-I-TY */ + 06,0200+'b','i','l',0200+'i',0200+'t', /* -BIL-I-TY */ + 03,'i',0200+'t', /* I-TY */ + 04,0200+'b','u','r', /* -BUR-Y */ + 04,0200+'t','o',0200+'r', /* -TO-RY */ + 05,0200+'q','u','a','r', /* -QUAR-Y */ + 040+04,'u',0200+'a','r', /* U-ARY */ + 07,0200+'m','e','n',0200+'t','a',0200+'r', /* -MEN-TA-RY */ + 06,'i','o','n',0200+'a','r', /* ION-ARY */ + 04,'i',0200+'a','r', /* I-ARY */ + 04,'n',0200+'o',0200+'m', /* N-O-MY */ + 03,0200+'p','l', /* -PLY */ + 04,'g',0200+'g','l', /* G-GLY */ + 05,0200+'p','a',0200+'b','l', /* -PA-BLY */ + 05,'f','a',0200+'b','l', /* FA-BLY */ + 05,0200+'c','a',0200+'b','l', /* -CA-BLY */ + 04,0200+'a','b','l', /* -ABLY */ + 03,0200+'b','l', /* -BLY */ + 02,0200+'l', /* -LY */ + 03,0200+'s','k', /* -SKY */ + 040+06,'g',0200+'r','a',0200+'p','h', /* G-RA-PHY */ + 04,'l',0200+'o',0200+'g', /* L-O-GY */ + 02,0200+'f', /* -FY */ + 03,0200+'n','e', /* -NEY */ + 03,0200+'l','e', /* -LEY */ + 04,'c','k',0200+'e', /* CK-EY */ + 03,0200+'k','e', /* -KEY */ + 04,0200+'b','o','d', /* -BODY */ + 05,0200+'s','t','u','d', /* -STUDY */ + 0340+04,'e','e','d', /* EEDY */ + 02,0200+'b', /* -BY */ + 03,0200+'w','a', /* -WAY */ + 03,0200+'d','a', /* -DAY */ + 00 +}; + +char *suftab[] = { + sufa, + 0, + sufc, + sufd, + sufe, + suff, + sufg, + sufh, + sufi, + 0, + sufk, + sufl, + sufm, + sufn, + sufo, + sufp, + 0, + sufr, + sufs, + suft, + 0, + 0, + 0, + 0, + sufy, + 0, +}; diff --git a/src/troff/t10.c b/src/troff/t10.c new file mode 100755 index 00000000..dbd45673 --- /dev/null +++ b/src/troff/t10.c @@ -0,0 +1,315 @@ +#include "tdef.h" +extern +#include "d.h" +extern +#include "v.h" +/* +troff10.c + +CAT interface +*/ + +extern int *olinep; +extern int oline[]; +extern int *pslp; +extern int back; +extern int xpts; +extern int mpts; +extern int po; +extern int xflg; +extern int line[]; +extern int lss; +extern int xbitf; +extern char obuf[]; +extern char *obufp; +extern int esct; +extern int trflg; +extern int cs; +extern int smnt; +extern int mfont; +extern int xfont; +extern int code; +extern int mcase; +extern int esc; +extern int lead; +extern int paper; +extern int cps; +extern int psflg; +extern int ptid; +extern int verm; +extern int escm; +extern char pstab[], psctab[]; +extern int dpn; +extern int ascii; +int mrail = 0; /*0=LR,1=UR*/ +int mmag = 1; /*0=UM,1=LM*/ +extern int nofeed; +extern int gflag; +extern int fontlab[]; +int papflg; +extern int pfont; +extern int ppts; +extern int oldbits; +extern int bd; +extern int vflag; +extern int stopmesg; +extern int xxx; + +ptinit(){ + + if(ascii || gflag)return; + oput(T_INIT); + esc = T_IESC; + ptesc(); + esct = 0; + esc = po; + oput(0140); /*some initial lead*/ +} +ptout(i) +int i; +{ + register *k, lw, *j; + int ds, de, inith, temp, *slp, dv; + int psl[16]; + + if((i & CMASK) != '\n'){ + *olinep++ = i; + return; + } + if(olinep == oline){ + lead += lss; + return; + } + pslp = psl; + *pslp = lw = inith = dv = 0; + for(k=oline; kblss + lss; + dip->blss = 0; + slp = k; +scan: + temp = esct - po; + if(mpts & DBL)temp -= 55; + ds = temp - inith; + de = lw - temp; + if(de >= ds){ + back = 0; + esc = -ds; + for(k=slp; k=slp; --k)ptout0(*k); + } + if(xflg && (--pslp >= psl))goto scan; + olinep = oline; + lead += dip->alss; + dip->alss = 0; +} +ptout0(i) +int i; +{ + register j, k, w; + int z; + + if(i & MOT){ + j = i & ~MOTV; + if(i & NMOT)j = -j; + if(back)j = -j; + if(i & VMOT)lead += j; + else esc += j; + return; + } + xbitf = 2; + if((i>>BYTE) == oldbits){ + xfont = pfont; + xpts = ppts; + xbitf = 0; + }else xbits(i); + if((k = (i & CMASK)) < 040){ + return; + } + w = getcw(k-32); + if(cs){ + if(bd)w += bd - 1; + j = (cs-w)/2; + w = cs - j; + if(bd)w -= bd - 1; + }else j = 0; + if(i & ZBIT){ + if(cs)w = -j; else w = 0; + z = 1; + }else z = 0; + if(back){ + k = j; + j = -w; + w = -k; + } + esc += j; + if((!xflg || (xpts == *pslp)) && (code & 077)){ + if(code & 0200){ + if(smnt)xfont = smnt -1; + else goto p1; + } + if((k=(code>>6)&01)^mcase)oput((mcase=k)+0105); + if(xfont != mfont){ + mfont = xfont; + if(mrail != (xfont&01)) + oput(0101 + (mrail=xfont&01)); + if(mmag != (xfont<2)) + oput(0103 + (mmag=(xfont<2))); + } + if(xpts != mpts)ptps(); + if(lead)ptlead(); + if(esc)ptesc(); +/* + oput(code & 077); +*/ + *obufp++ = code & 077; + if(obufp == (obuf + OBUFSZ + ascii - 1))flusho(); + if(bd){ + bd -= 1; + if(back && !z)bd = -bd; + if(esc += bd)ptesc(); + oput(code & 077); + if(z)esc -= bd; + } + }else if(bd && !z){ + bd -= 1; + if(back)bd = -bd; + esc += bd; + } +p1: + esc += w; + return; +} +ptps(){ + register i, j, k; + + if(psflg)return; + if(cps){ + psflg++; + i = findps(cps); + }else i = xpts; + for(j=0; (i&077) > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;} + j = psctab[j]; + oput((j & ~0200) | 0120); + if((!(mpts & DBL))^(!(j & 0200))){ + if(j & 0200)k = 55; + else k = -55; + esc += k; + } + mpts = i; +} +ptlead(){ + register i, k; + + if(k = lead < 0)lead = -lead; + if(k^verm)oput(0112 + ((verm=k)<<1)); + if(((k=lead)%3) == 2)k++; + k /= 3; + while(k > 0){ + if((i=31) > k)i = k; + if(verm)paper -= i; + else paper += i; + oput(((~i) & 037) | 0140); + if((paper > (11*144*15)) && !papflg && ptid != 1){ + prstr("Excessive paper use.\n"); + papflg++; + if(ptid != 1){ + lead = 0; + done2(0200); + } + } + k -= i; + } + lead = 0; +} +ptesc(){ + register i, j, k; + + if(k = esc < 0)esc = -esc; + if(k^escm)oput(0107 + (escm=k)); + k = esc; + while(k > 0){ + if((i=127) > k)i = k; + if(((j = (esct + i*(1-2*escm))) > (46*72+18-T_IESC)) || + (j < 0))break; +/* + oput(~i); +*/ + *obufp++ = ~i; + if(obufp == (obuf + OBUFSZ + ascii - 1))flusho(); + esct = j; + k -= i; + } + esc = 0; +} +dostop(){ + register i; + + if(ascii)return; + if(!nofeed && !gflag)lead += TRAILER; + ptlead(); + flusho(); + oput(T_INIT); + oput(T_STOP); + if(gflag){ + oput('f'); + for(i=0; i<4; i++){ + oput(fontlab[i] & BMASK); + oput((fontlab[i]>>BYTE) & BMASK); + } + }else for(i=8; i>0; i--)oput(T_PAD); + flusho(); + if(stopmesg)prstr("Pages finished.\n"); + mcase = mpts = mfont = mrail = verm = escm = 0; + mmag = 1; + report(); + paper = 0; + esc = T_IESC; + ptesc(); + esct = 0; + esc = po; +} diff --git a/src/troff/t6.c b/src/troff/t6.c new file mode 100755 index 00000000..cc581edb --- /dev/null +++ b/src/troff/t6.c @@ -0,0 +1,606 @@ +#ifdef VAX /* Nick */ +#include /* for open() and related definitions */ +#endif +#include "tdef.h" +extern +#include "d.h" +extern +#include "v.h" + +/* +troff6.c + +width functions, sizes and fonts +*/ + +extern int eschar; +extern int widthp; +extern int ohc; +extern int xpts; +extern int xfont; +extern int code; +extern int smnt; +extern int setwdf; +extern int cs; +extern int ccs; +extern int spacesz; +extern char trtab[]; +extern int xbitf; +extern int mfont; +extern int mpts; +extern int pfont; +extern int ppts; +extern int oldbits; +extern int chbits; +extern int spbits; +extern int nonumb; +extern int noscale; +extern int font; +extern int font1; +extern int pts; +extern int pts1; +extern int apts; +extern int apts1; +extern int sps; +extern int nlflg; +extern int nform; +extern int dfact; +extern int lss; +extern int lss1; +extern int vflag; +extern int ch0; +extern int lg; +char fontfile[] = "/usr/lib/font/ftXX"; +int ffi = 16; +extern int bd; +extern int level; +extern int ch; +extern int res; +extern int ptid; +extern char W1[],W2[],W3[],W4[]; +extern int xxx; +int trflg; +char *fontab[] = {W1,W2,W3,W4}; +int fontlab[] = {'R','I','B','S',0}; +char pstab[] = {6,7,8,9,10,11,12,14,16,18,20,22,24,28,36,0}; +char psctab[] = {010,000,001,007,002,003,004,005,0211,006, + 0212,0213,0214,0215,0216,0}; +int cstab[4], ccstab[4]; +int bdtab[4]; +int sbold = 0; +int spsz = 0; +struct fz { + char sign; + char size; + int inc; + } fz[4]; + +width(c) +int c; +{ + register i,j,k; + + j = c; + k = 0; + if(j & MOT){ + if(j & VMOT)goto rtn; + k = j & ~MOTV; + if(j & NMOT)k = -k; + goto rtn; + } + if((i = (j & CMASK)) == 010){ + k = -widthp; + goto rtn; + } + if(i == PRESC)i = eschar; + if((i == ohc) || + (i >= 0370))goto rtn; + if((j>>BYTE) == oldbits){ + xfont = pfont; + xpts = ppts; + }else xbits(j); + if(j & ZBIT)goto rtn; + if(!trflg)i = trtab[i] & BMASK; + if((i -= 32) < 0)goto rtn; + k = getcw(i); + if(bd)k += bd - 1; + if(cs)k = cs; + widthp = k; +rtn: + xbitf = trflg = 0; + return(k); +} +getcw(i) +int i; +{ + register j,k; + register char *p; + int x; + extern char codetab[]; + + bd = 0; + if((code = codetab[i]) & 0200){ + if(smnt){ + p = fontab[smnt-1]; + if(xfont == (sbold-1))bd = bdtab[smnt-1]; + goto g0; + } + code = 0; + k = 36; + goto g1; + } + p = fontab[xfont]; +g0: + if(!i)k = spacesz; + else k = *(p + i) & BMASK; + if(setwdf)v.ct |= ((k>>6) & 3); +g1: + k = (j = (k&077)*(xpts&077))/6; + if((j%6) >= 3)k++; + if(cs = cstab[xfont]){ + if(ccs = ccstab[xfont])x = ccs; else x = xpts; + cs = (j = (cs&077)*(x&077))/6; + if((j%6) >= 3)cs++; + } + if(!bd)bd = bdtab[xfont]; + return(k); +} +xbits(i) +int i; +{ + register j, k; + +/* + if((j = i >> BYTE) == oldbits){ + xfont = pfont; + xpts = ppts; + goto rtn; + } +*/ + j = i >> BYTE; + xfont = (j>>1) & 03; + if(k = (j>>3) & 017){ + xpts = pstab[--k]; + if(psctab[k] < 0)xpts |= DBL; + oldbits = j; + pfont = xfont; + ppts = xpts; + goto rtn; + } + switch(xbitf){ + case 0: + xfont = font; + xpts = pts; + break; + case 1: + xfont = pfont; + xpts = ppts; + break; + case 2: + xfont = mfont; + xpts = mpts; + } +rtn: + xbitf = 0; +} +setch(){ + register i,*j,k; + extern int chtab[]; + + if((i = getrq()) == 0)return(0); + for(j=chtab;*j != i;j++)if(*(j++) == 0)return(0); + k = *(++j) | chbits; +/* + if((i & CMASK) == '*'){ + if(((i = find('R',fontlab)) < 0) && + ((i = find('G',fontlab)) < 0)) + return(k); + else return((k & ~(03<<(BYTE+1))) | (i<<(BYTE+1))); + } +*/ + return(k); +} +find(i,j) +int i,j[]; +{ + register k; + + if(((k = i-'0') >= 1) && (k <= 4) && (k != smnt))return(--k); + for(k=0; j[k] != i; k++)if(j[k] == 0)return(-1); + return(k); +} +casefz(){ + register i, j, k; + int savinc; + + k = 0; +fz0: + if(skip() || !(i = getrq()) || + ((j = find(i,fontlab)) == -1)){ + if(k)goto fz1; + else return; + } + if(j == (smnt-1)){ + k = smnt; + goto fz0; + } + if(k){ + spsz = j + 1; + j = k -1; + } +fz1: + if((j==font) && fz[j].inc)savinc = fz[j].inc; + else savinc = 0; + fz[j].inc = fz[j].sign = fz[j].size = 0; + if(skip()){ + if(k)spsz = 0; + goto fz2; + } + if(((i=((k=getch()) & CMASK)) == '+') || (i == '-'))fz[j].sign = i; + else{ + fz[j].sign = 0; + ch = k; + } + noscale++; + fz[j].size = atoix(); /* Nick atoi */ + noscale = 0; +fz2: + if(j==font)casps1(apts + savinc); + else if(j == smnt-1)mchbits(); +} +caseps(){ + register i; + + if(skip())i = apts1; + else{ + noscale++; + i = inumb(&apts); + noscale = 0; + if(nonumb)return; + } + casps1(i); +} +casps1(i) +int i; +{ + if(i <= 0)return; + if(fz[font].size){ + i = getfz(font, i); + } + apts1 = apts; + apts = i; + pts1 = pts; + pts = findps(i & 077); + mchbits(); +} +findps(i) +int i; +{ + register j, k; + + for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;} + if(psctab[j] < 0)k |= DBL; + return(k); +} +mchbits(){ + register i, j, k; + + spbits = 0; + i = pts & 077; + for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;} + chbits = (((++j)<<2) | font) << (BYTE + 1); + sps = width(' ' | chbits); + if(font == (spsz-1)){ + i = findps(getfz(smnt-1, apts + fz[font].inc)); + for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;} + spbits = (((++j)<<2) | font) << (BYTE + 1); + } +} +getfz(x,y) +int x, y; +{ + register i, j, k; + + i = fz[x].size; + j = fz[x].sign; + if(i || j){ + if(j == '+')i += y; + else if(j == '-')i = y - i; + } + fz[x].inc = y - i; + return(i); +} +setps(){ + register i,j; + + if((((i=getch() & CMASK) == '+') || (i == '-')) && + (((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9))){ + if(i == '-')j = -j; + ch = 0; + casps1(apts+j); + return; + } + if((i -= '0') == 0){ + casps1(apts1); + return; + } + if((i > 0) && (i <= 9)){ + if((i <= 3) && + ((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9)){ + i = 10*i +j; + ch = 0; + } + casps1(i); + } +} +caseft(){ + skip(); + setfont(1); +} +setfont(a) +int a; +{ + register i,j; + + if(a)i = getrq(); + else i = getsn(); + if(!i || (i == 'P')){ + j = font1; + goto s0; + } + if(i == 'S')return; + if((j = find(i,fontlab)) == -1)return; +s0: + font1 = font; + font = j; + i = 0; + if(fz[font1].size){ + i++; + casps1(apts + fz[font1].inc); + }else if(fz[font].size){ + i++; + casps1(apts); + } + if(!i)mchbits(); +} +setwd(){ + register i, base, wid; + int delim, em, k; + int savlevel, savhp, savapts, savapts1, savfont, savfont1, + savpts, savpts1; + + base = v.st = v.sb = wid = v.ct = 0; + if((delim = getch() & CMASK) & MOT)return; + savhp = v.hp; + savlevel = level; + v.hp = level = 0; + savapts = apts; + savapts1 = apts1; + savfont = font; + savfont1 = font1; + savpts = pts; + savpts1 = pts1; + setwdf++; + while((((i = getch()) & CMASK) != delim) && !nlflg){ + wid += width(i); + if(!(i & MOT)){ + em = (xpts & 077)*6; + }else if(i & VMOT){ + k = i & ~MOTV; + if(i & NMOT)k = -k; + base -= k; + em = 0; + }else continue; + if(base < v.sb)v.sb = base; + if((k=base + em) > v.st)v.st = k; + } + nform = 0; + setn1(wid); + v.hp = savhp; + level = savlevel; + apts = savapts; + apts1 = savapts1; + font = savfont; + font1 = savfont1; + pts = savpts; + pts1 = savpts1; + mchbits(); + setwdf = 0; +} +vmot(){ + dfact = lss; + vflag++; + return(mot()); +} +hmot(){ + dfact = 6 * (pts & 077); + return(mot()); +} +mot(){ + register i, j; + + j = HOR; + getch(); /*eat delim*/ + if(i = atoix()){ /* Nick atoi */ + if(vflag)j = VERT; + i = makem(quant(i,j)); + } + getch(); + vflag = 0; + dfact = 1; + return(i); +} +sethl(k) +int k; +{ + register i; + + i = 3 * (pts & 077); + if(k == 'u')i = -i; + else if(k == 'r')i = -2*i; + vflag++; + i = makem(i); + vflag = 0; + return(i); +} +makem(i) +int i; +{ + register j; + + if((j = i) < 0)j = -j; + j = (j & ~MOTV) | MOT; + if(i < 0)j |= NMOT; + if(vflag)j |= VMOT; + return(j); +} +getlg(i) +int i; +{ + register j, k; + + switch((j = getch0()) & CMASK){ + case 'f': + if(lg!=2){switch((k =getch0()) & CMASK){ + case 'i': + j = 0214; + break; + case 'l': + j = 0215; + break; + default: + ch0 = k; + j = 0213; + } + }else j = 0213; + break; + case 'l': + j = 0212; + break; + case 'i': + j = 0211; + break; + default: + ch0 = j; + j = i; + } + return((i & ~CMASK) | j); +} +caselg(){ + + lg = 1; + if(skip())return; + lg = atoix(); /* Nick atoi */ +} +casefp(){ + register i, j, k; + int x; + + skip(); + if(((i = (getch() & CMASK) - '0' -1) < 0) || (i >3)){prstr("fp: bad font position\n"); return;} + if(skip() || !(j = getrq())){prstr("fp: no font name\n"); return;} + fontfile[ffi] = j & BMASK; + fontfile[ffi+1] = j>>BYTE; + if((k = open(fontfile, O_BINARY | O_RDONLY)) < 0){ + prstr("Cannot open "); + c0: + prstr(fontfile); + prstr("\n"); + done(-1); + } + if(lseek(k,8L * sizeof(int),0) < 0)goto c1; + if(read(k,fontab[i],256-32) != 256-32){ + c1: + prstr("Cannot read "); + goto c0; + } + close(k); + if(i == (smnt-1)){smnt = 0; sbold = 0; spsz = 0;} + if((fontlab[i] = j) == 'S')smnt = i + 1; + bdtab[i] = cstab[i] = ccstab[i] = 0; + fz[i].inc = fz[i].sign = fz[i].size = 0; + if(ptid != 1){ + prstr("Mount font "); + prstr(&fontfile[ffi]); + prstr(" on "); + x = PAIR((i + '1'),0); + prstr((char *)&x); + prstr("\n"); + } +} +casecs(){ + register i, j; + + noscale++; + skip(); + if(!(i=getrq()) || + ((i = find(i,fontlab)) < 0))goto rtn; + skip(); + cstab[i] = atoix(); /* Nick atoi */ + skip(); + j = atoix(); /* Nick atoi */ + if(!nonumb)ccstab[i] = findps(j); +rtn: + noscale = 0; +} +casebd(){ + register i, j, k; + + k = 0; +bd0: + if(skip() || !(i = getrq()) || + ((j = find(i,fontlab)) == -1)){ + if(k)goto bd1; + else return; + } + if(j == (smnt-1)){ + k = smnt; + goto bd0; + } + if(k){ + sbold = j + 1; + j = k -1; + } +bd1: + skip(); + noscale++; + bdtab[j] = atoix(); /* Nick atoi */ + noscale = 0; +} +casevs(){ + register i; + + skip(); + vflag++; + dfact = 6; /*default scaling is points!*/ + res = VERT; + i = inumb(&lss); + if(nonumb)i = lss1; + if(i < VERT)i = VERT; + lss1 = lss; + lss = i; +} +casess(){ + register i; + + noscale++; + skip(); + if(i = atoix()){ /* Nick atoi */ + spacesz = i& 0177; + sps = width(' ' | chbits); + } + noscale = 0; +} +xlss(){ + register i, j; + + getch(); + dfact = lss; + i = quant(atoix(),VERT); /* Nick atoi */ + dfact = 1; + getch(); + if((j = i) < 0)j = -j; + ch0 = ((j & 03700)<<3) | HX; + if(i < 0)ch0 |= 040000; + return(((j & 077)<<9) | LX); +} diff --git a/src/troff/tab3.c b/src/troff/tab3.c new file mode 100755 index 00000000..fea3cd06 --- /dev/null +++ b/src/troff/tab3.c @@ -0,0 +1,892 @@ +#define BYTE 8 +#define PAIR(A,B) (A|(B<','='), 0277, /*>=*/ +PAIR('<','='), 0300, /*<=*/ +PAIR('=','='), 0301, /*identically equal*/ +PAIR('~','='), 0303, /*approx =*/ +PAIR('a','p'), 0304, /*approximates*/ +PAIR('!','='), 0305, /*not equal*/ +PAIR('-','>'), 0306, /*right arrow*/ +PAIR('<','-'), 0307, /*left arrow*/ +PAIR('u','a'), 0310, /*up arrow*/ +PAIR('d','a'), 0311, /*down arrow*/ +PAIR('e','q'), 0312, /*equation equal*/ +PAIR('m','u'), 0313, /*multiply*/ +PAIR('d','i'), 0314, /*divide*/ +PAIR('+','-'), 0315, /*plus-minus*/ +PAIR('c','u'), 0316, /*cup (union)*/ +PAIR('c','a'), 0317, /*cap (intersection)*/ +PAIR('s','b'), 0320, /*subset of*/ +PAIR('s','p'), 0321, /*superset of*/ +PAIR('i','b'), 0322, /*improper subset*/ +PAIR('i','p'), 0323, /* " superset*/ +PAIR('i','f'), 0324, /*infinity*/ +PAIR('p','d'), 0325, /*partial derivative*/ +PAIR('g','r'), 0326, /*gradient*/ +PAIR('n','o'), 0327, /*not*/ +PAIR('i','s'), 0330, /*integral sign*/ +PAIR('p','t'), 0331, /*proportional to*/ +PAIR('e','s'), 0332, /*empty set*/ +PAIR('m','o'), 0333, /*member of*/ +PAIR('p','l'), 0334, /*equation plus*/ +PAIR('r','g'), 0335, /*registered*/ +PAIR('c','o'), 0336, /*copyright*/ +PAIR('b','r'), 0337, /*box vert rule*/ +PAIR('c','t'), 0340, /*cent sign*/ +PAIR('d','d'), 0341, /*dbl dagger*/ +PAIR('r','h'), 0342, /*right hand*/ +PAIR('l','h'), 0343, /*left hand*/ +PAIR('*','*'), 0344, /*math * */ +PAIR('b','s'), 0345, /*bell system sign*/ +PAIR('o','r'), 0346, /*or*/ +PAIR('c','i'), 0347, /*circle*/ +PAIR('l','t'), 0350, /*left top (of big curly)*/ +PAIR('l','b'), 0351, /*left bottom*/ +PAIR('r','t'), 0352, /*right top*/ +PAIR('r','b'), 0353, /*right bot*/ +PAIR('l','k'), 0354, /*left center of big curly bracket*/ +PAIR('r','k'), 0355, /*right center of big curly bracket*/ +PAIR('b','v'), 0356, /*bold vertical*/ +PAIR('l','f'), 0357, /*left floor (left bot of big sq bract)*/ +PAIR('r','f'), 0360, /*right floor (rb of ")*/ +PAIR('l','c'), 0361, /*left ceiling (lt of ")*/ +PAIR('r','c'), 0362, /*right ceiling (rt of ")*/ +0,0}; + +char codetab[256-32] = { /*cat codes*/ +00, /*space*/ +0145, /*!*/ +0230, /*"*/ +0337, /*#*/ +0155, /*$*/ +053, /*%*/ +050, /*&*/ +032, /*' close*/ +0132, /*(*/ +0133, /*)*/ +0122, /***/ +0143, /*+*/ +047, /*,*/ +040, /*- hyphen*/ +044, /*.*/ +043, /*/*/ +0110, /*0*/ +0111, /*1*/ +0112, /*2*/ +0113, /*3*/ +0114, /*4*/ +0115, /*5*/ +0116, /*6*/ +0117, /*7*/ +0120, /*8*/ +0121, /*9*/ +0142, /*:*/ +023, /*;*/ +0303, /*<*/ +0140, /*=*/ +0301, /*>*/ +0147, /*?*/ +0222, /*@*/ +0103, /*A*/ +075, /*B*/ +070, /*C*/ +074, /*D*/ +072, /*E*/ +0101, /*F*/ +065, /*G*/ +060, /*H*/ +066, /*I*/ +0105, /*J*/ +0107, /*K*/ +063, /*L*/ +062, /*M*/ +061, /*N*/ +057, /*O*/ +067, /*P*/ +055, /*Q*/ +064, /*R*/ +076, /*S*/ +056, /*T*/ +0106, /*U*/ +071, /*V*/ +0104, /*W*/ +0102, /*X*/ +077, /*Y*/ +073, /*Z*/ +0134, /*[*/ +0241, /*\*/ +0135, /*]*/ +0336, /*^*/ +0240, /*_*/ +030, /*` open*/ +025, /*a*/ +012, /*b*/ +027, /*c*/ +011, /*d*/ +031, /*e*/ +014, /*f*/ +045, /*g*/ +001, /*h*/ +006, /*i*/ +015, /*j*/ +017, /*k*/ +005, /*l*/ +004, /*m*/ +003, /*n*/ +033, /*o*/ +021, /*p*/ +042, /*q*/ +035, /*r*/ +010, /*s*/ +002, /*t*/ +016, /*u*/ +037, /*v*/ +041, /*w*/ +013, /*x*/ +051, /*y*/ +007, /*z*/ +0332, /*{*/ +0151, /*|*/ +0333, /*}*/ +0342, /*~*/ +00, /*narrow space*/ +040, /*hyphen*/ +0146, /*bullet*/ +0154, /*square*/ +022, /*3/4 em*/ +026, /*rule*/ +034, /*1/4*/ +036, /*1/2*/ +046, /*3/4*/ +0123, /*minus*/ +0124, /*fi*/ +0125, /*fl*/ +0126, /*ff*/ +0131, /*ffi*/ +0130, /*ffl*/ +0136, /*degree*/ +0137, /*dagger*/ +0355, /*section*/ +0150, /*foot mark*/ +0334, /*acute accent*/ +0335, /*grave accent*/ +0240, /*underrule*/ +0304, /*slash (longer)*/ +00, /*half nar sp*/ +00, /**/ +0225, /*alpha*/ +0212, /*beta*/ +0245, /*gamma*/ +0211, /*delta*/ +0231, /*epsilon*/ +0207, /*zeta*/ +0214, /*eta*/ +0202, /*theta*/ +0206, /*iota*/ +0217, /*kappa*/ +0205, /*lambda*/ +0204, /*mu*/ +0203, /*nu*/ +0213, /*xi*/ +0233, /*omicron*/ +0221, /*pi*/ +0235, /*rho*/ +0210, /*sigma*/ +0237, /*tau*/ +0216, /*upsilon*/ +0215, /*phi*/ +0227, /*chi*/ +0201, /*psi*/ +0251, /*omega*/ +0265, /*Gamma*/ +0274, /*Delta*/ +0256, /*Theta*/ +0263, /*Lambda*/ +0302, /*Xi*/ +0267, /*Pi*/ +0276, /*Sigma*/ +00, /**/ +0306, /*Upsilon*/ +0255, /*Phi*/ +0242, /*Psi*/ +0257, /*Omega*/ +0275, /*square root*/ +0262, /*terminal sigma (was root em)*/ +0261, /*root en*/ +0327, /*>=*/ +0326, /*<=*/ +0330, /*identically equal*/ +0264, /*equation minus*/ +0277, /*approx =*/ +0272, /*approximates*/ +0331, /*not equal*/ +0354, /*right arrow*/ +0234, /*left arrow*/ +0236, /*up arrow*/ +0223, /*down arrow*/ +0232, /*equation equal*/ +0323, /*multiply*/ +0324, /*divide*/ +0325, /*plus-minus*/ +0260, /*cup (union)*/ +0305, /*cap (intersection)*/ +0270, /*subset of*/ +0271, /*superset of*/ +0350, /*improper subset*/ +0246, /* improper superset*/ +0244, /*infinity*/ +0273, /*partial derivative*/ +0253, /*gradient*/ +0307, /*not*/ +0266, /*integral sign*/ +0247, /*proportional to*/ +0343, /*empty set*/ +0341, /*member of*/ +0353, /*equation plus*/ +0141, /*registered*/ +0153, /*copyright*/ +0346, /*box rule (was parallel sign)*/ +0127, /*cent sign*/ +0345, /*dbl dagger*/ +0250, /*right hand*/ +0340, /*left hand*/ +0347, /*math * */ +0243, /*bell system sign*/ +0226, /*or (was star)*/ +0351, /*circle*/ +0311, /*left top (of big curly)*/ +0314, /*left bottom*/ +0315, /*right top*/ +0317, /*right bot*/ +0313, /*left center of big curly bracket*/ +0316, /*right center of big curly bracket*/ +0312, /*bold vertical*/ +0321, /*left floor (left bot of big sq bract)*/ +0320, /*right floor (rb of ")*/ +0322, /*left ceiling (lt of ")*/ +0310}; /*right ceiling (rt of ")*/ + +/*modified for Commercial II*/ +char W1[256-32] = { /*Times Roman widths*/ +12, /*space*/ +12, /*!*/ +0, /*"*/ +0, /*#*/ +19, /*$*/ +29, /*%*/ +28, /*&*/ +12, /*' close*/ +16, /*(*/ +16, /*)*/ +16, /***/ +36, /*+*/ +12, /*,*/ +13, /*- hyphen*/ +10, /*.*/ +17, /*/*/ +19+0200, /*0*/ +19+0200, /*1*/ +19+0200, /*2*/ +19+0200, /*3*/ +19+0200, /*4*/ +19+0200, /*5*/ +19+0200, /*6*/ +19+0200, /*7*/ +19+0200, /*8*/ +19+0200, /*9*/ +10, /*:*/ +12, /*;*/ +0, /*<*/ +36, /*=*/ +0, /*>*/ +20, /*?*/ +0, /*@*/ +29+0200, /*A*/ +23+0200, /*B*/ +26+0200, /*C*/ +30+0200, /*D*/ +24+0200, /*E*/ +23+0200, /*F*/ +30+0200, /*G*/ +29+0200, /*H*/ +13+0200, /*I*/ +16+0200, /*J*/ +28+0200, /*K*/ +24+0200, /*L*/ +35+0200, /*M*/ +29+0200, /*N*/ +27+0200, /*O*/ +22+0200, /*P*/ +27+0300, /*Q*/ +27+0200, /*R*/ +20+0200, /*S*/ +24+0200, /*T*/ +29+0200, /*U*/ +27+0200, /*V*/ +36+0200, /*W*/ +28+0200, /*X*/ +27+0200, /*Y*/ +23+0200, /*Z*/ +14, /*[*/ +0, /*\*/ +14, /*]*/ +0, /*^*/ +0, /*_*/ +12, /*` open*/ +17, /*a*/ +20+0200, /*b*/ +16, /*c*/ +20+0200, /*d*/ +18, /*e*/ +13+0200, /*f*/ +18+0100, /*g*/ +21+0200, /*h*/ +10+0200, /*i*/ +9+0300, /*j*/ +20+0200, /*k*/ +10+0200, /*l*/ +32, /*m*/ +21, /*n*/ +20, /*o*/ +19+0100, /*p*/ +19+0100, /*q*/ +14, /*r*/ +15, /*s*/ +12+0200, /*t*/ +21, /*u*/ +20, /*v*/ +26, /*w*/ +20, /*x*/ +18+0100, /*y*/ +17, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +13, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +29, /*1/4*/ +29, /*1/2*/ +29, /*3/4*/ +36, /*minus*/ +21, /*fi*/ +21, /*fl*/ +24, /*ff*/ +32, /*ffi*/ +32, /*ffl*/ +15, /*degree*/ +20, /*dagger*/ +0, /*section*/ +8, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copyright*/ +0, +19, /*cent*/ +}; + +char W2[256-32] = { /*Times Italic widths*/ +12, /*space*/ +13, /*!*/ +0, /*"*/ +0, /*#*/ +19, /*$*/ +27, /*%*/ +26, /*&*/ +11, /*' close*/ +15, /*(*/ +15, /*)*/ +16, /***/ +36, /*+*/ +11, /*,*/ +13, /*- hyphen*/ +11, /*.*/ +9, /*/*/ +19+0200, /*0*/ +19+0200, /*1*/ +19+0200, /*2*/ +19+0200, /*3*/ +19+0200, /*4*/ +19+0200, /*5*/ +19+0200, /*6*/ +19+0200, /*7*/ +19+0200, /*8*/ +19+0200, /*9*/ +11, /*:*/ +11, /*;*/ +0, /*<*/ +36, /*=*/ +0, /*>*/ +20, /*?*/ +0, /*@*/ +25+0200, /*A*/ +24+0200, /*B*/ +26+0200, /*C*/ +27+0200, /*D*/ +23+0200, /*E*/ +21+0200, /*F*/ +27+0200, /*G*/ +29+0200, /*H*/ +14+0200, /*I*/ +16+0200, /*J*/ +28+0200, /*K*/ +24+0200, /*L*/ +34+0200, /*M*/ +27+0200, /*N*/ +27+0200, /*O*/ +22+0200, /*P*/ +27+0300, /*Q*/ +27+0200, /*R*/ +20+0200, /*S*/ +23+0200, /*T*/ +28+0200, /*U*/ +25+0200, /*V*/ +36+0200, /*W*/ +24+0200, /*X*/ +24+0200, /*Y*/ +25+0200, /*Z*/ +13, /*[*/ +0, /*\*/ +13, /*]*/ +0, /*^*/ +0, /*_*/ +11, /*` open*/ +19, /*a*/ +18+0200, /*b*/ +15, /*c*/ +18+0200, /*d*/ +16, /*e*/ +11+0200, /*f*/ +17+0100, /*g*/ +19+0200, /*h*/ +9+0200, /*i*/ +9+0300, /*j*/ +19+0200, /*k*/ +9+0200, /*l*/ +28, /*m*/ +19, /*n*/ +18, /*o*/ +17+0100, /*p*/ +18+0100, /*q*/ +13, /*r*/ +14, /*s*/ +10+0200, /*t*/ +19, /*u*/ +16, /*v*/ +24, /*w*/ +18, /*x*/ +16+0100, /*y*/ +14, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +13, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +27, /*1/4*/ +27, /*1/2*/ +27, /*3/4*/ +36, /*minus*/ +21, /*fi*/ +21, /*fl*/ +21, /*ff*/ +31, /*ffi*/ +31, /*ffl*/ +15, /*degree*/ +19, /*dagger*/ +16, /*section*/ +7, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copyright*/ +0, +19, /*cent*/ +}; +char W3[256-32] = { /*Times Bold widths*/ +12, /*space*/ +13, /*!*/ +0, /*"*/ +0, /*#*/ +18, /*$*/ +28, /*%*/ +27, /*&*/ +12, /*' close*/ +16, /*(*/ +16, /*)*/ +18, /***/ +36, /*+*/ +12, /*,*/ +14, /*- hyphen*/ +12, /*.*/ +18, /*/*/ +19+0200, /*0*/ +19+0200, /*1*/ +19+0200, /*2*/ +19+0200, /*3*/ +19+0200, /*4*/ +19+0200, /*5*/ +19+0200, /*6*/ +19+0200, /*7*/ +19+0200, /*8*/ +19+0200, /*9*/ +13, /*:*/ +13, /*;*/ +0, /*<*/ +36, /*=*/ +0, /*>*/ +22, /*?*/ +0, /*@*/ +28+0200, /*A*/ +26+0200, /*B*/ +26+0200, /*C*/ +29+0200, /*D*/ +25+0200, /*E*/ +23+0200, /*F*/ +28+0200, /*G*/ +32+0200, /*H*/ +16+0200, /*I*/ +21+0200, /*J*/ +28+0200, /*K*/ +25+0200, /*L*/ +36+0200, /*M*/ +30+0200, /*N*/ +29+0200, /*O*/ +25+0200, /*P*/ +29+0300, /*Q*/ +28+0200, /*R*/ +23+0200, /*S*/ +25+0200, /*T*/ +29+0200, /*U*/ +27+0200, /*V*/ +36+0200, /*W*/ +27+0200, /*X*/ +28+0200, /*Y*/ +27+0200, /*Z*/ +12, /*[*/ +0, /*\*/ +12, /*]*/ +0, /*^*/ +0, /*_*/ +12, /*` open*/ +19, /*a*/ +19+0200, /*b*/ +16, /*c*/ +19+0200, /*d*/ +17, /*e*/ +13+0200, /*f*/ +18+0100, /*g*/ +22+0200, /*h*/ +12+0200, /*i*/ +12+0300, /*j*/ +23+0200, /*k*/ +12+0200, /*l*/ +32, /*m*/ +22, /*n*/ +18, /*o*/ +20+0100, /*p*/ +19+0100, /*q*/ +15, /*r*/ +17, /*s*/ +13+0200, /*t*/ +21, /*u*/ +19, /*v*/ +27, /*w*/ +21, /*x*/ +19+0100, /*y*/ +17, /*z*/ +0, /*{*/ +2, /*|*/ +0, /*}*/ +0, /*~*/ +6, /*narrow space*/ +14, /*hyphen*/ +27, /*bullet*/ +27, /*square*/ +36, /*3/4 em*/ +18, /*rule*/ +28, /*1/4*/ +28, /*1/2*/ +28, /*3/4*/ +36, /*minus*/ +22, /*fi*/ +22, /*fl*/ +23, /*ff*/ +33, /*ffi*/ +33, /*ffl*/ +15, /*degree*/ +20, /*dagger*/ +0, /*section*/ +9, /*foot mark*/ +0, /*'*/ +0, /*`*/ +0, /*_*/ +0, +3, /*half nar sp*/ +0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0, +20, /*registered*/ +20, /*copyright*/ +0, +19, /*cent*/ +}; + +/* +Modified for Commercial II +and with +, -, and = for equations +*/ +char W4[256-32] = { /*Special font widths*/ +0,0, /*.=Sw+042-40*/ +13, /*"*/ +29, /*#*/ +0,0,0,0, /*.=Sw+074-40*/ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0, +36, /*<*/ +0, /*.=Sw+076-40*/ +36, /*>*/ +0, /*.=Sw+100-40*/ +36, /*@*/ +0,0,0,0,0,0,0, /*.=Sw+134-40*/ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0, +15, /*\\*/ +0, /*.=Sw+136-40*/ +15, /*^*/ +18, /*_ underrule*/ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +0,0,0, +14, /*{*/ +0, /*.=Sw+175-40*/ +14, /*}*/ +15, /*~*/ +0, /*.=Sw+220-40*/ +0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0, +17, /*section*/ +0, /*.=Sw+222-40*/ +10, /*acute accent*/ +10, /*grave accent*/ +18, /*underrule*/ +15, /*slash (longer)*/ +0, /**/ +0, /**/ +24, /*alpha*/ +23+0300, /*beta*/ +23+0100, /*gamma*/ +19+0200, /*delta*/ +18, /*epsilon*/ +18+0300, /*zeta*/ +23+0100, /*eta*/ +19+0200, /*theta*/ +13, /*iota*/ +21, /*kappa*/ +22+0200, /*lambda*/ +25+0100, /*mu*/ +20, /*nu*/ +20+0300, /*xi*/ +20, /*omicron*/ +27, /*pi*/ +21+0100, /*rho*/ +27, /*sigma*/ +20, /*tau*/ +21, /*upsilon*/ +25+0300, /*phi*/ +22+0100, /*chi*/ +24+0300, /*psi*/ +25, /*omega*/ +24+0200, /*Gamma*/ +26+0200, /*Delta*/ +28+0200, /*Theta*/ +28+0200, /*Lambda*/ +27+0200, /*Xi*/ +29+0200, /*Pi*/ +25+0200, /*Sigma*/ +0, /**/ +28+0200, /*Upsilon*/ +29+0200, /*Phi*/ +32+0200, /*Psi*/ +36+0200, /*Omega*/ +30, /*square root*/ +18+0100, /*terminal sigma*/ +18, /*root en*/ +36, /*>=*/ +36, /*<=*/ +36, /*identically equal*/ +27, /*minus*/ +36, /*approx =*/ +36, /*approximates*/ +36, /*not equal*/ +36, /*right arrow*/ +36, /*left arrow*/ +18, /*up arrow*/ +18, /*down arrow*/ +27, /*equal*/ +27, /*multiply*/ +27, /*divide*/ +36, /*plus-minus*/ +36, /*cup (union)*/ +36, /*cap (intersection)*/ +36, /*subset of*/ +36, /*superset of*/ +36, /*improper subset*/ +36, /*improper superset*/ +34, /*infinity*/ +21, /*partial derivative*/ +36+0200, /*gradient*/ +22, /*not*/ +24, /*integral sign*/ +27, /*proportional to*/ +28, /*empty set*/ +27, /*member of*/ +27, /*plus*/ +0, +0, +0, /*box vert rule (was 2.)*/ +0, +17, /*dbl dagger*/ +42, /*right hand*/ +42, /*left hand*/ +16, /*math * */ +41, /*bell system sign*/ +9, /*or*/ +27, /*circle*/ +9, /*left top (of big curly)*/ +9, /*left bottom*/ +9, /*right top*/ +9, /*right bot*/ +9, /*left center of big curly bracket*/ +9, /*right center of big curly bracket*/ +9, /*bold vertical*/ +9, /*left floor (left bot of big sq bract)*/ +9, /*right floor (rb of ")*/ +9, /*left ceiling (lt of ")*/ +9 }; /*right ceiling (rt of ")*/ diff --git a/src/troff/tdef.h b/src/troff/tdef.h new file mode 100755 index 00000000..449d6d98 --- /dev/null +++ b/src/troff/tdef.h @@ -0,0 +1,130 @@ +#ifndef VAX /* Nick */ +#define read _read /* Nick, very temporary */ +#define write _write /* Nick, very temporary */ +int ioctl(int fd, int request, ...); /* IAR don't use regparams! */ +int open(char *name, unsigned int flag, ...); /* IAR don't use regparams! */ +#endif + +#define MAXPTR (char *)-1 /* max value of any pointer variable */ +#ifdef NROFF /*NROFF*/ +#define EM t.Em +#define HOR t.Hor +#define VERT t.Vert +#define INCH 240 /*increments per inch*/ +#define SPS INCH/10 /*space size*/ +#define SS INCH/10 /* " */ +#define TRAILER 0 +#define UNPAD 0227 +#define PO 0 /*page offset*/ +#define ASCII 1 +#define PTID 1 +#define LG 0 +#define DTAB 0 /*set at 8 Ems at init time*/ +#define ICS 2*SPS +#define TEMP 256 /*65K*/ +#endif +#ifndef NROFF /*TROFF*/ +#define INCH 432 /*troff resolution*/ +#define SPS 20 /*space size at 10pt; 1/3 Em*/ +#define SS 12 /*space size in 36ths of an em*/ +#define TRAILER 6048 /*144*14*3 = 14 inches*/ +#define UNPAD 027 +#define PO 416 /*page offset 26/27ths inch*/ +#define HOR 1 +#define VERT 3 +#define EM (6*(pts&077)) +#define ASCII 0 +#define PTID 0 +#define LG 1 +#define DTAB (INCH/2) +#define ICS 3*SPS +#define TEMP 512 /*128K*/ +#endif + +#include +#define NARSP 0177 /*narrow space*/ +#define HNSP 0226 /*half narrow space*/ +#define PS 10 /*default point size*/ +#define FT 0 /*default font position*/ +#define LL 65*INCH/10 /*line length; 39picas=6.5in*/ +#define VS INCH/6 /*vert space; 12points*/ +#define NN 200 /*number registers*/ +/* NN changed Jan 31 from 132 */ +#define NNAMES 14 /*predefined reg names*/ +#define NIF 15 /*if-else nesting*/ +#define NS 64 /*name buffer*/ +#define NTM 256 /*tm buffer*/ +#define NEV 3 /*environments*/ +#define EVLSZ 10 /*size of ev stack*/ +#define EVS 4*256 /*environment size in words*/ +/* BWK - trying 4*256 instead of 3*256 */ +#define NM 300 /*requests + macros*/ +#define DELTA 512 /*delta core bytes*/ +#define NHYP 10 /*max hyphens per word*/ +#define NHEX 128 /*byte size of exception word list*/ +#define NTAB 35 /*tab stops*/ +#define NSO 5 /*"so" depth*/ +#define WDSIZE 170 /*word buffer size*/ +#define LNSIZE 680 /*line buffer size*/ +/* BWK - changed from 480 after EVS changed */ +#define NDI 5 /*number of diversions*/ +#define DBL 0100000 /*double size indicator*/ +#define MOT 0100000 /*motion character indicator*/ +#define MOTV 0160000 /*clear for motion part*/ +#define VMOT 0040000 /*vert motion bit*/ +#define NMOT 0020000 /* negative motion indicator*/ +#define MMASK 0100000 /*macro mask indicator*/ +#define CMASK 0100377 +#define ZBIT 0400 /*zero width char*/ +#define BMASK 0377 +#define BYTE 8 +#define IMP 004 /*impossible char*/ +#define FILLER 037 +#define PRESC 026 +#define HX 0376 /*High-order part of xlss*/ +#define LX 0375 /*low-order part of xlss*/ +#define CONT 025 +#define COLON 013 +#define XPAR 030 +#define ESC 033 +#define FLSS 031 +#define RPT 014 +#define JREG 0374 +#define NTRAP 20 /*number of traps*/ +#define NPN 20 /*numbers in "-o"*/ +#define T_PAD 0101 /*cat padding*/ +#define T_INIT 0100 +#define T_IESC 16 /*initial offset*/ +#define T_STOP 0111 +#define NPP 10 /*pads per field*/ +#define FBUFSZ 256 /*field buf size words*/ +#define OBUFSZ 512 /*bytes*/ +#define IBUFSZ 512 /*bytes*/ +#define NC 256 /*cbuf size words*/ +#define NOV 10 /*number of overstrike chars*/ +#define ZONE 5 /*5hrs for EST*/ +#define TDELIM 032 +#define LEFT 035 +#define RIGHT 036 +#define LEADER 001 +#define TAB 011 +#define TMASK 037777 +#define RTAB 0100000 +#define CTAB 0040000 +#define OHC 024 + +#define PAIR(A,B) (A|(B<", /*>*/ +"\001?", /*?*/ +"\001@", /*@*/ +"\201A", /*A*/ +"\201B", /*B*/ +"\201C", /*C*/ +"\201D", /*D*/ +"\201E", /*E*/ +"\201F", /*F*/ +"\201G", /*G*/ +"\201H", /*H*/ +"\201I", /*I*/ +"\201J", /*J*/ +"\201K", /*K*/ +"\201L", /*L*/ +"\201M", /*M*/ +"\201N", /*N*/ +"\201O", /*O*/ +"\201P", /*P*/ +"\201Q", /*Q*/ +"\201R", /*R*/ +"\201S", /*S*/ +"\201T", /*T*/ +"\201U", /*U*/ +"\201V", /*V*/ +"\201W", /*W*/ +"\201X", /*X*/ +"\201Y", /*Y*/ +"\201Z", /*Z*/ +"\001[", /*[*/ +"\001\\", /*\*/ +"\001]", /*]*/ +"\001^", /*^*/ +"\001_", /*_ dash*/ +"\001`", /*` open*/ +"\201a", /*a*/ +"\201b", /*b*/ +"\201c", /*c*/ +"\201d", /*d*/ +"\201e", /*e*/ +"\201f", /*f*/ +"\201g", /*g*/ +"\201h", /*h*/ +"\201i", /*i*/ +"\201j", /*j*/ +"\201k", /*k*/ +"\201l", /*l*/ +"\201m", /*m*/ +"\201n", /*n*/ +"\201o", /*o*/ +"\201p", /*p*/ +"\201q", /*q*/ +"\201r", /*r*/ +"\201s", /*s*/ +"\201t", /*t*/ +"\201u", /*u*/ +"\201v", /*v*/ +"\201w", /*w*/ +"\201x", /*x*/ +"\201y", /*y*/ +"\201z", /*z*/ +"\001{", /*{*/ +"\001|", /*|*/ +"\001}", /*}*/ +"\001~", /*~*/ +"\000\0", /*narrow sp*/ +"\001-", /*hyphen*/ +"\001o\b+", /*bullet*/ +"\002\[]", /*square*/ +"\001-", /*3/4 em*/ +"\001_", /*rule*/ +"\0031/4", /*1/4*/ +"\0031/2", /*1/2*/ +"\0033/4", /*3/4*/ +"\001-", /*minus*/ +"\202fi", /*fi*/ +"\202fl", /*fl*/ +"\202ff", /*ff*/ +"\203ffi", /*ffi*/ +"\203ffl", /*ffl*/ +"\001\344o\304", /*degree*/ +"\001|\b-", /*dagger*/ +"\001l\bo", /* section*/ +"\001'", /*foot mark*/ +"\001'", /*acute accent*/ +"\001`", /*grave accent*/ +"\001_", /*underrule*/ +"\001/", /*slash (longer)*/ +"\000\0", /*half narrow space*/ +"\001 ", /*unpaddable space*/ +"\001\241c\202(\241", /*alpha*/ +"\001\200B\242\302\|\202\342", /*beta*/ +"\001\200)\201/\241", /*gamma*/ +"\001\200o\342<\302", /*delta*/ +"\001<\b-", /*epsilon*/ +"\001\200c\201\301,\241\343<\302", /*zeta*/ +"\001\200n\202\302|\242\342", /*eta*/ +"\001O\b-", /*theta*/ +"\001i", /*iota*/ +"\001k", /*kappa*/ +"\001\200\\\304\241'\301\241'\345\202", /*lambda*/ +"\001\200u\242,\202", /*mu*/ +"\001\241(\203/\242", /*nu*/ +"\001\200c\201\301,\241\343c\241\301`\201\301", /*xi*/ +"\001o", /*omicron*/ +"\001\341-\303\"\301\"\343", /*pi*/ +"\001\200o\242\302|\342\202", /*rho*/ +"\001\200o\301\202~\341\242", /*sigma*/ +"\001\200t\301\202~\243~\201\341", /*tau*/ +"\001v", /*upsilon*/ +"\001o\b/", /*phi*/ +"\001x", /*chi*/ +"\001\200/-\302\202'\244'\202\342", /*psi*/ +"\001\241u\203u\242", /*omega*/ +"\001\242|\202\343-\303\202`\242", /*Gamma*/ +"\001\242/\303-\204-\343\\\242", /*Delta*/ +"\001O\b=", /*Theta*/ +"\001\242/\204\\\242", /*Lambda*/ +"\001\\b/", /*Xi*/ +"\001\242[]\204[]\242\343-\303", /*Pi*/ +"\001\200>\302-\345-\303", /*Sigma*/ +"\000\0", /**/ +"\001Y", /*Upsilon*/ +"\001o\b[\b]", /*Phi*/ +"\001\200[]-\302\202'\244`\202\342", /*Psi*/ +"\001\200O\302\241-\202-\241\342", /*Omega*/ +"\000\0", /*square root*/ +"\000\0", /*terminal sigma*/ +"\000\0", /*root en*/ +"\001>\b_", /*>=*/ +"\001<\b_", /*<=*/ +"\001=\b_", /*identically equal*/ +"\001-", /*equation minus*/ +"\001=\b~", /*approx =*/ +"\000\0", /*approximates*/ +"\001=\b/", /*not equal*/ +"\002->", /*right arrow*/ +"\002<-", /*left arrow*/ +"\001|\b^", /*up arrow*/ +"\000\0", /*down arrow*/ +"\001=", /*equation equal*/ +"\001x", /*multiply*/ +"\001/", /*divide*/ +"\001+\b_", /*plus-minus*/ +"\001U", /*cup (union)*/ +"\000\0", /*cap (intersection)*/ +"\000\0", /*subset of*/ +"\000\0", /*superset of*/ +"\000\0", /*improper subset*/ +"\000\0", /* improper superset*/ +"\002oo", /*infinity*/ +"\001\200o\201\301`\241\341`\241\341`\201\301", /*partial derivative*/ +"\001\242\\\343-\204-\303/\242", /*gradient*/ +"\001\200-\202\341,\301\242", /*not*/ +"\001\200|'\202`\243\306'\241`\202\346", /*integral sign*/ +"\000\0", /*proportional to*/ +"\000\0", /*empty set*/ +"\000\0", /*member of*/ +"\001+", /*equation plus*/ +"\001r\bO", /*registered*/ +"\001c\bO", /*copyright*/ +"\001|", /*box rule */ +"\001c\b/", /*cent sign*/ +"\001|\b=", /*dbl dagger*/ +"\002=>", /*right hand*/ +"\002<=", /*left hand*/ +"\001*", /*math * */ +"\000\0", /*bell system sign*/ +"\001|", /*or (was star)*/ +"\001O", /*circle*/ +"\001|", /*left top (of big curly)*/ +"\001|", /*left bottom*/ +"\001|", /*right top*/ +"\001|", /*right bot*/ +"\001|", /*left center of big curly bracket*/ +"\001|", /*right center of big curly bracket*/ +"\001|", /*bold vertical*/ +"\001|", /*left floor (left bot of big sq bract)*/ +"\001|", /*right floor (rb of ")*/ +"\001|", /*left ceiling (lt of ")*/ +"\001|"}; /*right ceiling (rt of ")*/ diff --git a/src/troff/term/makefile b/src/troff/term/makefile new file mode 100755 index 00000000..0f3cda73 --- /dev/null +++ b/src/troff/term/makefile @@ -0,0 +1,14 @@ +cp: all + for i in *.o; do cp $$i /usr/lib/term/`basename $$i .o`; done + rm *.o + +cmp: all + for i in *.o; do cmp $$i /usr/lib/term/`basename $$i .o`; done + rm *.o + +all: tab300-12.o tab300.o tab300s-12.o tab300s.o +all: tab37.o tab450-12-8.o tab450-12.o tab450.o tab832.o taba1.o tablp.o tabtn300.o + : + +.c.o: + cc -c $<; strip $@ diff --git a/src/troff/term/n.bat b/src/troff/term/n.bat new file mode 100755 index 00000000..42c18bb9 --- /dev/null +++ b/src/troff/term/n.bat @@ -0,0 +1,20 @@ +rem iccz80 -S -w -ml -v1 -z -A -I..\..\include\ tab37 +rem @if errorlevel 1 goto failure +rem del tab37.r01 +rem as-z80 -l -o tab37.s01 +rem @if errorlevel 1 goto failure + +as-z80 -l -o tab37.asm +@if errorlevel 1 goto failure + +link-z80 -f tab37 +@if errorlevel 1 goto failure +ihex2bin tab37.i86 tab37 +@if errorlevel 1 goto failure + +@echo SUCCESS +@goto done +:failure +@echo FAILURE +:done + diff --git a/src/troff/term/tab300-12.c b/src/troff/term/tab300-12.c new file mode 100755 index 00000000..44af5845 --- /dev/null +++ b/src/troff/term/tab300-12.c @@ -0,0 +1,59 @@ +#define INCH 240 +/* +DASI300 +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0177420, +/*Hor*/ INCH/60, +/*Vert*/ INCH/48, +/*Newline*/ INCH/8, +/*Char*/ INCH/12, +/*Em*/ INCH/12, +/*Halfline*/ INCH/16, +/*Adj*/ INCH/12, +/*twinit*/ "\007", +/*twrest*/ "\007", +/*twnl*/ "\015\n", +/*hlr*/ "\006\013\013\013\006", +/*hlf*/ "\006\012\012\012\006", +/*flr*/ "\013", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "\006", +/*plotoff*/ "\033\006", +/*up*/ "\013", +/*down*/ "\n", +/*right*/ " ", +/*left*/ "\b", +/*codetab*/ +#include "code.300" diff --git a/src/troff/term/tab300.c b/src/troff/term/tab300.c new file mode 100755 index 00000000..2c154887 --- /dev/null +++ b/src/troff/term/tab300.c @@ -0,0 +1,59 @@ +#define INCH 240 +/* +DASI300 +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0177420, +/*Hor*/ INCH/60, +/*Vert*/ INCH/48, +/*Newline*/ INCH/6, +/*Char*/ INCH/10, +/*Em*/ INCH/10, +/*Halfline*/ INCH/12, +/*Adj*/ INCH/10, +/*twinit*/ "\007", +/*twrest*/ "\007", +/*twnl*/ "\015\n", +/*hlr*/ "\006\013\013\013\013\006", +/*hlf*/ "\006\012\012\012\012\006", +/*flr*/ "\013", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "\006", +/*plotoff*/ "\033\006", +/*up*/ "\013", +/*down*/ "\n", +/*right*/ " ", +/*left*/ "\b", +/*codetab*/ +#include "code.300" diff --git a/src/troff/term/tab300s-12.c b/src/troff/term/tab300s-12.c new file mode 100755 index 00000000..f480565d --- /dev/null +++ b/src/troff/term/tab300s-12.c @@ -0,0 +1,59 @@ +#define INCH 240 +/* +DASI300S +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0177420, +/*Hor*/ INCH/60, +/*Vert*/ INCH/48, +/*Newline*/ INCH/8, +/*Char*/ INCH/12, +/*Em*/ INCH/12, +/*Halfline*/ INCH/16, +/*Adj*/ INCH/12, +/*twinit*/ "\033\006", +/*twrest*/ "\033\006", +/*twnl*/ "\015\n", +/*hlr*/ "", +/*hlf*/ "", +/*flr*/ "\032", +/*bdon*/ "\033E", +/*bdoff*/ "\033E", +/*ploton*/ "\006", +/*plotoff*/ "\033\006", +/*up*/ "\032", +/*down*/ "\n", +/*right*/ " ", +/*left*/ "\b", +/*codetab*/ +#include "code.300" diff --git a/src/troff/term/tab300s.c b/src/troff/term/tab300s.c new file mode 100755 index 00000000..7f47ba86 --- /dev/null +++ b/src/troff/term/tab300s.c @@ -0,0 +1,59 @@ +#define INCH 240 +/* +DASI300S +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0177420, +/*Hor*/ INCH/60, +/*Vert*/ INCH/48, +/*Newline*/ INCH/6, +/*Char*/ INCH/10, +/*Em*/ INCH/10, +/*Halfline*/ INCH/12, +/*Adj*/ INCH/10, +/*twinit*/ "\033\006", +/*twrest*/ "\033\006", +/*twnl*/ "\015\n", +/*hlr*/ "\033H", +/*hlf*/ "\033h", +/*flr*/ "\032", +/*bdon*/ "\033E", +/*bdoff*/ "\033E", +/*ploton*/ "\006", +/*plotoff*/ "\033\006", +/*up*/ "\032", +/*down*/ "\n", +/*right*/ " ", +/*left*/ "\b", +/*codetab*/ +#include "code.300" diff --git a/src/troff/term/tab37 b/src/troff/term/tab37 new file mode 100755 index 0000000000000000000000000000000000000000..9df5607f8d619d6ec097c60dc2ea3c286ae4b2e5 GIT binary patch literal 1288 zcmZ{i3uxC>6vw~kdye?W@V_2bt0gVX*L2Ot)~0UL>D+X>mvhcNbmnqtTU)c$Y;9ww zffX2$&;tx%APGfML{d}~f+2;`i=;4&-jP%jD@n5M{U;(pm;3vibMF1!d+zz(J6?dZ zh6^nOp`~LIW(G!^j$dU=PRkkjL;jS%R!J?v#4`#H#Aj&K(r;ch<0J$!;s zb1(OCl>2#r&+!Gm$d`GDukj7O#lt+pqkNC=^Fw~ZI$ zJWo;6@j5{#>g9TsUZdCP4SJ(a(P=tUvvr>4YQ7d~iI(Xqt<+kr*CuV%cJ0tE?a^NC z(|#S)VI9$j^-W`?eII` z+u+;bcfvd1o$$NhUGQ%B-S8gx4){IrUiiK6``~@>o$&kN{g4MB1CT+;P!uT^-kq2Y zHiwMCZ-vgw$&Hu~T@bu5_+b0?@O6f-9V6`_2C`t^4Iu{Ow zXBGS$FuNEm3=;#1O{pc}8SISDMrOwq^{IU>0lT{)$&G0N%@M5;n=Z{6USCGRj;Lcs hL0d{rNL$DhG8BPDF' + DEFB 0 +?0035: + DEFB 1 + DEFB '?' + DEFB 0 +?0036: + DEFB 1 + DEFB '@' + DEFB 0 +?0037: + DEFB -127 + DEFB 'A' + DEFB 0 +?0038: + DEFB -127 + DEFB 'B' + DEFB 0 +?0039: + DEFB -127 + DEFB 'C' + DEFB 0 +?0040: + DEFB -127 + DEFB 'D' + DEFB 0 +?0041: + DEFB -127 + DEFB 'E' + DEFB 0 +?0042: + DEFB -127 + DEFB 'F' + DEFB 0 +?0043: + DEFB -127 + DEFB 'G' + DEFB 0 +?0044: + DEFB -127 + DEFB 'H' + DEFB 0 +?0045: + DEFB -127 + DEFB 'I' + DEFB 0 +?0046: + DEFB -127 + DEFB 'J' + DEFB 0 +?0047: + DEFB -127 + DEFB 'K' + DEFB 0 +?0048: + DEFB -127 + DEFB 'L' + DEFB 0 +?0049: + DEFB -127 + DEFB 'M' + DEFB 0 +?0050: + DEFB -127 + DEFB 'N' + DEFB 0 +?0051: + DEFB -127 + DEFB 'O' + DEFB 0 +?0052: + DEFB -127 + DEFB 'P' + DEFB 0 +?0053: + DEFB -127 + DEFB 'Q' + DEFB 0 +?0054: + DEFB -127 + DEFB 'R' + DEFB 0 +?0055: + DEFB -127 + DEFB 'S' + DEFB 0 +?0056: + DEFB -127 + DEFB 'T' + DEFB 0 +?0057: + DEFB -127 + DEFB 'U' + DEFB 0 +?0058: + DEFB -127 + DEFB 'V' + DEFB 0 +?0059: + DEFB -127 + DEFB 'W' + DEFB 0 +?0060: + DEFB -127 + DEFB 'X' + DEFB 0 +?0061: + DEFB -127 + DEFB 'Y' + DEFB 0 +?0062: + DEFB -127 + DEFB 'Z' + DEFB 0 +?0063: + DEFB 1 + DEFB '[' + DEFB 0 +?0064: + DEFB 1,92,0 +?0065: + DEFB 1 + DEFB ']' + DEFB 0 +?0066: + DEFB 1 + DEFB '^' + DEFB 0 +?0067: + DEFB 1 + DEFB '_' + DEFB 0 +?0068: + DEFB 1 + DEFB '`' + DEFB 0 +?0069: + DEFB -127 + DEFB 'a' + DEFB 0 +?0070: + DEFB -127 + DEFB 'b' + DEFB 0 +?0071: + DEFB -127 + DEFB 'c' + DEFB 0 +?0072: + DEFB -127 + DEFB 'd' + DEFB 0 +?0073: + DEFB -127 + DEFB 'e' + DEFB 0 +?0074: + DEFB -127 + DEFB 'f' + DEFB 0 +?0075: + DEFB -127 + DEFB 'g' + DEFB 0 +?0076: + DEFB -127 + DEFB 'h' + DEFB 0 +?0077: + DEFB -127 + DEFB 'i' + DEFB 0 +?0078: + DEFB -127 + DEFB 'j' + DEFB 0 +?0079: + DEFB -127 + DEFB 'k' + DEFB 0 +?0080: + DEFB -127 + DEFB 'l' + DEFB 0 +?0081: + DEFB -127 + DEFB 'm' + DEFB 0 +?0082: + DEFB -127 + DEFB 'n' + DEFB 0 +?0083: + DEFB -127 + DEFB 'o' + DEFB 0 +?0084: + DEFB -127 + DEFB 'p' + DEFB 0 +?0085: + DEFB -127 + DEFB 'q' + DEFB 0 +?0086: + DEFB -127 + DEFB 'r' + DEFB 0 +?0087: + DEFB -127 + DEFB 's' + DEFB 0 +?0088: + DEFB -127 + DEFB 't' + DEFB 0 +?0089: + DEFB -127 + DEFB 'u' + DEFB 0 +?0090: + DEFB -127 + DEFB 'v' + DEFB 0 +?0091: + DEFB -127 + DEFB 'w' + DEFB 0 +?0092: + DEFB -127 + DEFB 'x' + DEFB 0 +?0093: + DEFB -127 + DEFB 'y' + DEFB 0 +?0094: + DEFB -127 + DEFB 'z' + DEFB 0 +?0095: + DEFB 1 + DEFB '{' + DEFB 0 +?0096: + DEFB 1 + DEFB '|' + DEFB 0 +?0097: + DEFB 1 + DEFB '}' + DEFB 0 +?0098: + DEFB 1 + DEFB '~' + DEFB 0 +?0099: + DEFB 0,0,0 +?0100: + DEFB 1 + DEFB 'o' + DEFB 8 + DEFB '+' + DEFB 0 +?0101: + DEFB 2 + DEFB '[]' + DEFB 0 +?0102: + DEFB 3 + DEFB '1/4' + DEFB 0 +?0103: + DEFB 3 + DEFB '1/2' + DEFB 0 +?0104: + DEFB 3 + DEFB '3/4' + DEFB 0 +?0105: + DEFB -126 + DEFB 'fi' + DEFB 0 +?0106: + DEFB -126 + DEFB 'fl' + DEFB 0 +?0107: + DEFB -126 + DEFB 'ff' + DEFB 0 +?0108: + DEFB -125 + DEFB 'ffi' + DEFB 0 +?0109: + DEFB -125 + DEFB 'ffl' + DEFB 0 +?0110: + DEFB 1,27 + DEFB '8o' + DEFB 27 + DEFB '9' + DEFB 0 +?0111: + DEFB 1 + DEFB '|' + DEFB 8 + DEFB '-' + DEFB 0 +?0112: + DEFB -127,14 + DEFB 'A' + DEFB 15,0 +?0113: + DEFB -127,14 + DEFB 'B' + DEFB 15,0 +?0114: + DEFB -127,14,92,15,0 +?0115: + DEFB -127,14 + DEFB 'D' + DEFB 15,0 +?0116: + DEFB -127,14 + DEFB 'S' + DEFB 15,0 +?0117: + DEFB -127,14 + DEFB 'Q' + DEFB 15,0 +?0118: + DEFB -127,14 + DEFB 'N' + DEFB 15,0 +?0119: + DEFB -127,14 + DEFB 'O' + DEFB 15,0 +?0120: + DEFB -127,14 + DEFB 'L' + DEFB 15,0 +?0121: + DEFB -127,14 + DEFB 'M' + DEFB 15,0 +?0122: + DEFB -127,14 + DEFB '@' + DEFB 15,0 +?0123: + DEFB -127,14 + DEFB 'X' + DEFB 15,0 +?0124: + DEFB -127,14 + DEFB 'J' + DEFB 15,0 +?0125: + DEFB -127,14 + DEFB 'K' + DEFB 15,0 +?0126: + DEFB -127,14 + DEFB 'Y' + DEFB 15,0 +?0127: + DEFB -127,14 + DEFB 'I' + DEFB 15,0 +?0128: + DEFB -127,14 + DEFB 'U' + DEFB 15,0 +?0129: + DEFB -127,14 + DEFB 'V' + DEFB 15,0 +?0130: + DEFB -127,14 + DEFB 'C' + DEFB 15,0 +?0131: + DEFB -127,14 + DEFB 'G' + DEFB 15,0 +?0132: + DEFB -127,14 + DEFB 'W' + DEFB 15,0 +?0133: + DEFB -127,14 + DEFB 'T' + DEFB 15,0 +?0134: + DEFB -127,14 + DEFB 'E' + DEFB 15,0 +?0135: + DEFB -127,14 + DEFB 'P' + DEFB 15,0 +?0136: + DEFB -127,14 + DEFB 'R' + DEFB 15,0 +?0137: + DEFB -127,14 + DEFB 'F' + DEFB 15,0 +?0138: + DEFB -127,14 + DEFB 'H' + DEFB 15,0 +?0139: + DEFB -127,14 + DEFB 'Z' + DEFB 15,0 +?0140: + DEFB 1 + DEFB '>' + DEFB 8 + DEFB '_' + DEFB 0 +?0141: + DEFB 1 + DEFB '<' + DEFB 8 + DEFB '_' + DEFB 0 +?0142: + DEFB 1 + DEFB '=' + DEFB 8 + DEFB '_' + DEFB 0 +?0143: + DEFB 1 + DEFB '=' + DEFB 8 + DEFB '~' + DEFB 0 +?0144: + DEFB 1,27 + DEFB '9~' + DEFB 27 + DEFB '8' + DEFB 0 +?0145: + DEFB 1 + DEFB '=' + DEFB 8 + DEFB '/' + DEFB 0 +?0146: + DEFB 2 + DEFB '->' + DEFB 0 +?0147: + DEFB 2 + DEFB '<-' + DEFB 0 +?0148: + DEFB 1 + DEFB '|' + DEFB 8 + DEFB '^' + DEFB 0 +?0149: + DEFB 1 + DEFB 'x' + DEFB 0 +?0150: + DEFB 1 + DEFB '+' + DEFB 8 + DEFB '_' + DEFB 0 +?0151: + DEFB 1 + DEFB 'U' + DEFB 0 +?0152: + DEFB 2 + DEFB 'oo' + DEFB 0 +?0153: + DEFB 1,14 + DEFB ']' + DEFB 15,0 +?0154: + DEFB 1,14 + DEFB '[' + DEFB 15,0 +?0155: + DEFB 1,14 + DEFB '_' + DEFB 15,0 +?0156: + DEFB 1,14 + DEFB '^' + DEFB 15,0 +?0157: + DEFB 1,27 + DEFB '8r' + DEFB 27 + DEFB '9' + DEFB 0 +?0158: + DEFB 1,27 + DEFB '8c' + DEFB 27 + DEFB '9' + DEFB 0 +?0159: + DEFB 1 + DEFB 'c' + DEFB 8 + DEFB '/' + DEFB 0 +?0160: + DEFB 1 + DEFB '|' + DEFB 8 + DEFB '=' + DEFB 0 +?0161: + DEFB 2 + DEFB '=>' + DEFB 0 +?0162: + DEFB 2 + DEFB '<=' + DEFB 0 +?0163: + DEFB 1 + DEFB 'O' + DEFB 0 + +string_final: + + end diff --git a/src/troff/term/tab37.c b/src/troff/term/tab37.c new file mode 100755 index 00000000..a12c198f --- /dev/null +++ b/src/troff/term/tab37.c @@ -0,0 +1,270 @@ +#define INCH 240 +/* +TTY M37 +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t = +{ +/*bset*/ 0, +/*breset*/ 0, +/*Hor*/ INCH/10, +/*Vert*/ INCH/12, +/*Newline*/ INCH/6, +/*Char*/ INCH/10, +/*Em*/ INCH/10, +/*Halfline*/ INCH/12, +/*Adj*/ INCH/10, +/*twinit*/ "", +/*twrest*/ "", +/*twnl*/ "\n", +/*hlr*/ "\0338", +/*hlf*/ "\0339", +/*flr*/ "\0337", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "", +/*plotoff*/ "", +/*up*/ "", +/*down*/ "", +/*right*/ "", +/*left*/ "", +/*codetab*/ +"\001 ", /*space*/ +"\001!", /*!*/ +"\001\"", /*"*/ +"\001#", /*#*/ +"\001$", /*$*/ +"\001%", /*%*/ +"\001&", /*&*/ +"\001'", /*' close*/ +"\001(", /*(*/ +"\001)", /*)*/ +"\001*", /***/ +"\001+", /*+*/ +"\001,", /*,*/ +"\001-", /*- hyphen*/ +"\001.", /*.*/ +"\001/", /*/*/ +"\2010", /*0*/ +"\2011", /*1*/ +"\2012", /*2*/ +"\2013", /*3*/ +"\2014", /*4*/ +"\2015", /*5*/ +"\2016", /*6*/ +"\2017", /*7*/ +"\2018", /*8*/ +"\2019", /*9*/ +"\001:", /*:*/ +"\001;", /*;*/ +"\001<", /*<*/ +"\001=", /*=*/ +"\001>", /*>*/ +"\001?", /*?*/ +"\001@", /*@*/ +"\201A", /*A*/ +"\201B", /*B*/ +"\201C", /*C*/ +"\201D", /*D*/ +"\201E", /*E*/ +"\201F", /*F*/ +"\201G", /*G*/ +"\201H", /*H*/ +"\201I", /*I*/ +"\201J", /*J*/ +"\201K", /*K*/ +"\201L", /*L*/ +"\201M", /*M*/ +"\201N", /*N*/ +"\201O", /*O*/ +"\201P", /*P*/ +"\201Q", /*Q*/ +"\201R", /*R*/ +"\201S", /*S*/ +"\201T", /*T*/ +"\201U", /*U*/ +"\201V", /*V*/ +"\201W", /*W*/ +"\201X", /*X*/ +"\201Y", /*Y*/ +"\201Z", /*Z*/ +"\001[", /*[*/ +"\001\\", /*\*/ +"\001]", /*]*/ +"\001^", /*^*/ +"\001_", /*_ dash*/ +"\001`", /*` open*/ +"\201a", /*a*/ +"\201b", /*b*/ +"\201c", /*c*/ +"\201d", /*d*/ +"\201e", /*e*/ +"\201f", /*f*/ +"\201g", /*g*/ +"\201h", /*h*/ +"\201i", /*i*/ +"\201j", /*j*/ +"\201k", /*k*/ +"\201l", /*l*/ +"\201m", /*m*/ +"\201n", /*n*/ +"\201o", /*o*/ +"\201p", /*p*/ +"\201q", /*q*/ +"\201r", /*r*/ +"\201s", /*s*/ +"\201t", /*t*/ +"\201u", /*u*/ +"\201v", /*v*/ +"\201w", /*w*/ +"\201x", /*x*/ +"\201y", /*y*/ +"\201z", /*z*/ +"\001{", /*{*/ +"\001|", /*|*/ +"\001}", /*}*/ +"\001~", /*~*/ +"\000\0", /*narrow sp*/ +"\001-", /*hyphen*/ +"\001o\b+", /*bullet*/ +"\002\[]", /*square*/ +"\001-", /*3/4 em*/ +"\001_", /*rule*/ +"\0031/4", /*1/4*/ +"\0031/2", /*1/2*/ +"\0033/4", /*3/4*/ +"\001-", /*minus*/ +"\202fi", /*fi*/ +"\202fl", /*fl*/ +"\202ff", /*ff*/ +"\203ffi", /*ffi*/ +"\203ffl", /*ffl*/ +"\001\0338o\0339", /*degree*/ +"\001|\b-", /*dagger*/ +"\000\0", /*section*/ +"\001'", /*foot mark*/ +"\001'", /*acute accent*/ +"\001`", /*grave accent*/ +"\001_", /*underrule*/ +"\001/", /*slash (longer)*/ +"\000\0", /*half narrow space*/ +"\001 ", /*unpaddable space*/ +"\201\016A\017", /*alpha*/ +"\201\016B\017", /*beta*/ +"\201\016\\\017", /*gamma*/ +"\201\016D\017", /*delta*/ +"\201\016S\017", /*epsilon*/ +"\201\016Q\017", /*zeta*/ +"\201\016N\017", /*eta*/ +"\201\016O\017", /*theta*/ +"\201i", /*iota*/ +"\201k", /*kappa*/ +"\201\016L\017", /*lambda*/ +"\201\016M\017", /*mu*/ +"\201\016@\017", /*nu*/ +"\201\016X\017", /*xi*/ +"\201o", /*omicron*/ +"\201\016J\017", /*pi*/ +"\201\016K\017", /*rho*/ +"\201\016Y\017", /*sigma*/ +"\201\016I\017", /*tau*/ +"\201v", /*upsilon*/ +"\201\016U\017", /*phi*/ +"\201x", /*chi*/ +"\201\016V\017", /*psi*/ +"\201\016C\017", /*omega*/ +"\201\016G\017", /*Gamma*/ +"\201\016W\017", /*Delta*/ +"\201\016T\017", /*Theta*/ +"\201\016E\017", /*Lambda*/ +"\000\0", /*Xi*/ +"\201\016P\017", /*Pi*/ +"\201\016R\017", /*Sigma*/ +"\000\0", /**/ +"\201Y", /*Upsilon*/ +"\201\016F\017", /*Phi*/ +"\201\016H\017", /*Psi*/ +"\201\016Z\017", /*Omega*/ +"\000\0", /*square root*/ +"\000\0", /*terminal sigma*/ +"\000\0", /*root en*/ +"\001>\b_", /*>=*/ +"\001<\b_", /*<=*/ +"\001=\b_", /*identically equal*/ +"\001-", /*equation minus*/ +"\001=\b~", /*approx =*/ +"\001\0339~\0338", /*approximates*/ +"\001=\b/", /*not equal*/ +"\002->", /*right arrow*/ +"\002<-", /*left arrow*/ +"\001|\b^", /*up arrow*/ +"\000\0", /*down arrow*/ +"\001=", /*equation equal*/ +"\001x", /*multiply*/ +"\001/", /*divide*/ +"\001+\b_", /*plus-minus*/ +"\001U", /*cup (union)*/ +"\000\0", /*cap (intersection)*/ +"\000\0", /*subset of*/ +"\000\0", /*superset of*/ +"\000\0", /*improper subset*/ +"\000\0", /* improper superset*/ +"\002oo", /*infinity*/ +"\001\016]\017", /*partial derivative*/ +"\001\016[\017", /*gradient*/ +"\001\016_\017", /*not*/ +"\001\016^\017", /*integral sign*/ +"\000\0", /*proportional to*/ +"\000\0", /*empty set*/ +"\000\0", /*member of*/ +"\001+", /*equation plus*/ +"\001\0338r\0339", /*registered*/ +"\001\0338c\0339", /*copyright*/ +"\001|", /*box rule */ +"\001c\b/", /*cent sign*/ +"\001|\b=", /*dbl dagger*/ +"\002=>", /*right hand*/ +"\002<=", /*left hand*/ +"\001*", /*math * */ +"\000\0", /*bell system sign*/ +"\001|", /*or (was star)*/ +"\001O", /*circle*/ +"\001|", /*left top (of big curly)*/ +"\001|", /*left bottom*/ +"\001|", /*right top*/ +"\001|", /*right bot*/ +"\001|", /*left center of big curly bracket*/ +"\001|", /*right center of big curly bracket*/ +"\001|", /*bold vertical*/ +"\001|", /*left floor (left bot of big sq bract)*/ +"\001|", /*right floor (rb of ")*/ +"\001|", /*left ceiling (lt of ")*/ +"\001|"}; /*right ceiling (rt of ")*/ diff --git a/src/troff/term/tab37.lnk b/src/troff/term/tab37.lnk new file mode 100755 index 00000000..00b0ff13 --- /dev/null +++ b/src/troff/term/tab37.lnk @@ -0,0 +1,8 @@ +-k ..\..\..\..\..\lib +-l libiar.lib +-m +-u +-i +-o tab37 +-bl CODE=0 +tab37 diff --git a/src/troff/term/tab450-12-8.c b/src/troff/term/tab450-12-8.c new file mode 100755 index 00000000..2cef2f5a --- /dev/null +++ b/src/troff/term/tab450-12-8.c @@ -0,0 +1,60 @@ +#define INCH 240 +/* +DASI450 +12 chars/inch, 8 lines/inch +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0177420, +/*Hor*/ INCH/60, +/*Vert*/ INCH/48, +/*Newline*/ INCH/8, +/*Char*/ INCH/12, +/*Em*/ INCH/12, +/*Halfline*/ INCH/16, +/*Adj*/ INCH/12, +/*twinit*/ "\0334\033\037\013\033\036\007", +/*twrest*/ "\0334\033\037\015\033\036\011", +/*twnl*/ "\015\n", +/*hlr*/ "\033D", +/*hlf*/ "\033U", +/*flr*/ "\033\n", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "\0333", +/*plotoff*/ "\0334", +/*up*/ "\033\n", +/*down*/ "\n", +/*right*/ " ", +/*left*/ "\b", +/*codetab*/ +#include "code.300" diff --git a/src/troff/term/tab450-12.c b/src/troff/term/tab450-12.c new file mode 100755 index 00000000..ca0575fa --- /dev/null +++ b/src/troff/term/tab450-12.c @@ -0,0 +1,60 @@ +#define INCH 240 +/* +DASI450 +12 chars/inch, 6 lines/inch +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0177420, +/*Hor*/ INCH/60, +/*Vert*/ INCH/48, +/*Newline*/ INCH/6, +/*Char*/ INCH/12, +/*Em*/ INCH/12, +/*Halfline*/ INCH/12, +/*Adj*/ INCH/12, +/*twinit*/ "\0334\033\037\013", +/*twrest*/ "\0334\033\037\015", +/*twnl*/ "\015\n", +/*hlr*/ "\033D", +/*hlf*/ "\033U", +/*flr*/ "\033\n", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "\0333", +/*plotoff*/ "\0334", +/*up*/ "\033\n", +/*down*/ "\n", +/*right*/ " ", +/*left*/ "\b", +/*codetab*/ +#include "code.300" diff --git a/src/troff/term/tab450.c b/src/troff/term/tab450.c new file mode 100755 index 00000000..368da416 --- /dev/null +++ b/src/troff/term/tab450.c @@ -0,0 +1,59 @@ +#define INCH 240 +/* +DASI450 +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0177420, +/*Hor*/ INCH/60, +/*Vert*/ INCH/48, +/*Newline*/ INCH/6, +/*Char*/ INCH/10, +/*Em*/ INCH/10, +/*Halfline*/ INCH/12, +/*Adj*/ INCH/10, +/*twinit*/ "\0334", +/*twrest*/ "\0334", +/*twnl*/ "\015\n", +/*hlr*/ "\033D", +/*hlf*/ "\033U", +/*flr*/ "\033\n", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "\0333", +/*plotoff*/ "\0334", +/*up*/ "\033\n", +/*down*/ "\n", +/*right*/ " ", +/*left*/ "\b", +/*codetab*/ +#include "code.300" diff --git a/src/troff/term/tab832.c b/src/troff/term/tab832.c new file mode 100755 index 00000000..6c4bf8c5 --- /dev/null +++ b/src/troff/term/tab832.c @@ -0,0 +1,59 @@ +#define INCH 240 +/* +Anderson Jacobson 832 +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0177420, +/*Hor*/ INCH/60, +/*Vert*/ INCH/48, +/*Newline*/ INCH/6, +/*Char*/ INCH/10, +/*Em*/ INCH/10, +/*Halfline*/ INCH/12, +/*Adj*/ INCH/10, +/*twinit*/ "\033N", +/*twrest*/ "\033N", +/*twnl*/ "\015\n", +/*hlr*/ "\0338", +/*hlf*/ "\0339", +/*flr*/ "\0337", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "\033P", +/*plotoff*/ "\033N", +/*up*/ "\013", +/*down*/ "\n", +/*right*/ " ", +/*left*/ "\b", +/*codetab*/ +#include "code.300" diff --git a/src/troff/term/taba1.c b/src/troff/term/taba1.c new file mode 100755 index 00000000..4f42f08a --- /dev/null +++ b/src/troff/term/taba1.c @@ -0,0 +1,59 @@ +#define INCH 240 +/* +DASI450 +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0177420, +/*Hor*/ INCH/60, +/*Vert*/ INCH/48, +/*Newline*/ INCH/6, +/*Char*/ INCH/10, +/*Em*/ INCH/10, +/*Halfline*/ INCH/12, +/*Adj*/ INCH/10, +/*twinit*/ "\033R", +/*twrest*/ "\033R", +/*twnl*/ "\015\n", +/*hlr*/ "\033S", +/*hlf*/ "\033B", +/*flr*/ "\033\n", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "\0334", +/*plotoff*/ "\033R", +/*up*/ "\005", +/*down*/ "\n", +/*right*/ " ", +/*left*/ "\b", +/*codetab*/ +#include "code.300" diff --git a/src/troff/term/tablp.c b/src/troff/term/tablp.c new file mode 100755 index 00000000..46568cb5 --- /dev/null +++ b/src/troff/term/tablp.c @@ -0,0 +1,269 @@ +#define INCH 240 +/* +Line Printer with col-only reverse line feed +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0, +/*Hor*/ INCH/10, +/*Vert*/ INCH/6, +/*Newline*/ INCH/6, +/*Char*/ INCH/10, +/*Em*/ INCH/10, +/*Halfline*/ INCH/12, +/*Adj*/ INCH/10, +/*twinit*/ "", +/*twrest*/ "", +/*twnl*/ "\n", +/*hlr*/ "", +/*hlf*/ "", +/*flr*/ "\0337", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "", +/*plotoff*/ "", +/*up*/ "", +/*down*/ "", +/*right*/ "", +/*left*/ "", +/*codetab*/ +"\001 ", /*space*/ +"\001!", /*!*/ +"\001\"", /*"*/ +"\001#", /*#*/ +"\001$", /*$*/ +"\001%", /*%*/ +"\001&", /*&*/ +"\001'", /*' close*/ +"\001(", /*(*/ +"\001)", /*)*/ +"\001*", /***/ +"\001+", /*+*/ +"\001,", /*,*/ +"\001-", /*- hyphen*/ +"\001.", /*.*/ +"\001/", /*/*/ +"\2010", /*0*/ +"\2011", /*1*/ +"\2012", /*2*/ +"\2013", /*3*/ +"\2014", /*4*/ +"\2015", /*5*/ +"\2016", /*6*/ +"\2017", /*7*/ +"\2018", /*8*/ +"\2019", /*9*/ +"\001:", /*:*/ +"\001;", /*;*/ +"\001<", /*<*/ +"\001=", /*=*/ +"\001>", /*>*/ +"\001?", /*?*/ +"\001@", /*@*/ +"\201A", /*A*/ +"\201B", /*B*/ +"\201C", /*C*/ +"\201D", /*D*/ +"\201E", /*E*/ +"\201F", /*F*/ +"\201G", /*G*/ +"\201H", /*H*/ +"\201I", /*I*/ +"\201J", /*J*/ +"\201K", /*K*/ +"\201L", /*L*/ +"\201M", /*M*/ +"\201N", /*N*/ +"\201O", /*O*/ +"\201P", /*P*/ +"\201Q", /*Q*/ +"\201R", /*R*/ +"\201S", /*S*/ +"\201T", /*T*/ +"\201U", /*U*/ +"\201V", /*V*/ +"\201W", /*W*/ +"\201X", /*X*/ +"\201Y", /*Y*/ +"\201Z", /*Z*/ +"\001[", /*[*/ +"\001\\", /*\*/ +"\001]", /*]*/ +"\001^", /*^*/ +"\001_", /*_ dash*/ +"\001`", /*` open*/ +"\201a", /*a*/ +"\201b", /*b*/ +"\201c", /*c*/ +"\201d", /*d*/ +"\201e", /*e*/ +"\201f", /*f*/ +"\201g", /*g*/ +"\201h", /*h*/ +"\201i", /*i*/ +"\201j", /*j*/ +"\201k", /*k*/ +"\201l", /*l*/ +"\201m", /*m*/ +"\201n", /*n*/ +"\201o", /*o*/ +"\201p", /*p*/ +"\201q", /*q*/ +"\201r", /*r*/ +"\201s", /*s*/ +"\201t", /*t*/ +"\201u", /*u*/ +"\201v", /*v*/ +"\201w", /*w*/ +"\201x", /*x*/ +"\201y", /*y*/ +"\201z", /*z*/ +"\001{", /*{*/ +"\001|", /*|*/ +"\001}", /*}*/ +"\001~", /*~*/ +"\000\0", /*nar sp*/ +"\001-", /*hyphen*/ +"\001o\b+", /*bullet*/ +"\002\[]", /*square*/ +"\001-", /*3/4 em*/ +"\001_", /*rule*/ +"\000\0", /*1/4*/ +"\000\0", /*1/2*/ +"\000\0", /*3/4*/ +"\001-", /*minus*/ +"\202fi", /*fi*/ +"\202fl", /*fl*/ +"\202ff", /*ff*/ +"\203ffi", /*ffi*/ +"\203ffl", /*ffl*/ +"\000\0", /*degree*/ +"\000\0", /*dagger*/ +"\000\0", /*section*/ +"\001'", /*foot mark*/ +"\001'", /*acute accent*/ +"\001`", /*grave accent*/ +"\001_", /*underrule*/ +"\001/", /*slash (longer)*/ +"\000\0", /*half narrow space*/ +"\001 ", /*unpaddable space*/ +"\000", /*alpha*/ +"\000", /*beta*/ +"\000", /*gamma*/ +"\000", /*delta*/ +"\000", /*epsilon*/ +"\000", /*zeta*/ +"\000", /*eta*/ +"\000", /*theta*/ +"\201i", /*iota*/ +"\201k", /*kappa*/ +"\000", /*lambda*/ +"\000", /*mu*/ +"\000", /*nu*/ +"\000", /*xi*/ +"\201o", /*omicron*/ +"\000", /*pi*/ +"\000", /*rho*/ +"\000", /*sigma*/ +"\000", /*tau*/ +"\201v", /*upsilon*/ +"\000", /*phi*/ +"\201x", /*chi*/ +"\000", /*psi*/ +"\000", /*omega*/ +"\000", /*Gamma*/ +"\000", /*Delta*/ +"\000", /*Theta*/ +"\000", /*Lambda*/ +"\000\0", /*Xi*/ +"\000", /*Pi*/ +"\000", /*Sigma*/ +"\000\0", /**/ +"\201Y", /*Upsilon*/ +"\000", /*Phi*/ +"\000", /*Psi*/ +"\000", /*Omega*/ +"\000\0", /*square root*/ +"\000\0", /*terminal sigma*/ +"\000\0", /*root en*/ +"\001>\b_", /*>=*/ +"\001<\b_", /*<=*/ +"\001=\b_", /*identically equal*/ +"\001-", /*equation minus*/ +"\001=\b~", /*approx =*/ +"\000\0", /*approximates*/ +"\001=\b/", /*not equal*/ +"\002->", /*right arrow*/ +"\002<-", /*left arrow*/ +"\001|\b^", /*up arrow*/ +"\000\0", /*down arrow*/ +"\001=", /*equation equal*/ +"\001x", /*multiply*/ +"\001/", /*divide*/ +"\001+\b_", /*plus-minus*/ +"\001U", /*cup (union)*/ +"\000\0", /*cap (intersection)*/ +"\000\0", /*subset of*/ +"\000\0", /*superset of*/ +"\000\0", /*improper subset*/ +"\000\0", /* improper superset*/ +"\002oo", /*infinity*/ +"\000", /*partial derivative*/ +"\000", /*gradient*/ +"\000", /*not*/ +"\000", /*integral sign*/ +"\000\0", /*proportional to*/ +"\000\0", /*empty set*/ +"\000\0", /*member of*/ +"\001+", /*equation plus*/ +"\001r\bO", /*registered*/ +"\001c\bO", /*copyright*/ +"\001|", /*box rule */ +"\001c\b/", /*cent sign*/ +"\000\0", /*dbl dagger*/ +"\000\0", /*right hand*/ +"\001*", /*left hand*/ +"\001*", /*math * */ +"\000\0", /*bell system sign*/ +"\001|", /*or (was star)*/ +"\001O", /*circle*/ +"\001|", /*left top (of big curly)*/ +"\001|", /*left bottom*/ +"\001|", /*right top*/ +"\001|", /*right bot*/ +"\001|", /*left center of big curly bracket*/ +"\001|", /*right center of big curly bracket*/ +"\001|", /*bold vertical*/ +"\001|", /*left floor (left bot of big sq bract)*/ +"\001|", /*right floor (rb of ")*/ +"\001|", /*left ceiling (lt of ")*/ +"\001|"}; /*right ceiling (rt of ")*/ diff --git a/src/troff/term/tabtn300.c b/src/troff/term/tabtn300.c new file mode 100755 index 00000000..5f70e5b8 --- /dev/null +++ b/src/troff/term/tabtn300.c @@ -0,0 +1,269 @@ +#define INCH 240 +/* +Terminet300 +nroff driving tables +width and code tables +*/ + +struct { + int bset; + int breset; + int Hor; + int Vert; + int Newline; + int Char; + int Em; + int Halfline; + int Adj; + char *twinit; + char *twrest; + char *twnl; + char *hlr; + char *hlf; + char *flr; + char *bdon; + char *bdoff; + char *ploton; + char *plotoff; + char *up; + char *down; + char *right; + char *left; + char *codetab[256-32]; + int zzz; + } t { +/*bset*/ 0, +/*breset*/ 0, +/*Hor*/ INCH/10, +/*Vert*/ INCH/6, +/*Newline*/ INCH/6, +/*Char*/ INCH/10, +/*Em*/ INCH/10, +/*Halfline*/ INCH/12, +/*Adj*/ INCH/10, +/*twinit*/ "", +/*twrest*/ "", +/*twnl*/ "\n", +/*hlr*/ "", +/*hlf*/ "", +/*flr*/ "", +/*bdon*/ "", +/*bdoff*/ "", +/*ploton*/ "", +/*plotoff*/ "", +/*up*/ "", +/*down*/ "", +/*right*/ "", +/*left*/ "", +/*codetab*/ +"\001 ", /*space*/ +"\001!", /*!*/ +"\001\"", /*"*/ +"\001#", /*#*/ +"\001$", /*$*/ +"\001%", /*%*/ +"\001&", /*&*/ +"\001'", /*' close*/ +"\001(", /*(*/ +"\001)", /*)*/ +"\001*", /***/ +"\001+", /*+*/ +"\001,", /*,*/ +"\001-", /*- hyphen*/ +"\001.", /*.*/ +"\001/", /*/*/ +"\2010", /*0*/ +"\2011", /*1*/ +"\2012", /*2*/ +"\2013", /*3*/ +"\2014", /*4*/ +"\2015", /*5*/ +"\2016", /*6*/ +"\2017", /*7*/ +"\2018", /*8*/ +"\2019", /*9*/ +"\001:", /*:*/ +"\001;", /*;*/ +"\001<", /*<*/ +"\001=", /*=*/ +"\001>", /*>*/ +"\001?", /*?*/ +"\001@", /*@*/ +"\201A", /*A*/ +"\201B", /*B*/ +"\201C", /*C*/ +"\201D", /*D*/ +"\201E", /*E*/ +"\201F", /*F*/ +"\201G", /*G*/ +"\201H", /*H*/ +"\201I", /*I*/ +"\201J", /*J*/ +"\201K", /*K*/ +"\201L", /*L*/ +"\201M", /*M*/ +"\201N", /*N*/ +"\201O", /*O*/ +"\201P", /*P*/ +"\201Q", /*Q*/ +"\201R", /*R*/ +"\201S", /*S*/ +"\201T", /*T*/ +"\201U", /*U*/ +"\201V", /*V*/ +"\201W", /*W*/ +"\201X", /*X*/ +"\201Y", /*Y*/ +"\201Z", /*Z*/ +"\001[", /*[*/ +"\001\\", /*\*/ +"\001]", /*]*/ +"\001^", /*^*/ +"\001_", /*_ dash*/ +"\001`", /*` open*/ +"\201a", /*a*/ +"\201b", /*b*/ +"\201c", /*c*/ +"\201d", /*d*/ +"\201e", /*e*/ +"\201f", /*f*/ +"\201g", /*g*/ +"\201h", /*h*/ +"\201i", /*i*/ +"\201j", /*j*/ +"\201k", /*k*/ +"\201l", /*l*/ +"\201m", /*m*/ +"\201n", /*n*/ +"\201o", /*o*/ +"\201p", /*p*/ +"\201q", /*q*/ +"\201r", /*r*/ +"\201s", /*s*/ +"\201t", /*t*/ +"\201u", /*u*/ +"\201v", /*v*/ +"\201w", /*w*/ +"\201x", /*x*/ +"\201y", /*y*/ +"\201z", /*z*/ +"\001{", /*{*/ +"\001|", /*|*/ +"\001}", /*}*/ +"\001~", /*~*/ +"\000\0", /*nar sp*/ +"\001-", /*hyphen*/ +"\001o\b+", /*bullet*/ +"\002\[]", /*square*/ +"\001-", /*3/4 em*/ +"\001_", /*rule*/ +"\0031/4", /*1/4*/ +"\0031/2", /*1/2*/ +"\0033/4", /*3/4*/ +"\001-", /*minus*/ +"\202fi", /*fi*/ +"\202fl", /*fl*/ +"\202ff", /*ff*/ +"\203ffi", /*ffi*/ +"\203ffl", /*ffl*/ +"\000\0", /*degree*/ +"\001|\b-", /*dagger*/ +"\000\0", /*section*/ +"\001'", /*foot mark*/ +"\001'", /*acute accent*/ +"\001`", /*grave accent*/ +"\001_", /*underrule*/ +"\001/", /*slash (longer)*/ +"\000\0", /*half narrow space*/ +"\001 ", /*unpaddable space*/ +"\000", /*alpha*/ +"\000", /*beta*/ +"\000", /*gamma*/ +"\000", /*delta*/ +"\000", /*epsilon*/ +"\000", /*zeta*/ +"\000", /*eta*/ +"\000", /*theta*/ +"\201i", /*iota*/ +"\201k", /*kappa*/ +"\000", /*lambda*/ +"\000", /*mu*/ +"\000", /*nu*/ +"\000", /*xi*/ +"\201o", /*omicron*/ +"\000", /*pi*/ +"\000", /*rho*/ +"\000", /*sigma*/ +"\000", /*tau*/ +"\201v", /*upsilon*/ +"\000", /*phi*/ +"\201x", /*chi*/ +"\000", /*psi*/ +"\000", /*omega*/ +"\000", /*Gamma*/ +"\000", /*Delta*/ +"\000", /*Theta*/ +"\000", /*Lambda*/ +"\000\0", /*Xi*/ +"\000", /*Pi*/ +"\000", /*Sigma*/ +"\000\0", /**/ +"\201Y", /*Upsilon*/ +"\000", /*Phi*/ +"\000", /*Psi*/ +"\000", /*Omega*/ +"\000\0", /*square root*/ +"\000\0", /*terminal sigma*/ +"\000\0", /*root en*/ +"\001>\b_", /*>=*/ +"\001<\b_", /*<=*/ +"\001=\b_", /*identically equal*/ +"\001-", /*equation minus*/ +"\001=\b~", /*approx =*/ +"\000\0", /*approximates*/ +"\001=\b/", /*not equal*/ +"\002->", /*right arrow*/ +"\002<-", /*left arrow*/ +"\001|\b^", /*up arrow*/ +"\000\0", /*down arrow*/ +"\001=", /*equation equal*/ +"\001x", /*multiply*/ +"\001/", /*divide*/ +"\001+\b_", /*plus-minus*/ +"\001U", /*cup (union)*/ +"\000\0", /*cap (intersection)*/ +"\000\0", /*subset of*/ +"\000\0", /*superset of*/ +"\000\0", /*improper subset*/ +"\000\0", /* improper superset*/ +"\002oo", /*infinity*/ +"\000", /*partial derivative*/ +"\000", /*gradient*/ +"\000", /*not*/ +"\000", /*integral sign*/ +"\000\0", /*proportional to*/ +"\000\0", /*empty set*/ +"\000\0", /*member of*/ +"\001+", /*equation plus*/ +"\001r\bO", /*registered*/ +"\001c\bO", /*copyright*/ +"\001|", /*box rule */ +"\001c\b/", /*cent sign*/ +"\001|\b=", /*dbl dagger*/ +"\002=>", /*right hand*/ +"\002<=", /*left hand*/ +"\001*", /*math * */ +"\000\0", /*bell system sign*/ +"\001|", /*or (was star)*/ +"\001O", /*circle*/ +"\001|", /*left top (of big curly)*/ +"\001|", /*left bottom*/ +"\001|", /*right top*/ +"\001|", /*right bot*/ +"\001|", /*left center of big curly bracket*/ +"\001|", /*right center of big curly bracket*/ +"\001|", /*bold vertical*/ +"\001|", /*left floor (left bot of big sq bract)*/ +"\001|", /*right floor (rb of ")*/ +"\001|", /*left ceiling (lt of ")*/ +"\001|"}; /*right ceiling (rt of ")*/ diff --git a/src/troff/textscript b/src/troff/textscript new file mode 100755 index 00000000..ae322fec --- /dev/null +++ b/src/troff/textscript @@ -0,0 +1,5 @@ +g/\.data/d +0a +.text +. +w diff --git a/src/troff/tmac/tmac.an b/src/troff/tmac/tmac.an new file mode 100755 index 00000000..a21878c9 --- /dev/null +++ b/src/troff/tmac/tmac.an @@ -0,0 +1,267 @@ +' # month name +.if "\nd"0" .nr m \n(mo-1 +.if "\nm"0" .ds ]m January +.if "\nm"1" .ds ]m February +.if "\nm"2" .ds ]m March +.if "\nm"3" .ds ]m April +.if "\nm"4" .ds ]m May +.if "\nm"5" .ds ]m June +.if "\nm"6" .ds ]m July +.if "\nm"7" .ds ]m August +.if "\nm"8" .ds ]m September +.if "\nm"9" .ds ]m October +.if "\nm"10" .ds ]m November +.if "\nm"11" .ds ]m December +' # set the date +.if n \{.nr m \nm+1 +. ie \nd .ds ]W Modified \nd/\nm/\ny +. el .ds ]W Printed \n(dy/\n(mo/\n(yr\} +.if t \{.ie \nd .ds ]W \*(]m \nd, \ny +. el .ds ]W \*(]m \n(dy, \n(yr\} +.if t .ds ]W 7th Edition +' # reset the basic page layout +.de }E +.}f +.in \\n()Ru+\\n(INu +.ll \\n(LLu +.. +' # default tabs +.de DT +'ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +.. +' # set type font and size +.de }f +.ps 10 +.ft 1 +.. +' # handle the head of the page +.de }H +.ev 1 +.}C +'sp .5i +.ft 1 +.ps 10 +.tl @\\*(]H@\\*(]D@\\*(]H@ +'sp .5i +.ev +.ns +.. +' # handle the foot of the page +.de }F +.ev 1 +.ft 1 +.ps 10 +'sp .5i +.tl @\\*(]W@\\*(]L@%@ +'bp +.ev +.. +' # the cut mark +.if n .ig +.de }C +.po .1i +.tl '-' +.po +.. +' # the final cut mark +.de }M +.}N +.wh -1p }C +.ll \\n(LLu +.. +' # no runout unless there was a .TH +.de }K +.}N +.pl 1 +.ll \\n(LLu +.. +.em }K +' # set title and heading +.de TH +.PD +.if n .nr IN .5i +.if t .nr IN .5i +.nr LL \\n(.l +.ds ]H \\$1\|(\|\\$2\|) +.ds ]D UNIX Programmer's Manual +.ds ]L \\$3 +.wh 0 }H +.if t .wh -1i }F +.if n .wh -1.167i }F +.em }M +.if \\n(nl .bp 1 +.}E +.DT +.nr )I .5i +.nr )R 0 +.if n .na +.. +' # section heading +.de SH +.}X 0 +.nr )E 2 +\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 +.. +' # sub section heading +.de SS +.}X \\n()Ru+\\n(INu +\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 +.br +.. +' # subroutine for section heading +.de }X +.}E +.ti \\$1 +.sp \\n()Pu +.ne 2 +.nr )R 0 +.fi +.it 1 }N +.SM +.B +.. +' # end of SH (cf }X above and }N below) +.de }2 +.nr )E 0 +.}E +.nr )I .5i +.ns +.. +' # italic +.de I +.ft 2 +.it 1 }N +.if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 +.. +' # bold +.de B +.ft 3 +.it 1 }N +.if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 +.. +' # small +.de SM +.ps 9 +.it 1 }N +.if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 +.. +' # combinations of Roman, italic, bold +.de RI +.}S 1 2 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de RB +.}S 1 3 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de IR +.}S 2 1 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de IB +.}S 2 3 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de BR +.}S 3 1 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de BI +.}S 3 2 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +' # make special case of shift out of italic +.de }S +.ds ]F +.if "\\$1"2" .if !"\\$5"" .ds ]F\^ +.ie !"\\$4"" .}S \\$2 \\$1 "\\$3\f\\$1\\$4\\*(]F" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9" +.el \\$3 +.}f +.. +' # paragraph +.de LP +.PP +.. +.de PP +.sp \\n()Pu +.ne 2 +.}E +.nr )I .5i +.ns +.. +' # paragraph distance +.de PD +.if t .nr )P .4v +.if n .nr )P 1v +.if !"\\$1"" .nr )P \\$1v +.. +' # hanging indent +.de HP +.sp \\n()Pu +.ne 2 +.if !"\\$1"" .nr )I \\$1n +.ll \\n(LLu +.in \\n()Ru+\\n(INu+\\n()Iu +.ti \\n()Ru+\\n(INu +.}f +.. +' # indented paragraph +.de IP +.TP \\$2 +\&\\$1 +.. +' # hanging label +.de TP +.if !"\\$1"" .nr )I \\$1n +.sp \\n()Pu +.in \\n()Ru +.nr )E 1 +.ns +.it 1 }N +.di ]B +.. +' # end of TP (cf }N below) +.de }1 +.ds ]X \&\\*(]B\\ +.nr )E 0 +.if !"\\$1"" .nr )I \\$1n +.}f +.ll \\n(LLu +.in \\n()Ru+\\n(INu+\\n()Iu +.ti \\n(INu +.ie !\\n()Iu+\\n()Ru-\w@\\*(]X@u-3p \{\\*(]X +.br\} +.el \\*(]X\h@|\\n()Iu+\\n()Ru@\c +.}f +.. +' # handle end of 1-line features +.de }N +.if \\n()E .br +.di +.if "\\n()E"0" .}f +.if "\\n()E"1" .}1 +.if "\\n()E"2" .}2 +.nr )E 0 +.. +' # increase relative indent +.de RS +.nr ]\\n+()p \\n()I +.nr )\\n()p \\n()R +.ie !"\\$1"" .nr )R +\\$1n +.el .nr )R +\\n()I +.nr )I .5i +.}E +.. +' # decrease relative indent +.de RE +.if !"\\$1"" \{.ie "\\$1"0" .nr )p 1 1 +. el .nr )p \\$1 1\} +.ds ]i \\*(]I\\n()p +.ds ]r \\*(]R\\n()p +.nr )I \\*(]i +.nr )R \\*(]r +.if \\n()p .nr )p -1 +.}E +.. +.nr )p 0 1 +.ds ]I \\\\n(] +.ds ]R \\\\n() +.bd S 3 3 +.if t .ds R \(rg +.if n .ds R (Reg.) +.ds S \s10 +.hy 14 diff --git a/src/troff/tmac/tmac.an$ b/src/troff/tmac/tmac.an$ new file mode 100755 index 00000000..dc3dc437 --- /dev/null +++ b/src/troff/tmac/tmac.an$ @@ -0,0 +1,267 @@ +' # month name +.if "\nd"0" .nr m \n(mo-1 +.if "\nm"0" .ds ]m January +.if "\nm"1" .ds ]m February +.if "\nm"2" .ds ]m March +.if "\nm"3" .ds ]m April +.if "\nm"4" .ds ]m May +.if "\nm"5" .ds ]m June +.if "\nm"6" .ds ]m July +.if "\nm"7" .ds ]m August +.if "\nm"8" .ds ]m September +.if "\nm"9" .ds ]m October +.if "\nm"10" .ds ]m November +.if "\nm"11" .ds ]m December +' # set the date +.if n \{.nr m \nm+1 +. ie \nd .ds ]W Modified \nm/\nd/\ny +. el .ds ]W Printed \n(mo/\n(dy/\n(yr\} +.if t \{.ie \nd .ds ]W \*(]m \nd, 19\ny +. el .ds ]W \*(]m \n(dy, 19\n(yr\} +.if t .ds ]W 7th Edition +' # reset the basic page layout +.de }E +.}f +.in \\n()Ru+\\n(INu +.ll \\n(LLu +.. +' # default tabs +.de DT +'ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i +.. +' # set type font and size +.de }f +.ps 10 +.ft 1 +.. +' # handle the head of the page +.de }H +.ev 1 +.}C +'sp .5i +.ft 1 +.ps 10 +.tl @\\*(]H@\\*(]D@\\*(]H@ +'sp .5i +.ev +.ns +.. +' # handle the foot of the page +.de }F +.ev 1 +.ft 1 +.ps 10 +'sp .5i +.tl @\\*(]W@\\*(]L@%@ +'bp +.ev +.. +' # the cut mark +.if n .ig +.de }C +.po .1i +.tl '-' +.po +.. +' # the final cut mark +.de }M +.}N +.wh -1p }C +.ll \\n(LLu +.. +' # no runout unless there was a .TH +.de }K +.}N +.pl 1 +.ll \\n(LLu +.. +.em }K +' # set title and heading +.de TH +.PD +.if n .nr IN .5i +.if t .nr IN .5i +.nr LL \\n(.l +.ds ]H \\$1\|(\|\\$2\|) +.ds ]D UNIX Programmer's Manual +.ds ]L \\$3 +.wh 0 }H +.if t .wh -1i }F +.if n .wh -1.167i }F +.em }M +.if \\n(nl .bp 1 +.}E +.DT +.nr )I .5i +.nr )R 0 +.if n .na +.. +' # section heading +.de SH +.}X 0 +.nr )E 2 +\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 +.. +' # sub section heading +.de SS +.}X \\n()Ru+\\n(INu +\&\\$1 \|\\$2 \|\\$3 \|\\$4 \|\\$5 \|\\$6 +.br +.. +' # subroutine for section heading +.de }X +.}E +.ti \\$1 +.sp \\n()Pu +.ne 2 +.nr )R 0 +.fi +.it 1 }N +.SM +.B +.. +' # end of SH (cf }X above and }N below) +.de }2 +.nr )E 0 +.}E +.nr )I .5i +.ns +.. +' # italic +.de I +.ft 2 +.it 1 }N +.if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 +.. +' # bold +.de B +.ft 3 +.it 1 }N +.if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 +.. +' # small +.de SM +.ps 9 +.it 1 }N +.if !"\\$1"" \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 +.. +' # combinations of Roman, italic, bold +.de RI +.}S 1 2 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de RB +.}S 1 3 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de IR +.}S 2 1 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de IB +.}S 2 3 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de BR +.}S 3 1 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +.de BI +.}S 3 2 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" +.. +' # make special case of shift out of italic +.de }S +.ds ]F +.if "\\$1"2" .if !"\\$5"" .ds ]F\^ +.ie !"\\$4"" .}S \\$2 \\$1 "\\$3\f\\$1\\$4\\*(]F" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9" +.el \\$3 +.}f +.. +' # paragraph +.de LP +.PP +.. +.de PP +.sp \\n()Pu +.ne 2 +.}E +.nr )I .5i +.ns +.. +' # paragraph distance +.de PD +.if t .nr )P .4v +.if n .nr )P 1v +.if !"\\$1"" .nr )P \\$1v +.. +' # hanging indent +.de HP +.sp \\n()Pu +.ne 2 +.if !"\\$1"" .nr )I \\$1n +.ll \\n(LLu +.in \\n()Ru+\\n(INu+\\n()Iu +.ti \\n()Ru+\\n(INu +.}f +.. +' # indented paragraph +.de IP +.TP \\$2 +\&\\$1 +.. +' # hanging label +.de TP +.if !"\\$1"" .nr )I \\$1n +.sp \\n()Pu +.in \\n()Ru +.nr )E 1 +.ns +.it 1 }N +.di ]B +.. +' # end of TP (cf }N below) +.de }1 +.ds ]X \&\\*(]B\\ +.nr )E 0 +.if !"\\$1"" .nr )I \\$1n +.}f +.ll \\n(LLu +.in \\n()Ru+\\n(INu+\\n()Iu +.ti \\n(INu +.ie !\\n()Iu+\\n()Ru-\w@\\*(]X@u-3p \{\\*(]X +.br\} +.el \\*(]X\h@|\\n()Iu+\\n()Ru@\c +.}f +.. +' # handle end of 1-line features +.de }N +.if \\n()E .br +.di +.if "\\n()E"0" .}f +.if "\\n()E"1" .}1 +.if "\\n()E"2" .}2 +.nr )E 0 +.. +' # increase relative indent +.de RS +.nr ]\\n+()p \\n()I +.nr )\\n()p \\n()R +.ie !"\\$1"" .nr )R +\\$1n +.el .nr )R +\\n()I +.nr )I .5i +.}E +.. +' # decrease relative indent +.de RE +.if !"\\$1"" \{.ie "\\$1"0" .nr )p 1 1 +. el .nr )p \\$1 1\} +.ds ]i \\*(]I\\n()p +.ds ]r \\*(]R\\n()p +.nr )I \\*(]i +.nr )R \\*(]r +.if \\n()p .nr )p -1 +.}E +.. +.nr )p 0 1 +.ds ]I \\\\n(] +.ds ]R \\\\n() +.bd S 3 3 +.if t .ds R \(rg +.if n .ds R (Reg.) +.ds S \s10 +.hy 14 diff --git a/src/troff/tmake b/src/troff/tmake new file mode 100755 index 00000000..ddc735d3 --- /dev/null +++ b/src/troff/tmake @@ -0,0 +1,32 @@ +CFLAGS=-n -s -O +TFILES=n1.o n2.o n3.o n4.o n5.o t6.o n7.o n8.o n9.o t10.o ni.o nii.o tab3.o hytab.o suftab.o + +troff: $(TFILES) + cc -o troff $(CFLAGS) $(TFILES) + +n1.o: tdef.h d.h v.h tw.h s.h +n2.o: tdef.h d.h v.h tw.h s.h +n3.o: tdef.h d.h v.h tw.h s.h +n4.o: tdef.h d.h v.h tw.h s.h +n5.o: tdef.h d.h v.h tw.h s.h +n6.o: tdef.h d.h v.h tw.h s.h +t6.o: tdef.h d.h v.h tw.h s.h +n7.o: tdef.h d.h v.h tw.h s.h +n8.o: tdef.h d.h v.h tw.h s.h +n9.o: tdef.h d.h v.h tw.h s.h +n10.o: tdef.h d.h v.h tw.h s.h +t10.o: tdef.h d.h v.h tw.h s.h +ni.o: tdef.h d.h v.h tw.h s.h +nii.o: tdef.h d.h v.h tw.h s.h + +hytab.o: hytab.c + cc -S hytab.c + ed hytab.s

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 literal 0 HcmV?d00001 diff --git a/bin/banked/head b/bin/banked/head new file mode 100755 index 0000000000000000000000000000000000000000..3fa7fa7d25cb246611999587f56f29ec5c22fdeb GIT binary patch literal 9396 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 literal 0 HcmV?d00001 diff --git a/bin/banked/init b/bin/banked/init new file mode 100755 index 0000000000000000000000000000000000000000..2bfcaf32a8894dbb461faa3d890b357e36696100 GIT binary patch literal 21590 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%0DdkROZPD8D%JtKf(vq?tgA2~` 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 literal 0 HcmV?d00001 diff --git a/bin/banked/lpr b/bin/banked/lpr new file mode 100755 index 0000000000000000000000000000000000000000..c1d9379bbe8def595af75869dc1d6e29cb1d1b6c GIT binary patch literal 7116 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 i1iG{{&-a|q z=bZ1&er01Xb};q=W1R5=e$0gvftl&%@(%vPy~fB@b4Edt?TKs?8oqL`)2}pkXrKB zO8eWzzgG{|=a&!GuN{6}9xrTV$D?zyK5IljmKXH7n2Wuq-O==vChG~~wywEY@@{lK zHYzXNnY+Cte{eYw!N)=~HzK1;i!Q|Efq?-RYi5kfvr$dc4S9Ac7Bym&5t}vir4^aE zST4d%6T&tK*%ce}M{Wj~61a+lv3Y+{8f1#2J;r_Dk692tn|O7t&!9+44J;~%NROp=&rBWD{cU$1ePvB9(* zd-{f|uif*W69r_aA~BC0k(sx6F32(CA!QT=6}OF{=Tq_=QbL4RtPM!jA=SV?6H=C& zQARH@T^rO_2j|!JHa}e5lin}iz^a-J;`V+>+Q6`5!5tf<96mb?Ia^9GmRsb%-kbo< z0dZ$qC03X3lYJK03{D2^c35;k!bub%SplO8S_R@&RT$|X9=wY{@}$j$`$PZtkhJL= znG?9cn?H`+LM?izb#ahyZAFHeClBE|gc>kYf$1u46ze1}lN^P{;3i8)0 zeDsKaf6sef!f#^pPNR)pTo>GL=ltok~7{^E*d?QUg8XcTp;rE#(j yMgta2NT7#gLy=uzbg4LGSrEqyMzZ&ZK&wN%fhJ-46P}0S3_&5Ube$!J&VK-qD%%tQ literal 0 HcmV?d00001 diff --git a/bin/banked/mknod b/bin/banked/mknod new file mode 100755 index 0000000000000000000000000000000000000000..932ebcd8d0efa522d181530d896cdbffe19afb7e GIT binary patch literal 2288 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 literal 0 HcmV?d00001 diff --git a/bin/banked/mount b/bin/banked/mount new file mode 100755 index 0000000000000000000000000000000000000000..5de87b42a9b697741692e31c750e45d31262a035 GIT binary patch literal 9491 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 literal 0 HcmV?d00001 diff --git a/bin/banked/msh b/bin/banked/msh new file mode 100755 index 0000000000000000000000000000000000000000..794803df181d0fe08e82bdbcd563d6b44ef18892 GIT binary patch literal 40306 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 literal 0 HcmV?d00001 diff --git a/bin/banked/ncheck b/bin/banked/ncheck new file mode 100755 index 0000000000000000000000000000000000000000..c40280a4799dd8dca2abd98c19fcabc6c9f32f24 GIT binary patch literal 16380 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 I4YTuq0e8>|O#lD@ literal 0 HcmV?d00001 diff --git a/bin/banked/nroff b/bin/banked/nroff new file mode 100755 index 0000000000000000000000000000000000000000..0dc5b607f9e3cfe2e0e608ab5864a12be7a99cbe GIT binary patch literal 69116 zcmeFadwf(ynm1m3Ngx3U0mOr%^aU`SAc@LEa5O?dKm!3mK#f8=NhfJ((xJOU03`-+ z6teH@24~h~+!=>;9c3H_7?(j|e3_)%xC-KW!*N`XBbP)mG$arLLP*~4Q&s15cL2xT zeSiDM?~_1xpHrtUPd)Y2Q_rpHy!*15bzWs+Ll|4b*7&#N|6Bf_Ka9-tZ)u2332r&$ zSiZ&1CS{urdi*&IJditnsG@-fcXHYiFKwTFZf% zYr;b)Ps^Br7hB#va!_m1?2Ks>wFOC9FiBg~SF7xMuwFL>0hlf3=E$D+E zZBgPJ{4{BctlEOE$irHBf>zQe;vJ?#7zzt81$kI;%HS&30C= zubQ5op5FHEp+=*t$C^gh_^KneiD>A^u^8NJTMOJAIdkx_=bVdIz2IDkU;KnOuZ_v` zz&f6X!?EJ`X;<|_Cfk`+&)M3XfQUfKw6-|M3E)#@ zuSDiHtY{z{QX5V7L}dP#DrfbJRUbO51OJS!`!`Q-`|uFQ@3ZR&IWagOdT5#WUCXhg zq-tl0ui^V3-7Ww<)bRRyJD+?DfF9yt5_uir^`2>JL~ri+$(aK$JlWRrx~rnkL2wti%N|9b1YXPQt! z3kqTMx9j!2o@N=WBtDk0cvS|c0iH?Tw(-vW>`6ZIAY&6KIqRHVF%P><+uu1<+kX+C zE_}L&YCk%cHg13F{(<|i-ajNVcY6s1b zuPFbgt*O8RaI1ex6!kn&)X#~cHc5)&q<8DBoLp(rseIA_itN<=gZB@*^Bvw&PUfj3 z<>Z;w8NSCeN>^sgUXg(g?_ZUsW183J3VO;*ZFjFIa#sXBzVdO&Y>KPA+!wSJ`Q5Id+ZJ>$t+17Nyly-} za&RTPe`SR`;0^}eep_K>U}dy~ufkn!W67+@Reod8#_y=0jot6_*_OJ>SK2CErEXh! z<1~{T~sH4;q0EP${&x)d@tJrdHaTUAgfhn^d zVhd(YUC5?-mV1ibw!)RRRc^m8T4jaTMNRo#6-b*O0Foyc`p||xEX6*XdpXrwa+BK| zaNB%q7tv z!|wJL+p0XpK`JfjLLX(uFbu3Ov#|`85nNi4!RAc9e+CfL~m=gGJ(w zuuo=@Fwd6?D6H&ZHV33c5YZintk}Ig1JfRvy1Rc^jn%cHg6?kmW#%M& z7Y8Z}O|C#up(#-D(j(@Q;J9Vxioh?Ho0kV_D$V77%UrXku z$L5@jqN6kQCp~>&hzR&D0|2vn-Rebw=vp=9LFqgZ&ns2V~ehAQ9kCmE( z{u5>9O78}bxu~+rWA+CB5v{FwZoVntTfM;KDSg0Y3Kkt&U@j@DSz>V)rIwoAzL9{c zsC|Liy?pgzv%k2-ZFUu|UTQA!KDyZKUeW!CDG=DQ++0#Ipwe6vcyYP8u=v-@&EC>q zEjO1Hy}!U*wzAJcb9q@lzLpky&E@6yE;R?1f3n2v3)sA7Z(!Vm=Axo4z{V|qL>o(I zEjGJKw$3$|Ro(cIWogmjN6i&W&n-7qcnS+ll_mXgThv`?Dhr-_&{9+qUWoDP{p-a* zF9v!s@SngyW=!5>h&l9+{uKO6!#`RFltl4QtPLhMj@<~|o)#Igvix_Yk1b~2Wbaom z26{2ji-BGY^kSeF1OFo!7`dBP@UoRPtgvzo3oKj9+)LLnf8~?x=J7vaH{bFUyLJ52 zY^f*2N<14_iMN)Ol>8l==J{W2n)iRRV)rwwxb*K?ps0?OEZxXlu4h@P>!+;J`!g2s z{sU88o0wYobEcL)&(z|7VygQWOkMR$rmlQ}sb#-ns%JA(m;5tRy)QC#>Ax_w{3WIq z{hF!1mzi4e3RC@Cm>T#EQ-iNEweq)2E!oP{6~ANZvTaPQ+RoI;lbM>6!_?_Jm^$_M zOuhSVratr#Qy-kc)ETca^`3i}nw!hing7bvS+kg$m&ep8JDECrHdE*PfvI!nFm>K8 zrrv))Q|G_I)M>k!`oIHBy>Aaw7ygk2{BN>g;Qugx`CgWN=bzXech<8z?`&YzcZQj( z;w@&svyt7D{WiPfrhj9Vu6J0m>s{tvwvR2X+|PkSdC>zBCF`b3fKpA ztRi7^Up6U`)vymXvpJRm#&C~h$6&k7HpppL#-}p-B;>72WCa#v!~Z$vy1uLe_w0j# zjQ+|0&cKgG4suR)++1=q>qBJ#!6e4!FuF|2w3_Bv=&A;ZXovsbT!Y^Vh8FP~bCbz7 zr#kKT*#YlN$b{fMq%h zM;F{uy8gk@(_T)wCle?`9vgoc9W0cd1lT6YCk0uf+y!hxxAMRgOG=^**#W31Q-jL_ zM!1;6Z1^u5tq?azMmBzBHGS`9CXQq&Dm_86$Tkp_(TDyrX?SaR8IabG9GNw2{j(*B zPu3+{HY3v{d~JzidUlSZWNlg^8*@W|<)P6~SO%ut*=;j*rK(o zoV+V#QpbB4hnq*R%vasF`?@P{%?hTSW|%6RdQ&*Kvr~T6U2}Z?4C{8r>NC!cJ?VSq zy_tXClFl;j`n$XCdg9-^XLf&k7t5v_-xJ+qyT6^y?wr5rN6%zr-Fjowf+TibM)#Q3 zIcierMb}iy!~vP1>&O*wVXv8Lb(&I)>c!6ahNouGUFs(4XowHngh5 zaqnF-ZrR$QcC!G`4eWGhCd0VAeZ=#=Hk)OBU(+_mzUq$trTpo)2ev=c{Zz@@-z|8a zSu>I+wN|vEV2Y1bk1F%}9WSpheRRquqEQ=-&m@*QCxvL#T<`&4G}WbG!pt%KGd&qt zkdisrKe}+x)9W8pr)^1@k;xoHAvRV!DFua5Mi3jyAbWu+wSbMDlmZ&Pdd1BHa=Og?wfU&|i1{$Hx`W61 zxV*;#?H((AD%w2>$5#fAS$)A{39fRa(5DC=7ZS@(cr4||EK84By~jP)LVS*RJr?gV zOW83?$uUduG0S0(#dXXQaalZvnDwmBZ#|ArGd|zB{MNHBf5O+5xM;`4VIM9|;NrLk z7sv4V8lS^1zvYw0uxXDu7lyJ1N$Q^Q{ zcDKv=joZZ%T>fLL&~5ti9$S@o$X|@h({AtbgqCv8a)9byKBcX)j}J&GKVvyjX*pUM zs%%_V=?Ypa4+RO#AUYRJZ1?$b>n=YO1X#g@Z+w-3gd<*G!0I^}u%7h<5?p~Z{*k9E z{fW(<(ldT%yB}o*rV`GUx&4W!EAUOjcZ5bT;dGI&!n*P#A;MRl&{_txe2tI$WckRZ z^72uxQ=W3v?*WcH<$X^1DgmDLv~Q{P2tMterIzzvOS{){+6y8`=+Jmn?-&TT3i+~1vwR+t6^16x+G0Vx4 zgjPQY24iJ8N9l{uop2ami7VU7fOWS!Saz&D(M>lArC;N#_$a;# z4|~cj$I4kk#8(+iz>Ek2A3*{tkl>~-fD=gYpTHMj3Q(&7OcMH{E6lL~)fS-I0+wS) zhIg^gVW0nGWog3UN`I-f!&78A;j$ceStFQqH0zI)t@D(ua~CHZ3KU^(xR;8l7@_$E z9G!Jxi2bf2OtvCsX|7BNoOOFK&AbVx%jhde108hXvDbRU<+UttvQ#!%mNZ#|Wlah2 zYBpJ1O~q}ME@$N-OS{Wj=|428^yCSb)mMH9fMBRy7;4w3cE9J4l|Co%If~B_kIV8k zpme)No^rbq!Bmd85>DgGdhCeHg8zqIi6?x#6DKMYe5X8TocQlPli*o?EP!eQ37!bP zh+BSv`T1meW2Em!;KX0UwNb zEXO^T77y^{_F&R`5=zU0O&H;&O_qq;>T7Wm%G%v-41n8t+C@(efivp(K^I(vlCZ}G zS^@(CUYzbjAQTrQV+^ye(tO5xy3Av3al4uIyvrZ*0}khD-^f#*lUC2FCV;lQ$$E0R z+uF3esV}B_Yh|!$6efr}!56^Qp`vzo;#t23mmVaJa?_U!Ul?6CSRF3>c($|&1 zG6CaKnSimVOu%4Nj`SeuYd78D3(T*w@Qn3@J77KT4iugqRdMpTr|{U6bM7gp-BSU^ zRDjUH5)o^FS>vHEqMStUNt#U!#6c<<)0@h-r9&rT{uo%#?<+FHBCN%qr z<$`@+gfQ(r?s6+w5h1p;Eb%b^23NrKSvS5hhrj?ay-G$>_rLaGknzE4XFXen>q-wB ziGdiktkTmCQfMFL3mj_)-L(^l?bdQndm4DK$9t^3FW4~u1!Jb)ME-3-F-&`q_^AZU zLI23gL;gMhtlf2rx_ZbD;QZF|leFGjOTX^P)+IwXAGe%dGP?AXtF_DugqWKxC)}3f z7_}u$mKF@KuNY)q36!{t&4(>#U6!LR*7PgJ25f$G^YDK@_~Nk_tN!J$|H9are@S`i zrI(JpwE5RB|C+H~zkcQAlP{ClLw{>uVJrilU+DF{f4vy!#Xv6xdNI(8fnE&sVxSiT zy%^}lKraS*G0=;FUJUeNpcezZ80f`7F9v!s(2Idy4D@2){}l!f+`jHy_YJ0l_ES@v zQcWz|YJYtOHv6}=>1pPev~1JwcG~W;GuC7`vH0vpVr+gR(GpY108^vge0Ni7YL7Gm zAh}0c8uImzNyDK5T1f)!Ctoy_Wt;4??gp${o>`k_>8C9-YZVqWd0^YRkG{(hS)ER; z(y9e{k?O9SLVEf%XGxiJ(SZwV1~4}7es`H?X}ParnLn`V%bZ}&E0gz6zI}4_$pzq&Zqlb|<>$1L?{G`G(<`hAX=ddM^^1C^;|l^irYUsy z&kq0yq^k7*w4MM}+1pMBdz-F8NDEP#{kqynZvK@asBV73WYZtmBl+hWkbmM5WWoU6td0yJSygxL zanb=A>Kl7-iot|yRddLR(o~Htl!`t77W?zFQABweh5Ox$D{RxpW_@+wMijS%znrR$ zriz9}a(C`g-{h4fBPrc6I)sN>b!T(8PpiJzTvMu5VwZn+wt~rgkJ{egB-k8i%@K;t zm7V;%ooU138*9PsBM%W22MI7o2*uM;JpAAk^}RYePheU%pidj1z8}4_t&F?tqn@jC z0x7cP_y$%tch7#jxn?>YL{QP4ZTroRwB+n0ZCjVNtJ`K)KEh!III_U8X_IW&1eRs8 z@4W{g5o}hv!0#XK$1i{~vIBc6@d~6JBsOQVzqA;)ABMkL(|9no<|jz_B~8oAF{ck3 zkc;{&xLzzj>QNP#X=k?>t5;W}HZek4wYke>8)#2pT3)9%?ILCw4Vy7F+~u z&6K+Z>|^;PTz=X*btkA`=RT*Iby6q_#H4SM^#}7tW>V zHfiNJ(V;tC3^0h{D*LH=F)B&Rl*8G!TQ)R+E%d2CISy4?lEhF~WBBtm9DKW(IS$uv z*Q&a-D%qF!9z%Y|)-9mc@o33}mKgQiVvl)pEuNV96RZHSPrw@z?c0BX@&Y=?xAm&8 z7Qpo*OquKtP{-6|NU>$9?+{PRu$yX{?19?YJ}#@}SouQ~D_!0CD5AN)Uq)TZ>a=KC z7n$f2us~>b(wwlfzD=g*>LU4H)g$wDgzYxvGke+Z9p@VDAM9~_ve)s!UZUtnY8~os z6JvC}WlLnrt6S{d-Hy?_(bPkP?NnyQ<*%3G(y?ogW9J_Gt8X|QyX`|5O}iw=o;_fL zj?e1_HqUpXo{5j#kFg3)MG?9~<*9R~9q>I#OQ^l(zNVG~53F-KZrL5lzh(E}!GleG z*nwx)4UWtkzuW#=A4eL}({`Jzl=#?dX?^X(nd7^sfzj*fR}Pb@e~rLxcFoq(NKWST zNbW7WMar1evri9O;4FC*tKx*KM4Ho)xf=k=8$m4TV@zkCP6Ge2-?F=UBTjkQRHbZD z({?)nLHNb#AdRkW$?kwD;N+9Nprqf^*og`VW1BXKI;r=lJE5K_IqM!Xlam7CN;m z9ArY=c>AujLE3n;&7zIR|4#b7s2r7(M$Cms{^2MY^sJC*1|);Si1^$z*YZ@@2MSD-OQ#ttD9?fq}`$J*|WXMS*2B5wOt8meF6EO z%S8`3TZ$|BW-XoLgDmfP2?=9GAzK0(QAS{X9PF8!PA97N6nu!>I^-yApU+{Gun&r+ z5TnP8GAqNx$hgO`)!MGk*^g_xE`rH+Y87<;3;2ns?0mQS7FOi9_NbdS0SV*rBi4MK zFJ~wJW(Q=BPAnRo4PwYqA{`~f!W`Z|8xK+RDw%9gW=I1-@6+NHUzud`*ZpS4zHPZ$ z^?9IBtG+-uw1f+1XAhHX|4x048h|xwKq$U0bzdF&2R23mietFGAgKee@C^usuemq7 zzpSPo3Pv6zyj^oIYFxcD^xNF*68UhH`Z%$q8`M*HV7o?JbY5F<0R;Zruq}SPgDpgBn~ATq z$P;sL|I46J7^SG7fk!^naf{_@pbtyuj zKjl|$T>Xq+<>P8Szq$`sBly*HTwTqt?!;9;eswFZ6n-@ZS4nh5n9Vwm#ZbQ-61^Np zmn2LvE^<9lib;2#Cfx;0y7OAa1?mo`!8y_48H_F5nQSI2WW}t6m9ayrp?i}orcvl|bGcGfJ#-X*CsisWCeOo0U((wfX97WA@hL4Bo(Rr!# zkDYDGAaUpDXfUXi7#m66U~Hu%Q`@eKVV~-5t`&f#W@D+%-YvN%cu=~*gE&_Z!i-(r zU9COUiRD>)=3